If you could only put a full command there, I think
#!/bin/sed 1d|/usr/bin/gs
could work.
Do I have to make a helper script to prune the first line
and then pipe to gs?
This is so cool, i've got to share it with anyone who didn't follow
into the other group.
With this program compiled in my home directory as gscmd:
#include <unistd.h>
int main(int i, char **v) {
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c", "(#!)cvn{currentfile =string readline pop pop}bind def",
"--", v[1], NULL);
}
I can edit this document in vi:
#!/home/olpc/gscmd
/Palatino-Roman 20 selectfont
/lead 24 def
/scratch 5 string def
/space ( ) def
/dash ( ) dup 1 8#320 put def
/stringtype { show //dash show } def
/integertype { //scratch cvs show //space show } dup 3 1 roll def
/nametype exch def
36 720 moveto
{
{()(Shelf Lives)}
{(Iced Coffee (refridgerated))8/hours (, (room temp)) 4/hours}
{(Iced Tea)12/hours}
{(Chai)24/hours}
{(Mocha)24/hours}
{(Open Coffee Beans)7/days}
{(Caramel)14/days}
{(White Mocha)14/days}
{(Bottled Syrups)30/days}
} cvlit {
gsave
{ dup type exec } forall
grestore
0 lead neg rmoveto
} forall
showpage
And I can preview it with the ex: command !%
!% !!
So I think this trick should be called
"Throwing it for a loop."
--
Is it really 3 in the morning?
Anybody know how best to pass arguments with this method?
I mean besides fixing the C program to actually pass
all its arguments. How do you pass arguments from the
gs command line into the postscript program?
At first guess, you could put them in an array as part
of the -c string. But I feel there's got to be a nicer
way. Perhaps something someone's already done that I
could shamelessly exploit. Bwaahahaha!
--
You're supposed to be a lap cat. Act like one!
Every argument passed to gs by a -s or -d switch gets defined in systemdict
during initialization. Example:
gs -NODISPLAY -sME="I'm a nerd"
GS>/ME where{/ME get == flush}if
(I'm a nerd)
GS>
Helge
That's a start, I think.
With the following, I can pass an option on the shebang:
#include <unistd.h>
int main(int i, char **v) {
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c", "(#!)cvn{currentfile =string readline pop pop}bind def",
//"--",
v[1], v[2], v[3], v[4], v[5], NULL);
}
...
#!/home/olpc/gscmd -dsmall
/fsld
[ 20 24 ]
/small where { pop pop [ 10 11 ] } if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def
But this won't work as a command, because they end up in the wrong
order on the line: gs processes the file before it even sees
the -d option. And I don't like having to lose the "--". That
seemed to keep gs from opening %stdin with executive. And my
one-page document would disappear with just [enter].
Thinking through my goal a little further, I'd like to
put all the options in an array, perhaps called $ or $$.
And I'd like to provide a shift procedure like a real shell.
I guess it all boils down to string-mangling in C. All of this
should fit into the -c argument, I think.
--
lxt
> Thinking through my goal a little further, I'd like to
> put all the options in an array, perhaps called $ or $$.
> And I'd like to provide a shift procedure like a real shell.
>
> I guess it all boils down to string-mangling in C. All of this
> should fit into the -c argument, I think.
Now that I look at it. I'm not sure I like it.
Maybe a dictionary really /is/ best.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int arc, char **arv) {
char c[500] = "";
char d[550];
char s[2] = "/";
int i;
for (i = 2; i < arc; i++) {
strcat(c, s);
strcat(c, arv[i]);
}
sprintf(d, "(#!)cvn{currentfile =string readline pop pop}bind def /
$$ { %s } cvlit def", c);
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c",
d,
"--",
arv[1], NULL);
}
...
#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if
false $$ {
/small eq { pop true exit } if
} forall {
pop
[ 10 11 ]
} if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def
That 'false ... forall' baloney is a lot uglier
than 'where'.
--
back to the sandbox...
Here's how it looks with the shift proc.
A big problem with this way is it blocks
all options from being passed to gs.
Perhaps I could grab all the /^-/ arguments
in a vector, use the first /^[^^]/ argument
as the filename and pack the rest in another vector,
collate them with the default arguments,
and use execv. That sounds like a lot more work.
Anyway, the shift just makes it uglier!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int arc, char **arv) {
char c[500] = "";
char d[550];
char p[2][2] = { "(", ")" };
char s[2] = "/";
int i;
for (i = 2; i < arc; i++) {
//strcat(c, p[0]);
strcat(c, s);
strcat(c, arv[i]);
//strcat(c, p[1]);
}
sprintf(d,
"(#!)cvn{currentfile =string readline pop pop}bind def"
"/$$ { %s } cvlit def"
"/$shift {"
"$$ length 0 gt {"
"$$ 0 get "
"$$ length 1 ge {"
"/$$ $$ 1 $$ length 1 sub getinterval def"
"} if"
"}{ null } ifelse"
"} def",
c);
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c",
d,
"--",
arv[1], NULL);
return 0;
}
...
#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if
%false $$ {
%/small eq { pop true exit } if
%} forall { pop [ 10 11 ] } if
{
$shift
dup /small eq { pop true exit } if
null eq { false exit } if
} loop { pop [ 10 11 ] } if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def
--
down the rabbithole
or just a wild goosechase?
I meant /^[^-]/ here. Got a little carrot crazy. ;)
> as the filename and pack the rest in another vector,
> collate them with the default arguments,
> and use execv. That sounds like a lot more work.
...
>
> I meant /^[^-]/ here. Got a little carrot crazy. ;)
>
Um ... that's *caret* (not carrot (the veggie), nor carat (the jeweler's measurement unit)) :-) .
But no offense taken; after all, what's a li'l typo amongst friends?
Cheers, -- tlvp
--
Avant de repondre, jeter la poubelle, SVP
Oh, that was deliberate.
It went along with the "down the rabbithole" signature.
But now that you mention it, the jeweller's measurement
has always bothered me.
1/4-carat diamond, 18-carat gold:
it's got to mean at least 2 different things, right?
--
Route 66 is a really long road.
yes.
For gold, only, it is a measure of 'purity', Number of "24ths" by weight,
that is the metallic element with the symbol "Au".
For diamonds, and other things, it is a measure of weight - 205 milligrams.
So my Ibuprophen tablets are 1-caret doses?! Awesome!
Well, to within under 3% and a couple of typos: yes, so it would seem :-) .
Why didn't I read the manpage just a little more closely?!!
OPTIONS
-- filename arg1 ...
Takes the next argument as a file name as usual,
but takes all remaining arguments (even if they
have the syntactic form of switches) and defines
the name "ARGUMENTS" in "userdict" (not "system-
dict") as an array of those strings, before run-
ning the file. When Ghostscript finishes exe-
cuting the file, it exits back to the shell.
That's just perfect!
> Why didn't I read the manpage just a little more closely?!!
>
> OPTIONS
> -- filename arg1 ...
> Takes the next argument as a file name as usual,
> but takes all remaining arguments (even if they
> have the syntactic form of switches) and defines
> the name "ARGUMENTS" in "userdict" (not "system-
> dict") as an array of those strings, before run-
> ning the file. When Ghostscript finishes exe-
> cuting the file, it exits back to the shell.
>
> That's just perfect!
Now we're getting somewhere.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
gscmd [-shebang-opt] ps-script [ ARGUMENTS ]
*/
int main(int argc, char **argv) {
char **v;
unsigned shebang;
int i;
int o;
printf("%d\n", argc);
switch (argc) {
case 0: fprintf(stderr,"no program!\n"); exit(1);
case 1: fprintf(stderr,"no script!\n"); exit(1);
}
v = malloc( (argc+5) *sizeof*v);
if (!v) { fprintf(stderr,"no memory!\n"); exit(2); }
o = 0;
v[o++] = "gs";
//v[o++] = "echo";
v[o++] = "-q";
if (argv[1][0] == '-') {
shebang = 1;
v[o++] = argv[1];
}
v[o++] = "-c";
v[o++] = "(#!)cvn{currentfile =string readline pop pop}bind def";
v[o++] = "--";
if (!shebang) {
v[o++] = argv[1];
}
for (i=2; i<argc; i++) {
v[o++] = argv[i];
}
v[o++] = NULL;
//execvp("gs", v);
execv("/usr/bin/gs", v);
//execv("/bin/echo", v);
/*
gs -q -c '(#!)cvn{currentfile =string readline pop pop}bind def' -
shebang-opt -- ps-script ARGUMENTS
*/
return 0;
}
...
#!/home/olpc/gscmd -dsmall
/fsld
[ 20 24 ]
/small where { pop pop [ 10 11 ] } if
%false ARGUMENTS {
%cvn /small eq { pop true exit } if
%} forall { pop [ 10 11 ] } if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def
--or--
#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if
false ARGUMENTS {
cvn /small eq { pop true exit } if
} forall { pop [ 10 11 ] } if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def
The first way passes the option to gs on the shebang line.
The second way lets you mention the options on the command line.
$ shelflife.ps small
But right now it allows at most one option to pass to gs.
So I'm not completely satisfied, yet. You can't tell the document
to convert itself:
$ shelflife.ps -sDEVICE=pdfwrite -sOutputFile=sl.pdf
It shouldn't be too hard, now; but I think I'll have to ponder
a bit more.
--
luser
> unsigned shebang;
Heisenbug!
This should be:
unsigned shebang = 0;
Sorry for any inconvenience.
Oh, also the comment at the end of the c program
doesn't show shebang-opt in the right place.
--
Day late, 2 pennies short.
You could have carats of carotin (from carrots, also spelled carotene) in a
pill marked with a caret symbol.
One is tempted to shout "sexist!" and note that the "PC" language would be
'itbang'. *snicker.
Yeah, I can see where you're coming from.
But as an unaccented vowel, it's really more of a schwa sound
and could be written with any vowel at all. I chose e because
I saw it that way elsewhere in the thread (originally I just
called it bang), but it could also be:
shabang
shubang
shybang
schaebang
schobangue!
Besides I think the term is from printer lingo for ?! as one
glyph with a common dot. Which is the punctuation sign for
doing a karate chop on the podium at the end of your sentence.
I repeat: "*SNICKER*"
To quote Foghorn Leghorn, "it's a Joke, son. J O K E *JOKE*!"
I be poking fun at the "PC language nazis" not the particular term.
I ,_personally_ have been using that term for over 25 years -- for the magic
first two characters of a script file. And longer than that, casually, as a
synonym for 'the whole kit and kaboodle'.
"PC" I am not, most of what i do is on workstations, minicomputers, or
mainframes, with the occasional 'embedded' u-processor. :)
>Besides I think the term is from printer lingo for ?! as one
>glyph with a common dot.
Nope. the proper name for _that_ glyph is the "interrobang" (admixture
of 'interrogative' and 'bang') Invented by Martin K Speckter, in 1962.
First included as standard glyph in a commercial type face, in 1966.
I know the history/origin of the 'shebang' term --
"The name shebang comes from an inexact contraction of SHArp bang or
haSH bang, referring to the two typical Unix names of the two characters."
It, like Mopsy, "just grew". The gang at Murray Hill -- specifically Dennis
Ritchie, he who put the feature into UNIX -- did not have (as Dennis put
it) a 'pet name' for the interpreter directive at the beginning of a script.