Commit | Line | Data |
---|---|---|
502dfc8b WJ |
1 | % Copyright (C) 1991 Aladdin Enterprises. All rights reserved. |
2 | % Distributed by Free Software Foundation, Inc. | |
3 | % | |
4 | % This file is part of Ghostscript. | |
5 | % | |
6 | % Ghostscript is distributed in the hope that it will be useful, but | |
7 | % WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | % to anyone for the consequences of using it or for whether it serves any | |
9 | % particular purpose or works at all, unless he says so in writing. Refer | |
10 | % to the Ghostscript General Public License for full details. | |
11 | % | |
12 | % Everyone is granted permission to copy, modify and redistribute | |
13 | % Ghostscript, but only under the conditions described in the Ghostscript | |
14 | % General Public License. A copy of this license is supposed to have been | |
15 | % given to you along with Ghostscript so you can know your rights and | |
16 | % responsibilities. It should be in a file named COPYING. Among other | |
17 | % things, the copyright notice and this notice must be preserved on all | |
18 | % copies. | |
19 | ||
20 | % gslp.ps - format and print text | |
21 | ||
22 | % This utility provides functionality approximately equivalent to the Unix | |
23 | % `enscript' program. It prints plain text files using a single font. | |
24 | % It currently handles tabs and formfeeds, but not backspaces. | |
25 | % Currently it neither truncates nor wraps over-length lines. | |
26 | % It only works with fixed-pitch fonts. | |
27 | % Flags implemented: -12BclrR -b -f -F -L -p | |
28 | % Flags added: | |
29 | % -T<n> for defining the tab width | |
30 | % -P<n> for setting the first page to print | |
31 | % -Q<n> for setting the last page to print | |
32 | ||
33 | /lpdict 80 dict def | |
34 | lpdict begin | |
35 | ||
36 | % Define the initial values of the printing parameters. | |
37 | ||
38 | /BodyFont null def % use default | |
39 | /defaultBodyFont | |
40 | { /Courier findfont Landscape { 7 } { 10 } ifelse scalefont } def | |
41 | /Columns 1 def | |
42 | /Headers true def | |
43 | /HeadingLeft () def | |
44 | /HeadingCenter () def | |
45 | /HeadingRight null def % use page # | |
46 | /HeadingFont null def % use default | |
47 | /defaultHeadingFont | |
48 | { /Courier-Bold findfont 10 scalefont } def | |
49 | /MaxLines 9999 def % max lines per page | |
50 | /Landscape false def | |
51 | /OutFile null def % null = write directly to device | |
52 | /PageFirst 1 def | |
53 | /PageLast 99999 def | |
54 | /Tab 8 def | |
55 | /Truncate false def % wrap long lines, don't truncate | |
56 | ||
57 | % When writing to a file, we want to write out PostScript; | |
58 | % when writing to the printer, we want to execute it; | |
59 | % some commands should be executed regardless. | |
60 | % lpexec provides for all this. | |
61 | ||
62 | /lpexec % arg1...argn /op n do_always lpexec -> | |
63 | { OutFile null eq | |
64 | { pop 1 add true | |
65 | } | |
66 | { /t exch def 1 add /n exch def cvx | |
67 | n { n -1 roll dup wosp } repeat | |
68 | OutFile (\n) writestring | |
69 | n t | |
70 | } | |
71 | ifelse | |
72 | { pop load exec } | |
73 | { { pop } repeat } | |
74 | ifelse | |
75 | } def | |
76 | ||
77 | /lpmoveto | |
78 | { /moveto 2 true lpexec | |
79 | } def | |
80 | /lpshow | |
81 | { dup length 0 ne { /show 1 false lpexec } { pop } ifelse | |
82 | } def | |
83 | /lpsetmyfont | |
84 | { dup load setfont | |
85 | OutFile null ne { cvx /setfont 1 false lpexec } { pop } ifelse | |
86 | } def | |
87 | ||
88 | % Define some utility procedures. | |
89 | ||
90 | /beginpage | |
91 | { /lindex 0 def | |
92 | /skipping pindex PageFirst ge pindex PageLast le and not def | |
93 | /save 0 true lpexec /pagesave exch def | |
94 | skipping { nulldevice /OutFile null def } if | |
95 | Headers | |
96 | { /HFont lpsetmyfont | |
97 | HeadingLeft 0 topskip showline2 | |
98 | HeadingCenter dup stringwidth pop 2 div topskip showline2 | |
99 | HeadingRight null eq | |
100 | { (page ) pindex 4 string cvs concatstrings } | |
101 | { HeadingRight } | |
102 | ifelse | |
103 | dup stringwidth pop pwidth 0.95 mul exch sub | |
104 | topskip showline2 | |
105 | } | |
106 | if | |
107 | /BFont lpsetmyfont | |
108 | } def | |
109 | ||
110 | /endpage | |
111 | { lindex 0 ne { /showpage 0 false lpexec } if | |
112 | pagesave /restore 0 true lpexec | |
113 | /pindex pindex 1 add def | |
114 | } def | |
115 | ||
116 | /fontheight % font -> height | |
117 | { dup /FontBBox get | |
118 | dup 3 get exch 1 get sub | |
119 | exch /FontMatrix get | |
120 | 0 get mul 1.2 mul | |
121 | } def | |
122 | ||
123 | /wosp | |
124 | { OutFile ( ) writestring OutFile exch write==only | |
125 | } def | |
126 | ||
127 | /outfont % name font -> | |
128 | { OutFile null ne | |
129 | { exch wosp | |
130 | dup /FontName get wosp OutFile ( findfont) writestring | |
131 | /FontMatrix get 0 get 1000 mul round cvi wosp | |
132 | OutFile ( scalefont def\n) writestring | |
133 | } | |
134 | { pop pop | |
135 | } | |
136 | ifelse | |
137 | } def | |
138 | ||
139 | % showline doesn't do line wrapping yet.... | |
140 | /showline % line -> leftover_line (handles \f) | |
141 | { (\f) search | |
142 | { { dup length 0 eq { pop exit } if showline1 } loop | |
143 | endpage beginpage | |
144 | pop | |
145 | } | |
146 | if | |
147 | showline1 | |
148 | } def | |
149 | ||
150 | /showline1 % line -> leftover_line (handles page break) | |
151 | { lindex llength eq { endpage beginpage } if | |
152 | lindex colines idiv cowidth mul % x | |
153 | lindex colines mod fheight mul neg % y | |
154 | showline2 | |
155 | /lindex lindex 1 add def | |
156 | () | |
157 | } def | |
158 | ||
159 | /showline2 % string x y -> (handles tabs) | |
160 | { lpmoveto | |
161 | { dup length 0 eq { pop exit } if | |
162 | (\t) search | |
163 | { dup length 0 ne { lpshow } { pop } ifelse pop | |
164 | currentpoint exch tabwx div | |
165 | 0.05 add ceiling tabwx mul exch lpmoveto | |
166 | } | |
167 | { lpshow exit } | |
168 | ifelse | |
169 | } loop | |
170 | } def | |
171 | ||
172 | % The main printing procedure | |
173 | ||
174 | /lp | |
175 | { /lpfile exch def | |
176 | /save 0 true lpexec | |
177 | ||
178 | % Initialize the device and fonts. | |
179 | /BFont | |
180 | BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def | |
181 | /BFont BFont outfont | |
182 | /HFont | |
183 | HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def | |
184 | /HFont HFont outfont | |
185 | ||
186 | % Get the layout parameters. | |
187 | clippath | |
188 | Landscape { -90 /rotate 1 true lpexec } if | |
189 | BFont setfont ( ) stringwidth pop /cwx exch def | |
190 | cwx Tab mul /tabwx exch def | |
191 | BFont fontheight /fheight exch def | |
192 | Headers { HFont fontheight fheight add } { 0 } ifelse | |
193 | /topskip exch def | |
194 | pathbbox | |
195 | 2 index sub /plength exch def | |
196 | 2 index sub dup /pwidth exch def | |
197 | Columns div /cowidth exch def | |
198 | exch cowidth 0.025 mul add | |
199 | exch plength 0.98 mul add topskip sub | |
200 | /translate 2 true lpexec | |
201 | plength 0.9 mul topskip sub fheight div cvi MaxLines min | |
202 | dup /colines exch def | |
203 | Columns mul /llength exch def | |
204 | OutFile null ne { nulldevice } if | |
205 | ||
206 | % Print layout | |
207 | (Page height = ) print llength =only | |
208 | (.\n) print flush | |
209 | ||
210 | % Disable stack recording so we can use stopped with readline. | |
211 | $error /recordstacks false put | |
212 | ||
213 | % Initialize for the first page. | |
214 | /lbuf 1000 string def | |
215 | /pindex 1 def | |
216 | beginpage | |
217 | ||
218 | % Iterate through the file. | |
219 | () | |
220 | { dup length /pos exch def | |
221 | lbuf exch 0 exch putinterval | |
222 | { lpfile lbuf pos lbuf length pos sub getinterval readline } stopped | |
223 | { exch pop true } if | |
224 | exch length pos add lbuf exch 0 exch getinterval exch | |
225 | { showline } | |
226 | { dup length 0 ne { showline } if exit } | |
227 | ifelse | |
228 | } loop | |
229 | pop | |
230 | ||
231 | % Wrap up. | |
232 | endpage | |
233 | /restore 0 true lpexec | |
234 | ||
235 | } def | |
236 | ||
237 | end | |
238 | ||
239 | % Usage: <file> lp | |
240 | % prints <file> using the current parameter settings. | |
241 | % Usage: [ <arg1> ... <argn> ] lpcommand | |
242 | % interprets args like a command line. | |
243 | ||
244 | /lp { save lpdict begin lp end restore } def | |
245 | ||
246 | lpdict begin | |
247 | ||
248 | /splitfn % (FontNNN) -> <font> | |
249 | { dup /arg exch def length | |
250 | { dup 0 le { exit } if | |
251 | dup 1 sub arg exch get dup 48 ge exch 59 le and not { exit } if | |
252 | 1 sub | |
253 | } loop | |
254 | arg exch 0 exch getinterval dup cvn findfont | |
255 | exch arg exch anchorsearch pop pop cvr scalefont | |
256 | } def | |
257 | ||
258 | % Parse the command line switches. | |
259 | ||
260 | /doswitch % (-*) argstring -> | |
261 | { exch dup cvn lpdict exch known | |
262 | { cvn load exec } | |
263 | { exch pop (Unknown switch: ) print print (\n) print flush } | |
264 | ifelse | |
265 | } def | |
266 | ||
267 | /more % string -> | |
268 | { dup length 0 ne | |
269 | { (- ) dup 1 3 index 0 get put | |
270 | exch dup length 1 sub 1 exch getinterval | |
271 | doswitch | |
272 | } | |
273 | { pop | |
274 | } | |
275 | ifelse | |
276 | } def | |
277 | ||
278 | (-1)cvn { /Columns 1 def more } def | |
279 | (-2)cvn { /Columns 2 def more } def | |
280 | /-b { /HeadingLeft exch def /HeadingCenter () def /HeadingRight null def | |
281 | /Headers true def | |
282 | /break true def | |
283 | } def | |
284 | /-B { /Headers false def more } def | |
285 | /-c { /Truncate true def more } def | |
286 | /-f { splitfn /BodyFont exch def } def | |
287 | /-F { splitfn /HeadingFont exch def } def | |
288 | /-l { 66 -L -B } def | |
289 | /-L { cvi /MaxLines exch def } def | |
290 | /-p { (w) file /OutFile exch def Outfile (%!\n) writestring } def | |
291 | /-P { cvi /PageFirst exch def } def | |
292 | /-Q { cvi /PageLast exch def } def | |
293 | /-r { /Landscape true def more } def | |
294 | /-R { /Landscape false def more } def | |
295 | /-T { cvi /Tab exch def } def | |
296 | ||
297 | end | |
298 | ||
299 | /lpcommand | |
300 | { lpdict begin | |
301 | /break false def | |
302 | { dup length 2 ge { dup 0 get (-) 0 get eq } { false } ifelse | |
303 | { dup 0 2 getinterval | |
304 | exch dup length 2 sub 2 exch getinterval | |
305 | doswitch | |
306 | } | |
307 | { break not { dup /HeadingLeft exch def } if | |
308 | (r) file lp | |
309 | } | |
310 | ifelse | |
311 | } forall | |
312 | OutFile null ne { OutFile closefile /OutFile null def } if | |
313 | end | |
314 | } def | |
315 | ||
316 | [ shellarguments | |
317 | { ] dup length 0 ne | |
318 | { lpcommand | |
319 | } | |
320 | { (Usage: gslp [-12BclrR] [-b<header] [-f<font>] [-F<hfont>]\n) print | |
321 | ( [-L<lines>] [-p<outfile>] [-P<startpage#>] [-Q<stoppage#>]\n) print | |
322 | ( [-T<tabwidth>] file1 ... filen\n) print flush | |
323 | } | |
324 | ifelse | |
325 | } | |
326 | { pop } | |
327 | ifelse |