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