* configure.in: Restore Kerberos code deleted on 1999-05-29 that didn't need to
[bpt/emacs.git] / lisp / ps-print.el
CommitLineData
535efc38 1;;; ps-print.el --- Print text from the buffer as PostScript
12d89a2e 2
7d8b7e8e 3;; Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
ef2cbb24 4
e65df0a1 5;; Author: Jim Thompson (was <thompson@wg2.waii.com>)
024ced4d 6;; Author: Jacques Duthen (was <duthen@cegelec-red.fr>)
e65df0a1 7;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
024ced4d
KH
8;; Author: Kenichi Handa <handa@etl.go.jp> (multi-byte characters)
9;; Maintainer: Kenichi Handa <handa@etl.go.jp> (multi-byte characters)
e65df0a1 10;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
bc0d41bd
KH
11;; Keywords: wp, print, PostScript
12;; Time-stamp: <99/07/03 20:16:48 vinicius>
13;; Version: 5.0
e65df0a1 14
bc0d41bd
KH
15(defconst ps-print-version "5.0"
16 "ps-print.el, v 5.0 <99/07/03 vinicius>
090be653 17
535efc38 18Vinicius's last change version -- this file may have been edited as part of
090be653
RS
19Emacs without changes to the version number. When reporting bugs,
20please also report the version of Emacs, if any, that ps-print was
21distributed with.
22
23Please send all bug fixes and enhancements to
8bd22fcf 24 Vinicius Jose Latorre <vinicius@cpqd.com.br>.
090be653 25")
ef2cbb24 26
86c10ecb 27;; This file is part of GNU Emacs.
ef2cbb24
RS
28
29;; GNU Emacs is free software; you can redistribute it and/or modify
30;; it under the terms of the GNU General Public License as published by
31;; the Free Software Foundation; either version 2, or (at your option)
32;; any later version.
33
34;; GNU Emacs is distributed in the hope that it will be useful,
35;; but WITHOUT ANY WARRANTY; without even the implied warranty of
36;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37;; GNU General Public License for more details.
38
39;; You should have received a copy of the GNU General Public License
b578f267
EN
40;; along with GNU Emacs; see the file COPYING. If not, write to the
41;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
42;; Boston, MA 02111-1307, USA.
ef2cbb24 43
12d89a2e 44;;; Commentary:
ef2cbb24 45
bc0d41bd 46;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ef2cbb24 47;;
12d89a2e 48;; About ps-print
ef2cbb24 49;; --------------
bcc0d457 50;;
ef2cbb24
RS
51;; This package provides printing of Emacs buffers on PostScript
52;; printers; the buffer's bold and italic text attributes are
d3ab8dac 53;; preserved in the printer output. ps-print is intended for use with
00aa16af
RS
54;; Emacs 19 or Lucid Emacs, together with a fontifying package such as
55;; font-lock or hilit.
12d89a2e 56;;
87a16a06
RS
57;; ps-print uses the same face attributes defined through font-lock or hilit
58;; to print a PostScript file, but some faces are better seeing on the screen
59;; than on paper, specially when you have a black/white PostScript printer.
60;;
61;; ps-print allows a remap of face to another one that it is better to print,
62;; for example, the face font-lock-comment-face (if you are using font-lock)
63;; could have bold or italic attribute when printing, besides foreground color.
64;; This remap improves printing look (see How Ps-Print Maps Faces).
65;;
bcc0d457 66;;
12d89a2e 67;; Using ps-print
ef2cbb24 68;; --------------
ef2cbb24 69;;
d3ab8dac 70;; ps-print provides eight commands for generating PostScript images
12d89a2e
RS
71;; of Emacs buffers:
72;;
73;; ps-print-buffer
74;; ps-print-buffer-with-faces
75;; ps-print-region
76;; ps-print-region-with-faces
77;; ps-spool-buffer
78;; ps-spool-buffer-with-faces
79;; ps-spool-region
80;; ps-spool-region-with-faces
81;;
82;; These commands all perform essentially the same function: they
83;; generate PostScript images suitable for printing on a PostScript
84;; printer or displaying with GhostScript. These commands are
85;; collectively referred to as "ps-print- commands".
86;;
87;; The word "print" or "spool" in the command name determines when the
88;; PostScript image is sent to the printer:
ef2cbb24 89;;
12d89a2e
RS
90;; print - The PostScript image is immediately sent to the
91;; printer;
ef2cbb24 92;;
12d89a2e
RS
93;; spool - The PostScript image is saved temporarily in an
94;; Emacs buffer. Many images may be spooled locally
95;; before printing them. To send the spooled images
bcc0d457 96;; to the printer, use the command `ps-despool'.
ef2cbb24 97;;
12d89a2e
RS
98;; The spooling mechanism was designed for printing lots of small
99;; files (mail messages or netnews articles) to save paper that would
100;; otherwise be wasted on banner pages, and to make it easier to find
101;; your output at the printer (it's easier to pick up one 50-page
102;; printout than to find 50 single-page printouts).
06fb6aab 103;;
d3ab8dac 104;; ps-print has a hook in the `kill-emacs-hook' so that you won't
a7acbbe4 105;; accidentally quit from Emacs while you have unprinted PostScript
12d89a2e
RS
106;; waiting in the spool buffer. If you do attempt to exit with
107;; spooled PostScript, you'll be asked if you want to print it, and if
108;; you decline, you'll be asked to confirm the exit; this is modeled
109;; on the confirmation that Emacs uses for modified buffers.
110;;
111;; The word "buffer" or "region" in the command name determines how
112;; much of the buffer is printed:
113;;
114;; buffer - Print the entire buffer.
115;;
116;; region - Print just the current region.
117;;
118;; The -with-faces suffix on the command name means that the command
119;; will include font, color, and underline information in the
120;; PostScript image, so the printed image can look as pretty as the
121;; buffer. The ps-print- commands without the -with-faces suffix
122;; don't include font, color, or underline information; images printed
123;; with these commands aren't as pretty, but are faster to generate.
124;;
125;; Two ps-print- command examples:
126;;
127;; ps-print-buffer - print the entire buffer,
128;; without font, color, or
129;; underline information, and
130;; send it immediately to the
131;; printer.
132;;
133;; ps-spool-region-with-faces - print just the current region;
134;; include font, color, and
135;; underline information, and
136;; spool the image in Emacs to
137;; send to the printer later.
138;;
139;;
140;; Invoking Ps-Print
bcc0d457 141;; -----------------
ef2cbb24 142;;
12d89a2e 143;; To print your buffer, type
ef2cbb24 144;;
12d89a2e 145;; M-x ps-print-buffer
ef2cbb24 146;;
12d89a2e
RS
147;; or substitute one of the other seven ps-print- commands. The
148;; command will generate the PostScript image and print or spool it as
149;; specified. By giving the command a prefix argument
150;;
151;; C-u M-x ps-print-buffer
152;;
153;; it will save the PostScript image to a file instead of sending it
154;; to the printer; you will be prompted for the name of the file to
155;; save the image to. The prefix argument is ignored by the commands
156;; that spool their images, but you may save the spooled images to a
bcc0d457 157;; file by giving a prefix argument to `ps-despool':
12d89a2e
RS
158;;
159;; C-u M-x ps-despool
160;;
bcc0d457 161;; When invoked this way, `ps-despool' will prompt you for the name of
12d89a2e
RS
162;; the file to save to.
163;;
bcc0d457
RS
164;; Any of the `ps-print-' commands can be bound to keys; I recommend
165;; binding `ps-spool-buffer-with-faces', `ps-spool-region-with-faces',
166;; and `ps-despool'. Here are the bindings I use on my Sun 4 keyboard:
12d89a2e
RS
167;;
168;; (global-set-key 'f22 'ps-spool-buffer-with-faces) ;f22 is prsc
ef2cbb24
RS
169;; (global-set-key '(shift f22) 'ps-spool-region-with-faces)
170;; (global-set-key '(control f22) 'ps-despool)
171;;
12d89a2e
RS
172;;
173;; The Printer Interface
bcc0d457 174;; ---------------------
12d89a2e 175;;
bcc0d457 176;; The variables `ps-lpr-command' and `ps-lpr-switches' determine what
12d89a2e 177;; command is used to send the PostScript images to the printer, and
bcc0d457
RS
178;; what arguments to give the command. These are analogous to
179;; `lpr-command' and `lpr-switches'.
87a16a06 180;;
bcc0d457
RS
181;; Make sure that they contain appropriate values for your system;
182;; see the usage notes below and the documentation of these variables.
183;;
bc0d41bd 184;; The variable `ps-printer-name' determines the name of a local printer for
d3ab8dac
KH
185;; printing PostScript files.
186;;
bcc0d457
RS
187;; NOTE: `ps-lpr-command' and `ps-lpr-switches' take their initial values
188;; from the variables `lpr-command' and `lpr-switches'. If you have
189;; `lpr-command' set to invoke a pretty-printer such as `enscript',
190;; then ps-print won't work properly. `ps-lpr-command' must name
12d89a2e 191;; a program that does not format the files it prints.
d3ab8dac
KH
192;; `ps-printer-name' takes its initial value from the variable
193;; `printer-name'.
12d89a2e 194;;
bc0d41bd
KH
195;; The variable `ps-print-region-function' specifies a function to print the
196;; region on a PostScript printer.
197;; See definition of `call-process-region' for calling conventions. The fourth
198;; and the sixth arguments are both nil.
199;;
12d89a2e 200;;
bcc0d457
RS
201;; The Page Layout
202;; ---------------
12d89a2e 203;;
bcc0d457
RS
204;; All dimensions are floats in PostScript points.
205;; 1 inch == 2.54 cm == 72 points
206;; 1 cm == (/ 1 2.54) inch == (/ 72 2.54) points
12d89a2e 207;;
bcc0d457
RS
208;; The variable `ps-paper-type' determines the size of paper ps-print
209;; formats for; it should contain one of the symbols:
210;; `a4' `a3' `letter' `legal' `letter-small' `tabloid'
211;; `ledger' `statement' `executive' `a4small' `b4' `b5'
12d89a2e 212;;
bcc0d457
RS
213;; The variable `ps-landscape-mode' determines the orientation
214;; of the printing on the page:
215;; nil means `portrait' mode, non-nil means `landscape' mode.
216;; There is no oblique mode yet, though this is easy to do in ps.
87a16a06 217;;
bcc0d457
RS
218;; In landscape mode, the text is NOT scaled: you may print 70 lines
219;; in portrait mode and only 50 lignes in landscape mode.
220;; The margins represent margins in the printed paper:
221;; the top margin is the margin between the top of the page
222;; and the printed header, whatever the orientation is.
043620f4 223;;
bcc0d457
RS
224;; The variable `ps-number-of-columns' determines the number of columns
225;; both in landscape and portrait mode.
226;; You can use:
227;; - (the standard) one column portrait mode
228;; - (my favorite) two columns landscape mode (which spares trees)
229;; but also
230;; - one column landscape mode for files with very long lines.
231;; - multi-column portrait or landscape mode
12d89a2e 232;;
12d89a2e 233;;
bcc0d457
RS
234;; Horizontal layout
235;; -----------------
12d89a2e 236;;
bcc0d457
RS
237;; The horizontal layout is determined by the variables
238;; `ps-left-margin' `ps-inter-column' `ps-right-margin'
239;; as follows:
12d89a2e 240;;
bcc0d457
RS
241;; ------------------------------------------
242;; | | | | | | | |
243;; | lm | text | ic | text | ic | text | rm |
244;; | | | | | | | |
245;; ------------------------------------------
12d89a2e 246;;
bcc0d457
RS
247;; If `ps-number-of-columns' is 1, `ps-inter-column' is not relevant.
248;; Usually, lm = rm > 0 and ic = lm
249;; If (ic < 0), the text of adjacent columns can overlap.
12d89a2e 250;;
12d89a2e 251;;
bcc0d457
RS
252;; Vertical layout
253;; ---------------
254;;
255;; The vertical layout is determined by the variables
256;; `ps-bottom-margin' `ps-top-margin' `ps-header-offset'
257;; as follows:
258;;
259;; |--------| |--------|
260;; | tm | | tm |
261;; |--------| |--------|
262;; | header | | |
263;; |--------| | |
264;; | ho | | |
265;; |--------| or | text |
266;; | | | |
267;; | text | | |
268;; | | | |
269;; |--------| |--------|
270;; | bm | | bm |
271;; |--------| |--------|
272;;
273;; If `ps-print-header' is nil, `ps-header-offset' is not relevant.
274;; The margins represent margins in the printed paper:
275;; the top margin is the margin between the top of the page
276;; and the printed header, whatever the orientation is.
12d89a2e
RS
277;;
278;;
279;; Headers
bcc0d457 280;; -------
12d89a2e 281;;
d3ab8dac 282;; ps-print can print headers at the top of each column or at the top
12b88fff
RS
283;; of each page; the default headers contain the following four items:
284;; on the left, the name of the buffer and, if the buffer is visiting
285;; a file, the file's directory; on the right, the page number and
286;; date of printing. The default headers look something like this:
12d89a2e
RS
287;;
288;; ps-print.el 1/21
289;; /home/jct/emacs-lisp/ps/new 94/12/31
06fb6aab 290;;
12d89a2e 291;; When printing on duplex printers, left and right are reversed so
bcc0d457 292;; that the page numbers are toward the outside (cf. `ps-spool-duplex').
12d89a2e 293;;
bcc0d457
RS
294;; Headers are configurable:
295;; To turn them off completely, set `ps-print-header' to nil.
296;; To turn off the header's gaudy framing box,
297;; set `ps-print-header-frame' to nil.
298;;
12b88fff
RS
299;; To print only one header at the top of each page,
300;; set `ps-print-only-one-header' to t.
301;;
bcc0d457 302;; The font family and size of text in the header are determined
06fb6aab 303;; by the variables `ps-header-font-family', `ps-header-font-size' and
bcc0d457
RS
304;; `ps-header-title-font-size' (see below).
305;;
306;; The variable `ps-header-line-pad' determines the portion of a header
307;; title line height to insert between the header frame and the text
308;; it contains, both in the vertical and horizontal directions:
309;; .5 means half a line.
310
311;; Page numbers are printed in `n/m' format, indicating page n of m pages;
312;; to omit the total page count and just print the page number,
313;; set `ps-show-n-of-n' to nil.
12d89a2e
RS
314;;
315;; The amount of information in the header can be changed by changing
bcc0d457 316;; the number of lines. To show less, set `ps-header-lines' to 1, and
12d89a2e 317;; the header will show only the buffer name and page number. To show
bcc0d457 318;; more, set `ps-header-lines' to 3, and the header will show the time of
12d89a2e
RS
319;; printing below the date.
320;;
321;; To change the content of the headers, change the variables
bcc0d457
RS
322;; `ps-left-header' and `ps-right-header'.
323;; These variables are lists, specifying top-to-bottom the text
324;; to display on the left or right side of the header.
325;; Each element of the list should be a string or a symbol.
326;; Strings are inserted directly into the PostScript arrays,
327;; and should contain the PostScript string delimiters '(' and ')'.
12d89a2e
RS
328;;
329;; Symbols in the header format lists can either represent functions
330;; or variables. Functions are called, and should return a string to
331;; show in the header. Variables should contain strings to display in
332;; the header. In either case, function or variable, the PostScript
a7acbbe4 333;; string delimiters are added by ps-print, and should not be part of
12d89a2e
RS
334;; the returned value.
335;;
336;; Here's an example: say we want the left header to display the text
337;;
338;; Moe
339;; Larry
340;; Curly
341;;
342;; where we have a function to return "Moe"
343;;
344;; (defun moe-func ()
345;; "Moe")
346;;
347;; a variable specifying "Larry"
348;;
349;; (setq larry-var "Larry")
350;;
bcc0d457 351;; and a literal for "Curly". Here's how `ps-left-header' should be
12d89a2e
RS
352;; set:
353;;
354;; (setq ps-left-header (list 'moe-func 'larry-var "(Curly)"))
355;;
356;; Note that Curly has the PostScript string delimiters inside his
bcc0d457 357;; quotes -- those aren't misplaced lisp delimiters!
87a16a06 358;;
bcc0d457
RS
359;; Without them, PostScript would attempt to call the undefined
360;; function Curly, which would result in a PostScript error.
87a16a06 361;;
bcc0d457
RS
362;; Since most printers don't report PostScript errors except by
363;; aborting the print job, this kind of error can be hard to track down.
87a16a06 364;;
bcc0d457 365;; Consider yourself warned!
12d89a2e
RS
366;;
367;;
d3ab8dac
KH
368;; PostScript Prologue Header
369;; --------------------------
370;;
371;; It is possible to add PostScript prologue header comments besides that
372;; ps-print generates by setting the variable `ps-print-prologue-header'.
373;;
bc0d41bd
KH
374;; `ps-print-prologue-header' may be a string or a symbol function which returns
375;; a string. Note that this string is inserted on PostScript prologue header
376;; section which is used to define some document characteristic through
d3ab8dac
KH
377;; PostScript special comments, like "%%Requirements: jog\n".
378;;
379;; By default `ps-print-prologue-header' is nil.
380;;
381;; ps-print always inserts the %%Requirements: comment, so if you need to insert
382;; more requirements put them first in `ps-print-prologue-header' using the
383;; "%%+" comment. For example, if you need to set numcopies to 3 and jog on
384;; requirements and set %%LanguageLevel: to 2, do:
385;;
386;; (setq ps-print-prologue-header
387;; "%%+ numcopies(3) jog\n%%LanguageLevel: 2\n")
388;;
389;; The duplex requirement is inserted by ps-print (see section Duplex Printers).
390;;
391;; Do not forget to terminate the string with "\n".
392;;
393;; For more information about PostScript document comments, see:
394;; PostScript Language Reference Manual (2nd edition)
395;; Adobe Systems Incorporated
396;; Appendix G: Document Structuring Conventions -- Version 3.0
397;;
398;;
12d89a2e 399;; Duplex Printers
bcc0d457 400;; ---------------
12d89a2e 401;;
bc0d41bd
KH
402;; If you have a duplex-capable printer (one that prints both sides of the
403;; paper), set `ps-spool-duplex' to t.
404;; ps-print will insert blank pages to make sure each buffer starts on the
405;; correct side of the paper.
406;;
407;; The variable `ps-spool-config' specifies who is the responsable for setting
408;; duplex and page size switches. Valid values are:
409;;
410;; lpr-switches duplex and page size are configured by `ps-lpr-switches'.
411;; Don't forget to set `ps-lpr-switches' to select duplex
412;; printing for your printer.
413;;
414;; setpagedevice duplex and page size are configured by ps-print using the
415;; setpagedevice PostScript operator.
416;;
417;; nil duplex and page size are configured by ps-print *not* using
418;; the setpagedevice PostScript operator.
419;;
420;; Any other value is treated as nil.
421;;
422;; The default value is `lpr-switches'.
423;;
424;; WARNING: The setpagedevice PostScript operator affects ghostview utility when
425;; viewing file generated using landscape. Also on some printers,
426;; setpagedevice affects zebra stripes; on other printers,
427;; setpagedevice affects the left margin.
428;; Besides all that, if your printer does not have the paper size
429;; specified by setpagedevice, your printing will be aborted.
430;; So, if you need to use setpagedevice, set `ps-spool-config' to
431;; `setpagedevice', generate a test file and send it to your printer;
432;; if the printed file isn't ok, set `ps-spool-config' to nil.
433;;
434;; The variable `ps-spool-tumble' specifies how the page images on opposite
435;; sides of a sheet are oriented with respect to each other. If
436;; `ps-spool-tumble' is nil, produces output suitable for binding on the left or
437;; right. If `ps-spool-tumble' is non-nil, produces output suitable for binding
438;; at the top or bottom. It has effect only when `ps-spool-duplex' is non-nil.
439;; The default value is nil.
440;;
441;; Some printer system prints a header page and forces the first page be printed
442;; on header page back, when using duplex. If your printer system has this
443;; behavior, set variable `ps-banner-page-when-duplexing' to t.
444;;
445;; When `ps-banner-page-when-duplexing' is non-nil means the very first page is
446;; skipped. It's like the very first character of buffer (or region) is ^L
447;; (\014).
448;;
449;; The default for `ps-banner-page-when-duplexing' is nil (*don't* skip the very
450;; first page).
451;;
452;;
453;; N-up Printing
454;; -------------
455;;
456;; The variable `ps-n-up-printing' specifies the number of pages per sheet of
457;; paper. The value specified must be between 1 and 100. The default is 1.
458;;
459;; NOTE: some PostScript printer may crash printing if `ps-n-up-printing' is set
460;; to a high value (for example, 23). If this happens, set a lower value.
461;;
462;; The variable `ps-n-up-margin' specifies the margin in points between the
463;; sheet border and the n-up printing. The default is 1 cm (or 0.3937 inches,
464;; or 28.35 points).
465;;
466;; If variable `ps-n-up-border-p' is non-nil a border is drawn around each page.
467;; The default is t.
468;;
469;; The variable `ps-n-up-filling' specifies how page matrix is filled on each
470;; sheet of paper. Following are the valid values for `ps-n-up-filling' with a
471;; filling example using a 3x4 page matrix:
472;;
473;; left-top 1 2 3 4 left-bottom 9 10 11 12
474;; 5 6 7 8 5 6 7 8
475;; 9 10 11 12 1 2 3 4
476;;
477;; right-top 4 3 2 1 right-bottom 12 11 10 9
478;; 8 7 6 5 8 7 6 5
479;; 12 11 10 9 4 3 2 1
480;;
481;; top-left 1 4 7 10 bottom-left 3 6 9 12
482;; 2 5 8 11 2 5 8 11
483;; 3 6 9 12 1 4 7 10
484;;
485;; top-right 10 7 4 1 bottom-right 12 9 6 3
486;; 11 8 5 2 11 8 5 2
487;; 12 9 6 3 10 7 4 1
488;;
489;; Any other value is treated as left-top.
490;;
491;; The default value is left-top.
bcc0d457 492;;
06fb6aab 493;;
857686a6
RS
494;; Control And 8-bit Characters
495;; ----------------------------
496;;
497;; The variable `ps-print-control-characters' specifies whether you want to see
498;; a printable form for control and 8-bit characters, that is, instead of
6bdb808e 499;; sending, for example, a ^D (\004) to printer, it is sent the string "^D".
857686a6
RS
500;;
501;; Valid values for `ps-print-control-characters' are:
502;;
c82b4a75
KH
503;; 8-bit This is the value to use when you want an ASCII encoding of
504;; any control or non-ASCII character. Control characters are
505;; encoded as "^D", and non-ASCII characters have an
6bdb808e
RS
506;; octal encoding.
507;;
c82b4a75 508;; control-8-bit This is the value to use when you want an ASCII encoding of
6bdb808e
RS
509;; any control character, whether it is 7 or 8-bit.
510;; European 8-bits accented characters are printed according
511;; the current font.
512;;
c82b4a75 513;; control Only ASCII control characters have an ASCII encoding.
6bdb808e
RS
514;; European 8-bits accented characters are printed according
515;; the current font.
516;;
c82b4a75 517;; nil No ASCII encoding. Any character is printed according the
6bdb808e 518;; current font.
857686a6
RS
519;;
520;; Any other value is treated as nil.
521;;
496725ad 522;; The default is `control-8-bit'.
857686a6
RS
523;;
524;; Characters TAB, NEWLINE and FORMFEED are always treated by ps-print engine.
525;;
526;;
024ced4d
KH
527;; Printing Multi-byte Buffer
528;; --------------------------
d3ab8dac 529;;
298bfad9 530;; See ps-mule.el for documentation.
e65df0a1 531;;
bc0d41bd
KH
532;; See ps-print-def.el for definition.
533;;
e65df0a1 534;;
87a16a06
RS
535;; Line Number
536;; -----------
537;;
a18ed129
RS
538;; The variable `ps-line-number' specifies whether to number each line;
539;; non-nil means do so. The default is nil (don't number each line).
87a16a06
RS
540;;
541;;
542;; Zebra Stripes
543;; -------------
544;;
a18ed129
RS
545;; Zebra stripes are a kind of background that appear "underneath" the text
546;; and can make the text easier to read. They look like this:
87a16a06
RS
547;;
548;; XXXXXXXXXXXXXXXXXXXXXXXX
549;; XXXXXXXXXXXXXXXXXXXXXXXX
535efc38
RS
550;; XXXXXXXXXXXXXXXXXXXXXXXX
551;;
87a16a06
RS
552;;
553;;
554;; XXXXXXXXXXXXXXXXXXXXXXXX
555;; XXXXXXXXXXXXXXXXXXXXXXXX
535efc38 556;; XXXXXXXXXXXXXXXXXXXXXXXX
87a16a06 557;;
06fb6aab 558;; The blocks of X's represent rectangles filled with a light gray color.
a18ed129
RS
559;; Each rectangle extends all the way across the page.
560;;
561;; The height, in lines, of each rectangle is controlled by
535efc38
RS
562;; the variable `ps-zebra-stripe-height', which is 3 by default.
563;; The distance between stripes equals the height of a stripe.
8bd22fcf 564;;
01961237 565;; The variable `ps-zebra-stripes' controls whether to print zebra stripes.
a18ed129
RS
566;; Non-nil means yes, nil means no. The default is nil.
567;;
bc0d41bd
KH
568;; The variable `ps-zebra-gray' controls the zebra stripes gray scale.
569;; It should be a float number between 0.0 (black color) and 1.0 (white color).
570;; The default is 0.95.
571;;
a18ed129 572;; See also section How Ps-Print Has A Text And/Or Image On Background.
87a16a06 573;;
87a16a06 574;;
12b88fff
RS
575;; Hooks
576;; -----
577;;
d3ab8dac 578;; ps-print has the following hook variables:
12b88fff
RS
579;;
580;; `ps-print-hook'
581;; It is evaluated once before any printing process. This is the right
582;; place to initialize ps-print global data.
583;; For an example, see section Adding a New Font Family.
584;;
bc0d41bd
KH
585;; `ps-print-begin-sheet-hook'
586;; It is evaluated on each beginning of sheet of paper.
587;; If `ps-n-up-printing' is equal to 1, `ps-print-begin-page-hook' is never
588;; evaluated.
589;;
12b88fff 590;; `ps-print-begin-page-hook'
bc0d41bd
KH
591;; It is evaluated on each beginning of page, except in the beginning
592;; of page that `ps-print-begin-sheet-hook' is evaluated.
12b88fff
RS
593;;
594;; `ps-print-begin-column-hook'
595;; It is evaluated on each beginning of column, except in the beginning
bc0d41bd
KH
596;; of column that `ps-print-begin-page-hook' is evaluated or that
597;; `ps-print-begin-sheet-hook' is evaluated.
12b88fff
RS
598;;
599;;
600;; Font Managing
bcc0d457
RS
601;; -------------
602;;
7d8b7e8e
KH
603;; ps-print now knows rather precisely some fonts: the variable
604;; `ps-font-info-database' contains information for a list of font families
605;; (currently mainly `Courier' `Helvetica' `Times' `Palatino' `Helvetica-Narrow'
606;; `NewCenturySchlbk'). Each font family contains the font names for standard,
607;; bold, italic and bold-italic characters, a reference size (usually 10) and
608;; the corresponding line height, width of a space and average character width.
06fb6aab 609;;
7d8b7e8e
KH
610;; The variable `ps-font-family' determines which font family is to be used for
611;; ordinary text. If its value does not correspond to a known font family, an
612;; error message is printed into the `*Messages*' buffer, which lists the
613;; currently available font families.
bcc0d457 614;;
7d8b7e8e
KH
615;; The variable `ps-font-size' determines the size (in points) of the font for
616;; ordinary text, when generating PostScript. Its value is a float or a cons of
617;; floats which has the following form:
bcc0d457 618;;
7d8b7e8e
KH
619;; (LANDSCAPE-SIZE . PORTRAIT-SIZE)
620;;
621;; Similarly, the variable `ps-header-font-family' determines which font family
622;; is to be used for text in the header.
623;;
624;; The variable `ps-header-font-size' determines the font size, in points, for
625;; text in the header (similar to `ps-font-size').
626;;
627;; The variable `ps-header-title-font-size' determines the font size, in points,
628;; for the top line of text in the header (similar to `ps-font-size').
bcc0d457
RS
629;;
630;;
12b88fff 631;; Adding a New Font Family
bcc0d457
RS
632;; ------------------------
633;;
634;; To use a new font family, you MUST first teach ps-print
87a16a06 635;; this font, i.e., add its information to `ps-font-info-database',
bcc0d457
RS
636;; otherwise ps-print cannot correctly place line and page breaks.
637;;
87a16a06 638;; For example, assuming `Helvetica' is unknown,
bcc0d457
RS
639;; you first need to do the following ONLY ONCE:
640;;
641;; - create a new buffer
642;; - generate the PostScript image to a file (C-u M-x ps-print-buffer)
643;; - open this file and find the line:
644;; `% 3 cm 20 cm moveto 10 /Courier ReportFontInfo showpage'
a18ed129 645;; - delete the leading `%' (which is the PostScript comment character)
bcc0d457
RS
646;; - replace in this line `Courier' by the new font (say `Helvetica')
647;; to get the line:
648;; `3 cm 20 cm moveto 10 /Helvetica ReportFontInfo showpage'
649;; - send this file to the printer (or to ghostscript).
650;; You should read the following on the output page:
651;;
652;; For Helvetica 10 point, the line height is 11.56, the space width is 2.78
653;; and a crude estimate of average character width is 5.09243
654;;
655;; - Add these values to the `ps-font-info-database':
656;; (setq ps-font-info-database
12b88fff
RS
657;; (append
658;; '((Helvetica ; the family key
659;; (fonts (normal . "Helvetica")
660;; (bold . "Helvetica-Bold")
661;; (italic . "Helvetica-Oblique")
662;; (bold-italic . "Helvetica-BoldOblique"))
663;; (size . 10.0)
664;; (line-height . 11.56)
665;; (space-width . 2.78)
666;; (avg-char-width . 5.09243)))
667;; ps-font-info-database))
bcc0d457
RS
668;; - Now you can use this font family with any size:
669;; (setq ps-font-family 'Helvetica)
670;; - if you want to use this family in another emacs session, you must
671;; put into your `~/.emacs':
672;; (require 'ps-print)
673;; (setq ps-font-info-database (append ...)))
674;; if you don't want to load ps-print, you have to copy the whole value:
675;; (setq ps-font-info-database '(<your stuff> <the standard stuff>))
12b88fff
RS
676;; or, use `ps-print-hook' (see section Hooks):
677;; (add-hook 'ps-print-hook
bc0d41bd
KH
678;; '(lambda ()
679;; (or (assq 'Helvetica ps-font-info-database)
680;; (setq ps-font-info-database (append ...)))))
bcc0d457
RS
681;;
682;; You can create new `mixed' font families like:
12b88fff
RS
683;; (my-mixed-family
684;; (fonts (normal . "Courier-Bold")
685;; (bold . "Helvetica")
686;; (italic . "Zapf-Chancery-MediumItalic")
687;; (bold-italic . "NewCenturySchlbk-BoldItalic")
688;; (w3-table-hack-x-face . "LineDrawNormal"))
689;; (size . 10.0)
690;; (line-height . 10.55)
691;; (space-width . 6.0)
692;; (avg-char-width . 6.0))
d3ab8dac 693;;
bcc0d457
RS
694;; Now you can use your new font family with any size:
695;; (setq ps-font-family 'my-mixed-family)
696;;
12b88fff
RS
697;; Note that on above example the `w3-table-hack-x-face' entry refers to
698;; a face symbol, so when printing this face it'll be used the font
699;; `LineDrawNormal'. If the face `w3-table-hack-x-face' is remapped to
700;; use bold and/or italic attribute, the corresponding entry (bold, italic
701;; or bold-italic) will be used instead of `w3-table-hack-x-face' entry.
702;;
703;; Note also that the font family entry order is irrelevant, so the above
704;; example could also be written:
705;; (my-mixed-family
706;; (size . 10.0)
707;; (fonts (w3-table-hack-x-face . "LineDrawNormal")
708;; (bold . "Helvetica")
709;; (bold-italic . "NewCenturySchlbk-BoldItalic")
710;; (italic . "Zapf-Chancery-MediumItalic")
711;; (normal . "Courier-Bold"))
712;; (avg-char-width . 6.0)
713;; (space-width . 6.0)
714;; (line-height . 10.55))
715;;
716;; Despite the note above, it is recommended that some convention about
717;; entry order be used.
718;;
bcc0d457
RS
719;; You can get information on all the fonts resident in YOUR printer
720;; by uncommenting the line:
721;; % 3 cm 20 cm moveto ReportAllFontInfo showpage
722;;
a18ed129
RS
723;; The PostScript file should be sent to YOUR PostScript printer.
724;; If you send it to ghostscript or to another PostScript printer,
bcc0d457
RS
725;; you may get slightly different results.
726;; Anyway, as ghostscript fonts are autoload, you won't get
727;; much font info.
728;;
729;;
730;; How Ps-Print Deals With Faces
731;; -----------------------------
12d89a2e 732;;
bcc0d457
RS
733;; The ps-print-*-with-faces commands attempt to determine which faces
734;; should be printed in bold or italic, but their guesses aren't
735;; always right. For example, you might want to map colors into faces
736;; so that blue faces print in bold, and red faces in italic.
12d89a2e 737;;
857686a6
RS
738;; It is possible to force ps-print to consider specific faces bold,
739;; italic or underline, no matter what font they are displayed in, by setting
740;; the variables `ps-bold-faces', `ps-italic-faces' and `ps-underlined-faces'.
741;; These variables contain lists of faces that ps-print should consider bold,
742;; italic or underline; to set them, put code like the following into your
743;; .emacs file:
12d89a2e 744;;
12b88fff 745;; (setq ps-bold-faces '(my-blue-face))
bcc0d457 746;; (setq ps-italic-faces '(my-red-face))
857686a6 747;; (setq ps-underlined-faces '(my-green-face))
bcc0d457
RS
748;;
749;; Faces like bold-italic that are both bold and italic should go in
750;; *both* lists.
751;;
d3ab8dac 752;; ps-print keeps internal lists of which fonts are bold and which are
bcc0d457
RS
753;; italic; these lists are built the first time you invoke ps-print.
754;; For the sake of efficiency, the lists are built only once; the same
755;; lists are referred in later invocations of ps-print.
756;;
757;; Because these lists are built only once, it's possible for them to
758;; get out of sync, if a face changes, or if new faces are added. To
759;; get the lists back in sync, you can set the variable
760;; `ps-build-face-reference' to t, and the lists will be rebuilt the
857686a6
RS
761;; next time ps-print is invoked. If you need that the lists always be
762;; rebuilt when ps-print is invoked, set the variable
763;; `ps-always-build-face-reference' to t.
bcc0d457
RS
764;;
765;;
766;; How Ps-Print Deals With Color
767;; -----------------------------
768;;
d3ab8dac 769;; ps-print detects faces with foreground and background colors
bcc0d457
RS
770;; defined and embeds color information in the PostScript image.
771;; The default foreground and background colors are defined by the
772;; variables `ps-default-fg' and `ps-default-bg'.
773;; On black-and-white printers, colors are displayed in grayscale.
774;; To turn off color output, set `ps-print-color-p' to nil.
775;;
776;;
87a16a06
RS
777;; How Ps-Print Maps Faces
778;; -----------------------
779;;
780;; As ps-print uses PostScript to print buffers, it is possible to have
781;; other attributes associated with faces. So the new attributes used
782;; by ps-print are:
783;;
784;; strikeout - like underline, but the line is in middle of text.
785;; overline - like underline, but the line is over the text.
786;; shadow - text will have a shadow.
787;; box - text will be surrounded by a box.
a18ed129 788;; outline - print characters as hollow outlines.
87a16a06 789;;
06fb6aab 790;; See the documentation for `ps-extend-face'.
87a16a06 791;;
bc0d41bd
KH
792;; Let's, for example, remap `font-lock-keyword-face' to another foreground
793;; color and bold attribute:
87a16a06 794;;
a18ed129 795;; (ps-extend-face '(font-lock-keyword-face "RoyalBlue" nil bold) 'MERGE)
87a16a06 796;;
6c8f2753
RS
797;; If you want to use a new face, define it first with `defface',
798;; and then call `ps-extend-face' to specify how to print it.
799;;
87a16a06
RS
800;;
801;; How Ps-Print Has A Text And/Or Image On Background
802;; --------------------------------------------------
803;;
d3ab8dac 804;; ps-print can print texts and/or EPS PostScript images on background; it is
87a16a06
RS
805;; possible to define the following text attributes: font name, font size,
806;; initial position, angle, gray scale and pages to print.
807;;
808;; It has the following EPS PostScript images attributes: file name containing
809;; the image, initial position, X and Y scales, angle and pages to print.
810;;
811;; See documentation for `ps-print-background-text' and
812;; `ps-print-background-image'.
813;;
814;; For example, if we wish to print text "preliminary" on all pages and text
815;; "special" on page 5 and from page 11 to page 17, we could specify:
816;;
817;; (setq ps-print-background-text
818;; '(("preliminary")
819;; ("special"
820;; "LeftMargin" "BottomMargin PrintHeight add" ; X and Y position
821;; ; (upper left corner)
822;; nil nil nil
12b88fff 823;; "PrintHeight neg PrintPageWidth atan" ; angle
87a16a06
RS
824;; 5 (11 . 17)) ; page list
825;; ))
826;;
827;; Similarly, we could print image "~/images/EPS-image1.ps" on all pages and
828;; image "~/images/EPS-image2.ps" on page 5 and from page 11 to page 17, we
829;; specify:
830;;
831;; (setq ps-print-background-image
832;; '(("~/images/EPS-image1.ps"
833;; "LeftMargin" "BottomMargin") ; X and Y position (lower left corner)
834;; ("~/images/EPS-image2.ps"
835;; "LeftMargin" "BottomMargin PrintHeight 2 div add" ; X and Y position
836;; ; (upper left corner)
837;; nil nil nil
838;; 5 (11 . 17)) ; page list
839;; ))
840;;
841;; If it is not possible to read (or does not exist) an image file, that file
842;; is ignored.
843;;
844;; The printing order is:
845;;
846;; 1. Print zebra stripes
847;; 2. Print background texts that it should be on all pages
848;; 3. Print background images that it should be on all pages
849;; 4. Print background texts only for current page (if any)
850;; 5. Print background images only for current page (if any)
851;; 6. Print header
a18ed129 852;; 7. Print buffer text (with faces, if specified) and line number
87a16a06
RS
853;;
854;;
bcc0d457
RS
855;; Utilities
856;; ---------
857;;
858;; Some tools are provided to help you customize your font setup.
859;;
860;; `ps-setup' returns (some part of) the current setup.
861;;
862;; To avoid wrapping too many lines, you may want to adjust the
863;; left and right margins and the font size. On UN*X systems, do:
864;; pr -t file | awk '{printf "%3d %s\n", length($0), $0}' | sort -r | head
865;; to determine the longest lines of your file.
87a16a06 866;; Then, the command `ps-line-lengths' will give you the correspondence
bcc0d457
RS
867;; between a line length (number of characters) and the maximum font
868;; size which doesn't wrap such a line with the current ps-print setup.
869;;
870;; The commands `ps-nb-pages-buffer' and `ps-nb-pages-region' display
87a16a06 871;; the correspondence between a number of pages and the maximum font
bcc0d457
RS
872;; size which allow the number of lines of the current buffer or of
873;; its current region to fit in this number of pages.
a18ed129
RS
874;;
875;; NOTE: line folding is not taken into account in this process and could
876;; change the results.
b87c5d3d 877;;
b87c5d3d 878;;
b87c5d3d
RS
879;; New since version 1.5
880;; ---------------------
b87c5d3d 881;;
bcc0d457 882;; Color output capability.
b87c5d3d 883;; Automatic detection of font attributes (bold, italic).
b87c5d3d 884;; Configurable headers with page numbers.
b87c5d3d 885;; Slightly faster.
b87c5d3d 886;; Support for different paper sizes.
b87c5d3d
RS
887;; Better conformance to PostScript Document Structure Conventions.
888;;
ef2cbb24 889;;
bcc0d457
RS
890;; New since version 2.8
891;; ---------------------
892;;
bc0d41bd
KH
893;; [vinicius] 990703 Vinicius Jose Latorre <vinicius@cpqd.com.br>
894;;
895;; Better customization.
896;; `ps-banner-page-when-duplexing' and `ps-zebra-gray'.
897;;
898;; [vinicius] 990513 Vinicius Jose Latorre <vinicius@cpqd.com.br>
899;;
900;; N-up printing.
901;; Hook: `ps-print-begin-sheet-hook'.
902;;
903;; [keinichi] 990509 Kein'ichi Handa <handa@etl.go.jp>
904;;
905;; `ps-print-region-function'
906;;
907;; [vinicius] 990301 Vinicius Jose Latorre <vinicius@cpqd.com.br>
908;;
909;; PostScript tumble and setpagedevice.
910;;
d3ab8dac
KH
911;; [vinicius] 980922 Vinicius Jose Latorre <vinicius@cpqd.com.br>
912;;
913;; PostScript prologue header comment insertion.
914;; Skip invisible text better.
915;;
e65df0a1
KH
916;; [keinichi] 980819 Kein'ichi Handa <handa@etl.go.jp>
917;;
024ced4d 918;; Multi-byte buffer handling.
e65df0a1 919;;
12b88fff
RS
920;; [vinicius] 980306 Vinicius Jose Latorre <vinicius@cpqd.com.br>
921;;
e65df0a1 922;; Skip invisible text.
12b88fff
RS
923;;
924;; [vinicius] 971130 Vinicius Jose Latorre <vinicius@cpqd.com.br>
925;;
926;; Hooks: `ps-print-hook', `ps-print-begin-page-hook' and
927;; `ps-print-begin-column-hook'.
928;; Put one header per page over the columns.
929;; Better database font management.
930;; Better control characters handling.
931;;
857686a6 932;; [vinicius] 971121 Vinicius Jose Latorre <vinicius@cpqd.com.br>
87a16a06 933;;
12b88fff 934;; Dynamic evaluation at print time of `ps-lpr-switches'.
87a16a06
RS
935;; Handle control characters.
936;; Face remapping.
937;; New face attributes.
938;; Line number.
939;; Zebra stripes.
940;; Text and/or image on background.
941;;
bcc0d457
RS
942;; [jack] 960517 Jacques Duthen <duthen@cegelec-red.fr>
943;;
a18ed129 944;; Font family and float size for text and header.
bcc0d457
RS
945;; Landscape mode.
946;; Multiple columns.
947;; Tools for page setup.
948;;
949;;
d3ab8dac 950;; Known bugs and limitations of ps-print
ef2cbb24 951;; --------------------------------------
bcc0d457 952;;
043620f4
KH
953;; Although color printing will work in XEmacs 19.12, it doesn't work
954;; well; in particular, bold or italic fonts don't print in the right
955;; background color.
956;;
957;; Invisible properties aren't correctly ignored in XEmacs 19.12.
958;;
b87c5d3d 959;; Automatic font-attribute detection doesn't work well, especially
00aa16af 960;; with hilit19 and older versions of get-create-face. Users having
bcc0d457 961;; problems with auto-font detection should use the lists
857686a6
RS
962;; `ps-italic-faces', `ps-bold-faces' and `ps-underlined-faces' and/or
963;; turn off automatic detection by setting `ps-auto-font-detect' to nil.
00aa16af 964;;
043620f4 965;; Automatic font-attribute detection doesn't work with XEmacs 19.12
857686a6
RS
966;; in tty mode; use the lists `ps-italic-faces', `ps-bold-faces' and
967;; `ps-underlined-faces' instead.
12d89a2e 968;;
00aa16af 969;; Still too slow; could use some hand-optimization.
ef2cbb24 970;;
12d89a2e 971;; Default background color isn't working.
ef2cbb24
RS
972;;
973;; Faces are always treated as opaque.
974;;
12d89a2e 975;; Epoch and Emacs 18 not supported. At all.
ef2cbb24 976;;
06fb6aab 977;; Fixed-pitch fonts work better for line folding, but are not required.
bcc0d457
RS
978;;
979;; `ps-nb-pages-buffer' and `ps-nb-pages-region' don't take care
980;; of folding lines.
ef2cbb24 981;;
12d89a2e 982;;
d3ab8dac 983;; Things to change
bcc0d457 984;; ----------------
ef2cbb24 985;;
12b88fff 986;; Avoid page break inside a paragraph.
bcc0d457 987;; Add `ps-non-bold-faces' and `ps-non-italic-faces' (should be easy).
bcc0d457
RS
988;; Improve the memory management for big files (hard?).
989;; `ps-nb-pages-buffer' and `ps-nb-pages-region' should take care
990;; of folding lines.
ef2cbb24 991;;
ef2cbb24 992;;
12d89a2e
RS
993;; Acknowledgements
994;; ----------------
12b88fff 995;;
024ced4d 996;; Thanks to Kein'ichi Handa <handa@etl.go.jp> for multi-byte buffer handling.
915293a2
KH
997;;
998;; Thanks to Matthew O Persico <Matthew.Persico@lazard.com> for line number on
999;; empty columns.
1000;;
1001;; Thanks to Theodore Jump <tjump@cais.com> for adjust PostScript code order on
1002;; last page.
1003;;
6bdb808e
RS
1004;; Thanks to Roland Ducournau <ducour@lirmm.fr> for
1005;; `ps-print-control-characters' variable documentation.
1006;;
12b88fff
RS
1007;; Thanks to Marcus G Daniels <marcus@cathcart.sysc.pdx.edu> for a better
1008;; database font management.
1009;;
1010;; Thanks to Martin Boyer <gamin@videotron.ca> for some ideas on putting one
6bdb808e
RS
1011;; header per page over the columns and correct line numbers when printing a
1012;; region.
12b88fff
RS
1013;;
1014;; Thanks to Steven L Baur <steve@miranova.com> for dynamic evaluation at
1015;; print time of `ps-lpr-switches'.
1016;;
6bdb808e
RS
1017;; Thanks to Kevin Rodgers <kevinr@ihs.com> for handling control characters
1018;; (his code was severely modified, but the main idea was kept).
1019;;
12b88fff
RS
1020;; Thanks to some suggestions on:
1021;; * Face color map: Marco Melgazzi <marco@techie.com>
1022;; * XEmacs compatibility: William J. Henney <will@astrosmo.unam.mx>
984e7bd9 1023;; * Check `ps-paper-type': Sudhakar Frederick <sfrederi@asc.corp.mot.com>
12b88fff 1024;;
857686a6
RS
1025;; Thanks to Jacques Duthen <duthen@cegelec-red.fr> (Jack) for the 3.4 version
1026;; I started from. [vinicius]
1027;;
bcc0d457
RS
1028;; Thanks to Jim Thompson <?@?> for the 2.8 version I started from.
1029;; [jack]
1030;;
12d89a2e
RS
1031;; Thanks to Kevin Rodgers <kevinr@ihs.com> for adding support for
1032;; color and the invisible property.
ef2cbb24 1033;;
12d89a2e
RS
1034;; Thanks to Avishai Yacobi, avishaiy@mcil.comm.mot.com, for writing
1035;; the initial port to Emacs 19. His code is no longer part of
1036;; ps-print, but his work is still appreciated.
ef2cbb24 1037;;
12d89a2e
RS
1038;; Thanks to Remi Houdaille and Michel Train, michel@metasoft.fdn.org,
1039;; for adding underline support. Their code also is no longer part of
1040;; ps-print, but their efforts are not forgotten.
1041;;
1042;; Thanks also to all of you who mailed code to add features to
1043;; ps-print; although I didn't use your code, I still appreciate your
1044;; sharing it with me.
1045;;
1046;; Thanks to all who mailed comments, encouragement, and criticism.
1047;; Thanks also to all who responded to my survey; I had too many
1048;; responses to reply to them all, but I greatly appreciate your
1049;; interest.
1050;;
1051;; Jim
bc0d41bd 1052;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ef2cbb24
RS
1053
1054;;; Code:
1055
090be653
RS
1056(unless (featurep 'lisp-float-type)
1057 (error "`ps-print' requires floating point support"))
ef2cbb24 1058
298bfad9
KH
1059;; For Emacs 20.2 and the earlier version.
1060(eval-and-compile
bc0d41bd
KH
1061 (and (boundp 'mule-version) ; only if mule package is loaded
1062 (string< mule-version "4.0")
298bfad9
KH
1063 (progn
1064 (defun set-buffer-multibyte (arg)
1065 (setq enable-multibyte-characters arg))
1066 (defun string-as-unibyte (arg) arg)
1067 (defun string-as-multibyte (arg) arg)
1068 (defun charset-after (&optional arg)
1069 (char-charset (char-after arg))))))
1070
ef2cbb24 1071;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e
RS
1072;; User Variables:
1073
bcc0d457
RS
1074;;; Interface to the command system
1075
bc0d41bd
KH
1076(defgroup postscript nil
1077 "PostScript Group"
1078 :tag "PostScript"
1079 :group 'emacs)
1080
e0af0d3e 1081(defgroup ps-print nil
8bd22fcf 1082 "PostScript generator for Emacs 19"
e0af0d3e 1083 :prefix "ps-"
bc0d41bd
KH
1084 :group 'wp
1085 :group 'postscript)
e0af0d3e
RS
1086
1087(defgroup ps-print-horizontal nil
1088 "Horizontal page layout"
1089 :prefix "ps-"
1090 :tag "Horizontal"
1091 :group 'ps-print)
1092
1093(defgroup ps-print-vertical nil
1094 "Vertical page layout"
1095 :prefix "ps-"
1096 :tag "Vertical"
1097 :group 'ps-print)
1098
1099(defgroup ps-print-header nil
1100 "Headers layout"
1101 :prefix "ps-"
1102 :tag "Header"
1103 :group 'ps-print)
1104
1105(defgroup ps-print-font nil
1106 "Fonts customization"
1107 :prefix "ps-"
1108 :tag "Font"
1109 :group 'ps-print)
1110
1111(defgroup ps-print-color nil
1112 "Color customization"
1113 :prefix "ps-"
1114 :tag "Color"
1115 :group 'ps-print)
1116
1117(defgroup ps-print-face nil
1118 "Faces customization"
1119 :prefix "ps-"
1120 :tag "PS Faces"
1121 :group 'ps-print
1122 :group 'faces)
1123
bc0d41bd
KH
1124(defgroup ps-print-n-up nil
1125 "N-up customization"
1126 :prefix "ps-"
1127 :tag "N-Up"
1128 :group 'ps-print)
1129
1130(defgroup ps-print-zebra nil
1131 "Zebra customization"
1132 :prefix "ps-"
1133 :tag "Zebra"
1134 :group 'ps-print)
1135
1136(defgroup ps-print-background nil
1137 "Background customization"
1138 :prefix "ps-"
1139 :tag "Background"
1140 :group 'ps-print)
1141
1142(defgroup ps-print-printer nil
1143 "Printer customization"
1144 :prefix "ps-"
1145 :tag "Printer"
1146 :group 'ps-print)
1147
1148(defgroup ps-print-page nil
1149 "Page customization"
1150 :prefix "ps-"
1151 :tag "Page"
1152 :group 'ps-print)
1153
1154
5daebd00 1155(require 'ps-vars) ; Common definitions
bc0d41bd 1156
e0af0d3e 1157
d3ab8dac
KH
1158(defcustom ps-print-prologue-header nil
1159 "*PostScript prologue header comments besides that ps-print generates.
1160
1161`ps-print-prologue-header' may be a string or a symbol function which
1162returns a string. Note that this string is inserted on PostScript prologue
1163header section which is used to define some document characteristic through
1164PostScript special comments, like \"%%Requirements: jog\\n\".
1165
1166ps-print always inserts the %%Requirements: comment, so if you need to insert
1167more requirements put them first in `ps-print-prologue-header' using the
1168\"%%+\" comment. For example, if you need to set numcopies to 3 and jog on
1169requirements and set %%LanguageLevel: to 2, do:
1170
1171(setq ps-print-prologue-header
1172 \"%%+ numcopies(3) jog\\n%%LanguageLevel: 2\\n\")
1173
1174The duplex requirement is inserted by ps-print (see `ps-spool-duplex').
1175
1176Do not forget to terminate the string with \"\\n\".
1177
1178For more information about PostScript document comments, see:
1179 PostScript Language Reference Manual (2nd edition)
1180 Adobe Systems Incorporated
1181 Appendix G: Document Structuring Conventions -- Version 3.0"
bc0d41bd
KH
1182 :type '(choice :tag "Prologue Header"
1183 string symbol (other :tag "nil" nil))
d3ab8dac
KH
1184 :group 'ps-print)
1185
298bfad9
KH
1186(defcustom ps-printer-name (and (boundp 'printer-name)
1187 printer-name)
03820514
RS
1188 "*The name of a local printer for printing PostScript files.
1189
1190On Unix-like systems, a string value should be a name understood by
52cf535f
AI
1191lpr's -P option; a value of nil means use the value of `printer-name'
1192instead. Any other value will be ignored.
1193
1194On MS-DOS and MS-Windows systems, a string value is taken as the name of
1195the printer device or port to which PostScript files are written,
1196provided `ps-lpr-command' is \"\". By default it is the same as
1197`printer-name'; typical non-default settings would be \"LPT1\" to
1198\"LPT3\" for parallel printers, or \"COM1\" to \"COM4\" or \"AUX\" for
1199serial printers, or \"//hostname/printer\" for a shared network printer.
1200You can also set it to a name of a file, in which case the output gets
1201appended to that file. \(Note that `ps-print' package already has
1202facilities for printing to a file, so you might as well use them instead
270a64ac 1203of changing the setting of this variable.\) If you want to silently
52cf535f 1204discard the printed output, set this to \"NUL\"."
bc0d41bd
KH
1205 :type '(choice :tag "Printer Name"
1206 file (other :tag "Pipe to ps-lpr-command" pipe))
1207 :group 'ps-print-printer)
03820514 1208
e0af0d3e 1209(defcustom ps-lpr-command lpr-command
52cf535f
AI
1210 "*Name of program for printing a PostScript file.
1211
1212On MS-DOS and MS-Windows systems, if the value is an empty string then
1213Emacs will write directly to the printer port named by `ps-printer-name'.
1214The programs `print' and `nprint' (the standard print programs on Windows
1215NT and Novell Netware respectively) are handled specially, using
1216`ps-printer-name' as the destination for output; any other program is
1217treated like `lpr' except that an explicit filename is given as the last
1218argument."
e0af0d3e 1219 :type 'string
bc0d41bd 1220 :group 'ps-print-printer)
e0af0d3e
RS
1221
1222(defcustom ps-lpr-switches lpr-switches
1223 "*A list of extra switches to pass to `ps-lpr-command'."
1224 :type '(repeat string)
bc0d41bd 1225 :group 'ps-print-printer)
12d89a2e 1226
52cf535f 1227(defcustom ps-print-region-function nil
bc0d41bd
KH
1228 "*Specify a function to print the region on a PostScript printer.
1229See definition of `call-process-region' for calling conventions. The fourth and
1230the sixth arguments are both nil."
52cf535f 1231 :type 'function
bc0d41bd 1232 :group 'ps-print-printer)
52cf535f 1233
bcc0d457 1234;;; Page layout
12d89a2e 1235
bcc0d457
RS
1236;; All page dimensions are in PostScript points.
1237;; 1 inch == 2.54 cm == 72 points
1238;; 1 cm == (/ 1 2.54) inch == (/ 72 2.54) points
1239
1240;; Letter 8.5 inch x 11.0 inch
1241;; Legal 8.5 inch x 14.0 inch
1242;; A4 8.26 inch x 11.69 inch = 21.0 cm x 29.7 cm
1243
1244;; LetterSmall 7.68 inch x 10.16 inch
1245;; Tabloid 11.0 inch x 17.0 inch
1246;; Ledger 17.0 inch x 11.0 inch
1247;; Statement 5.5 inch x 8.5 inch
1248;; Executive 7.5 inch x 10.0 inch
1249;; A3 11.69 inch x 16.5 inch = 29.7 cm x 42.0 cm
1250;; A4Small 7.47 inch x 10.85 inch
1251;; B4 10.125 inch x 14.33 inch
1252;; B5 7.16 inch x 10.125 inch
1253
e0af0d3e 1254(defcustom ps-page-dimensions-database
bc0d41bd
KH
1255 (list (list 'a4 (/ (* 72 21.0) 2.54) (/ (* 72 29.7) 2.54) "A4")
1256 (list 'a3 (/ (* 72 29.7) 2.54) (/ (* 72 42.0) 2.54) "A3")
1257 (list 'letter (* 72 8.5) (* 72 11.0) "Letter")
1258 (list 'legal (* 72 8.5) (* 72 14.0) "Legal")
1259 (list 'letter-small (* 72 7.68) (* 72 10.16) "LetterSmall")
1260 (list 'tabloid (* 72 11.0) (* 72 17.0) "Tabloid")
1261 (list 'ledger (* 72 17.0) (* 72 11.0) "Ledger")
1262 (list 'statement (* 72 5.5) (* 72 8.5) "Statement")
1263 (list 'executive (* 72 7.5) (* 72 10.0) "Executive")
1264 (list 'a4small (* 72 7.47) (* 72 10.85) "A4Small")
1265 (list 'b4 (* 72 10.125) (* 72 14.33) "B4")
1266 (list 'b5 (* 72 7.16) (* 72 10.125) "B5"))
1267 "*List associating a symbolic paper type to its width, height and doc media.
1268See `ps-paper-type'."
e0af0d3e
RS
1269 :type '(repeat (list :tag "Paper Type"
1270 (symbol :tag "Name")
1271 (number :tag "Width")
bc0d41bd
KH
1272 (number :tag "Height")
1273 (string :tag "Media")))
1274 :group 'ps-print-page)
e0af0d3e 1275
857686a6 1276;;;###autoload
e0af0d3e 1277(defcustom ps-paper-type 'letter
bc0d41bd 1278 "*Specify the size of paper to format for.
090be653 1279Should be one of the paper types defined in `ps-page-dimensions-database', for
e0af0d3e
RS
1280example `letter', `legal' or `a4'."
1281 :type '(symbol :validate (lambda (wid)
87a16a06
RS
1282 (if (assq (widget-value wid)
1283 ps-page-dimensions-database)
e0af0d3e
RS
1284 nil
1285 (widget-put wid :error "Unknown paper size")
1286 wid)))
bc0d41bd 1287 :group 'ps-print-page)
e0af0d3e 1288
87a16a06 1289(defcustom ps-landscape-mode nil
e0af0d3e
RS
1290 "*Non-nil means print in landscape mode."
1291 :type 'boolean
bc0d41bd 1292 :group 'ps-print-page)
e0af0d3e 1293
857686a6 1294(defcustom ps-print-control-characters 'control-8-bit
bc0d41bd
KH
1295 "*Specify the printable form for control and 8-bit characters.
1296That is, instead of sending, for example, a ^D (\\004) to printer,
915293a2 1297it is sent the string \"^D\".
6bdb808e 1298
857686a6 1299Valid values are:
6bdb808e 1300
984e7bd9 1301 `8-bit' This is the value to use when you want an ASCII encoding of
d3ab8dac
KH
1302 any control or non-ASCII character. Control characters are
1303 encoded as \"^D\", and non-ASCII characters have an
1304 octal encoding.
6bdb808e 1305
984e7bd9 1306 `control-8-bit' This is the value to use when you want an ASCII encoding of
d3ab8dac
KH
1307 any control character, whether it is 7 or 8-bit.
1308 European 8-bits accented characters are printed according
1309 the current font.
6bdb808e 1310
c82b4a75 1311 `control' Only ASCII control characters have an ASCII encoding.
d3ab8dac
KH
1312 European 8-bits accented characters are printed according
1313 the current font.
6bdb808e 1314
984e7bd9 1315 nil No ASCII encoding. Any character is printed according the
d3ab8dac 1316 current font.
6bdb808e 1317
857686a6 1318Any other value is treated as nil."
bc0d41bd
KH
1319 :type '(choice :tag "Control Char"
1320 (const 8-bit) (const control-8-bit)
ab2739aa 1321 (const control) (other :tag "nil" nil))
857686a6
RS
1322 :group 'ps-print)
1323
bc0d41bd
KH
1324(defcustom ps-n-up-printing 1
1325 "*Specify the number of pages per sheet paper."
1326 :type '(integer
1327 :tag "N Up Printing"
1328 :validate
1329 (lambda (wid)
1330 (if (and (< 0 (widget-value wid))
1331 (<= (widget-value wid) 100))
1332 nil
1333 (widget-put
1334 wid :error
1335 "Number of pages per sheet paper must be between 1 and 100.")
1336 wid)))
1337 :group 'ps-print-n-up)
1338
1339(defcustom ps-n-up-margin (/ (* 72 1.0) 2.54) ; 1 cm
1340 "*Specify the margin in points between the sheet border and n-up printing."
1341 :type 'number
1342 :group 'ps-print-n-up)
1343
1344(defcustom ps-n-up-border-p t
1345 "*Non-nil means a border is drawn around each page."
1346 :type 'boolean
1347 :group 'ps-print-n-up)
1348
1349(defcustom ps-n-up-filling 'left-top
1350 "*Specify how page matrix is filled on each sheet of paper.
1351
1352Following are the valid values for `ps-n-up-filling' with a filling example
1353using a 3x4 page matrix:
1354
1355 `left-top' 1 2 3 4 `left-bottom' 9 10 11 12
1356 5 6 7 8 5 6 7 8
1357 9 10 11 12 1 2 3 4
1358
1359 `right-top' 4 3 2 1 `right-bottom' 12 11 10 9
1360 8 7 6 5 8 7 6 5
1361 12 11 10 9 4 3 2 1
1362
1363 `top-left' 1 4 7 10 `bottom-left' 3 6 9 12
1364 2 5 8 11 2 5 8 11
1365 3 6 9 12 1 4 7 10
1366
1367 `top-right' 10 7 4 1 `bottom-right' 12 9 6 3
1368 11 8 5 2 11 8 5 2
1369 12 9 6 3 10 7 4 1
1370
1371Any other value is treated as `left-top'."
1372 :type '(choice :tag "N-Up Filling"
1373 (const left-top) (const left-bottom)
1374 (const right-top) (const right-bottom)
1375 (const top-left) (const bottom-left)
1376 (const top-right) (const bottom-right))
1377 :group 'ps-print-n-up)
1378
e0af0d3e 1379(defcustom ps-number-of-columns (if ps-landscape-mode 2 1)
bc0d41bd 1380 "*Specify the number of columns"
87a16a06
RS
1381 :type 'number
1382 :group 'ps-print)
1383
535efc38 1384(defcustom ps-zebra-stripes nil
87a16a06 1385 "*Non-nil means print zebra stripes.
bc0d41bd 1386See also documentation for `ps-zebra-stripe-height' and `ps-zebra-gray'."
87a16a06 1387 :type 'boolean
bc0d41bd 1388 :group 'ps-print-zebra)
87a16a06 1389
535efc38 1390(defcustom ps-zebra-stripe-height 3
87a16a06 1391 "*Number of zebra stripe lines.
bc0d41bd 1392See also documentation for `ps-zebra-stripes' and `ps-zebra-gray'."
87a16a06 1393 :type 'number
bc0d41bd
KH
1394 :group 'ps-print-zebra)
1395
1396(defcustom ps-zebra-gray 0.95
1397 "*Zebra stripe gray scale.
1398See also documentation for `ps-zebra-stripes' and `ps-zebra-stripe-height'."
1399 :type 'number
1400 :group 'ps-print-zebra)
87a16a06
RS
1401
1402(defcustom ps-line-number nil
1403 "*Non-nil means print line number."
1404 :type 'boolean
1405 :group 'ps-print)
1406
1407(defcustom ps-print-background-image nil
1408 "*EPS image list to be printed on background.
1409
1410The elements are:
1411
1412 (FILENAME X Y XSCALE YSCALE ROTATION PAGES...)
1413
1414FILENAME is a file name which contains an EPS image or some PostScript
1415programming like EPS.
1416FILENAME is ignored, if it doesn't exist or is read protected.
1417
1418X and Y are relative positions on paper to put the image.
1419If X and Y are nil, the image is centralized on paper.
1420
1421XSCALE and YSCALE are scale factor to be applied to image before printing.
1422If XSCALE and YSCALE are nil, the original size is used.
1423
1424ROTATION is the image rotation angle; if nil, the default is 0.
1425
1426PAGES designates the page to print background image.
1427PAGES may be a number or a cons cell (FROM . TO) designating FROM page
1428to TO page.
1429If PAGES is nil, print background image on all pages.
1430
1431X, Y, XSCALE, YSCALE and ROTATION may be a floating point number,
1432an integer number or a string. If it is a string, the string should contain
1433PostScript programming that returns a float or integer value.
1434
1435For example, if you wish to print an EPS image on all pages do:
1436
1437 '((\"~/images/EPS-image.ps\"))"
bc0d41bd 1438 :type '(repeat (list (file :tag "EPS File")
35378a09
KH
1439 (choice :tag "X" number string (const nil))
1440 (choice :tag "Y" number string (const nil))
1441 (choice :tag "X Scale" number string (const nil))
1442 (choice :tag "Y Scale" number string (const nil))
1443 (choice :tag "Rotation" number string (const nil))
1444 (repeat :tag "Pages" :inline t
bc0d41bd 1445 (radio (integer :tag "Page")
35378a09
KH
1446 (cons :tag "Range"
1447 (integer :tag "From")
1448 (integer :tag "To"))))))
bc0d41bd 1449 :group 'ps-print-background)
87a16a06
RS
1450
1451(defcustom ps-print-background-text nil
1452 "*Text list to be printed on background.
1453
1454The elements are:
1455
1456 (STRING X Y FONT FONTSIZE GRAY ROTATION PAGES...)
1457
1458STRING is the text to be printed on background.
1459
1460X and Y are positions on paper to put the text.
1461If X and Y are nil, the text is positioned at lower left corner.
1462
1463FONT is a font name to be used on printing the text.
1464If nil, \"Times-Roman\" is used.
1465
1466FONTSIZE is font size to be used, if nil, 200 is used.
1467
1468GRAY is the text gray factor (should be very light like 0.8).
1469If nil, the default is 0.85.
1470
1471ROTATION is the text rotation angle; if nil, the angle is given by
1472the diagonal from lower left corner to upper right corner.
1473
1474PAGES designates the page to print background text.
1475PAGES may be a number or a cons cell (FROM . TO) designating FROM page
1476to TO page.
1477If PAGES is nil, print background text on all pages.
1478
1479X, Y, FONTSIZE, GRAY and ROTATION may be a floating point number,
1480an integer number or a string. If it is a string, the string should contain
1481PostScript programming that returns a float or integer value.
1482
1483For example, if you wish to print text \"Preliminary\" on all pages do:
1484
1485 '((\"Preliminary\"))"
bc0d41bd 1486 :type '(repeat (list (string :tag "Text")
35378a09
KH
1487 (choice :tag "X" number string (const nil))
1488 (choice :tag "Y" number string (const nil))
1489 (choice :tag "Font" string (const nil))
1490 (choice :tag "Fontsize" number string (const nil))
1491 (choice :tag "Gray" number string (const nil))
1492 (choice :tag "Rotation" number string (const nil))
1493 (repeat :tag "Pages" :inline t
bc0d41bd 1494 (radio (integer :tag "Page")
35378a09
KH
1495 (cons :tag "Range"
1496 (integer :tag "From")
1497 (integer :tag "To"))))))
bc0d41bd 1498 :group 'ps-print-background)
bcc0d457
RS
1499
1500;;; Horizontal layout
1501
1502;; ------------------------------------------
1503;; | | | | | | | |
1504;; | lm | text | ic | text | ic | text | rm |
1505;; | | | | | | | |
1506;; ------------------------------------------
1507
e0af0d3e
RS
1508(defcustom ps-left-margin (/ (* 72 2.0) 2.54) ; 2 cm
1509 "*Left margin in points (1/72 inch)."
1510 :type 'number
1511 :group 'ps-print-horizontal)
bcc0d457 1512
e0af0d3e
RS
1513(defcustom ps-right-margin (/ (* 72 2.0) 2.54) ; 2 cm
1514 "*Right margin in points (1/72 inch)."
1515 :type 'number
1516 :group 'ps-print-horizontal)
bcc0d457 1517
e0af0d3e
RS
1518(defcustom ps-inter-column (/ (* 72 2.0) 2.54) ; 2 cm
1519 "*Horizontal space between columns in points (1/72 inch)."
1520 :type 'number
1521 :group 'ps-print-horizontal)
bcc0d457
RS
1522
1523;;; Vertical layout
1524
1525;; |--------|
1526;; | tm |
1527;; |--------|
1528;; | header |
1529;; |--------|
1530;; | ho |
1531;; |--------|
1532;; | text |
1533;; |--------|
1534;; | bm |
1535;; |--------|
1536
e0af0d3e
RS
1537(defcustom ps-bottom-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
1538 "*Bottom margin in points (1/72 inch)."
1539 :type 'number
1540 :group 'ps-print-vertical)
bcc0d457 1541
e0af0d3e
RS
1542(defcustom ps-top-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
1543 "*Top margin in points (1/72 inch)."
1544 :type 'number
1545 :group 'ps-print-vertical)
bcc0d457 1546
e0af0d3e
RS
1547(defcustom ps-header-offset (/ (* 72 1.0) 2.54) ; 1.0 cm
1548 "*Vertical space in points (1/72 inch) between the main text and the header."
1549 :type 'number
1550 :group 'ps-print-vertical)
bcc0d457 1551
e0af0d3e 1552(defcustom ps-header-line-pad 0.15
bcc0d457 1553 "*Portion of a header title line height to insert between the header frame
e0af0d3e
RS
1554and the text it contains, both in the vertical and horizontal directions."
1555 :type 'number
1556 :group 'ps-print-vertical)
bcc0d457
RS
1557
1558;;; Header setup
12d89a2e 1559
e0af0d3e 1560(defcustom ps-print-header t
86c10ecb
RS
1561 "*Non-nil means print a header at the top of each page.
1562By default, the header displays the buffer name, page number, and, if
1563the buffer is visiting a file, the file's directory. Headers are
ae7f6761 1564customizable by changing variables `ps-left-header' and
e0af0d3e
RS
1565`ps-right-header'."
1566 :type 'boolean
1567 :group 'ps-print-header)
1568
12b88fff
RS
1569(defcustom ps-print-only-one-header nil
1570 "*Non-nil means print only one header at the top of each page.
1571This is useful when printing more than one column, so it is possible
1572to have only one header over all columns or one header per column.
1573See also `ps-print-header'."
1574 :type 'boolean
1575 :group 'ps-print-header)
1576
e0af0d3e
RS
1577(defcustom ps-print-header-frame t
1578 "*Non-nil means draw a gaudy frame around the header."
1579 :type 'boolean
1580 :group 'ps-print-header)
1581
1582(defcustom ps-header-lines 2
8bd22fcf 1583 "*Number of lines to display in page header, when generating PostScript."
e0af0d3e
RS
1584 :type 'integer
1585 :group 'ps-print-header)
bcc0d457
RS
1586(make-variable-buffer-local 'ps-header-lines)
1587
e0af0d3e 1588(defcustom ps-show-n-of-n t
00aa16af 1589 "*Non-nil means show page numbers as N/M, meaning page N of M.
8bd22fcf
KH
1590NOTE: page numbers are displayed as part of headers,
1591 see variable `ps-print-headers'."
e0af0d3e
RS
1592 :type 'boolean
1593 :group 'ps-print-header)
12d89a2e 1594
bc0d41bd
KH
1595(defcustom ps-spool-config 'lpr-switches
1596 "*Specify who is responsable for setting duplex and page size switches.
1597
1598Valid values are:
1599
1600 `lpr-switches' duplex and page size are configured by `ps-lpr-switches'.
1601 Don't forget to set `ps-lpr-switches' to select duplex
1602 printing for your printer.
1603
1604 `setpagedevice' duplex and page size are configured by ps-print using the
1605 setpagedevice PostScript operator.
1606
1607 nil duplex and page size are configured by ps-print *not* using
1608 the setpagedevice PostScript operator.
1609
1610Any other value is treated as nil.
1611
1612WARNING: The setpagedevice PostScript operator affects ghostview utility when
1613 viewing file generated using landscape. Also on some printers,
1614 setpagedevice affects zebra stripes; on other printers, setpagedevice
1615 affects the left margin.
1616 Besides all that, if your printer does not have the paper size
1617 specified by setpagedevice, your printing will be aborted.
1618 So, if you need to use setpagedevice, set `ps-spool-config' to
1619 `setpagedevice', generate a test file and send it to your printer; if
1620 the printed file isn't ok, set `ps-spool-config' to nil."
1621 :type '(choice :tag "Spool Config"
1622 (const lpr-switches) (const setpagedevice)
1623 (other :tag "nil" nil))
1624 :group 'ps-print-header)
1625
1626(defcustom ps-spool-duplex nil ; Not many people have duplex printers,
1627 ; so default to nil.
1628 "*Non-nil generates PostScript for a two-sided printer.
1629For a duplex printer, the `ps-spool-*' and `ps-print-*' commands will insert
1630blank pages as needed between print jobs so that the next buffer printed will
1631start on the right page. Also, if headers are turned on, the headers will be
1632reversed on duplex printers so that the page numbers fall to the left on
1633even-numbered pages."
1634 :type 'boolean
1635 :group 'ps-print-header)
1636
1637(defcustom ps-spool-tumble nil
1638 "*Specify how the page images on opposite sides of a sheet are oriented.
1639If `ps-spool-tumble' is nil, produces output suitable for binding on the left or
1640right. If `ps-spool-tumble' is non-nil, produces output suitable for binding at
1641the top or bottom.
1642
1643It has effect only when `ps-spool-duplex' is non-nil."
e0af0d3e
RS
1644 :type 'boolean
1645 :group 'ps-print-header)
bcc0d457
RS
1646
1647;;; Fonts
1648
e0af0d3e 1649(defcustom ps-font-info-database
bcc0d457 1650 '((Courier ; the family key
12b88fff
RS
1651 (fonts (normal . "Courier")
1652 (bold . "Courier-Bold")
1653 (italic . "Courier-Oblique")
1654 (bold-italic . "Courier-BoldOblique"))
1655 (size . 10.0)
1656 (line-height . 10.55)
1657 (space-width . 6.0)
1658 (avg-char-width . 6.0))
bcc0d457 1659 (Helvetica ; the family key
12b88fff
RS
1660 (fonts (normal . "Helvetica")
1661 (bold . "Helvetica-Bold")
1662 (italic . "Helvetica-Oblique")
1663 (bold-italic . "Helvetica-BoldOblique"))
1664 (size . 10.0)
1665 (line-height . 11.56)
1666 (space-width . 2.78)
1667 (avg-char-width . 5.09243))
bcc0d457 1668 (Times
12b88fff
RS
1669 (fonts (normal . "Times-Roman")
1670 (bold . "Times-Bold")
1671 (italic . "Times-Italic")
1672 (bold-italic . "Times-BoldItalic"))
1673 (size . 10.0)
1674 (line-height . 11.0)
1675 (space-width . 2.5)
334cc3b7 1676 (avg-char-width . 4.71432))
bcc0d457 1677 (Palatino
12b88fff
RS
1678 (fonts (normal . "Palatino-Roman")
1679 (bold . "Palatino-Bold")
1680 (italic . "Palatino-Italic")
1681 (bold-italic . "Palatino-BoldItalic"))
1682 (size . 10.0)
1683 (line-height . 12.1)
1684 (space-width . 2.5)
1685 (avg-char-width . 5.08676))
bcc0d457 1686 (Helvetica-Narrow
12b88fff
RS
1687 (fonts (normal . "Helvetica-Narrow")
1688 (bold . "Helvetica-Narrow-Bold")
1689 (italic . "Helvetica-Narrow-Oblique")
1690 (bold-italic . "Helvetica-Narrow-BoldOblique"))
1691 (size . 10.0)
1692 (line-height . 11.56)
1693 (space-width . 2.2796)
1694 (avg-char-width . 4.17579))
bcc0d457 1695 (NewCenturySchlbk
12b88fff
RS
1696 (fonts (normal . "NewCenturySchlbk-Roman")
1697 (bold . "NewCenturySchlbk-Bold")
1698 (italic . "NewCenturySchlbk-Italic")
1699 (bold-italic . "NewCenturySchlbk-BoldItalic"))
1700 (size . 10.0)
334cc3b7 1701 (line-height . 12.15)
12b88fff
RS
1702 (space-width . 2.78)
1703 (avg-char-width . 5.31162))
bcc0d457
RS
1704 ;; got no bold for the next ones
1705 (AvantGarde-Book
12b88fff
RS
1706 (fonts (normal . "AvantGarde-Book")
1707 (italic . "AvantGarde-BookOblique"))
1708 (size . 10.0)
1709 (line-height . 11.77)
1710 (space-width . 2.77)
1711 (avg-char-width . 5.45189))
bcc0d457 1712 (AvantGarde-Demi
12b88fff
RS
1713 (fonts (normal . "AvantGarde-Demi")
1714 (italic . "AvantGarde-DemiOblique"))
1715 (size . 10.0)
1716 (line-height . 12.72)
1717 (space-width . 2.8)
1718 (avg-char-width . 5.51351))
bcc0d457 1719 (Bookman-Demi
12b88fff
RS
1720 (fonts (normal . "Bookman-Demi")
1721 (italic . "Bookman-DemiItalic"))
1722 (size . 10.0)
1723 (line-height . 11.77)
1724 (space-width . 3.4)
1725 (avg-char-width . 6.05946))
bcc0d457 1726 (Bookman-Light
12b88fff
RS
1727 (fonts (normal . "Bookman-Light")
1728 (italic . "Bookman-LightItalic"))
1729 (size . 10.0)
1730 (line-height . 11.79)
1731 (space-width . 3.2)
1732 (avg-char-width . 5.67027))
bcc0d457
RS
1733 ;; got no bold and no italic for the next ones
1734 (Symbol
12b88fff
RS
1735 (fonts (normal . "Symbol"))
1736 (size . 10.0)
1737 (line-height . 13.03)
1738 (space-width . 2.5)
1739 (avg-char-width . 3.24324))
bcc0d457 1740 (Zapf-Dingbats
12b88fff
RS
1741 (fonts (normal . "Zapf-Dingbats"))
1742 (size . 10.0)
1743 (line-height . 9.63)
1744 (space-width . 2.78)
1745 (avg-char-width . 2.78))
bcc0d457 1746 (Zapf-Chancery-MediumItalic
12b88fff
RS
1747 (fonts (normal . "Zapf-Chancery-MediumItalic"))
1748 (size . 10.0)
1749 (line-height . 11.45)
1750 (space-width . 2.2)
1751 (avg-char-width . 4.10811))
87a16a06 1752 )
bcc0d457
RS
1753 "*Font info database: font family (the key), name, bold, italic, bold-italic,
1754reference size, line height, space width, average character width.
1755To get the info for another specific font (say Helvetica), do the following:
1756- create a new buffer
1757- generate the PostScript image to a file (C-u M-x ps-print-buffer)
8bd22fcf 1758- open this file and delete the leading `%' (which is the PostScript
bcc0d457 1759 comment character) from the line
87a16a06 1760 `% 3 cm 20 cm moveto 10 /Courier ReportFontInfo showpage'
bcc0d457 1761 to get the line
87a16a06 1762 `3 cm 20 cm moveto 10 /Helvetica ReportFontInfo showpage'
bcc0d457 1763- add the values to `ps-font-info-database'.
e0af0d3e
RS
1764You can get all the fonts of YOUR printer using `ReportAllFontInfo'."
1765 :type '(repeat (list :tag "Font Definition"
12b88fff 1766 (symbol :tag "Font Family")
334cc3b7
AS
1767 (cons :format "%v"
1768 (const :format "" fonts)
1769 (repeat :tag "Faces"
1770 (cons (choice (const normal)
12b88fff
RS
1771 (const bold)
1772 (const italic)
1773 (const bold-italic)
1774 (symbol :tag "Face"))
1775 (string :tag "Font Name"))))
334cc3b7
AS
1776 (cons :format "%v"
1777 (const :format "" size)
12b88fff 1778 (number :tag "Reference Size"))
334cc3b7
AS
1779 (cons :format "%v"
1780 (const :format "" line-height)
12b88fff 1781 (number :tag "Line Height"))
334cc3b7
AS
1782 (cons :format "%v"
1783 (const :format "" space-width)
12b88fff 1784 (number :tag "Space Width"))
334cc3b7
AS
1785 (cons :format "%v"
1786 (const :format "" avg-char-width)
12b88fff 1787 (number :tag "Average Character Width"))))
e0af0d3e
RS
1788 :group 'ps-print-font)
1789
1790(defcustom ps-font-family 'Courier
d3ab8dac 1791 "*Font family name for ordinary text, when generating PostScript."
e0af0d3e
RS
1792 :type 'symbol
1793 :group 'ps-print-font)
1794
7d8b7e8e 1795(defcustom ps-font-size '(7 . 8.5)
d3ab8dac 1796 "*Font size, in points, for ordinary text, when generating PostScript."
7d8b7e8e
KH
1797 :type '(choice (number :tag "Text Size")
1798 (cons :tag "Landscape/Portrait"
1799 (number :tag "Landscape Text Size")
1800 (number :tag "Portrait Text Size")))
e0af0d3e
RS
1801 :group 'ps-print-font)
1802
1803(defcustom ps-header-font-family 'Helvetica
d3ab8dac 1804 "*Font family name for text in the header, when generating PostScript."
e0af0d3e
RS
1805 :type 'symbol
1806 :group 'ps-print-font)
1807
7d8b7e8e 1808(defcustom ps-header-font-size '(10 . 12)
d3ab8dac 1809 "*Font size, in points, for text in the header, when generating PostScript."
7d8b7e8e
KH
1810 :type '(choice (number :tag "Header Size")
1811 (cons :tag "Landscape/Portrait"
1812 (number :tag "Landscape Header Size")
1813 (number :tag "Portrait Header Size")))
e0af0d3e
RS
1814 :group 'ps-print-font)
1815
7d8b7e8e 1816(defcustom ps-header-title-font-size '(12 . 14)
d3ab8dac 1817 "*Font size, in points, for the top line of text in header, in PostScript."
7d8b7e8e
KH
1818 :type '(choice (number :tag "Header Title Size")
1819 (cons :tag "Landscape/Portrait"
1820 (number :tag "Landscape Header Title Size")
1821 (number :tag "Portrait Header Title Size")))
e0af0d3e 1822 :group 'ps-print-font)
bcc0d457
RS
1823
1824;;; Colors
1825
87a16a06
RS
1826;; Printing color requires x-color-values.
1827(defcustom ps-print-color-p (or (fboundp 'x-color-values) ; Emacs
857686a6
RS
1828 (fboundp 'color-instance-rgb-components))
1829 ; XEmacs
bc0d41bd 1830 "*Non-nil means print the buffer's text in color."
e0af0d3e
RS
1831 :type 'boolean
1832 :group 'ps-print-color)
12d89a2e 1833
e0af0d3e
RS
1834(defcustom ps-default-fg '(0.0 0.0 0.0)
1835 "*RGB values of the default foreground color. Defaults to black."
1836 :type '(list (number :tag "Red") (number :tag "Green") (number :tag "Blue"))
1837 :group 'ps-print-color)
12d89a2e 1838
e0af0d3e
RS
1839(defcustom ps-default-bg '(1.0 1.0 1.0)
1840 "*RGB values of the default background color. Defaults to white."
1841 :type '(list (number :tag "Red") (number :tag "Green") (number :tag "Blue"))
1842 :group 'ps-print-color)
12d89a2e 1843
e0af0d3e 1844(defcustom ps-auto-font-detect t
12d89a2e 1845 "*Non-nil means automatically detect bold/italic face attributes.
7f72c06f 1846If nil, we rely solely on the lists `ps-bold-faces', `ps-italic-faces',
e0af0d3e
RS
1847and `ps-underlined-faces'."
1848 :type 'boolean
1849 :group 'ps-print-font)
12d89a2e 1850
e0af0d3e 1851(defcustom ps-bold-faces
090be653
RS
1852 (unless ps-print-color-p
1853 '(font-lock-function-name-face
1854 font-lock-builtin-face
1855 font-lock-variable-name-face
1856 font-lock-keyword-face
1857 font-lock-warning-face))
86c10ecb 1858 "*A list of the \(non-bold\) faces that should be printed in bold font.
8bd22fcf 1859This applies to generating PostScript."
e0af0d3e
RS
1860 :type '(repeat face)
1861 :group 'ps-print-face)
12d89a2e 1862
e0af0d3e 1863(defcustom ps-italic-faces
090be653
RS
1864 (unless ps-print-color-p
1865 '(font-lock-variable-name-face
8bd22fcf 1866 font-lock-type-face
090be653
RS
1867 font-lock-string-face
1868 font-lock-comment-face
1869 font-lock-warning-face))
86c10ecb 1870 "*A list of the \(non-italic\) faces that should be printed in italic font.
8bd22fcf 1871This applies to generating PostScript."
e0af0d3e
RS
1872 :type '(repeat face)
1873 :group 'ps-print-face)
12d89a2e 1874
e0af0d3e 1875(defcustom ps-underlined-faces
090be653
RS
1876 (unless ps-print-color-p
1877 '(font-lock-function-name-face
883212ce 1878 font-lock-constant-face
090be653 1879 font-lock-warning-face))
86c10ecb 1880 "*A list of the \(non-underlined\) faces that should be printed underlined.
8bd22fcf 1881This applies to generating PostScript."
e0af0d3e
RS
1882 :type '(repeat face)
1883 :group 'ps-print-face)
12d89a2e 1884
e0af0d3e 1885(defcustom ps-left-header
12d89a2e 1886 (list 'ps-get-buffer-name 'ps-header-dirpart)
bcc0d457 1887 "*The items to display (each on a line) on the left part of the page header.
8bd22fcf 1888This applies to generating PostScript.
12d89a2e 1889
86c10ecb 1890The value should be a list of strings and symbols, each representing an
12d89a2e
RS
1891entry in the PostScript array HeaderLinesLeft.
1892
1893Strings are inserted unchanged into the array; those representing
1894PostScript string literals should be delimited with PostScript string
1895delimiters '(' and ')'.
1896
1897For symbols with bound functions, the function is called and should
1898return a string to be inserted into the array. For symbols with bound
1899values, the value should be a string to be inserted into the array.
1900In either case, function or variable, the string value has PostScript
e0af0d3e
RS
1901string delimiters added to it."
1902 :type '(repeat (choice string symbol))
a6c6e755 1903 :group 'ps-print-header)
12d89a2e
RS
1904(make-variable-buffer-local 'ps-left-header)
1905
e0af0d3e 1906(defcustom ps-right-header
090be653 1907 (list "/pagenumberstring load" 'time-stamp-mon-dd-yyyy 'time-stamp-hh:mm:ss)
bcc0d457 1908 "*The items to display (each on a line) on the right part of the page header.
8bd22fcf 1909This applies to generating PostScript.
12d89a2e 1910
86c10ecb 1911See the variable `ps-left-header' for a description of the format of
e0af0d3e
RS
1912this variable."
1913 :type '(repeat (choice string symbol))
a6c6e755 1914 :group 'ps-print-header)
12d89a2e 1915(make-variable-buffer-local 'ps-right-header)
ef2cbb24 1916
e0af0d3e
RS
1917(defcustom ps-razzle-dazzle t
1918 "*Non-nil means report progress while formatting buffer."
1919 :type 'boolean
1920 :group 'ps-print)
12d89a2e 1921
a18ed129 1922(defcustom ps-adobe-tag "%!PS-Adobe-3.0\n"
12d89a2e
RS
1923 "*Contains the header line identifying the output as PostScript.
1924By default, `ps-adobe-tag' contains the standard identifier. Some
a18ed129
RS
1925printers require slightly different versions of this line."
1926 :type 'string
1927 :group 'ps-print)
12d89a2e 1928
e0af0d3e 1929(defcustom ps-build-face-reference t
12d89a2e
RS
1930 "*Non-nil means build the reference face lists.
1931
d3ab8dac 1932ps-print sets this value to nil after it builds its internal reference
12d89a2e
RS
1933lists of bold and italic faces. By settings its value back to t, you
1934can force ps-print to rebuild the lists the next time you invoke one
86c10ecb 1935of the ...-with-faces commands.
12d89a2e
RS
1936
1937You should set this value back to t after you change the attributes of
1938any face, or create new faces. Most users shouldn't have to worry
e0af0d3e
RS
1939about its setting, though."
1940 :type 'boolean
1941 :group 'ps-print-face)
12d89a2e 1942
e0af0d3e 1943(defcustom ps-always-build-face-reference nil
12d89a2e
RS
1944 "*Non-nil means always rebuild the reference face lists.
1945
1946If this variable is non-nil, ps-print will rebuild its internal
1947reference lists of bold and italic faces *every* time one of the
496725ad 1948...-with-faces commands is called. Most users shouldn't need to set this
e0af0d3e
RS
1949variable."
1950 :type 'boolean
1951 :group 'ps-print-face)
ef2cbb24 1952
bc0d41bd
KH
1953(defcustom ps-banner-page-when-duplexing nil
1954 "*Non-nil means the very first page is skipped.
1955It's like the very first character of buffer (or region) is ^L (\\014)."
1956 :type 'boolean
1957 :group 'ps-print-header)
1958
ef2cbb24 1959;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e 1960;; User commands
ef2cbb24 1961
00aa16af 1962;;;###autoload
ef2cbb24 1963(defun ps-print-buffer (&optional filename)
12d89a2e 1964 "Generate and print a PostScript image of the buffer.
ef2cbb24 1965
5ac0cb14
RS
1966Interactively, when you use a prefix argument (C-u), the command
1967prompts the user for a file name, and saves the PostScript image
1968in that file instead of sending it to the printer.
ef2cbb24 1969
5ac0cb14 1970Noninteractively, the argument FILENAME is treated as follows: if it
ef2cbb24 1971is nil, send the image to the printer. If FILENAME is a string, save
79080fa0 1972the PostScript image in a file with that name."
00aa16af 1973 (interactive (list (ps-print-preprint current-prefix-arg)))
87a16a06 1974 (ps-print-without-faces (point-min) (point-max) filename))
ef2cbb24
RS
1975
1976
00aa16af 1977;;;###autoload
ef2cbb24 1978(defun ps-print-buffer-with-faces (&optional filename)
12d89a2e 1979 "Generate and print a PostScript image of the buffer.
12d89a2e 1980Like `ps-print-buffer', but includes font, color, and underline
107e7c70
KH
1981information in the generated image. This command works only if you
1982are using a window system, so it has a way to determine color values."
00aa16af 1983 (interactive (list (ps-print-preprint current-prefix-arg)))
87a16a06 1984 (ps-print-with-faces (point-min) (point-max) filename))
ef2cbb24 1985
ef2cbb24 1986
00aa16af 1987;;;###autoload
ef2cbb24 1988(defun ps-print-region (from to &optional filename)
12d89a2e 1989 "Generate and print a PostScript image of the region.
12d89a2e 1990Like `ps-print-buffer', but prints just the current region."
00aa16af 1991 (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
a18ed129 1992 (ps-print-without-faces from to filename t))
ef2cbb24 1993
ef2cbb24 1994
00aa16af 1995;;;###autoload
ef2cbb24 1996(defun ps-print-region-with-faces (from to &optional filename)
12d89a2e 1997 "Generate and print a PostScript image of the region.
12d89a2e 1998Like `ps-print-region', but includes font, color, and underline
107e7c70
KH
1999information in the generated image. This command works only if you
2000are using a window system, so it has a way to determine color values."
00aa16af 2001 (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
a18ed129 2002 (ps-print-with-faces from to filename t))
ef2cbb24 2003
ef2cbb24 2004
00aa16af 2005;;;###autoload
ef2cbb24 2006(defun ps-spool-buffer ()
12d89a2e 2007 "Generate and spool a PostScript image of the buffer.
12d89a2e
RS
2008Like `ps-print-buffer' except that the PostScript image is saved in a
2009local buffer to be sent to the printer later.
ef2cbb24 2010
12d89a2e 2011Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 2012 (interactive)
87a16a06 2013 (ps-spool-without-faces (point-min) (point-max)))
ef2cbb24 2014
ef2cbb24 2015
00aa16af 2016;;;###autoload
ef2cbb24 2017(defun ps-spool-buffer-with-faces ()
12d89a2e 2018 "Generate and spool a PostScript image of the buffer.
12d89a2e 2019Like `ps-spool-buffer', but includes font, color, and underline
107e7c70 2020information in the generated image. This command works only if you
1cd7962f 2021are using a window system, so it has a way to determine color values.
ef2cbb24 2022
12d89a2e 2023Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 2024 (interactive)
87a16a06 2025 (ps-spool-with-faces (point-min) (point-max)))
ef2cbb24 2026
ef2cbb24 2027
00aa16af 2028;;;###autoload
ef2cbb24 2029(defun ps-spool-region (from to)
12d89a2e 2030 "Generate a PostScript image of the region and spool locally.
12d89a2e 2031Like `ps-spool-buffer', but spools just the current region.
ef2cbb24 2032
12d89a2e 2033Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 2034 (interactive "r")
a18ed129 2035 (ps-spool-without-faces from to t))
ef2cbb24 2036
ef2cbb24 2037
00aa16af 2038;;;###autoload
ef2cbb24 2039(defun ps-spool-region-with-faces (from to)
12d89a2e 2040 "Generate a PostScript image of the region and spool locally.
12d89a2e 2041Like `ps-spool-region', but includes font, color, and underline
107e7c70 2042information in the generated image. This command works only if you
1cd7962f 2043are using a window system, so it has a way to determine color values.
ef2cbb24 2044
12d89a2e 2045Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 2046 (interactive "r")
a18ed129 2047 (ps-spool-with-faces from to t))
ef2cbb24 2048
00aa16af 2049;;;###autoload
ef2cbb24
RS
2050(defun ps-despool (&optional filename)
2051 "Send the spooled PostScript to the printer.
2052
79080fa0
RS
2053Interactively, when you use a prefix argument (C-u), the command
2054prompts the user for a file name, and saves the spooled PostScript
2055image in that file instead of sending it to the printer.
ef2cbb24 2056
298bfad9 2057Noninteractively, the argument FILENAME is treated as follows: if it
ef2cbb24 2058is nil, send the image to the printer. If FILENAME is a string, save
79080fa0 2059the PostScript image in a file with that name."
00aa16af
RS
2060 (interactive (list (ps-print-preprint current-prefix-arg)))
2061 (ps-do-despool filename))
12d89a2e 2062
bcc0d457
RS
2063;;;###autoload
2064(defun ps-line-lengths ()
06fb6aab 2065 "Display the correspondence between a line length and a font size,
bcc0d457
RS
2066using the current ps-print setup.
2067Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
2068 (interactive)
2069 (ps-line-lengths-internal))
2070
2071;;;###autoload
2072(defun ps-nb-pages-buffer (nb-lines)
06fb6aab
RS
2073 "Display number of pages to print this buffer, for various font heights.
2074The table depends on the current ps-print setup."
bcc0d457
RS
2075 (interactive (list (count-lines (point-min) (point-max))))
2076 (ps-nb-pages nb-lines))
2077
2078;;;###autoload
2079(defun ps-nb-pages-region (nb-lines)
06fb6aab
RS
2080 "Display number of pages to print the region, for various font heights.
2081The table depends on the current ps-print setup."
bcc0d457
RS
2082 (interactive (list (count-lines (mark) (point))))
2083 (ps-nb-pages nb-lines))
2084
2085;;;###autoload
2086(defun ps-setup ()
496725ad 2087 "Return the current PostScript-generation setup."
a18ed129
RS
2088 (format
2089 "
bc0d41bd
KH
2090\(setq ps-print-color-p %s
2091 ps-lpr-command %S
2092 ps-lpr-switches %s
2093 ps-printer-name %S
2094 ps-print-region-function %s
bcc0d457 2095
7d8b7e8e 2096 ps-paper-type %s
8bd22fcf
KH
2097 ps-landscape-mode %s
2098 ps-number-of-columns %s
bcc0d457 2099
8bd22fcf 2100 ps-zebra-stripes %s
01961237 2101 ps-zebra-stripe-height %s
bc0d41bd 2102 ps-zebra-gray %s
8bd22fcf 2103 ps-line-number %s
a18ed129 2104
7d8b7e8e 2105 ps-print-control-characters %s
d3ab8dac 2106
7d8b7e8e 2107 ps-print-background-image %s
857686a6 2108
7d8b7e8e 2109 ps-print-background-text %s
a18ed129 2110
7d8b7e8e 2111 ps-print-prologue-header %s
a18ed129 2112
bc0d41bd
KH
2113 ps-left-margin %s
2114 ps-right-margin %s
2115 ps-inter-column %s
2116 ps-bottom-margin %s
2117 ps-top-margin %s
2118 ps-header-offset %s
2119 ps-header-line-pad %s
2120 ps-print-header %s
2121 ps-print-only-one-header %s
2122 ps-print-header-frame %s
2123 ps-header-lines %s
2124 ps-show-n-of-n %s
2125 ps-spool-config %s
2126 ps-spool-duplex %s
2127 ps-spool-tumble %s
2128 ps-banner-page-when-duplexing %s
2129
2130 ps-n-up-printing %s
2131 ps-n-up-margin %s
2132 ps-n-up-border-p %s
2133 ps-n-up-filling %s
bcc0d457 2134
7d8b7e8e
KH
2135 ps-multibyte-buffer %s
2136 ps-font-family %s
a18ed129 2137 ps-font-size %s
7d8b7e8e 2138 ps-header-font-family %s
a18ed129
RS
2139 ps-header-font-size %s
2140 ps-header-title-font-size %s)
bcc0d457 2141"
a18ed129
RS
2142 ps-print-color-p
2143 ps-lpr-command
d3ab8dac
KH
2144 (ps-print-quote ps-lpr-switches)
2145 ps-printer-name
bc0d41bd 2146 (ps-print-quote ps-print-region-function)
d3ab8dac 2147 (ps-print-quote ps-paper-type)
a18ed129
RS
2148 ps-landscape-mode
2149 ps-number-of-columns
01961237
RS
2150 ps-zebra-stripes
2151 ps-zebra-stripe-height
bc0d41bd 2152 ps-zebra-gray
a18ed129 2153 ps-line-number
d3ab8dac
KH
2154 (ps-print-quote ps-print-control-characters)
2155 (ps-print-quote ps-print-background-image)
2156 (ps-print-quote ps-print-background-text)
2157 (ps-print-quote ps-print-prologue-header)
a18ed129
RS
2158 ps-left-margin
2159 ps-right-margin
2160 ps-inter-column
2161 ps-bottom-margin
2162 ps-top-margin
2163 ps-header-offset
2164 ps-header-line-pad
2165 ps-print-header
d3ab8dac 2166 ps-print-only-one-header
a18ed129
RS
2167 ps-print-header-frame
2168 ps-header-lines
2169 ps-show-n-of-n
bc0d41bd 2170 (ps-print-quote ps-spool-config)
a18ed129 2171 ps-spool-duplex
bc0d41bd
KH
2172 ps-spool-tumble
2173 ps-banner-page-when-duplexing
2174 ps-n-up-printing
2175 ps-n-up-margin
2176 ps-n-up-border-p
2177 (ps-print-quote ps-n-up-filling)
2178 (ps-print-quote ps-multibyte-buffer) ; see `ps-mule.el' and `ps-print-def.el'
d3ab8dac 2179 (ps-print-quote ps-font-family)
7d8b7e8e 2180 (ps-print-quote ps-font-size)
d3ab8dac 2181 (ps-print-quote ps-header-font-family)
7d8b7e8e
KH
2182 (ps-print-quote ps-header-font-size)
2183 (ps-print-quote ps-header-title-font-size)))
bcc0d457 2184
12d89a2e
RS
2185;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2186;; Utility functions and variables:
2187
d3ab8dac 2188(defun ps-print-quote (sym)
7d8b7e8e
KH
2189 (cond ((null sym)
2190 nil)
2191 ((or (symbolp sym) (listp sym))
2192 (format "'%S" sym))
2193 ((stringp sym)
2194 (format "%S" sym))
2195 (t
d3ab8dac
KH
2196 sym)))
2197
6770a60f
RS
2198(defvar ps-print-emacs-type
2199 (cond ((string-match "XEmacs" emacs-version) 'xemacs)
2200 ((string-match "Lucid" emacs-version) 'lucid)
2201 ((string-match "Epoch" emacs-version) 'epoch)
2202 (t 'emacs)))
2203
2204(if (or (eq ps-print-emacs-type 'lucid)
2205 (eq ps-print-emacs-type 'xemacs))
043620f4
KH
2206 (if (< emacs-minor-version 12)
2207 (setq ps-print-color-p nil))
12d89a2e
RS
2208 (require 'faces)) ; face-font, face-underline-p,
2209 ; x-font-regexp
2210
857686a6
RS
2211;; Return t if the device (which can be changed during an emacs session)
2212;; can handle colors.
2213;; This is function is not yet implemented for GNU emacs.
e65df0a1
KH
2214(cond ((and (eq ps-print-emacs-type 'xemacs)
2215 (>= emacs-minor-version 12)) ; xemacs
2216 (defun ps-color-device ()
2217 (eq (device-class) 'color))
2218 )
2219
2220 (t ; emacs
2221 (defun ps-color-device ()
2222 t)
2223 ))
2224
857686a6 2225
12d89a2e
RS
2226(require 'time-stamp)
2227
bc0d41bd
KH
2228(defconst ps-print-prologue-1
2229 "
2230% ISOLatin1Encoding stolen from ps_init.ps in GhostScript 2.6.1.4:
12d89a2e 2231/ISOLatin1Encoding where { pop } {
bcc0d457
RS
2232% -- The ISO Latin-1 encoding vector isn't known, so define it.
2233% -- The first half is the same as the standard encoding,
2234% -- except for minus instead of hyphen at code 055.
12d89a2e
RS
2235/ISOLatin1Encoding
2236StandardEncoding 0 45 getinterval aload pop
2237 /minus
2238StandardEncoding 46 82 getinterval aload pop
2239%*** NOTE: the following are missing in the Adobe documentation,
2240%*** but appear in the displayed table:
2241%*** macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240.
bcc0d457 2242% 0200 (128)
12d89a2e
RS
2243 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
2244 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
2245 /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent
2246 /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron
bcc0d457 2247% 0240 (160)
12d89a2e
RS
2248 /space /exclamdown /cent /sterling
2249 /currency /yen /brokenbar /section
2250 /dieresis /copyright /ordfeminine /guillemotleft
2251 /logicalnot /hyphen /registered /macron
2252 /degree /plusminus /twosuperior /threesuperior
2253 /acute /mu /paragraph /periodcentered
2254 /cedilla /onesuperior /ordmasculine /guillemotright
2255 /onequarter /onehalf /threequarters /questiondown
bcc0d457 2256% 0300 (192)
12d89a2e
RS
2257 /Agrave /Aacute /Acircumflex /Atilde
2258 /Adieresis /Aring /AE /Ccedilla
2259 /Egrave /Eacute /Ecircumflex /Edieresis
2260 /Igrave /Iacute /Icircumflex /Idieresis
2261 /Eth /Ntilde /Ograve /Oacute
2262 /Ocircumflex /Otilde /Odieresis /multiply
2263 /Oslash /Ugrave /Uacute /Ucircumflex
2264 /Udieresis /Yacute /Thorn /germandbls
bcc0d457 2265% 0340 (224)
12d89a2e
RS
2266 /agrave /aacute /acircumflex /atilde
2267 /adieresis /aring /ae /ccedilla
2268 /egrave /eacute /ecircumflex /edieresis
2269 /igrave /iacute /icircumflex /idieresis
2270 /eth /ntilde /ograve /oacute
2271 /ocircumflex /otilde /odieresis /divide
2272 /oslash /ugrave /uacute /ucircumflex
2273 /udieresis /yacute /thorn /ydieresis
2274256 packedarray def
2275} ifelse
2276
2277/reencodeFontISO { %def
2278 dup
87a16a06 2279 length 12 add dict % Make a new font (a new dict the same size
bcc0d457 2280 % as the old one) with room for our new symbols.
12d89a2e 2281
bcc0d457 2282 begin % Make the new font the current dictionary.
12d89a2e
RS
2283
2284
2285 { 1 index /FID ne
2286 { def } { pop pop } ifelse
bcc0d457
RS
2287 } forall % Copy each of the symbols from the old dictionary
2288 % to the new one except for the font ID.
12d89a2e 2289
12b88fff
RS
2290 currentdict /FontType get 0 ne {
2291 /Encoding ISOLatin1Encoding def % Override the encoding with
12d89a2e 2292 % the ISOLatin1 encoding.
12b88fff 2293 } if
12d89a2e
RS
2294
2295 % Use the font's bounding box to determine the ascent, descent,
2296 % and overall height; don't forget that these values have to be
2297 % transformed using the font's matrix.
bcc0d457
RS
2298
2299% ^ (x2 y2)
2300% | |
2301% | v
2302% | +----+ - -
2303% | | | ^
2304% | | | | Ascent (usually > 0)
2305% | | | |
2306% (0 0) -> +--+----+-------->
2307% | | |
2308% | | v Descent (usually < 0)
2309% (x1 y1) --> +----+ - -
2310
12b88fff 2311 currentdict /FontType get 0 ne {
e65df0a1 2312 /FontBBox load aload pop % -- x1 y1 x2 y2
12b88fff
RS
2313 FontMatrix transform /Ascent exch def pop
2314 FontMatrix transform /Descent exch def pop
2315 } {
2316 /PrimaryFont FDepVector 0 get def
2317 PrimaryFont /FontBBox get aload pop
2318 PrimaryFont /FontMatrix get transform /Ascent exch def pop
2319 PrimaryFont /FontMatrix get transform /Descent exch def pop
2320 } ifelse
2321
bcc0d457 2322 /FontHeight Ascent Descent sub def % use `sub' because descent < 0
12d89a2e 2323
bcc0d457 2324 % Define these in case they're not in the FontInfo
87a16a06
RS
2325 % (also, here they're easier to get to).
2326 /UnderlinePosition Descent 0.70 mul def
2327 /OverlinePosition Descent UnderlinePosition sub Ascent add def
2328 /StrikeoutPosition Ascent 0.30 mul def
e65df0a1
KH
2329 /LineThickness FontHeight 0.05 mul def
2330 /Xshadow FontHeight 0.08 mul def
2331 /Yshadow FontHeight -0.09 mul def
87a16a06
RS
2332 /SpaceBackground Descent neg UnderlinePosition add def
2333 /XBox Descent neg def
2334 /YBox LineThickness 0.7 mul def
12d89a2e 2335
bcc0d457
RS
2336 currentdict % Leave the new font on the stack
2337 end % Stop using the font as the current dictionary.
2338 definefont % Put the font into the font dictionary
2339 pop % Discard the returned font.
12d89a2e 2340} bind def
ef2cbb24 2341
bcc0d457 2342/DefFont { % Font definition
12d89a2e
RS
2343 findfont exch scalefont reencodeFontISO
2344} def
2345
bcc0d457 2346/F { % Font selection
12d89a2e 2347 findfont
87a16a06
RS
2348 dup /Ascent get /Ascent exch def
2349 dup /Descent get /Descent exch def
2350 dup /FontHeight get /FontHeight exch def
2351 dup /UnderlinePosition get /UnderlinePosition exch def
2352 dup /OverlinePosition get /OverlinePosition exch def
2353 dup /StrikeoutPosition get /StrikeoutPosition exch def
2354 dup /LineThickness get /LineThickness exch def
2355 dup /Xshadow get /Xshadow exch def
2356 dup /Yshadow get /Yshadow exch def
2357 dup /SpaceBackground get /SpaceBackground exch def
2358 dup /XBox get /XBox exch def
2359 dup /YBox get /YBox exch def
12d89a2e
RS
2360 setfont
2361} def
2362
2363/FG /setrgbcolor load def
2364
2365/bg false def
2366/BG {
2367 dup /bg exch def
87a16a06
RS
2368 {mark 4 1 roll ]}
2369 {[ 1.0 1.0 1.0 ]}
2370 ifelse
2371 /bgcolor exch def
12d89a2e
RS
2372} def
2373
bcc0d457
RS
2374% B width C
2375% +-----------+
2376% | Ascent (usually > 0)
2377% A + +
2378% | Descent (usually < 0)
2379% +-----------+
2380% E width D
2381
12d89a2e 2382/dobackground { % width --
bcc0d457 2383 currentpoint % -- width x y
12d89a2e
RS
2384 gsave
2385 newpath
bcc0d457
RS
2386 moveto % A (x y)
2387 0 Ascent rmoveto % B
2388 dup 0 rlineto % C
2389 0 Descent Ascent sub rlineto % D
2390 neg 0 rlineto % E
12d89a2e
RS
2391 closepath
2392 bgcolor aload pop setrgbcolor
2393 fill
2394 grestore
2395} def
2396
bcc0d457
RS
2397/eolbg { % dobackground until right margin
2398 PrintWidth % -- x-eol
2399 currentpoint pop % -- cur-x
2400 sub % -- width until eol
2401 dobackground
12d89a2e
RS
2402} def
2403
87a16a06 2404/PLN {PrintLineNumber {doLineNumber}if} def
12d89a2e
RS
2405
2406/SL { % Soft Linefeed
2407 bg { eolbg } if
bcc0d457 2408 0 currentpoint exch pop LineHeight sub moveto
12d89a2e
RS
2409} def
2410
87a16a06 2411/HL {SL PLN} def % Hard Linefeed
12d89a2e
RS
2412
2413% Some debug
2414/dcp { currentpoint exch 40 string cvs print (, ) print = } def
87a16a06 2415/dp { print 2 copy exch 40 string cvs print (, ) print = } def
12d89a2e
RS
2416
2417/W {
bcc0d457
RS
2418 ( ) stringwidth % Get the width of a space in the current font.
2419 pop % Discard the Y component.
2420 mul % Multiply the width of a space
2421 % by the number of spaces to plot
12d89a2e
RS
2422 bg { dup dobackground } if
2423 0 rmoveto
87a16a06
RS
2424} def
2425
2426/Effect 0 def
2427/EF {/Effect exch def} def
2428
2429% stack: string |- --
2430% effect: 1 - underline 2 - strikeout 4 - overline
2431% 8 - shadow 16 - box 32 - outline
2432/S {
2433 /xx currentpoint dup Descent add /yy exch def
2434 Ascent add /YY exch def def
2435 dup stringwidth pop xx add /XX exch def
2436 Effect 8 and 0 ne {
2437 /yy yy Yshadow add def
2438 /XX XX Xshadow add def
2439 } if
2440 bg {
2441 true
2442 Effect 16 and 0 ne
2443 {SpaceBackground doBox}
2444 {xx yy XX YY doRect}
2445 ifelse
2446 } if % background
2447 Effect 16 and 0 ne {false 0 doBox}if % box
2448 Effect 8 and 0 ne {dup doShadow}if % shadow
2449 Effect 32 and 0 ne
2450 {true doOutline} % outline
2451 {show} % normal text
2452 ifelse
2453 Effect 1 and 0 ne {UnderlinePosition Hline}if % underline
2454 Effect 2 and 0 ne {StrikeoutPosition Hline}if % strikeout
2455 Effect 4 and 0 ne {OverlinePosition Hline}if % overline
2456} bind def
2457
2458% stack: position |- --
2459/Hline {
2460 currentpoint exch pop add dup
2461 gsave
2462 newpath
2463 xx exch moveto
2464 XX exch lineto
2465 closepath
2466 LineThickness setlinewidth stroke
2467 grestore
2468} bind def
2469
2470% stack: fill-or-not delta |- --
2471/doBox {
2472 /dd exch def
2473 xx XBox sub dd sub yy YBox sub dd sub
2474 XX XBox add dd add YY YBox add dd add
2475 doRect
2476} bind def
2477
2478% stack: fill-or-not lower-x lower-y upper-x upper-y |- --
2479/doRect {
2480 /rYY exch def
2481 /rXX exch def
2482 /ryy exch def
2483 /rxx exch def
2484 gsave
2485 newpath
2486 rXX rYY moveto
2487 rxx rYY lineto
2488 rxx ryy lineto
2489 rXX ryy lineto
2490 closepath
2491 % top of stack: fill-or-not
2492 {FillBgColor}
2493 {LineThickness setlinewidth stroke}
2494 ifelse
2495 grestore
2496} bind def
2497
2498% stack: string |- --
2499/doShadow {
2500 gsave
2501 Xshadow Yshadow rmoveto
2502 false doOutline
2503 grestore
2504} bind def
2505
2506/st 1 string def
2507
2508% stack: string fill-or-not |- --
2509/doOutline {
2510 /-fillp- exch def
2511 /-ox- currentpoint /-oy- exch def def
2512 gsave
2513 LineThickness setlinewidth
2514 {
2515 st 0 3 -1 roll put
2516 st dup true charpath
2517 -fillp- {gsave FillBgColor grestore}if
2518 stroke stringwidth
2519 -oy- add /-oy- exch def
2520 -ox- add /-ox- exch def
2521 -ox- -oy- moveto
2522 } forall
2523 grestore
2524 -ox- -oy- moveto
2525} bind def
2526
2527% stack: --
2528/FillBgColor {bgcolor aload pop setrgbcolor fill} bind def
2529
2530/L0 6 /Times-Italic DefFont
2531
2532% stack: --
2533/doLineNumber {
f68af055
RS
2534 /LineNumber where
2535 {
2536 pop
2537 currentfont
2538 gsave
2539 0.0 0.0 0.0 setrgbcolor
2540 /L0 findfont setfont
2541 LineNumber Lines ge
2542 {(end )}
2543 {LineNumber 6 string cvs ( ) strcat}
2544 ifelse
2545 dup stringwidth pop neg 0 rmoveto
2546 show
2547 grestore
2548 setfont
2549 /LineNumber LineNumber 1 add def
2550 } if
87a16a06
RS
2551} def
2552
2553% stack: --
2554/printZebra {
2555 gsave
bc0d41bd 2556 ZebraGray setgray
857686a6 2557 /double-zebra ZebraHeight ZebraHeight add def
87a16a06
RS
2558 /yiter double-zebra LineHeight mul neg def
2559 /xiter PrintWidth InterColumn add def
2560 NumberOfColumns {LinesPerColumn doColumnZebra xiter 0 rmoveto}repeat
2561 grestore
2562} def
2563
2564% stack: lines-per-column |- --
2565/doColumnZebra {
2566 gsave
857686a6 2567 dup double-zebra idiv {ZebraHeight doZebra 0 yiter rmoveto}repeat
87a16a06 2568 double-zebra mod
857686a6 2569 dup 0 le {pop}{dup ZebraHeight gt {pop ZebraHeight}if doZebra}ifelse
87a16a06
RS
2570 grestore
2571} def
2572
2573% stack: zebra-height (in lines) |- --
2574/doZebra {
2575 /zh exch 0.05 sub LineHeight mul def
2576 gsave
2577 0 LineHeight 0.65 mul rmoveto
2578 PrintWidth 0 rlineto
2579 0 zh neg rlineto
2580 PrintWidth neg 0 rlineto
2581 0 zh rlineto
2582 fill
2583 grestore
2584} def
2585
2586% tx ty rotation xscale yscale xpos ypos BeginBackImage
2587/BeginBackImage {
2588 /-save-image- save def
2589 /showpage {}def
2590 translate
2591 scale
2592 rotate
2593 translate
2594} def
2595
2596/EndBackImage {
2597 -save-image- restore
2598} def
2599
2600% string fontsize fontname rotation gray xpos ypos ShowBackText
2601/ShowBackText {
2602 gsave
2603 translate
2604 setgray
2605 rotate
2606 findfont exch dup /-offset- exch -0.25 mul def scalefont setfont
2607 0 -offset- moveto
2608 /-saveLineThickness- LineThickness def
2609 /LineThickness 1 def
2610 false doOutline
2611 /LineThickness -saveLineThickness- def
2612 grestore
12d89a2e
RS
2613} def
2614
bcc0d457 2615/BeginDoc {
e65df0a1
KH
2616 % ---- Remember space width of the normal text font `f0'.
2617 /SpaceWidth /f0 findfont setfont ( ) stringwidth pop def
bcc0d457
RS
2618 % ---- save the state of the document (useful for ghostscript!)
2619 /docState save def
f8c70761 2620 % ---- [andrewi] set PageSize based on chosen dimensions
bc0d41bd
KH
2621 UseSetpagedevice {
2622 0
2623 {<< /PageSize [PageWidth LandscapePageHeight] >> setpagedevice}
2624 CheckConfig
2625 }{
9bf0a587
AI
2626 LandscapeMode {
2627 % ---- translate to bottom-right corner of Portrait page
2628 LandscapePageHeight 0 translate
2629 90 rotate
2630 }if
bc0d41bd
KH
2631 }ifelse
2632 % ---- [jack] Kludge: my ghostscript window is 21x27.7 instead of 21x29.7
2633 /JackGhostscript where {pop 1 27.7 29.7 div scale}if
2634 % ---- N-Up printing
2635 N-Up 1 gt {
2636 % ---- landscape
2637 N-Up-Landscape {
2638 PageWidth 0 translate
2639 90 rotate
2640 }if
2641 N-Up-Margin dup translate
2642 % ---- scale
2643 LandscapeMode{
2644 /HH PageWidth def
2645 /WW LandscapePageHeight def
2646 }{
2647 /HH LandscapePageHeight def
2648 /WW PageWidth def
2649 }ifelse
2650 WW N-Up-Margin sub N-Up-Margin sub
2651 N-Up-Landscape
2652 {N-Up-Lines div HH}{N-Up-Columns N-Up-Missing add div WW}ifelse
2653 div dup scale
2654 0 N-Up-Repeat 1 sub LandscapePageHeight mul translate
2655 % ---- go to start position in page matrix
2656 N-Up-XStart N-Up-Missing 0.5 mul
2657 LandscapeMode{
2658 LandscapePageHeight mul N-Up-YStart add
2659 }{
2660 PageWidth mul add N-Up-YStart
2661 }ifelse
2662 translate
2663 }if
bcc0d457
RS
2664 /ColumnWidth PrintWidth InterColumn add def
2665 % ---- translate to lower left corner of TEXT
2666 LeftMargin BottomMargin translate
2667 % ---- define where printing will start
2668 /f0 F % this installs Ascent
2669 /PrintStartY PrintHeight Ascent sub def
2670 /ColumnIndex 1 def
bc0d41bd
KH
2671 /N-Up-Counter N-Up-End 1 sub def
2672 SkipFirstPage{save showpage restore}if
2673}def
bcc0d457
RS
2674
2675/EndDoc {
bcc0d457
RS
2676 % ---- restore the state of the document (useful for ghostscript!)
2677 docState restore
bc0d41bd 2678}def
bcc0d457 2679
12d89a2e 2680/BeginDSCPage {
bcc0d457 2681 % ---- when 1st column, save the state of the page
bc0d41bd
KH
2682 ColumnIndex 1 eq {
2683 /pageState save def
2684 }if
bcc0d457
RS
2685 % ---- save the state of the column
2686 /columnState save def
bc0d41bd 2687}def
12d89a2e 2688
12b88fff
RS
2689/PrintHeaderWidth PrintOnlyOneHeader{PrintPageWidth}{PrintWidth}ifelse def
2690
12d89a2e 2691/BeginPage {
a18ed129
RS
2692 % ---- when 1st column, print all background effects
2693 ColumnIndex 1 eq {
bc0d41bd
KH
2694 0 PrintStartY moveto % move to where printing will start
2695 Zebra {printZebra}if
2696 printGlobalBackground
2697 printLocalBackground
2698 }if
12d89a2e 2699 PrintHeader {
12b88fff
RS
2700 PrintOnlyOneHeader{ColumnIndex 1 eq}{true}ifelse {
2701 PrintHeaderFrame {HeaderFrame}if
2702 HeaderText
bc0d41bd
KH
2703 }if
2704 }if
bcc0d457 2705 0 PrintStartY moveto % move to where printing will start
87a16a06 2706 PLN
bc0d41bd 2707}def
12d89a2e
RS
2708
2709/EndPage {
bc0d41bd
KH
2710 bg {eolbg}if
2711}def
12d89a2e
RS
2712
2713/EndDSCPage {
bcc0d457 2714 ColumnIndex NumberOfColumns eq {
bcc0d457
RS
2715 % ---- restore the state of the page
2716 pageState restore
2717 /ColumnIndex 1 def
bc0d41bd
KH
2718 % ---- N-up printing
2719 N-Up 1 gt {
2720 N-Up-Counter 0 gt {
2721 % ---- Next page on same row
2722 /N-Up-Counter N-Up-Counter 1 sub def
2723 N-Up-XColumn N-Up-YColumn
2724 }{
2725 % ---- Next page on next line
2726 /N-Up-Counter N-Up-End 1 sub def
2727 N-Up-XLine N-Up-YLine
2728 }ifelse
2729 translate
2730 }if
2731 }{ % else
bcc0d457
RS
2732 % ---- restore the state of the current column
2733 columnState restore
2734 % ---- and translate to the next column
2735 ColumnWidth 0 translate
2736 /ColumnIndex ColumnIndex 1 add def
bc0d41bd
KH
2737 }ifelse
2738}def
2739
2740% stack: number-of-pages-per-sheet |- --
2741/BeginSheet {
2742 /sheetState save def
2743 /pages-per-sheet exch def
2744 % ---- N-up printing
2745 N-Up 1 gt N-Up-Border and pages-per-sheet 0 gt and {
2746 % ---- page border
2747 gsave
2748 0 setgray
2749 LeftMargin neg BottomMargin neg moveto
2750 N-Up-Repeat
2751 {N-Up-End
2752 {gsave
2753 PageWidth 0 rlineto
2754 0 LandscapePageHeight rlineto
2755 PageWidth neg 0 rlineto
2756 closepath stroke
2757 grestore
2758 /pages-per-sheet pages-per-sheet 1 sub def
2759 pages-per-sheet 0 le{exit}if
2760 N-Up-XColumn N-Up-YColumn rmoveto
2761 }repeat
2762 pages-per-sheet 0 le{exit}if
2763 N-Up-XLine N-Up-XColumn sub N-Up-YLine rmoveto
2764 }repeat
2765 grestore
2766 }if
2767}def
2768
2769/EndSheet {
2770 showpage
2771 sheetState restore
2772}def
12d89a2e 2773
bcc0d457 2774/SetHeaderLines { % nb-lines --
12d89a2e 2775 /HeaderLines exch def
bcc0d457
RS
2776 % ---- bottom up
2777 HeaderPad
2778 HeaderLines 1 sub HeaderLineHeight mul add
2779 HeaderTitleLineHeight add
2780 HeaderPad add
2781 /HeaderHeight exch def
12d89a2e
RS
2782} def
2783
bcc0d457
RS
2784% |---------|
2785% | tm |
2786% |---------|
2787% | header |
2788% |-+-------| <-- (x y)
2789% | ho |
2790% |---------|
2791% | text |
2792% |-+-------| <-- (0 0)
2793% | bm |
2794% |---------|
2795
2796/HeaderFrameStart { % -- x y
2797 0 PrintHeight HeaderOffset add
12d89a2e
RS
2798} def
2799
2800/HeaderFramePath {
12b88fff
RS
2801 PrintHeaderWidth 0 rlineto
2802 0 HeaderHeight rlineto
2803 PrintHeaderWidth neg 0 rlineto
2804 0 HeaderHeight neg rlineto
12d89a2e
RS
2805} def
2806
2807/HeaderFrame {
2808 gsave
2809 0.4 setlinewidth
bcc0d457 2810 % ---- fill a black rectangle (the shadow of the next one)
12d89a2e
RS
2811 HeaderFrameStart moveto
2812 1 -1 rmoveto
2813 HeaderFramePath
2814 0 setgray fill
bcc0d457 2815 % ---- do the next rectangle ...
12d89a2e
RS
2816 HeaderFrameStart moveto
2817 HeaderFramePath
bcc0d457
RS
2818 gsave 0.9 setgray fill grestore % filled with grey
2819 gsave 0 setgray stroke grestore % drawn with black
12d89a2e
RS
2820 grestore
2821} def
2822
2823/HeaderStart {
2824 HeaderFrameStart
bcc0d457
RS
2825 exch HeaderPad add exch % horizontal pad
2826 % ---- bottom up
2827 HeaderPad add % vertical pad
2828 HeaderDescent sub
2829 HeaderLineHeight HeaderLines 1 sub mul add
12d89a2e
RS
2830} def
2831
2832/strcat {
2833 dup length 3 -1 roll dup length dup 4 -1 roll add string dup
2834 0 5 -1 roll putinterval
2835 dup 4 2 roll exch putinterval
2836} def
2837
2838/pagenumberstring {
2839 PageNumber 32 string cvs
2840 ShowNofN {
2841 (/) strcat
2842 PageCount 32 string cvs strcat
2843 } if
2844} def
2845
2846/HeaderText {
2847 HeaderStart moveto
2848
bcc0d457
RS
2849 HeaderLinesRight HeaderLinesLeft % -- rightLines leftLines
2850
2851 % ---- hack: `PN 1 and' == `PN 2 modulo'
2852
bc0d41bd
KH
2853 % ---- if even page number and duplex, then exchange left and right
2854 PageNumber 1 and 0 eq DuplexValue and { exch } if
12d89a2e 2855
bcc0d457 2856 { % ---- process the left lines
12d89a2e
RS
2857 aload pop
2858 exch F
2859 gsave
2860 dup xcheck { exec } if
2861 show
2862 grestore
2863 0 HeaderLineHeight neg rmoveto
2864 } forall
2865
2866 HeaderStart moveto
2867
bcc0d457 2868 { % ---- process the right lines
12d89a2e
RS
2869 aload pop
2870 exch F
2871 gsave
2872 dup xcheck { exec } if
2873 dup stringwidth pop
12b88fff 2874 PrintHeaderWidth exch sub HeaderPad 2 mul sub 0 rmoveto
12d89a2e
RS
2875 show
2876 grestore
2877 0 HeaderLineHeight neg rmoveto
2878 } forall
2879} def
2880
2881/ReportFontInfo {
2882 2 copy
bcc0d457 2883 /t0 3 1 roll DefFont
12d89a2e 2884 /t0 F
00aa16af 2885 /lh FontHeight def
12d89a2e
RS
2886 /sw ( ) stringwidth pop def
2887 /aw (01234567890abcdefghijklmnopqrstuvwxyz) dup length exch
2888 stringwidth pop exch div def
bcc0d457 2889 /t1 12 /Helvetica-Oblique DefFont
12d89a2e 2890 /t1 F
bc0d41bd
KH
2891 gsave
2892 (languagelevel = ) show
2893 gs_languagelevel 32 string cvs show
2894 grestore
2895 0 FontHeight neg rmoveto
12d89a2e
RS
2896 gsave
2897 (For ) show
2898 128 string cvs show
2899 ( ) show
2900 32 string cvs show
2901 ( point, the line height is ) show
2902 lh 32 string cvs show
2903 (, the space width is ) show
2904 sw 32 string cvs show
2905 (,) show
2906 grestore
00aa16af 2907 0 FontHeight neg rmoveto
bcc0d457
RS
2908 gsave
2909 (and a crude estimate of average character width is ) show
2910 aw 32 string cvs show
2911 (.) show
2912 grestore
2913 0 FontHeight neg rmoveto
2914} def
2915
2916/cm { % cm to point
2917 72 mul 2.54 div
2918} def
2919
2920/ReportAllFontInfo {
2921 FontDirectory
2922 { % key = font name value = font dictionary
2923 pop 10 exch ReportFontInfo
2924 } forall
12d89a2e
RS
2925} def
2926
bcc0d457
RS
2927% 3 cm 20 cm moveto 10 /Courier ReportFontInfo showpage
2928% 3 cm 20 cm moveto ReportAllFontInfo showpage
2929
bc0d41bd
KH
2930/ErrorMessages
2931 [(This PostScript printer is not configured with this document page size.)
2932 (Duplex printing is not supported on this PostScript printer.)]def
2933
2934% stack: error-index proc |- --
2935/CheckConfig {
2936 stopped {
2937 1 cm LandscapePageHeight 0.5 mul moveto
2938 /Courier findfont 10 scalefont setfont
2939 gsave
2940 (ps-print error:) show
2941 grestore
2942 0 -10 rmoveto
2943 ErrorMessages exch get show
2944 showpage
2945 $error /newerror false put
2946 stop
2947 }if
2948} bind def
2949
bcc0d457
RS
2950")
2951
bc0d41bd 2952(defconst ps-print-prologue-2
bcc0d457
RS
2953 "
2954% ---- These lines must be kept together because...
2955
2956/h0 F
2957/HeaderTitleLineHeight FontHeight def
2958
2959/h1 F
2960/HeaderLineHeight FontHeight def
2961/HeaderDescent Descent def
2962
2963% ---- ...because `F' has a side-effect on `FontHeight' and `Descent'
2964
12d89a2e
RS
2965")
2966
bc0d41bd
KH
2967(defconst ps-print-duplex-feature
2968 "
2969% --- duplex feature verification
29701
2971UseSetpagedevice {
2972 {<< /Duplex DuplexValue /Tumble TumbleValue >> setpagedevice}
2973}{
2974 {statusdict begin
2975 DuplexValue setduplexmode TumbleValue settumble
2976 end}
2977}ifelse
2978CheckConfig
2979")
2980
12d89a2e 2981;; Start Editing Here:
ef2cbb24 2982
12d89a2e
RS
2983(defvar ps-source-buffer nil)
2984(defvar ps-spool-buffer-name "*PostScript*")
2985(defvar ps-spool-buffer nil)
ef2cbb24 2986
12d89a2e
RS
2987(defvar ps-output-head nil)
2988(defvar ps-output-tail nil)
ef2cbb24 2989
7da17ab6 2990(defvar ps-page-postscript 0)
bc0d41bd 2991(defvar ps-page-order 0)
12d89a2e 2992(defvar ps-page-count 0)
87a16a06
RS
2993(defvar ps-showline-count 1)
2994
857686a6
RS
2995(defvar ps-control-or-escape-regexp nil)
2996
87a16a06
RS
2997(defvar ps-background-pages nil)
2998(defvar ps-background-all-pages nil)
2999(defvar ps-background-text-count 0)
3000(defvar ps-background-image-count 0)
ef2cbb24 3001
12d89a2e 3002(defvar ps-current-font 0)
d3ab8dac 3003(defvar ps-default-color (and ps-print-color-p ps-default-fg)) ; black
12d89a2e
RS
3004(defvar ps-current-color ps-default-color)
3005(defvar ps-current-bg nil)
3006
3007(defvar ps-razchunk 0)
3008
d3ab8dac 3009(defvar ps-color-p nil)
bcc0d457
RS
3010(defvar ps-color-format
3011 (if (eq ps-print-emacs-type 'emacs)
12d89a2e 3012
12b88fff
RS
3013 ;; Emacs understands the %f format; we'll use it to limit color RGB
3014 ;; values to three decimals to cut down some on the size of the
3015 ;; PostScript output.
3016 "%0.3f %0.3f %0.3f"
12d89a2e 3017
12b88fff 3018 ;; Lucid emacsen will have to make do with %s (princ) for floats.
bcc0d457 3019 "%s %s %s"))
12d89a2e
RS
3020
3021;; These values determine how much print-height to deduct when headers
3022;; are turned on. This is a pretty clumsy way of handling it, but
3023;; it'll do for now.
12d89a2e 3024
bcc0d457 3025(defvar ps-header-pad 0
496725ad
RS
3026 "Vertical and horizontal space between the header frame and the text.
3027This is in units of points (1/72 inch).")
12d89a2e 3028
bcc0d457 3029;; Define accessors to the dimensions list.
12d89a2e 3030
bcc0d457
RS
3031(defmacro ps-page-dimensions-get-width (dims) `(nth 0 ,dims))
3032(defmacro ps-page-dimensions-get-height (dims) `(nth 1 ,dims))
bc0d41bd 3033(defmacro ps-page-dimensions-get-media (dims) `(nth 2 ,dims))
12d89a2e 3034
87a16a06 3035(defvar ps-landscape-page-height nil)
12d89a2e 3036
12d89a2e
RS
3037(defvar ps-print-width nil)
3038(defvar ps-print-height nil)
3039
8bd22fcf
KH
3040(defvar ps-height-remaining nil)
3041(defvar ps-width-remaining nil)
12d89a2e 3042
bcc0d457
RS
3043(defvar ps-print-color-scale nil)
3044
7d8b7e8e
KH
3045(defvar ps-font-size-internal nil)
3046(defvar ps-header-font-size-internal nil)
3047(defvar ps-header-title-font-size-internal nil)
3048
87a16a06
RS
3049\f
3050;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3051;; Internal Variables
3052
3053
3054(defvar ps-print-face-extension-alist nil
a18ed129 3055 "Alist of symbolic faces *WITH* extension features (box, outline, etc).
87a16a06
RS
3056An element of this list has the following form:
3057
3058 (FACE . [BITS FG BG])
3059
3060 FACE is a symbol denoting a face name
3061 BITS is a bit vector, where each bit correspond
3062 to a feature (bold, underline, etc)
3063 (see documentation for `ps-print-face-map-alist')
3064 FG foreground color (string or nil)
3065 BG background color (string or nil)
3066
a18ed129
RS
3067Don't change this list directly; instead,
3068use `ps-extend-face' and `ps-extend-face-list'.
3069See documentation for `ps-extend-face' for valid extension symbol.")
3070
3071
3072(defvar ps-print-face-alist nil
3073 "Alist of symbolic faces *WITHOUT* extension features (box, outline, etc).
3074
3075An element of this list has the same form as an element of
3076`ps-print-face-extension-alist'.
3077
3078Don't change this list directly; this list is used by `ps-face-attributes',
3079`ps-map-face' and `ps-build-reference-face-lists'.")
87a16a06
RS
3080
3081
3082(defconst ps-print-face-map-alist
3083 '((bold . 1)
3084 (italic . 2)
3085 (underline . 4)
3086 (strikeout . 8)
3087 (overline . 16)
3088 (shadow . 32)
3089 (box . 64)
3090 (outline . 128))
3091 "Alist of all features and the corresponding bit mask.
3092Each symbol correspond to one bit in a bit vector.")
3093
3094\f
3095;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
a18ed129 3096;; Remapping Faces
87a16a06
RS
3097
3098
3099;;;###autoload
3100(defun ps-extend-face-list (face-extension-list &optional merge-p)
3101 "Extend face in `ps-print-face-extension-alist'.
3102
a18ed129
RS
3103If optional MERGE-P is non-nil, extensions in FACE-EXTENSION-LIST are merged
3104with face extension in `ps-print-face-extension-alist'; otherwise, overrides.
87a16a06
RS
3105
3106The elements in FACE-EXTENSION-LIST is like those for `ps-extend-face'.
3107
3108See `ps-extend-face' for documentation."
3109 (while face-extension-list
3110 (ps-extend-face (car face-extension-list) merge-p)
3111 (setq face-extension-list (cdr face-extension-list))))
3112
3113
3114;;;###autoload
3115(defun ps-extend-face (face-extension &optional merge-p)
3116 "Extend face in `ps-print-face-extension-alist'.
3117
6bdb808e 3118If optional MERGE-P is non-nil, extensions in FACE-EXTENSION list are merged
a18ed129 3119with face extensions in `ps-print-face-extension-alist'; otherwise, overrides.
87a16a06
RS
3120
3121The elements of FACE-EXTENSION list have the form:
3122
3123 (FACE-NAME FOREGROUND BACKGROUND EXTENSION...)
3124
3125FACE-NAME is a face name symbol.
3126
3127FOREGROUND and BACKGROUND may be nil or a string that denotes the
3128foreground and background colors respectively.
3129
3130EXTENSION is one of the following symbols:
3131 bold - use bold font.
3132 italic - use italic font.
3133 underline - put a line under text.
3134 strikeout - like underline, but the line is in middle of text.
3135 overline - like underline, but the line is over the text.
3136 shadow - text will have a shadow.
3137 box - text will be surrounded by a box.
a18ed129 3138 outline - print characters as hollow outlines.
87a16a06
RS
3139
3140If EXTENSION is any other symbol, it is ignored."
3141 (let* ((face-name (nth 0 face-extension))
3142 (foreground (nth 1 face-extension))
3143 (background (nth 2 face-extension))
3144 (ps-face (cdr (assq face-name ps-print-face-extension-alist)))
3145 (face-vector (or ps-face (vector 0 nil nil)))
3146 (face-bit (ps-extension-bit face-extension)))
3147 ;; extend face
3148 (aset face-vector 0 (if merge-p
3149 (logior (aref face-vector 0) face-bit)
3150 face-bit))
3151 (and foreground (stringp foreground) (aset face-vector 1 foreground))
3152 (and background (stringp background) (aset face-vector 2 background))
3153 ;; if face does not exist, insert it
3154 (or ps-face
3155 (setq ps-print-face-extension-alist
3156 (cons (cons face-name face-vector)
3157 ps-print-face-extension-alist)))))
3158
3159
3160(defun ps-extension-bit (face-extension)
3161 (let ((face-bit 0))
3162 ;; map valid symbol extension to bit vector
3163 (setq face-extension (cdr (cdr face-extension)))
3164 (while (setq face-extension (cdr face-extension))
3165 (setq face-bit (logior face-bit
3166 (or (cdr (assq (car face-extension)
3167 ps-print-face-map-alist))
3168 0))))
3169 face-bit))
3170
3171\f
857686a6 3172;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bc0d41bd 3173;; Adapted from font-lock: (obsolete stuff)
857686a6
RS
3174;; Originally face attributes were specified via `font-lock-face-attributes'.
3175;; Users then changed the default face attributes by setting that variable.
3176;; However, we try and be back-compatible and respect its value if set except
3177;; for faces where M-x customize has been used to save changes for the face.
3178
3179(defun ps-font-lock-face-attributes ()
3180 (and (boundp 'font-lock-mode) (symbol-value 'font-lock-mode)
3181 (boundp 'font-lock-face-attributes)
3182 (let ((face-attributes font-lock-face-attributes))
3183 (while face-attributes
6bdb808e
RS
3184 (let* ((face-attribute
3185 (car (prog1 face-attributes
3186 (setq face-attributes (cdr face-attributes)))))
857686a6
RS
3187 (face (car face-attribute)))
3188 ;; Rustle up a `defface' SPEC from a
3189 ;; `font-lock-face-attributes' entry.
3190 (unless (get face 'saved-face)
3191 (let ((foreground (nth 1 face-attribute))
3192 (background (nth 2 face-attribute))
3193 (bold-p (nth 3 face-attribute))
3194 (italic-p (nth 4 face-attribute))
3195 (underline-p (nth 5 face-attribute))
3196 face-spec)
3197 (when foreground
3198 (setq face-spec (cons ':foreground
3199 (cons foreground face-spec))))
3200 (when background
3201 (setq face-spec (cons ':background
3202 (cons background face-spec))))
3203 (when bold-p
3204 (setq face-spec (append '(:bold t) face-spec)))
3205 (when italic-p
3206 (setq face-spec (append '(:italic t) face-spec)))
3207 (when underline-p
3208 (setq face-spec (append '(:underline t) face-spec)))
3209 (custom-declare-face face (list (list t face-spec)) nil)
3210 )))))))
3211
3212\f
87a16a06
RS
3213;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3214;; Internal functions and variables
3215
3216
12b88fff 3217(make-local-hook 'ps-print-hook)
bc0d41bd 3218(make-local-hook 'ps-print-begin-sheet-hook)
12b88fff
RS
3219(make-local-hook 'ps-print-begin-page-hook)
3220(make-local-hook 'ps-print-begin-column-hook)
3221
3222
a18ed129 3223(defun ps-print-without-faces (from to &optional filename region-p)
857686a6 3224 (ps-spool-without-faces from to region-p)
87a16a06
RS
3225 (ps-do-despool filename))
3226
3227
a18ed129 3228(defun ps-spool-without-faces (from to &optional region-p)
12b88fff 3229 (run-hooks 'ps-print-hook)
a18ed129 3230 (ps-printing-region region-p)
87a16a06
RS
3231 (ps-generate (current-buffer) from to 'ps-generate-postscript))
3232
3233
a18ed129 3234(defun ps-print-with-faces (from to &optional filename region-p)
857686a6 3235 (ps-spool-with-faces from to region-p)
87a16a06
RS
3236 (ps-do-despool filename))
3237
3238
a18ed129 3239(defun ps-spool-with-faces (from to &optional region-p)
12b88fff 3240 (run-hooks 'ps-print-hook)
a18ed129 3241 (ps-printing-region region-p)
87a16a06
RS
3242 (ps-generate (current-buffer) from to 'ps-generate-postscript-with-faces))
3243
3244
bc0d41bd 3245(defun ps-count-lines (from to)
a18ed129 3246 (+ (count-lines from to)
857686a6
RS
3247 (save-excursion
3248 (goto-char to)
3249 (if (= (current-column) 0) 1 0))))
87a16a06
RS
3250
3251
a18ed129 3252(defvar ps-printing-region nil
bc0d41bd
KH
3253 "Variable used to indicate if the region that ps-print is printing.
3254It is a cons, the car of which is the line number where the region begins, and
3255its cdr is the total number of lines in the buffer. Formatting functions can
3256use this information to print the original line number (and not the number of
3257lines printed), and to indicate in the header that the printout is of a partial
3258file.")
3259
3260
3261(defvar ps-printing-region-p nil
3262 "Non-nil means ps-print is printing a region.")
87a16a06
RS
3263
3264
a18ed129 3265(defun ps-printing-region (region-p)
bc0d41bd
KH
3266 (setq ps-printing-region-p region-p
3267 ps-printing-region
3268 (cons (if region-p
3269 (ps-count-lines (point-min) (region-beginning))
3270 1)
3271 (ps-count-lines (point-min) (point-max)))))
87a16a06
RS
3272
3273\f
12d89a2e
RS
3274;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3275;; Internal functions
3276
7ae35a2f 3277(defsubst ps-font-alist (font-sym)
12b88fff
RS
3278 (get font-sym 'fonts))
3279
3280(defun ps-font (font-sym font-type)
3281 "Font family name for text of `font-type', when generating PostScript."
7ae35a2f 3282 (let* ((font-list (ps-font-alist font-sym))
12b88fff 3283 (normal-font (cdr (assq 'normal font-list))))
6bdb808e
RS
3284 (while (and font-list (not (eq font-type (car (car font-list)))))
3285 (setq font-list (cdr font-list)))
3286 (or (cdr (car font-list)) normal-font)))
12b88fff
RS
3287
3288(defun ps-fonts (font-sym)
7ae35a2f 3289 (mapcar 'cdr (ps-font-alist font-sym)))
12b88fff
RS
3290
3291(defun ps-font-number (font-sym font-type)
7ae35a2f 3292 (or (ps-alist-position font-type (ps-font-alist font-sym))
12b88fff
RS
3293 0))
3294
3295(defsubst ps-line-height (font-sym)
3296 "The height of a line, for generating PostScript.
3297This is the value that ps-print uses to determine the height,
3298y-dimension, of the lines of text it has printed, and thus affects the
3299point at which page-breaks are placed.
3300The line-height is *not* the same as the point size of the font."
3301 (get font-sym 'line-height))
3302
3303(defsubst ps-title-line-height (font-sym)
3304 "The height of a `title' line, for generating PostScript.
3305This is the value that ps-print uses to determine the height,
3306y-dimension, of the lines of text it has printed, and thus affects the
3307point at which page-breaks are placed.
3308The title-line-height is *not* the same as the point size of the font."
3309 (get font-sym 'title-line-height))
3310
3311(defsubst ps-space-width (font-sym)
3312 "The width of a space character, for generating PostScript.
3313This value is used in expanding tab characters."
3314 (get font-sym 'space-width))
3315
3316(defsubst ps-avg-char-width (font-sym)
3317 "The average width, in points, of a character, for generating PostScript.
3318This is the value that ps-print uses to determine the length,
3319x-dimension, of the text it has printed, and thus affects the point at
3320which long lines wrap around."
3321 (get font-sym 'avg-char-width))
3322
bcc0d457 3323(defun ps-line-lengths-internal ()
87a16a06 3324 "Display the correspondence between a line length and a font size,
bcc0d457
RS
3325using the current ps-print setup.
3326Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
3327 (let ((buf (get-buffer-create "*Line-lengths*"))
7d8b7e8e 3328 (ifs ps-font-size-internal) ; initial font size
12b88fff 3329 (icw (ps-avg-char-width 'ps-font-for-text)) ; initial character width
bcc0d457
RS
3330 (print-width (progn (ps-get-page-dimensions)
3331 ps-print-width))
3332 (ps-setup (ps-setup)) ; setup for the current buffer
3333 (fs-min 5) ; minimum font size
3334 cw-min ; minimum character width
3335 nb-cpl-max ; maximum nb of characters per line
3336 (fs-max 14) ; maximum font size
3337 cw-max ; maximum character width
3338 nb-cpl-min ; minimum nb of characters per line
3339 fs ; current font size
3340 cw ; current character width
3341 nb-cpl ; current nb of characters per line
3342 )
3343 (setq cw-min (/ (* icw fs-min) ifs)
3344 nb-cpl-max (floor (/ print-width cw-min))
3345 cw-max (/ (* icw fs-max) ifs)
8bd22fcf
KH
3346 nb-cpl-min (floor (/ print-width cw-max))
3347 nb-cpl nb-cpl-min)
bcc0d457
RS
3348 (set-buffer buf)
3349 (goto-char (point-max))
8bd22fcf
KH
3350 (or (bolp) (insert "\n"))
3351 (insert ps-setup
3352 "nb char per line / font size\n")
bcc0d457 3353 (while (<= nb-cpl nb-cpl-max)
8bd22fcf
KH
3354 (setq cw (/ print-width (float nb-cpl))
3355 fs (/ (* ifs cw) icw))
bcc0d457
RS
3356 (insert (format "%3s %s\n" nb-cpl fs))
3357 (setq nb-cpl (1+ nb-cpl)))
3358 (insert "\n")
3359 (display-buffer buf 'not-this-window)))
3360
3361(defun ps-nb-pages (nb-lines)
496725ad
RS
3362 "Display correspondence between font size and the number of pages.
3363The correspondence is based on having NB-LINES lines of text,
3364and on the current ps-print setup."
bcc0d457 3365 (let ((buf (get-buffer-create "*Nb-Pages*"))
7d8b7e8e 3366 (ifs ps-font-size-internal) ; initial font size
12b88fff 3367 (ilh (ps-line-height 'ps-font-for-text)) ; initial line height
bcc0d457
RS
3368 (page-height (progn (ps-get-page-dimensions)
3369 ps-print-height))
3370 (ps-setup (ps-setup)) ; setup for the current buffer
3371 (fs-min 4) ; minimum font size
3372 lh-min ; minimum line height
3373 nb-lpp-max ; maximum nb of lines per page
3374 nb-page-min ; minimum nb of pages
3375 (fs-max 14) ; maximum font size
3376 lh-max ; maximum line height
3377 nb-lpp-min ; minimum nb of lines per page
3378 nb-page-max ; maximum nb of pages
3379 fs ; current font size
3380 lh ; current line height
3381 nb-lpp ; current nb of lines per page
3382 nb-page ; current nb of pages
3383 )
3384 (setq lh-min (/ (* ilh fs-min) ifs)
3385 nb-lpp-max (floor (/ page-height lh-min))
3386 nb-page-min (ceiling (/ (float nb-lines) nb-lpp-max))
3387 lh-max (/ (* ilh fs-max) ifs)
3388 nb-lpp-min (floor (/ page-height lh-max))
8bd22fcf
KH
3389 nb-page-max (ceiling (/ (float nb-lines) nb-lpp-min))
3390 nb-page nb-page-min)
bcc0d457
RS
3391 (set-buffer buf)
3392 (goto-char (point-max))
8bd22fcf
KH
3393 (or (bolp) (insert "\n"))
3394 (insert ps-setup
3395 (format "%d lines\n" nb-lines)
3396 "nb page / font size\n")
bcc0d457
RS
3397 (while (<= nb-page nb-page-max)
3398 (setq nb-lpp (ceiling (/ nb-lines (float nb-page)))
3399 lh (/ page-height nb-lpp)
3400 fs (/ (* ifs lh) ilh))
3401 (insert (format "%s %s\n" nb-page fs))
3402 (setq nb-page (1+ nb-page)))
3403 (insert "\n")
3404 (display-buffer buf 'not-this-window)))
3405
6bdb808e
RS
3406;; macros used in `ps-select-font'
3407(defmacro ps-lookup (key) `(cdr (assq ,key font-entry)))
3408(defmacro ps-size-scale (key) `(/ (* (ps-lookup ,key) font-size) size))
3409
12b88fff
RS
3410(defun ps-select-font (font-family sym font-size title-font-size)
3411 (let ((font-entry (cdr (assq font-family ps-font-info-database))))
3412 (or font-entry
3413 (error "Don't have data to scale font %s. Known fonts families are %s"
3414 font-family
3415 (mapcar 'car ps-font-info-database)))
6bdb808e
RS
3416 (let ((size (ps-lookup 'size)))
3417 (put sym 'fonts (ps-lookup 'fonts))
3418 (put sym 'space-width (ps-size-scale 'space-width))
3419 (put sym 'avg-char-width (ps-size-scale 'avg-char-width))
3420 (put sym 'line-height (ps-size-scale 'line-height))
3421 (put sym 'title-line-height
3422 (/ (* (ps-lookup 'line-height) title-font-size) size)))))
bcc0d457 3423
12d89a2e 3424(defun ps-get-page-dimensions ()
bcc0d457
RS
3425 (let ((page-dimensions (cdr (assq ps-paper-type ps-page-dimensions-database)))
3426 page-width page-height)
3427 (cond
3428 ((null page-dimensions)
3429 (error "`ps-paper-type' must be one of:\n%s"
3430 (mapcar 'car ps-page-dimensions-database)))
3431 ((< ps-number-of-columns 1)
12b88fff 3432 (error "The number of columns %d should be positive"
8bd22fcf 3433 ps-number-of-columns)))
bcc0d457 3434
12b88fff 3435 (ps-select-font ps-font-family 'ps-font-for-text
7d8b7e8e 3436 ps-font-size-internal ps-font-size-internal)
12b88fff 3437 (ps-select-font ps-header-font-family 'ps-font-for-header
7d8b7e8e
KH
3438 ps-header-font-size-internal
3439 ps-header-title-font-size-internal)
bcc0d457
RS
3440
3441 (setq page-width (ps-page-dimensions-get-width page-dimensions)
3442 page-height (ps-page-dimensions-get-height page-dimensions))
3443
3444 ;; Landscape mode
3445 (if ps-landscape-mode
3446 ;; exchange width and height
3447 (setq page-width (prog1 page-height (setq page-height page-width))))
3448
3449 ;; It is used to get the lower right corner (only in landscape mode)
3450 (setq ps-landscape-page-height page-height)
3451
3452 ;; | lm | text | ic | text | ic | text | rm |
3453 ;; page-width == lm + n * pw + (n - 1) * ic + rm
3454 ;; => pw == (page-width - lm -rm - (n - 1) * ic) / n
8bd22fcf
KH
3455 (setq ps-print-width (/ (- page-width
3456 ps-left-margin ps-right-margin
3457 (* (1- ps-number-of-columns) ps-inter-column))
3458 ps-number-of-columns))
bcc0d457
RS
3459 (if (<= ps-print-width 0)
3460 (error "Bad horizontal layout:
3461page-width == %s
3462ps-left-margin == %s
3463ps-right-margin == %s
3464ps-inter-column == %s
3465ps-number-of-columns == %s
3466| lm | text | ic | text | ic | text | rm |
3467page-width == lm + n * print-width + (n - 1) * ic + rm
3468=> print-width == %d !"
3469 page-width
3470 ps-left-margin
3471 ps-right-margin
3472 ps-inter-column
3473 ps-number-of-columns
3474 ps-print-width))
3475
3476 (setq ps-print-height
3477 (- page-height ps-bottom-margin ps-top-margin))
3478 (if (<= ps-print-height 0)
3479 (error "Bad vertical layout:
3480ps-top-margin == %s
3481ps-bottom-margin == %s
3482page-height == bm + print-height + tm
3483=> print-height == %d !"
3484 ps-top-margin
3485 ps-bottom-margin
3486 ps-print-height))
3487 ;; If headers are turned on, deduct the height of the header from
3488 ;; the print height.
8bd22fcf 3489 (if ps-print-header
12b88fff
RS
3490 (setq ps-header-pad (* ps-header-line-pad
3491 (ps-title-line-height 'ps-font-for-header))
8bd22fcf
KH
3492 ps-print-height (- ps-print-height
3493 ps-header-offset
3494 ps-header-pad
12b88fff
RS
3495 (ps-title-line-height 'ps-font-for-header)
3496 (* (ps-line-height 'ps-font-for-header)
3497 (1- ps-header-lines))
8bd22fcf 3498 ps-header-pad)))
bcc0d457
RS
3499 (if (<= ps-print-height 0)
3500 (error "Bad vertical layout:
3501ps-top-margin == %s
3502ps-bottom-margin == %s
3503ps-header-offset == %s
3504ps-header-pad == %s
3505header-height == %s
3506page-height == bm + print-height + tm - ho - hh
3507=> print-height == %d !"
3508 ps-top-margin
3509 ps-bottom-margin
3510 ps-header-offset
3511 ps-header-pad
3512 (+ ps-header-pad
12b88fff
RS
3513 (ps-title-line-height 'ps-font-for-header)
3514 (* (ps-line-height 'ps-font-for-header)
3515 (1- ps-header-lines))
bcc0d457
RS
3516 ps-header-pad)
3517 ps-print-height))))
ef2cbb24 3518
12d89a2e 3519(defun ps-print-preprint (&optional filename)
8bd22fcf
KH
3520 (and filename
3521 (or (numberp filename)
3522 (listp filename))
d3ab8dac
KH
3523 (let* ((name (concat (file-name-nondirectory (or (buffer-file-name)
3524 (buffer-name)))
3525 ".ps"))
8bd22fcf
KH
3526 (prompt (format "Save PostScript to file: (default %s) " name))
3527 (res (read-file-name prompt default-directory name nil)))
d3ab8dac
KH
3528 (while (cond ((not (file-writable-p res))
3529 (ding)
3530 (setq prompt "is unwritable"))
3531 ((file-exists-p res)
3532 (setq prompt "exists")
3533 (not (y-or-n-p (format "File `%s' exists; overwrite? "
3534 res))))
3535 (t nil))
3536 (setq res (read-file-name
3537 (format "File %s; save PostScript to file: " prompt)
3538 (file-name-directory res) nil nil
3539 (file-name-nondirectory res))))
8bd22fcf
KH
3540 (if (file-directory-p res)
3541 (expand-file-name name (file-name-as-directory res))
3542 res))))
12d89a2e
RS
3543
3544;; The following functions implement a simple list-buffering scheme so
3545;; that ps-print doesn't have to repeatedly switch between buffers
857686a6
RS
3546;; while spooling. The functions `ps-output' and `ps-output-string' build
3547;; up the lists; the function `ps-flush-output' takes the lists and
12d89a2e
RS
3548;; insert its contents into the spool buffer (*PostScript*).
3549
857686a6
RS
3550(defvar ps-string-escape-codes
3551 (let ((table (make-vector 256 nil))
3552 (char ?\000))
3553 ;; control characters
3554 (while (<= char ?\037)
3555 (aset table char (format "\\%03o" char))
3556 (setq char (1+ char)))
3557 ;; printable characters
3558 (while (< char ?\177)
3559 (aset table char (format "%c" char))
3560 (setq char (1+ char)))
3561 ;; DEL and 8-bit characters
3562 (while (<= char ?\377)
3563 (aset table char (format "\\%o" char))
3564 (setq char (1+ char)))
3565 ;; Override ASCII formatting characters with named escape code:
3566 (aset table ?\n "\\n") ; [NL] linefeed
3567 (aset table ?\r "\\r") ; [CR] carriage return
3568 (aset table ?\t "\\t") ; [HT] horizontal tab
3569 (aset table ?\b "\\b") ; [BS] backspace
3570 (aset table ?\f "\\f") ; [NP] form feed
3571 ;; Escape PostScript escape and string delimiter characters:
3572 (aset table ?\\ "\\\\")
3573 (aset table ?\( "\\(")
3574 (aset table ?\) "\\)")
3575 table)
3576 "Vector used to map characters to PostScript string escape codes.")
3577
12d89a2e
RS
3578(defun ps-output-string-prim (string)
3579 (insert "(") ;insert start-string delimiter
3580 (save-excursion ;insert string
e65df0a1 3581 (insert (string-as-unibyte string)))
12d89a2e 3582 ;; Find and quote special characters as necessary for PS
c82b4a75 3583 ;; This skips everything except control chars, non-ASCII chars, (, ) and \.
b61e2c11
RS
3584 (while (progn (skip-chars-forward " -'*-[]-~") (not (eobp)))
3585 (let ((special (following-char)))
e65df0a1
KH
3586 (delete-char 1)
3587 (insert (aref ps-string-escape-codes special))))
12d89a2e
RS
3588 (goto-char (point-max))
3589 (insert ")")) ;insert end-string delimiter
ef2cbb24 3590
12d89a2e 3591(defun ps-init-output-queue ()
8bd22fcf
KH
3592 (setq ps-output-head '("")
3593 ps-output-tail ps-output-head))
ef2cbb24 3594
12d89a2e
RS
3595(defun ps-output (&rest args)
3596 (setcdr ps-output-tail args)
3597 (while (cdr ps-output-tail)
3598 (setq ps-output-tail (cdr ps-output-tail))))
ef2cbb24 3599
12d89a2e
RS
3600(defun ps-output-string (string)
3601 (ps-output t string))
ef2cbb24 3602
87a16a06
RS
3603(defun ps-output-list (the-list)
3604 (mapcar 'ps-output the-list))
3605
e65df0a1
KH
3606;; Output strings in the list ARGS in the PostScript prologue part.
3607(defun ps-output-prologue (args)
3608 (ps-output 'prologue (if (stringp args) (list args) args)))
3609
12d89a2e
RS
3610(defun ps-flush-output ()
3611 (save-excursion
3612 (set-buffer ps-spool-buffer)
3613 (goto-char (point-max))
3614 (while ps-output-head
3615 (let ((it (car ps-output-head)))
e65df0a1
KH
3616 (cond
3617 ((eq t it)
3618 (setq ps-output-head (cdr ps-output-head))
3619 (ps-output-string-prim (car ps-output-head)))
3620 ((eq 'prologue it)
12d89a2e 3621 (setq ps-output-head (cdr ps-output-head))
e65df0a1
KH
3622 (save-excursion
3623 (search-backward "\nBeginDoc")
3624 (forward-char 1)
3625 (apply 'insert (car ps-output-head))))
3626 (t
3627 (insert it))))
12d89a2e
RS
3628 (setq ps-output-head (cdr ps-output-head))))
3629 (ps-init-output-queue))
3630
3631(defun ps-insert-file (fname)
3632 (ps-flush-output)
12d89a2e 3633 ;; Check to see that the file exists and is readable; if not, throw
87a16a06
RS
3634 ;; an error.
3635 (or (file-readable-p fname)
12d89a2e 3636 (error "Could not read file `%s'" fname))
12d89a2e
RS
3637 (save-excursion
3638 (set-buffer ps-spool-buffer)
3639 (goto-char (point-max))
3640 (insert-file fname)))
06fb6aab 3641
12d89a2e
RS
3642;; These functions insert the arrays that define the contents of the
3643;; headers.
ef2cbb24 3644
12d89a2e
RS
3645(defun ps-generate-header-line (fonttag &optional content)
3646 (ps-output " [ " fonttag " ")
3647 (cond
3648 ;; Literal strings should be output as is -- the string must
3649 ;; contain its own PS string delimiters, '(' and ')', if necessary.
3650 ((stringp content)
3651 (ps-output content))
3652
3653 ;; Functions are called -- they should return strings; they will be
3654 ;; inserted as strings and the PS string delimiters added.
3655 ((and (symbolp content) (fboundp content))
3656 (ps-output-string (funcall content)))
3657
3658 ;; Variables will have their contents inserted. They should
3659 ;; contain strings, and will be inserted as strings.
3660 ((and (symbolp content) (boundp content))
3661 (ps-output-string (symbol-value content)))
3662
3663 ;; Anything else will get turned into an empty string.
3664 (t
3665 (ps-output-string "")))
3666 (ps-output " ]\n"))
3667
3668(defun ps-generate-header (name contents)
3669 (ps-output "/" name " [\n")
3670 (if (> ps-header-lines 0)
3671 (let ((count 1))
3672 (ps-generate-header-line "/h0" (car contents))
3673 (while (and (< count ps-header-lines)
3674 (setq contents (cdr contents)))
3675 (ps-generate-header-line "/h1" (car contents))
8bd22fcf 3676 (setq count (1+ count)))
12d89a2e
RS
3677 (ps-output "] def\n"))))
3678
bc0d41bd
KH
3679
3680(defun ps-output-boolean (name bool &optional no-def)
3681 (ps-output (format "/%s %s%s"
3682 name (if bool "true" "false") (if no-def "\n" " def\n"))))
ef2cbb24 3683
06fb6aab 3684
87a16a06
RS
3685(defun ps-background-pages (page-list func)
3686 (if page-list
3687 (mapcar
bc0d41bd
KH
3688 #'(lambda (pages)
3689 (let ((start (if (consp pages) (car pages) pages))
3690 (end (if (consp pages) (cdr pages) pages)))
3691 (and (integerp start) (integerp end) (<= start end)
3692 (add-to-list 'ps-background-pages (vector start end func)))))
87a16a06
RS
3693 page-list)
3694 (setq ps-background-all-pages (cons func ps-background-all-pages))))
3695
3696
bc0d41bd
KH
3697(defconst ps-boundingbox-re
3698 "^%%BoundingBox:\
3699\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)")
3700
3701
87a16a06
RS
3702(defun ps-get-boundingbox ()
3703 (save-excursion
3704 (set-buffer ps-spool-buffer)
3705 (save-excursion
bc0d41bd 3706 (if (re-search-forward ps-boundingbox-re nil t)
87a16a06
RS
3707 (vector (string-to-number ; lower x
3708 (buffer-substring (match-beginning 1) (match-end 1)))
3709 (string-to-number ; lower y
3710 (buffer-substring (match-beginning 2) (match-end 2)))
3711 (string-to-number ; upper x
3712 (buffer-substring (match-beginning 3) (match-end 3)))
3713 (string-to-number ; upper y
3714 (buffer-substring (match-beginning 4) (match-end 4))))
3715 (vector 0 0 0 0)))))
3716
3717
3718;; Emacs understands the %f format; we'll use it to limit color RGB values
3719;; to three decimals to cut down some on the size of the PostScript output.
3720;; Lucid emacsen will have to make do with %s (princ) for floats.
3721
3722(defvar ps-float-format (if (eq ps-print-emacs-type 'emacs)
3723 "%0.3f " ; emacs
3724 "%s ")) ; Lucid emacsen
3725
3726
3727(defun ps-float-format (value &optional default)
3728 (let ((literal (or value default)))
3729 (if literal
3730 (format (if (numberp literal)
3731 ps-float-format
3732 "%s ")
3733 literal)
3734 " ")))
3735
3736
3737(defun ps-background-text ()
3738 (mapcar
bc0d41bd
KH
3739 #'(lambda (text)
3740 (setq ps-background-text-count (1+ ps-background-text-count))
3741 (ps-output (format "/ShowBackText-%d {\n" ps-background-text-count))
3742 (ps-output-string (nth 0 text)) ; text
3743 (ps-output
3744 "\n"
3745 (ps-float-format (nth 4 text) 200.0) ; font size
3746 (format "/%s " (or (nth 3 text) "Times-Roman")) ; font name
3747 (ps-float-format (nth 6 text)
3748 "PrintHeight PrintPageWidth atan") ; rotation
3749 (ps-float-format (nth 5 text) 0.85) ; gray
3750 (ps-float-format (nth 1 text) "0") ; x position
3751 (ps-float-format (nth 2 text) "BottomMargin") ; y position
3752 "\nShowBackText} def\n")
3753 (ps-background-pages (nthcdr 7 text) ; page list
3754 (format "ShowBackText-%d\n"
3755 ps-background-text-count)))
87a16a06
RS
3756 ps-print-background-text))
3757
3758
3759(defun ps-background-image ()
3760 (mapcar
bc0d41bd
KH
3761 #'(lambda (image)
3762 (let ((image-file (expand-file-name (nth 0 image))))
3763 (if (file-readable-p image-file)
3764 (progn
3765 (setq ps-background-image-count (1+ ps-background-image-count))
3766 (ps-output
3767 (format "/ShowBackImage-%d {\n--back-- "
3768 ps-background-image-count)
3769 (ps-float-format (nth 5 image) 0.0) ; rotation
3770 (ps-float-format (nth 3 image) 1.0) ; x scale
3771 (ps-float-format (nth 4 image) 1.0) ; y scale
3772 (ps-float-format (nth 1 image) ; x position
3773 "PrintPageWidth 2 div")
3774 (ps-float-format (nth 2 image) ; y position
3775 "PrintHeight 2 div BottomMargin add")
3776 "\nBeginBackImage\n")
3777 (ps-insert-file image-file)
3778 ;; coordinate adjustment to centralize image
3779 ;; around x and y position
3780 (let ((box (ps-get-boundingbox)))
3781 (save-excursion
3782 (set-buffer ps-spool-buffer)
3783 (save-excursion
3784 (if (re-search-backward "^--back--" nil t)
3785 (replace-match
3786 (format "%s %s"
3787 (ps-float-format
3788 (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
3789 (aref box 0))))
3790 (ps-float-format
3791 (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
3792 (aref box 1)))))
3793 t)))))
3794 (ps-output "\nEndBackImage} def\n")
3795 (ps-background-pages (nthcdr 6 image) ; page list
3796 (format "ShowBackImage-%d\n"
3797 ps-background-image-count))))))
87a16a06
RS
3798 ps-print-background-image))
3799
3800
a18ed129 3801(defun ps-background (page-number)
87a16a06 3802 (let (has-local-background)
bc0d41bd
KH
3803 (mapcar #'(lambda (range)
3804 (and (<= (aref range 0) page-number)
3805 (<= page-number (aref range 1))
3806 (if has-local-background
3807 (ps-output (aref range 2))
3808 (setq has-local-background t)
3809 (ps-output "/printLocalBackground {\n"
3810 (aref range 2)))))
87a16a06
RS
3811 ps-background-pages)
3812 (and has-local-background (ps-output "} def\n"))))
3813
3814
0140c600
EZ
3815;; Return a list of the distinct elements of LIST.
3816;; Elements are compared with `equal'.
3817(defun ps-remove-duplicates (list)
3818 (let (new (tail list))
3819 (while tail
3820 (or (member (car tail) new)
3821 (setq new (cons (car tail) new)))
3822 (setq tail (cdr tail)))
3823 (nreverse new)))
3824
c82b4a75 3825
6bdb808e
RS
3826;; Find the first occurrence of ITEM in LIST.
3827;; Return the index of the matching item, or nil if not found.
3828;; Elements are compared with `eq'.
7ae35a2f 3829(defun ps-alist-position (item list)
6bdb808e
RS
3830 (let ((tail list) (index 0) found)
3831 (while tail
7ae35a2f 3832 (if (setq found (eq (car (car tail)) item))
6bdb808e
RS
3833 (setq tail nil)
3834 (setq index (1+ index)
3835 tail (cdr tail))))
3836 (and found index)))
3837
3838
bc0d41bd
KH
3839(defconst ps-n-up-database
3840 '((a4
3841 (1 nil 1 1 0)
3842 (2 t 1 2 0)
3843 (4 nil 2 2 0)
3844 (6 t 2 3 1)
3845 (8 t 2 4 0)
3846 (9 nil 3 3 0)
3847 (12 t 3 4 2)
3848 (16 nil 4 4 0)
3849 (18 t 3 6 0)
3850 (20 nil 5 4 1)
3851 (25 nil 5 5 0)
3852 (30 nil 6 5 1)
3853 (32 t 4 8 0)
3854 (36 nil 6 6 0)
3855 (42 nil 7 6 1)
3856 (49 nil 7 7 0)
3857 (50 t 5 10 0)
3858 (56 nil 8 7 1)
3859 (64 nil 8 8 0)
3860 (72 nil 9 8 1)
3861 (81 nil 9 9 0)
3862 (90 nil 10 9 1)
3863 (100 nil 10 10 0))
3864 (a3
3865 (1 nil 1 1 0)
3866 (2 t 1 2 0)
3867 (4 nil 2 2 0)
3868 (6 t 2 3 1)
3869 (8 t 2 4 0)
3870 (9 nil 3 3 0)
3871 (12 nil 4 3 1)
3872 (16 nil 4 4 0)
3873 (18 t 3 6 0)
3874 (20 nil 5 4 1)
3875 (25 nil 5 5 0)
3876 (30 nil 6 5 1)
3877 (32 t 4 8 0)
3878 (36 nil 6 6 0)
3879 (42 nil 7 6 1)
3880 (49 nil 7 7 0)
3881 (50 t 5 10 0)
3882 (56 nil 8 7 1)
3883 (64 nil 8 8 0)
3884 (72 nil 9 8 1)
3885 (81 nil 9 9 0)
3886 (90 nil 10 9 1)
3887 (100 nil 10 10 0))
3888 (letter
3889 (1 nil 1 1 0)
3890 (4 nil 2 2 0)
3891 (6 t 2 3 0)
3892 (9 nil 3 3 0)
3893 (12 nil 4 3 1)
3894 (16 nil 4 4 0)
3895 (20 nil 5 4 1)
3896 (25 nil 5 5 0)
3897 (30 nil 6 5 1)
3898 (36 nil 6 6 0)
3899 (40 t 5 8 0)
3900 (42 nil 7 6 1)
3901 (49 nil 7 7 0)
3902 (56 nil 8 7 1)
3903 (64 nil 8 8 0)
3904 (72 nil 9 8 1)
3905 (81 nil 9 9 0)
3906 (90 nil 10 9 1)
3907 (100 nil 10 10 0))
3908 (legal
3909 (1 nil 1 1 0)
3910 (2 t 1 2 0)
3911 (4 nil 2 2 0)
3912 (6 nil 3 2 1)
3913 (9 nil 3 3 0)
3914 (10 t 2 5 0)
3915 (12 nil 4 3 1)
3916 (16 nil 4 4 0)
3917 (20 nil 5 4 1)
3918 (25 nil 5 5 0)
3919 (30 nil 6 5 1)
3920 (36 nil 6 6 0)
3921 (42 nil 7 6 1)
3922 (49 nil 7 7 0)
3923 (56 nil 8 7 1)
3924 (64 nil 8 8 0)
3925 (70 t 5 14 0)
3926 (72 nil 9 8 1)
3927 (81 nil 9 9 0)
3928 (90 nil 10 9 1)
3929 (100 nil 10 10 0))
3930 (letter-small
3931 (1 nil 1 1 0)
3932 (4 nil 2 2 0)
3933 (6 t 2 3 0)
3934 (9 nil 3 3 0)
3935 (12 t 3 4 1)
3936 (15 t 3 5 0)
3937 (16 nil 4 4 0)
3938 (20 nil 5 4 1)
3939 (25 nil 5 5 0)
3940 (28 t 4 7 0)
3941 (30 nil 6 5 1)
3942 (36 nil 6 6 0)
3943 (40 t 5 8 0)
3944 (42 nil 7 6 1)
3945 (49 nil 7 7 0)
3946 (56 nil 8 7 1)
3947 (60 t 6 10 0)
3948 (64 nil 8 8 0)
3949 (72 ni 9 8 1)
3950 (81 nil 9 9 0)
3951 (84 t 7 12 0)
3952 (90 nil 10 9 1)
3953 (100 nil 10 10 0))
3954 (tabloid
3955 (1 nil 1 1 0)
3956 (2 t 1 2 0)
3957 (4 nil 2 2 0)
3958 (6 t 2 3 1)
3959 (8 t 2 4 0)
3960 (9 nil 3 3 0)
3961 (12 nil 4 3 1)
3962 (16 nil 4 4 0)
3963 (20 nil 5 4 1)
3964 (25 nil 5 5 0)
3965 (30 nil 6 5 1)
3966 (36 nil 6 6 0)
3967 (42 nil 7 6 1)
3968 (49 nil 7 7 0)
3969 (56 nil 8 7 1)
3970 (64 nil 8 8 0)
3971 (72 nil 9 8 1)
3972 (81 nil 9 9 0)
3973 (84 t 6 14 0)
3974 (90 nil 10 9 1)
3975 (100 nil 10 10 0))
3976 ;; Ledger paper size is a special case, it is the only paper size where the
3977 ;; normal size is landscaped, that is, the height is smaller than width.
3978 ;; So, we use the special value `pag' in the `landscape' field.
3979 (ledger
3980 (1 nil 1 1 0)
3981 (2 pag 1 2 0)
3982 (4 nil 2 2 0)
3983 (6 pag 2 3 1)
3984 (8 pag 2 4 0)
3985 (9 nil 3 3 0)
3986 (12 nil 4 3 1)
3987 (16 nil 4 4 0)
3988 (20 nil 5 4 1)
3989 (25 nil 5 5 0)
3990 (30 nil 6 5 1)
3991 (36 nil 6 6 0)
3992 (42 nil 7 6 1)
3993 (49 nil 7 7 0)
3994 (56 nil 8 7 1)
3995 (64 nil 8 8 0)
3996 (72 nil 9 8 1)
3997 (81 nil 9 9 0)
3998 (84 pag 6 14 0)
3999 (90 nil 10 9 1)
4000 (100 nil 10 10 0))
4001 (statement
4002 (1 nil 1 1 0)
4003 (2 t 1 2 0)
4004 (4 nil 2 2 0)
4005 (6 nil 3 2 1)
4006 (9 nil 3 3 0)
4007 (10 t 2 5 0)
4008 (12 nil 4 3 1)
4009 (16 nil 4 4 0)
4010 (20 nil 5 4 1)
4011 (21 t 3 7 0)
4012 (25 nil 5 5 0)
4013 (30 nil 6 5 1)
4014 (36 nil 6 6 0)
4015 (40 t 4 10 0)
4016 (42 nil 7 6 1)
4017 (49 nil 7 7 0)
4018 (56 nil 8 7 1)
4019 (60 t 5 12 0)
4020 (64 nil 8 8 0)
4021 (72 nil 9 8 1)
4022 (81 nil 9 9 0)
4023 (90 nil 10 9 1)
4024 (100 nil 10 10 0))
4025 (executive
4026 (1 nil 1 1 0)
4027 (4 nil 2 2 0)
4028 (6 t 2 3 0)
4029 (9 nil 3 3 0)
4030 (12 nil 4 3 1)
4031 (16 nil 4 4 0)
4032 (20 nil 5 4 1)
4033 (25 nil 5 5 0)
4034 (28 t 4 7 0)
4035 (30 nil 6 5 1)
4036 (36 nil 6 6 0)
4037 (42 nil 7 6 1)
4038 (45 t 5 9 0)
4039 (49 nil 7 7 0)
4040 (56 nil 8 7 1)
4041 (60 t 6 10 0)
4042 (64 nil 8 8 0)
4043 (72 nil 9 8 1)
4044 (81 nil 9 9 0)
4045 (84 t 7 12 0)
4046 (90 nil 10 9 1)
4047 (100 nil 10 10 0))
4048 (a4small
4049 (1 nil 1 1 0)
4050 (2 t 1 2 0)
4051 (4 nil 2 2 0)
4052 (6 t 2 3 1)
4053 (8 t 2 4 0)
4054 (9 nil 3 3 0)
4055 (12 nil 4 3 1)
4056 (16 nil 4 4 0)
4057 (18 t 3 6 0)
4058 (20 nil 5 4 1)
4059 (25 nil 5 5 0)
4060 (30 nil 6 5 1)
4061 (32 t 4 8 0)
4062 (36 nil 6 6 0)
4063 (42 nil 7 6 1)
4064 (49 nil 7 7 0)
4065 (50 t 5 10 0)
4066 (56 nil 8 7 1)
4067 (64 nil 8 8 0)
4068 (72 nil 9 8 1)
4069 (78 t 6 13 0)
4070 (81 nil 9 9 0)
4071 (90 nil 10 9 1)
4072 (100 nil 10 10 0))
4073 (b4
4074 (1 nil 1 1 0)
4075 (2 t 1 2 0)
4076 (4 nil 2 2 0)
4077 (6 t 2 3 1)
4078 (8 t 2 4 0)
4079 (9 nil 3 3 0)
4080 (12 nil 4 3 1)
4081 (16 nil 4 4 0)
4082 (18 t 3 6 0)
4083 (20 nil 5 4 1)
4084 (25 nil 5 5 0)
4085 (30 nil 6 5 1)
4086 (32 t 4 8 0)
4087 (36 nil 6 6 0)
4088 (42 nil 7 6 1)
4089 (49 nil 7 7 0)
4090 (50 t 5 10 0)
4091 (56 nil 8 7 1)
4092 (64 nil 8 8 0)
4093 (72 nil 9 8 1)
4094 (81 nil 9 9 0)
4095 (90 nil 10 9 1)
4096 (100 nil 10 10 0))
4097 (b5
4098 (1 nil 1 1 0)
4099 (2 t 1 2 0)
4100 (4 nil 2 2 0)
4101 (6 t 2 3 1)
4102 (8 t 2 4 0)
4103 (9 nil 3 3 0)
4104 (12 nil 4 3 1)
4105 (16 nil 4 4 0)
4106 (18 t 3 6 0)
4107 (20 nil 5 4 1)
4108 (25 nil 5 5 0)
4109 (30 nil 6 5 1)
4110 (32 t 4 8 0)
4111 (36 nil 6 6 0)
4112 (42 nil 7 6 1)
4113 (49 nil 7 7 0)
4114 (50 t 5 10 0)
4115 (56 nil 8 7 1)
4116 (64 nil 8 8 0)
4117 (72 nil 9 8 0)
4118 (81 nil 9 9 0)
4119 (90 nil 10 9 1)
4120 (98 t 7 14 0)
4121 (100 nil 10 10 0)))
4122 "Alist which is the page matrix database used for N-up printing.
4123
4124Each element has the following form:
4125
4126 (PAGE
4127 (MAX LANDSCAPE LINES COLUMNS COL-MISSING)
4128 ...)
4129
4130Where:
4131PAGE is the page size used (see `ps-paper-type').
4132MAX is the maximum elements of this page matrix.
4133LANDSCAPE specifies if page matrix is landscaped, has the following valid
4134 values:
4135 nil the sheet is in portrait mode.
4136 t the sheet is in landscape mode.
4137 pag the sheet is in portrait mode and page is in landscape mode.
4138LINES is the number of lines of page matrix.
4139COLUMNS is the number of columns of page matrix.
4140COL-MISSING is the number of columns missing to fill the sheet.")
4141
4142
4143(defmacro ps-n-up-landscape (mat) `(nth 1 ,mat))
4144(defmacro ps-n-up-lines (mat) `(nth 2 ,mat))
4145(defmacro ps-n-up-columns (mat) `(nth 3 ,mat))
4146(defmacro ps-n-up-missing (mat) `(nth 4 ,mat))
4147
4148
4149(defun ps-n-up-printing ()
4150 ;; force `ps-n-up-printing' be in range 1 to 100.
4151 (setq ps-n-up-printing (max (min ps-n-up-printing 100) 1))
4152 ;; find suitable page matrix for a given `ps-paper-type'.
4153 (let ((the-list (cdr (assq ps-paper-type ps-n-up-database))))
4154 (and the-list
4155 (while (> ps-n-up-printing (caar the-list))
4156 (setq the-list (cdr the-list))))
4157 (car the-list)))
4158
4159
4160(defconst ps-n-up-filling-database
4161 '((left-top
4162 "PageWidth" ; N-Up-XColumn
4163 "0" ; N-Up-YColumn
4164 "N-Up-End 1 sub PageWidth mul neg" ; N-Up-XLine
4165 "LandscapePageHeight neg" ; N-Up-YLine
4166 "N-Up-Lines" ; N-Up-Repeat
4167 "N-Up-Columns" ; N-Up-End
4168 "0" ; N-Up-XStart
4169 "0") ; N-Up-YStart
4170 (left-bottom
4171 "PageWidth" ; N-Up-XColumn
4172 "0" ; N-Up-YColumn
4173 "N-Up-End 1 sub PageWidth mul neg" ; N-Up-XLine
4174 "LandscapePageHeight" ; N-Up-YLine
4175 "N-Up-Lines" ; N-Up-Repeat
4176 "N-Up-Columns" ; N-Up-End
4177 "0" ; N-Up-XStart
4178 "N-Up-Repeat 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
4179 (right-top
4180 "PageWidth neg" ; N-Up-XColumn
4181 "0" ; N-Up-YColumn
4182 "N-Up-End 1 sub PageWidth mul" ; N-Up-XLine
4183 "LandscapePageHeight neg" ; N-Up-YLine
4184 "N-Up-Lines" ; N-Up-Repeat
4185 "N-Up-Columns" ; N-Up-End
4186 "N-Up-End 1 sub PageWidth mul" ; N-Up-XStart
4187 "0") ; N-Up-YStart
4188 (right-bottom
4189 "PageWidth neg" ; N-Up-XColumn
4190 "0" ; N-Up-YColumn
4191 "N-Up-End 1 sub PageWidth mul" ; N-Up-XLine
4192 "LandscapePageHeight" ; N-Up-YLine
4193 "N-Up-Lines" ; N-Up-Repeat
4194 "N-Up-Columns" ; N-Up-End
4195 "N-Up-End 1 sub PageWidth mul" ; N-Up-XStart
4196 "N-Up-Repeat 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
4197 (top-left
4198 "0" ; N-Up-XColumn
4199 "LandscapePageHeight neg" ; N-Up-YColumn
4200 "PageWidth" ; N-Up-XLine
4201 "N-Up-End 1 sub LandscapePageHeight mul" ; N-Up-YLine
4202 "N-Up-Columns" ; N-Up-Repeat
4203 "N-Up-Lines" ; N-Up-End
4204 "0" ; N-Up-XStart
4205 "0") ; N-Up-YStart
4206 (bottom-left
4207 "0" ; N-Up-XColumn
4208 "LandscapePageHeight" ; N-Up-YColumn
4209 "PageWidth" ; N-Up-XLine
4210 "N-Up-End 1 sub LandscapePageHeight mul neg" ; N-Up-YLine
4211 "N-Up-Columns" ; N-Up-Repeat
4212 "N-Up-Lines" ; N-Up-End
4213 "0" ; N-Up-XStart
4214 "N-Up-End 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
4215 (top-right
4216 "0" ; N-Up-XColumn
4217 "LandscapePageHeight neg" ; N-Up-YColumn
4218 "PageWidth neg" ; N-Up-XLine
4219 "N-Up-End 1 sub LandscapePageHeight mul" ; N-Up-YLine
4220 "N-Up-Columns" ; N-Up-Repeat
4221 "N-Up-Lines" ; N-Up-End
4222 "N-Up-Repeat 1 sub PageWidth mul" ; N-Up-XStart
4223 "0") ; N-Up-YStart
4224 (bottom-right
4225 "0" ; N-Up-XColumn
4226 "LandscapePageHeight" ; N-Up-YColumn
4227 "PageWidth neg" ; N-Up-XLine
4228 "N-Up-End 1 sub LandscapePageHeight mul neg" ; N-Up-YLine
4229 "N-Up-Columns" ; N-Up-Repeat
4230 "N-Up-Lines" ; N-Up-End
4231 "N-Up-Repeat 1 sub PageWidth mul" ; N-Up-XStart
4232 "N-Up-End 1 sub LandscapePageHeight mul neg")) ; N-Up-YStart
4233 "Alist for n-up printing initializations.
4234
4235Each element has the following form:
4236
4237 (KIND XCOL YCOL XLIN YLIN REPEAT END XSTART YSTART)
4238
4239Where:
4240KIND is a valid value of `ps-n-up-filling'.
4241XCOL YCOL are the relative position for the next column.
4242XLIN YLIN are the relative position for the beginning of next line.
4243REPEAT is the number of repetions for external loop.
4244END is the number of repetions for internal loop and also the number of pages in
4245 a row.
4246XSTART YSTART are the relative position for the first page in a sheet.")
4247
4248
4249(defun ps-n-up-filling ()
4250 (cdr (or (assq ps-n-up-filling ps-n-up-filling-database)
4251 (assq 'left-top ps-n-up-filling-database))))
4252
4253
4254(defmacro ps-n-up-xcolumn (init) `(nth 0 ,init))
4255(defmacro ps-n-up-ycolumn (init) `(nth 1 ,init))
4256(defmacro ps-n-up-xline (init) `(nth 2 ,init))
4257(defmacro ps-n-up-yline (init) `(nth 3 ,init))
4258(defmacro ps-n-up-repeat (init) `(nth 4 ,init))
4259(defmacro ps-n-up-end (init) `(nth 5 ,init))
4260(defmacro ps-n-up-xstart (init) `(nth 6 ,init))
4261(defmacro ps-n-up-ystart (init) `(nth 7 ,init))
4262
4263
ef2cbb24 4264(defun ps-begin-file ()
bcc0d457 4265 (ps-get-page-dimensions)
7da17ab6 4266 (setq ps-page-postscript 0
bc0d41bd 4267 ps-page-order 0
87a16a06
RS
4268 ps-background-text-count 0
4269 ps-background-image-count 0
4270 ps-background-pages nil
4271 ps-background-all-pages nil)
12d89a2e 4272
bc0d41bd
KH
4273 (let ((dimensions (cdr (assq ps-paper-type ps-page-dimensions-database)))
4274 (tumble (if ps-landscape-mode (not ps-spool-tumble) ps-spool-tumble))
4275 (n-up (ps-n-up-printing))
4276 (n-up-filling (ps-n-up-filling)))
4277 (and (> ps-n-up-printing 1) (setq tumble (not tumble)))
4278 (ps-output
4279 ps-adobe-tag
4280 "%%Title: " (buffer-name) ; Take job name from name of
8bd22fcf 4281 ; first buffer printed
bc0d41bd
KH
4282 "\n%%Creator: " (user-full-name)
4283 " (using ps-print v" ps-print-version
4284 ")\n%%CreationDate: "
4285 (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy)
4286 "\n%%Orientation: "
4287 (if ps-landscape-mode "Landscape" "Portrait")
4288 "\n%%DocumentNeededResources: font Times-Roman Times-Italic\n%%+ font "
4289 (mapconcat 'identity
4290 (ps-remove-duplicates
4291 (append (ps-fonts 'ps-font-for-text)
4292 (list (ps-font 'ps-font-for-header 'normal)
4293 (ps-font 'ps-font-for-header 'bold))))
4294 "\n%%+ font ")
4295 "\n%%DocumentMedia: " (ps-page-dimensions-get-media dimensions)
4296 (format " %d" (round (ps-page-dimensions-get-width dimensions)))
4297 (format " %d" (round (ps-page-dimensions-get-height dimensions)))
4298 " 0 () ()\n%%PageOrder: Ascend\n%%Pages: (atend)\n%%Requirements:"
4299 (if ps-spool-duplex
4300 (format " duplex%s" (if tumble "(tumble)\n" "\n"))
4301 "\n"))
4302
4303 (let ((comments (if (functionp ps-print-prologue-header)
4304 (funcall ps-print-prologue-header)
4305 ps-print-prologue-header)))
4306 (and (stringp comments)
4307 (ps-output comments)))
4308
4309 (ps-output "%%EndComments\n\n%%BeginPrologue\n\n"
4310 "/gs_languagelevel /languagelevel where {pop languagelevel}{1}ifelse def\n\n")
4311
4312 (ps-output-boolean "SkipFirstPage " ps-banner-page-when-duplexing)
4313 (ps-output-boolean "LandscapeMode "
4314 (or ps-landscape-mode
4315 (eq (ps-n-up-landscape n-up) 'pag)))
4316 (ps-output (format "/NumberOfColumns %d def\n" ps-number-of-columns)
4317
4318 (format "/LandscapePageHeight %s def\n" ps-landscape-page-height)
4319 (format "/PrintPageWidth %s def\n"
4320 (- (* (+ ps-print-width ps-inter-column)
4321 ps-number-of-columns)
4322 ps-inter-column))
4323 (format "/PrintWidth %s def\n" ps-print-width)
4324 (format "/PrintHeight %s def\n" ps-print-height)
4325
4326 (format "/LeftMargin %s def\n" ps-left-margin)
4327 (format "/RightMargin %s def\n" ps-right-margin)
4328 (format "/InterColumn %s def\n" ps-inter-column)
4329
4330 (format "/BottomMargin %s def\n" ps-bottom-margin)
4331 (format "/TopMargin %s def\n" ps-top-margin) ; not used
4332 (format "/HeaderOffset %s def\n" ps-header-offset)
4333 (format "/HeaderPad %s def\n" ps-header-pad))
4334
4335 (ps-output-boolean "PrintHeader " ps-print-header)
4336 (ps-output-boolean "PrintOnlyOneHeader" ps-print-only-one-header)
4337 (ps-output-boolean "PrintHeaderFrame " ps-print-header-frame)
4338 (ps-output-boolean "ShowNofN " ps-show-n-of-n)
4339 (ps-output-boolean "DuplexValue " ps-spool-duplex)
4340 (ps-output-boolean "TumbleValue " tumble)
4341
4342 (let ((line-height (ps-line-height 'ps-font-for-text)))
4343 (ps-output (format "/LineHeight %s def\n" line-height)
4344 (format "/LinesPerColumn %d def\n"
4345 (round (/ (+ ps-print-height
4346 (* line-height 0.45))
4347 line-height)))))
4348
4349 (ps-output-boolean "Zebra " ps-zebra-stripes)
4350 (ps-output-boolean "PrintLineNumber " ps-line-number)
4351 (ps-output (format "/ZebraHeight %d def\n" ps-zebra-stripe-height)
4352 (format "/ZebraGray %s def\n" ps-zebra-gray)
4353 "/UseSetpagedevice "
4354 (if (eq ps-spool-config 'setpagedevice)
4355 "/setpagedevice where {pop true}{false}ifelse def\n"
4356 "false def\n")
4357 "\n/PageWidth "
4358 "PrintPageWidth LeftMargin add RightMargin add def\n\n"
4359 (format "/N-Up %d def\n" ps-n-up-printing))
4360 (ps-output-boolean "N-Up-Landscape" (eq (ps-n-up-landscape n-up) t))
4361 (ps-output-boolean "N-Up-Border " ps-n-up-border-p)
4362 (ps-output (format "/N-Up-Lines %d def\n" (ps-n-up-lines n-up))
4363 (format "/N-Up-Columns %d def\n" (ps-n-up-columns n-up))
4364 (format "/N-Up-Missing %d def\n" (ps-n-up-missing n-up))
4365 (format "/N-Up-Margin %s" ps-n-up-margin)
4366 " def\n/N-Up-Repeat "
4367 (if ps-landscape-mode
4368 (ps-n-up-end n-up-filling)
4369 (ps-n-up-repeat n-up-filling))
4370 " def\n/N-Up-End "
4371 (if ps-landscape-mode
4372 (ps-n-up-repeat n-up-filling)
4373 (ps-n-up-end n-up-filling))
4374 " def\n/N-Up-XColumn " (ps-n-up-xcolumn n-up-filling)
4375 " def\n/N-Up-YColumn " (ps-n-up-ycolumn n-up-filling)
4376 " def\n/N-Up-XLine " (ps-n-up-xline n-up-filling)
4377 " def\n/N-Up-YLine " (ps-n-up-yline n-up-filling)
4378 " def\n/N-Up-XStart " (ps-n-up-xstart n-up-filling)
4379 " def\n/N-Up-YStart " (ps-n-up-ystart n-up-filling) " def\n")
4380
4381 (ps-background-text)
4382 (ps-background-image)
4383 (setq ps-background-all-pages (nreverse ps-background-all-pages)
4384 ps-background-pages (nreverse ps-background-pages))
4385
4386 (ps-output ps-print-prologue-1)
4387
4388 (ps-output "/printGlobalBackground {\n")
4389 (ps-output-list ps-background-all-pages)
4390 (ps-output "} def\n/printLocalBackground {\n} def\n")
4391
4392 ;; Header fonts
4393 (ps-output (format "/h0 %s (%s) cvn DefFont\n" ; /h0 14 /Helvetica-Bold DefFont
4394 ps-header-title-font-size-internal
4395 (ps-font 'ps-font-for-header 'bold))
4396 (format "/h1 %s (%s) cvn DefFont\n" ; /h1 12 /Helvetica DefFont
4397 ps-header-font-size-internal
4398 (ps-font 'ps-font-for-header 'normal)))
4399
4400 (ps-output ps-print-prologue-2)
4401
4402 ;; Text fonts
4403 (let ((font (ps-font-alist 'ps-font-for-text))
4404 (i 0))
4405 (while font
4406 (ps-output (format "/f%d %s (%s) cvn DefFont\n"
4407 i
4408 ps-font-size-internal
4409 (ps-font 'ps-font-for-text (car (car font)))))
4410 (setq font (cdr font)
4411 i (1+ i))))
4412
4413 (let ((font-entry (cdr (assq ps-font-family ps-font-info-database))))
4414 (ps-output (format "/SpaceWidthRatio %f def\n"
4415 (/ (ps-lookup 'space-width) (ps-lookup 'size)))))
4416
4417 (ps-output "\n%%EndPrologue\n\n%%BeginSetup\n")
4418 (unless (eq ps-spool-config 'lpr-switches)
4419 (ps-output "\n%%BeginFeature: *Duplex "
4420 (ps-boolean-capitalized ps-spool-duplex)
4421 " *Tumble "
4422 (ps-boolean-capitalized tumble)
4423 ps-print-duplex-feature
4424 "%%EndFeature\n")))
4425 (ps-output "\n/Lines 0 def\n/PageCount 0 def\n\nBeginDoc\n%%EndSetup\n"))
4426
4427
4428(defun ps-boolean-capitalized (bool)
4429 (if bool "True" "False"))
4430
ef2cbb24 4431
12d89a2e
RS
4432(defun ps-header-dirpart ()
4433 (let ((fname (buffer-file-name)))
4434 (if fname
4435 (if (string-equal (buffer-name) (file-name-nondirectory fname))
4436 (file-name-directory fname)
4437 fname)
4438 "")))
ef2cbb24 4439
bc0d41bd 4440
12d89a2e 4441(defun ps-get-buffer-name ()
bcc0d457
RS
4442 (cond
4443 ;; Indulge Jim this little easter egg:
4444 ((string= (buffer-name) "ps-print.el")
4445 "Hey, Cool! It's ps-print.el!!!")
4446 ;; Indulge Jack this other little easter egg:
4447 ((string= (buffer-name) "sokoban.el")
4448 "Super! C'est sokoban.el!")
87a16a06 4449 (t (concat
bc0d41bd 4450 (and ps-printing-region-p "Subset of: ")
87a16a06
RS
4451 (buffer-name)
4452 (and (buffer-modified-p) " (unsaved)")))))
ef2cbb24 4453
7d8b7e8e
KH
4454
4455(defun ps-get-font-size (font-sym)
4456 (let ((font-size (symbol-value font-sym)))
4457 (cond ((numberp font-size)
4458 font-size)
4459 ((and (consp font-size)
4460 (numberp (car font-size))
4461 (numberp (cdr font-size)))
4462 (if ps-landscape-mode
4463 (car font-size)
4464 (cdr font-size)))
4465 (t
4466 (error "Invalid font size `%S' for `%S'" font-size font-sym)))))
4467
4468
12d89a2e 4469(defun ps-begin-job ()
7da17ab6
RS
4470 (save-excursion
4471 (set-buffer ps-spool-buffer)
4472 (goto-char (point-max))
4473 (and (re-search-backward "^%%Trailer$" nil t)
4474 (delete-region (match-beginning 0) (point-max))))
bc0d41bd 4475 (setq ps-showline-count (car ps-printing-region)
7da17ab6 4476 ps-page-count 0
7d8b7e8e
KH
4477 ps-font-size-internal (ps-get-font-size 'ps-font-size)
4478 ps-header-font-size-internal (ps-get-font-size 'ps-header-font-size)
4479 ps-header-title-font-size-internal
4480 (ps-get-font-size 'ps-header-title-font-size)
857686a6 4481 ps-control-or-escape-regexp
298bfad9
KH
4482 (cond ((eq ps-print-control-characters '8-bit)
4483 (string-as-unibyte "[\000-\037\177-\377]"))
4484 ((eq ps-print-control-characters 'control-8-bit)
4485 (string-as-unibyte "[\000-\037\177-\237]"))
4486 ((eq ps-print-control-characters 'control)
4487 "[\000-\037\177]")
4488 (t "[\t\n\f]"))))
ef2cbb24 4489
12b88fff
RS
4490(defmacro ps-page-number ()
4491 `(1+ (/ (1- ps-page-count) ps-number-of-columns)))
4492
ef2cbb24 4493(defun ps-end-file ()
bc0d41bd
KH
4494 ;; Back to the PS output buffer to set the last page n-up printing
4495 (save-excursion
4496 (let ((pages-per-sheet (mod ps-page-postscript ps-n-up-printing))
4497 case-fold-search)
4498 (set-buffer ps-spool-buffer)
4499 (goto-char (point-max))
4500 (and (> pages-per-sheet 0)
4501 (re-search-backward "^[0-9]+ BeginSheet$" nil t)
4502 (replace-match (format "%d BeginSheet" pages-per-sheet) t))))
4503 ;; Set dummy page
4504 (and ps-spool-duplex (= (mod ps-page-order 2) 1)
4505 (ps-dummy-page))
4506 ;; Set end of PostScript file
4507 (ps-output "EndSheet\n\n%%Trailer\n%%Pages: "
4508 (format "%d" ps-page-order)
984e7bd9 4509 "\n\nEndDoc\n\n%%EOF\n"))
87a16a06
RS
4510
4511
ef2cbb24
RS
4512(defun ps-next-page ()
4513 (ps-end-page)
12d89a2e
RS
4514 (ps-flush-output)
4515 (ps-begin-page))
4516
bc0d41bd
KH
4517
4518(defun ps-header-sheet ()
4519 ;; Print only when a new sheet begins.
4520 (setq ps-page-postscript (1+ ps-page-postscript)
4521 ps-page-order (1+ ps-page-order))
4522 (and (> ps-page-order 1)
4523 (ps-output "EndSheet\n"))
4524 (ps-output (format "\n%%%%Page: %d %d\n"
4525 ps-page-postscript ps-page-order))
4526 (ps-output (format "%d BeginSheet\nBeginDSCPage\n" ps-n-up-printing)))
4527
4528
4529(defsubst ps-header-page ()
7da17ab6
RS
4530 ;; set total line and page number when printing has finished
4531 ;; (see `ps-generate')
bc0d41bd
KH
4532 (run-hooks
4533 (if (prog1
4534 (zerop (mod ps-page-count ps-number-of-columns))
4535 (setq ps-page-count (1+ ps-page-count)))
4536 (prog1
4537 (if (zerop (mod ps-page-postscript ps-n-up-printing))
4538 ;; Print only when a new sheet begins.
4539 (progn
4540 (ps-header-sheet)
4541 'ps-print-begin-sheet-hook)
4542 ;; Print only when a new page begins.
4543 (setq ps-page-postscript (1+ ps-page-postscript))
4544 (ps-output "BeginDSCPage\n")
4545 'ps-print-begin-page-hook)
4546 (ps-background ps-page-postscript))
4547 ;; Print only when a new column begins.
4548 (ps-output "BeginDSCPage\n")
4549 'ps-print-begin-column-hook)))
a18ed129 4550
8bd22fcf 4551(defun ps-begin-page ()
12d89a2e 4552 (ps-get-page-dimensions)
8bd22fcf 4553 (setq ps-width-remaining ps-print-width
298bfad9 4554 ps-height-remaining ps-print-height)
12d89a2e 4555
a18ed129 4556 (ps-header-page)
12d89a2e 4557
87a16a06 4558 (ps-output (format "/LineNumber %d def\n" ps-showline-count)
12b88fff
RS
4559 (format "/PageNumber %d def\n" (if ps-print-only-one-header
4560 (ps-page-number)
4561 ps-page-count)))
12d89a2e 4562
090be653
RS
4563 (when ps-print-header
4564 (ps-generate-header "HeaderLinesLeft" ps-left-header)
4565 (ps-generate-header "HeaderLinesRight" ps-right-header)
4566 (ps-output (format "%d SetHeaderLines\n" ps-header-lines)))
12d89a2e
RS
4567
4568 (ps-output "BeginPage\n")
87a16a06
RS
4569 (ps-set-font ps-current-font)
4570 (ps-set-bg ps-current-bg)
298bfad9
KH
4571 (ps-set-color ps-current-color)
4572 (ps-mule-begin-page))
ef2cbb24
RS
4573
4574(defun ps-end-page ()
a18ed129 4575 (ps-output "EndPage\nEndDSCPage\n"))
12d89a2e
RS
4576
4577(defun ps-dummy-page ()
bc0d41bd
KH
4578 (let ((ps-n-up-printing 0))
4579 (ps-header-sheet))
a18ed129 4580 (ps-output "/PrintHeader false def
bc0d41bd
KH
4581/ColumnIndex 0 def
4582/PrintLineNumber false def
12d89a2e
RS
4583BeginPage
4584EndPage
bc0d41bd
KH
4585EndDSCPage\n")
4586 (setq ps-page-postscript ps-n-up-printing))
06fb6aab 4587
ef2cbb24 4588(defun ps-next-line ()
87a16a06 4589 (setq ps-showline-count (1+ ps-showline-count))
12b88fff
RS
4590 (let ((lh (ps-line-height 'ps-font-for-text)))
4591 (if (< ps-height-remaining lh)
4592 (ps-next-page)
4593 (setq ps-width-remaining ps-print-width
4594 ps-height-remaining (- ps-height-remaining lh))
4595 (ps-output "HL\n"))))
ef2cbb24
RS
4596
4597(defun ps-continue-line ()
12b88fff
RS
4598 (let ((lh (ps-line-height 'ps-font-for-text)))
4599 (if (< ps-height-remaining lh)
4600 (ps-next-page)
4601 (setq ps-width-remaining ps-print-width
4602 ps-height-remaining (- ps-height-remaining lh))
4603 (ps-output "SL\n"))))
12d89a2e
RS
4604
4605(defun ps-find-wrappoint (from to char-width)
4606 (let ((avail (truncate (/ ps-width-remaining char-width)))
4607 (todo (- to from)))
4608 (if (< todo avail)
4609 (cons to (* todo char-width))
4610 (cons (+ from avail) ps-width-remaining))))
4611
4612(defun ps-basic-plot-string (from to &optional bg-color)
12b88fff
RS
4613 (let* ((wrappoint (ps-find-wrappoint from to
4614 (ps-avg-char-width 'ps-font-for-text)))
12d89a2e 4615 (to (car wrappoint))
298bfad9
KH
4616 (string (buffer-substring-no-properties from to)))
4617 (ps-mule-prepare-ascii-font string)
12d89a2e 4618 (ps-output-string string)
bcc0d457 4619 (ps-output " S\n")
12d89a2e
RS
4620 wrappoint))
4621
4622(defun ps-basic-plot-whitespace (from to &optional bg-color)
12b88fff
RS
4623 (let* ((wrappoint (ps-find-wrappoint from to
4624 (ps-space-width 'ps-font-for-text)))
12d89a2e 4625 (to (car wrappoint)))
12d89a2e
RS
4626 (ps-output (format "%d W\n" (- to from)))
4627 wrappoint))
4628
4629(defun ps-plot (plotfunc from to &optional bg-color)
ef2cbb24 4630 (while (< from to)
12d89a2e
RS
4631 (let* ((wrappoint (funcall plotfunc from to bg-color))
4632 (plotted-to (car wrappoint))
4633 (plotted-width (cdr wrappoint)))
8bd22fcf
KH
4634 (setq from plotted-to
4635 ps-width-remaining (- ps-width-remaining plotted-width))
12d89a2e
RS
4636 (if (< from to)
4637 (ps-continue-line))))
ef2cbb24
RS
4638 (if ps-razzle-dazzle
4639 (let* ((q-todo (- (point-max) (point-min)))
12d89a2e 4640 (q-done (- (point) (point-min)))
ef2cbb24 4641 (chunkfrac (/ q-todo 8))
857686a6 4642 (chunksize (min chunkfrac 1000)))
ef2cbb24 4643 (if (> (- q-done ps-razchunk) chunksize)
8bd22fcf 4644 (progn
ef2cbb24 4645 (setq ps-razchunk q-done)
8bd22fcf
KH
4646 (message "Formatting...%3d%%"
4647 (if (< q-todo 100)
4648 (/ (* 100 q-done) q-todo)
4649 (/ q-done (/ q-todo 100)))
4650 ))))))
12d89a2e 4651
298bfad9
KH
4652(defvar ps-last-font nil)
4653
12d89a2e 4654(defun ps-set-font (font)
e65df0a1
KH
4655 (setq ps-last-font (format "f%d" (setq ps-current-font font)))
4656 (ps-output (format "/%s F\n" ps-last-font)))
12d89a2e 4657
12d89a2e
RS
4658(defun ps-set-bg (color)
4659 (if (setq ps-current-bg color)
8bd22fcf
KH
4660 (ps-output (format ps-color-format
4661 (nth 0 color) (nth 1 color) (nth 2 color))
12d89a2e
RS
4662 " true BG\n")
4663 (ps-output "false BG\n")))
4664
4665(defun ps-set-color (color)
a18ed129 4666 (setq ps-current-color (or color ps-default-fg))
8bd22fcf
KH
4667 (ps-output (format ps-color-format
4668 (nth 0 ps-current-color)
043620f4
KH
4669 (nth 1 ps-current-color) (nth 2 ps-current-color))
4670 " FG\n"))
12d89a2e 4671
12d89a2e 4672
87a16a06 4673(defvar ps-current-effect 0)
12d89a2e 4674
87a16a06
RS
4675
4676(defun ps-plot-region (from to font &optional fg-color bg-color effects)
12d89a2e
RS
4677 (if (not (equal font ps-current-font))
4678 (ps-set-font font))
06fb6aab 4679
12d89a2e
RS
4680 ;; Specify a foreground color only if one's specified and it's
4681 ;; different than the current.
4682 (if (not (equal fg-color ps-current-color))
4683 (ps-set-color fg-color))
06fb6aab 4684
12d89a2e
RS
4685 (if (not (equal bg-color ps-current-bg))
4686 (ps-set-bg bg-color))
06fb6aab 4687
87a16a06
RS
4688 ;; Specify effects (underline, overline, box, etc)
4689 (cond
4690 ((not (integerp effects))
4691 (ps-output "0 EF\n")
4692 (setq ps-current-effect 0))
4693 ((/= effects ps-current-effect)
4694 (ps-output (number-to-string effects) " EF\n")
4695 (setq ps-current-effect effects)))
ef2cbb24 4696
12d89a2e 4697 ;; Starting at the beginning of the specified region...
ef2cbb24
RS
4698 (save-excursion
4699 (goto-char from)
12d89a2e
RS
4700
4701 ;; ...break the region up into chunks separated by tabs, linefeeds,
87a16a06 4702 ;; pagefeeds, control characters, and plot each chunk.
ef2cbb24 4703 (while (< from to)
857686a6 4704 (if (re-search-forward ps-control-or-escape-regexp to t)
024ced4d 4705 ;; region with some control characters or some multi-byte characters
12b88fff
RS
4706 (let* ((match-point (match-beginning 0))
4707 (match (char-after match-point)))
e65df0a1 4708 (when (< from match-point)
298bfad9 4709 (ps-mule-set-ascii-font)
e65df0a1 4710 (ps-plot 'ps-basic-plot-string from match-point bg-color))
857686a6
RS
4711 (cond
4712 ((= match ?\t) ; tab
be415ea7 4713 (let ((linestart (line-beginning-position)))
857686a6
RS
4714 (forward-char -1)
4715 (setq from (+ linestart (current-column)))
e65df0a1 4716 (when (re-search-forward "[ \t]+" to t)
298bfad9 4717 (ps-mule-set-ascii-font)
e65df0a1
KH
4718 (ps-plot 'ps-basic-plot-whitespace
4719 from (+ linestart (current-column))
4720 bg-color))))
857686a6
RS
4721
4722 ((= match ?\n) ; newline
4723 (ps-next-line))
4724
4725 ((= match ?\f) ; form feed
12b88fff
RS
4726 ;; do not skip page if previous character is NEWLINE and
4727 ;; it is a beginning of page.
4728 (or (and (= (char-after (1- match-point)) ?\n)
4729 (= ps-height-remaining ps-print-height))
4730 (ps-next-page)))
e65df0a1 4731
024ced4d 4732 ((> match 255) ; a multi-byte character
e65df0a1
KH
4733 (let ((charset (char-charset match)))
4734 (or (eq charset 'composition)
298bfad9
KH
4735 (while (eq (charset-after) charset)
4736 (forward-char 1)))
e65df0a1 4737 (ps-plot 'ps-mule-plot-string match-point (point) bg-color)))
857686a6
RS
4738 ; characters from ^@ to ^_ and
4739 (t ; characters from 127 to 255
4740 (ps-control-character match)))
87a16a06 4741 (setq from (point)))
024ced4d 4742 ;; region without control characters nor multi-byte characters
298bfad9 4743 (ps-mule-set-ascii-font)
87a16a06
RS
4744 (ps-plot 'ps-basic-plot-string from to bg-color)
4745 (setq from to)))))
4746
857686a6
RS
4747(defvar ps-string-control-codes
4748 (let ((table (make-vector 256 nil))
4749 (char ?\000))
4750 ;; control character
4751 (while (<= char ?\037)
4752 (aset table char (format "^%c" (+ char ?@)))
4753 (setq char (1+ char)))
4754 ;; printable character
4755 (while (< char ?\177)
4756 (aset table char (format "%c" char))
4757 (setq char (1+ char)))
4758 ;; DEL
4759 (aset table char "^?")
4760 ;; 8-bit character
4761 (while (<= (setq char (1+ char)) ?\377)
4762 (aset table char (format "\\%o" char)))
4763 table)
4764 "Vector used to map characters to a printable string.")
4765
4766(defun ps-control-character (char)
4767 (let* ((str (aref ps-string-control-codes char))
4768 (from (1- (point)))
87a16a06
RS
4769 (len (length str))
4770 (to (+ from len))
12b88fff
RS
4771 (char-width (ps-avg-char-width 'ps-font-for-text))
4772 (wrappoint (ps-find-wrappoint from to char-width)))
87a16a06
RS
4773 (if (< (car wrappoint) to)
4774 (ps-continue-line))
12b88fff 4775 (setq ps-width-remaining (- ps-width-remaining (* len char-width)))
36243805 4776 (ps-mule-prepare-ascii-font str)
87a16a06
RS
4777 (ps-output-string str)
4778 (ps-output " S\n")))
ef2cbb24 4779
12d89a2e
RS
4780(defun ps-color-value (x-color-value)
4781 ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
4782 (/ x-color-value ps-print-color-scale))
ef2cbb24 4783
d3ab8dac
KH
4784
4785(cond ((eq ps-print-emacs-type 'emacs) ; emacs
4786
4787 (defun ps-color-values (x-color)
4788 (if (fboundp 'x-color-values)
4789 (x-color-values x-color)
4790 (error "No available function to determine X color values.")))
4791 )
4792 ; xemacs
4793 ; lucid
4794 (t ; epoch
4795 (defun ps-color-values (x-color)
4796 (cond ((fboundp 'x-color-values)
4797 (x-color-values x-color))
4798 ((and (fboundp 'color-instance-rgb-components)
4799 (ps-color-device))
4800 (color-instance-rgb-components
4801 (if (color-instance-p x-color)
4802 x-color
4803 (make-color-instance
4804 (if (color-specifier-p x-color)
4805 (color-name x-color)
4806 x-color)))))
bc0d41bd
KH
4807 (t
4808 (error "No available function to determine X color values."))))
d3ab8dac 4809 ))
043620f4 4810
87a16a06 4811
a18ed129
RS
4812(defun ps-face-attributes (face)
4813 "Return face attribute vector.
87a16a06 4814
a18ed129
RS
4815If FACE is not in `ps-print-face-extension-alist' or in
4816`ps-print-face-alist', insert it on `ps-print-face-alist' and
4817return the attribute vector.
87a16a06
RS
4818
4819If FACE is not a valid face name, it is used default face."
a18ed129
RS
4820 (cdr (or (assq face ps-print-face-extension-alist)
4821 (assq face ps-print-face-alist)
4822 (let* ((the-face (if (facep face) face 'default))
4823 (new-face (ps-screen-to-bit-face the-face)))
4824 (or (and (eq the-face 'default)
4825 (assq the-face ps-print-face-alist))
4826 (setq ps-print-face-alist (cons new-face ps-print-face-alist)))
4827 new-face))))
87a16a06 4828
043620f4
KH
4829
4830(defun ps-face-attribute-list (face-or-list)
4831 (if (listp face-or-list)
87a16a06 4832 ;; list of faces
857686a6
RS
4833 (let ((effects 0)
4834 foreground background face-attr)
043620f4 4835 (while face-or-list
857686a6 4836 (setq face-attr (ps-face-attributes (car face-or-list))
87a16a06
RS
4837 effects (logior effects (aref face-attr 0)))
4838 (or foreground (setq foreground (aref face-attr 1)))
4839 (or background (setq background (aref face-attr 2)))
043620f4 4840 (setq face-or-list (cdr face-or-list)))
87a16a06
RS
4841 (vector effects foreground background))
4842 ;; simple face
043620f4
KH
4843 (ps-face-attributes face-or-list)))
4844
87a16a06 4845
12b88fff
RS
4846(defconst ps-font-type (vector nil 'bold 'italic 'bold-italic))
4847
4848
12d89a2e 4849(defun ps-plot-with-face (from to face)
12b88fff
RS
4850 (cond
4851 ((null face) ; print text with null face
87a16a06 4852 (ps-plot-region from to 0))
12b88fff
RS
4853 ((eq face 'emacs--invisible--face)) ; skip invisible text!!!
4854 (t ; otherwise, text has a valid face
4855 (let* ((face-bit (ps-face-attribute-list face))
4856 (effect (aref face-bit 0))
4857 (foreground (aref face-bit 1))
4858 (background (aref face-bit 2))
d3ab8dac 4859 (fg-color (if (and ps-color-p foreground)
12b88fff
RS
4860 (mapcar 'ps-color-value
4861 (ps-color-values foreground))
4862 ps-default-color))
d3ab8dac 4863 (bg-color (and ps-color-p background
12b88fff
RS
4864 (mapcar 'ps-color-value
4865 (ps-color-values background)))))
4866 (ps-plot-region
4867 from to
4868 (ps-font-number 'ps-font-for-text
4869 (or (aref ps-font-type (logand effect 3))
4870 face))
4871 fg-color bg-color (lsh effect -2)))))
87a16a06 4872 (goto-char to))
12d89a2e
RS
4873
4874
298bfad9
KH
4875(defun ps-xemacs-face-kind-p (face kind kind-regex kind-list)
4876 (let* ((frame-font (or (face-font-instance face)
4877 (face-font-instance 'default)))
4878 (kind-cons (and frame-font
4879 (assq kind
4880 (font-instance-properties frame-font))))
4881 (kind-spec (cdr-safe kind-cons))
4882 (case-fold-search t))
4883 (or (and kind-spec (string-match kind-regex kind-spec))
4884 ;; Kludge-compatible:
4885 (memq face kind-list))))
4886
4887
e65df0a1
KH
4888(cond ((eq ps-print-emacs-type 'emacs) ; emacs
4889
4890 (defun ps-face-bold-p (face)
4891 (or (face-bold-p face)
4892 (memq face ps-bold-faces)))
4893
4894 (defun ps-face-italic-p (face)
4895 (or (face-italic-p face)
4896 (memq face ps-italic-faces)))
4897 )
4898 ; xemacs
4899 ; lucid
e65df0a1
KH
4900 (t ; epoch
4901 (defun ps-face-bold-p (face)
d3ab8dac
KH
4902 (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold"
4903 ps-bold-faces))
e65df0a1
KH
4904
4905 (defun ps-face-italic-p (face)
4906 (or (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o" ps-italic-faces)
4907 (ps-xemacs-face-kind-p face 'SLANT "i\\|o" ps-italic-faces)))
4908 ))
4909
12d89a2e
RS
4910
4911(defun ps-face-underlined-p (face)
4912 (or (face-underline-p face)
4913 (memq face ps-underlined-faces)))
4914
a18ed129 4915
043620f4
KH
4916;; Ensure that face-list is fbound.
4917(or (fboundp 'face-list) (defalias 'face-list 'list-faces))
12d89a2e 4918
a18ed129 4919
12d89a2e 4920(defun ps-build-reference-face-lists ()
857686a6
RS
4921 ;; Ensure that face database is updated with faces on
4922 ;; `font-lock-face-attributes' (obsolete stuff)
4923 (ps-font-lock-face-attributes)
4924 ;; Now, rebuild reference face lists
a18ed129 4925 (setq ps-print-face-alist nil)
12d89a2e 4926 (if ps-auto-font-detect
a18ed129
RS
4927 (mapcar 'ps-map-face (face-list))
4928 (mapcar 'ps-set-face-bold ps-bold-faces)
4929 (mapcar 'ps-set-face-italic ps-italic-faces)
4930 (mapcar 'ps-set-face-underline ps-underlined-faces))
12d89a2e 4931 (setq ps-build-face-reference nil))
ef2cbb24 4932
a18ed129
RS
4933
4934(defun ps-set-face-bold (face)
4935 (ps-set-face-attribute face 1))
4936
4937(defun ps-set-face-italic (face)
4938 (ps-set-face-attribute face 2))
4939
4940(defun ps-set-face-underline (face)
4941 (ps-set-face-attribute face 4))
4942
4943
4944(defun ps-set-face-attribute (face effect)
4945 (let ((face-bit (cdr (ps-map-face face))))
4946 (aset face-bit 0 (logior (aref face-bit 0) effect))))
4947
4948
4949(defun ps-map-face (face)
4950 (let* ((face-map (ps-screen-to-bit-face face))
4951 (ps-face-bit (cdr (assq (car face-map) ps-print-face-alist))))
4952 (if ps-face-bit
4953 ;; if face exists, merge both
4954 (let ((face-bit (cdr face-map)))
4955 (aset ps-face-bit 0 (logior (aref ps-face-bit 0) (aref face-bit 0)))
4956 (or (aref ps-face-bit 1) (aset ps-face-bit 1 (aref face-bit 1)))
4957 (or (aref ps-face-bit 2) (aset ps-face-bit 2 (aref face-bit 2))))
4958 ;; if face does not exist, insert it
4959 (setq ps-print-face-alist (cons face-map ps-print-face-alist)))
4960 face-map))
4961
4962
4963(defun ps-screen-to-bit-face (face)
4964 (cons face
4965 (vector (logior (if (ps-face-bold-p face) 1 0) ; bold
4966 (if (ps-face-italic-p face) 2 0) ; italic
4967 (if (ps-face-underlined-p face) 4 0)) ; underline
4968 (face-foreground face)
4969 (face-background face))))
4970
4971
d3ab8dac
KH
4972(cond ((not (eq ps-print-emacs-type 'emacs))
4973 ; xemacs
4974 ; lucid
4975 ; epoch
4976 (defun ps-mapper (extent list)
4977 (nconc list (list (list (extent-start-position extent) 'push extent)
4978 (list (extent-end-position extent) 'pull extent)))
4979 nil)
4980
4981 (defun ps-extent-sorter (a b)
4982 (< (extent-priority a) (extent-priority b)))
4983 ))
ef2cbb24 4984
043620f4
KH
4985
4986(defun ps-print-ensure-fontified (start end)
857686a6 4987 (and (boundp 'lazy-lock-mode) (symbol-value 'lazy-lock-mode)
d3ab8dac 4988 (lazy-lock-fontify-region start end)))
043620f4 4989
ef2cbb24 4990(defun ps-generate-postscript-with-faces (from to)
87a16a06 4991 ;; Some initialization...
857686a6 4992 (setq ps-current-effect 0)
87a16a06 4993
00aa16af 4994 ;; Build the reference lists of faces if necessary.
12d89a2e
RS
4995 (if (or ps-always-build-face-reference
4996 ps-build-face-reference)
4997 (progn
4998 (message "Collecting face information...")
4999 (ps-build-reference-face-lists)))
00aa16af
RS
5000 ;; Set the color scale. We do it here instead of in the defvar so
5001 ;; that ps-print can be dumped into emacs. This expression can't be
5002 ;; evaluated at dump-time because X isn't initialized.
d3ab8dac
KH
5003 (setq ps-color-p (and ps-print-color-p (ps-color-device))
5004 ps-print-color-scale (if ps-color-p
5005 (float (car (ps-color-values "white")))
5006 1.0))
00aa16af 5007 ;; Generate some PostScript.
ef2cbb24
RS
5008 (save-restriction
5009 (narrow-to-region from to)
d3ab8dac 5010 (ps-print-ensure-fontified from to)
12d89a2e
RS
5011 (let ((face 'default)
5012 (position to))
87a16a06
RS
5013 (cond
5014 ((or (eq ps-print-emacs-type 'lucid)
5015 (eq ps-print-emacs-type 'xemacs))
5016 ;; Build the list of extents...
5017 (let ((a (cons 'dummy nil))
5018 record type extent extent-list)
5019 (map-extents 'ps-mapper nil from to a)
8bd22fcf
KH
5020 (setq a (sort (cdr a) 'car-less-than-car)
5021 extent-list nil)
87a16a06
RS
5022
5023 ;; Loop through the extents...
5024 (while a
8bd22fcf 5025 (setq record (car a)
87a16a06 5026
8bd22fcf
KH
5027 position (car record)
5028 record (cdr record)
87a16a06 5029
8bd22fcf
KH
5030 type (car record)
5031 record (cdr record)
87a16a06 5032
8bd22fcf 5033 extent (car record))
87a16a06
RS
5034
5035 ;; Plot up to this record.
5036 ;; XEmacs 19.12: for some reason, we're getting into a
5037 ;; situation in which some of the records have
5038 ;; positions less than 'from'. Since we've narrowed
5039 ;; the buffer, this'll generate errors. This is a
5040 ;; hack, but don't call ps-plot-with-face unless from >
5041 ;; point-min.
8bd22fcf
KH
5042 (and (>= from (point-min)) (<= position (point-max))
5043 (ps-plot-with-face from position face))
87a16a06
RS
5044
5045 (cond
5046 ((eq type 'push)
d3ab8dac
KH
5047 (and (extent-face extent)
5048 (setq extent-list (sort (cons extent extent-list)
5049 'ps-extent-sorter))))
87a16a06
RS
5050
5051 ((eq type 'pull)
5052 (setq extent-list (sort (delq extent extent-list)
5053 'ps-extent-sorter))))
5054
d3ab8dac
KH
5055 (setq face (if extent-list
5056 (extent-face (car extent-list))
5057 'default)
8bd22fcf
KH
5058 from position
5059 a (cdr a)))))
87a16a06
RS
5060
5061 ((eq ps-print-emacs-type 'emacs)
5062 (let ((property-change from)
e65df0a1
KH
5063 (overlay-change from)
5064 (save-buffer-invisibility-spec buffer-invisibility-spec)
c82b4a75 5065 (buffer-invisibility-spec nil))
87a16a06 5066 (while (< from to)
d3ab8dac 5067 (and (< property-change to) ; Don't search for property change
12d89a2e 5068 ; unless previous search succeeded.
d3ab8dac
KH
5069 (setq property-change (next-property-change from nil to)))
5070 (and (< overlay-change to) ; Don't search for overlay change
12d89a2e 5071 ; unless previous search succeeded.
d3ab8dac
KH
5072 (setq overlay-change (min (next-overlay-change from) to)))
5073 (setq position (min property-change overlay-change))
87a16a06
RS
5074 ;; The code below is not quite correct,
5075 ;; because a non-nil overlay invisible property
5076 ;; which is inactive according to the current value
5077 ;; of buffer-invisibility-spec nonetheless overrides
5078 ;; a face text property.
5079 (setq face
5080 (cond ((let ((prop (get-text-property from 'invisible)))
5081 ;; Decide whether this invisible property
5082 ;; really makes the text invisible.
e65df0a1 5083 (if (eq save-buffer-invisibility-spec t)
87a16a06 5084 (not (null prop))
e65df0a1
KH
5085 (or (memq prop save-buffer-invisibility-spec)
5086 (assq prop save-buffer-invisibility-spec))))
12b88fff 5087 'emacs--invisible--face)
87a16a06
RS
5088 ((get-text-property from 'face))
5089 (t 'default)))
5090 (let ((overlays (overlays-at from))
5091 (face-priority -1)) ; text-property
d3ab8dac
KH
5092 (while (and overlays
5093 (not (eq face 'emacs--invisible--face)))
87a16a06 5094 (let* ((overlay (car overlays))
87a16a06 5095 (overlay-invisible (overlay-get overlay 'invisible))
d3ab8dac 5096 (overlay-priority (or (overlay-get overlay 'priority)
87a16a06 5097 0)))
d3ab8dac 5098 (and (> overlay-priority face-priority)
e65df0a1
KH
5099 (setq face
5100 (cond ((if (eq save-buffer-invisibility-spec t)
5101 (not (null overlay-invisible))
5102 (or (memq overlay-invisible
5103 save-buffer-invisibility-spec)
5104 (assq overlay-invisible
5105 save-buffer-invisibility-spec)))
c82b4a75 5106 'emacs--invisible--face)
d3ab8dac
KH
5107 ((overlay-get overlay 'face))
5108 (t face))
8bd22fcf 5109 face-priority overlay-priority)))
87a16a06
RS
5110 (setq overlays (cdr overlays))))
5111 ;; Plot up to this record.
5112 (ps-plot-with-face from position face)
5113 (setq from position)))))
5114 (ps-plot-with-face from to face))))
ef2cbb24
RS
5115
5116(defun ps-generate-postscript (from to)
12d89a2e 5117 (ps-plot-region from to 0 nil))
ef2cbb24
RS
5118
5119(defun ps-generate (buffer from to genfunc)
87a16a06
RS
5120 (save-excursion
5121 (let ((from (min to from))
5122 (to (max to from))
5123 ;; This avoids trouble if chars with read-only properties
5124 ;; are copied into ps-spool-buffer.
5125 (inhibit-read-only t))
5126 (save-restriction
5127 (narrow-to-region from to)
857686a6
RS
5128 (and ps-razzle-dazzle
5129 (message "Formatting...%3d%%" (setq ps-razchunk 0)))
8bd22fcf
KH
5130 (setq ps-source-buffer buffer
5131 ps-spool-buffer (get-buffer-create ps-spool-buffer-name))
87a16a06
RS
5132 (ps-init-output-queue)
5133 (let (safe-marker completed-safely needs-begin-file)
5134 (unwind-protect
00aa16af
RS
5135 (progn
5136 (set-buffer ps-spool-buffer)
7da17ab6 5137 (set-buffer-multibyte nil)
915293a2 5138
87a16a06
RS
5139 ;; Get a marker and make it point to the current end of the
5140 ;; buffer, If an error occurs, we'll delete everything from
5141 ;; the end of this marker onwards.
5142 (setq safe-marker (make-marker))
5143 (set-marker safe-marker (point-max))
5144
5145 (goto-char (point-min))
8bd22fcf
KH
5146 (or (looking-at (regexp-quote ps-adobe-tag))
5147 (setq needs-begin-file t))
87a16a06
RS
5148 (save-excursion
5149 (set-buffer ps-source-buffer)
7d8b7e8e 5150 (ps-begin-job)
298bfad9
KH
5151 (when needs-begin-file
5152 (ps-begin-file)
5153 (ps-mule-initialize))
298bfad9 5154 (ps-mule-begin-job from to)
87a16a06
RS
5155 (ps-begin-page))
5156 (set-buffer ps-source-buffer)
5157 (funcall genfunc from to)
5158 (ps-end-page)
5159
7da17ab6 5160 (ps-end-file)
87a16a06 5161 (ps-flush-output)
bc0d41bd 5162 (ps-end-job)
87a16a06
RS
5163
5164 ;; Setting this variable tells the unwind form that the
8bd22fcf 5165 ;; the PostScript was generated without error.
87a16a06
RS
5166 (setq completed-safely t))
5167
5168 ;; Unwind form: If some bad mojo occurred while generating
8bd22fcf 5169 ;; PostScript, delete all the PostScript that was generated.
87a16a06
RS
5170 ;; This protects the previously spooled files from getting
5171 ;; corrupted.
8bd22fcf
KH
5172 (and (markerp safe-marker) (not completed-safely)
5173 (progn
5174 (set-buffer ps-spool-buffer)
5175 (delete-region (marker-position safe-marker) (point-max))))))
87a16a06 5176
857686a6 5177 (and ps-razzle-dazzle (message "Formatting...done"))))))
ef2cbb24 5178
e65df0a1 5179
bc0d41bd
KH
5180(defun ps-end-job ()
5181 (let ((total-lines (cdr ps-printing-region))
5182 (total-pages (if ps-print-only-one-header
5183 (ps-page-number)
5184 ps-page-count))
5185 case-fold-search)
5186 (set-buffer ps-spool-buffer)
5187 ;; Back to the PS output buffer to set the page count
5188 (goto-char (point-min))
5189 (and (re-search-forward "^/Lines 0 def\n/PageCount 0 def$" nil t)
5190 (replace-match (format "/Lines %d def\n/PageCount %d def"
5191 total-lines total-pages) t))))
7d8b7e8e
KH
5192
5193
857686a6 5194;; Permit dynamic evaluation at print time of `ps-lpr-switches'.
ef2cbb24 5195(defun ps-do-despool (filename)
12d89a2e 5196 (if (or (not (boundp 'ps-spool-buffer))
bcc0d457 5197 (not (symbol-value 'ps-spool-buffer)))
12d89a2e 5198 (message "No spooled PostScript to print")
ef2cbb24
RS
5199 (if filename
5200 (save-excursion
857686a6 5201 (and ps-razzle-dazzle (message "Saving..."))
12d89a2e 5202 (set-buffer ps-spool-buffer)
ef2cbb24 5203 (setq filename (expand-file-name filename))
7ffaf659
EZ
5204 (let ((coding-system-for-write 'raw-text-unix))
5205 (write-region (point-min) (point-max) filename))
857686a6 5206 (and ps-razzle-dazzle (message "Wrote %s" filename)))
ef2cbb24 5207 ;; Else, spool to the printer
857686a6 5208 (and ps-razzle-dazzle (message "Printing..."))
ef2cbb24 5209 (save-excursion
12d89a2e 5210 (set-buffer ps-spool-buffer)
200127fd 5211 (let* ((coding-system-for-write 'raw-text-unix)
298bfad9
KH
5212 (ps-printer-name (or ps-printer-name
5213 (and (boundp 'printer-name)
5214 printer-name)))
200127fd 5215 (ps-lpr-switches
bc0d41bd
KH
5216 (append (and (stringp ps-printer-name)
5217 (list (concat "-P" ps-printer-name)))
5218 ps-lpr-switches)))
52cf535f
AI
5219 (apply (or ps-print-region-function 'call-process-region)
5220 (point-min) (point-max) ps-lpr-command nil
5221 (and (fboundp 'start-process) 0)
5222 nil
5223 (ps-flatten-list ; dynamic evaluation
5224 (mapcar 'ps-eval-switch ps-lpr-switches)))))
857686a6 5225 (and ps-razzle-dazzle (message "Printing...done")))
12d89a2e
RS
5226 (kill-buffer ps-spool-buffer)))
5227
857686a6
RS
5228;; Dynamic evaluation
5229(defun ps-eval-switch (arg)
5230 (cond ((stringp arg) arg)
5231 ((functionp arg) (apply arg nil))
5232 ((symbolp arg) (symbol-value arg))
5233 ((consp arg) (apply (car arg) (cdr arg)))
5234 (t nil)))
5235
5236;; `ps-flatten-list' is defined here (copied from "message.el" and
5237;; enhanced to handle dotted pairs as well) until we can get some
5238;; sensible autoloads, or `flatten-list' gets put somewhere decent.
5239
5240;; (ps-flatten-list '((a . b) c (d . e) (f g h) i . j))
5241;; => (a b c d e f g h i j)
5242
5243(defun ps-flatten-list (&rest list)
5244 (ps-flatten-list-1 list))
5245
5246(defun ps-flatten-list-1 (list)
5247 (cond ((null list) nil)
5248 ((consp list) (append (ps-flatten-list-1 (car list))
5249 (ps-flatten-list-1 (cdr list))))
5250 (t (list list))))
5251
12d89a2e
RS
5252(defun ps-kill-emacs-check ()
5253 (let (ps-buffer)
8bd22fcf
KH
5254 (and (setq ps-buffer (get-buffer ps-spool-buffer-name))
5255 (buffer-modified-p ps-buffer)
5256 (y-or-n-p "Unprinted PostScript waiting; print now? ")
5257 (ps-despool))
5258 (and (setq ps-buffer (get-buffer ps-spool-buffer-name))
5259 (buffer-modified-p ps-buffer)
5260 (not (yes-or-no-p "Unprinted PostScript waiting; exit anyway? "))
5261 (error "Unprinted PostScript"))))
12d89a2e 5262
d3ab8dac
KH
5263(cond ((fboundp 'add-hook)
5264 (funcall 'add-hook 'kill-emacs-hook 'ps-kill-emacs-check))
5265 (kill-emacs-hook
5266 (message "Won't override existing `kill-emacs-hook'"))
5267 (t
5268 (setq kill-emacs-hook 'ps-kill-emacs-check)))
ef2cbb24 5269
298bfad9
KH
5270\f
5271;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e 5272;;; Sample Setup Code:
ef2cbb24 5273
12d89a2e 5274;; This stuff is for anybody that's brave enough to look this far,
87a16a06
RS
5275;; and able to figure out how to use it. It isn't really part of
5276;; ps-print, but I'll leave it here in hopes it might be useful:
ef2cbb24 5277
298bfad9
KH
5278;; WARNING!!! The following code is *sample* code only.
5279;; Don't use it unless you understand what it does!
043620f4 5280
87a16a06
RS
5281(defmacro ps-prsc ()
5282 `(if (eq ps-print-emacs-type 'emacs) [f22] 'f22))
5283(defmacro ps-c-prsc ()
5284 `(if (eq ps-print-emacs-type 'emacs) [C-f22] '(control f22)))
5285(defmacro ps-s-prsc ()
5286 `(if (eq ps-print-emacs-type 'emacs) [S-f22] '(shift f22)))
00aa16af 5287
a18ed129
RS
5288;; A hook to bind to `rmail-mode-hook' to locally bind prsc and set the
5289;; `ps-left-headers' specially for mail messages.
5290(defun ps-rmail-mode-hook ()
5291 (local-set-key (ps-prsc) 'ps-rmail-print-message-from-summary)
5292 (setq ps-header-lines 3
5293 ps-left-header
5294 ;; The left headers will display the message's subject, its
5295 ;; author, and the name of the folder it was in.
5296 '(ps-article-subject ps-article-author buffer-name)))
5297
5298;; See `ps-gnus-print-article-from-summary'. This function does the
5299;; same thing for rmail.
5300(defun ps-rmail-print-message-from-summary ()
5301 (interactive)
5302 (ps-print-message-from-summary 'rmail-summary-buffer "RMAIL"))
5303
5304;; Used in `ps-rmail-print-article-from-summary',
5305;; `ps-gnus-print-article-from-summary' and `ps-vm-print-message-from-summary'.
5306(defun ps-print-message-from-summary (summary-buffer summary-default)
5307 (let ((ps-buf (or (and (boundp summary-buffer)
5308 (symbol-value summary-buffer))
5309 summary-default)))
5310 (and (get-buffer ps-buf)
5311 (save-excursion
5312 (set-buffer ps-buf)
5313 (ps-spool-buffer-with-faces)))))
5314
12d89a2e 5315;; Look in an article or mail message for the Subject: line. To be
87a16a06 5316;; placed in `ps-left-headers'.
12d89a2e 5317(defun ps-article-subject ()
ef2cbb24 5318 (save-excursion
12d89a2e 5319 (goto-char (point-min))
45a870d9 5320 (if (re-search-forward "^Subject:[ \t]+\\(.*\\)$" nil t)
055e7bf2 5321 (buffer-substring-no-properties (match-beginning 1) (match-end 1))
12d89a2e
RS
5322 "Subject ???")))
5323
5324;; Look in an article or mail message for the From: line. Sorta-kinda
5325;; understands RFC-822 addresses and can pull the real name out where
87a16a06 5326;; it's provided. To be placed in `ps-left-headers'.
12d89a2e
RS
5327(defun ps-article-author ()
5328 (save-excursion
5329 (goto-char (point-min))
a97592dd 5330 (if (re-search-forward "^From:[ \t]+\\(.*\\)$" nil t)
87a16a06
RS
5331 (let ((fromstring (buffer-substring-no-properties (match-beginning 1)
5332 (match-end 1))))
12d89a2e
RS
5333 (cond
5334
5335 ;; Try first to match addresses that look like
5336 ;; thompson@wg2.waii.com (Jim Thompson)
5337 ((string-match ".*[ \t]+(\\(.*\\))" fromstring)
5338 (substring fromstring (match-beginning 1) (match-end 1)))
5339
5340 ;; Next try to match addresses that look like
5341 ;; Jim Thompson <thompson@wg2.waii.com>
5342 ((string-match "\\(.*\\)[ \t]+<.*>" fromstring)
5343 (substring fromstring (match-beginning 1) (match-end 1)))
5344
5345 ;; Couldn't find a real name -- show the address instead.
5346 (t fromstring)))
5347 "From ???")))
5348
a18ed129 5349;; A hook to bind to `gnus-article-prepare-hook'. This will set the
87a16a06
RS
5350;; `ps-left-headers' specially for gnus articles. Unfortunately,
5351;; `gnus-article-mode-hook' is called only once, the first time the *Article*
12d89a2e
RS
5352;; buffer enters that mode, so it would only work for the first time
5353;; we ran gnus. The second time, this hook wouldn't get set up. The
87a16a06 5354;; only alternative is `gnus-article-prepare-hook'.
12d89a2e 5355(defun ps-gnus-article-prepare-hook ()
8bd22fcf
KH
5356 (setq ps-header-lines 3
5357 ps-left-header
12d89a2e
RS
5358 ;; The left headers will display the article's subject, its
5359 ;; author, and the newsgroup it was in.
8bd22fcf 5360 '(ps-article-subject ps-article-author gnus-newsgroup-name)))
12d89a2e 5361
a18ed129
RS
5362;; A hook to bind to `vm-mode-hook' to locally bind prsc and set the
5363;; `ps-left-headers' specially for mail messages.
12d89a2e 5364(defun ps-vm-mode-hook ()
00aa16af 5365 (local-set-key (ps-prsc) 'ps-vm-print-message-from-summary)
8bd22fcf
KH
5366 (setq ps-header-lines 3
5367 ps-left-header
12d89a2e
RS
5368 ;; The left headers will display the message's subject, its
5369 ;; author, and the name of the folder it was in.
8bd22fcf 5370 '(ps-article-subject ps-article-author buffer-name)))
12d89a2e
RS
5371
5372;; Every now and then I forget to switch from the *Summary* buffer to
5373;; the *Article* before hitting prsc, and a nicely formatted list of
5374;; article subjects shows up at the printer. This function, bound to
5375;; prsc for the gnus *Summary* buffer means I don't have to switch
5376;; buffers first.
87a16a06 5377;; sb: Updated for Gnus 5.
12d89a2e
RS
5378(defun ps-gnus-print-article-from-summary ()
5379 (interactive)
a18ed129 5380 (ps-print-message-from-summary 'gnus-article-buffer "*Article*"))
ef2cbb24 5381
87a16a06 5382;; See `ps-gnus-print-article-from-summary'. This function does the
12d89a2e
RS
5383;; same thing for vm.
5384(defun ps-vm-print-message-from-summary ()
5385 (interactive)
a18ed129 5386 (ps-print-message-from-summary 'vm-mail-buffer ""))
ef2cbb24 5387
87a16a06 5388;; A hook to bind to bind to `gnus-summary-setup-buffer' to locally bind
12d89a2e
RS
5389;; prsc.
5390(defun ps-gnus-summary-setup ()
00aa16af 5391 (local-set-key (ps-prsc) 'ps-gnus-print-article-from-summary))
12d89a2e
RS
5392
5393;; Look in an article or mail message for the Subject: line. To be
87a16a06 5394;; placed in `ps-left-headers'.
12d89a2e
RS
5395(defun ps-info-file ()
5396 (save-excursion
5397 (goto-char (point-min))
a97592dd 5398 (if (re-search-forward "File:[ \t]+\\([^, \t\n]*\\)" nil t)
055e7bf2 5399 (buffer-substring-no-properties (match-beginning 1) (match-end 1))
12d89a2e
RS
5400 "File ???")))
5401
5402;; Look in an article or mail message for the Subject: line. To be
87a16a06 5403;; placed in `ps-left-headers'.
12d89a2e
RS
5404(defun ps-info-node ()
5405 (save-excursion
5406 (goto-char (point-min))
a97592dd 5407 (if (re-search-forward "Node:[ \t]+\\([^,\t\n]*\\)" nil t)
055e7bf2 5408 (buffer-substring-no-properties (match-beginning 1) (match-end 1))
12d89a2e
RS
5409 "Node ???")))
5410
5411(defun ps-info-mode-hook ()
5412 (setq ps-left-header
5413 ;; The left headers will display the node name and file name.
8bd22fcf 5414 '(ps-info-node ps-info-file)))
12d89a2e 5415
043620f4
KH
5416;; WARNING! The following function is a *sample* only, and is *not*
5417;; meant to be used as a whole unless you understand what the effects
87a16a06
RS
5418;; will be! (In fact, this is a copy of Jim's setup for ps-print --
5419;; I'd be very surprised if it was useful to *anybody*, without
043620f4
KH
5420;; modification.)
5421
12d89a2e 5422(defun ps-jts-ps-setup ()
00aa16af
RS
5423 (global-set-key (ps-prsc) 'ps-spool-buffer-with-faces) ;f22 is prsc
5424 (global-set-key (ps-s-prsc) 'ps-spool-region-with-faces)
5425 (global-set-key (ps-c-prsc) 'ps-despool)
12d89a2e
RS
5426 (add-hook 'gnus-article-prepare-hook 'ps-gnus-article-prepare-hook)
5427 (add-hook 'gnus-summary-mode-hook 'ps-gnus-summary-setup)
5428 (add-hook 'vm-mode-hook 'ps-vm-mode-hook)
00aa16af 5429 (add-hook 'vm-mode-hooks 'ps-vm-mode-hook)
12d89a2e 5430 (add-hook 'Info-mode-hook 'ps-info-mode-hook)
8bd22fcf
KH
5431 (setq ps-spool-duplex t
5432 ps-print-color-p nil
5433 ps-lpr-command "lpr"
5434 ps-lpr-switches '("-Jjct,duplex_long"))
bcc0d457
RS
5435 'ps-jts-ps-setup)
5436
5437;; WARNING! The following function is a *sample* only, and is *not*
5438;; meant to be used as a whole unless it corresponds to your needs.
5439;; (In fact, this is a copy of Jack's setup for ps-print --
5440;; I would not be that surprised if it was useful to *anybody*,
5441;; without modification.)
5442
5443(defun ps-jack-setup ()
87a16a06 5444 (setq ps-print-color-p nil
bcc0d457 5445 ps-lpr-command "lpr"
8bd22fcf 5446 ps-lpr-switches nil
bcc0d457 5447
87a16a06
RS
5448 ps-paper-type 'a4
5449 ps-landscape-mode t
bcc0d457
RS
5450 ps-number-of-columns 2
5451
5452 ps-left-margin (/ (* 72 1.0) 2.54) ; 1.0 cm
5453 ps-right-margin (/ (* 72 1.0) 2.54) ; 1.0 cm
5454 ps-inter-column (/ (* 72 1.0) 2.54) ; 1.0 cm
5455 ps-bottom-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
5456 ps-top-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
5457 ps-header-offset (/ (* 72 1.0) 2.54) ; 1.0 cm
5458 ps-header-line-pad .15
5459 ps-print-header t
5460 ps-print-header-frame t
5461 ps-header-lines 2
5462 ps-show-n-of-n t
5463 ps-spool-duplex nil
5464
5465 ps-font-family 'Courier
5466 ps-font-size 5.5
5467 ps-header-font-family 'Helvetica
5468 ps-header-font-size 6
5469 ps-header-title-font-size 8)
5470 'ps-jack-setup)
12d89a2e 5471
298bfad9
KH
5472\f
5473;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5474;; To make this file smaller, some commands go in a separate file.
5475;; But autoload them here to make the separation invisible.
5476
5477(autoload 'ps-mule-prepare-ascii-font "ps-mule"
5478 "Setup special ASCII font for STRING.
5479STRING should contain only ASCII characters.")
5480
5481(autoload 'ps-mule-set-ascii-font "ps-mule"
5482 "Adjust current font if current charset is not ASCII.")
5483
5484(autoload 'ps-mule-plot-string "ps-mule"
5485 "Generate PostScript code for ploting characters in the region FROM and TO.
5486
5487It is assumed that all characters in this region belong to the same charset.
5488
5489Optional argument BG-COLOR specifies background color.
5490
5491Returns the value:
5492
5493 (ENDPOS . RUN-WIDTH)
5494
5495Where ENDPOS is the end position of the sequence and RUN-WIDTH is the width of
5496the sequence.")
5497
5498(autoload 'ps-mule-initialize "ps-mule"
5499 "Initialize global data for printing multi-byte characters.")
5500
5501(autoload 'ps-mule-begin-job "ps-mule"
5502 "Start printing job for multi-byte chars between FROM and TO.
5503This checks if all multi-byte characters in the region are printable or not.")
5504
5505(autoload 'ps-mule-begin-page "ps-mule"
5506 "Initialize multi-byte charset for printing current page.")
5507
5508\f
5509;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5510
12d89a2e 5511(provide 'ps-print)
b87c5d3d 5512
12d89a2e 5513;;; ps-print.el ends here