home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / inne / gs300ini / gslp.ps < prev    next >
Encoding:
Text File  |  1994-08-02  |  14.0 KB  |  484 lines

  1. %    Copyright (C) 1991, 1993 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % gslp.ps - format and print text
  16.  
  17. % This utility provides functionality approximately equivalent to the Unix
  18. % `enscript' program.  It prints plain text files using a single font.
  19. % It currently handles tabs and formfeeds, but not backspaces.
  20. % It only works with fixed-pitch fonts.
  21. % Standard flags implemented:
  22. %    -12BclqRr -b -f -F -L -p
  23. % Sun flags implemented:
  24. %    -T<n>    set tab width
  25. % Flags ignored:
  26. %    -GghKkmow -# -C -d -J -n -P -S -s -t -v
  27. % Flags added:
  28. %    --detect
  29. %        treats the file as PostScript if it starts with %!
  30. %    --(heading|footing)-(left|center|right) <string>
  31. %        sets the heading/footing fields; use -B first to clear
  32. %    --first-page <n>
  33. %        sets the first page to print
  34. %    --last-page <n>
  35. %        sets the last page to print
  36. %    --spacing <n>
  37. %        for double (n=2), triple (n=3), etc. spacing
  38. % Also, the string %# in a heading or footing is replaced with the page #.
  39. /PageNumberString (%#) def
  40.  
  41. /lpdict 150 dict def
  42. lpdict begin
  43.  
  44. % Define the initial values of the printing parameters.
  45.  
  46. /BodyFont null def        % use default
  47.   /defaultBodyFont
  48.     { /Courier findfont Landscape { 7 } { 10 } ifelse scalefont } def
  49. /Columns 1 def
  50. /DetectFileType false def
  51. /Footers false def
  52. /FootingLeft () def
  53. /FootingCenter () def
  54. /FootingRight () def
  55. /Headers true def
  56. /HeadingLeft () def
  57. /HeadingCenter () def
  58. /HeadingRight (page ) PageNumberString concatstrings def
  59. /HeadingFont null def        % use default
  60.   /defaultHeadingFont
  61.     { /Courier-Bold findfont 10 scalefont } def
  62. /Landscape false def
  63. /MarginBottom 36 def        % 1/2"
  64. /MarginLeft 36 def        % 1/2"
  65. /MarginRight 36 def        % 1/2"
  66. /MarginTop 36 def        % 1/2"
  67. /MaxLines 9999 def        % max lines per page
  68. /Noisy true def            % i.e., not quiet
  69. /OutFile null def        % null = write directly to device
  70. /PageFirst 1 def
  71. /PageLast 99999 def
  72. /Spacing 1 def
  73. /Tab 8 def
  74. /Truncate false def        % wrap long lines, don't truncate
  75.  
  76. % When writing to a file, we want to write out PostScript;
  77. % when writing to the printer, we want to execute it;
  78. % some commands should be executed regardless.
  79. % lpexec provides for all this.
  80.  
  81. /lpexec        % <arg1> ... <argn> </op> <n> <do_always> lpexec -
  82.  { OutFile null eq
  83.     { pop 1 add true
  84.     }
  85.     { /t exch def 1 add /n exch def cvx
  86.       n { n -1 roll dup wosp } repeat
  87.       OutFile (\n) writestring
  88.       n t
  89.     }
  90.    ifelse
  91.     { pop load exec }
  92.     { { pop } repeat }
  93.    ifelse
  94.  } def
  95.  
  96. /lpmoveto
  97.  { /moveto 2 true lpexec
  98.  } def
  99. /lpshow
  100.  { dup length 0 ne { /show 1 false lpexec } { pop } ifelse
  101.  } def
  102. /lpsetmyfont
  103.  { dup load setfont
  104.    OutFile null ne { cvx /setfont 1 false lpexec } { pop } ifelse
  105.  } def
  106.  
  107. % Define some utility procedures.
  108.  
  109. /banner        % ypos left center right
  110.  { /HFont lpsetmyfont
  111.    3 -1 roll bannerstring pop 0 4 index pwidth showline2 pop
  112.    exch bannerstring pwidth exch sub 2 div 3 index pwidth showline2 pop
  113.    bannerstring pwidth exch sub
  114.    3 -1 roll pwidth showline2 pop
  115.  } def
  116.  
  117. /bannerstring    % string -> string width
  118.   { PageNumberString search
  119.      { exch pop pindex 4 string cvs concatstrings exch concatstrings
  120.      }
  121.     if dup stringwidth pop
  122.   } def
  123.  
  124. /beginpage
  125.  { /lindex 0 def
  126.    /skipping pindex PageFirst ge pindex PageLast le and not def
  127.    /save 0 true lpexec /pagesave exch def
  128.    skipping { nulldevice   /OutFile null def } if
  129.    Headers
  130.     { lheight hdescent add
  131.       HeadingLeft HeadingCenter HeadingRight banner
  132.     } if
  133.    /BFont lpsetmyfont
  134.  } def
  135.  
  136. /endpage
  137.  { lindex 0 ne
  138.     { Footers
  139.        { topskip plength sub hdescent add
  140.          FootingLeft FootingCenter FootingRight banner
  141.        } if
  142.       /showpage 0 false lpexec
  143.     } if
  144.    pagesave /restore 0 true lpexec
  145.    /pindex pindex 1 add def
  146.  } def
  147.  
  148. /fontheight    % <font> fontheight <ascent> <height>
  149.  { gsave setfont
  150.    newpath 0 0 moveto
  151.    (|^_j) false charpath
  152.    pathbbox exch pop dup 2 index sub 4 -2 roll pop pop
  153.    grestore exch 1.25 mul exch 1.25 mul
  154.  } def
  155.  
  156. /wosp
  157.  { OutFile ( ) writestring OutFile exch write==only
  158.  } def
  159.  
  160. /outfont        % name font ->
  161.  { OutFile null ne
  162.     { exch wosp
  163.       dup /FontName get wosp OutFile ( findfont) writestring
  164.       /FontMatrix get 0 get 1000 mul round cvi wosp
  165.       OutFile ( scalefont def\n) writestring
  166.     }
  167.     { pop pop
  168.     }
  169.    ifelse
  170.  } def
  171.  
  172. /StringFF (\f) def
  173. /CharFF StringFF 0 get def
  174. /StringTAB (\t) def
  175. /CharTAB StringTAB 0 get def
  176.  
  177. /showline        % line -> leftover_line (handles \f)
  178.  {  { showline1 dup length 0 eq { exit } if
  179.       dup 0 get CharFF ne { exit } if
  180.       endpage beginpage
  181.       skip1
  182.     }
  183.    loop
  184.  } def
  185.  
  186. /showline1        % line -> leftover_line (handles page break)
  187.  { lindex llength eq { endpage beginpage } if
  188.    lindex colines idiv cowidth mul        % x
  189.    lindex colines mod 1 add lheight mul neg fascent sub    % y
  190.    1 index cowidth add
  191.    showline2
  192.    /lindex lindex 1 add def
  193.  } def
  194.  
  195. /showline2    % string x y xlimit -> leftover_string (handles tabs)
  196.  { 2 index exch 5 2 roll lpmoveto    % xinit xlimit string
  197.     { showline3 dup length 0 eq { exit } if
  198.       dup 0 get CharTAB ne { exit } if
  199.       currentpoint exch 4 index sub tabwx div
  200.     0.05 add ceiling tabwx mul 4 index add exch lpmoveto
  201.       skip1
  202.       currentpoint pop 2 index ge { exit } if
  203.     }
  204.    loop exch pop exch pop
  205.  } def
  206.  
  207. /showline3    % xlimit string -> xlimit leftover_string
  208.         % (finds line break / tab / formfeed)
  209.  { currentpoint pop 2 index exch sub
  210.      cwx div 0.1 add cvi 0 max 1 index length min
  211.    1 index 0 3 -1 roll getinterval
  212.     % look for \f or \t
  213.    StringFF search { exch pop exch pop } if
  214.    StringTAB search { exch pop exch pop } if
  215.    dup lpshow
  216.    length dup 2 index length exch sub getinterval
  217.  } def
  218.  
  219. /skip1
  220.  { dup length 1 sub 1 exch getinterval
  221.  } def
  222.  
  223. % The main printing procedure
  224.  
  225. /lp        % file initial_chars ->
  226.  { /lpline exch def
  227.    /lpfile exch def
  228.    /save 0 true lpexec
  229.  
  230. % Initialize the device and fonts.
  231.    /BFont
  232.      BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def
  233.    /BFont BFont outfont
  234.    Headers Footers or
  235.     { /HFont
  236.     HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def
  237.       /HFont HFont outfont
  238.     }
  239.    if
  240.  
  241. % Get the layout parameters.
  242.    clippath
  243.    Landscape { -90 /rotate 1 true lpexec } if
  244.    BFont setfont ( ) stringwidth pop /cwx exch def
  245.      cwx Tab mul /tabwx exch def
  246.    BFont fontheight /fheight exch def /fascent exch def
  247.    Headers Footers or { HFont fontheight } { 0 0 } ifelse
  248.      /hheight exch def /hascent exch def
  249.      /hdescent hheight hascent sub def
  250.    fheight Spacing mul /lheight exch def
  251.    Headers { hheight lheight add } { 0 } ifelse
  252.      /topskip exch def
  253.    Footers { hheight lheight add } { 0 } ifelse
  254.      /botskip exch def
  255.    /pskip topskip botskip add def
  256.     % Translate the page so that (0,0) corresponds to
  257.     % the top of the topmost body line.
  258.    pathbbox
  259.      2 index sub MarginBottom MarginTop add sub /plength exch def
  260.      2 index sub MarginLeft MarginRight add sub /pwidth exch def
  261.      pwidth Columns div /cowidth exch def
  262.      exch MarginLeft add
  263.      exch MarginBottom add plength add topskip sub
  264.      /translate 2 true lpexec
  265.    plength pskip sub lheight div cvi MaxLines min
  266.      dup /colines exch def
  267.      Columns mul /llength exch def
  268.    OutFile null ne { nulldevice } if
  269.  
  270. % Print layout
  271.    Noisy
  272.     { (Page height = ) print llength =only
  273.       (.\n) print flush
  274.     } if
  275.  
  276. % Disable stack recording so we can use stopped with readline.
  277.    $error /recordstacks false put
  278.  
  279. % Initialize for the first page.
  280.    /lbuf 1000 string def
  281.    /pindex 1 def
  282.    beginpage
  283.  
  284. % Iterate through the file.
  285.    lpline
  286.     { dup length /pos exch def
  287.       lbuf exch 0 exch putinterval
  288.        { lpfile lbuf pos lbuf length pos sub getinterval readline } stopped
  289.        {    % Filled the line before a CR or EOF.
  290.          exch pop showline
  291.        }
  292.        {    % Reached CR and/or EOF first.
  293.          exch length pos add lbuf exch 0 exch getinterval
  294.      1 index { showline } if        % omit final empty line
  295.       { dup length 0 eq Truncate or { pop () exit } if
  296.         showline
  297.       }
  298.      loop
  299.      exch not { exit } if
  300.        }
  301.       ifelse
  302.     } loop
  303.    pop
  304.  
  305. % Wrap up.
  306.    endpage
  307.    /restore 0 true lpexec
  308.  
  309.  } def
  310.  
  311. end
  312.  
  313. % Usage: <file> lp
  314. %   prints <file> using the current parameter settings.
  315. % Usage: [ <arg1> ... <argn> ] lpcommand
  316. %   interprets args like a command line.
  317.  
  318. /lp { save   lpdict begin () lp end   restore } def
  319.  
  320. lpdict begin
  321.  
  322. /splitfn        % (FontNNN) -> <font>
  323.  { dup /arg exch def length
  324.     { dup 0 le { exit } if
  325.       dup 1 sub arg exch get dup 48 ge exch 59 le and not { exit } if
  326.       1 sub
  327.     } loop
  328.    arg exch 0 exch getinterval dup cvn findfont
  329.    exch arg exch anchorsearch pop pop cvr scalefont
  330.  } def
  331.  
  332. % Parse the command line switches.
  333.  
  334. /doswitch    % argn ... arg1 (-?) restofswitch ->
  335.  { exch dup cvn lpdict exch known
  336.     { cvn load exec }
  337.     { exch pop (Unknown switch: ) print print (\n) print flush }
  338.    ifelse
  339.  } def
  340.  
  341. /more        % argn ... arg1 restofswitch ->
  342.  { dup length 0 ne
  343.     { (- ) dup 1 3 index 0 get put
  344.       exch dup length 1 sub 1 exch getinterval
  345.       doswitch
  346.     }
  347.     { pop
  348.     }
  349.    ifelse
  350.  } def
  351.  
  352. /-- { (--) exch concatstrings
  353.       dup cvn lpdict exch known
  354.        { cvn load exec }
  355.        { (Unknown switch: ) print print (\n) print flush }
  356.       ifelse
  357.     } def
  358. /--columns { cvi 1 max /Columns exch def } def
  359. /--detect { /DetectFileType true def } def
  360. /--first-page { cvi /PageFirst exch def } def
  361. /--footing-center { /FootingCenter exch def   /Footers true def } def
  362. /--footing-left { /FootingLeft exch def   /Footers true def } def
  363. /--footing-right { /FootingRight exch def   /Footers true def} def
  364. /--heading-center { /HeadingCenter exch def   /Headers true def } def
  365. /--heading-left { /HeadingLeft exch def   /Headers true def } def
  366. /--heading-right { /HeadingRight exch def   /Headers true def } def
  367. /--margin-bottom { cvr 72.0 mul /MarginBottom exch def } def
  368. /--margin-left { cvr 72.0 mul /MarginLeft exch def } def
  369. /--margin-right { cvr 72.0 mul /MarginRight exch def } def
  370. /--margin-top { cvr 72.0 mul /MarginTop exch def } def
  371. /--last-page { cvi /PageLast exch def } def
  372. /--spacing { cvr /Spacing exch def } def
  373.  
  374. /-# { pop } def        % ignore
  375. /-+ { -- } def
  376. (-1)cvn { /Columns 1 def   more } def
  377. (-2)cvn { /Columns 2 def   more } def
  378. /-b { /HeadingLeft exch def   /HeadingCenter () def   /HeadingRight PageNumberString def
  379.       /Headers true def
  380.       /break true def
  381.     } def
  382. /-B { /HeadingLeft () def   /HeadingCenter () def   /HeadingRight () def
  383.       /Headers false def
  384.       /FootingLeft () def   /FootingCenter () def   /FootingRight () def
  385.       /Footers false def
  386.       /break true def
  387.       more
  388.     } def
  389. /-C { pop } def        % ignore
  390. /-c { /Truncate true def   more } def
  391. /-d { pop } def        % ignore
  392. /-f { splitfn /BodyFont exch def } def
  393. /-F { splitfn /HeadingFont exch def } def
  394. /-G { more } def    % ignore
  395. /-g { more } def    % ignore
  396. /-h { more } def    % ignore
  397. /-J { pop } def        % ignore
  398. /-K { more } def    % ignore
  399. /-k { more } def    % ignore
  400. /-l { 66 -L -B } def
  401. /-L { cvi /MaxLines exch def } def
  402. /-m { more } def    % ignore
  403. /-n { pop } def        % ignore
  404. /-o { more } def    % ignore
  405. /-p { (w) file /OutFile exch def   OutFile (%!\n) writestring } def
  406. /-P { pop } def        % ignore
  407. /-q { /Noisy false def   more } def
  408. /-r { /Landscape true def   more } def
  409. /-R { /Landscape false def   more } def
  410. /-S { pop } def        % ignore
  411. /-s { pop } def        % ignore
  412. /-T { cvi /Tab exch def } def
  413. /-v { pop } def        % ignore
  414. /-w { more } def    % ignore
  415.  
  416. /lp1        % filename ->
  417.  { break not { dup /HeadingLeft exch def } if
  418.    Noisy
  419.     { (Printing ) print dup print (\n) print flush
  420.     } if
  421.    (r) file
  422.         % If requested, check for a PostScript file.
  423.    DetectFileType
  424.     { dup 2 string readstring pop dup (%!) eq
  425.        {    % Yes, it's a PostScript file.
  426.          pop dup 80 string readline pop pop cvx exec
  427.        }
  428.        { lp
  429.        }
  430.       ifelse
  431.     }
  432.     { () lp
  433.     }
  434.    ifelse
  435.  } bind def
  436.  
  437. /lpcstring 100 string def
  438.  
  439. end
  440.  
  441. /lpcommand        % [arg1 ... argn] -> -
  442.  {    % Push the commands on the stack in reverse order
  443.    mark exch
  444.    dup length 1 sub -1 0 { 1 index exch get exch } for pop
  445.    lpdict begin
  446.    /break false def
  447.     { dup mark eq { pop exit } if
  448.       dup length 2 ge { dup 0 get (-) 0 get eq } { false } ifelse
  449.        { dup 0 2 getinterval
  450.          exch dup length 2 sub 2 exch getinterval
  451.      doswitch
  452.        }
  453.        { dup  /matched false def
  454.           { /matched true def    lp1 } lpcstring filenameforall
  455.      matched { pop } { lp1 } ifelse        % let the error happen
  456.        }
  457.       ifelse
  458.     } loop
  459.    OutFile null ne
  460.     { OutFile (%stdout) (w) file ne { OutFile closefile } if
  461.       /OutFile null def
  462.     } if
  463.    end
  464.  } def
  465.  
  466. [ shellarguments
  467.  { ] dup length 0 ne
  468.     { lpcommand
  469.     }
  470.     { (Usage: gslp [-12BclqRr] [-b<header] [-f<font>] [-F<hfont>]\n) print
  471.       (        [-L<lines>] [-p<outfile>] [-T<tabwidth>] [--columns <n>]\n) print
  472.       (        [--detect] [--first-page <page#>] [--last-page <page#>]\n) print
  473.       (        [--(heading|footing)-(left|right|center) <string>]\n) print
  474.       (        [--margin-(top|bottom|left|right) <inches>]\n) print
  475.       (        [--spacing <n>] file1 ... filen\n) print flush
  476.     }
  477.    ifelse
  478.  }
  479.  { pop }
  480. ifelse
  481.