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