You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

760 lines
22 KiB

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