]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/ghostscript/gslp.ps
merge
[plan9front.git] / sys / lib / ghostscript / gslp.ps
1 %    Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
3 % This software is provided AS-IS with no warranty, either express or
4 % implied.
5
6 % This software is distributed under license and may not be copied,
7 % modified or distributed except as expressly authorized under the terms
8 % of the license contained in the file LICENSE in this distribution.
9
10 % For more information about licensing, please refer to
11 % http://www.ghostscript.com/licensing/. For information on
12 % commercial licensing, go to http://www.artifex.com/licensing/ or
13 % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
16 % $Id: gslp.ps,v 1.7 2005/05/07 22:56:56 ray Exp $
17 % gslp.ps - format and print text
18
19 % This utility provides functionality approximately equivalent to the Unix
20 % `enscript' program.  It prints plain text files using a single font.
21 % It currently handles tabs and formfeeds, but not backspaces.
22 % It will line-wrap when using fixed-pitch fonts.
23 % It will also do kerning and width adjustment.
24 % Standard switches implemented:
25 %       -12BclqRr -b<header> -f<font> -F<hfont> -L<lines> -p<outfile>
26 % Sun switches implemented:
27 %       -T<n>   set tab width
28 % Switches ignored:
29 %       -GghKkmow -# -C -d -J -n -P -S -s -t -v
30 % Switches added:
31 %       --add-to-space <units>
32 %               add the given number of 1/72" units to the width of each
33 %               space (may be negative)
34 %       --add-to-width <units>
35 %               add the given number of 1/72" units to the width of each
36 %               character (may be negative)
37 %       --columns <n>
38 %               print in <n> columns
39 %       --detect
40 %               treat the file as PostScript if it starts with %!
41 %       --first-page <n>
42 %               start printing at page <n>
43 %       --kern <file.afm>
44 %               kern using information from the given .AFM file
45 %       --last-page <n>
46 %               stop printing after page <n>
47 %       --(heading|footing)-(left|center|right) <string>
48 %               set the heading/footing fields; use -B first to clear
49 %       --margin-(top|bottom|left|right) <inches>
50 %               set a margin
51 %       --no-eject-(file|formfeed)
52 %               end-of-file/FF only starts a new column, not a new sheet
53 %       --spacing <n>
54 %               use double (n=2), triple (n=3), etc. spacing
55 % Also, the string %# in a heading or footing is replaced with the page #.
56 /PageNumberString (%#) def
57
58 /lpdict 150 dict def
59 lpdict begin
60
61 % build iso-latin-1 version of a font
62 /font-to-iso-latin-1 {  % <font> font-to-iso-latin-1 <font>
63     %% reencode for iso latin1; from the 2nd edition red book, sec 5.6.1
64     dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall
65     /Encoding ISOLatin1Encoding def currentdict end
66     dup /FontName get 80 string cvs (-ISOLatin1) concatstrings cvn 
67     exch definefont
68 } def
69
70 /find-latin-font {      % <name> find-latin-font <font>
71   findfont font-to-iso-latin-1
72 } def
73
74 % Define the initial values of the printing parameters.
75
76 /AddToSpace 0 def
77 /AddToWidth 0 def
78 /BodyFont null def              % use default
79   /defaultBodyFontPortrait
80     /Courier find-latin-font 10 scalefont def
81   /defaultBodyFontLandscape
82     /Courier find-latin-font 7 scalefont def
83   /defaultBodyFont
84     { Landscape { defaultBodyFontLandscape } { defaultBodyFontPortrait } ifelse } def
85 /Columns 1 def
86 /DetectFileType false def
87 /EjectEOF true def
88 /EjectFF true def
89 /Footers false def
90 /FootingLeft () def
91 /FootingCenter () def
92 /FootingRight () def
93 /Headers true def
94 /HeadingLeft () def
95 /HeadingCenter () def
96 /HeadingRight (page ) PageNumberString concatstrings def
97 /HeadingFont null def           % use default
98   /defaultHeadingFont
99     /Courier-Bold find-latin-font 10 scalefont def
100 /Kern 0 dict def                % no kerning
101 /Landscape false def
102 /MarginBottom 36 def            % 1/2"
103 /MarginLeft 36 def              % 1/2"
104 /MarginRight 36 def             % 1/2"
105 /MarginTop 36 def               % 1/2"
106 /MaxLines 9999 def              % max lines per page
107 /Noisy true def                 % i.e., not quiet
108 /OutFile null def               % null = write directly to device
109 /PageFirst 1 def
110 /PageLast 99999 def
111 /Spacing 1 def
112 /Tab 8 def
113 /Truncate false def             % wrap long lines, don't truncate
114
115 % When writing to a file, we want to write out PostScript;
116 % when writing to the printer, we want to execute it;
117 % some commands should be executed regardless.
118 % lpexec provides for all this.
119
120 /lpdef {        % <name> <value> lpdef -
121   /def 2 true lpexec
122 } def
123
124 /lpexec {       % <arg1> ... <argn> </op> <n> <do_always> lpexec -
125   OutFile null eq {
126     pop 1 add true
127   } {
128     /t exch def 1 add /n exch def cvx
129     n -1 roll dup wo
130     n 1 sub { n -1 roll dup wosp } repeat
131     (\n) ws n t
132   } ifelse
133     { pop load exec }
134     { { pop } repeat }
135   ifelse
136 } def
137
138 /lpmoveto {     % <x> <y> lpmoveto -
139         % Round the coordinates for smaller output.
140   2 {
141     exch 100 mul round 100 div
142     dup dup cvi eq { cvi } if
143   } repeat
144   1 index X eq { neg exch pop /V 1 } { neg /M 2 } ifelse true lpexec
145 } def
146 /lpshow {       % <string> lpshow -
147   dup length 0 ne {
148     addspace 0 ne {
149       addspace 0 32 
150       addwidth 0 ne {
151         addwidth 0 6 -1 roll /awidthshow 6 true lpexec
152       } {
153         4 -1 roll /widthshow 4 true lpexec
154       } ifelse
155     } {
156       addwidth 0 ne {
157         addwidth 0 3 -1 roll /ashow 3 true lpexec
158       } {
159         OutFile null ne {
160           dup dup length =string length gt {
161             /show 1 false lpexec
162           } {
163             (S ) ws ws (\n) ws
164           } ifelse
165         } if show 
166       } ifelse
167     } ifelse
168   } {
169     pop
170   } ifelse
171 } def
172 /lpsetmyfont {
173   dup load setfont
174    OutFile null ne { cvx /setfont 1 false lpexec } { pop } ifelse
175 } def
176
177 % Define some utility procedures.
178
179 /banner         % ypos left center right
180  { /HFont lpsetmyfont
181    /addspace 0 def /addwidth 0 def
182    /pairkern 0 dict def
183    3 -1 roll bannerstring pop 0 4 index pwidth showline2 pop
184    exch bannerstring pwidth exch sub 2 div 3 index pwidth showline2 pop
185    bannerstring
186                 % Prevent the last character of the heading from grazing
187                 % the right margin.
188                 % ****** WHY DOES IT REQUIRE SO MUCH PADDING? ******
189    ( ) stringwidth pop 2 mul add
190    pwidth exch sub
191    3 -1 roll pwidth showline2 pop
192  } def
193
194 /bannerstring   % string -> string width
195   { PageNumberString search
196      { exch pop pindex 4 string cvs concatstrings exch concatstrings
197      }
198     if dup stringwidth pop
199   } def
200
201 /beginpage
202  { /lindex 0 def
203    /skipping pindex PageFirst ge pindex PageLast le and not def
204    pagex pagey Landscape {/BL} {/B} ifelse 2 true lpexec
205    /pagesave exch def
206    skipping { nulldevice   /OutFile null def } if
207    Headers
208     { lheight hdescent add
209       HeadingLeft HeadingCenter HeadingRight banner
210     } if
211    /BFont lpsetmyfont
212    /pairkern Kern def
213    /addspace AddToSpace def /addwidth AddToWidth def
214    pairkern length 0 ne {
215      /addspace AddToSpace lpdef /addwidth AddToWidth lpdef
216    } if
217  } def
218
219 /endpage {
220   lindex 0 ne {
221     Footers {
222       topskip plength sub hdescent add
223       FootingLeft FootingCenter FootingRight banner
224     } if
225     /E
226   } {
227     /restore
228   } ifelse
229   pagesave exch 0 true lpexec
230   /pindex pindex 1 add def
231 } def
232
233 /endcolumn
234  { lindex colines 1 sub add colines idiv colines mul
235    dup llength ge { pop endpage beginpage } { /lindex exch def } ifelse
236  } def
237
238 /fontheight     % <font> fontheight <ascent> <height>
239  { gsave setfont
240    newpath 0 0 moveto
241    (|^_j) false charpath
242    pathbbox exch pop dup 2 index sub 4 -2 roll pop pop
243    grestore exch 1.25 mul exch 1.25 mul
244  } def
245
246 /wdict {
247   dup length wosp ( dict\n) ws
248   { (dup) ws exch wosp wosp ( put\n) ws } forall
249 } def
250 /wosp { ( ) ws wo } def
251 /wo {
252   dup type /dicttype eq { wdict } { OutFile exch write==only } ifelse
253 } def
254 /ws {
255   OutFile exch writestring
256 } def
257
258 /outfont {              % <name> <font> outfont -
259   OutFile null ne {
260     exch wo
261     dup /FontName get 
262     dup wosp (-ISOLatin1) ws wosp ( RE) ws
263     /FontMatrix get 0 get 1000 mul round cvi wosp
264     ( scalefont def\n) ws
265   } {
266     pop pop
267   }ifelse
268 } def
269
270 /StringFF (\f) def
271 /CharFF StringFF 0 get def
272 /StringTAB (\t) def
273 /CharTAB StringTAB 0 get def
274
275 /showline               % line -> leftover_line (handles \f)
276  {  { showline1 dup length 0 eq { exit } if
277       dup 0 get CharFF ne { exit } if
278       EjectFF { endpage beginpage } { endcolumn } ifelse
279       skip1
280     }
281    loop
282  } def
283
284 /showline1              % line -> leftover_line (handles page break)
285  { lindex llength eq { endpage beginpage } if
286    lindex colines idiv cowidth mul              % x
287    lindex colines mod 1 add lheight mul neg fascent sub % y
288    1 index cowidth add
289    showline2
290    /lindex lindex 1 add def
291  } def
292
293 /setxy {
294   /ty exch def /tx exch def
295 } def
296
297 /showline2 {    % string x y xlimit -> leftover_string (handles tabs)
298   2 index exch 5 2 roll setxy {
299                 % Stack: xinit xlimit string
300     showline3 dup length 0 eq { exit } if
301     dup 0 get CharTAB ne { exit } if
302     tx 3 index sub tabwx div
303       0.05 add ceiling tabwx mul 3 index add ty setxy
304     skip1
305     tx 2 index ge { exit } if
306   } loop exch pop exch pop
307 } def
308
309 /showline3 {    % xlimit string -> xlimit leftover_string
310                 % (finds line break / tab / formfeed)
311   1 index tx sub
312     cwx div 0.1 add cvi 0 .max 1 index length .min
313   1 index 0 3 -1 roll getinterval
314         % look for \f or \t
315   StringFF search { exch pop exch pop } if
316   StringTAB search { exch pop exch pop } if
317   dup length 0 ne {
318     tx ty lpmoveto
319     dup pairkern length 0 eq {
320       lpshow
321     } {
322       { kproc } exch /kshow 2 true lpexec
323     } ifelse
324     currentpoint setxy
325   } if
326   length dup 2 index length exch sub getinterval
327 } def
328
329 /kproc {        % <char1> <char2> kproc -
330   pairkern currentfont /Encoding get 3 index get
331   2 copy known {
332     get currentfont /Encoding get 2 index get
333     2 copy known {
334       get currentfont /FontMatrix get 0 get mul
335     } {
336       pop pop 0
337     } ifelse
338   } {
339     pop pop 0
340   } ifelse
341   addwidth add 2 index 32 eq { addspace add } if
342   dup 0 eq { pop } { 0 rmoveto } ifelse
343   pop pop
344 } def
345
346 /skip1
347  { dup length 1 sub 1 exch getinterval
348  } def
349
350 /e== {          % <object> e== - -- print an object to stderr
351   (%stderr) (w) file dup 3 -1 roll write==only flushfile
352 } def
353
354 /eprint {       % <string> eprint - -- print a string to stderr
355   (%stderr) (w) file dup 3 -1 roll writestring flushfile
356 } def
357
358 % Read kerning information from a .AFM file.
359
360 /readkern {     % <afmfile> readkern <pairkerndict>
361   /mfilename 1 index def
362   (r) file /mfile exch def
363   mfile =string readline pop
364   (StartFontMetrics ) anchorsearch {
365     pop pop
366     /kdict 256 dict def
367     { mfile =string readline pop
368       (EndFontMetrics) anchorsearch { pop pop exit } if
369       (KPX ) anchorsearch {
370         pop token pop cvlit /char1 exch def
371         token pop cvlit /char2 exch def
372         token pop /kern exch def pop
373         kdict char1 .knownget not {
374           5 dict kdict char1 2 index .growput
375         } if
376         char2 kern .growput
377       } {
378         pop
379       } ifelse
380     } loop kdict
381   } {
382     pop
383     mfilename eprint ( does not begin with StartFontMetrics.\n) eprint
384     0 dict
385   } ifelse
386   mfile closefile
387 } def
388
389 % The main printing procedure
390
391 /doFirst true def
392 /prevBFont null def
393 /prevHFont null def
394
395 /lpfirst {      % - lpfirst -
396 % Define some abbreviating procedures.
397   /B {save 3 1 roll translate /X 0 def} lpdef
398   /BL {save 3 1 roll 90 rotate translate /X 0 def} lpdef
399   /E {showpage restore} lpdef
400   /V {neg X exch moveto} lpdef
401   /M {/X 2 index def neg moveto} lpdef
402   /S {currentfile =string readline pop show} lpdef
403   /RE {         % <isoname> <fontname> RE <font>
404     findfont
405         %% reencode for iso latin1; from the 2nd edition red book, sec 5.6.1
406     dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall
407     /Encoding ISOLatin1Encoding def currentdict end
408     definefont
409   } lpdef
410 } def
411
412 /lp {           % file initial_chars ->
413   /lpline exch def
414   /lpfile exch def
415
416   doFirst { lpfirst /doFirst false def } if
417
418 % Initialize the device and fonts.
419   /BFont
420     BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def
421   BFont prevBFont ne {
422     /BFont BFont outfont
423     /prevBFont BFont def
424   } if
425   Headers Footers or {
426     /HFont
427       HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def
428     HFont prevHFont ne {
429       /HFont HFont outfont
430       /prevHFont HFont def
431     } if
432   } if
433   save
434
435 % Get the layout parameters.
436    clippath
437    gsave        % for possible rotation
438    Landscape { 90 rotate } if
439    BFont setfont ( ) stringwidth pop /cwx exch def
440      cwx Tab mul /tabwx exch def
441    BFont fontheight /fheight exch def /fascent exch def
442    Headers Footers or { HFont fontheight } { 0 0 } ifelse
443      /hheight exch def /hascent exch def
444      /hdescent hheight hascent sub def
445    fheight Spacing mul /lheight exch def
446    Headers { hheight lheight add } { 0 } ifelse
447      /topskip exch def
448    Footers { hheight lheight add } { 0 } ifelse
449      /botskip exch def
450    /pskip topskip botskip add def
451         % Translate the page so that (0,0) corresponds to
452         % the top of the topmost body line.
453    pathbbox
454      2 index sub MarginBottom MarginTop add sub /plength exch def
455      2 index sub MarginLeft MarginRight add sub /pwidth exch def
456      pwidth Columns div /cowidth exch def
457      exch MarginLeft add
458      exch MarginBottom add plength add topskip sub
459      /pagey exch def /pagex exch def
460    plength pskip sub lheight div cvi MaxLines .min
461      dup /colines exch def
462      Columns mul /llength exch def
463    grestore
464    OutFile null ne { nulldevice } if
465
466 % Print layout
467    Noisy
468     { (Page height = ) eprint llength e==
469       (.\n) eprint flush
470     } if
471
472 % Write the kerning table, if relevant.
473    OutFile null ne Kern length 0 ne and {
474      (/kproc) ws /kproc load wosp ( def\n) ws
475      (/pairkern) ws Kern wosp ( def\n) ws
476    } if
477
478 % Disable stack recording so we can use stopped with readline.
479    $error /recordstacks false put
480
481 % Initialize for the first page.
482    /lbuf 64000 string def
483    /pindex 1 def
484    beginpage
485
486 % Iterate through the file.
487    lpline
488     { dup length /pos exch def
489       lbuf exch 0 exch putinterval
490        { lpfile lbuf pos lbuf length pos sub getinterval readline } stopped
491        {        % Filled the line before a CR or EOF.
492          exch pop showline
493        }
494        {        % Reached CR and/or EOF first.
495          exch length pos add lbuf exch 0 exch getinterval
496          1 index { showline } if                % omit final empty line
497           { dup length 0 eq Truncate or { pop () exit } if
498             showline
499           }
500          loop
501          exch not { exit } if
502        }
503       ifelse
504       pindex PageLast gt { exit } if
505     } loop
506    pop
507
508 % Wrap up.
509 %**************** WHY IS THIS COMMENTED OUT? ****************
510 %   EjectEOF { endpage } { endcolumn } ifelse
511    endpage
512    restore
513
514 } def
515
516 end
517
518 % Usage: <file> lp
519 %   prints <file> using the current parameter settings.
520 % Usage: [ <arg1> ... <argn> ] lpcommand
521 %   interprets args like a command line.
522
523 /lp { save   lpdict begin () lp end   restore } def
524
525 lpdict begin
526
527 /splitfn                % (FontNN.NN) -> <font>
528  { dup /arg exch def length
529     { dup 0 le { exit } if
530       dup 1 sub arg exch get dup 48 ge 1 index 59 le and exch 46 eq or not { exit } if
531       1 sub
532     } loop
533    arg exch 0 exch getinterval dup cvn find-latin-font
534    exch arg exch anchorsearch pop pop cvr scalefont
535  } def
536
537 % Parse the command line switches.
538
539 /doswitch       % argn ... arg1 (-?) restofswitch ->
540  { exch dup cvn lpdict exch known
541     { cvn load exec }
542     { exch pop (Unknown switch: ) eprint eprint (\n) eprint }
543    ifelse
544  } def
545
546 /more           % argn ... arg1 restofswitch ->
547  { dup length 0 ne
548     { (- ) dup 1 3 index 0 get put
549       exch dup length 1 sub 1 exch getinterval
550       doswitch
551     }
552     { pop
553     }
554    ifelse
555  } def
556
557 /-- { (--) exch concatstrings
558       dup cvn lpdict exch known
559        { cvn load exec }
560        { (Unknown switch: ) eprint eprint (\n) eprint }
561       ifelse
562     } def
563 /--add-to-space { cvr /AddToSpace exch def } def
564 /--add-to-width { cvr /AddToWidth exch def } def
565 /--columns { cvi 1 .max /Columns exch def } def
566 /--detect { /DetectFileType true def } def
567 /--first-page { cvi /PageFirst exch def } def
568 /--footing-center { /FootingCenter exch def   /Footers true def } def
569 /--footing-left { /FootingLeft exch def   /Footers true def } def
570 /--footing-right { /FootingRight exch def   /Footers true def} def
571 /--heading-center { /HeadingCenter exch def   /Headers true def } def
572 /--heading-left { /HeadingLeft exch def   /Headers true def } def
573 /--heading-right { /HeadingRight exch def   /Headers true def } def
574 /--kern { readkern /Kern exch def } def
575 /--last-page { cvi /PageLast exch def } def
576 /--margin-bottom { cvr 72.0 mul /MarginBottom exch def } def
577 /--margin-left { cvr 72.0 mul /MarginLeft exch def } def
578 /--margin-right { cvr 72.0 mul /MarginRight exch def } def
579 /--margin-top { cvr 72.0 mul /MarginTop exch def } def
580 /--no-eject-file { /EjectEOF false def } def
581 /--no-eject-formfeed { /EjectFF false def } def
582 /--spacing { cvr /Spacing exch def } def
583
584 /-# { pop } def         % ignore
585 /-+ { -- } def
586 (-1)cvn { /Columns 1 def   more } def
587 (-2)cvn { /Columns 2 def   more } def
588 /-b { /HeadingLeft exch def   /HeadingCenter () def   /HeadingRight PageNumberString def
589       /Headers true def
590       /break true def
591     } def
592 /-B { /HeadingLeft () def   /HeadingCenter () def   /HeadingRight () def
593       /Headers false def
594       /FootingLeft () def   /FootingCenter () def   /FootingRight () def
595       /Footers false def
596       /break true def
597       more
598     } def
599 /-C { pop } def         % ignore
600 /-c { /Truncate true def   more } def
601 /-d { pop } def         % ignore
602 /-f { splitfn /BodyFont exch def } def
603 /-F { splitfn /HeadingFont exch def } def
604 /-G { more } def        % ignore
605 /-g { more } def        % ignore
606 /-h { more } def        % ignore
607 /-J { pop } def         % ignore
608 /-K { more } def        % ignore
609 /-k { more } def        % ignore
610 /-l { 66 -L -B } def
611 /-L { cvi /MaxLines exch def } def
612 /-m { more } def        % ignore
613 /-n { pop } def         % ignore
614 /-o { more } def        % ignore
615 /-p { (w) file /OutFile exch def   OutFile (%!\n) writestring } def
616 /-P { pop } def         % ignore
617 /-q { /Noisy false def   more } def
618 /-r { /Landscape true def   more } def
619 /-R { /Landscape false def   more } def
620 /-S { pop } def         % ignore
621 /-s { pop } def         % ignore
622 /-T { cvi /Tab exch def } def
623 /-v { pop } def         % ignore
624 /-w { more } def        % ignore
625
626 /lp1            % filename ->
627  { break not { dup /HeadingLeft exch def } if
628    Noisy
629     { (Printing ) eprint dup eprint (\n) eprint 
630     } if
631    (r) file
632                 % If requested, check for a PostScript file.
633    DetectFileType
634     { dup 2 string readstring pop dup (%!) eq
635        {        % Yes, it's a PostScript file.
636          pop dup 80 string readline pop pop cvx exec
637        }
638        { lp
639        }
640       ifelse
641     }
642     { () lp
643     }
644    ifelse
645  } bind def
646
647 /lpcstring 8192 string def
648
649 end
650
651 /lpcommand              % <[arg1 ... argn]> lpcommand <any_printed>
652  {      % Push the commands on the stack in reverse order
653    mark exch
654    dup length 1 sub -1 0 { 1 index exch get exch } for pop
655    lpdict begin
656    /any false def
657    /break false def
658     { dup mark eq { pop exit } if
659       dup length 2 ge { dup 0 get (-) 0 get eq } { false } ifelse
660        { dup 0 2 getinterval
661          exch dup length 2 sub 2 exch getinterval
662          doswitch
663        }
664        { dup  /matched false def
665           { /matched true def   /any true def   lp1 } lpcstring filenameforall
666          matched { pop } { lp1 } ifelse         % let the error happen
667        }
668       ifelse
669     } loop
670    OutFile null ne
671     { OutFile (%stdout) (w) file ne { OutFile closefile } if
672       /OutFile null def
673     } if
674    any
675    end
676  } def
677
678 [ shellarguments
679  { ] dup length 0 ne { lpcommand } { false } ifelse not
680     { (%stderr) (w) file
681       [ (Usage: )
682         /PROGNAME where { pop PROGNAME } { (gslp) } ifelse
683         ( [-12BclqRr] [-b<header>] [-f<font>] [-F<hfont>]\n)
684         (        [-L<lines>] [-p<outfile>] [-T<tabwidth>]\n)
685         (        [--add-to-(space|width) <units>] [--columns <n>]\n)
686         (        [--detect] [--first-page <page#>] [--last-page <page#>]\n)
687         (        [--(heading|footing)-(left|right|center) <string>]\n)
688         (        [--kern <afmfile>] [--margin-(top|bottom|left|right) <inches>]\n)
689         (        [--no-eject-(file|formfeed)] [--spacing <n>] file1 ... filen\n)
690       ] { 2 copy writestring pop } forall dup flushfile closefile
691     }
692    if
693  }
694  { pop }
695 ifelse