(cal-tex-which-days, cal-tex-holidays)
[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,
d7a0267c 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>
07239461
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
3f0257cb 13;; Version: 6.7.5
502ca00a 14;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
e65df0a1 15
3f0257cb
VJL
16(defconst ps-print-version "6.7.5"
17 "ps-print.el, v 6.7.5 <2007/07/20 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
30;; Software Foundation; either version 2, or (at your option) any later
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
RS
1091;;
1092;;
87a16a06
RS
1093;; How Ps-Print Maps Faces
1094;; -----------------------
1095;;
319acba0
GM
1096;; As ps-print uses PostScript to print buffers, it is possible to have other
1097;; attributes associated with faces. So the new attributes used by ps-print
1098;; are:
87a16a06
RS
1099;;
1100;; strikeout - like underline, but the line is in middle of text.
1101;; overline - like underline, but the line is over the text.
1102;; shadow - text will have a shadow.
1103;; box - text will be surrounded by a box.
a18ed129 1104;; outline - print characters as hollow outlines.
87a16a06 1105;;
06fb6aab 1106;; See the documentation for `ps-extend-face'.
87a16a06 1107;;
bc0d41bd
KH
1108;; Let's, for example, remap `font-lock-keyword-face' to another foreground
1109;; color and bold attribute:
87a16a06 1110;;
a18ed129 1111;; (ps-extend-face '(font-lock-keyword-face "RoyalBlue" nil bold) 'MERGE)
87a16a06 1112;;
319acba0
GM
1113;; If you want to use a new face, define it first with `defface', and then call
1114;; `ps-extend-face' to specify how to print it.
6c8f2753 1115;;
87a16a06
RS
1116;;
1117;; How Ps-Print Has A Text And/Or Image On Background
1118;; --------------------------------------------------
1119;;
d3ab8dac 1120;; ps-print can print texts and/or EPS PostScript images on background; it is
87a16a06
RS
1121;; possible to define the following text attributes: font name, font size,
1122;; initial position, angle, gray scale and pages to print.
1123;;
1124;; It has the following EPS PostScript images attributes: file name containing
1125;; the image, initial position, X and Y scales, angle and pages to print.
1126;;
1127;; See documentation for `ps-print-background-text' and
1128;; `ps-print-background-image'.
1129;;
1130;; For example, if we wish to print text "preliminary" on all pages and text
1131;; "special" on page 5 and from page 11 to page 17, we could specify:
1132;;
1133;; (setq ps-print-background-text
1134;; '(("preliminary")
1135;; ("special"
1136;; "LeftMargin" "BottomMargin PrintHeight add" ; X and Y position
1137;; ; (upper left corner)
1138;; nil nil nil
12b88fff 1139;; "PrintHeight neg PrintPageWidth atan" ; angle
87a16a06
RS
1140;; 5 (11 . 17)) ; page list
1141;; ))
1142;;
1143;; Similarly, we could print image "~/images/EPS-image1.ps" on all pages and
1144;; image "~/images/EPS-image2.ps" on page 5 and from page 11 to page 17, we
1145;; specify:
1146;;
1147;; (setq ps-print-background-image
1148;; '(("~/images/EPS-image1.ps"
1149;; "LeftMargin" "BottomMargin") ; X and Y position (lower left corner)
1150;; ("~/images/EPS-image2.ps"
319acba0 1151;; "LeftMargin" "BottomMargin PrintHeight 2 div add" ; X and Y pos.
87a16a06
RS
1152;; ; (upper left corner)
1153;; nil nil nil
1154;; 5 (11 . 17)) ; page list
1155;; ))
1156;;
1157;; If it is not possible to read (or does not exist) an image file, that file
1158;; is ignored.
1159;;
1160;; The printing order is:
1161;;
6e1b1da6
GM
1162;; 1. Print background color
1163;; 2. Print zebra stripes
1164;; 3. Print background texts that it should be on all pages
1165;; 4. Print background images that it should be on all pages
1166;; 5. Print background texts only for current page (if any)
1167;; 6. Print background images only for current page (if any)
1168;; 7. Print header
1169;; 8. Print buffer text (with faces, if specified) and line number
87a16a06
RS
1170;;
1171;;
bcc0d457
RS
1172;; Utilities
1173;; ---------
1174;;
1175;; Some tools are provided to help you customize your font setup.
1176;;
1177;; `ps-setup' returns (some part of) the current setup.
1178;;
319acba0
GM
1179;; To avoid wrapping too many lines, you may want to adjust the left and right
1180;; margins and the font size. On UN*X systems, do:
bcc0d457
RS
1181;; pr -t file | awk '{printf "%3d %s\n", length($0), $0}' | sort -r | head
1182;; to determine the longest lines of your file.
319acba0
GM
1183;; Then, the command `ps-line-lengths' will give you the correspondence between
1184;; a line length (number of characters) and the maximum font size which doesn't
1185;; wrap such a line with the current ps-print setup.
bcc0d457 1186;;
319acba0
GM
1187;; The commands `ps-nb-pages-buffer' and `ps-nb-pages-region' display the
1188;; correspondence between a number of pages and the maximum font size which
1189;; allow the number of lines of the current buffer or of its current region to
1190;; fit in this number of pages.
a18ed129
RS
1191;;
1192;; NOTE: line folding is not taken into account in this process and could
1193;; change the results.
b87c5d3d 1194;;
0a5daee5
KH
1195;; The command `ps-print-customize' activates a customization buffer for
1196;; ps-print options.
1197;;
b87c5d3d 1198;;
b87c5d3d
RS
1199;; New since version 1.5
1200;; ---------------------
b87c5d3d 1201;;
bcc0d457 1202;; Color output capability.
b87c5d3d 1203;; Automatic detection of font attributes (bold, italic).
b87c5d3d 1204;; Configurable headers with page numbers.
b87c5d3d 1205;; Slightly faster.
b87c5d3d 1206;; Support for different paper sizes.
b87c5d3d
RS
1207;; Better conformance to PostScript Document Structure Conventions.
1208;;
ef2cbb24 1209;;
bcc0d457
RS
1210;; New since version 2.8
1211;; ---------------------
1212;;
e59d29d6 1213;; [vinicius] Vinicius Jose Latorre <viniciusjl@ig.com.br>
0a5daee5 1214;;
71efd3c4
VJL
1215;; 20040229
1216;; `ps-time-stamp-yyyy-mm-dd', `ps-time-stamp-iso8601'
1217;;
4b81a999
GM
1218;; 20010619
1219;; `ps-time-stamp-locale-default'
1220;;
1221;; 20010530
1222;; Handle before-string and after-string overlay properties.
1223;;
319acba0
GM
1224;; 20010407
1225;; `ps-line-number-color', `ps-print-footer', `ps-footer-offset',
1226;; `ps-print-footer-frame', `ps-footer-font-family',
1227;; `ps-footer-font-size', `ps-footer-line-pad', `ps-footer-lines',
1228;; `ps-left-footer', `ps-right-footer', `ps-footer-frame-alist' and
1229;; `ps-header-frame-alist'.
1230;;
1231;; 20010328
1232;; `ps-line-spacing', `ps-paragraph-spacing', `ps-paragraph-regexp',
1233;; `ps-begin-cut-regexp' and `ps-end-cut-regexp'.
1234;;
ef1159c2
EZ
1235;; 20001122
1236;; `ps-line-number-font', `ps-line-number-font-size' and
1237;; `ps-end-with-control-d'.
1238;;
c3d6d211
GM
1239;; 20000821
1240;; `ps-even-or-odd-pages'
1241;;
1fd9b7fe
GM
1242;; 20000617
1243;; `ps-manual-feed', `ps-warn-paper-type', `ps-print-upside-down',
1244;; `ps-selected-pages', `ps-last-selected-pages',
1245;; `ps-restore-selected-pages', `ps-switch-header',
1246;; `ps-line-number-step', `ps-line-number-start',
1247;; `ps-zebra-stripe-follow' and `ps-use-face-background'.
0a5daee5 1248;;
1fd9b7fe
GM
1249;; 20000310
1250;; PostScript error handler.
1251;; `ps-user-defined-prologue' and `ps-error-handler-message'.
bc0d41bd 1252;;
df5e6194 1253;; 19991211
1fd9b7fe 1254;; `ps-print-customize'.
bc0d41bd 1255;;
df5e6194 1256;; 19990703
1fd9b7fe
GM
1257;; Better customization.
1258;; `ps-banner-page-when-duplexing' and `ps-zebra-color'.
bc0d41bd 1259;;
df5e6194 1260;; 19990513
1fd9b7fe
GM
1261;; N-up printing.
1262;; Hook: `ps-print-begin-sheet-hook'.
bc0d41bd 1263;;
edf2174f 1264;; [kenichi] 19990509 Ken'ichi Handa <handa@m17n.org>
bc0d41bd 1265;;
71efd3c4 1266;; `ps-print-region-function'
bc0d41bd 1267;;
e59d29d6 1268;; [vinicius] Vinicius Jose Latorre <viniciusjl@ig.com.br>
bc0d41bd 1269;;
df5e6194 1270;; 19990301
1fd9b7fe 1271;; PostScript tumble and setpagedevice.
bc0d41bd 1272;;
df5e6194 1273;; 19980922
1fd9b7fe
GM
1274;; PostScript prologue header comment insertion.
1275;; Skip invisible text better.
d3ab8dac 1276;;
edf2174f 1277;; [kenichi] 19980819 Ken'ichi Handa <handa@m17n.org>
e65df0a1 1278;;
71efd3c4 1279;; Multi-byte buffer handling.
e65df0a1 1280;;
e59d29d6 1281;; [vinicius] Vinicius Jose Latorre <viniciusjl@ig.com.br>
12b88fff 1282;;
df5e6194 1283;; 19980306
1fd9b7fe 1284;; Skip invisible text.
12b88fff 1285;;
df5e6194 1286;; 19971130
1fd9b7fe
GM
1287;; Hooks: `ps-print-hook', `ps-print-begin-page-hook' and
1288;; `ps-print-begin-column-hook'.
1289;; Put one header per page over the columns.
1290;; Better database font management.
1291;; Better control characters handling.
12b88fff 1292;;
df5e6194 1293;; 19971121
1fd9b7fe
GM
1294;; Dynamic evaluation at print time of `ps-lpr-switches'.
1295;; Handle control characters.
1296;; Face remapping.
1297;; New face attributes.
1298;; Line number.
1299;; Zebra stripes.
1300;; Text and/or image on background.
87a16a06 1301;;
df5e6194 1302;; [jack] 19960517 Jacques Duthen <duthen@cegelec-red.fr>
bcc0d457 1303;;
a18ed129 1304;; Font family and float size for text and header.
bcc0d457
RS
1305;; Landscape mode.
1306;; Multiple columns.
1307;; Tools for page setup.
1308;;
1309;;
d3ab8dac 1310;; Known bugs and limitations of ps-print
ef2cbb24 1311;; --------------------------------------
bcc0d457 1312;;
319acba0
GM
1313;; Although color printing will work in XEmacs 19.12, it doesn't work well; in
1314;; particular, bold or italic fonts don't print in the right background color.
043620f4
KH
1315;;
1316;; Invisible properties aren't correctly ignored in XEmacs 19.12.
1317;;
319acba0
GM
1318;; Automatic font-attribute detection doesn't work well, especially with
1319;; hilit19 and older versions of get-create-face. Users having problems with
1320;; auto-font detection should use the lists `ps-italic-faces', `ps-bold-faces'
1321;; and `ps-underlined-faces' and/or turn off automatic detection by setting
1322;; `ps-auto-font-detect' to nil.
00aa16af 1323;;
319acba0
GM
1324;; Automatic font-attribute detection doesn't work with XEmacs 19.12 in tty
1325;; mode; use the lists `ps-italic-faces', `ps-bold-faces' and
857686a6 1326;; `ps-underlined-faces' instead.
12d89a2e 1327;;
00aa16af 1328;; Still too slow; could use some hand-optimization.
ef2cbb24 1329;;
12d89a2e 1330;; Default background color isn't working.
ef2cbb24
RS
1331;;
1332;; Faces are always treated as opaque.
1333;;
4abc74e8 1334;; Epoch, Lucid and Emacs 21 not supported. At all.
ef2cbb24 1335;;
06fb6aab 1336;; Fixed-pitch fonts work better for line folding, but are not required.
bcc0d457 1337;;
319acba0
GM
1338;; `ps-nb-pages-buffer' and `ps-nb-pages-region' don't take care of folding
1339;; lines.
ef2cbb24 1340;;
12d89a2e 1341;;
d3ab8dac 1342;; Things to change
bcc0d457 1343;; ----------------
ef2cbb24 1344;;
12b88fff 1345;; Avoid page break inside a paragraph.
bcc0d457 1346;; Add `ps-non-bold-faces' and `ps-non-italic-faces' (should be easy).
bcc0d457 1347;; Improve the memory management for big files (hard?).
319acba0
GM
1348;; `ps-nb-pages-buffer' and `ps-nb-pages-region' should take care of folding
1349;; lines.
ef2cbb24 1350;;
ef2cbb24 1351;;
6bf5fb46
GM
1352;; Acknowledgments
1353;; ---------------
1354;;
9586e1d3
VJL
1355;; Thanks to Michael Piotrowski <mxp@dynalabs.de> for improving the DSC
1356;; compliance of the generated PostScript.
1357;;
55732434
GM
1358;; Thanks to Adam Doppelt <adoppelt@avogadro.com> for face mapping suggestion
1359;; for black/white PostScript printers.
1360;;
319acba0
GM
1361;; Thanks to Toni Ronkko <tronkko@hytti.uku.fi> for line and paragraph spacing,
1362;; region to cut out when printing and footer suggestions.
1363;;
6bf5fb46 1364;; Thanks to Pavel Janik ml <Pavel@Janik.cz> for documentation correction.
12b88fff 1365;;
ef1159c2
EZ
1366;; Thanks to Corinne Ilvedson <cilvedson@draper.com> for line number font size
1367;; suggestion.
1368;;
c3d6d211
GM
1369;; Thanks to Gord Wait <Gord_Wait@spectrumsignal.com> for
1370;; `ps-user-defined-prologue' example setting for HP PostScript printer.
1371;;
98f2fbe7
GM
1372;; Thanks to Paul Furnanz <pfurnanz@synopsys.com> for XEmacs compatibility
1373;; suggestion for `ps-postscript-code-directory' variable.
1374;;
906d41a7
GM
1375;; Thanks to David X Callaway <dxc@xprt.net> for helping debugging PostScript
1376;; level 1 compatibility.
1377;;
71efd3c4
VJL
1378;; Thanks to Colin Marquardt <colin.marquardt@usa.alcatel.com> for:
1379;; - upside-down, line number step, line number start and zebra stripe
1380;; follow suggestions.
1381;; - `ps-time-stamp-yyyy-mm-dd' and `ps-time-stamp-iso8601' suggestion.
1382;; - and for XEmacs beta-tests.
906d41a7 1383;;
66e63857 1384;; Thanks to Klaus Berndl <klaus.berndl@sdm.de> for user defined PostScript
2bd80d73
GM
1385;; prologue code suggestion, for odd/even printing suggestion and for
1386;; `ps-prologue-file' enhancement.
66e63857 1387;;
edf2174f 1388;; Thanks to Ken'ichi Handa <handa@m17n.org> for multi-byte buffer handling.
915293a2
KH
1389;;
1390;; Thanks to Matthew O Persico <Matthew.Persico@lazard.com> for line number on
1391;; empty columns.
1392;;
1393;; Thanks to Theodore Jump <tjump@cais.com> for adjust PostScript code order on
1394;; last page.
1395;;
6bdb808e
RS
1396;; Thanks to Roland Ducournau <ducour@lirmm.fr> for
1397;; `ps-print-control-characters' variable documentation.
1398;;
12b88fff
RS
1399;; Thanks to Marcus G Daniels <marcus@cathcart.sysc.pdx.edu> for a better
1400;; database font management.
1401;;
1402;; Thanks to Martin Boyer <gamin@videotron.ca> for some ideas on putting one
6bdb808e
RS
1403;; header per page over the columns and correct line numbers when printing a
1404;; region.
12b88fff
RS
1405;;
1406;; Thanks to Steven L Baur <steve@miranova.com> for dynamic evaluation at
1407;; print time of `ps-lpr-switches'.
1408;;
6bdb808e
RS
1409;; Thanks to Kevin Rodgers <kevinr@ihs.com> for handling control characters
1410;; (his code was severely modified, but the main idea was kept).
1411;;
12b88fff
RS
1412;; Thanks to some suggestions on:
1413;; * Face color map: Marco Melgazzi <marco@techie.com>
1414;; * XEmacs compatibility: William J. Henney <will@astrosmo.unam.mx>
984e7bd9 1415;; * Check `ps-paper-type': Sudhakar Frederick <sfrederi@asc.corp.mot.com>
12b88fff 1416;;
319acba0
GM
1417;; Thanks to Jacques Duthen <duthen@cegelec-red.fr> (Jack) for version 3.4 I
1418;; started from. [vinicius]
857686a6 1419;;
319acba0 1420;; Thanks to Jim Thompson <?@?> for the 2.8 version I started from. [jack]
bcc0d457 1421;;
319acba0
GM
1422;; Thanks to Kevin Rodgers <kevinr@ihs.com> for adding support for color and
1423;; the invisible property.
ef2cbb24 1424;;
319acba0
GM
1425;; Thanks to Avishai Yacobi, avishaiy@mcil.comm.mot.com, for writing the
1426;; initial port to Emacs 19. His code is no longer part of ps-print, but his
1427;; work is still appreciated.
ef2cbb24 1428;;
9586e1d3 1429;; Thanks to Remi Houdaille and Michel Train <michel@metasoft.fdn.org> for
319acba0
GM
1430;; adding underline support. Their code also is no longer part of ps-print,
1431;; but their efforts are not forgotten.
12d89a2e 1432;;
319acba0
GM
1433;; Thanks also to all of you who mailed code to add features to ps-print;
1434;; although I didn't use your code, I still appreciate your sharing it with me.
12d89a2e
RS
1435;;
1436;; Thanks to all who mailed comments, encouragement, and criticism.
319acba0
GM
1437;; Thanks also to all who responded to my survey; I had too many responses to
1438;; reply to them all, but I greatly appreciate your interest.
12d89a2e
RS
1439;;
1440;; Jim
bc0d41bd 1441;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ef2cbb24
RS
1442
1443;;; Code:
1444
55732434 1445
b6d0ac87 1446(require 'lpr)
68e684a0 1447
b6d0ac87
VJL
1448(or (featurep 'lisp-float-type)
1449 (error "`ps-print' requires floating point support"))
68e684a0 1450
cf04718a
SM
1451(let ((case-fold-search t))
1452 (cond ((string-match "XEmacs" emacs-version))
d3241651
VJL
1453 ((string-match "Lucid" emacs-version)
1454 (error "`ps-print' doesn't support Lucid"))
1455 ((string-match "Epoch" emacs-version)
1456 (error "`ps-print' doesn't support Epoch"))
1457 (t
1458 (unless (and (boundp 'emacs-major-version)
1459 (>= emacs-major-version 22))
1460 (error "`ps-print' only supports Emacs 22 and higher")))))
eafa92bf 1461
68e684a0 1462
b6d0ac87
VJL
1463;; GNU Emacs
1464(or (fboundp 'line-beginning-position)
1465 (defun line-beginning-position (&optional n)
1466 (save-excursion
1467 (and n (/= n 1) (forward-line (1- n)))
1468 (beginning-of-line)
1469 (point))))
1470
1471
1472;; to avoid compilation gripes
1473
1474;; XEmacs
1475(defalias 'ps-x-color-instance-p 'color-instance-p)
1476(defalias 'ps-x-color-instance-rgb-components 'color-instance-rgb-components)
1477(defalias 'ps-x-color-name 'color-name)
1478(defalias 'ps-x-color-specifier-p 'color-specifier-p)
1479(defalias 'ps-x-copy-coding-system 'copy-coding-system)
1480(defalias 'ps-x-device-class 'device-class)
1481(defalias 'ps-x-extent-end-position 'extent-end-position)
1482(defalias 'ps-x-extent-face 'extent-face)
1483(defalias 'ps-x-extent-priority 'extent-priority)
1484(defalias 'ps-x-extent-start-position 'extent-start-position)
1485(defalias 'ps-x-face-font-instance 'face-font-instance)
1486(defalias 'ps-x-find-coding-system 'find-coding-system)
1487(defalias 'ps-x-font-instance-properties 'font-instance-properties)
1488(defalias 'ps-x-make-color-instance 'make-color-instance)
1489(defalias 'ps-x-map-extents 'map-extents)
1490
1491;; GNU Emacs
1492(defalias 'ps-e-face-bold-p 'face-bold-p)
1493(defalias 'ps-e-face-italic-p 'face-italic-p)
1494(defalias 'ps-e-next-overlay-change 'next-overlay-change)
1495(defalias 'ps-e-overlays-at 'overlays-at)
1496(defalias 'ps-e-overlay-get 'overlay-get)
1497(defalias 'ps-e-overlay-end 'overlay-end)
1498(defalias 'ps-e-x-color-values 'x-color-values)
1499(defalias 'ps-e-color-values 'color-values)
cf04718a 1500(defalias 'ps-e-find-composition (if (fboundp 'find-composition)
d3241651
VJL
1501 'find-composition
1502 'ignore))
b6d0ac87
VJL
1503
1504
1505(defconst ps-windows-system
1506 (memq system-type '(emx win32 w32 mswindows ms-dos windows-nt)))
1507(defconst ps-lp-system
1508 (memq system-type '(usg-unix-v dgux hpux irix)))
1509
1510
1511(defun ps-xemacs-color-name (color)
1512 (if (ps-x-color-specifier-p color)
1513 (ps-x-color-name color)
1514 color))
1515
cf04718a
SM
1516(defalias 'ps-frame-parameter
1517 (if (fboundp 'frame-parameter) 'frame-parameter 'frame-property))
d3241651 1518
cf04718a
SM
1519(defalias 'ps-mark-active-p
1520 (if (fboundp 'region-active-p)
d3241651
VJL
1521 'region-active-p ; XEmacs
1522 (defvar mark-active) ; To shup up XEmacs's byte compiler.
1523 (lambda () mark-active))) ; Emacs
b6d0ac87 1524
cf04718a 1525(cond ((featurep 'xemacs) ; XEmacs
b6d0ac87
VJL
1526 (defun ps-face-foreground-name (face)
1527 (ps-xemacs-color-name (face-foreground face)))
1528 (defun ps-face-background-name (face)
1529 (ps-xemacs-color-name (face-background face)))
1530 )
cf04718a 1531 (t ; Emacs 22 or higher
8906db27
JL
1532 (defun ps-face-foreground-name (face)
1533 (face-foreground face nil t))
1534 (defun ps-face-background-name (face)
c1a1c994 1535 (face-background face nil t))
c1a1c994 1536 ))
906d41a7
GM
1537
1538
ef2cbb24 1539;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e
RS
1540;; User Variables:
1541
0a5daee5 1542
bcc0d457
RS
1543;;; Interface to the command system
1544
bc0d41bd 1545(defgroup postscript nil
b0fa9df7 1546 "PostScript Group."
bc0d41bd 1547 :tag "PostScript"
b6d0ac87 1548 :version "20"
bc0d41bd
KH
1549 :group 'emacs)
1550
e0af0d3e 1551(defgroup ps-print nil
b0fa9df7 1552 "PostScript generator for Emacs."
3556c6dd 1553 :link '(emacs-library-link :tag "Source Lisp File" "ps-print.el")
e0af0d3e 1554 :prefix "ps-"
b6d0ac87 1555 :version "20"
bc0d41bd
KH
1556 :group 'wp
1557 :group 'postscript)
e0af0d3e
RS
1558
1559(defgroup ps-print-horizontal nil
b0fa9df7 1560 "Horizontal page layout."
e0af0d3e
RS
1561 :prefix "ps-"
1562 :tag "Horizontal"
b6d0ac87 1563 :version "20"
e0af0d3e
RS
1564 :group 'ps-print)
1565
1566(defgroup ps-print-vertical nil
b0fa9df7 1567 "Vertical page layout."
e0af0d3e
RS
1568 :prefix "ps-"
1569 :tag "Vertical"
b6d0ac87 1570 :version "20"
e0af0d3e
RS
1571 :group 'ps-print)
1572
6e1b1da6 1573(defgroup ps-print-headers nil
b0fa9df7 1574 "Headers & footers layout."
e0af0d3e 1575 :prefix "ps-"
319acba0 1576 :tag "Header & Footer"
b6d0ac87 1577 :version "20"
e0af0d3e
RS
1578 :group 'ps-print)
1579
1580(defgroup ps-print-font nil
b0fa9df7 1581 "Fonts customization."
e0af0d3e
RS
1582 :prefix "ps-"
1583 :tag "Font"
b6d0ac87 1584 :version "20"
e0af0d3e
RS
1585 :group 'ps-print)
1586
1587(defgroup ps-print-color nil
b0fa9df7 1588 "Color customization."
e0af0d3e
RS
1589 :prefix "ps-"
1590 :tag "Color"
b6d0ac87 1591 :version "20"
e0af0d3e
RS
1592 :group 'ps-print)
1593
1594(defgroup ps-print-face nil
b0fa9df7 1595 "Faces customization."
e0af0d3e
RS
1596 :prefix "ps-"
1597 :tag "PS Faces"
b6d0ac87 1598 :version "20"
e0af0d3e
RS
1599 :group 'ps-print
1600 :group 'faces)
1601
bc0d41bd 1602(defgroup ps-print-n-up nil
b0fa9df7 1603 "N-up customization."
bc0d41bd
KH
1604 :prefix "ps-"
1605 :tag "N-Up"
b6d0ac87 1606 :version "20"
bc0d41bd
KH
1607 :group 'ps-print)
1608
1609(defgroup ps-print-zebra nil
b0fa9df7 1610 "Zebra customization."
bc0d41bd
KH
1611 :prefix "ps-"
1612 :tag "Zebra"
b6d0ac87 1613 :version "20"
bc0d41bd
KH
1614 :group 'ps-print)
1615
1616(defgroup ps-print-background nil
b0fa9df7 1617 "Background customization."
bc0d41bd
KH
1618 :prefix "ps-"
1619 :tag "Background"
b6d0ac87 1620 :version "20"
bc0d41bd
KH
1621 :group 'ps-print)
1622
1426742b 1623(defgroup ps-print-printer '((lpr custom-group))
b0fa9df7 1624 "Printer customization."
bc0d41bd
KH
1625 :prefix "ps-"
1626 :tag "Printer"
b6d0ac87 1627 :version "20"
bc0d41bd
KH
1628 :group 'ps-print)
1629
1630(defgroup ps-print-page nil
b0fa9df7 1631 "Page customization."
bc0d41bd
KH
1632 :prefix "ps-"
1633 :tag "Page"
b6d0ac87 1634 :version "20"
bc0d41bd
KH
1635 :group 'ps-print)
1636
6e1b1da6 1637(defgroup ps-print-miscellany nil
b0fa9df7 1638 "Miscellany customization."
6e1b1da6
GM
1639 :prefix "ps-"
1640 :tag "Miscellany"
b6d0ac87 1641 :version "20"
6e1b1da6
GM
1642 :group 'ps-print)
1643
bc0d41bd 1644
66e63857
GM
1645(defcustom ps-error-handler-message 'paper
1646 "*Specify where the error handler message should be sent.
1647
1648Valid values are:
1649
1650 `none' catch the error and *DON'T* send any message.
1651
1652 `paper' catch the error and print on paper the error message.
1653
1654 `system' catch the error and send back the error message to
6e1b1da6
GM
1655 printing system. This is useful only if printing system
1656 send back an email reporting the error, or if there is
1657 some other alternative way to report back the error from
1658 the system to you.
66e63857
GM
1659
1660 `paper-and-system' catch the error, print on paper the error message and
1661 send back the error message to printing system.
1662
1663Any other value is treated as `paper'."
8e234846
GM
1664 :type '(choice :menu-tag "Error Handler Message"
1665 :tag "Error Handler Message"
66e63857
GM
1666 (const none) (const paper)
1667 (const system) (const paper-and-system))
b6d0ac87 1668 :version "20"
6e1b1da6 1669 :group 'ps-print-miscellany)
66e63857
GM
1670
1671(defcustom ps-user-defined-prologue nil
1672 "*User defined PostScript prologue code inserted before all prologue code.
1673
1674`ps-user-defined-prologue' may be a string or a symbol function which returns a
1675string. Note that this string is inserted after `ps-adobe-tag' and PostScript
1676prologue comments, and before ps-print PostScript prologue code section. That
1677is, this string is inserted after error handler initialization and before
1678ps-print settings.
1679
66e63857
GM
1680It's strongly recommended only insert PostScript code and/or comments specific
1681for your printing system particularities. For example, some special
1682initialization that only your printing system needs.
1683
319acba0
GM
1684Do not insert code for duplex printing, n-up printing or error handler,
1685ps-print handles this in a suitable way.
66e63857
GM
1686
1687For more information about PostScript, see:
1688 PostScript Language Reference Manual (2nd edition)
c3d6d211
GM
1689 Adobe Systems Incorporated
1690
1691As an example for `ps-user-defined-prologue' setting:
1692
1693 ;; Setting for HP PostScript printer
1694 (setq ps-user-defined-prologue
1695 (concat \"<</DeferredMediaSelection true /PageSize [612 792] \"
2285bf9d 1696 \"/MediaPosition 2 /MediaType (Plain)>> setpagedevice\"))"
8e234846
GM
1697 :type '(choice :menu-tag "User Defined Prologue"
1698 :tag "User Defined Prologue"
98f2fbe7 1699 (const :tag "none" nil) string symbol)
b6d0ac87 1700 :version "20"
6e1b1da6 1701 :group 'ps-print-miscellany)
66e63857 1702
d3ab8dac
KH
1703(defcustom ps-print-prologue-header nil
1704 "*PostScript prologue header comments besides that ps-print generates.
1705
319acba0
GM
1706`ps-print-prologue-header' may be a string or a symbol function which returns a
1707string. Note that this string is inserted on PostScript prologue header
1708section which is used to define some document characteristic through PostScript
1709special comments, like \"%%Requirements: jog\\n\".
d3ab8dac
KH
1710
1711ps-print always inserts the %%Requirements: comment, so if you need to insert
1712more requirements put them first in `ps-print-prologue-header' using the
1713\"%%+\" comment. For example, if you need to set numcopies to 3 and jog on
1714requirements and set %%LanguageLevel: to 2, do:
1715
2285bf9d 1716 (setq ps-print-prologue-header
e59d29d6 1717 \"%%+ numcopies(3) jog\\n%%LanguageLevel: 2\\n\")
d3ab8dac
KH
1718
1719The duplex requirement is inserted by ps-print (see `ps-spool-duplex').
1720
1721Do not forget to terminate the string with \"\\n\".
1722
1723For more information about PostScript document comments, see:
1724 PostScript Language Reference Manual (2nd edition)
1725 Adobe Systems Incorporated
1726 Appendix G: Document Structuring Conventions -- Version 3.0"
8e234846
GM
1727 :type '(choice :menu-tag "Prologue Header"
1728 :tag "Prologue Header"
98f2fbe7 1729 (const :tag "none" nil) string symbol)
b6d0ac87 1730 :version "20"
6e1b1da6 1731 :group 'ps-print-miscellany)
d3ab8dac 1732
298bfad9 1733(defcustom ps-printer-name (and (boundp 'printer-name)
2bd80d73 1734 (symbol-value 'printer-name))
03820514
RS
1735 "*The name of a local printer for printing PostScript files.
1736
3556c6dd
GM
1737On Unix-like systems, a string value should be a name understood by lpr's -P
1738option; a value of nil means use the value of `printer-name' instead.
1739
1740On MS-DOS and MS-Windows systems, a string value is taken as the name of the
1741printer device or port to which PostScript files are written, provided
1742`ps-lpr-command' is \"\". By default it is the same as `printer-name'; typical
1743non-default settings would be \"LPT1\" to \"LPT3\" for parallel printers, or
7bb054a5 1744\"COM1\" to \"COM4\" or \"AUX\" for serial printers, or \"\\\\hostname\\printer\"
3556c6dd
GM
1745for a shared network printer. You can also set it to a name of a file, in
1746which case the output gets appended to that file. \(Note that `ps-print'
1747package already has facilities for printing to a file, so you might as well use
1748them instead of changing the setting of this variable.\) If you want to
1749silently discard the printed output, set this to \"NUL\".
1750
1751Set to t, if the utility given by `ps-lpr-command' needs an empty printer name.
1752
1753Any other value is treated as t, that is, an empty printer name.
1754
1755See also `ps-printer-name-option' for documentation."
8e234846
GM
1756 :type '(choice :menu-tag "Printer Name"
1757 :tag "Printer Name"
1758 (const :tag "Same as printer-name" nil)
3556c6dd 1759 (const :tag "No Printer Name" t)
6e1b1da6 1760 (file :tag "Print to file")
8e234846 1761 (string :tag "Pipe to ps-lpr-command"))
b6d0ac87 1762 :version "20"
bc0d41bd 1763 :group 'ps-print-printer)
03820514 1764
3556c6dd
GM
1765(defcustom ps-printer-name-option
1766 (cond (ps-windows-system
1767 "/D:")
1768 (ps-lp-system
1769 "-d")
1770 (t
1771 "-P" ))
1772 "*Option for `ps-printer-name' variable (see it).
1773
2285bf9d
RS
1774On Unix-like systems, if `lpr' is in use, this should be the string
1775\"-P\"; if `lp' is in use, this should be the string \"-d\".
3556c6dd 1776
2285bf9d 1777On MS-DOS and MS-Windows systems, if `print' is in use, this should be
3556c6dd
GM
1778the string \"/D:\".
1779
2285bf9d 1780For any other printing utility, see its documentation.
3556c6dd 1781
c90a10fa
RS
1782Set this to \"\" or nil, if the utility given by `ps-lpr-command'
1783needs an empty printer name option--that is, pass the printer name
1784with no special option preceding it.
3556c6dd 1785
c90a10fa 1786Any value that is not a string is treated as nil.
3556c6dd
GM
1787
1788This variable is used only when `ps-printer-name' is a non-empty string."
1789 :type '(choice :menu-tag "Printer Name Option"
1790 :tag "Printer Name Option"
1791 (const :tag "None" nil)
1792 (string :tag "Option"))
6bf5fb46 1793 :version "21.1"
3556c6dd
GM
1794 :group 'ps-print-printer)
1795
e0af0d3e 1796(defcustom ps-lpr-command lpr-command
52cf535f
AI
1797 "*Name of program for printing a PostScript file.
1798
3556c6dd
GM
1799On MS-DOS and MS-Windows systems, if the value is an empty string then Emacs
1800will write directly to the printer port named by `ps-printer-name'. The
1801programs `print' and `nprint' (the standard print programs on Windows NT and
1802Novell Netware respectively) are handled specially, using `ps-printer-name' as
1803the destination for output; any other program is treated like `lpr' except that
1804an explicit filename is given as the last argument."
e0af0d3e 1805 :type 'string
b6d0ac87 1806 :version "20"
bc0d41bd 1807 :group 'ps-print-printer)
e0af0d3e
RS
1808
1809(defcustom ps-lpr-switches lpr-switches
1810 "*A list of extra switches to pass to `ps-lpr-command'."
edc9cd35 1811 :type '(repeat :tag "PostScript lpr Switches"
ef1159c2
EZ
1812 (choice :menu-tag "PostScript lpr Switch"
1813 :tag "PostScript lpr Switch"
1814 string symbol (repeat sexp)))
b6d0ac87 1815 :version "20"
bc0d41bd 1816 :group 'ps-print-printer)
12d89a2e 1817
52cf535f 1818(defcustom ps-print-region-function nil
bc0d41bd 1819 "*Specify a function to print the region on a PostScript printer.
319acba0
GM
1820See definition of `call-process-region' for calling conventions. The fourth
1821and the sixth arguments are both nil."
942a1d58 1822 :type '(choice (const nil) function)
b6d0ac87 1823 :version "20"
bc0d41bd 1824 :group 'ps-print-printer)
52cf535f 1825
8e234846
GM
1826(defcustom ps-manual-feed nil
1827 "*Non-nil means the printer will manually feed paper.
1828
1829If it's nil, automatic feeding takes place."
1830 :type 'boolean
b6d0ac87 1831 :version "20"
8e234846
GM
1832 :group 'ps-print-printer)
1833
bd7a2e26 1834(defcustom ps-end-with-control-d (and ps-windows-system t)
ef1159c2 1835 "*Non-nil means insert C-d at end of PostScript file generated."
6bf5fb46 1836 :version "21.1"
ef1159c2 1837 :type 'boolean
b6d0ac87 1838 :version "20"
ef1159c2
EZ
1839 :group 'ps-print-printer)
1840
bcc0d457 1841;;; Page layout
12d89a2e 1842
bcc0d457
RS
1843;; All page dimensions are in PostScript points.
1844;; 1 inch == 2.54 cm == 72 points
1845;; 1 cm == (/ 1 2.54) inch == (/ 72 2.54) points
1846
1847;; Letter 8.5 inch x 11.0 inch
1848;; Legal 8.5 inch x 14.0 inch
1849;; A4 8.26 inch x 11.69 inch = 21.0 cm x 29.7 cm
1850
1851;; LetterSmall 7.68 inch x 10.16 inch
1852;; Tabloid 11.0 inch x 17.0 inch
1853;; Ledger 17.0 inch x 11.0 inch
1854;; Statement 5.5 inch x 8.5 inch
1855;; Executive 7.5 inch x 10.0 inch
1856;; A3 11.69 inch x 16.5 inch = 29.7 cm x 42.0 cm
1857;; A4Small 7.47 inch x 10.85 inch
1858;; B4 10.125 inch x 14.33 inch
1859;; B5 7.16 inch x 10.125 inch
1860
c90a10fa 1861;;;###autoload
e0af0d3e 1862(defcustom ps-page-dimensions-database
bc0d41bd
KH
1863 (list (list 'a4 (/ (* 72 21.0) 2.54) (/ (* 72 29.7) 2.54) "A4")
1864 (list 'a3 (/ (* 72 29.7) 2.54) (/ (* 72 42.0) 2.54) "A3")
1865 (list 'letter (* 72 8.5) (* 72 11.0) "Letter")
1866 (list 'legal (* 72 8.5) (* 72 14.0) "Legal")
1867 (list 'letter-small (* 72 7.68) (* 72 10.16) "LetterSmall")
1868 (list 'tabloid (* 72 11.0) (* 72 17.0) "Tabloid")
1869 (list 'ledger (* 72 17.0) (* 72 11.0) "Ledger")
1870 (list 'statement (* 72 5.5) (* 72 8.5) "Statement")
1871 (list 'executive (* 72 7.5) (* 72 10.0) "Executive")
1872 (list 'a4small (* 72 7.47) (* 72 10.85) "A4Small")
1873 (list 'b4 (* 72 10.125) (* 72 14.33) "B4")
1874 (list 'b5 (* 72 7.16) (* 72 10.125) "B5"))
1875 "*List associating a symbolic paper type to its width, height and doc media.
1876See `ps-paper-type'."
e0af0d3e
RS
1877 :type '(repeat (list :tag "Paper Type"
1878 (symbol :tag "Name")
1879 (number :tag "Width")
bc0d41bd
KH
1880 (number :tag "Height")
1881 (string :tag "Media")))
b6d0ac87 1882 :version "20"
bc0d41bd 1883 :group 'ps-print-page)
e0af0d3e 1884
857686a6 1885;;;###autoload
e0af0d3e 1886(defcustom ps-paper-type 'letter
bc0d41bd 1887 "*Specify the size of paper to format for.
090be653 1888Should be one of the paper types defined in `ps-page-dimensions-database', for
e0af0d3e
RS
1889example `letter', `legal' or `a4'."
1890 :type '(symbol :validate (lambda (wid)
87a16a06
RS
1891 (if (assq (widget-value wid)
1892 ps-page-dimensions-database)
e0af0d3e
RS
1893 nil
1894 (widget-put wid :error "Unknown paper size")
1895 wid)))
b6d0ac87 1896 :version "20"
bc0d41bd 1897 :group 'ps-print-page)
e0af0d3e 1898
8e234846
GM
1899(defcustom ps-warn-paper-type t
1900 "*Non-nil means give an error if paper size is not equal to `ps-paper-type'.
1901
1902It's used when `ps-spool-config' is set to `setpagedevice'."
1903 :type 'boolean
b6d0ac87 1904 :version "20"
8e234846
GM
1905 :group 'ps-print-page)
1906
87a16a06 1907(defcustom ps-landscape-mode nil
e0af0d3e
RS
1908 "*Non-nil means print in landscape mode."
1909 :type 'boolean
b6d0ac87 1910 :version "20"
bc0d41bd 1911 :group 'ps-print-page)
e0af0d3e 1912
906d41a7 1913(defcustom ps-print-upside-down nil
2285bf9d 1914 "*Non-nil means print upside-down (that is, rotated by 180 degrees)."
906d41a7 1915 :type 'boolean
319acba0 1916 :version "21.1"
906d41a7
GM
1917 :group 'ps-print-page)
1918
1fd9b7fe
GM
1919(defcustom ps-selected-pages nil
1920 "*Specify which pages to print.
1921
2285bf9d 1922If nil, print all pages.
1fd9b7fe 1923
2285bf9d 1924If a list, the lists element may be an integer or a cons cell (FROM . TO)
1fd9b7fe 1925designating FROM page to TO page; any invalid element is ignored, that is, an
e59d29d6 1926integer lesser than one or if FROM is greater than TO.
1fd9b7fe
GM
1927
1928Otherwise, it's treated as nil.
1929
2285bf9d
RS
1930After ps-print processing `ps-selected-pages' is set to nil. But the
1931latest `ps-selected-pages' is saved in `ps-last-selected-pages' (which
1932see). So you can restore the latest selected pages by using
1933`ps-last-selected-pages' or with the `ps-restore-selected-pages'
1934command (which see).
ea0c615d
GM
1935
1936See also `ps-even-or-odd-pages'."
1fd9b7fe
GM
1937 :type '(repeat :tag "Selected Pages"
1938 (radio :tag "Page"
1939 (integer :tag "Number")
1940 (cons :tag "Range"
1941 (integer :tag "From")
1942 (integer :tag "To"))))
b6d0ac87 1943 :version "20"
1fd9b7fe
GM
1944 :group 'ps-print-page)
1945
c3d6d211
GM
1946(defcustom ps-even-or-odd-pages nil
1947 "*Specify if it prints even/odd pages.
1948
1949Valid values are:
1950
1951 nil print all pages.
1952
4b3eb10f
GM
1953 `even-page' print only even pages.
1954
1955 `odd-page' print only odd pages.
1956
1957 `even-sheet' print only even sheets.
bd7a2e26
GM
1958 That is, if `ps-n-up-printing' is 1, it behaves as `even-page';
1959 but for values greater than 1, it'll print only the even sheet
1960 of paper.
c3d6d211 1961
4b3eb10f 1962 `odd-sheet' print only odd sheets.
bd7a2e26
GM
1963 That is, if `ps-n-up-printing' is 1, it behaves as `odd-page';
1964 but for values greater than 1, it'll print only the odd sheet
1965 of paper.
c3d6d211 1966
ea0c615d
GM
1967Any other value is treated as nil.
1968
1969If you set `ps-selected-pages' (see it for documentation), first the pages are
1970filtered by `ps-selected-pages' and then by `ps-even-or-odd-pages'. For
1971example, if we have:
1972
4b3eb10f 1973 (setq ps-selected-pages '(1 4 (6 . 10) (12 . 16) 20))
ea0c615d 1974
4b3eb10f 1975Combining with `ps-even-or-odd-pages' and `ps-n-up-printing', we have:
ea0c615d 1976
4b3eb10f 1977`ps-n-up-printing' = 1:
ea0c615d 1978 `ps-even-or-odd-pages' PAGES PRINTED
4b3eb10f
GM
1979 nil 1, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 20
1980 even-page 4, 6, 8, 10, 12, 14, 16, 20
1981 odd-page 1, 7, 9, 13, 15
1982 even-sheet 4, 6, 8, 10, 12, 14, 16, 20
1983 odd-sheet 1, 7, 9, 13, 15
1984
1985`ps-n-up-printing' = 2:
1986 `ps-even-or-odd-pages' PAGES PRINTED
1987 nil 1/4, 6/7, 8/9, 10/12, 13/14, 15/16, 20
1988 even-page 4/6, 8/10, 12/14, 16/20
1989 odd-page 1/7, 9/13, 15
1990 even-sheet 6/7, 10/12, 15/16
1991 odd-sheet 1/4, 8/9, 13/14, 20
1992
1993So even-page/odd-page are about page parity and even-sheet/odd-sheet are about
1994sheet parity."
c3d6d211
GM
1995 :type '(choice :menu-tag "Print Even/Odd Pages"
1996 :tag "Print Even/Odd Pages"
1997 (const :tag "All Pages" nil)
4b3eb10f
GM
1998 (const :tag "Only Even Pages" even-page)
1999 (const :tag "Only Odd Pages" odd-page)
2000 (const :tag "Only Even Sheets" even-sheet)
2001 (const :tag "Only Odd Sheets" odd-sheet))
b6d0ac87 2002 :version "20"
c3d6d211
GM
2003 :group 'ps-print-page)
2004
857686a6 2005(defcustom ps-print-control-characters 'control-8-bit
bc0d41bd
KH
2006 "*Specify the printable form for control and 8-bit characters.
2007That is, instead of sending, for example, a ^D (\\004) to printer,
915293a2 2008it is sent the string \"^D\".
6bdb808e 2009
857686a6 2010Valid values are:
6bdb808e 2011
984e7bd9 2012 `8-bit' This is the value to use when you want an ASCII encoding of
d3ab8dac
KH
2013 any control or non-ASCII character. Control characters are
2014 encoded as \"^D\", and non-ASCII characters have an
2015 octal encoding.
6bdb808e 2016
984e7bd9 2017 `control-8-bit' This is the value to use when you want an ASCII encoding of
d3ab8dac
KH
2018 any control character, whether it is 7 or 8-bit.
2019 European 8-bits accented characters are printed according
2020 the current font.
6bdb808e 2021
c82b4a75 2022 `control' Only ASCII control characters have an ASCII encoding.
d3ab8dac
KH
2023 European 8-bits accented characters are printed according
2024 the current font.
6bdb808e 2025
984e7bd9 2026 nil No ASCII encoding. Any character is printed according the
d3ab8dac 2027 current font.
6bdb808e 2028
857686a6 2029Any other value is treated as nil."
8e234846
GM
2030 :type '(choice :menu-tag "Control Char"
2031 :tag "Control Char"
bc0d41bd 2032 (const 8-bit) (const control-8-bit)
edc9cd35 2033 (const control) (const :tag "nil" nil))
b6d0ac87 2034 :version "20"
6e1b1da6 2035 :group 'ps-print-miscellany)
857686a6 2036
bc0d41bd
KH
2037(defcustom ps-n-up-printing 1
2038 "*Specify the number of pages per sheet paper."
2039 :type '(integer
2040 :tag "N Up Printing"
2041 :validate
2042 (lambda (wid)
2043 (if (and (< 0 (widget-value wid))
2044 (<= (widget-value wid) 100))
2045 nil
2046 (widget-put
2047 wid :error
2048 "Number of pages per sheet paper must be between 1 and 100.")
2049 wid)))
b6d0ac87 2050 :version "20"
bc0d41bd
KH
2051 :group 'ps-print-n-up)
2052
2053(defcustom ps-n-up-margin (/ (* 72 1.0) 2.54) ; 1 cm
2054 "*Specify the margin in points between the sheet border and n-up printing."
2055 :type 'number
b6d0ac87 2056 :version "20"
bc0d41bd
KH
2057 :group 'ps-print-n-up)
2058
2059(defcustom ps-n-up-border-p t
2060 "*Non-nil means a border is drawn around each page."
2061 :type 'boolean
b6d0ac87 2062 :version "20"
bc0d41bd
KH
2063 :group 'ps-print-n-up)
2064
2065(defcustom ps-n-up-filling 'left-top
2066 "*Specify how page matrix is filled on each sheet of paper.
2067
2068Following are the valid values for `ps-n-up-filling' with a filling example
2069using a 3x4 page matrix:
2070
2071 `left-top' 1 2 3 4 `left-bottom' 9 10 11 12
2072 5 6 7 8 5 6 7 8
2073 9 10 11 12 1 2 3 4
2074
2075 `right-top' 4 3 2 1 `right-bottom' 12 11 10 9
2076 8 7 6 5 8 7 6 5
2077 12 11 10 9 4 3 2 1
2078
2079 `top-left' 1 4 7 10 `bottom-left' 3 6 9 12
2080 2 5 8 11 2 5 8 11
2081 3 6 9 12 1 4 7 10
2082
2083 `top-right' 10 7 4 1 `bottom-right' 12 9 6 3
2084 11 8 5 2 11 8 5 2
2085 12 9 6 3 10 7 4 1
2086
2087Any other value is treated as `left-top'."
8e234846
GM
2088 :type '(choice :menu-tag "N-Up Filling"
2089 :tag "N-Up Filling"
bc0d41bd
KH
2090 (const left-top) (const left-bottom)
2091 (const right-top) (const right-bottom)
2092 (const top-left) (const bottom-left)
2093 (const top-right) (const bottom-right))
b6d0ac87 2094 :version "20"
bc0d41bd
KH
2095 :group 'ps-print-n-up)
2096
e0af0d3e 2097(defcustom ps-number-of-columns (if ps-landscape-mode 2 1)
2285bf9d 2098 "*Specify the number of columns."
87a16a06 2099 :type 'number
b6d0ac87 2100 :version "20"
6e1b1da6 2101 :group 'ps-print-miscellany)
87a16a06 2102
535efc38 2103(defcustom ps-zebra-stripes nil
87a16a06 2104 "*Non-nil means print zebra stripes.
6e1b1da6 2105See also documentation for `ps-zebra-stripe-height' and `ps-zebra-color'."
87a16a06 2106 :type 'boolean
b6d0ac87 2107 :version "20"
bc0d41bd 2108 :group 'ps-print-zebra)
87a16a06 2109
535efc38 2110(defcustom ps-zebra-stripe-height 3
87a16a06 2111 "*Number of zebra stripe lines.
6e1b1da6 2112See also documentation for `ps-zebra-stripes' and `ps-zebra-color'."
87a16a06 2113 :type 'number
b6d0ac87 2114 :version "20"
bc0d41bd
KH
2115 :group 'ps-print-zebra)
2116
6e1b1da6
GM
2117(defcustom ps-zebra-color 0.95
2118 "*Zebra stripe gray scale or RGB color.
bc0d41bd 2119See also documentation for `ps-zebra-stripes' and `ps-zebra-stripe-height'."
8e234846
GM
2120 :type '(choice :menu-tag "Zebra Gray/Color"
2121 :tag "Zebra Gray/Color"
6e1b1da6
GM
2122 (number :tag "Gray Scale" :value 0.95)
2123 (string :tag "Color Name" :value "gray95")
2124 (list :tag "RGB Color" :value (0.95 0.95 0.95)
2125 (number :tag "Red")
2126 (number :tag "Green")
2127 (number :tag "Blue")))
b6d0ac87 2128 :version "20"
bc0d41bd 2129 :group 'ps-print-zebra)
87a16a06 2130
8e234846 2131(defcustom ps-zebra-stripe-follow nil
2bd80d73
GM
2132 "*Specify how zebra stripes continue on next page.
2133
2134Visually, valid values are (the character `+' at right of each column indicates
2135that a line is printed):
2136
2137 `nil' `follow' `full' `full-follow'
2138 Current Page -------- ----------- --------- ----------------
2139 1 XXXXX + 1 XXXXXXXX + 1 XXXXXX + 1 XXXXXXXXXXXXX +
2140 2 XXXXX + 2 XXXXXXXX + 2 XXXXXX + 2 XXXXXXXXXXXXX +
2141 3 XXXXX + 3 XXXXXXXX + 3 XXXXXX + 3 XXXXXXXXXXXXX +
2142 4 + 4 + 4 + 4 +
2143 5 + 5 + 5 + 5 +
2144 6 + 6 + 6 + 6 +
2145 7 XXXXX + 7 XXXXXXXX + 7 XXXXXX + 7 XXXXXXXXXXXXX +
2146 8 XXXXX + 8 XXXXXXXX + 8 XXXXXX + 8 XXXXXXXXXXXXX +
2147 9 XXXXX + 9 XXXXXXXX + 9 XXXXXX + 9 XXXXXXXXXXXXX +
2148 10 + 10 +
2149 11 + 11 +
2150 -------- ----------- --------- ----------------
2151 Next Page -------- ----------- --------- ----------------
2152 12 XXXXX + 12 + 10 XXXXXX + 10 +
2153 13 XXXXX + 13 XXXXXXXX + 11 XXXXXX + 11 +
2154 14 XXXXX + 14 XXXXXXXX + 12 XXXXXX + 12 +
2155 15 + 15 XXXXXXXX + 13 + 13 XXXXXXXXXXXXX +
2156 16 + 16 + 14 + 14 XXXXXXXXXXXXX +
2157 17 + 17 + 15 + 15 XXXXXXXXXXXXX +
2158 18 XXXXX + 18 + 16 XXXXXX + 16 +
2159 19 XXXXX + 19 XXXXXXXX + 17 XXXXXX + 17 +
2160 20 XXXXX + 20 XXXXXXXX + 18 XXXXXX + 18 +
2161 21 + 21 XXXXXXXX +
2162 22 + 22 +
2163 -------- ----------- --------- ----------------
2164
d730a5ac 2165Any other value is treated as nil."
2bd80d73
GM
2166 :type '(choice :menu-tag "Zebra Stripe Follow"
2167 :tag "Zebra Stripe Follow"
2168 (const :tag "Always Restart" nil)
2169 (const :tag "Continue on Next Page" follow)
2170 (const :tag "Print Only Full Stripe" full)
2171 (const :tag "Continue on Full Stripe" full-follow))
b6d0ac87 2172 :version "20"
8e234846
GM
2173 :group 'ps-print-zebra)
2174
87a16a06
RS
2175(defcustom ps-line-number nil
2176 "*Non-nil means print line number."
2177 :type 'boolean
b6d0ac87 2178 :version "20"
6e1b1da6 2179 :group 'ps-print-miscellany)
87a16a06 2180
906d41a7
GM
2181(defcustom ps-line-number-step 1
2182 "*Specify the interval that line number is printed.
2183
2184For example, `ps-line-number-step' is set to 2, the printing will look like:
2185
2186 1 one line
2187 one line
2188 3 one line
2189 one line
98f2fbe7 2190 5 one line
906d41a7
GM
2191 one line
2192 ...
2193
2194Valid values are:
2195
2196 integer an integer that specifies the interval that line number is
2197 printed. If it's lesser than or equal to zero, it's used the
2198 value 1.
2199
319acba0
GM
2200 `zebra' specifies that only the line number of the first line in a
2201 zebra stripe is to be printed.
906d41a7
GM
2202
2203Any other value is treated as `zebra'."
8e234846
GM
2204 :type '(choice :menu-tag "Line Number Step"
2205 :tag "Line Number Step"
906d41a7
GM
2206 (integer :tag "Step Interval")
2207 (const :tag "Synchronize Zebra" zebra))
b6d0ac87 2208 :version "20"
906d41a7
GM
2209 :group 'ps-print-miscellany)
2210
98f2fbe7
GM
2211(defcustom ps-line-number-start 1
2212 "*Specify the starting point in the interval given by `ps-line-number-step'.
2213
3556c6dd
GM
2214For example, if `ps-line-number-step' is set to 3 and `ps-line-number-start' is
2215set to 3, the printing will look like:
98f2fbe7
GM
2216
2217 one line
2218 one line
2219 3 one line
2220 one line
2221 one line
2222 6 one line
2223 one line
2224 one line
2225 9 one line
2226 one line
2227 ...
2228
2229The values for `ps-line-number-start':
2230
319acba0
GM
2231 * If `ps-line-number-step' is an integer, must be between 1 and the value of
2232 `ps-line-number-step' inclusive.
98f2fbe7
GM
2233
2234 * If `ps-line-number-step' is set to `zebra', must be between 1 and the
2235 value of `ps-zebra-strip-height' inclusive. Use this combination if you
2236 wish that line number be relative to zebra stripes."
2237 :type '(integer :tag "Start Step Interval")
b6d0ac87 2238 :version "20"
98f2fbe7
GM
2239 :group 'ps-print-miscellany)
2240
87a16a06
RS
2241(defcustom ps-print-background-image nil
2242 "*EPS image list to be printed on background.
2243
2244The elements are:
2245
2246 (FILENAME X Y XSCALE YSCALE ROTATION PAGES...)
2247
2248FILENAME is a file name which contains an EPS image or some PostScript
2249programming like EPS.
2250FILENAME is ignored, if it doesn't exist or is read protected.
2251
2252X and Y are relative positions on paper to put the image.
01cdabc6 2253If X and Y are nil, the image is centered on paper.
87a16a06
RS
2254
2255XSCALE and YSCALE are scale factor to be applied to image before printing.
2256If XSCALE and YSCALE are nil, the original size is used.
2257
2258ROTATION is the image rotation angle; if nil, the default is 0.
2259
2260PAGES designates the page to print background image.
319acba0
GM
2261PAGES may be a number or a cons cell (FROM . TO) designating FROM page to TO
2262page.
87a16a06
RS
2263If PAGES is nil, print background image on all pages.
2264
319acba0 2265X, Y, XSCALE, YSCALE and ROTATION may be a floating point number, an integer
2285bf9d 2266number or a string. If it is a string, the string should contain PostScript
319acba0 2267programming that returns a float or integer value.
87a16a06
RS
2268
2269For example, if you wish to print an EPS image on all pages do:
2270
2271 '((\"~/images/EPS-image.ps\"))"
98f2fbe7
GM
2272 :type '(repeat
2273 (list
2274 (file :tag "EPS File")
2275 (choice :tag "X" (const :tag "default" nil) number string)
2276 (choice :tag "Y" (const :tag "default" nil) number string)
2277 (choice :tag "X Scale" (const :tag "default" nil) number string)
2278 (choice :tag "Y Scale" (const :tag "default" nil) number string)
2279 (choice :tag "Rotation" (const :tag "default" nil) number string)
2280 (repeat :tag "Pages" :inline t
2281 (radio (integer :tag "Page")
2282 (cons :tag "Range"
2283 (integer :tag "From")
2284 (integer :tag "To"))))))
b6d0ac87 2285 :version "20"
bc0d41bd 2286 :group 'ps-print-background)
87a16a06
RS
2287
2288(defcustom ps-print-background-text nil
2289 "*Text list to be printed on background.
2290
2291The elements are:
2292
2293 (STRING X Y FONT FONTSIZE GRAY ROTATION PAGES...)
2294
2295STRING is the text to be printed on background.
2296
2297X and Y are positions on paper to put the text.
2298If X and Y are nil, the text is positioned at lower left corner.
2299
2300FONT is a font name to be used on printing the text.
2301If nil, \"Times-Roman\" is used.
2302
2303FONTSIZE is font size to be used, if nil, 200 is used.
2304
2305GRAY is the text gray factor (should be very light like 0.8).
2306If nil, the default is 0.85.
2307
319acba0
GM
2308ROTATION is the text rotation angle; if nil, the angle is given by the diagonal
2309from lower left corner to upper right corner.
87a16a06
RS
2310
2311PAGES designates the page to print background text.
319acba0
GM
2312PAGES may be a number or a cons cell (FROM . TO) designating FROM page to TO
2313page.
87a16a06
RS
2314If PAGES is nil, print background text on all pages.
2315
319acba0 2316X, Y, FONTSIZE, GRAY and ROTATION may be a floating point number, an integer
2285bf9d 2317number or a string. If it is a string, the string should contain PostScript
319acba0 2318programming that returns a float or integer value.
87a16a06
RS
2319
2320For example, if you wish to print text \"Preliminary\" on all pages do:
2321
2322 '((\"Preliminary\"))"
98f2fbe7
GM
2323 :type '(repeat
2324 (list
2325 (string :tag "Text")
2326 (choice :tag "X" (const :tag "default" nil) number string)
2327 (choice :tag "Y" (const :tag "default" nil) number string)
2328 (choice :tag "Font" (const :tag "default" nil) string)
2329 (choice :tag "Fontsize" (const :tag "default" nil) number string)
2330 (choice :tag "Gray" (const :tag "default" nil) number string)
2331 (choice :tag "Rotation" (const :tag "default" nil) number string)
2332 (repeat :tag "Pages" :inline t
2333 (radio (integer :tag "Page")
2334 (cons :tag "Range"
2335 (integer :tag "From")
2336 (integer :tag "To"))))))
b6d0ac87 2337 :version "20"
bc0d41bd 2338 :group 'ps-print-background)
bcc0d457
RS
2339
2340;;; Horizontal layout
2341
2342;; ------------------------------------------
2343;; | | | | | | | |
2344;; | lm | text | ic | text | ic | text | rm |
2345;; | | | | | | | |
2346;; ------------------------------------------
2347
e0af0d3e
RS
2348(defcustom ps-left-margin (/ (* 72 2.0) 2.54) ; 2 cm
2349 "*Left margin in points (1/72 inch)."
2350 :type 'number
b6d0ac87 2351 :version "20"
e0af0d3e 2352 :group 'ps-print-horizontal)
bcc0d457 2353
e0af0d3e
RS
2354(defcustom ps-right-margin (/ (* 72 2.0) 2.54) ; 2 cm
2355 "*Right margin in points (1/72 inch)."
2356 :type 'number
b6d0ac87 2357 :version "20"
e0af0d3e 2358 :group 'ps-print-horizontal)
bcc0d457 2359
e0af0d3e
RS
2360(defcustom ps-inter-column (/ (* 72 2.0) 2.54) ; 2 cm
2361 "*Horizontal space between columns in points (1/72 inch)."
2362 :type 'number
b6d0ac87 2363 :version "20"
e0af0d3e 2364 :group 'ps-print-horizontal)
bcc0d457
RS
2365
2366;;; Vertical layout
2367
2368;; |--------|
2369;; | tm |
2370;; |--------|
2371;; | header |
2372;; |--------|
2373;; | ho |
2374;; |--------|
2375;; | text |
2376;; |--------|
2377;; | bm |
2378;; |--------|
2379
e0af0d3e
RS
2380(defcustom ps-bottom-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
2381 "*Bottom margin in points (1/72 inch)."
2382 :type 'number
b6d0ac87 2383 :version "20"
e0af0d3e 2384 :group 'ps-print-vertical)
bcc0d457 2385
e0af0d3e
RS
2386(defcustom ps-top-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
2387 "*Top margin in points (1/72 inch)."
2388 :type 'number
b6d0ac87 2389 :version "20"
e0af0d3e 2390 :group 'ps-print-vertical)
bcc0d457 2391
e0af0d3e
RS
2392(defcustom ps-header-offset (/ (* 72 1.0) 2.54) ; 1.0 cm
2393 "*Vertical space in points (1/72 inch) between the main text and the header."
2394 :type 'number
b6d0ac87 2395 :version "20"
e0af0d3e 2396 :group 'ps-print-vertical)
bcc0d457 2397
e0af0d3e 2398(defcustom ps-header-line-pad 0.15
2285bf9d
RS
2399 "*Portion of a header title line height to insert.
2400The insertion is done between the header frame and the text it contains,
2401both in the vertical and horizontal directions."
e0af0d3e 2402 :type 'number
b6d0ac87 2403 :version "20"
e0af0d3e 2404 :group 'ps-print-vertical)
bcc0d457 2405
319acba0
GM
2406(defcustom ps-footer-offset (/ (* 72 1.0) 2.54) ; 1.0 cm
2407 "*Vertical space in points (1/72 inch) between the main text and the footer."
2408 :type 'number
b6d0ac87 2409 :version "20"
319acba0
GM
2410 :group 'ps-print-vertical)
2411
2412(defcustom ps-footer-line-pad 0.15
2285bf9d
RS
2413 "*Portion of a footer title line height to insert.
2414The insertion is done between the footer frame and the text it contains,
2415both in the vertical and horizontal directions."
319acba0 2416 :type 'number
b6d0ac87 2417 :version "20"
319acba0
GM
2418 :group 'ps-print-vertical)
2419
2420;;; Header/Footer setup
12d89a2e 2421
e0af0d3e 2422(defcustom ps-print-header t
86c10ecb 2423 "*Non-nil means print a header at the top of each page.
319acba0
GM
2424By default, the header displays the buffer name, page number, and, if the
2425buffer is visiting a file, the file's directory. Headers are customizable by
2426changing variables `ps-left-header' and `ps-right-header'."
12b88fff 2427 :type 'boolean
b6d0ac87 2428 :version "20"
6e1b1da6 2429 :group 'ps-print-headers)
12b88fff 2430
e0af0d3e
RS
2431(defcustom ps-print-header-frame t
2432 "*Non-nil means draw a gaudy frame around the header."
2433 :type 'boolean
b6d0ac87 2434 :version "20"
6e1b1da6 2435 :group 'ps-print-headers)
e0af0d3e 2436
319acba0 2437(defcustom ps-header-frame-alist
efa89c1f 2438 '((fore-color . 0.0)
319acba0
GM
2439 (back-color . 0.9)
2440 (border-width . 0.4)
efa89c1f
GM
2441 (border-color . 0.0)
2442 (shadow-color . 0.0))
319acba0
GM
2443 "*Specify header frame properties alist.
2444
2445Valid frame properties are:
2446
2447 `fore-color' Specify the foreground frame color.
2448 It should be a float number between 0.0 (black color)
2449 and 1.0 (white color), a string which is a color name,
2450 or a list of 3 float numbers which corresponds to the
2451 Red Green Blue color scale, each float number between
2452 0.0 (dark color) and 1.0 (bright color).
2453
2454 `back-color' Specify the background frame color (similar to
2455 `fore-color').
2456
2457 `shadow-color' Specify the shadow color (similar to `fore-color').
2458
2459 `border-color' Specify the border color (similar to `fore-color').
2460
2461 `border-width' Specify the border width.
2462
2463Any other property is ignored.
2464
2465Don't change this alist directly, instead use customization, or `ps-value',
2466`ps-get', `ps-put' and `ps-del' functions (see them for documentation)."
2467 :version "21.1"
2468 :type '(repeat
2469 (choice :menu-tag "Header Frame Element"
2470 :tag ""
2471 (cons :tag "Foreground Color" :format "%v"
2472 (const :format "" fore-color)
2473 (choice :menu-tag "Foreground Color"
2474 :tag "Foreground Color"
efa89c1f 2475 (number :tag "Gray Scale" :value 0.0)
319acba0 2476 (string :tag "Color Name" :value "black")
efa89c1f 2477 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2478 (number :tag "Red")
2479 (number :tag "Green")
2480 (number :tag "Blue"))))
2481 (cons :tag "Background Color" :format "%v"
2482 (const :format "" back-color)
2483 (choice :menu-tag "Background Color"
2484 :tag "Background Color"
2485 (number :tag "Gray Scale" :value 0.9)
2486 (string :tag "Color Name" :value "gray90")
2487 (list :tag "RGB Color" :value (0.9 0.9 0.9)
2488 (number :tag "Red")
2489 (number :tag "Green")
2490 (number :tag "Blue"))))
2491 (cons :tag "Border Width" :format "%v"
2492 (const :format "" border-width)
2493 (number :tag "Border Width" :value 0.4))
2494 (cons :tag "Border Color" :format "%v"
2495 (const :format "" border-color)
2496 (choice :menu-tag "Border Color"
2497 :tag "Border Color"
efa89c1f 2498 (number :tag "Gray Scale" :value 0.0)
319acba0 2499 (string :tag "Color Name" :value "black")
efa89c1f 2500 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2501 (number :tag "Red")
2502 (number :tag "Green")
2503 (number :tag "Blue"))))
2504 (cons :tag "Shadow Color" :format "%v"
2505 (const :format "" shadow-color)
2506 (choice :menu-tag "Shadow Color"
2507 :tag "Shadow Color"
efa89c1f 2508 (number :tag "Gray Scale" :value 0.0)
319acba0 2509 (string :tag "Color Name" :value "black")
efa89c1f 2510 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2511 (number :tag "Red")
2512 (number :tag "Green")
2513 (number :tag "Blue"))))))
b6d0ac87 2514 :version "20"
319acba0
GM
2515 :group 'ps-print-headers)
2516
e0af0d3e 2517(defcustom ps-header-lines 2
8bd22fcf 2518 "*Number of lines to display in page header, when generating PostScript."
e0af0d3e 2519 :type 'integer
b6d0ac87 2520 :version "20"
6e1b1da6 2521 :group 'ps-print-headers)
bcc0d457 2522
319acba0
GM
2523(defcustom ps-print-footer nil
2524 "*Non-nil means print a footer at the bottom of each page.
2525By default, the footer displays page number.
2526Footers are customizable by changing variables `ps-left-footer' and
2527`ps-right-footer'."
319acba0 2528 :type 'boolean
b6d0ac87 2529 :version "21.1"
319acba0
GM
2530 :group 'ps-print-headers)
2531
2532(defcustom ps-print-footer-frame t
2533 "*Non-nil means draw a gaudy frame around the footer."
319acba0 2534 :type 'boolean
b6d0ac87 2535 :version "21.1"
319acba0
GM
2536 :group 'ps-print-headers)
2537
2538(defcustom ps-footer-frame-alist
efa89c1f 2539 '((fore-color . 0.0)
319acba0
GM
2540 (back-color . 0.9)
2541 (border-width . 0.4)
efa89c1f
GM
2542 (border-color . 0.0)
2543 (shadow-color . 0.0))
319acba0
GM
2544 "*Specify footer frame properties alist.
2545
2546Don't change this alist directly, instead use customization, or `ps-value',
2547`ps-get', `ps-put' and `ps-del' functions (see them for documentation).
2548
2549See also `ps-header-frame-alist' for documentation."
319acba0
GM
2550 :type '(repeat
2551 (choice :menu-tag "Header Frame Element"
2552 :tag ""
2553 (cons :tag "Foreground Color" :format "%v"
2554 (const :format "" fore-color)
2555 (choice :menu-tag "Foreground Color"
2556 :tag "Foreground Color"
efa89c1f 2557 (number :tag "Gray Scale" :value 0.0)
319acba0 2558 (string :tag "Color Name" :value "black")
efa89c1f 2559 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2560 (number :tag "Red")
2561 (number :tag "Green")
2562 (number :tag "Blue"))))
2563 (cons :tag "Background Color" :format "%v"
2564 (const :format "" back-color)
2565 (choice :menu-tag "Background Color"
2566 :tag "Background Color"
2567 (number :tag "Gray Scale" :value 0.9)
2568 (string :tag "Color Name" :value "gray90")
2569 (list :tag "RGB Color" :value (0.9 0.9 0.9)
2570 (number :tag "Red")
2571 (number :tag "Green")
2572 (number :tag "Blue"))))
2573 (cons :tag "Border Width" :format "%v"
2574 (const :format "" border-width)
2575 (number :tag "Border Width" :value 0.4))
2576 (cons :tag "Border Color" :format "%v"
2577 (const :format "" border-color)
2578 (choice :menu-tag "Border Color"
2579 :tag "Border Color"
efa89c1f 2580 (number :tag "Gray Scale" :value 0.0)
319acba0 2581 (string :tag "Color Name" :value "black")
efa89c1f 2582 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2583 (number :tag "Red")
2584 (number :tag "Green")
2585 (number :tag "Blue"))))
2586 (cons :tag "Shadow Color" :format "%v"
2587 (const :format "" shadow-color)
2588 (choice :menu-tag "Shadow Color"
2589 :tag "Shadow Color"
efa89c1f 2590 (number :tag "Gray Scale" :value 0.0)
319acba0 2591 (string :tag "Color Name" :value "black")
efa89c1f 2592 (list :tag "RGB Color" :value (0.0 0.0 0.0)
319acba0
GM
2593 (number :tag "Red")
2594 (number :tag "Green")
2595 (number :tag "Blue"))))))
b6d0ac87 2596 :version "21.1"
319acba0
GM
2597 :group 'ps-print-headers)
2598
2599(defcustom ps-footer-lines 2
2600 "*Number of lines to display in page footer, when generating PostScript."
319acba0 2601 :type 'integer
b6d0ac87 2602 :version "21.1"
319acba0
GM
2603 :group 'ps-print-headers)
2604
2605(defcustom ps-print-only-one-header nil
2606 "*Non-nil means print only one header/footer at the top/bottom of each page.
2607This is useful when printing more than one column, so it is possible to have
2608only one header/footer over all columns or one header/footer per column.
2609See also `ps-print-header' and `ps-print-footer'."
2610 :type 'boolean
b6d0ac87 2611 :version "20"
319acba0
GM
2612 :group 'ps-print-headers)
2613
8e234846 2614(defcustom ps-switch-header 'duplex
319acba0 2615 "*Specify if headers/footers are switched or not.
8e234846
GM
2616
2617Valid values are:
2618
319acba0 2619nil Never switch headers/footers.
8e234846 2620
319acba0 2621t Always switch headers/footers.
8e234846 2622
319acba0 2623duplex Switch headers/footers only when duplexing is on, that is, when
8e234846
GM
2624 `ps-spool-duplex' is non-nil.
2625
319acba0
GM
2626Any other value is treated as t.
2627
2628See also `ps-print-header' and `ps-print-footer'."
2629 :type '(choice :menu-tag "Switch Header/Footer"
2630 :tag "Switch Header/Footer"
8e234846
GM
2631 (const :tag "Never Switch" nil)
2632 (const :tag "Always Switch" t)
2633 (const :tag "Switch When Duplexing" duplex))
b6d0ac87 2634 :version "20"
8e234846
GM
2635 :group 'ps-print-headers)
2636
e0af0d3e 2637(defcustom ps-show-n-of-n t
00aa16af 2638 "*Non-nil means show page numbers as N/M, meaning page N of M.
8bd22fcf 2639NOTE: page numbers are displayed as part of headers,
6e1b1da6 2640 see variable `ps-print-header'."
e0af0d3e 2641 :type 'boolean
b6d0ac87 2642 :version "20"
6e1b1da6 2643 :group 'ps-print-headers)
12d89a2e 2644
edc9cd35 2645(defcustom ps-spool-config
906d41a7 2646 (if ps-windows-system
edc9cd35
GM
2647 nil
2648 'lpr-switches)
319acba0 2649 "*Specify who is responsible for setting duplex and page size.
bc0d41bd
KH
2650
2651Valid values are:
2652
2653 `lpr-switches' duplex and page size are configured by `ps-lpr-switches'.
2654 Don't forget to set `ps-lpr-switches' to select duplex
2655 printing for your printer.
2656
2657 `setpagedevice' duplex and page size are configured by ps-print using the
2658 setpagedevice PostScript operator.
2659
2660 nil duplex and page size are configured by ps-print *not* using
2661 the setpagedevice PostScript operator.
2662
2663Any other value is treated as nil.
2664
2665WARNING: The setpagedevice PostScript operator affects ghostview utility when
2666 viewing file generated using landscape. Also on some printers,
2667 setpagedevice affects zebra stripes; on other printers, setpagedevice
2668 affects the left margin.
2669 Besides all that, if your printer does not have the paper size
2670 specified by setpagedevice, your printing will be aborted.
2671 So, if you need to use setpagedevice, set `ps-spool-config' to
2672 `setpagedevice', generate a test file and send it to your printer; if
2285bf9d 2673 the printed file isn't OK, set `ps-spool-config' to nil."
8e234846
GM
2674 :type '(choice :menu-tag "Spool Config"
2675 :tag "Spool Config"
bc0d41bd 2676 (const lpr-switches) (const setpagedevice)
edc9cd35 2677 (const :tag "nil" nil))
b6d0ac87 2678 :version "20"
6e1b1da6 2679 :group 'ps-print-headers)
bc0d41bd
KH
2680
2681(defcustom ps-spool-duplex nil ; Not many people have duplex printers,
2682 ; so default to nil.
2683 "*Non-nil generates PostScript for a two-sided printer.
2684For a duplex printer, the `ps-spool-*' and `ps-print-*' commands will insert
2685blank pages as needed between print jobs so that the next buffer printed will
2686start on the right page. Also, if headers are turned on, the headers will be
2687reversed on duplex printers so that the page numbers fall to the left on
0a5daee5
KH
2688even-numbered pages.
2689
2690See also `ps-spool-tumble'."
bc0d41bd 2691 :type 'boolean
b6d0ac87 2692 :version "20"
6e1b1da6 2693 :group 'ps-print-headers)
bc0d41bd
KH
2694
2695(defcustom ps-spool-tumble nil
2696 "*Specify how the page images on opposite sides of a sheet are oriented.
319acba0
GM
2697If `ps-spool-tumble' is nil, produces output suitable for binding on the left
2698or right. If `ps-spool-tumble' is non-nil, produces output suitable for
2699binding at the top or bottom.
bc0d41bd
KH
2700
2701It has effect only when `ps-spool-duplex' is non-nil."
e0af0d3e 2702 :type 'boolean
b6d0ac87 2703 :version "20"
6e1b1da6 2704 :group 'ps-print-headers)
bcc0d457
RS
2705
2706;;; Fonts
2707
e0af0d3e 2708(defcustom ps-font-info-database
bcc0d457 2709 '((Courier ; the family key
12b88fff
RS
2710 (fonts (normal . "Courier")
2711 (bold . "Courier-Bold")
2712 (italic . "Courier-Oblique")
2713 (bold-italic . "Courier-BoldOblique"))
2714 (size . 10.0)
2715 (line-height . 10.55)
2716 (space-width . 6.0)
2717 (avg-char-width . 6.0))
bcc0d457 2718 (Helvetica ; the family key
12b88fff
RS
2719 (fonts (normal . "Helvetica")
2720 (bold . "Helvetica-Bold")
2721 (italic . "Helvetica-Oblique")
2722 (bold-italic . "Helvetica-BoldOblique"))
2723 (size . 10.0)
2724 (line-height . 11.56)
2725 (space-width . 2.78)
2726 (avg-char-width . 5.09243))
bcc0d457 2727 (Times
12b88fff
RS
2728 (fonts (normal . "Times-Roman")
2729 (bold . "Times-Bold")
2730 (italic . "Times-Italic")
2731 (bold-italic . "Times-BoldItalic"))
2732 (size . 10.0)
2733 (line-height . 11.0)
2734 (space-width . 2.5)
334cc3b7 2735 (avg-char-width . 4.71432))
bcc0d457 2736 (Palatino
12b88fff
RS
2737 (fonts (normal . "Palatino-Roman")
2738 (bold . "Palatino-Bold")
2739 (italic . "Palatino-Italic")
2740 (bold-italic . "Palatino-BoldItalic"))
2741 (size . 10.0)
2742 (line-height . 12.1)
2743 (space-width . 2.5)
2744 (avg-char-width . 5.08676))
bcc0d457 2745 (Helvetica-Narrow
12b88fff
RS
2746 (fonts (normal . "Helvetica-Narrow")
2747 (bold . "Helvetica-Narrow-Bold")
2748 (italic . "Helvetica-Narrow-Oblique")
2749 (bold-italic . "Helvetica-Narrow-BoldOblique"))
2750 (size . 10.0)
2751 (line-height . 11.56)
2752 (space-width . 2.2796)
2753 (avg-char-width . 4.17579))
bcc0d457 2754 (NewCenturySchlbk
12b88fff
RS
2755 (fonts (normal . "NewCenturySchlbk-Roman")
2756 (bold . "NewCenturySchlbk-Bold")
2757 (italic . "NewCenturySchlbk-Italic")
2758 (bold-italic . "NewCenturySchlbk-BoldItalic"))
2759 (size . 10.0)
334cc3b7 2760 (line-height . 12.15)
12b88fff
RS
2761 (space-width . 2.78)
2762 (avg-char-width . 5.31162))
bcc0d457
RS
2763 ;; got no bold for the next ones
2764 (AvantGarde-Book
12b88fff
RS
2765 (fonts (normal . "AvantGarde-Book")
2766 (italic . "AvantGarde-BookOblique"))
2767 (size . 10.0)
2768 (line-height . 11.77)
2769 (space-width . 2.77)
2770 (avg-char-width . 5.45189))
bcc0d457 2771 (AvantGarde-Demi
12b88fff
RS
2772 (fonts (normal . "AvantGarde-Demi")
2773 (italic . "AvantGarde-DemiOblique"))
2774 (size . 10.0)
2775 (line-height . 12.72)
2776 (space-width . 2.8)
2777 (avg-char-width . 5.51351))
bcc0d457 2778 (Bookman-Demi
12b88fff
RS
2779 (fonts (normal . "Bookman-Demi")
2780 (italic . "Bookman-DemiItalic"))
2781 (size . 10.0)
2782 (line-height . 11.77)
2783 (space-width . 3.4)
2784 (avg-char-width . 6.05946))
bcc0d457 2785 (Bookman-Light
12b88fff
RS
2786 (fonts (normal . "Bookman-Light")
2787 (italic . "Bookman-LightItalic"))
2788 (size . 10.0)
2789 (line-height . 11.79)
2790 (space-width . 3.2)
2791 (avg-char-width . 5.67027))
bcc0d457
RS
2792 ;; got no bold and no italic for the next ones
2793 (Symbol
12b88fff
RS
2794 (fonts (normal . "Symbol"))
2795 (size . 10.0)
2796 (line-height . 13.03)
2797 (space-width . 2.5)
2798 (avg-char-width . 3.24324))
bcc0d457 2799 (Zapf-Dingbats
12b88fff
RS
2800 (fonts (normal . "Zapf-Dingbats"))
2801 (size . 10.0)
2802 (line-height . 9.63)
2803 (space-width . 2.78)
2804 (avg-char-width . 2.78))
92dc83a9
KH
2805 (ZapfChancery-MediumItalic
2806 (fonts (normal . "ZapfChancery-MediumItalic"))
2807 (size . 10.0)
2808 (line-height . 11.45)
2809 (space-width . 2.2)
2810 (avg-char-width . 4.10811))
2811 ;; We keep this wrong entry name (but with correct font name) for
2812 ;; backward compatibility.
bcc0d457 2813 (Zapf-Chancery-MediumItalic
92dc83a9 2814 (fonts (normal . "ZapfChancery-MediumItalic"))
12b88fff
RS
2815 (size . 10.0)
2816 (line-height . 11.45)
2817 (space-width . 2.2)
2818 (avg-char-width . 4.10811))
87a16a06 2819 )
2285bf9d
RS
2820 "*Font info database.
2821Each element comprises: font family (the key), name, bold, italic, bold-italic,
bcc0d457
RS
2822reference size, line height, space width, average character width.
2823To get the info for another specific font (say Helvetica), do the following:
2824- create a new buffer
2825- generate the PostScript image to a file (C-u M-x ps-print-buffer)
319acba0
GM
2826- open this file and delete the leading `%' (which is the PostScript comment
2827 character) from the line
1fd9b7fe 2828 `% 3 cm 20 cm moveto 10/Courier ReportFontInfo showpage'
bcc0d457 2829 to get the line
1fd9b7fe 2830 `3 cm 20 cm moveto 10/Helvetica ReportFontInfo showpage'
bcc0d457 2831- add the values to `ps-font-info-database'.
c3d6d211
GM
2832You can get all the fonts of YOUR printer using `ReportAllFontInfo'.
2833
319acba0
GM
2834Note also that ps-print DOESN'T download any font to your printer, instead it
2835uses the fonts resident in your printer."
ef1159c2
EZ
2836 :type '(repeat
2837 (list :tag "Font Definition"
2838 (symbol :tag "Font Family")
2839 (cons :format "%v"
2840 (const :format "" fonts)
2841 (repeat :tag "Faces"
2842 (cons (choice :menu-tag "Font Weight/Slant"
2843 :tag "Font Weight/Slant"
2844 (const normal)
2845 (const bold)
2846 (const italic)
2847 (const bold-italic)
2848 (symbol :tag "Face"))
2849 (string :tag "Font Name"))))
2850 (cons :format "%v"
2851 (const :format "" size)
2852 (number :tag "Reference Size"))
2853 (cons :format "%v"
2854 (const :format "" line-height)
2855 (number :tag "Line Height"))
2856 (cons :format "%v"
2857 (const :format "" space-width)
2858 (number :tag "Space Width"))
2859 (cons :format "%v"
2860 (const :format "" avg-char-width)
2861 (number :tag "Average Character Width"))))
b6d0ac87 2862 :version "20"
e0af0d3e
RS
2863 :group 'ps-print-font)
2864
2865(defcustom ps-font-family 'Courier
d3ab8dac 2866 "*Font family name for ordinary text, when generating PostScript."
e0af0d3e 2867 :type 'symbol
b6d0ac87 2868 :version "20"
e0af0d3e
RS
2869 :group 'ps-print-font)
2870
7d8b7e8e 2871(defcustom ps-font-size '(7 . 8.5)
d3ab8dac 2872 "*Font size, in points, for ordinary text, when generating PostScript."
ef1159c2
EZ
2873 :type '(choice :menu-tag "Ordinary Text Font Size"
2874 :tag "Ordinary Text Font Size"
2875 (number :tag "Text Size")
7d8b7e8e
KH
2876 (cons :tag "Landscape/Portrait"
2877 (number :tag "Landscape Text Size")
2878 (number :tag "Portrait Text Size")))
b6d0ac87 2879 :version "20"
e0af0d3e
RS
2880 :group 'ps-print-font)
2881
2882(defcustom ps-header-font-family 'Helvetica
d3ab8dac 2883 "*Font family name for text in the header, when generating PostScript."
e0af0d3e 2884 :type 'symbol
b6d0ac87 2885 :version "20"
e0af0d3e
RS
2886 :group 'ps-print-font)
2887
7d8b7e8e 2888(defcustom ps-header-font-size '(10 . 12)
d3ab8dac 2889 "*Font size, in points, for text in the header, when generating PostScript."
ef1159c2
EZ
2890 :type '(choice :menu-tag "Header Font Size"
2891 :tag "Header Font Size"
2892 (number :tag "Header Size")
7d8b7e8e
KH
2893 (cons :tag "Landscape/Portrait"
2894 (number :tag "Landscape Header Size")
2895 (number :tag "Portrait Header Size")))
b6d0ac87 2896 :version "20"
e0af0d3e
RS
2897 :group 'ps-print-font)
2898
7d8b7e8e 2899(defcustom ps-header-title-font-size '(12 . 14)
d3ab8dac 2900 "*Font size, in points, for the top line of text in header, in PostScript."
ef1159c2
EZ
2901 :type '(choice :menu-tag "Header Title Font Size"
2902 :tag "Header Title Font Size"
2903 (number :tag "Header Title Size")
7d8b7e8e
KH
2904 (cons :tag "Landscape/Portrait"
2905 (number :tag "Landscape Header Title Size")
2906 (number :tag "Portrait Header Title Size")))
b6d0ac87 2907 :version "20"
e0af0d3e 2908 :group 'ps-print-font)
bcc0d457 2909
319acba0
GM
2910(defcustom ps-footer-font-family 'Helvetica
2911 "*Font family name for text in the footer, when generating PostScript."
319acba0 2912 :type 'symbol
b6d0ac87 2913 :version "21.1"
319acba0
GM
2914 :group 'ps-print-font)
2915
2916(defcustom ps-footer-font-size '(10 . 12)
2917 "*Font size, in points, for text in the footer, when generating PostScript."
319acba0
GM
2918 :type '(choice :menu-tag "Footer Font Size"
2919 :tag "Footer Font Size"
2920 (number :tag "Footer Size")
2921 (cons :tag "Landscape/Portrait"
2922 (number :tag "Landscape Footer Size")
2923 (number :tag "Portrait Footer Size")))
b6d0ac87 2924 :version "21.1"
319acba0
GM
2925 :group 'ps-print-font)
2926
2927(defcustom ps-line-number-color "black"
2928 "*Specify color for line-number, when generating PostScript."
2929 :type '(choice :menu-tag "Line Number Color"
2930 :tag "Line Number Color"
2931 (number :tag "Gray Scale" :value 0)
2932 (string :tag "Color Name" :value "black")
2933 (list :tag "RGB Color" :value (0 0 0)
2934 (number :tag "Red")
2935 (number :tag "Green")
2936 (number :tag "Blue")))
2937 :version "21.1"
2938 :group 'ps-print-font
2939 :group 'ps-print-miscellany)
2940
ef1159c2
EZ
2941(defcustom ps-line-number-font "Times-Italic"
2942 "*Font for line-number, when generating PostScript."
2943 :type 'string
b6d0ac87 2944 :version "20"
ef1159c2
EZ
2945 :group 'ps-print-font
2946 :group 'ps-print-miscellany)
2947
2948(defcustom ps-line-number-font-size 6
2949 "*Font size, in points, for line number, when generating PostScript."
2950 :type '(choice :menu-tag "Line Number Font Size"
2951 :tag "Line Number Font Size"
2952 (number :tag "Font Size")
2953 (cons :tag "Landscape/Portrait"
2954 (number :tag "Landscape Font Size")
2955 (number :tag "Portrait Font Size")))
b6d0ac87 2956 :version "20"
ef1159c2
EZ
2957 :group 'ps-print-font
2958 :group 'ps-print-miscellany)
2959
bcc0d457
RS
2960;;; Colors
2961
87a16a06 2962;; Printing color requires x-color-values.
c90a10fa
RS
2963;; XEmacs change: Need autoload for the "Options->Printing->Color Printing"
2964;; widget to work.
2965;;;###autoload
ea0c615d 2966(defcustom ps-print-color-p
509b4dbc 2967 (or (fboundp 'x-color-values) ; Emacs
ea0c615d 2968 (fboundp 'color-instance-rgb-components))
857686a6 2969 ; XEmacs
55732434
GM
2970 "*Specify how buffer's text color is printed.
2971
2972Valid values are:
2973
2974 nil Do not print colors.
2975
2976 t Print colors.
2977
2978 black-white Print colors on black/white printer.
2979 See also `ps-black-white-faces'.
2980
2981Any other value is treated as t."
2982 :type '(choice :menu-tag "Print Color"
2983 :tag "Print Color"
2984 (const :tag "Do NOT Print Color" nil)
2985 (const :tag "Print Always Color" t)
2986 (const :tag "Print Black/White Color" black-white))
b6d0ac87 2987 :version "20"
e0af0d3e 2988 :group 'ps-print-color)
12d89a2e 2989
3f0257cb 2990(defcustom ps-default-fg nil
c1a1c994 2991 "*RGB values of the default foreground color.
e59d29d6
VJL
2992
2993The `ps-default-fg' variable contains the default foreground color used by
2994ps-print, that is, if there is a face in a text that doesn't have a foreground
2995color, the `ps-default-fg' color should be used.
2996
2997Valid values are:
2998
2999 t The foreground color of Emacs session will be used.
3000
c1a1c994
VJL
3001 frame-parameter The foreground-color frame parameter will be used.
3002
e59d29d6
VJL
3003 NUMBER It's a real value between 0.0 (black) and 1.0 (white) that
3004 indicate the gray color.
3005
640477ee 3006 COLOR-NAME It's a string which contains the color name. For example:
e59d29d6
VJL
3007 \"yellow\".
3008
3009 LIST It's a list of RGB values, that is a list of three real values
3010 of the form:
3011
3012 (RED, GREEN, BLUE)
3013
3014 Where RED, GREEN and BLUE are reals between 0.0 (no color) and
3015 1.0 (full color).
3016
c1a1c994 3017Any other value is ignored and black color will be used.
e59d29d6
VJL
3018
3019It's used only when `ps-print-color-p' is non-nil."
8e234846
GM
3020 :type '(choice :menu-tag "Default Foreground Gray/Color"
3021 :tag "Default Foreground Gray/Color"
c794a94d 3022 (const :tag "Session Foreground" t)
c1a1c994 3023 (const :tag "Frame Foreground" frame-parameter)
6e1b1da6
GM
3024 (number :tag "Gray Scale" :value 0.0)
3025 (string :tag "Color Name" :value "black")
3026 (list :tag "RGB Color" :value (0.0 0.0 0.0)
3027 (number :tag "Red")
3028 (number :tag "Green")
3029 (number :tag "Blue")))
b6d0ac87 3030 :version "20"
e0af0d3e 3031 :group 'ps-print-color)
12d89a2e 3032
3f0257cb 3033(defcustom ps-default-bg nil
c1a1c994 3034 "*RGB values of the default background color.
e59d29d6
VJL
3035
3036The `ps-default-bg' variable contains the default background color used by
3037ps-print, that is, if there is a face in a text that doesn't have a background
3038color, the `ps-default-bg' color should be used.
3039
3040Valid values are:
3041
3042 t The background color of Emacs session will be used.
3043
c1a1c994
VJL
3044 frame-parameter The background-color frame parameter will be used.
3045
e59d29d6
VJL
3046 NUMBER It's a real value between 0.0 (black) and 1.0 (white) that
3047 indicate the gray color.
3048
640477ee 3049 COLOR-NAME It's a string which contains the color name. For example:
e59d29d6
VJL
3050 \"yellow\".
3051
3052 LIST It's a list of RGB values, that is a list of three real values
3053 of the form:
3054
3055 (RED, GREEN, BLUE)
3056
3057 Where RED, GREEN and BLUE are reals between 0.0 (no color) and
3058 1.0 (full color).
3059
c1a1c994 3060Any other value is ignored and white color will be used.
e59d29d6
VJL
3061
3062It's used only when `ps-print-color-p' is non-nil.
3063
3064See also `ps-use-face-background'."
8e234846
GM
3065 :type '(choice :menu-tag "Default Background Gray/Color"
3066 :tag "Default Background Gray/Color"
c794a94d 3067 (const :tag "Session Background" t)
c1a1c994 3068 (const :tag "Frame Background" frame-parameter)
6e1b1da6
GM
3069 (number :tag "Gray Scale" :value 1.0)
3070 (string :tag "Color Name" :value "white")
3071 (list :tag "RGB Color" :value (1.0 1.0 1.0)
3072 (number :tag "Red")
3073 (number :tag "Green")
3074 (number :tag "Blue")))
b6d0ac87 3075 :version "20"
e0af0d3e 3076 :group 'ps-print-color)
12d89a2e 3077
e0af0d3e 3078(defcustom ps-auto-font-detect t
df5e6194 3079 "*Non-nil means automatically detect bold/italic/underline face attributes.
319acba0
GM
3080If nil, we rely solely on the lists `ps-bold-faces', `ps-italic-faces', and
3081`ps-underlined-faces'."
e0af0d3e 3082 :type 'boolean
b6d0ac87 3083 :version "20"
e0af0d3e 3084 :group 'ps-print-font)
12d89a2e 3085
55732434
GM
3086(defcustom ps-black-white-faces
3087 '((font-lock-builtin-face "black" nil bold )
3088 (font-lock-comment-face "gray20" nil italic)
3089 (font-lock-constant-face "black" nil bold )
3090 (font-lock-function-name-face "black" nil bold )
3091 (font-lock-keyword-face "black" nil bold )
3092 (font-lock-string-face "black" nil italic)
3093 (font-lock-type-face "black" nil italic)
3094 (font-lock-variable-name-face "black" nil bold italic)
3095 (font-lock-warning-face "black" nil bold italic))
3096 "*Specify list of face attributes to print colors on black/white printers.
3097
3098The list elements are the same as defined on `ps-extend-face' (which see).
3099
3100This variable is used only when `ps-print-color-p' is set to `black-white'."
3101 :version "21.1"
3102 :type '(repeat
3103 (list :tag "Face Specification"
3104 (face :tag "Face Symbol")
3105 (choice :menu-tag "Foreground Color"
3106 :tag "Foreground Color"
3107 (const :tag "Black" nil)
3108 (string :tag "Color Name"))
3109 (choice :menu-tag "Background Color"
3110 :tag "Background Color"
3111 (const :tag "None" nil)
3112 (string :tag "Color Name"))
3113 (repeat :inline t
3114 (choice :menu-tag "Attribute"
3115 (const bold)
3116 (const italic)
3117 (const underline)
3118 (const strikeout)
3119 (const overline)
3120 (const shadow)
3121 (const box)
3122 (const outline)))))
b6d0ac87 3123 :version "20"
55732434
GM
3124 :group 'ps-print-face)
3125
e0af0d3e 3126(defcustom ps-bold-faces
090be653
RS
3127 (unless ps-print-color-p
3128 '(font-lock-function-name-face
3129 font-lock-builtin-face
3130 font-lock-variable-name-face
3131 font-lock-keyword-face
3132 font-lock-warning-face))
86c10ecb 3133 "*A list of the \(non-bold\) faces that should be printed in bold font.
8bd22fcf 3134This applies to generating PostScript."
e0af0d3e 3135 :type '(repeat face)
b6d0ac87 3136 :version "20"
e0af0d3e 3137 :group 'ps-print-face)
12d89a2e 3138
e0af0d3e 3139(defcustom ps-italic-faces
090be653
RS
3140 (unless ps-print-color-p
3141 '(font-lock-variable-name-face
8bd22fcf 3142 font-lock-type-face
090be653
RS
3143 font-lock-string-face
3144 font-lock-comment-face
3145 font-lock-warning-face))
86c10ecb 3146 "*A list of the \(non-italic\) faces that should be printed in italic font.
8bd22fcf 3147This applies to generating PostScript."
e0af0d3e 3148 :type '(repeat face)
b6d0ac87 3149 :version "20"
e0af0d3e 3150 :group 'ps-print-face)
12d89a2e 3151
e0af0d3e 3152(defcustom ps-underlined-faces
090be653
RS
3153 (unless ps-print-color-p
3154 '(font-lock-function-name-face
883212ce 3155 font-lock-constant-face
090be653 3156 font-lock-warning-face))
86c10ecb 3157 "*A list of the \(non-underlined\) faces that should be printed underlined.
8bd22fcf 3158This applies to generating PostScript."
e0af0d3e 3159 :type '(repeat face)
b6d0ac87 3160 :version "20"
e0af0d3e 3161 :group 'ps-print-face)
12d89a2e 3162
906d41a7
GM
3163(defcustom ps-use-face-background nil
3164 "*Specify if face background should be used.
3165
3166Valid values are:
3167
3168 t always use face background color.
3169 nil never use face background color.
3170 (face...) list of faces whose background color will be used.
3171
3172Any other value will be treated as t."
8e234846
GM
3173 :type '(choice :menu-tag "Use Face Background"
3174 :tag "Use Face Background"
906d41a7
GM
3175 (const :tag "Always Use Face Background" t)
3176 (const :tag "Never Use Face Background" nil)
3177 (repeat :menu-tag "Face Background List"
3178 :tag "Face Background List"
3179 face))
b6d0ac87 3180 :version "20"
906d41a7
GM
3181 :group 'ps-print-face)
3182
e0af0d3e 3183(defcustom ps-left-header
12d89a2e 3184 (list 'ps-get-buffer-name 'ps-header-dirpart)
bcc0d457 3185 "*The items to display (each on a line) on the left part of the page header.
8bd22fcf 3186This applies to generating PostScript.
12d89a2e 3187
319acba0
GM
3188The value should be a list of strings and symbols, each representing an entry
3189in the PostScript array HeaderLinesLeft.
12d89a2e
RS
3190
3191Strings are inserted unchanged into the array; those representing
3192PostScript string literals should be delimited with PostScript string
3193delimiters '(' and ')'.
3194
319acba0
GM
3195For symbols with bound functions, the function is called and should return a
3196string to be inserted into the array. For symbols with bound values, the value
3197should be a string to be inserted into the array. In either case, function or
71efd3c4
VJL
3198variable, the string value has PostScript string delimiters added to it.
3199
3200If symbols are unbounded, they are silently ignored."
ef1159c2
EZ
3201 :type '(repeat (choice :menu-tag "Left Header"
3202 :tag "Left Header"
3203 string symbol))
b6d0ac87 3204 :version "20"
6e1b1da6 3205 :group 'ps-print-headers)
12d89a2e 3206
e0af0d3e 3207(defcustom ps-right-header
2bd80d73 3208 (list "/pagenumberstring load"
4b81a999 3209 'ps-time-stamp-locale-default 'ps-time-stamp-hh:mm:ss)
bcc0d457 3210 "*The items to display (each on a line) on the right part of the page header.
8bd22fcf 3211This applies to generating PostScript.
12d89a2e 3212
319acba0 3213See the variable `ps-left-header' for a description of the format of this
4b81a999
GM
3214variable.
3215
3216There are the following basic functions implemented:
3217
3218 `ps-time-stamp-locale-default' Return the locale's \"preferred\" date
3219 as, for example, \"06/18/01\".
3220
3221 `ps-time-stamp-hh:mm:ss' Return time as \"17:28:31\".
3222
3223 `ps-time-stamp-mon-dd-yyyy' Return date as \"Jun 18 2001\".
3224
71efd3c4
VJL
3225 `ps-time-stamp-yyyy-mm-dd' Return date as \"2001-06-18\" (ISO
3226 date).
3227
3228 `ps-time-stamp-iso8601' Alias for `ps-time-stamp-yyyy-mm-dd'.
3229
4b81a999 3230You can also create your own time stamp function by using `format-time-string'
2285bf9d 3231\(which see)."
ef1159c2
EZ
3232 :type '(repeat (choice :menu-tag "Right Header"
3233 :tag "Right Header"
3234 string symbol))
b6d0ac87 3235 :version "20"
6e1b1da6 3236 :group 'ps-print-headers)
ef2cbb24 3237
319acba0
GM
3238(defcustom ps-left-footer
3239 (list 'ps-get-buffer-name 'ps-header-dirpart)
3240 "*The items to display (each on a line) on the left part of the page footer.
3241This applies to generating PostScript.
3242
3243The value should be a list of strings and symbols, each representing an entry
3244in the PostScript array FooterLinesLeft.
3245
3246Strings are inserted unchanged into the array; those representing PostScript
3247string literals should be delimited with PostScript string delimiters '(' and
3248')'.
3249
3250For symbols with bound functions, the function is called and should return a
3251string to be inserted into the array. For symbols with bound values, the value
3252should be a string to be inserted into the array. In either case, function or
71efd3c4
VJL
3253variable, the string value has PostScript string delimiters added to it.
3254
3255If symbols are unbounded, they are silently ignored."
319acba0
GM
3256 :type '(repeat (choice :menu-tag "Left Footer"
3257 :tag "Left Footer"
3258 string symbol))
b6d0ac87 3259 :version "21.1"
319acba0
GM
3260 :group 'ps-print-headers)
3261
3262(defcustom ps-right-footer
3263 (list "/pagenumberstring load"
4b81a999 3264 'ps-time-stamp-locale-default 'ps-time-stamp-hh:mm:ss)
319acba0
GM
3265 "*The items to display (each on a line) on the right part of the page footer.
3266This applies to generating PostScript.
3267
3268See the variable `ps-left-footer' for a description of the format of this
4b81a999
GM
3269variable.
3270
3271There are the following basic functions implemented:
3272
3273 `ps-time-stamp-locale-default' Return the locale's \"preferred\" date
3274 as, for example, \"06/18/01\".
3275
3276 `ps-time-stamp-hh:mm:ss' Return time as \"17:28:31\".
3277
3278 `ps-time-stamp-mon-dd-yyyy' Return date as \"Jun 18 2001\".
3279
71efd3c4
VJL
3280 `ps-time-stamp-yyyy-mm-dd' Return date as \"2001-06-18\" (ISO
3281 date).
3282
3283 `ps-time-stamp-iso8601' Alias for `ps-time-stamp-yyyy-mm-dd'.
3284
4b81a999 3285You can also create your own time stamp function by using `format-time-string'
2285bf9d 3286\(which see)."
319acba0
GM
3287 :type '(repeat (choice :menu-tag "Right Footer"
3288 :tag "Right Footer"
3289 string symbol))
b6d0ac87 3290 :version "21.1"
319acba0
GM
3291 :group 'ps-print-headers)
3292
e0af0d3e
RS
3293(defcustom ps-razzle-dazzle t
3294 "*Non-nil means report progress while formatting buffer."
3295 :type 'boolean
b6d0ac87 3296 :version "20"
6e1b1da6 3297 :group 'ps-print-miscellany)
12d89a2e 3298
a18ed129 3299(defcustom ps-adobe-tag "%!PS-Adobe-3.0\n"
12d89a2e 3300 "*Contains the header line identifying the output as PostScript.
319acba0
GM
3301By default, `ps-adobe-tag' contains the standard identifier. Some printers
3302require slightly different versions of this line."
a18ed129 3303 :type 'string
b6d0ac87 3304 :version "20"
6e1b1da6 3305 :group 'ps-print-miscellany)
12d89a2e 3306
e0af0d3e 3307(defcustom ps-build-face-reference t
12d89a2e
RS
3308 "*Non-nil means build the reference face lists.
3309
319acba0 3310ps-print sets this value to nil after it builds its internal reference lists of
1b1200a1 3311bold and italic faces. By setting its value back to t, you can force ps-print
319acba0
GM
3312to rebuild the lists the next time you invoke one of the ...-with-faces
3313commands.
12d89a2e 3314
319acba0
GM
3315You should set this value back to t after you change the attributes of any
3316face, or create new faces. Most users shouldn't have to worry about its
3317setting, though."
e0af0d3e 3318 :type 'boolean
b6d0ac87 3319 :version "20"
e0af0d3e 3320 :group 'ps-print-face)
12d89a2e 3321
e0af0d3e 3322(defcustom ps-always-build-face-reference nil
12d89a2e
RS
3323 "*Non-nil means always rebuild the reference face lists.
3324
319acba0
GM
3325If this variable is non-nil, ps-print will rebuild its internal reference lists
3326of bold and italic faces *every* time one of the ...-with-faces commands is
3327called. Most users shouldn't need to set this variable."
e0af0d3e 3328 :type 'boolean
b6d0ac87 3329 :version "20"
e0af0d3e 3330 :group 'ps-print-face)
ef2cbb24 3331
bc0d41bd
KH
3332(defcustom ps-banner-page-when-duplexing nil
3333 "*Non-nil means the very first page is skipped.
3334It's like the very first character of buffer (or region) is ^L (\\014)."
3335 :type 'boolean
b6d0ac87 3336 :version "20"
6e1b1da6 3337 :group 'ps-print-headers)
bc0d41bd 3338
98f2fbe7 3339(defcustom ps-postscript-code-directory
b6d0ac87 3340 (or (if (featurep 'xemacs)
073238d6 3341 (cond ((fboundp 'locate-data-directory) ; XEmacs
b6d0ac87 3342 (locate-data-directory "ps-print"))
073238d6 3343 ((boundp 'data-directory) ; XEmacs
b6d0ac87
VJL
3344 data-directory)
3345 (t ; don't know what to do
3346 nil))
073238d6 3347 data-directory) ; Emacs
eafa92bf 3348 (error "`ps-postscript-code-directory' isn't set properly"))
41481e4b
KH
3349 "*Directory where it's located the PostScript prologue file used by ps-print.
3350By default, this directory is the same as in the variable `data-directory'."
3351 :type 'directory
b6d0ac87 3352 :version "20"
6e1b1da6 3353 :group 'ps-print-miscellany)
41481e4b 3354
6bf5fb46
GM
3355(defcustom ps-line-spacing 0
3356 "*Specify line spacing, in points, for ordinary text.
3357
3358See also `ps-paragraph-spacing' and `ps-paragraph-regexp'.
3359
3360To get all lines with some spacing set both `ps-line-spacing' and
3361`ps-paragraph-spacing' variables."
3362 :type '(choice :menu-tag "Line Spacing For Ordinary Text"
3363 :tag "Line Spacing For Ordinary Text"
3364 (number :tag "Line Spacing")
3365 (cons :tag "Landscape/Portrait"
3366 (number :tag "Landscape Line Spacing")
3367 (number :tag "Portrait Line Spacing")))
3368 :version "21.1"
3369 :group 'ps-print-miscellany)
3370
3371(defcustom ps-paragraph-spacing 0
3372 "*Specify paragraph spacing, in points, for ordinary text.
3373
3374See also `ps-line-spacing' and `ps-paragraph-regexp'.
3375
3376To get all lines with some spacing set both `ps-line-spacing' and
3377`ps-paragraph-spacing' variables."
3378 :type '(choice :menu-tag "Paragraph Spacing For Ordinary Text"
3379 :tag "Paragraph Spacing For Ordinary Text"
3380 (number :tag "Paragraph Spacing")
3381 (cons :tag "Landscape/Portrait"
3382 (number :tag "Landscape Paragraph Spacing")
3383 (number :tag "Portrait Paragraph Spacing")))
3384 :version "21.1"
3385 :group 'ps-print-miscellany)
3386
3387(defcustom ps-paragraph-regexp "[ \t]*$"
3388 "*Specify paragraph delimiter.
3389
3390It should be a regexp or nil.
3391
3392See also `ps-paragraph-spacing'."
3393 :type '(choice :menu-tag "Paragraph Delimiter"
3394 (const :tag "No Delimiter" nil)
3395 (regexp :tag "Delimiter Regexp"))
3396 :version "21.1"
3397 :group 'ps-print-miscellany)
3398
3399(defcustom ps-begin-cut-regexp nil
3400 "*Specify regexp which is start of a region to cut out when printing.
3401
3402As an example, variables `ps-begin-cut-regexp' and `ps-end-cut-regexp' may be
3403set to \"^Local Variables:\" and \"^End:\", respectively, in order to leave out
3404some special printing instructions from the actual print. Special printing
3405instructions may be appended to the end of the file just like any other
3406buffer-local variables. See section \"Local Variables in Files\" on Emacs
3407manual for more information.
3408
3409Variables `ps-begin-cut-regexp' and `ps-end-cut-regexp' control together what
3410actually gets printed. Both variables may be set to nil in which case no
3411cutting occurs."
bf29d4c1
MR
3412 :type '(choice (const :tag "No Delimiter" nil)
3413 (regexp :tag "Delimiter Regexp"))
6bf5fb46
GM
3414 :version "21.1"
3415 :group 'ps-print-miscellany)
3416
3417(defcustom ps-end-cut-regexp nil
3418 "*Specify regexp which is end of the region to cut out when printing.
3419
3420See `ps-begin-cut-regexp' for more information."
bf29d4c1
MR
3421 :type '(choice (const :tag "No Delimiter" nil)
3422 (regexp :tag "Delimiter Regexp"))
6bf5fb46
GM
3423 :version "21.1"
3424 :group 'ps-print-miscellany)
3425
0a5daee5 3426
1fd9b7fe
GM
3427;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3428;; Selected Pages
3429
3430
3431(defvar ps-last-selected-pages nil
3432 "Latest `ps-selected-pages' value.")
3433
3434
3435(defun ps-restore-selected-pages ()
3436 "Restore latest `ps-selected-pages' value."
3437 (interactive)
3438 (setq ps-selected-pages ps-last-selected-pages))
3439
3440
0a5daee5
KH
3441;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3442;; Customization
3443
3444
3445;;;###autoload
3446(defun ps-print-customize ()
3447 "Customization of ps-print group."
3448 (interactive)
3449 (customize-group 'ps-print))
3450
3451
ef2cbb24 3452;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e 3453;; User commands
ef2cbb24 3454
0a5daee5 3455
00aa16af 3456;;;###autoload
ef2cbb24 3457(defun ps-print-buffer (&optional filename)
12d89a2e 3458 "Generate and print a PostScript image of the buffer.
ef2cbb24 3459
2285bf9d 3460Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
319acba0
GM
3461user for a file name, and saves the PostScript image in that file instead of
3462sending it to the printer.
ef2cbb24 3463
319acba0
GM
3464Noninteractively, the argument FILENAME is treated as follows: if it is nil,
3465send the image to the printer. If FILENAME is a string, save the PostScript
3466image in a file with that name."
00aa16af 3467 (interactive (list (ps-print-preprint current-prefix-arg)))
87a16a06 3468 (ps-print-without-faces (point-min) (point-max) filename))
ef2cbb24
RS
3469
3470
00aa16af 3471;;;###autoload
ef2cbb24 3472(defun ps-print-buffer-with-faces (&optional filename)
12d89a2e 3473 "Generate and print a PostScript image of the buffer.
319acba0
GM
3474Like `ps-print-buffer', but includes font, color, and underline information in
3475the generated image. This command works only if you are using a window system,
3476so it has a way to determine color values."
00aa16af 3477 (interactive (list (ps-print-preprint current-prefix-arg)))
87a16a06 3478 (ps-print-with-faces (point-min) (point-max) filename))
ef2cbb24 3479
ef2cbb24 3480
00aa16af 3481;;;###autoload
ef2cbb24 3482(defun ps-print-region (from to &optional filename)
12d89a2e 3483 "Generate and print a PostScript image of the region.
12d89a2e 3484Like `ps-print-buffer', but prints just the current region."
55732434 3485 (interactive (ps-print-preprint-region current-prefix-arg))
a18ed129 3486 (ps-print-without-faces from to filename t))
ef2cbb24 3487
ef2cbb24 3488
00aa16af 3489;;;###autoload
ef2cbb24 3490(defun ps-print-region-with-faces (from to &optional filename)
12d89a2e 3491 "Generate and print a PostScript image of the region.
319acba0
GM
3492Like `ps-print-region', but includes font, color, and underline information in
3493the generated image. This command works only if you are using a window system,
3494so it has a way to determine color values."
55732434 3495 (interactive (ps-print-preprint-region current-prefix-arg))
a18ed129 3496 (ps-print-with-faces from to filename t))
ef2cbb24 3497
ef2cbb24 3498
00aa16af 3499;;;###autoload
ef2cbb24 3500(defun ps-spool-buffer ()
12d89a2e 3501 "Generate and spool a PostScript image of the buffer.
319acba0
GM
3502Like `ps-print-buffer' except that the PostScript image is saved in a local
3503buffer to be sent to the printer later.
ef2cbb24 3504
12d89a2e 3505Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 3506 (interactive)
87a16a06 3507 (ps-spool-without-faces (point-min) (point-max)))
ef2cbb24 3508
ef2cbb24 3509
00aa16af 3510;;;###autoload
ef2cbb24 3511(defun ps-spool-buffer-with-faces ()
12d89a2e 3512 "Generate and spool a PostScript image of the buffer.
319acba0
GM
3513Like `ps-spool-buffer', but includes font, color, and underline information in
3514the generated image. This command works only if you are using a window system,
3515so it has a way to determine color values.
ef2cbb24 3516
12d89a2e 3517Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 3518 (interactive)
87a16a06 3519 (ps-spool-with-faces (point-min) (point-max)))
ef2cbb24 3520
ef2cbb24 3521
00aa16af 3522;;;###autoload
ef2cbb24 3523(defun ps-spool-region (from to)
12d89a2e 3524 "Generate a PostScript image of the region and spool locally.
12d89a2e 3525Like `ps-spool-buffer', but spools just the current region.
ef2cbb24 3526
12d89a2e 3527Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 3528 (interactive "r")
a18ed129 3529 (ps-spool-without-faces from to t))
ef2cbb24 3530
ef2cbb24 3531
00aa16af 3532;;;###autoload
ef2cbb24 3533(defun ps-spool-region-with-faces (from to)
12d89a2e 3534 "Generate a PostScript image of the region and spool locally.
319acba0
GM
3535Like `ps-spool-region', but includes font, color, and underline information in
3536the generated image. This command works only if you are using a window system,
3537so it has a way to determine color values.
ef2cbb24 3538
12d89a2e 3539Use the command `ps-despool' to send the spooled images to the printer."
ef2cbb24 3540 (interactive "r")
a18ed129 3541 (ps-spool-with-faces from to t))
ef2cbb24 3542
00aa16af 3543;;;###autoload
ef2cbb24
RS
3544(defun ps-despool (&optional filename)
3545 "Send the spooled PostScript to the printer.
3546
2285bf9d 3547Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
319acba0
GM
3548user for a file name, and saves the spooled PostScript image in that file
3549instead of sending it to the printer.
ef2cbb24 3550
319acba0
GM
3551Noninteractively, the argument FILENAME is treated as follows: if it is nil,
3552send the image to the printer. If FILENAME is a string, save the PostScript
3553image in a file with that name."
00aa16af
RS
3554 (interactive (list (ps-print-preprint current-prefix-arg)))
3555 (ps-do-despool filename))
12d89a2e 3556
bcc0d457
RS
3557;;;###autoload
3558(defun ps-line-lengths ()
2285bf9d
RS
3559 "Display the correspondence between a line length and a font size.
3560Done using the current ps-print setup.
bcc0d457
RS
3561Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
3562 (interactive)
3563 (ps-line-lengths-internal))
3564
3565;;;###autoload
3566(defun ps-nb-pages-buffer (nb-lines)
06fb6aab
RS
3567 "Display number of pages to print this buffer, for various font heights.
3568The table depends on the current ps-print setup."
55732434 3569 (interactive (ps-count-lines-preprint (point-min) (point-max)))
bcc0d457
RS
3570 (ps-nb-pages nb-lines))
3571
3572;;;###autoload
3573(defun ps-nb-pages-region (nb-lines)
06fb6aab
RS
3574 "Display number of pages to print the region, for various font heights.
3575The table depends on the current ps-print setup."
55732434 3576 (interactive (ps-count-lines-preprint (mark) (point)))
bcc0d457
RS
3577 (ps-nb-pages nb-lines))
3578
c86f4619
GM
3579(defvar ps-prefix-quote nil
3580 "Used for `ps-print-quote' (which see).")
efa89c1f 3581
bcc0d457
RS
3582;;;###autoload
3583(defun ps-setup ()
496725ad 3584 "Return the current PostScript-generation setup."
efa89c1f 3585 (let (ps-prefix-quote)
319acba0 3586 (mapconcat
efa89c1f 3587 #'ps-print-quote
319acba0 3588 (list
d3241651
VJL
3589 (concat "\n;;; (" (if (featurep 'xemacs) "XEmacs" "Emacs")
3590 ") ps-print version " ps-print-version "\n")
208ccc30 3591 ";; internal vars"
d3241651
VJL
3592 (ps-comment-string "emacs-version " emacs-version)
3593 (ps-comment-string "ps-windows-system " ps-windows-system)
3594 (ps-comment-string "ps-lp-system " ps-lp-system)
208ccc30 3595 nil
319acba0
GM
3596 '(25 . ps-print-color-p)
3597 '(25 . ps-lpr-command)
3598 '(25 . ps-lpr-switches)
3599 '(25 . ps-printer-name)
3600 '(25 . ps-printer-name-option)
3601 '(25 . ps-print-region-function)
3602 '(25 . ps-manual-feed)
3603 '(25 . ps-end-with-control-d)
3604 nil
3605 '(23 . ps-paper-type)
3606 '(23 . ps-warn-paper-type)
3607 '(23 . ps-landscape-mode)
3608 '(23 . ps-print-upside-down)
3609 '(23 . ps-number-of-columns)
3610 nil
3611 '(23 . ps-zebra-stripes)
3612 '(23 . ps-zebra-stripe-height)
3613 '(23 . ps-zebra-stripe-follow)
3614 '(23 . ps-zebra-color)
3615 '(23 . ps-line-number)
3616 '(23 . ps-line-number-step)
3617 '(23 . ps-line-number-start)
3618 nil
3619 '(17 . ps-default-fg)
3620 '(17 . ps-default-bg)
3621 '(17 . ps-razzle-dazzle)
3622 nil
3623 '(23 . ps-use-face-background)
3624 nil
3625 '(28 . ps-print-control-characters)
3626 nil
3627 '(26 . ps-print-background-image)
3628 nil
3629 '(25 . ps-print-background-text)
3630 nil
3631 '(29 . ps-error-handler-message)
3632 '(29 . ps-user-defined-prologue)
3633 '(29 . ps-print-prologue-header)
3634 '(29 . ps-postscript-code-directory)
3635 '(29 . ps-adobe-tag)
3636 nil
3637 '(30 . ps-left-margin)
3638 '(30 . ps-right-margin)
3639 '(30 . ps-inter-column)
3640 '(30 . ps-bottom-margin)
3641 '(30 . ps-top-margin)
3642 '(30 . ps-print-only-one-header)
3643 '(30 . ps-switch-header)
3644 '(30 . ps-print-header)
3645 '(30 . ps-header-lines)
3646 '(30 . ps-header-offset)
3647 '(30 . ps-header-line-pad)
3648 '(30 . ps-print-header-frame)
3649 '(30 . ps-header-frame-alist)
3650 '(30 . ps-print-footer)
3651 '(30 . ps-footer-lines)
3652 '(30 . ps-footer-offset)
3653 '(30 . ps-footer-line-pad)
3654 '(30 . ps-print-footer-frame)
3655 '(30 . ps-footer-frame-alist)
3656 '(30 . ps-show-n-of-n)
3657 '(30 . ps-spool-config)
3658 '(30 . ps-spool-duplex)
3659 '(30 . ps-spool-tumble)
3660 '(30 . ps-banner-page-when-duplexing)
3661 '(30 . ps-left-header)
3662 '(30 . ps-right-header)
3663 '(30 . ps-left-footer)
3664 '(30 . ps-right-footer)
3665 nil
3666 '(23 . ps-n-up-printing)
3667 '(23 . ps-n-up-margin)
3668 '(23 . ps-n-up-border-p)
3669 '(23 . ps-n-up-filling)
3670 nil
3671 '(26 . ps-multibyte-buffer)
3672 '(26 . ps-font-family)
3673 '(26 . ps-font-size)
3674 '(26 . ps-header-font-family)
3675 '(26 . ps-header-font-size)
3676 '(26 . ps-header-title-font-size)
3677 '(26 . ps-footer-font-family)
3678 '(26 . ps-footer-font-size)
3679 '(26 . ps-line-number-color)
3680 '(26 . ps-line-number-font)
3681 '(26 . ps-line-number-font-size)
3682 '(26 . ps-line-spacing)
3683 '(26 . ps-paragraph-spacing)
3684 '(26 . ps-paragraph-regexp)
3685 '(26 . ps-begin-cut-regexp)
3686 '(26 . ps-end-cut-regexp)
3687 nil
3688 '(23 . ps-even-or-odd-pages)
3689 '(23 . ps-selected-pages)
3690 '(23 . ps-last-selected-pages)
3691 nil
3692 '(31 . ps-build-face-reference)
3693 '(31 . ps-always-build-face-reference)
3694 nil
3695 '(20 . ps-auto-font-detect)
3696 '(20 . ps-bold-faces)
3697 '(20 . ps-italic-faces)
3698 '(20 . ps-underlined-faces)
55732434 3699 '(20 . ps-black-white-faces)
c86f4619 3700 " )\n
bd7a2e26
GM
3701;; The following customized variables have long lists and are seldom modified:
3702;; ps-page-dimensions-database
3703;; ps-font-info-database
1fd9b7fe 3704
231f3e66 3705\;;; ps-print - end of settings\n")
319acba0 3706 "\n")))
bcc0d457 3707
0a5daee5 3708
12d89a2e
RS
3709;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3710;; Utility functions and variables:
3711
0a5daee5 3712
efa89c1f 3713(defun ps-print-quote (elt)
c86f4619
GM
3714 "Quote ELT for printing (used for showing settings).
3715
3716If ELT is nil, return an empty string.
3717If ELT is string, return it.
3718Otherwise, ELT should be a cons (LEN . SYM) where SYM is a variable symbol and
3719LEN is the field length where SYM name will be inserted. The variable
3720`ps-prefix-quote' is used to form the string, if `ps-prefix-quote' is nil, it's
3721used \"(setq \" as prefix; otherwise, it's used \" \". So, the string
3722generated is:
3723
3724 * If `ps-prefix-quote' is nil:
3725 \"(setq SYM-NAME SYM-VALUE\"
3726 |<------->|
3727 LEN
3728
3729 * If `ps-prefix-quote' is non-nil:
3730 \" SYM-NAME SYM-VALUE\"
3731 |<------->|
3732 LEN
3733
3734If `ps-prefix-quote' is nil, it's set to t after generating string."
efa89c1f 3735 (cond
efa89c1f 3736 ((stringp elt) elt)
c90a10fa
RS
3737 ((and (consp elt) (integerp (car elt))
3738 (symbolp (cdr elt)) (boundp (cdr elt)))
efa89c1f
GM
3739 (let* ((col (car elt))
3740 (sym (cdr elt))
3741 (key (symbol-name sym))
3742 (len (length key))
3743 (val (symbol-value sym)))
3744 (concat (if ps-prefix-quote
c86f4619
GM
3745 " "
3746 (setq ps-prefix-quote t)
efa89c1f
GM
3747 "(setq ")
3748 key
3749 (if (> col len)
4abc74e8 3750 (make-string (- col len) ?\s)
efa89c1f 3751 " ")
51138c94 3752 (ps-value-string val))))
c90a10fa 3753 (t "")
efa89c1f
GM
3754 ))
3755
3756
51138c94
VJL
3757(defun ps-value-string (val)
3758 "Return a string representation of VAL. Used by `ps-print-quote'."
3759 (cond ((null val)
3760 "nil")
3761 ((eq val t)
3762 "t")
3763 ((or (symbolp val) (listp val))
3764 (format "'%S" val))
3765 (t
3766 (format "%S" val))))
3767
3768
bd20e8cd 3769(defun ps-comment-string (str value)
cfb7b9ce
VJL
3770 "Return a comment string like \";; STR = VALUE\"."
3771 (format ";; %s = %s" str (ps-value-string value)))
bd20e8cd
VJL
3772
3773
319acba0
GM
3774(defun ps-value (alist-sym key)
3775 "Return value from association list ALIST-SYM which car is `eq' to KEY."
3776 (cdr (assq key (symbol-value alist-sym))))
3777
3778
3779(defun ps-get (alist-sym key)
3780 "Return element from association list ALIST-SYM which car is `eq' to KEY."
3781 (assq key (symbol-value alist-sym)))
3782
3783
3784(defun ps-put (alist-sym key value)
3785 "Store element (KEY . VALUE) into association list ALIST-SYM.
3786If KEY already exists in ALIST-SYM, modify cdr to VALUE.
3787It can be retrieved with `(ps-get ALIST-SYM KEY)'."
3788 (let ((elt: (assq key (symbol-value alist-sym)))) ; to avoid name conflict
3789 (if elt:
3790 (setcdr elt: value)
3791 (setq elt: (cons key value))
3792 (set alist-sym (cons elt: (symbol-value alist-sym))))
3793 elt:))
3794
3795
3796(defun ps-del (alist-sym key)
3797 "Delete by side effect element KEY from association list ALIST-SYM."
3798 (let ((a:list: (symbol-value alist-sym)) ; to avoid name conflict
3799 old)
3800 (while a:list:
3801 (if (eq key (car (car a:list:)))
3802 (progn
3803 (if old
3804 (setcdr old (cdr a:list:))
3805 (set alist-sym (cdr a:list:)))
3806 (setq a:list: nil))
3807 (setq old a:list:
3808 a:list: (cdr a:list:)))))
3809 (symbol-value alist-sym))
3810
3811
4b81a999
GM
3812(defun ps-time-stamp-locale-default ()
3813 "Return the locale's \"preferred\" date as, for example, \"06/18/01\"."
3814 (format-time-string "%x"))
3815
3816
2bd80d73 3817(defun ps-time-stamp-mon-dd-yyyy ()
4b81a999 3818 "Return date as \"Jun 18 2001\"."
2bd80d73
GM
3819 (format-time-string "%b %d %Y"))
3820
3821
71efd3c4
VJL
3822(defun ps-time-stamp-yyyy-mm-dd ()
3823 "Return date as \"2001-06-18\" (ISO date)."
3824 (format-time-string "%Y-%m-%d"))
3825
3826
3a504454
VJL
3827;; Alias for `ps-time-stamp-yyyy-mm-dd' (which see).
3828(defalias 'ps-time-stamp-iso8601 'ps-time-stamp-yyyy-mm-dd)
71efd3c4
VJL
3829
3830
2bd80d73 3831(defun ps-time-stamp-hh:mm:ss ()
4b81a999 3832 "Return time as \"17:28:31\"."
2bd80d73
GM
3833 (format-time-string "%T"))
3834
3835
b6d0ac87
VJL
3836(and (featurep 'xemacs)
3837 ;; XEmacs change: Need to check for emacs-major-version too.
3838 (or (< emacs-major-version 19)
3839 (and (= emacs-major-version 19) (< emacs-minor-version 12)))
3840 (setq ps-print-color-p nil))
3841
3842
3843;; Return t if the device (which can be changed during an emacs session)
3844;; can handle colors.
3845;; This function is not yet implemented for GNU emacs.
cf04718a
SM
3846(defalias 'ps-color-device
3847 (cond ((and (featurep 'xemacs)
d3241651
VJL
3848 ;; XEmacs change: Need to check for emacs-major-version too.
3849 (or (> emacs-major-version 19)
3850 (and (= emacs-major-version 19)
3851 (>= emacs-minor-version 12)))) ; XEmacs >= 19.12
3852 (lambda ()
3853 (eq (ps-x-device-class) 'color)))
3854
3855 (t ; Emacs
3856 (lambda ()
3857 (if (fboundp 'color-values)
3858 (ps-e-color-values "Green")
3859 t)))))
b6d0ac87
VJL
3860
3861
3862(defun ps-mapper (extent list)
3863 (nconc list
3864 (list (list (ps-x-extent-start-position extent) 'push extent)
3865 (list (ps-x-extent-end-position extent) 'pull extent)))
3866 nil)
3867
3868(defun ps-extent-sorter (a b)
3869 (< (ps-x-extent-priority a) (ps-x-extent-priority b)))
3870
3871(defun ps-xemacs-face-kind-p (face kind kind-regex)
3872 (let* ((frame-font (or (ps-x-face-font-instance face)
3873 (ps-x-face-font-instance 'default)))
3874 (kind-cons
3875 (and frame-font
3876 (assq kind
3877 (ps-x-font-instance-properties frame-font))))
3878 (kind-spec (cdr-safe kind-cons))
3879 (case-fold-search t))
3880 (and kind-spec (string-match kind-regex kind-spec))))
3881
cf04718a 3882(cond ((featurep 'xemacs) ; XEmacs
b6d0ac87
VJL
3883
3884 ;; to avoid XEmacs compilation gripes
cf04718a
SM
3885 (defvar coding-system-for-write)
3886 (defvar coding-system-for-read)
3887 (defvar buffer-file-coding-system)
b6d0ac87
VJL
3888
3889 (and (fboundp 'find-coding-system)
3890 (or (ps-x-find-coding-system 'raw-text-unix)
3891 (ps-x-copy-coding-system 'no-conversion-unix 'raw-text-unix)))
3892
3893 (defun ps-color-values (x-color)
3894 (let ((color (ps-xemacs-color-name x-color)))
ea0c615d 3895 (cond
ea0c615d 3896 ((fboundp 'x-color-values)
b6d0ac87
VJL
3897 (ps-e-x-color-values color))
3898 ((and (fboundp 'color-instance-rgb-components)
3899 (ps-color-device))
3900 (ps-x-color-instance-rgb-components
3901 (if (ps-x-color-instance-p x-color)
3902 x-color
3903 (ps-x-make-color-instance color))))
ea0c615d 3904 (t
b6d0ac87
VJL
3905 (error "No available function to determine X color values")))))
3906
3907 (defun ps-face-bold-p (face)
3908 (or (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold")
3909 (memq face ps-bold-faces))) ; Kludge-compatible
3910
3911 (defun ps-face-italic-p (face)
3912 (or (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o")
3913 (ps-xemacs-face-kind-p face 'SLANT "i\\|o")
3914 (memq face ps-italic-faces))) ; Kludge-compatible
3915 )
3916
cf04718a 3917 (t ; Emacs
b6d0ac87
VJL
3918
3919 (defun ps-color-values (x-color)
3920 (cond
3921 ((fboundp 'color-values)
3922 (ps-e-color-values x-color))
3923 ((fboundp 'x-color-values)
3924 (ps-e-x-color-values x-color))
3925 (t
3926 (error "No available function to determine X color values"))))
3e9cb08f 3927
b6d0ac87
VJL
3928 (defun ps-face-bold-p (face)
3929 (or (ps-e-face-bold-p face)
3930 (memq face ps-bold-faces)))
509b4dbc 3931
b6d0ac87
VJL
3932 (defun ps-face-italic-p (face)
3933 (or (ps-e-face-italic-p face)
3934 (memq face ps-italic-faces)))
3935 ))
3e9cb08f
GM
3936
3937
ea0c615d 3938(defvar ps-print-color-scale 1.0)
47b54c71 3939
3e9cb08f
GM
3940(defun ps-color-scale (color)
3941 ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
3942 (mapcar #'(lambda (value) (/ value ps-print-color-scale))
3943 (ps-color-values color)))
3944
3945
3946(defun ps-face-underlined-p (face)
3947 (or (face-underline-p face)
3948 (memq face ps-underlined-faces)))
e65df0a1 3949
857686a6 3950
41481e4b 3951(defun ps-prologue-file (filenumber)
2285bf9d 3952 "If prologue FILENUMBER exists and is readable, return contents as string.
2bd80d73
GM
3953
3954Note: No major/minor-mode is activated and no local variables are evaluated for
3955 FILENUMBER, but proper EOL-conversion and character interpretation is
3956 done!"
3957 (let ((filename (convert-standard-filename
3958 (expand-file-name (format "ps-prin%d.ps" filenumber)
3959 ps-postscript-code-directory))))
3960 (if (and (file-exists-p filename)
319acba0
GM
3961 (file-readable-p filename))
3962 (with-temp-buffer
3963 (insert-file-contents filename)
3964 (buffer-string))
e8af40ee 3965 (error "ps-print PostScript prologue `%s' file was not found"
2bd80d73 3966 filename))))
bcc0d457 3967
bcc0d457 3968
6db15364 3969(defvar ps-mark-code-directory nil)
bcc0d457 3970
66e63857
GM
3971(defvar ps-print-prologue-0 ""
3972 "ps-print PostScript error handler.")
3973
41481e4b 3974(defvar ps-print-prologue-1 ""
6bf5fb46 3975 "ps-print PostScript prologue.")
12d89a2e
RS
3976
3977;; Start Editing Here:
ef2cbb24 3978
6db15364 3979(defvar ps-source-buffer nil)
12d89a2e 3980(defvar ps-spool-buffer-name "*PostScript*")
6db15364 3981(defvar ps-spool-buffer nil)
ef2cbb24 3982
6db15364
VJL
3983(defvar ps-output-head nil)
3984(defvar ps-output-tail nil)
ef2cbb24 3985
4b3eb10f
GM
3986(defvar ps-page-postscript 0) ; page number
3987(defvar ps-page-order 0) ; PostScript page counter
3988(defvar ps-page-sheet 0) ; sheet counter
3989(defvar ps-page-column 0) ; column counter
3990(defvar ps-page-printed 0) ; total pages printed
3991(defvar ps-page-n-up 0) ; n-up counter
bd7a2e26
GM
3992(defvar ps-lines-printed 0) ; total lines printed
3993(defvar ps-showline-count 1) ; line number counter
6db15364
VJL
3994(defvar ps-first-page nil)
3995(defvar ps-last-page nil)
ea0c615d 3996(defvar ps-print-page-p t)
87a16a06 3997
6db15364
VJL
3998(defvar ps-control-or-escape-regexp nil)
3999(defvar ps-n-up-on nil)
857686a6 4000
6db15364
VJL
4001(defvar ps-background-pages nil)
4002(defvar ps-background-all-pages nil)
87a16a06
RS
4003(defvar ps-background-text-count 0)
4004(defvar ps-background-image-count 0)
ef2cbb24 4005
12d89a2e 4006(defvar ps-current-font 0)
6db15364
VJL
4007(defvar ps-default-foreground nil)
4008(defvar ps-default-background nil)
4009(defvar ps-default-color nil)
4010(defvar ps-current-color nil)
4011(defvar ps-current-bg nil)
12d89a2e 4012
6db15364 4013(defvar ps-zebra-stripe-full-p nil)
12d89a2e
RS
4014(defvar ps-razchunk 0)
4015
6db15364 4016(defvar ps-color-p nil)
bcc0d457 4017(defvar ps-color-format
b6d0ac87
VJL
4018 (if (featurep 'xemacs)
4019 ;; XEmacs will have to make do with %s (princ) for floats.
4020 "%s %s %s"
12d89a2e 4021
b6d0ac87
VJL
4022 ;; Emacs understands the %f format; we'll use it to limit color RGB
4023 ;; values to three decimals to cut down some on the size of the
4024 ;; PostScript output.
4025 "%0.3f %0.3f %0.3f"))
12d89a2e 4026
319acba0
GM
4027;; These values determine how much print-height to deduct when headers/footers
4028;; are turned on. This is a pretty clumsy way of handling it, but it'll do for
4029;; now.
12d89a2e 4030
bcc0d457 4031(defvar ps-header-pad 0
496725ad
RS
4032 "Vertical and horizontal space between the header frame and the text.
4033This is in units of points (1/72 inch).")
12d89a2e 4034
319acba0
GM
4035(defvar ps-footer-pad 0
4036 "Vertical and horizontal space between the footer frame and the text.
4037This is in units of points (1/72 inch).")
4038
bcc0d457 4039;; Define accessors to the dimensions list.
12d89a2e 4040
bcc0d457
RS
4041(defmacro ps-page-dimensions-get-width (dims) `(nth 0 ,dims))
4042(defmacro ps-page-dimensions-get-height (dims) `(nth 1 ,dims))
bc0d41bd 4043(defmacro ps-page-dimensions-get-media (dims) `(nth 2 ,dims))
12d89a2e 4044
6db15364 4045(defvar ps-landscape-page-height nil)
12d89a2e 4046
6db15364
VJL
4047(defvar ps-print-width nil)
4048(defvar ps-print-height nil)
12d89a2e 4049
6db15364
VJL
4050(defvar ps-height-remaining nil)
4051(defvar ps-width-remaining nil)
12d89a2e 4052
6db15364
VJL
4053(defvar ps-font-size-internal nil)
4054(defvar ps-header-font-size-internal nil)
4055(defvar ps-header-title-font-size-internal nil)
4056(defvar ps-footer-font-size-internal nil)
4057(defvar ps-line-spacing-internal nil)
4058(defvar ps-paragraph-spacing-internal nil)
7d8b7e8e 4059
87a16a06
RS
4060\f
4061;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4062;; Internal Variables
4063
4064
55732434
GM
4065(defvar ps-black-white-faces-alist nil
4066 "Alist of symbolic faces used for black/white PostScript printers.
4067An element of this list has the same form as `ps-print-face-extension-alist'
2285bf9d 4068\(which see).
55732434
GM
4069
4070Don't change this list directly; instead,
4071use `ps-extend-face' and `ps-extend-face-list'.
4072See documentation for `ps-extend-face' for valid extension symbol.
4073See also documentation for `ps-print-color-p'.")
4074
4075
87a16a06 4076(defvar ps-print-face-extension-alist nil
a18ed129 4077 "Alist of symbolic faces *WITH* extension features (box, outline, etc).
87a16a06
RS
4078An element of this list has the following form:
4079
4080 (FACE . [BITS FG BG])
4081
4082 FACE is a symbol denoting a face name
4083 BITS is a bit vector, where each bit correspond
4084 to a feature (bold, underline, etc)
4085 (see documentation for `ps-print-face-map-alist')
4086 FG foreground color (string or nil)
4087 BG background color (string or nil)
4088
a18ed129
RS
4089Don't change this list directly; instead,
4090use `ps-extend-face' and `ps-extend-face-list'.
4091See documentation for `ps-extend-face' for valid extension symbol.")
4092
4093
4094(defvar ps-print-face-alist nil
4095 "Alist of symbolic faces *WITHOUT* extension features (box, outline, etc).
4096
4097An element of this list has the same form as an element of
4098`ps-print-face-extension-alist'.
4099
4100Don't change this list directly; this list is used by `ps-face-attributes',
4101`ps-map-face' and `ps-build-reference-face-lists'.")
87a16a06
RS
4102
4103
4104(defconst ps-print-face-map-alist
4105 '((bold . 1)
4106 (italic . 2)
4107 (underline . 4)
4108 (strikeout . 8)
4109 (overline . 16)
4110 (shadow . 32)
4111 (box . 64)
4112 (outline . 128))
4113 "Alist of all features and the corresponding bit mask.
4114Each symbol correspond to one bit in a bit vector.")
4115
4116\f
4117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
a18ed129 4118;; Remapping Faces
87a16a06
RS
4119
4120
4121;;;###autoload
55732434
GM
4122(defun ps-extend-face-list (face-extension-list &optional merge-p alist-sym)
4123 "Extend face in ALIST-SYM.
87a16a06 4124
a18ed129 4125If optional MERGE-P is non-nil, extensions in FACE-EXTENSION-LIST are merged
55732434
GM
4126with face extension in ALIST-SYM; otherwise, overrides.
4127
01cdabc6 4128If optional ALIST-SYM is nil, `ps-print-face-extension-alist' is used;
55732434 4129otherwise, it should be an alist symbol.
87a16a06 4130
01cdabc6 4131The elements in FACE-EXTENSION-LIST are like those for `ps-extend-face'.
87a16a06
RS
4132
4133See `ps-extend-face' for documentation."
4134 (while face-extension-list
55732434 4135 (ps-extend-face (car face-extension-list) merge-p alist-sym)
87a16a06
RS
4136 (setq face-extension-list (cdr face-extension-list))))
4137
4138
4139;;;###autoload
55732434
GM
4140(defun ps-extend-face (face-extension &optional merge-p alist-sym)
4141 "Extend face in ALIST-SYM.
87a16a06 4142
6bdb808e 4143If optional MERGE-P is non-nil, extensions in FACE-EXTENSION list are merged
55732434
GM
4144with face extensions in ALIST-SYM; otherwise, overrides.
4145
01cdabc6 4146If optional ALIST-SYM is nil, `ps-print-face-extension-alist' is used;
55732434 4147otherwise, it should be an alist symbol.
87a16a06
RS
4148
4149The elements of FACE-EXTENSION list have the form:
4150
4151 (FACE-NAME FOREGROUND BACKGROUND EXTENSION...)
4152
4153FACE-NAME is a face name symbol.
4154
4155FOREGROUND and BACKGROUND may be nil or a string that denotes the
4156foreground and background colors respectively.
4157
4158EXTENSION is one of the following symbols:
4159 bold - use bold font.
4160 italic - use italic font.
4161 underline - put a line under text.
4162 strikeout - like underline, but the line is in middle of text.
4163 overline - like underline, but the line is over the text.
4164 shadow - text will have a shadow.
4165 box - text will be surrounded by a box.
a18ed129 4166 outline - print characters as hollow outlines.
87a16a06
RS
4167
4168If EXTENSION is any other symbol, it is ignored."
55732434
GM
4169 (or alist-sym
4170 (setq alist-sym 'ps-print-face-extension-alist))
4171 (let* ((background (nth 2 face-extension))
4172 (foreground (nth 1 face-extension))
4173 (face-name (nth 0 face-extension))
4174 (ps-face (cdr (assq face-name (symbol-value alist-sym))))
87a16a06 4175 (face-vector (or ps-face (vector 0 nil nil)))
55732434 4176 (face-bit (ps-extension-bit face-extension)))
87a16a06
RS
4177 ;; extend face
4178 (aset face-vector 0 (if merge-p
4179 (logior (aref face-vector 0) face-bit)
4180 face-bit))
55732434
GM
4181 (and (or (not merge-p) (and foreground (stringp foreground)))
4182 (aset face-vector 1 foreground))
4183 (and (or (not merge-p) (and background (stringp background)))
4184 (aset face-vector 2 background))
87a16a06
RS
4185 ;; if face does not exist, insert it
4186 (or ps-face
55732434
GM
4187 (set alist-sym (cons (cons face-name face-vector)
4188 (symbol-value alist-sym))))))
87a16a06
RS
4189
4190
4191(defun ps-extension-bit (face-extension)
4192 (let ((face-bit 0))
4193 ;; map valid symbol extension to bit vector
4194 (setq face-extension (cdr (cdr face-extension)))
4195 (while (setq face-extension (cdr face-extension))
4196 (setq face-bit (logior face-bit
4197 (or (cdr (assq (car face-extension)
4198 ps-print-face-map-alist))
4199 0))))
4200 face-bit))
4201
4202\f
857686a6 4203;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bc0d41bd 4204;; Adapted from font-lock: (obsolete stuff)
857686a6
RS
4205;; Originally face attributes were specified via `font-lock-face-attributes'.
4206;; Users then changed the default face attributes by setting that variable.
4207;; However, we try and be back-compatible and respect its value if set except
4208;; for faces where M-x customize has been used to save changes for the face.
4209
0a5daee5 4210
857686a6
RS
4211(defun ps-font-lock-face-attributes ()
4212 (and (boundp 'font-lock-mode) (symbol-value 'font-lock-mode)
4213 (boundp 'font-lock-face-attributes)
3e9cb08f 4214 (let ((face-attributes (symbol-value 'font-lock-face-attributes)))
857686a6 4215 (while face-attributes
6bdb808e
RS
4216 (let* ((face-attribute
4217 (car (prog1 face-attributes
4218 (setq face-attributes (cdr face-attributes)))))
857686a6
RS
4219 (face (car face-attribute)))
4220 ;; Rustle up a `defface' SPEC from a
4221 ;; `font-lock-face-attributes' entry.
4222 (unless (get face 'saved-face)
4223 (let ((foreground (nth 1 face-attribute))
4224 (background (nth 2 face-attribute))
4225 (bold-p (nth 3 face-attribute))
4226 (italic-p (nth 4 face-attribute))
4227 (underline-p (nth 5 face-attribute))
4228 face-spec)
4229 (when foreground
4230 (setq face-spec (cons ':foreground
4231 (cons foreground face-spec))))
4232 (when background
4233 (setq face-spec (cons ':background
4234 (cons background face-spec))))
4235 (when bold-p
e31c1fd5 4236 (setq face-spec (append '(:weight bold) face-spec)))
857686a6 4237 (when italic-p
e31c1fd5 4238 (setq face-spec (append '(:slant italic) face-spec)))
857686a6
RS
4239 (when underline-p
4240 (setq face-spec (append '(:underline t) face-spec)))
4241 (custom-declare-face face (list (list t face-spec)) nil)
4242 )))))))
4243
4244\f
87a16a06
RS
4245;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4246;; Internal functions and variables
4247
4248
197d4ebc
VJL
4249(defun ps-message-log-max ()
4250 (and (not (string= (buffer-name) "*Messages*"))
9586e1d3 4251 (boundp 'message-log-max)
197d4ebc
VJL
4252 message-log-max))
4253
4254
6db15364
VJL
4255(defvar ps-print-hook nil)
4256(defvar ps-print-begin-sheet-hook nil)
4257(defvar ps-print-begin-page-hook nil)
4258(defvar ps-print-begin-column-hook nil)
12b88fff
RS
4259
4260
a18ed129 4261(defun ps-print-without-faces (from to &optional filename region-p)
857686a6 4262 (ps-spool-without-faces from to region-p)
87a16a06
RS
4263 (ps-do-despool filename))
4264
4265
a18ed129 4266(defun ps-spool-without-faces (from to &optional region-p)
197d4ebc
VJL
4267 (let ((message-log-max (ps-message-log-max))) ; to print *Messages* buffer
4268 (run-hooks 'ps-print-hook)
4269 (ps-printing-region region-p from to)
4270 (ps-generate (current-buffer) from to 'ps-generate-postscript)))
87a16a06
RS
4271
4272
a18ed129 4273(defun ps-print-with-faces (from to &optional filename region-p)
857686a6 4274 (ps-spool-with-faces from to region-p)
87a16a06
RS
4275 (ps-do-despool filename))
4276
4277
a18ed129 4278(defun ps-spool-with-faces (from to &optional region-p)
197d4ebc
VJL
4279 (let ((message-log-max (ps-message-log-max))) ; to print *Messages* buffer
4280 (run-hooks 'ps-print-hook)
4281 (ps-printing-region region-p from to)
4282 (ps-generate (current-buffer) from to 'ps-generate-postscript-with-faces)))
87a16a06
RS
4283
4284
55732434 4285(defun ps-count-lines-preprint (from to)
197d4ebc
VJL
4286 (or (and from to)
4287 (error "The mark is not set now"))
4288 (let ((message-log-max (ps-message-log-max))) ; to count lines of *Messages*
4289 (list (count-lines from to))))
55732434
GM
4290
4291
bc0d41bd 4292(defun ps-count-lines (from to)
a18ed129 4293 (+ (count-lines from to)
857686a6
RS
4294 (save-excursion
4295 (goto-char to)
4296 (if (= (current-column) 0) 1 0))))
87a16a06
RS
4297
4298
a18ed129 4299(defvar ps-printing-region nil
9586e1d3 4300 "Variable used to indicate the region that ps-print is printing.
bc0d41bd
KH
4301It is a cons, the car of which is the line number where the region begins, and
4302its cdr is the total number of lines in the buffer. Formatting functions can
4303use this information to print the original line number (and not the number of
4304lines printed), and to indicate in the header that the printout is of a partial
4305file.")
4306
4307
4308(defvar ps-printing-region-p nil
4309 "Non-nil means ps-print is printing a region.")
87a16a06
RS
4310
4311
e22ba851 4312(defun ps-printing-region (region-p from to)
bc0d41bd
KH
4313 (setq ps-printing-region-p region-p
4314 ps-printing-region
4315 (cons (if region-p
e22ba851 4316 (ps-count-lines (point-min) (min from to))
bc0d41bd
KH
4317 1)
4318 (ps-count-lines (point-min) (point-max)))))
87a16a06
RS
4319
4320\f
12d89a2e
RS
4321;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4322;; Internal functions
4323
0a5daee5 4324
7ae35a2f 4325(defsubst ps-font-alist (font-sym)
12b88fff
RS
4326 (get font-sym 'fonts))
4327
4328(defun ps-font (font-sym font-type)
4329 "Font family name for text of `font-type', when generating PostScript."
7ae35a2f 4330 (let* ((font-list (ps-font-alist font-sym))
12b88fff 4331 (normal-font (cdr (assq 'normal font-list))))
6bdb808e
RS
4332 (while (and font-list (not (eq font-type (car (car font-list)))))
4333 (setq font-list (cdr font-list)))
4334 (or (cdr (car font-list)) normal-font)))
12b88fff 4335
319acba0 4336(defsubst ps-fonts (font-sym)
7ae35a2f 4337 (mapcar 'cdr (ps-font-alist font-sym)))
12b88fff 4338
319acba0 4339(defsubst ps-font-number (font-sym font-type)
7ae35a2f 4340 (or (ps-alist-position font-type (ps-font-alist font-sym))
12b88fff
RS
4341 0))
4342
4343(defsubst ps-line-height (font-sym)
4344 "The height of a line, for generating PostScript.
4345This is the value that ps-print uses to determine the height,
4346y-dimension, of the lines of text it has printed, and thus affects the
4347point at which page-breaks are placed.
4348The line-height is *not* the same as the point size of the font."
4349 (get font-sym 'line-height))
4350
4351(defsubst ps-title-line-height (font-sym)
4352 "The height of a `title' line, for generating PostScript.
4353This is the value that ps-print uses to determine the height,
4354y-dimension, of the lines of text it has printed, and thus affects the
4355point at which page-breaks are placed.
4356The title-line-height is *not* the same as the point size of the font."
4357 (get font-sym 'title-line-height))
4358
4359(defsubst ps-space-width (font-sym)
4360 "The width of a space character, for generating PostScript.
4361This value is used in expanding tab characters."
4362 (get font-sym 'space-width))
4363
4364(defsubst ps-avg-char-width (font-sym)
4365 "The average width, in points, of a character, for generating PostScript.
4366This is the value that ps-print uses to determine the length,
4367x-dimension, of the text it has printed, and thus affects the point at
4368which long lines wrap around."
4369 (get font-sym 'avg-char-width))
4370
bcc0d457 4371(defun ps-line-lengths-internal ()
2285bf9d
RS
4372 "Display the correspondence between a line length and a font size.
4373Done using the current ps-print setup.
bcc0d457 4374Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
df5e6194
GM
4375 (let* ((ps-font-size-internal
4376 (or ps-font-size-internal
4377 (ps-get-font-size 'ps-font-size)))
4378 (ps-header-font-size-internal
4379 (or ps-header-font-size-internal
4380 (ps-get-font-size 'ps-header-font-size)))
4381 (ps-header-title-font-size-internal
4382 (or ps-header-title-font-size-internal
4383 (ps-get-font-size 'ps-header-title-font-size)))
4384 (buf (get-buffer-create "*Line-lengths*"))
4385 (ifs ps-font-size-internal) ; initial font size
4386 (icw (ps-avg-char-width 'ps-font-for-text)) ; initial character width
4387 (print-width (progn (ps-get-page-dimensions)
4388 ps-print-width))
4389 (ps-setup (ps-setup)) ; setup for the current buffer
4390 (fs-min 5) ; minimum font size
4391 cw-min ; minimum character width
4392 nb-cpl-max ; maximum nb of characters per line
4393 (fs-max 14) ; maximum font size
4394 cw-max ; maximum character width
4395 nb-cpl-min ; minimum nb of characters per line
4396 fs ; current font size
4397 cw ; current character width
4398 nb-cpl ; current nb of characters per line
4399 )
bcc0d457
RS
4400 (setq cw-min (/ (* icw fs-min) ifs)
4401 nb-cpl-max (floor (/ print-width cw-min))
4402 cw-max (/ (* icw fs-max) ifs)
8bd22fcf
KH
4403 nb-cpl-min (floor (/ print-width cw-max))
4404 nb-cpl nb-cpl-min)
bcc0d457
RS
4405 (set-buffer buf)
4406 (goto-char (point-max))
df5e6194 4407 (or (bobp) (insert "\n" (make-string 75 ?\;) "\n"))
8bd22fcf 4408 (insert ps-setup
df5e6194 4409 "\nnb char per line / font size\n")
bcc0d457 4410 (while (<= nb-cpl nb-cpl-max)
8bd22fcf
KH
4411 (setq cw (/ print-width (float nb-cpl))
4412 fs (/ (* ifs cw) icw))
df5e6194 4413 (insert (format "%16d %s\n" nb-cpl fs))
bcc0d457
RS
4414 (setq nb-cpl (1+ nb-cpl)))
4415 (insert "\n")
4416 (display-buffer buf 'not-this-window)))
4417
4418(defun ps-nb-pages (nb-lines)
496725ad
RS
4419 "Display correspondence between font size and the number of pages.
4420The correspondence is based on having NB-LINES lines of text,
4421and on the current ps-print setup."
df5e6194
GM
4422 (let* ((ps-font-size-internal
4423 (or ps-font-size-internal
4424 (ps-get-font-size 'ps-font-size)))
4425 (ps-header-font-size-internal
4426 (or ps-header-font-size-internal
4427 (ps-get-font-size 'ps-header-font-size)))
4428 (ps-header-title-font-size-internal
4429 (or ps-header-title-font-size-internal
4430 (ps-get-font-size 'ps-header-title-font-size)))
6bf5fb46
GM
4431 (ps-line-spacing-internal
4432 (or ps-line-spacing-internal
4433 (ps-get-size ps-line-spacing "line spacing")))
df5e6194 4434 (buf (get-buffer-create "*Nb-Pages*"))
6bf5fb46 4435 (ils ps-line-spacing-internal) ; initial line spacing
df5e6194
GM
4436 (ifs ps-font-size-internal) ; initial font size
4437 (ilh (ps-line-height 'ps-font-for-text)) ; initial line height
4438 (page-height (progn (ps-get-page-dimensions)
4439 ps-print-height))
4440 (ps-setup (ps-setup)) ; setup for the current buffer
4441 (fs-min 4) ; minimum font size
4442 lh-min ; minimum line height
4443 nb-lpp-max ; maximum nb of lines per page
4444 nb-page-min ; minimum nb of pages
4445 (fs-max 14) ; maximum font size
4446 lh-max ; maximum line height
4447 nb-lpp-min ; minimum nb of lines per page
4448 nb-page-max ; maximum nb of pages
4449 fs ; current font size
4450 lh ; current line height
4451 nb-lpp ; current nb of lines per page
4452 nb-page ; current nb of pages
4453 )
6bf5fb46 4454 (setq lh-min (/ (- (* (+ ilh ils) fs-min) ils) ifs)
bcc0d457
RS
4455 nb-lpp-max (floor (/ page-height lh-min))
4456 nb-page-min (ceiling (/ (float nb-lines) nb-lpp-max))
6bf5fb46 4457 lh-max (/ (- (* (+ ilh ils) fs-max) ils) ifs)
bcc0d457 4458 nb-lpp-min (floor (/ page-height lh-max))
8bd22fcf
KH
4459 nb-page-max (ceiling (/ (float nb-lines) nb-lpp-min))
4460 nb-page nb-page-min)
bcc0d457
RS
4461 (set-buffer buf)
4462 (goto-char (point-max))
df5e6194 4463 (or (bobp) (insert "\n" (make-string 75 ?\;) "\n"))
8bd22fcf 4464 (insert ps-setup
df5e6194 4465 (format "\nThere are %d lines.\n\n" nb-lines)
8bd22fcf 4466 "nb page / font size\n")
bcc0d457
RS
4467 (while (<= nb-page nb-page-max)
4468 (setq nb-lpp (ceiling (/ nb-lines (float nb-page)))
4469 lh (/ page-height nb-lpp)
4470 fs (/ (* ifs lh) ilh))
df5e6194 4471 (insert (format "%7d %s\n" nb-page fs))
bcc0d457
RS
4472 (setq nb-page (1+ nb-page)))
4473 (insert "\n")
4474 (display-buffer buf 'not-this-window)))
4475
6bdb808e
RS
4476;; macros used in `ps-select-font'
4477(defmacro ps-lookup (key) `(cdr (assq ,key font-entry)))
4478(defmacro ps-size-scale (key) `(/ (* (ps-lookup ,key) font-size) size))
4479
12b88fff
RS
4480(defun ps-select-font (font-family sym font-size title-font-size)
4481 (let ((font-entry (cdr (assq font-family ps-font-info-database))))
4482 (or font-entry
ef1159c2 4483 (error "Don't have data to scale font %s. Known fonts families are %s"
12b88fff
RS
4484 font-family
4485 (mapcar 'car ps-font-info-database)))
6bdb808e
RS
4486 (let ((size (ps-lookup 'size)))
4487 (put sym 'fonts (ps-lookup 'fonts))
4488 (put sym 'space-width (ps-size-scale 'space-width))
4489 (put sym 'avg-char-width (ps-size-scale 'avg-char-width))
4490 (put sym 'line-height (ps-size-scale 'line-height))
4491 (put sym 'title-line-height
4492 (/ (* (ps-lookup 'line-height) title-font-size) size)))))
bcc0d457 4493
12d89a2e 4494(defun ps-get-page-dimensions ()
bcc0d457
RS
4495 (let ((page-dimensions (cdr (assq ps-paper-type ps-page-dimensions-database)))
4496 page-width page-height)
4497 (cond
4498 ((null page-dimensions)
4499 (error "`ps-paper-type' must be one of:\n%s"
4500 (mapcar 'car ps-page-dimensions-database)))
4501 ((< ps-number-of-columns 1)
12b88fff 4502 (error "The number of columns %d should be positive"
8bd22fcf 4503 ps-number-of-columns)))
bcc0d457 4504
12b88fff 4505 (ps-select-font ps-font-family 'ps-font-for-text
7d8b7e8e 4506 ps-font-size-internal ps-font-size-internal)
12b88fff 4507 (ps-select-font ps-header-font-family 'ps-font-for-header
7d8b7e8e
KH
4508 ps-header-font-size-internal
4509 ps-header-title-font-size-internal)
319acba0
GM
4510 (ps-select-font ps-footer-font-family 'ps-font-for-footer
4511 ps-footer-font-size-internal ps-footer-font-size-internal)
bcc0d457
RS
4512
4513 (setq page-width (ps-page-dimensions-get-width page-dimensions)
4514 page-height (ps-page-dimensions-get-height page-dimensions))
4515
4516 ;; Landscape mode
4517 (if ps-landscape-mode
4518 ;; exchange width and height
4519 (setq page-width (prog1 page-height (setq page-height page-width))))
4520
4521 ;; It is used to get the lower right corner (only in landscape mode)
4522 (setq ps-landscape-page-height page-height)
4523
4524 ;; | lm | text | ic | text | ic | text | rm |
4525 ;; page-width == lm + n * pw + (n - 1) * ic + rm
4526 ;; => pw == (page-width - lm -rm - (n - 1) * ic) / n
8bd22fcf
KH
4527 (setq ps-print-width (/ (- page-width
4528 ps-left-margin ps-right-margin
4529 (* (1- ps-number-of-columns) ps-inter-column))
4530 ps-number-of-columns))
bcc0d457
RS
4531 (if (<= ps-print-width 0)
4532 (error "Bad horizontal layout:
4533page-width == %s
4534ps-left-margin == %s
4535ps-right-margin == %s
4536ps-inter-column == %s
4537ps-number-of-columns == %s
4538| lm | text | ic | text | ic | text | rm |
4539page-width == lm + n * print-width + (n - 1) * ic + rm
4540=> print-width == %d !"
4541 page-width
4542 ps-left-margin
4543 ps-right-margin
4544 ps-inter-column
4545 ps-number-of-columns
4546 ps-print-width))
4547
4548 (setq ps-print-height
4549 (- page-height ps-bottom-margin ps-top-margin))
4550 (if (<= ps-print-height 0)
4551 (error "Bad vertical layout:
4552ps-top-margin == %s
4553ps-bottom-margin == %s
4554page-height == bm + print-height + tm
4555=> print-height == %d !"
4556 ps-top-margin
4557 ps-bottom-margin
4558 ps-print-height))
319acba0
GM
4559 ;; If headers are turned on, deduct the height of the header from the print
4560 ;; height.
8bd22fcf 4561 (if ps-print-header
12b88fff
RS
4562 (setq ps-header-pad (* ps-header-line-pad
4563 (ps-title-line-height 'ps-font-for-header))
8bd22fcf
KH
4564 ps-print-height (- ps-print-height
4565 ps-header-offset
4566 ps-header-pad
12b88fff
RS
4567 (ps-title-line-height 'ps-font-for-header)
4568 (* (ps-line-height 'ps-font-for-header)
4569 (1- ps-header-lines))
8bd22fcf 4570 ps-header-pad)))
bcc0d457 4571 (if (<= ps-print-height 0)
319acba0 4572 (error "Bad vertical layout (header):
bcc0d457
RS
4573ps-top-margin == %s
4574ps-bottom-margin == %s
4575ps-header-offset == %s
4576ps-header-pad == %s
4577header-height == %s
4578page-height == bm + print-height + tm - ho - hh
4579=> print-height == %d !"
4580 ps-top-margin
4581 ps-bottom-margin
4582 ps-header-offset
4583 ps-header-pad
4584 (+ ps-header-pad
12b88fff
RS
4585 (ps-title-line-height 'ps-font-for-header)
4586 (* (ps-line-height 'ps-font-for-header)
4587 (1- ps-header-lines))
bcc0d457 4588 ps-header-pad)
2bd80d73 4589 ps-print-height))
319acba0
GM
4590 ;; If footers are turned on, deduct the height of the footer from the print
4591 ;; height.
4592 (if ps-print-footer
4593 (setq ps-footer-pad (* ps-footer-line-pad
4594 (ps-title-line-height 'ps-font-for-footer))
4595 ps-print-height (- ps-print-height
4596 ps-footer-offset
4597 ps-footer-pad
4598 (* (ps-line-height 'ps-font-for-footer)
4599 (1- ps-footer-lines))
4600 ps-footer-pad)))
4601 (if (<= ps-print-height 0)
4602 (error "Bad vertical layout (footer):
4603ps-top-margin == %s
4604ps-bottom-margin == %s
4605ps-footer-offset == %s
4606ps-footer-pad == %s
4607footer-height == %s
4608page-height == bm + print-height + tm - fo - fh
4609=> print-height == %d !"
4610 ps-top-margin
4611 ps-bottom-margin
4612 ps-footer-offset
4613 ps-footer-pad
4614 (+ ps-footer-pad
4615 (* (ps-line-height 'ps-font-for-footer)
4616 (1- ps-footer-lines))
4617 ps-footer-pad)
4618 ps-print-height))
2bd80d73
GM
4619 ;; ps-zebra-stripe-follow is `full' or `full-follow'
4620 (if ps-zebra-stripe-full-p
4621 (let* ((line-height (ps-line-height 'ps-font-for-text))
6bf5fb46
GM
4622 (zebra (* (+ line-height ps-line-spacing-internal)
4623 ps-zebra-stripe-height)))
2bd80d73
GM
4624 (setq ps-print-height (- (* (floor ps-print-height zebra) zebra)
4625 line-height))
4626 (if (<= ps-print-height 0)
319acba0 4627 (error "Bad vertical layout (full zebra stripe follow):
2bd80d73
GM
4628ps-zebra-stripe-follow == %s
4629ps-zebra-stripe-height == %s
4630font-text-height == %s
6bf5fb46
GM
4631line-spacing == %s
4632page-height == ((floor print-height ((th + ls) * zh)) * ((th + ls) * zh)) - th
2bd80d73
GM
4633=> print-height == %d !"
4634 ps-zebra-stripe-follow
4635 ps-zebra-stripe-height
4636 (ps-line-height 'ps-font-for-text)
6bf5fb46 4637 ps-line-spacing-internal
2bd80d73 4638 ps-print-height))))))
ef2cbb24 4639
55732434
GM
4640
4641(defun ps-print-preprint-region (prefix-arg)
509b4dbc 4642 (or (ps-mark-active-p)
55732434
GM
4643 (error "The mark is not set now"))
4644 (list (point) (mark) (ps-print-preprint prefix-arg)))
4645
4646
edc9cd35
GM
4647(defun ps-print-preprint (prefix-arg)
4648 (and prefix-arg
4649 (or (numberp prefix-arg)
4650 (listp prefix-arg))
d3ab8dac
KH
4651 (let* ((name (concat (file-name-nondirectory (or (buffer-file-name)
4652 (buffer-name)))
4653 ".ps"))
5b76833f 4654 (prompt (format "Save PostScript to file (default %s): " name))
8bd22fcf 4655 (res (read-file-name prompt default-directory name nil)))
ea0c615d
GM
4656 (while (cond ((file-directory-p res)
4657 (ding)
4658 (setq prompt "It's a directory"))
4659 ((not (file-writable-p res))
d3ab8dac 4660 (ding)
ea0c615d 4661 (setq prompt "File is unwritable"))
d3ab8dac 4662 ((file-exists-p res)
ea0c615d 4663 (setq prompt "File exists")
d3ab8dac
KH
4664 (not (y-or-n-p (format "File `%s' exists; overwrite? "
4665 res))))
4666 (t nil))
4667 (setq res (read-file-name
ea0c615d 4668 (format "%s; save PostScript to file: " prompt)
d3ab8dac
KH
4669 (file-name-directory res) nil nil
4670 (file-name-nondirectory res))))
8bd22fcf
KH
4671 (if (file-directory-p res)
4672 (expand-file-name name (file-name-as-directory res))
4673 res))))
12d89a2e
RS
4674
4675;; The following functions implement a simple list-buffering scheme so
4676;; that ps-print doesn't have to repeatedly switch between buffers
857686a6
RS
4677;; while spooling. The functions `ps-output' and `ps-output-string' build
4678;; up the lists; the function `ps-flush-output' takes the lists and
12d89a2e
RS
4679;; insert its contents into the spool buffer (*PostScript*).
4680
857686a6
RS
4681(defvar ps-string-escape-codes
4682 (let ((table (make-vector 256 nil))
4683 (char ?\000))
4684 ;; control characters
4685 (while (<= char ?\037)
4686 (aset table char (format "\\%03o" char))
4687 (setq char (1+ char)))
4688 ;; printable characters
4689 (while (< char ?\177)
4690 (aset table char (format "%c" char))
4691 (setq char (1+ char)))
4692 ;; DEL and 8-bit characters
4693 (while (<= char ?\377)
4694 (aset table char (format "\\%o" char))
4695 (setq char (1+ char)))
4696 ;; Override ASCII formatting characters with named escape code:
4697 (aset table ?\n "\\n") ; [NL] linefeed
4698 (aset table ?\r "\\r") ; [CR] carriage return
4699 (aset table ?\t "\\t") ; [HT] horizontal tab
4700 (aset table ?\b "\\b") ; [BS] backspace
4701 (aset table ?\f "\\f") ; [NP] form feed
4702 ;; Escape PostScript escape and string delimiter characters:
4703 (aset table ?\\ "\\\\")
4704 (aset table ?\( "\\(")
4705 (aset table ?\) "\\)")
4706 table)
4707 "Vector used to map characters to PostScript string escape codes.")
4708
6bf5fb46 4709(defsubst ps-output-string-prim (string)
12d89a2e
RS
4710 (insert "(") ;insert start-string delimiter
4711 (save-excursion ;insert string
e65df0a1 4712 (insert (string-as-unibyte string)))
12d89a2e 4713 ;; Find and quote special characters as necessary for PS
c82b4a75 4714 ;; This skips everything except control chars, non-ASCII chars, (, ) and \.
b61e2c11
RS
4715 (while (progn (skip-chars-forward " -'*-[]-~") (not (eobp)))
4716 (let ((special (following-char)))
e65df0a1 4717 (delete-char 1)
c794a94d
JB
4718 (insert
4719 (if (and (<= 0 special) (<= special 255))
4720 (aref ps-string-escape-codes special)
4721 ;; insert hexadecimal representation if character code is out of range
4722 (format "\\%04X" special)
4723 ))))
12d89a2e
RS
4724 (goto-char (point-max))
4725 (insert ")")) ;insert end-string delimiter
ef2cbb24 4726
6bf5fb46 4727(defsubst ps-init-output-queue ()
1fd9b7fe 4728 (setq ps-output-head (list "")
8bd22fcf 4729 ps-output-tail ps-output-head))
ef2cbb24 4730
1fd9b7fe
GM
4731
4732(defun ps-selected-pages ()
4733 (while (progn
4734 (setq ps-first-page (car (car ps-selected-pages))
4735 ps-last-page (cdr (car ps-selected-pages))
4736 ps-selected-pages (cdr ps-selected-pages))
4737 (and ps-selected-pages
4738 (< ps-last-page ps-page-postscript)))))
4739
4740
6bf5fb46 4741(defsubst ps-print-page-p ()
ea0c615d
GM
4742 (setq ps-print-page-p
4743 (and (cond ((null ps-first-page))
4744 ((<= ps-page-postscript ps-last-page)
4745 (<= ps-first-page ps-page-postscript))
4746 (ps-selected-pages
4747 (ps-selected-pages)
4748 (and (<= ps-first-page ps-page-postscript)
4749 (<= ps-page-postscript ps-last-page)))
4750 (t
4751 nil))
4b3eb10f 4752 (cond ((eq ps-even-or-odd-pages 'even-page)
ea0c615d 4753 (= (logand ps-page-postscript 1) 0))
4b3eb10f 4754 ((eq ps-even-or-odd-pages 'odd-page)
ea0c615d
GM
4755 (= (logand ps-page-postscript 1) 1))
4756 (t)
4757 ))))
1fd9b7fe
GM
4758
4759
6bf5fb46 4760(defsubst ps-print-sheet-p ()
4b3eb10f
GM
4761 (setq ps-print-page-p
4762 (cond ((eq ps-even-or-odd-pages 'even-sheet)
4763 (= (logand ps-page-sheet 1) 0))
4764 ((eq ps-even-or-odd-pages 'odd-sheet)
4765 (= (logand ps-page-sheet 1) 1))
4766 (t)
4767 )))
4768
4769
12d89a2e 4770(defun ps-output (&rest args)
ea0c615d 4771 (when ps-print-page-p
1fd9b7fe
GM
4772 (setcdr ps-output-tail args)
4773 (while (cdr ps-output-tail)
4774 (setq ps-output-tail (cdr ps-output-tail)))))
ef2cbb24 4775
12d89a2e
RS
4776(defun ps-output-string (string)
4777 (ps-output t string))
ef2cbb24 4778
e65df0a1
KH
4779;; Output strings in the list ARGS in the PostScript prologue part.
4780(defun ps-output-prologue (args)
4781 (ps-output 'prologue (if (stringp args) (list args) args)))
4782
12d89a2e
RS
4783(defun ps-flush-output ()
4784 (save-excursion
4785 (set-buffer ps-spool-buffer)
4786 (goto-char (point-max))
4787 (while ps-output-head
4788 (let ((it (car ps-output-head)))
e65df0a1
KH
4789 (cond
4790 ((eq t it)
4791 (setq ps-output-head (cdr ps-output-head))
4792 (ps-output-string-prim (car ps-output-head)))
4793 ((eq 'prologue it)
12d89a2e 4794 (setq ps-output-head (cdr ps-output-head))
e65df0a1
KH
4795 (save-excursion
4796 (search-backward "\nBeginDoc")
4797 (forward-char 1)
4798 (apply 'insert (car ps-output-head))))
4799 (t
4800 (insert it))))
12d89a2e
RS
4801 (setq ps-output-head (cdr ps-output-head))))
4802 (ps-init-output-queue))
4803
4804(defun ps-insert-file (fname)
4805 (ps-flush-output)
12d89a2e
RS
4806 (save-excursion
4807 (set-buffer ps-spool-buffer)
4808 (goto-char (point-max))
b6d0ac87 4809 (insert-file-contents fname)))
06fb6aab 4810
edf0b0c5
VJL
4811;; These functions are used in `ps-mule' to get charset of header and footer.
4812;; To avoid unnecessary calls to functions in `ps-left-header',
4813;; `ps-right-header', `ps-left-footer' and `ps-right-footer'.
4814
4815(defun ps-generate-string-list (content)
4816 (let (str)
4817 (while content
4818 (setq str (cons (cond
9586e1d3 4819 ;; string
edf0b0c5
VJL
4820 ((stringp (car content))
4821 (car content))
9586e1d3 4822 ;; function symbol
5d62baca 4823 ((functionp (car content))
edf0b0c5 4824 (concat "(" (funcall (car content)) ")"))
9586e1d3 4825 ;; variable symbol
edf0b0c5
VJL
4826 ((and (symbolp (car content)) (boundp (car content)))
4827 (concat "(" (symbol-value (car content)) ")"))
9586e1d3 4828 ;; otherwise, empty string
edf0b0c5
VJL
4829 (t
4830 ""))
4831 str)
4832 content (cdr content)))
4833 (nreverse str)))
4834
6db15364
VJL
4835(defvar ps-lh-cache nil)
4836(defvar ps-rh-cache nil)
4837(defvar ps-lf-cache nil)
4838(defvar ps-rf-cache nil)
edf0b0c5
VJL
4839
4840(defun ps-header-footer-string ()
4841 (and ps-print-header
4842 (setq ps-lh-cache (ps-generate-string-list ps-left-header)
4843 ps-rh-cache (ps-generate-string-list ps-right-header)))
4844 (and ps-print-footer
4845 (setq ps-lf-cache (ps-generate-string-list ps-left-footer)
4846 ps-rf-cache (ps-generate-string-list ps-right-footer)))
b77ba60f 4847 (append ps-lh-cache ps-rh-cache ps-lf-cache ps-rf-cache))
edf0b0c5 4848
319acba0 4849;; These functions insert the arrays that define the contents of the headers.
ef2cbb24 4850
12d89a2e 4851(defun ps-generate-header-line (fonttag &optional content)
319acba0 4852 (ps-output " [" fonttag " ")
12d89a2e 4853 (cond
319acba0
GM
4854 ;; Literal strings should be output as is -- the string must contain its own
4855 ;; PS string delimiters, '(' and ')', if necessary.
12d89a2e 4856 ((stringp content)
6bf5fb46 4857 (ps-output (ps-mule-encode-header-string content fonttag)))
12d89a2e 4858
319acba0
GM
4859 ;; Functions are called -- they should return strings; they will be inserted
4860 ;; as strings and the PS string delimiters added.
5d62baca 4861 ((functionp content)
6bf5fb46
GM
4862 (ps-output-string (ps-mule-encode-header-string (funcall content)
4863 fonttag)))
12d89a2e 4864
319acba0
GM
4865 ;; Variables will have their contents inserted. They should contain
4866 ;; strings, and will be inserted as strings.
12d89a2e 4867 ((and (symbolp content) (boundp content))
6bf5fb46
GM
4868 (ps-output-string (ps-mule-encode-header-string (symbol-value content)
4869 fonttag)))
12d89a2e
RS
4870
4871 ;; Anything else will get turned into an empty string.
4872 (t
4873 (ps-output-string "")))
319acba0 4874 (ps-output "]\n"))
12d89a2e 4875
319acba0
GM
4876(defun ps-generate-header (name fonttag0 fonttag1 contents)
4877 (ps-output "/" name "[\n")
4878 (and contents (> ps-header-lines 0)
4879 (let ((count 1))
4880 (ps-generate-header-line fonttag0 (car contents))
4881 (while (and (< count ps-header-lines)
4882 (setq contents (cdr contents)))
4883 (ps-generate-header-line fonttag1 (car contents))
4884 (setq count (1+ count)))))
4885 (ps-output "]def\n"))
12d89a2e 4886
bc0d41bd 4887
6e1b1da6
GM
4888(defun ps-output-boolean (name bool)
4889 (ps-output (format "/%s %s def\n" name (if bool "true" "false"))))
ef2cbb24 4890
06fb6aab 4891
319acba0
GM
4892(defun ps-output-frame-properties (name alist)
4893 (ps-output "/" name " ["
efa89c1f 4894 (ps-format-color (cdr (assq 'fore-color alist)) 0.0)
319acba0
GM
4895 (ps-format-color (cdr (assq 'back-color alist)) 0.9)
4896 (ps-float-format (or (cdr (assq 'border-width alist)) 0.4))
efa89c1f
GM
4897 (ps-format-color (cdr (assq 'border-color alist)) 0.0)
4898 (ps-format-color (cdr (assq 'shadow-color alist)) 0.0)
319acba0
GM
4899 "]def\n"))
4900
4901
87a16a06
RS
4902(defun ps-background-pages (page-list func)
4903 (if page-list
4904 (mapcar
bc0d41bd
KH
4905 #'(lambda (pages)
4906 (let ((start (if (consp pages) (car pages) pages))
4907 (end (if (consp pages) (cdr pages) pages)))
4908 (and (integerp start) (integerp end) (<= start end)
4909 (add-to-list 'ps-background-pages (vector start end func)))))
87a16a06
RS
4910 page-list)
4911 (setq ps-background-all-pages (cons func ps-background-all-pages))))
4912
4913
bc0d41bd
KH
4914(defconst ps-boundingbox-re
4915 "^%%BoundingBox:\
4916\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)\\s-+\\([0-9.]+\\)")
4917
4918
87a16a06
RS
4919(defun ps-get-boundingbox ()
4920 (save-excursion
4921 (set-buffer ps-spool-buffer)
4922 (save-excursion
bc0d41bd 4923 (if (re-search-forward ps-boundingbox-re nil t)
87a16a06
RS
4924 (vector (string-to-number ; lower x
4925 (buffer-substring (match-beginning 1) (match-end 1)))
4926 (string-to-number ; lower y
4927 (buffer-substring (match-beginning 2) (match-end 2)))
4928 (string-to-number ; upper x
4929 (buffer-substring (match-beginning 3) (match-end 3)))
4930 (string-to-number ; upper y
4931 (buffer-substring (match-beginning 4) (match-end 4))))
4932 (vector 0 0 0 0)))))
4933
4934
4935;; Emacs understands the %f format; we'll use it to limit color RGB values
4936;; to three decimals to cut down some on the size of the PostScript output.
eafa92bf 4937;; XEmacs will have to make do with %s (princ) for floats.
87a16a06 4938
b6d0ac87 4939(defvar ps-float-format (if (featurep 'xemacs)
cf04718a
SM
4940 "%s " ; XEmacs
4941 "%0.3f ")) ; Emacs
87a16a06
RS
4942
4943
4944(defun ps-float-format (value &optional default)
4945 (let ((literal (or value default)))
efa89c1f
GM
4946 (cond ((null literal)
4947 " ")
4948 ((numberp literal)
4949 (format ps-float-format (* literal 1.0))) ; force float number
4950 (t
4951 (format "%s " literal))
4952 )))
87a16a06
RS
4953
4954
4955(defun ps-background-text ()
4956 (mapcar
bc0d41bd
KH
4957 #'(lambda (text)
4958 (setq ps-background-text-count (1+ ps-background-text-count))
c3d6d211 4959 (ps-output (format "/ShowBackText-%d{\n" ps-background-text-count))
bc0d41bd
KH
4960 (ps-output-string (nth 0 text)) ; text
4961 (ps-output
4962 "\n"
4963 (ps-float-format (nth 4 text) 200.0) ; font size
4964 (format "/%s " (or (nth 3 text) "Times-Roman")) ; font name
4965 (ps-float-format (nth 6 text)
4966 "PrintHeight PrintPageWidth atan") ; rotation
4967 (ps-float-format (nth 5 text) 0.85) ; gray
4968 (ps-float-format (nth 1 text) "0") ; x position
8e234846 4969 (ps-float-format (nth 2 text) "0") ; y position
c3d6d211 4970 "\nShowBackText}def\n")
bc0d41bd
KH
4971 (ps-background-pages (nthcdr 7 text) ; page list
4972 (format "ShowBackText-%d\n"
4973 ps-background-text-count)))
87a16a06
RS
4974 ps-print-background-text))
4975
4976
4977(defun ps-background-image ()
4978 (mapcar
bc0d41bd
KH
4979 #'(lambda (image)
4980 (let ((image-file (expand-file-name (nth 0 image))))
41481e4b
KH
4981 (when (file-readable-p image-file)
4982 (setq ps-background-image-count (1+ ps-background-image-count))
4983 (ps-output
c3d6d211 4984 (format "/ShowBackImage-%d{\n--back-- "
41481e4b
KH
4985 ps-background-image-count)
4986 (ps-float-format (nth 5 image) 0.0) ; rotation
4987 (ps-float-format (nth 3 image) 1.0) ; x scale
4988 (ps-float-format (nth 4 image) 1.0) ; y scale
4989 (ps-float-format (nth 1 image) ; x position
4990 "PrintPageWidth 2 div")
4991 (ps-float-format (nth 2 image) ; y position
4992 "PrintHeight 2 div BottomMargin add")
4993 "\nBeginBackImage\n")
4994 (ps-insert-file image-file)
01cdabc6 4995 ;; coordinate adjustment to center image
41481e4b
KH
4996 ;; around x and y position
4997 (let ((box (ps-get-boundingbox)))
4998 (save-excursion
4999 (set-buffer ps-spool-buffer)
5000 (save-excursion
5001 (if (re-search-backward "^--back--" nil t)
5002 (replace-match
5003 (format "%s %s"
5004 (ps-float-format
5005 (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
5006 (aref box 0))))
5007 (ps-float-format
5008 (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
5009 (aref box 1)))))
5010 t)))))
c3d6d211 5011 (ps-output "\nEndBackImage}def\n")
41481e4b
KH
5012 (ps-background-pages (nthcdr 6 image) ; page list
5013 (format "ShowBackImage-%d\n"
5014 ps-background-image-count)))))
87a16a06
RS
5015 ps-print-background-image))
5016
5017
a18ed129 5018(defun ps-background (page-number)
87a16a06 5019 (let (has-local-background)
bc0d41bd
KH
5020 (mapcar #'(lambda (range)
5021 (and (<= (aref range 0) page-number)
5022 (<= page-number (aref range 1))
5023 (if has-local-background
5024 (ps-output (aref range 2))
5025 (setq has-local-background t)
c3d6d211 5026 (ps-output "/printLocalBackground{\n"
bc0d41bd 5027 (aref range 2)))))
87a16a06 5028 ps-background-pages)
c3d6d211 5029 (and has-local-background (ps-output "}def\n"))))
87a16a06
RS
5030
5031
0140c600
EZ
5032;; Return a list of the distinct elements of LIST.
5033;; Elements are compared with `equal'.
5034(defun ps-remove-duplicates (list)
5035 (let (new (tail list))
5036 (while tail
5037 (or (member (car tail) new)
5038 (setq new (cons (car tail) new)))
5039 (setq tail (cdr tail)))
5040 (nreverse new)))
5041
c82b4a75 5042
6bdb808e
RS
5043;; Find the first occurrence of ITEM in LIST.
5044;; Return the index of the matching item, or nil if not found.
5045;; Elements are compared with `eq'.
7ae35a2f 5046(defun ps-alist-position (item list)
6bdb808e
RS
5047 (let ((tail list) (index 0) found)
5048 (while tail
7ae35a2f 5049 (if (setq found (eq (car (car tail)) item))
6bdb808e
RS
5050 (setq tail nil)
5051 (setq index (1+ index)
5052 tail (cdr tail))))
5053 (and found index)))
5054
5055
bc0d41bd
KH
5056(defconst ps-n-up-database
5057 '((a4
5058 (1 nil 1 1 0)
5059 (2 t 1 2 0)
5060 (4 nil 2 2 0)
5061 (6 t 2 3 1)
5062 (8 t 2 4 0)
5063 (9 nil 3 3 0)
5064 (12 t 3 4 2)
5065 (16 nil 4 4 0)
5066 (18 t 3 6 0)
5067 (20 nil 5 4 1)
5068 (25 nil 5 5 0)
5069 (30 nil 6 5 1)
5070 (32 t 4 8 0)
5071 (36 nil 6 6 0)
5072 (42 nil 7 6 1)
5073 (49 nil 7 7 0)
5074 (50 t 5 10 0)
5075 (56 nil 8 7 1)
5076 (64 nil 8 8 0)
5077 (72 nil 9 8 1)
5078 (81 nil 9 9 0)
5079 (90 nil 10 9 1)
5080 (100 nil 10 10 0))
5081 (a3
5082 (1 nil 1 1 0)
5083 (2 t 1 2 0)
5084 (4 nil 2 2 0)
5085 (6 t 2 3 1)
5086 (8 t 2 4 0)
5087 (9 nil 3 3 0)
5088 (12 nil 4 3 1)
5089 (16 nil 4 4 0)
5090 (18 t 3 6 0)
5091 (20 nil 5 4 1)
5092 (25 nil 5 5 0)
5093 (30 nil 6 5 1)
5094 (32 t 4 8 0)
5095 (36 nil 6 6 0)
5096 (42 nil 7 6 1)
5097 (49 nil 7 7 0)
5098 (50 t 5 10 0)
5099 (56 nil 8 7 1)
5100 (64 nil 8 8 0)
5101 (72 nil 9 8 1)
5102 (81 nil 9 9 0)
5103 (90 nil 10 9 1)
5104 (100 nil 10 10 0))
5105 (letter
5106 (1 nil 1 1 0)
8e234846 5107 (2 t 1 2 0) ; adjusted by PostScript code
bc0d41bd
KH
5108 (4 nil 2 2 0)
5109 (6 t 2 3 0)
5110 (9 nil 3 3 0)
5111 (12 nil 4 3 1)
5112 (16 nil 4 4 0)
5113 (20 nil 5 4 1)
5114 (25 nil 5 5 0)
5115 (30 nil 6 5 1)
5116 (36 nil 6 6 0)
5117 (40 t 5 8 0)
5118 (42 nil 7 6 1)
5119 (49 nil 7 7 0)
5120 (56 nil 8 7 1)
5121 (64 nil 8 8 0)
5122 (72 nil 9 8 1)
5123 (81 nil 9 9 0)
5124 (90 nil 10 9 1)
5125 (100 nil 10 10 0))
5126 (legal
5127 (1 nil 1 1 0)
5128 (2 t 1 2 0)
5129 (4 nil 2 2 0)
5130 (6 nil 3 2 1)
5131 (9 nil 3 3 0)
5132 (10 t 2 5 0)
5133 (12 nil 4 3 1)
5134 (16 nil 4 4 0)
5135 (20 nil 5 4 1)
5136 (25 nil 5 5 0)
5137 (30 nil 6 5 1)
5138 (36 nil 6 6 0)
5139 (42 nil 7 6 1)
5140 (49 nil 7 7 0)
5141 (56 nil 8 7 1)
5142 (64 nil 8 8 0)
5143 (70 t 5 14 0)
5144 (72 nil 9 8 1)
5145 (81 nil 9 9 0)
5146 (90 nil 10 9 1)
5147 (100 nil 10 10 0))
5148 (letter-small
5149 (1 nil 1 1 0)
8e234846 5150 (2 t 1 2 0) ; adjusted by PostScript code
bc0d41bd
KH
5151 (4 nil 2 2 0)
5152 (6 t 2 3 0)
5153 (9 nil 3 3 0)
5154 (12 t 3 4 1)
5155 (15 t 3 5 0)
5156 (16 nil 4 4 0)
5157 (20 nil 5 4 1)
5158 (25 nil 5 5 0)
5159 (28 t 4 7 0)
5160 (30 nil 6 5 1)
5161 (36 nil 6 6 0)
5162 (40 t 5 8 0)
5163 (42 nil 7 6 1)
5164 (49 nil 7 7 0)
5165 (56 nil 8 7 1)
5166 (60 t 6 10 0)
5167 (64 nil 8 8 0)
5168 (72 ni 9 8 1)
5169 (81 nil 9 9 0)
5170 (84 t 7 12 0)
5171 (90 nil 10 9 1)
5172 (100 nil 10 10 0))
5173 (tabloid
5174 (1 nil 1 1 0)
5175 (2 t 1 2 0)
5176 (4 nil 2 2 0)
5177 (6 t 2 3 1)
5178 (8 t 2 4 0)
5179 (9 nil 3 3 0)
5180 (12 nil 4 3 1)
5181 (16 nil 4 4 0)
5182 (20 nil 5 4 1)
5183 (25 nil 5 5 0)
5184 (30 nil 6 5 1)
5185 (36 nil 6 6 0)
5186 (42 nil 7 6 1)
5187 (49 nil 7 7 0)
5188 (56 nil 8 7 1)
5189 (64 nil 8 8 0)
5190 (72 nil 9 8 1)
5191 (81 nil 9 9 0)
5192 (84 t 6 14 0)
5193 (90 nil 10 9 1)
5194 (100 nil 10 10 0))
5195 ;; Ledger paper size is a special case, it is the only paper size where the
5196 ;; normal size is landscaped, that is, the height is smaller than width.
5197 ;; So, we use the special value `pag' in the `landscape' field.
5198 (ledger
5199 (1 nil 1 1 0)
5200 (2 pag 1 2 0)
5201 (4 nil 2 2 0)
5202 (6 pag 2 3 1)
5203 (8 pag 2 4 0)
5204 (9 nil 3 3 0)
5205 (12 nil 4 3 1)
5206 (16 nil 4 4 0)
5207 (20 nil 5 4 1)
5208 (25 nil 5 5 0)
5209 (30 nil 6 5 1)
5210 (36 nil 6 6 0)
5211 (42 nil 7 6 1)
5212 (49 nil 7 7 0)
5213 (56 nil 8 7 1)
5214 (64 nil 8 8 0)
5215 (72 nil 9 8 1)
5216 (81 nil 9 9 0)
5217 (84 pag 6 14 0)
5218 (90 nil 10 9 1)
5219 (100 nil 10 10 0))
5220 (statement
5221 (1 nil 1 1 0)
5222 (2 t 1 2 0)
5223 (4 nil 2 2 0)
5224 (6 nil 3 2 1)
5225 (9 nil 3 3 0)
5226 (10 t 2 5 0)
5227 (12 nil 4 3 1)
5228 (16 nil 4 4 0)
5229 (20 nil 5 4 1)
5230 (21 t 3 7 0)
5231 (25 nil 5 5 0)
5232 (30 nil 6 5 1)
5233 (36 nil 6 6 0)
5234 (40 t 4 10 0)
5235 (42 nil 7 6 1)
5236 (49 nil 7 7 0)
5237 (56 nil 8 7 1)
5238 (60 t 5 12 0)
5239 (64 nil 8 8 0)
5240 (72 nil 9 8 1)
5241 (81 nil 9 9 0)
5242 (90 nil 10 9 1)
5243 (100 nil 10 10 0))
5244 (executive
5245 (1 nil 1 1 0)
8e234846 5246 (2 t 1 2 0) ; adjusted by PostScript code
bc0d41bd
KH
5247 (4 nil 2 2 0)
5248 (6 t 2 3 0)
5249 (9 nil 3 3 0)
5250 (12 nil 4 3 1)
5251 (16 nil 4 4 0)
5252 (20 nil 5 4 1)
5253 (25 nil 5 5 0)
5254 (28 t 4 7 0)
5255 (30 nil 6 5 1)
5256 (36 nil 6 6 0)
5257 (42 nil 7 6 1)
5258 (45 t 5 9 0)
5259 (49 nil 7 7 0)
5260 (56 nil 8 7 1)
5261 (60 t 6 10 0)
5262 (64 nil 8 8 0)
5263 (72 nil 9 8 1)
5264 (81 nil 9 9 0)
5265 (84 t 7 12 0)
5266 (90 nil 10 9 1)
5267 (100 nil 10 10 0))
5268 (a4small
5269 (1 nil 1 1 0)
5270 (2 t 1 2 0)
5271 (4 nil 2 2 0)
5272 (6 t 2 3 1)
5273 (8 t 2 4 0)
5274 (9 nil 3 3 0)
5275 (12 nil 4 3 1)
5276 (16 nil 4 4 0)
5277 (18 t 3 6 0)
5278 (20 nil 5 4 1)
5279 (25 nil 5 5 0)
5280 (30 nil 6 5 1)
5281 (32 t 4 8 0)
5282 (36 nil 6 6 0)
5283 (42 nil 7 6 1)
5284 (49 nil 7 7 0)
5285 (50 t 5 10 0)
5286 (56 nil 8 7 1)
5287 (64 nil 8 8 0)
5288 (72 nil 9 8 1)
5289 (78 t 6 13 0)
5290 (81 nil 9 9 0)
5291 (90 nil 10 9 1)
5292 (100 nil 10 10 0))
5293 (b4
5294 (1 nil 1 1 0)
5295 (2 t 1 2 0)
5296 (4 nil 2 2 0)
5297 (6 t 2 3 1)
5298 (8 t 2 4 0)
5299 (9 nil 3 3 0)
5300 (12 nil 4 3 1)
5301 (16 nil 4 4 0)
5302 (18 t 3 6 0)
5303 (20 nil 5 4 1)
5304 (25 nil 5 5 0)
5305 (30 nil 6 5 1)
5306 (32 t 4 8 0)
5307 (36 nil 6 6 0)
5308 (42 nil 7 6 1)
5309 (49 nil 7 7 0)
5310 (50 t 5 10 0)
5311 (56 nil 8 7 1)
5312 (64 nil 8 8 0)
5313 (72 nil 9 8 1)
5314 (81 nil 9 9 0)
5315 (90 nil 10 9 1)
5316 (100 nil 10 10 0))
5317 (b5
5318 (1 nil 1 1 0)
5319 (2 t 1 2 0)
5320 (4 nil 2 2 0)
5321 (6 t 2 3 1)
5322 (8 t 2 4 0)
5323 (9 nil 3 3 0)
5324 (12 nil 4 3 1)
5325 (16 nil 4 4 0)
5326 (18 t 3 6 0)
5327 (20 nil 5 4 1)
5328 (25 nil 5 5 0)
5329 (30 nil 6 5 1)
5330 (32 t 4 8 0)
5331 (36 nil 6 6 0)
5332 (42 nil 7 6 1)
5333 (49 nil 7 7 0)
5334 (50 t 5 10 0)
5335 (56 nil 8 7 1)
5336 (64 nil 8 8 0)
5337 (72 nil 9 8 0)
5338 (81 nil 9 9 0)
5339 (90 nil 10 9 1)
5340 (98 t 7 14 0)
5341 (100 nil 10 10 0)))
5342 "Alist which is the page matrix database used for N-up printing.
5343
5344Each element has the following form:
5345
5346 (PAGE
5347 (MAX LANDSCAPE LINES COLUMNS COL-MISSING)
5348 ...)
5349
5350Where:
5351PAGE is the page size used (see `ps-paper-type').
5352MAX is the maximum elements of this page matrix.
5353LANDSCAPE specifies if page matrix is landscaped, has the following valid
5354 values:
5355 nil the sheet is in portrait mode.
5356 t the sheet is in landscape mode.
5357 pag the sheet is in portrait mode and page is in landscape mode.
5358LINES is the number of lines of page matrix.
5359COLUMNS is the number of columns of page matrix.
5360COL-MISSING is the number of columns missing to fill the sheet.")
5361
5362
5363(defmacro ps-n-up-landscape (mat) `(nth 1 ,mat))
5364(defmacro ps-n-up-lines (mat) `(nth 2 ,mat))
5365(defmacro ps-n-up-columns (mat) `(nth 3 ,mat))
5366(defmacro ps-n-up-missing (mat) `(nth 4 ,mat))
5367
5368
5369(defun ps-n-up-printing ()
5370 ;; force `ps-n-up-printing' be in range 1 to 100.
5371 (setq ps-n-up-printing (max (min ps-n-up-printing 100) 1))
5372 ;; find suitable page matrix for a given `ps-paper-type'.
5373 (let ((the-list (cdr (assq ps-paper-type ps-n-up-database))))
5374 (and the-list
5375 (while (> ps-n-up-printing (caar the-list))
5376 (setq the-list (cdr the-list))))
5377 (car the-list)))
5378
5379
5380(defconst ps-n-up-filling-database
5381 '((left-top
5382 "PageWidth" ; N-Up-XColumn
5383 "0" ; N-Up-YColumn
5384 "N-Up-End 1 sub PageWidth mul neg" ; N-Up-XLine
5385 "LandscapePageHeight neg" ; N-Up-YLine
5386 "N-Up-Lines" ; N-Up-Repeat
5387 "N-Up-Columns" ; N-Up-End
5388 "0" ; N-Up-XStart
5389 "0") ; N-Up-YStart
5390 (left-bottom
5391 "PageWidth" ; N-Up-XColumn
5392 "0" ; N-Up-YColumn
5393 "N-Up-End 1 sub PageWidth mul neg" ; N-Up-XLine
5394 "LandscapePageHeight" ; N-Up-YLine
5395 "N-Up-Lines" ; N-Up-Repeat
5396 "N-Up-Columns" ; N-Up-End
5397 "0" ; N-Up-XStart
5398 "N-Up-Repeat 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
5399 (right-top
5400 "PageWidth neg" ; N-Up-XColumn
5401 "0" ; N-Up-YColumn
5402 "N-Up-End 1 sub PageWidth mul" ; N-Up-XLine
5403 "LandscapePageHeight neg" ; N-Up-YLine
5404 "N-Up-Lines" ; N-Up-Repeat
5405 "N-Up-Columns" ; N-Up-End
5406 "N-Up-End 1 sub PageWidth mul" ; N-Up-XStart
5407 "0") ; N-Up-YStart
5408 (right-bottom
5409 "PageWidth neg" ; N-Up-XColumn
5410 "0" ; N-Up-YColumn
5411 "N-Up-End 1 sub PageWidth mul" ; N-Up-XLine
5412 "LandscapePageHeight" ; N-Up-YLine
5413 "N-Up-Lines" ; N-Up-Repeat
5414 "N-Up-Columns" ; N-Up-End
5415 "N-Up-End 1 sub PageWidth mul" ; N-Up-XStart
5416 "N-Up-Repeat 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
5417 (top-left
5418 "0" ; N-Up-XColumn
5419 "LandscapePageHeight neg" ; N-Up-YColumn
5420 "PageWidth" ; N-Up-XLine
5421 "N-Up-End 1 sub LandscapePageHeight mul" ; N-Up-YLine
5422 "N-Up-Columns" ; N-Up-Repeat
5423 "N-Up-Lines" ; N-Up-End
5424 "0" ; N-Up-XStart
5425 "0") ; N-Up-YStart
5426 (bottom-left
5427 "0" ; N-Up-XColumn
5428 "LandscapePageHeight" ; N-Up-YColumn
5429 "PageWidth" ; N-Up-XLine
5430 "N-Up-End 1 sub LandscapePageHeight mul neg" ; N-Up-YLine
5431 "N-Up-Columns" ; N-Up-Repeat
5432 "N-Up-Lines" ; N-Up-End
5433 "0" ; N-Up-XStart
5434 "N-Up-End 1 sub LandscapePageHeight mul neg") ; N-Up-YStart
5435 (top-right
5436 "0" ; N-Up-XColumn
5437 "LandscapePageHeight neg" ; N-Up-YColumn
5438 "PageWidth neg" ; N-Up-XLine
5439 "N-Up-End 1 sub LandscapePageHeight mul" ; N-Up-YLine
5440 "N-Up-Columns" ; N-Up-Repeat
5441 "N-Up-Lines" ; N-Up-End
5442 "N-Up-Repeat 1 sub PageWidth mul" ; N-Up-XStart
5443 "0") ; N-Up-YStart
5444 (bottom-right
5445 "0" ; N-Up-XColumn
5446 "LandscapePageHeight" ; N-Up-YColumn
5447 "PageWidth neg" ; N-Up-XLine
5448 "N-Up-End 1 sub LandscapePageHeight mul neg" ; N-Up-YLine
5449 "N-Up-Columns" ; N-Up-Repeat
5450 "N-Up-Lines" ; N-Up-End
5451 "N-Up-Repeat 1 sub PageWidth mul" ; N-Up-XStart
5452 "N-Up-End 1 sub LandscapePageHeight mul neg")) ; N-Up-YStart
5453 "Alist for n-up printing initializations.
5454
5455Each element has the following form:
5456
5457 (KIND XCOL YCOL XLIN YLIN REPEAT END XSTART YSTART)
5458
5459Where:
5460KIND is a valid value of `ps-n-up-filling'.
5461XCOL YCOL are the relative position for the next column.
5462XLIN YLIN are the relative position for the beginning of next line.
5463REPEAT is the number of repetions for external loop.
5464END is the number of repetions for internal loop and also the number of pages in
5465 a row.
5466XSTART YSTART are the relative position for the first page in a sheet.")
5467
5468
5469(defun ps-n-up-filling ()
5470 (cdr (or (assq ps-n-up-filling ps-n-up-filling-database)
5471 (assq 'left-top ps-n-up-filling-database))))
5472
5473
5474(defmacro ps-n-up-xcolumn (init) `(nth 0 ,init))
5475(defmacro ps-n-up-ycolumn (init) `(nth 1 ,init))
5476(defmacro ps-n-up-xline (init) `(nth 2 ,init))
5477(defmacro ps-n-up-yline (init) `(nth 3 ,init))
5478(defmacro ps-n-up-repeat (init) `(nth 4 ,init))
5479(defmacro ps-n-up-end (init) `(nth 5 ,init))
5480(defmacro ps-n-up-xstart (init) `(nth 6 ,init))
5481(defmacro ps-n-up-ystart (init) `(nth 7 ,init))
5482
5483
66e63857
GM
5484(defconst ps-error-handler-alist
5485 '((none . 0)
5486 (paper . 1)
5487 (system . 2)
5488 (paper-and-system . 3))
2bd80d73
GM
5489 "Alist for error handler message.")
5490
5491
5492(defconst ps-zebra-stripe-alist
5493 '((follow . 1)
5494 (full . 2)
5495 (full-follow . 3))
5496 "Alist for zebra stripe continuation.")
66e63857
GM
5497
5498
ef2cbb24 5499(defun ps-begin-file ()
7bb054a5 5500 (setq ps-page-order 0
4b3eb10f 5501 ps-page-printed 0
87a16a06
RS
5502 ps-background-text-count 0
5503 ps-background-image-count 0
5504 ps-background-pages nil
5505 ps-background-all-pages nil)
12d89a2e 5506
bc0d41bd
KH
5507 (let ((dimensions (cdr (assq ps-paper-type ps-page-dimensions-database)))
5508 (tumble (if ps-landscape-mode (not ps-spool-tumble) ps-spool-tumble))
5509 (n-up (ps-n-up-printing))
5510 (n-up-filling (ps-n-up-filling)))
98f2fbe7 5511 (and ps-n-up-on (setq tumble (not tumble)))
bc0d41bd
KH
5512 (ps-output
5513 ps-adobe-tag
5514 "%%Title: " (buffer-name) ; Take job name from name of
8bd22fcf 5515 ; first buffer printed
9586e1d3
VJL
5516 "\n%%Creator: ps-print v" ps-print-version
5517 "\n%%For: " (user-full-name)
5518 "\n%%CreationDate: " (format-time-string "%T %b %d %Y")
bc0d41bd
KH
5519 "\n%%Orientation: "
5520 (if ps-landscape-mode "Landscape" "Portrait")
5521 "\n%%DocumentNeededResources: font Times-Roman Times-Italic\n%%+ font "
5522 (mapconcat 'identity
5523 (ps-remove-duplicates
5524 (append (ps-fonts 'ps-font-for-text)
5525 (list (ps-font 'ps-font-for-header 'normal)
9586e1d3
VJL
5526 (ps-font 'ps-font-for-header 'bold)
5527 (ps-font 'ps-font-for-footer 'normal)
5528 (ps-font 'ps-font-for-footer 'bold))))
bc0d41bd 5529 "\n%%+ font ")
9586e1d3 5530 "\n%%DocumentSuppliedResources: procset PSPrintUserDefinedPrologue-" (user-login-name) " 0 0"
bc0d41bd
KH
5531 "\n%%DocumentMedia: " (ps-page-dimensions-get-media dimensions)
5532 (format " %d" (round (ps-page-dimensions-get-width dimensions)))
5533 (format " %d" (round (ps-page-dimensions-get-height dimensions)))
5534 " 0 () ()\n%%PageOrder: Ascend\n%%Pages: (atend)\n%%Requirements:"
5535 (if ps-spool-duplex
8e234846 5536 (if tumble " duplex(tumble)\n" " duplex\n")
bc0d41bd
KH
5537 "\n"))
5538
66e63857 5539 (ps-insert-string ps-print-prologue-header)
bc0d41bd 5540
8e234846
GM
5541 (ps-output "%%EndComments\n%%BeginDefaults\n%%PageMedia: "
5542 (ps-page-dimensions-get-media dimensions)
6bf5fb46 5543 "\n%%EndDefaults\n\n%%BeginProlog\n\n"
6e1b1da6
GM
5544 "/languagelevel where{pop}{/languagelevel 1 def}ifelse\n"
5545 (format "/ErrorMessage %s def\n\n"
66e63857
GM
5546 (or (cdr (assoc ps-error-handler-message
5547 ps-error-handler-alist))
5548 1)) ; send to paper
5549 ps-print-prologue-0
9586e1d3 5550 "\n%%BeginResource: procset PSPrintUserDefinedPrologue-" (user-login-name) " 0 0\n\n")
66e63857
GM
5551
5552 (ps-insert-string ps-user-defined-prologue)
5553
9586e1d3 5554 (ps-output "\n%%EndResource\n\n")
bc0d41bd 5555
bc0d41bd
KH
5556 (ps-output-boolean "LandscapeMode "
5557 (or ps-landscape-mode
5558 (eq (ps-n-up-landscape n-up) 'pag)))
906d41a7 5559 (ps-output-boolean "UpsideDown " ps-print-upside-down)
bc0d41bd
KH
5560 (ps-output (format "/NumberOfColumns %d def\n" ps-number-of-columns)
5561
5562 (format "/LandscapePageHeight %s def\n" ps-landscape-page-height)
5563 (format "/PrintPageWidth %s def\n"
5564 (- (* (+ ps-print-width ps-inter-column)
5565 ps-number-of-columns)
5566 ps-inter-column))
5567 (format "/PrintWidth %s def\n" ps-print-width)
5568 (format "/PrintHeight %s def\n" ps-print-height)
5569
5570 (format "/LeftMargin %s def\n" ps-left-margin)
5571 (format "/RightMargin %s def\n" ps-right-margin)
5572 (format "/InterColumn %s def\n" ps-inter-column)
5573
5574 (format "/BottomMargin %s def\n" ps-bottom-margin)
5575 (format "/TopMargin %s def\n" ps-top-margin) ; not used
5576 (format "/HeaderOffset %s def\n" ps-header-offset)
319acba0
GM
5577 (format "/HeaderPad %s def\n" ps-header-pad)
5578 (format "/FooterOffset %s def\n" ps-footer-offset)
5579 (format "/FooterPad %s def\n" ps-footer-pad)
5580 (format "/FooterLines %s def\n" ps-footer-lines))
bc0d41bd 5581
319acba0 5582 (ps-output-boolean "ShowNofN " ps-show-n-of-n)
8e234846
GM
5583 (ps-output-boolean "SwitchHeader " (if (eq ps-switch-header 'duplex)
5584 ps-spool-duplex
5585 ps-switch-header))
319acba0
GM
5586 (ps-output-boolean "PrintOnlyOneHeader" ps-print-only-one-header)
5587 (ps-output-boolean "PrintHeader " ps-print-header)
5588 (ps-output-boolean "PrintHeaderFrame " ps-print-header-frame)
5589 (ps-output-frame-properties "HeaderFrameProperties" ps-header-frame-alist)
5590 (ps-output-boolean "PrintFooter " ps-print-footer)
5591 (ps-output-boolean "PrintFooterFrame " ps-print-footer-frame)
5592 (ps-output-frame-properties "FooterFrameProperties" ps-footer-frame-alist)
bc0d41bd
KH
5593
5594 (let ((line-height (ps-line-height 'ps-font-for-text)))
6bf5fb46
GM
5595 (ps-output (format "/LineSpacing %s def\n" ps-line-spacing-internal)
5596 (format "/ParagraphSpacing %s def\n"
5597 ps-paragraph-spacing-internal)
5598 (format "/LineHeight %s def\n" line-height)
2bd80d73 5599 (format "/LinesPerColumn %d def\n"
6bf5fb46
GM
5600 (let ((height (+ line-height
5601 ps-line-spacing-internal)))
5602 (round (/ (+ ps-print-height
5603 (* height 0.45))
5604 height))))))
bc0d41bd 5605
8e234846 5606 (ps-output-boolean "WarnPaperSize " ps-warn-paper-type)
bc0d41bd
KH
5607 (ps-output-boolean "Zebra " ps-zebra-stripes)
5608 (ps-output-boolean "PrintLineNumber " ps-line-number)
906d41a7 5609 (ps-output-boolean "SyncLineZebra " (not (integerp ps-line-number-step)))
2bd80d73
GM
5610 (ps-output (format "/ZebraFollow %d def\n"
5611 (or (cdr (assq ps-zebra-stripe-follow
5612 ps-zebra-stripe-alist))
5613 0))
5614 (format "/PrintLineStep %d def\n"
906d41a7
GM
5615 (if (integerp ps-line-number-step)
5616 ps-line-number-step
98f2fbe7
GM
5617 ps-zebra-stripe-height))
5618 (format "/PrintLineStart %d def\n" ps-line-number-start)
319acba0
GM
5619 "/LineNumberColor "
5620 (ps-format-color ps-line-number-color 0.0)
5621 (format "def\n/ZebraHeight %d def\n"
5622 ps-zebra-stripe-height)
6e1b1da6
GM
5623 "/ZebraColor "
5624 (ps-format-color ps-zebra-color 0.95)
3f0257cb
VJL
5625 "def\n")
5626 (ps-output "/BackgroundColor "
e59d29d6 5627 (ps-format-color ps-default-background 1.0)
3f0257cb
VJL
5628 "def\n")
5629 (ps-output "/UseSetpagedevice "
bc0d41bd 5630 (if (eq ps-spool-config 'setpagedevice)
6e1b1da6
GM
5631 "/setpagedevice where{pop languagelevel 2 eq}{false}ifelse"
5632 "false")
5633 " def\n\n/PageWidth "
bc0d41bd
KH
5634 "PrintPageWidth LeftMargin add RightMargin add def\n\n"
5635 (format "/N-Up %d def\n" ps-n-up-printing))
5636 (ps-output-boolean "N-Up-Landscape" (eq (ps-n-up-landscape n-up) t))
5637 (ps-output-boolean "N-Up-Border " ps-n-up-border-p)
5638 (ps-output (format "/N-Up-Lines %d def\n" (ps-n-up-lines n-up))
5639 (format "/N-Up-Columns %d def\n" (ps-n-up-columns n-up))
5640 (format "/N-Up-Missing %d def\n" (ps-n-up-missing n-up))
6e1b1da6
GM
5641 (format "/N-Up-Margin %s def\n" ps-n-up-margin)
5642 "/N-Up-Repeat "
bc0d41bd
KH
5643 (if ps-landscape-mode
5644 (ps-n-up-end n-up-filling)
5645 (ps-n-up-repeat n-up-filling))
5646 " def\n/N-Up-End "
5647 (if ps-landscape-mode
5648 (ps-n-up-repeat n-up-filling)
5649 (ps-n-up-end n-up-filling))
5650 " def\n/N-Up-XColumn " (ps-n-up-xcolumn n-up-filling)
5651 " def\n/N-Up-YColumn " (ps-n-up-ycolumn n-up-filling)
5652 " def\n/N-Up-XLine " (ps-n-up-xline n-up-filling)
5653 " def\n/N-Up-YLine " (ps-n-up-yline n-up-filling)
5654 " def\n/N-Up-XStart " (ps-n-up-xstart n-up-filling)
5655 " def\n/N-Up-YStart " (ps-n-up-ystart n-up-filling) " def\n")
5656
5657 (ps-background-text)
5658 (ps-background-image)
5659 (setq ps-background-all-pages (nreverse ps-background-all-pages)
5660 ps-background-pages (nreverse ps-background-pages))
5661
47a97a6d
VJL
5662 (ps-output "\n" ps-print-prologue-1
5663 "\n/printGlobalBackground{\n")
7bb054a5 5664 (mapcar 'ps-output ps-background-all-pages)
9586e1d3 5665 (ps-output
47a97a6d
VJL
5666 "}def\n/printLocalBackground{\n}def\n"
5667 "\n%%EndProlog\n\n%%BeginSetup\n"
9586e1d3 5668 "\n%%IncludeResource: font Times-Roman"
47a97a6d
VJL
5669 "\n%%IncludeResource: font Times-Italic"
5670 "\n%%IncludeResource: font "
9586e1d3
VJL
5671 (mapconcat 'identity
5672 (ps-remove-duplicates
5673 (append (ps-fonts 'ps-font-for-text)
5674 (list (ps-font 'ps-font-for-header 'normal)
5675 (ps-font 'ps-font-for-header 'bold)
5676 (ps-font 'ps-font-for-footer 'normal)
5677 (ps-font 'ps-font-for-footer 'bold))))
5678 "\n%%IncludeResource: font ")
47a97a6d
VJL
5679 ;; Header/line number fonts
5680 (format "\n/h0 %s(%s)cvn DefFont\n" ; /h0 14/Helvetica-Bold DefFont
5681 ps-header-title-font-size-internal
5682 (ps-font 'ps-font-for-header 'bold))
5683 (format "/h1 %s(%s)cvn DefFont\n" ; /h1 12/Helvetica DefFont
5684 ps-header-font-size-internal
5685 (ps-font 'ps-font-for-header 'normal))
5686 (format "/L0 %s(%s)cvn DefFont\n" ; /L0 6/Times-Italic DefFont
5687 (ps-get-font-size 'ps-line-number-font-size)
5688 ps-line-number-font)
5689 (format "/H0 %s(%s)cvn DefFont\n" ; /H0 12/Helvetica DefFont
5690 ps-footer-font-size-internal
5691 (ps-font 'ps-font-for-footer 'normal))
5692 "\n\n% ---- These lines must be kept together because...
6bf5fb46
GM
5693
5694/h0 F
5695/HeaderTitleLineHeight FontHeight def
5696
5697/h1 F
5698/HeaderLineHeight FontHeight def
5699/HeaderDescent Descent def
5700
319acba0
GM
5701/H0 F
5702/FooterLineHeight FontHeight def
5703/FooterDescent Descent def
5704
6bf5fb46 5705% ---- ...because `F' has a side-effect on `FontHeight' and `Descent'\n\n")
bc0d41bd
KH
5706
5707 ;; Text fonts
5708 (let ((font (ps-font-alist 'ps-font-for-text))
5709 (i 0))
5710 (while font
c3d6d211 5711 (ps-output (format "/f%d %s(%s)cvn DefFont\n"
bc0d41bd
KH
5712 i
5713 ps-font-size-internal
5714 (ps-font 'ps-font-for-text (car (car font)))))
5715 (setq font (cdr font)
5716 i (1+ i))))
5717
5718 (let ((font-entry (cdr (assq ps-font-family ps-font-info-database))))
5719 (ps-output (format "/SpaceWidthRatio %f def\n"
5720 (/ (ps-lookup 'space-width) (ps-lookup 'size)))))
5721
bc0d41bd
KH
5722 (unless (eq ps-spool-config 'lpr-switches)
5723 (ps-output "\n%%BeginFeature: *Duplex "
5724 (ps-boolean-capitalized ps-spool-duplex)
5725 " *Tumble "
5726 (ps-boolean-capitalized tumble)
c3d6d211
GM
5727 "\nUseSetpagedevice\n{BMark/Duplex "
5728 (ps-boolean-constant ps-spool-duplex)
5729 "/Tumble "
5730 (ps-boolean-constant tumble)
5731 " EMark setpagedevice}\n{statusdict begin "
5732 (ps-boolean-constant ps-spool-duplex)
5733 " setduplexmode "
5734 (ps-boolean-constant tumble)
5735 " settumble end}ifelse\n%%EndFeature\n")))
8e234846
GM
5736 (ps-output "\n%%BeginFeature: *ManualFeed "
5737 (ps-boolean-capitalized ps-manual-feed)
5738 "\nBMark /ManualFeed "
5739 (ps-boolean-constant ps-manual-feed)
ef1159c2 5740 " EMark setpagedevice\n%%EndFeature\n\nBeginDoc\n%%EndSetup\n")
47d2ac75 5741 (and ps-banner-page-when-duplexing
98f2fbe7 5742 (ps-output "\n%%Page: banner 0\nsave showpage restore\n")))
bc0d41bd
KH
5743
5744
6e1b1da6
GM
5745(defun ps-format-color (color &optional default)
5746 (let ((the-color (if (stringp color)
5747 (ps-color-scale color)
5748 color)))
5749 (if (and the-color (listp the-color))
5750 (concat "["
5751 (format ps-color-format
efa89c1f
GM
5752 (* (nth 0 the-color) 1.0) ; force float number
5753 (* (nth 1 the-color) 1.0) ; force float number
5754 (* (nth 2 the-color) 1.0)) ; force float number
6e1b1da6
GM
5755 "] ")
5756 (ps-float-format (if (numberp the-color) the-color default)))))
5757
5758
66e63857
GM
5759(defun ps-insert-string (prologue)
5760 (let ((str (if (functionp prologue)
5761 (funcall prologue)
5762 prologue)))
5763 (and (stringp str)
5764 (ps-output str))))
5765
5766
bc0d41bd
KH
5767(defun ps-boolean-capitalized (bool)
5768 (if bool "True" "False"))
5769
ef2cbb24 5770
8e234846
GM
5771(defun ps-boolean-constant (bool)
5772 (if bool "true" "false"))
5773
5774
12d89a2e
RS
5775(defun ps-header-dirpart ()
5776 (let ((fname (buffer-file-name)))
5777 (if fname
5778 (if (string-equal (buffer-name) (file-name-nondirectory fname))
68e684a0 5779 (abbreviate-file-name (file-name-directory fname))
12d89a2e
RS
5780 fname)
5781 "")))
ef2cbb24 5782
bc0d41bd 5783
12d89a2e 5784(defun ps-get-buffer-name ()
bcc0d457
RS
5785 (cond
5786 ;; Indulge Jim this little easter egg:
5787 ((string= (buffer-name) "ps-print.el")
5788 "Hey, Cool! It's ps-print.el!!!")
5789 ;; Indulge Jack this other little easter egg:
5790 ((string= (buffer-name) "sokoban.el")
5791 "Super! C'est sokoban.el!")
87a16a06 5792 (t (concat
bc0d41bd 5793 (and ps-printing-region-p "Subset of: ")
87a16a06
RS
5794 (buffer-name)
5795 (and (buffer-modified-p) " (unsaved)")))))
ef2cbb24 5796
7d8b7e8e 5797
6bf5fb46
GM
5798(defun ps-get-size (size mess &optional arg)
5799 (let ((siz (cond ((numberp size)
5800 size)
5801 ((and (consp size)
5802 (numberp (car size))
5803 (numberp (cdr size)))
5804 (if ps-landscape-mode
5805 (car size)
5806 (cdr size)))
5807 (t
5808 -1))))
5809 (and (< siz 0)
5810 (error "Invalid %s `%S'%s"
5811 mess size
5812 (if arg
5813 (format " for `%S'" arg)
5814 "")))
5815 siz))
5816
5817
7d8b7e8e 5818(defun ps-get-font-size (font-sym)
6bf5fb46 5819 (ps-get-size (symbol-value font-sym) "font size" font-sym))
7d8b7e8e
KH
5820
5821
c6f33bac
VJL
5822(defun ps-rgb-color (color unspecified default)
5823 (cond
5824 ;; (float float float) ==> (R G B)
5825 ((and color (listp color) (= (length color) 3)
5826 (let ((cl color)
5827 (ok t) e)
5828 (while (and ok cl)
5829 (setq e (car cl)
5830 cl (cdr cl)
5831 ok (and (floatp e) (<= 0.0 e) (<= e 1.0))))
5832 ok))
5833 color)
5834 ;; float ==> 0.0 = black .. 1.0 = white
5835 ((and (floatp color) (<= 0.0 color) (<= color 1.0))
5836 (list color color color))
5837 ;; "colorName" but different from "unspecified-[bf]g"
5838 ((and (stringp color) (not (string= color unspecified)))
5839 (ps-color-scale color))
5840 ;; ok, use the default
5841 (t
5842 (list default default default))))
319acba0
GM
5843
5844
5167749c 5845(defun ps-begin-job (genfunc)
1fd9b7fe 5846 ;; prologue files
41481e4b 5847 (or (equal ps-mark-code-directory ps-postscript-code-directory)
c3d6d211
GM
5848 (setq ps-print-prologue-0 (ps-prologue-file 0)
5849 ps-print-prologue-1 (ps-prologue-file 1)
c3d6d211 5850 ps-mark-code-directory ps-postscript-code-directory))
1fd9b7fe
GM
5851 ;; selected pages
5852 (let (new page)
5853 (while ps-selected-pages
5854 (setq page (car ps-selected-pages)
5855 ps-selected-pages (cdr ps-selected-pages))
5856 (cond ((integerp page)
5857 (and (> page 0)
5858 (setq new (cons (cons page page) new))))
5859 ((consp page)
5860 (and (integerp (car page)) (integerp (cdr page))
5861 (> (car page) 0)
5862 (<= (car page) (cdr page))
5863 (setq new (cons page new))))))
5864 (setq ps-selected-pages (sort new #'(lambda (one other)
5865 (< (car one) (car other))))
5866 ps-last-selected-pages ps-selected-pages
5867 ps-first-page nil
5868 ps-last-page nil))
5869 ;; face background
906d41a7
GM
5870 (or (listp ps-use-face-background)
5871 (setq ps-use-face-background t))
1fd9b7fe 5872 ;; line number
906d41a7
GM
5873 (and (integerp ps-line-number-step)
5874 (<= ps-line-number-step 0)
5875 (setq ps-line-number-step 1))
98f2fbe7
GM
5876 (setq ps-n-up-on (> ps-n-up-printing 1)
5877 ps-line-number-start (max 1 (min ps-line-number-start
5878 (if (integerp ps-line-number-step)
5879 ps-line-number-step
5880 ps-zebra-stripe-height))))
1fd9b7fe 5881 ;; spooling buffer
7da17ab6
RS
5882 (save-excursion
5883 (set-buffer ps-spool-buffer)
5884 (goto-char (point-max))
5885 (and (re-search-backward "^%%Trailer$" nil t)
5886 (delete-region (match-beginning 0) (point-max))))
1fd9b7fe 5887 ;; miscellaneous
2bd80d73
GM
5888 (setq ps-zebra-stripe-full-p (memq ps-zebra-stripe-follow
5889 '(full full-follow))
5890 ps-page-postscript 0
7bb054a5
GM
5891 ps-page-sheet 0
5892 ps-page-n-up 0
4b3eb10f 5893 ps-page-column 0
bd7a2e26 5894 ps-lines-printed 0
7bb054a5
GM
5895 ps-print-page-p t
5896 ps-showline-count (car ps-printing-region)
6bf5fb46
GM
5897 ps-line-spacing-internal (ps-get-size ps-line-spacing
5898 "line spacing")
5899 ps-paragraph-spacing-internal (ps-get-size ps-paragraph-spacing
5900 "paragraph spacing")
7d8b7e8e
KH
5901 ps-font-size-internal (ps-get-font-size 'ps-font-size)
5902 ps-header-font-size-internal (ps-get-font-size 'ps-header-font-size)
5903 ps-header-title-font-size-internal
5904 (ps-get-font-size 'ps-header-title-font-size)
319acba0 5905 ps-footer-font-size-internal (ps-get-font-size 'ps-footer-font-size)
857686a6 5906 ps-control-or-escape-regexp
298bfad9
KH
5907 (cond ((eq ps-print-control-characters '8-bit)
5908 (string-as-unibyte "[\000-\037\177-\377]"))
5909 ((eq ps-print-control-characters 'control-8-bit)
5910 (string-as-unibyte "[\000-\037\177-\237]"))
5911 ((eq ps-print-control-characters 'control)
5912 "[\000-\037\177]")
6e1b1da6 5913 (t "[\t\n\f]"))
3f0257cb
VJL
5914 ;; Set the color scale. We do it here instead of in the defvar so
5915 ;; that ps-print can be dumped into emacs. This expression can't be
5916 ;; evaluated at dump-time because X isn't initialized.
5917 ps-color-p (and ps-print-color-p (ps-color-device))
5918 ps-print-color-scale (if ps-color-p
5919 (float (car (ps-color-values "white")))
5920 1.0)
e59d29d6 5921 ps-default-background (ps-rgb-color
c1a1c994 5922 (cond
3f0257cb
VJL
5923 ((or (not (eq ps-print-color-p t))
5924 (eq genfunc 'ps-generate-postscript))
5167749c 5925 nil)
c1a1c994 5926 ((eq ps-default-bg 'frame-parameter)
cf04718a 5927 (ps-frame-parameter nil 'background-color))
c1a1c994
VJL
5928 ((eq ps-default-bg t)
5929 (ps-face-background-name 'default))
5930 (t
5931 ps-default-bg))
c6f33bac 5932 "unspecified-bg"
e59d29d6 5933 1.0)
c794a94d 5934 ps-default-foreground (ps-rgb-color
c1a1c994 5935 (cond
3f0257cb
VJL
5936 ((or (not (eq ps-print-color-p t))
5937 (eq genfunc 'ps-generate-postscript))
5167749c 5938 nil)
c1a1c994 5939 ((eq ps-default-fg 'frame-parameter)
cf04718a 5940 (ps-frame-parameter nil 'foreground-color))
c1a1c994
VJL
5941 ((eq ps-default-fg t)
5942 (ps-face-foreground-name 'default))
5943 (t
5944 ps-default-fg))
c6f33bac 5945 "unspecified-fg"
c794a94d 5946 0.0)
3f0257cb
VJL
5947 ps-default-color (and (eq ps-print-color-p t)
5948 ps-default-foreground)
5949 ps-current-color ps-default-color)
319acba0 5950 ;; initialize page dimensions
e59d29d6
VJL
5951 (ps-get-page-dimensions)
5952 ;; final check
5953 (and ps-color-p
5954 (equal ps-default-background ps-default-foreground)
5955 (error
5956 (concat
5957 "`ps-default-fg' and `ps-default-bg' have the same color.\n"
5958 "Text won't appear on page. Please, check these variables."))))
6e1b1da6 5959
ef2cbb24 5960
ea0c615d
GM
5961(defun ps-page-number ()
5962 (if ps-print-only-one-header
4b3eb10f
GM
5963 (1+ (/ (1- ps-page-column) ps-number-of-columns))
5964 ps-page-column))
87a16a06
RS
5965
5966
319acba0
GM
5967(defsubst ps-end-page ()
5968 (ps-output "EndPage\nEndDSCPage\n"))
5969
5970
5971(defsubst ps-next-page ()
ef2cbb24 5972 (ps-end-page)
12d89a2e
RS
5973 (ps-flush-output)
5974 (ps-begin-page))
5975
bc0d41bd 5976
9dae638c
VJL
5977(defun ps-end-sheet ()
5978 (and ps-print-page-p (> ps-page-sheet 0)
5979 (ps-output "EndSheet\n")))
5980
5981
bc0d41bd
KH
5982(defun ps-header-sheet ()
5983 ;; Print only when a new sheet begins.
9dae638c 5984 (ps-end-sheet)
4b3eb10f
GM
5985 (setq ps-page-sheet (1+ ps-page-sheet))
5986 (when (ps-print-sheet-p)
5987 (setq ps-page-order (1+ ps-page-order))
5988 (ps-output (if ps-n-up-on
5989 (format "\n%%%%Page: (%d \\(%d\\)) %d\n"
5990 ps-page-order ps-page-postscript ps-page-order)
5991 (format "\n%%%%Page: %d %d\n"
5992 ps-page-postscript ps-page-order))
ef1159c2
EZ
5993 ;; spooling needs to redefine Lines and PageCount on each page
5994 "/Lines 0 def\n/PageCount 0 def\n"
4b3eb10f
GM
5995 (format "%d BeginSheet\nBeginDSCPage\n"
5996 ps-n-up-printing))))
ea0c615d
GM
5997
5998
5999(defun ps-header-page ()
7da17ab6
RS
6000 ;; set total line and page number when printing has finished
6001 ;; (see `ps-generate')
4b3eb10f 6002 (if (zerop (mod ps-page-column ps-number-of-columns))
ea0c615d
GM
6003 (progn
6004 (setq ps-page-postscript (1+ ps-page-postscript))
6005 (when (ps-print-page-p)
4b3eb10f 6006 (ps-print-sheet-p)
ea0c615d
GM
6007 (if (zerop (mod ps-page-n-up ps-n-up-printing))
6008 ;; Print only when a new sheet begins.
6009 (progn
6010 (ps-header-sheet)
6011 (run-hooks 'ps-print-begin-sheet-hook))
6012 ;; Print only when a new page begins.
6013 (ps-output "BeginDSCPage\n")
6014 (run-hooks 'ps-print-begin-page-hook))
6015 (ps-background ps-page-postscript)
4b3eb10f
GM
6016 (setq ps-page-n-up (1+ ps-page-n-up))
6017 (and ps-print-page-p
6018 (setq ps-page-printed (1+ ps-page-printed)))))
ea0c615d
GM
6019 ;; Print only when a new column begins.
6020 (ps-output "BeginDSCPage\n")
6021 (run-hooks 'ps-print-begin-column-hook))
4b3eb10f 6022 (setq ps-page-column (1+ ps-page-column)))
a18ed129 6023
8bd22fcf 6024(defun ps-begin-page ()
8bd22fcf 6025 (setq ps-width-remaining ps-print-width
298bfad9 6026 ps-height-remaining ps-print-height)
12d89a2e 6027
a18ed129 6028 (ps-header-page)
12d89a2e 6029
87a16a06 6030 (ps-output (format "/LineNumber %d def\n" ps-showline-count)
ea0c615d 6031 (format "/PageNumber %d def\n" (ps-page-number)))
12d89a2e 6032
090be653 6033 (when ps-print-header
edf0b0c5
VJL
6034 (ps-generate-header "HeaderLinesLeft" "/h0" "/h1"
6035 (or ps-lh-cache ps-left-header))
6036 (ps-generate-header "HeaderLinesRight" "/h0" "/h1"
6037 (or ps-rh-cache ps-right-header))
6038 (ps-output (format "%d SetHeaderLines\n" ps-header-lines))
6039 (setq ps-lh-cache nil
6040 ps-rh-cache nil))
12d89a2e 6041
319acba0 6042 (when ps-print-footer
edf0b0c5
VJL
6043 (ps-generate-header "FooterLinesLeft" "/H0" "/H0"
6044 (or ps-lf-cache ps-left-footer))
6045 (ps-generate-header "FooterLinesRight" "/H0" "/H0"
6046 (or ps-rf-cache ps-right-footer))
6047 (ps-output (format "%d SetFooterLines\n" ps-footer-lines))
6048 (setq ps-lf-cache nil
6049 ps-rf-cache nil))
319acba0 6050
bd7a2e26 6051 (ps-output (number-to-string ps-lines-printed) " BeginPage\n")
87a16a06
RS
6052 (ps-set-font ps-current-font)
6053 (ps-set-bg ps-current-bg)
298bfad9
KH
6054 (ps-set-color ps-current-color)
6055 (ps-mule-begin-page))
ef2cbb24 6056
319acba0 6057(defsubst ps-skip-newline (limit)
bd7a2e26
GM
6058 (setq ps-showline-count (1+ ps-showline-count)
6059 ps-lines-printed (1+ ps-lines-printed))
6060 (and (< (point) limit)
6061 (forward-char 1)))
6062
6bf5fb46 6063(defsubst ps-next-line ()
bd7a2e26
GM
6064 (setq ps-showline-count (1+ ps-showline-count)
6065 ps-lines-printed (1+ ps-lines-printed))
6bf5fb46
GM
6066 (let* ((paragraph-p (and ps-paragraph-regexp
6067 (looking-at ps-paragraph-regexp)))
6068 (lh (+ (ps-line-height 'ps-font-for-text)
6069 (if paragraph-p
6070 ps-paragraph-spacing-internal
6071 ps-line-spacing-internal))))
12b88fff
RS
6072 (if (< ps-height-remaining lh)
6073 (ps-next-page)
6074 (setq ps-width-remaining ps-print-width
6075 ps-height-remaining (- ps-height-remaining lh))
6bf5fb46 6076 (ps-output (if paragraph-p "PHL\n" "LHL\n")))))
ef2cbb24
RS
6077
6078(defun ps-continue-line ()
bd7a2e26 6079 (setq ps-lines-printed (1+ ps-lines-printed))
6bf5fb46 6080 (let ((lh (+ (ps-line-height 'ps-font-for-text) ps-line-spacing-internal)))
12b88fff
RS
6081 (if (< ps-height-remaining lh)
6082 (ps-next-page)
6083 (setq ps-width-remaining ps-print-width
6084 ps-height-remaining (- ps-height-remaining lh))
6085 (ps-output "SL\n"))))
12d89a2e
RS
6086
6087(defun ps-find-wrappoint (from to char-width)
6088 (let ((avail (truncate (/ ps-width-remaining char-width)))
6089 (todo (- to from)))
6090 (if (< todo avail)
6091 (cons to (* todo char-width))
6092 (cons (+ from avail) ps-width-remaining))))
6093
c86f4619
GM
6094(defun ps-basic-plot-str (from to string)
6095 (let* ((wrappoint (ps-find-wrappoint from to
6096 (ps-avg-char-width 'ps-font-for-text)))
6097 (to (car wrappoint))
6098 (str (substring string from to)))
6099 (ps-mule-prepare-ascii-font str)
6100 (ps-output-string str)
6101 (ps-output " S\n")
6102 wrappoint))
6103
12d89a2e 6104(defun ps-basic-plot-string (from to &optional bg-color)
12b88fff
RS
6105 (let* ((wrappoint (ps-find-wrappoint from to
6106 (ps-avg-char-width 'ps-font-for-text)))
12d89a2e 6107 (to (car wrappoint))
298bfad9
KH
6108 (string (buffer-substring-no-properties from to)))
6109 (ps-mule-prepare-ascii-font string)
12d89a2e 6110 (ps-output-string string)
bcc0d457 6111 (ps-output " S\n")
12d89a2e
RS
6112 wrappoint))
6113
6114(defun ps-basic-plot-whitespace (from to &optional bg-color)
12b88fff
RS
6115 (let* ((wrappoint (ps-find-wrappoint from to
6116 (ps-space-width 'ps-font-for-text)))
12d89a2e 6117 (to (car wrappoint)))
12d89a2e
RS
6118 (ps-output (format "%d W\n" (- to from)))
6119 wrappoint))
6120
6121(defun ps-plot (plotfunc from to &optional bg-color)
ef2cbb24 6122 (while (< from to)
12d89a2e
RS
6123 (let* ((wrappoint (funcall plotfunc from to bg-color))
6124 (plotted-to (car wrappoint))
6125 (plotted-width (cdr wrappoint)))
8bd22fcf
KH
6126 (setq from plotted-to
6127 ps-width-remaining (- ps-width-remaining plotted-width))
12d89a2e
RS
6128 (if (< from to)
6129 (ps-continue-line))))
ef2cbb24
RS
6130 (if ps-razzle-dazzle
6131 (let* ((q-todo (- (point-max) (point-min)))
12d89a2e 6132 (q-done (- (point) (point-min)))
ef2cbb24 6133 (chunkfrac (/ q-todo 8))
857686a6 6134 (chunksize (min chunkfrac 1000)))
ef2cbb24 6135 (if (> (- q-done ps-razchunk) chunksize)
8bd22fcf 6136 (progn
ef2cbb24 6137 (setq ps-razchunk q-done)
8bd22fcf
KH
6138 (message "Formatting...%3d%%"
6139 (if (< q-todo 100)
6140 (/ (* 100 q-done) q-todo)
6141 (/ q-done (/ q-todo 100)))
6142 ))))))
12d89a2e 6143
6db15364 6144(defvar ps-last-font nil)
298bfad9 6145
12d89a2e 6146(defun ps-set-font (font)
e65df0a1
KH
6147 (setq ps-last-font (format "f%d" (setq ps-current-font font)))
6148 (ps-output (format "/%s F\n" ps-last-font)))
12d89a2e 6149
12d89a2e
RS
6150(defun ps-set-bg (color)
6151 (if (setq ps-current-bg color)
8bd22fcf
KH
6152 (ps-output (format ps-color-format
6153 (nth 0 color) (nth 1 color) (nth 2 color))
12d89a2e
RS
6154 " true BG\n")
6155 (ps-output "false BG\n")))
6156
6157(defun ps-set-color (color)
6e1b1da6 6158 (setq ps-current-color (or color ps-default-foreground))
8bd22fcf
KH
6159 (ps-output (format ps-color-format
6160 (nth 0 ps-current-color)
043620f4
KH
6161 (nth 1 ps-current-color) (nth 2 ps-current-color))
6162 " FG\n"))
12d89a2e 6163
12d89a2e 6164
c86f4619
GM
6165(defsubst ps-plot-string (string)
6166 (ps-plot 'ps-basic-plot-str 0 (length string) string))
6167
6168
87a16a06 6169(defvar ps-current-effect 0)
12d89a2e 6170
3409eda2
KH
6171(defvar ps-print-translation-table
6172 (let ((tbl (make-char-table 'translation-table nil)))
6173 (if (and (boundp 'ucs-mule-8859-to-mule-unicode)
6174 (char-table-p ucs-mule-8859-to-mule-unicode))
6175 (map-char-table
640477ee 6176 #'(lambda (k v)
3409eda2
KH
6177 (if (and v (eq (char-charset v) 'latin-iso8859-1) (/= k v))
6178 (aset tbl k v)))
6179 ucs-mule-8859-to-mule-unicode))
6180 tbl)
6181 "Translation table for PostScript printing.
6182The default value is a table that translates non-Latin-1 Latin characters
6183to the equivalent Latin-1 characters.")
87a16a06
RS
6184
6185(defun ps-plot-region (from to font &optional fg-color bg-color effects)
efa89c1f 6186 (or (equal font ps-current-font)
12d89a2e 6187 (ps-set-font font))
06fb6aab 6188
12d89a2e
RS
6189 ;; Specify a foreground color only if one's specified and it's
6190 ;; different than the current.
efa89c1f
GM
6191 (let ((fg (or fg-color ps-default-foreground)))
6192 (or (equal fg ps-current-color)
6193 (ps-set-color fg)))
06fb6aab 6194
efa89c1f 6195 (or (equal bg-color ps-current-bg)
12d89a2e 6196 (ps-set-bg bg-color))
06fb6aab 6197
87a16a06
RS
6198 ;; Specify effects (underline, overline, box, etc)
6199 (cond
6200 ((not (integerp effects))
6201 (ps-output "0 EF\n")
6202 (setq ps-current-effect 0))
6203 ((/= effects ps-current-effect)
6204 (ps-output (number-to-string effects) " EF\n")
6205 (setq ps-current-effect effects)))
ef2cbb24 6206
12d89a2e 6207 ;; Starting at the beginning of the specified region...
ef2cbb24
RS
6208 (save-excursion
6209 (goto-char from)
12d89a2e
RS
6210
6211 ;; ...break the region up into chunks separated by tabs, linefeeds,
87a16a06 6212 ;; pagefeeds, control characters, and plot each chunk.
ef2cbb24 6213 (while (< from to)
6bf5fb46
GM
6214 ;; skip lines between cut markers
6215 (and ps-begin-cut-regexp ps-end-cut-regexp
6216 (looking-at ps-begin-cut-regexp)
6217 (progn
6218 (goto-char (match-end 0))
6219 (and (re-search-forward ps-end-cut-regexp to 'noerror)
6220 (= (following-char) ?\n)
6221 (forward-char 1))
6222 (setq from (point))))
857686a6 6223 (if (re-search-forward ps-control-or-escape-regexp to t)
024ced4d 6224 ;; region with some control characters or some multi-byte characters
12b88fff 6225 (let* ((match-point (match-beginning 0))
ea0c615d 6226 (match (char-after match-point))
3e9cb08f 6227 (composition (ps-e-find-composition from (1+ match-point))))
9d4d60c1
KH
6228 (if composition
6229 (if (and (nth 2 composition)
6230 (<= (car composition) match-point))
6231 (progn
6232 (setq match-point (car composition)
6233 match 0)
6234 (goto-char (nth 1 composition)))
6235 (setq composition nil)))
e65df0a1 6236 (when (< from match-point)
298bfad9 6237 (ps-mule-set-ascii-font)
e65df0a1 6238 (ps-plot 'ps-basic-plot-string from match-point bg-color))
857686a6
RS
6239 (cond
6240 ((= match ?\t) ; tab
be415ea7 6241 (let ((linestart (line-beginning-position)))
857686a6
RS
6242 (forward-char -1)
6243 (setq from (+ linestart (current-column)))
e65df0a1 6244 (when (re-search-forward "[ \t]+" to t)
298bfad9 6245 (ps-mule-set-ascii-font)
e65df0a1
KH
6246 (ps-plot 'ps-basic-plot-whitespace
6247 from (+ linestart (current-column))
6248 bg-color))))
857686a6
RS
6249
6250 ((= match ?\n) ; newline
bd7a2e26
GM
6251 (if (looking-at "\f[^\n]")
6252 ;; \n\ftext\n ==>> next page, but keep line counting!!
6253 (progn
6254 (ps-skip-newline to)
6255 (ps-next-page))
6256 ;; \n\f\n ==>> it'll be handled by form feed
6257 ;; \ntext\n ==>> next line
6258 (ps-next-line)))
857686a6
RS
6259
6260 ((= match ?\f) ; form feed
12b88fff
RS
6261 ;; do not skip page if previous character is NEWLINE and
6262 ;; it is a beginning of page.
bd7a2e26
GM
6263 (unless (and (equal (char-after (1- match-point)) ?\n)
6264 (= ps-height-remaining ps-print-height))
6265 ;; \f\n ==>> skip \n, but keep line counting!!
6266 (and (equal (following-char) ?\n)
6267 (ps-skip-newline to))
6268 (ps-next-page)))
e65df0a1 6269
9d4d60c1
KH
6270 (composition ; a composite sequence
6271 (ps-plot 'ps-mule-plot-composition match-point (point) bg-color))
6272
024ced4d 6273 ((> match 255) ; a multi-byte character
3409eda2 6274 (setq match (or (aref ps-print-translation-table match) match))
9d4d60c1 6275 (let* ((charset (char-charset match))
3e9cb08f 6276 (composition (ps-e-find-composition match-point to))
9d4d60c1 6277 (stop (if (nth 2 composition) (car composition) to)))
e65df0a1 6278 (or (eq charset 'composition)
3409eda2
KH
6279 (while (and (< (point) stop)
6280 (let ((ch (following-char)))
6281 (setq ch
6282 (or (aref ps-print-translation-table ch)
6283 ch))
6284 (eq (char-charset ch) charset)))
298bfad9 6285 (forward-char 1)))
e65df0a1 6286 (ps-plot 'ps-mule-plot-string match-point (point) bg-color)))
3556c6dd 6287 ; characters from ^@ to ^_ and
857686a6
RS
6288 (t ; characters from 127 to 255
6289 (ps-control-character match)))
87a16a06 6290 (setq from (point)))
024ced4d 6291 ;; region without control characters nor multi-byte characters
298bfad9 6292 (ps-mule-set-ascii-font)
87a16a06
RS
6293 (ps-plot 'ps-basic-plot-string from to bg-color)
6294 (setq from to)))))
6295
857686a6
RS
6296(defvar ps-string-control-codes
6297 (let ((table (make-vector 256 nil))
6298 (char ?\000))
6299 ;; control character
6300 (while (<= char ?\037)
6301 (aset table char (format "^%c" (+ char ?@)))
6302 (setq char (1+ char)))
6303 ;; printable character
6304 (while (< char ?\177)
6305 (aset table char (format "%c" char))
6306 (setq char (1+ char)))
6307 ;; DEL
6308 (aset table char "^?")
6309 ;; 8-bit character
6310 (while (<= (setq char (1+ char)) ?\377)
6311 (aset table char (format "\\%o" char)))
6312 table)
6313 "Vector used to map characters to a printable string.")
6314
6315(defun ps-control-character (char)
6316 (let* ((str (aref ps-string-control-codes char))
6317 (from (1- (point)))
87a16a06
RS
6318 (len (length str))
6319 (to (+ from len))
12b88fff
RS
6320 (char-width (ps-avg-char-width 'ps-font-for-text))
6321 (wrappoint (ps-find-wrappoint from to char-width)))
87a16a06
RS
6322 (if (< (car wrappoint) to)
6323 (ps-continue-line))
12b88fff 6324 (setq ps-width-remaining (- ps-width-remaining (* len char-width)))
36243805 6325 (ps-mule-prepare-ascii-font str)
87a16a06
RS
6326 (ps-output-string str)
6327 (ps-output " S\n")))
ef2cbb24 6328
87a16a06 6329
a18ed129
RS
6330(defun ps-face-attributes (face)
6331 "Return face attribute vector.
87a16a06 6332
a18ed129
RS
6333If FACE is not in `ps-print-face-extension-alist' or in
6334`ps-print-face-alist', insert it on `ps-print-face-alist' and
6335return the attribute vector.
87a16a06 6336
5167749c 6337If FACE is not a valid face name, use default face."
df5e6194 6338 (cond
55732434
GM
6339 (ps-black-white-faces-alist
6340 (or (and (symbolp face)
6341 (cdr (assq face ps-black-white-faces-alist)))
6342 (vector 0 nil nil)))
df5e6194
GM
6343 ((symbolp face)
6344 (cdr (or (assq face ps-print-face-extension-alist)
6345 (assq face ps-print-face-alist)
6346 (let* ((the-face (if (facep face) face 'default))
6347 (new-face (ps-screen-to-bit-face the-face)))
6348 (or (and (eq the-face 'default)
6349 (assq the-face ps-print-face-alist))
6350 (setq ps-print-face-alist
6351 (cons new-face ps-print-face-alist)))
6352 new-face))))
6353 ((eq (car face) 'foreground-color)
6354 (vector 0 (cdr face) nil))
6355 ((eq (car face) 'background-color)
6356 (vector 0 nil (cdr face)))
6357 (t
6358 (vector 0 nil nil))))
87a16a06 6359
043620f4 6360
906d41a7 6361(defun ps-face-background (face background)
5167749c
VJL
6362 (and (cond ((eq ps-use-face-background t)) ; always
6363 ((null ps-use-face-background) nil) ; never
6364 ;; ps-user-face-background is a symbol face list
6365 ((symbolp face)
6366 (memq face ps-use-face-background))
6367 ((listp face)
6368 (or (memq (car face) '(foreground-color background-color))
6369 (let (ok)
6370 (while face
6371 (if (or (memq (car face) ps-use-face-background)
6372 (memq (car face)
6373 '(foreground-color background-color)))
6374 (setq face nil
6375 ok t)
6376 (setq face (cdr face))))
6377 ok)))
6378 (t
6379 nil)
6380 )
906d41a7
GM
6381 background))
6382
6383
043620f4 6384(defun ps-face-attribute-list (face-or-list)
df5e6194
GM
6385 (cond
6386 ;; simple face
6387 ((not (listp face-or-list))
6388 (ps-face-attributes face-or-list))
6389 ;; only foreground color, not a `real' face
6390 ((eq (car face-or-list) 'foreground-color)
6391 (vector 0 (cdr face-or-list) nil))
6392 ;; only background color, not a `real' face
6393 ((eq (car face-or-list) 'background-color)
6394 (vector 0 nil (cdr face-or-list)))
6395 ;; list of faces
6396 (t
6397 (let ((effects 0)
6398 foreground background face-attr face)
6399 (while face-or-list
6400 (setq face (car face-or-list)
6401 face-or-list (cdr face-or-list)
6402 face-attr (ps-face-attributes face)
6403 effects (logior effects (aref face-attr 0)))
6404 (or foreground (setq foreground (aref face-attr 1)))
6405 (or background
6406 (setq background (ps-face-background face (aref face-attr 2)))))
6407 (vector effects foreground background)))))
043620f4 6408
87a16a06 6409
12b88fff
RS
6410(defconst ps-font-type (vector nil 'bold 'italic 'bold-italic))
6411
6412
12d89a2e 6413(defun ps-plot-with-face (from to face)
12b88fff
RS
6414 (cond
6415 ((null face) ; print text with null face
87a16a06 6416 (ps-plot-region from to 0))
12b88fff
RS
6417 ((eq face 'emacs--invisible--face)) ; skip invisible text!!!
6418 (t ; otherwise, text has a valid face
6419 (let* ((face-bit (ps-face-attribute-list face))
6420 (effect (aref face-bit 0))
6421 (foreground (aref face-bit 1))
906d41a7 6422 (background (ps-face-background face (aref face-bit 2)))
d3ab8dac 6423 (fg-color (if (and ps-color-p foreground)
6e1b1da6 6424 (ps-color-scale foreground)
12b88fff 6425 ps-default-color))
d3ab8dac 6426 (bg-color (and ps-color-p background
6e1b1da6 6427 (ps-color-scale background))))
12b88fff
RS
6428 (ps-plot-region
6429 from to
6430 (ps-font-number 'ps-font-for-text
6431 (or (aref ps-font-type (logand effect 3))
6432 face))
6433 fg-color bg-color (lsh effect -2)))))
87a16a06 6434 (goto-char to))
12d89a2e
RS
6435
6436
043620f4
KH
6437;; Ensure that face-list is fbound.
6438(or (fboundp 'face-list) (defalias 'face-list 'list-faces))
12d89a2e 6439
a18ed129 6440
12d89a2e 6441(defun ps-build-reference-face-lists ()
857686a6
RS
6442 ;; Ensure that face database is updated with faces on
6443 ;; `font-lock-face-attributes' (obsolete stuff)
6444 (ps-font-lock-face-attributes)
6445 ;; Now, rebuild reference face lists
a18ed129 6446 (setq ps-print-face-alist nil)
12d89a2e 6447 (if ps-auto-font-detect
a18ed129
RS
6448 (mapcar 'ps-map-face (face-list))
6449 (mapcar 'ps-set-face-bold ps-bold-faces)
6450 (mapcar 'ps-set-face-italic ps-italic-faces)
6451 (mapcar 'ps-set-face-underline ps-underlined-faces))
12d89a2e 6452 (setq ps-build-face-reference nil))
ef2cbb24 6453
a18ed129
RS
6454
6455(defun ps-set-face-bold (face)
6456 (ps-set-face-attribute face 1))
6457
6458(defun ps-set-face-italic (face)
6459 (ps-set-face-attribute face 2))
6460
6461(defun ps-set-face-underline (face)
6462 (ps-set-face-attribute face 4))
6463
6464
6465(defun ps-set-face-attribute (face effect)
6466 (let ((face-bit (cdr (ps-map-face face))))
6467 (aset face-bit 0 (logior (aref face-bit 0) effect))))
6468
6469
6470(defun ps-map-face (face)
6471 (let* ((face-map (ps-screen-to-bit-face face))
6472 (ps-face-bit (cdr (assq (car face-map) ps-print-face-alist))))
6473 (if ps-face-bit
6474 ;; if face exists, merge both
6475 (let ((face-bit (cdr face-map)))
6476 (aset ps-face-bit 0 (logior (aref ps-face-bit 0) (aref face-bit 0)))
6477 (or (aref ps-face-bit 1) (aset ps-face-bit 1 (aref face-bit 1)))
6478 (or (aref ps-face-bit 2) (aset ps-face-bit 2 (aref face-bit 2))))
6479 ;; if face does not exist, insert it
6480 (setq ps-print-face-alist (cons face-map ps-print-face-alist)))
6481 face-map))
6482
6483
6484(defun ps-screen-to-bit-face (face)
6485 (cons face
6486 (vector (logior (if (ps-face-bold-p face) 1 0) ; bold
6487 (if (ps-face-italic-p face) 2 0) ; italic
6488 (if (ps-face-underlined-p face) 4 0)) ; underline
8e234846
GM
6489 (ps-face-foreground-name face)
6490 (ps-face-background-name face))))
a18ed129
RS
6491
6492
b6d0ac87
VJL
6493;; to avoid compilation gripes
6494(defalias 'ps-jitify 'jit-lock-fontify-now)
6495(defalias 'ps-lazify 'lazy-lock-fontify-region)
6496
6497
3e9cb08f 6498;; to avoid compilation gripes
ea0c615d 6499(defun ps-print-ensure-fontified (start end)
b6d0ac87
VJL
6500 (cond ((and (boundp 'jit-lock-mode) (symbol-value 'jit-lock-mode))
6501 (ps-jitify start end))
6502 ((and (boundp 'lazy-lock-mode) (symbol-value 'lazy-lock-mode))
6503 (ps-lazify start end))))
043620f4 6504
043620f4 6505
ef2cbb24 6506(defun ps-generate-postscript-with-faces (from to)
87a16a06 6507 ;; Some initialization...
857686a6 6508 (setq ps-current-effect 0)
87a16a06 6509
00aa16af 6510 ;; Build the reference lists of faces if necessary.
8e234846
GM
6511 (when (or ps-always-build-face-reference
6512 ps-build-face-reference)
6513 (message "Collecting face information...")
6514 (ps-build-reference-face-lists))
55732434
GM
6515
6516 ;; Black/white printer.
6517 (setq ps-black-white-faces-alist nil)
6518 (and (eq ps-print-color-p 'black-white)
6519 (ps-extend-face-list ps-black-white-faces nil
6520 'ps-black-white-faces-alist))
6521
00aa16af 6522 ;; Generate some PostScript.
ef2cbb24
RS
6523 (save-restriction
6524 (narrow-to-region from to)
d3ab8dac 6525 (ps-print-ensure-fontified from to)
12d89a2e
RS
6526 (let ((face 'default)
6527 (position to))
87a16a06 6528 (cond
cf04718a 6529 ((featurep 'xemacs) ; XEmacs
87a16a06
RS
6530 ;; Build the list of extents...
6531 (let ((a (cons 'dummy nil))
6532 record type extent extent-list)
3e9cb08f 6533 (ps-x-map-extents 'ps-mapper nil from to a)
8bd22fcf
KH
6534 (setq a (sort (cdr a) 'car-less-than-car)
6535 extent-list nil)
87a16a06
RS
6536
6537 ;; Loop through the extents...
6538 (while a
8bd22fcf 6539 (setq record (car a)
8bd22fcf 6540 position (car record)
87a16a06 6541
8bd22fcf 6542 record (cdr record)
bd7a2e26 6543 type (car record)
87a16a06 6544
bd7a2e26 6545 record (cdr record)
8bd22fcf 6546 extent (car record))
87a16a06
RS
6547
6548 ;; Plot up to this record.
6549 ;; XEmacs 19.12: for some reason, we're getting into a
6550 ;; situation in which some of the records have
6551 ;; positions less than 'from'. Since we've narrowed
ea0c615d
GM
6552 ;; the buffer, this'll generate errors. This is a hack,
6553 ;; but don't call ps-plot-with-face unless from > point-min.
3e9cb08f
GM
6554 (and (>= from (point-min))
6555 (ps-plot-with-face from (min position (point-max)) face))
87a16a06
RS
6556
6557 (cond
6558 ((eq type 'push)
3e9cb08f 6559 (and (ps-x-extent-face extent)
d3ab8dac
KH
6560 (setq extent-list (sort (cons extent extent-list)
6561 'ps-extent-sorter))))
87a16a06
RS
6562
6563 ((eq type 'pull)
6564 (setq extent-list (sort (delq extent extent-list)
6565 'ps-extent-sorter))))
6566
d3ab8dac 6567 (setq face (if extent-list
3e9cb08f 6568 (ps-x-extent-face (car extent-list))
d3ab8dac 6569 'default)
8bd22fcf
KH
6570 from position
6571 a (cdr a)))))
87a16a06 6572
cf04718a 6573 (t ; Emacs
87a16a06 6574 (let ((property-change from)
e65df0a1
KH
6575 (overlay-change from)
6576 (save-buffer-invisibility-spec buffer-invisibility-spec)
c86f4619
GM
6577 (buffer-invisibility-spec nil)
6578 before-string after-string)
87a16a06 6579 (while (< from to)
d3ab8dac 6580 (and (< property-change to) ; Don't search for property change
12d89a2e 6581 ; unless previous search succeeded.
d3ab8dac
KH
6582 (setq property-change (next-property-change from nil to)))
6583 (and (< overlay-change to) ; Don't search for overlay change
12d89a2e 6584 ; unless previous search succeeded.
2bd80d73
GM
6585 (setq overlay-change (min (ps-e-next-overlay-change from)
6586 to)))
c86f4619
GM
6587 (setq position (min property-change overlay-change)
6588 before-string nil
6589 after-string nil)
87a16a06
RS
6590 ;; The code below is not quite correct,
6591 ;; because a non-nil overlay invisible property
6592 ;; which is inactive according to the current value
6593 ;; of buffer-invisibility-spec nonetheless overrides
6594 ;; a face text property.
6595 (setq face
6596 (cond ((let ((prop (get-text-property from 'invisible)))
6597 ;; Decide whether this invisible property
6598 ;; really makes the text invisible.
e65df0a1 6599 (if (eq save-buffer-invisibility-spec t)
87a16a06 6600 (not (null prop))
e65df0a1
KH
6601 (or (memq prop save-buffer-invisibility-spec)
6602 (assq prop save-buffer-invisibility-spec))))
12b88fff 6603 'emacs--invisible--face)
87a16a06
RS
6604 ((get-text-property from 'face))
6605 (t 'default)))
2bd80d73 6606 (let ((overlays (ps-e-overlays-at from))
87a16a06 6607 (face-priority -1)) ; text-property
d3ab8dac
KH
6608 (while (and overlays
6609 (not (eq face 'emacs--invisible--face)))
87a16a06 6610 (let* ((overlay (car overlays))
c86f4619
GM
6611 (overlay-invisible
6612 (ps-e-overlay-get overlay 'invisible))
6613 (overlay-priority
6614 (or (ps-e-overlay-get overlay 'priority) 0)))
d3ab8dac 6615 (and (> overlay-priority face-priority)
c86f4619
GM
6616 (setq before-string
6617 (or (ps-e-overlay-get overlay 'before-string)
6618 before-string)
6619 after-string
6620 (or (and (<= (ps-e-overlay-end overlay) position)
6621 (ps-e-overlay-get overlay 'after-string))
6622 after-string)
6623 face-priority overlay-priority
6624 face
6625 (cond
6626 ((if (eq save-buffer-invisibility-spec t)
6627 (not (null overlay-invisible))
6628 (or (memq overlay-invisible
6629 save-buffer-invisibility-spec)
6630 (assq overlay-invisible
6631 save-buffer-invisibility-spec)))
6632 'emacs--invisible--face)
6633 ((ps-e-overlay-get overlay 'face))
6634 (t face)
6635 ))))
87a16a06
RS
6636 (setq overlays (cdr overlays))))
6637 ;; Plot up to this record.
c86f4619
GM
6638 (and before-string
6639 (ps-plot-string before-string))
87a16a06 6640 (ps-plot-with-face from position face)
c86f4619
GM
6641 (and after-string
6642 (ps-plot-string after-string))
87a16a06
RS
6643 (setq from position)))))
6644 (ps-plot-with-face from to face))))
ef2cbb24
RS
6645
6646(defun ps-generate-postscript (from to)
5167749c 6647 (ps-plot-region from to 0))
ef2cbb24
RS
6648
6649(defun ps-generate (buffer from to genfunc)
87a16a06
RS
6650 (save-excursion
6651 (let ((from (min to from))
6652 (to (max to from))
6653 ;; This avoids trouble if chars with read-only properties
6654 ;; are copied into ps-spool-buffer.
6655 (inhibit-read-only t))
6656 (save-restriction
6657 (narrow-to-region from to)
857686a6
RS
6658 (and ps-razzle-dazzle
6659 (message "Formatting...%3d%%" (setq ps-razchunk 0)))
8bd22fcf
KH
6660 (setq ps-source-buffer buffer
6661 ps-spool-buffer (get-buffer-create ps-spool-buffer-name))
87a16a06
RS
6662 (ps-init-output-queue)
6663 (let (safe-marker completed-safely needs-begin-file)
6664 (unwind-protect
00aa16af
RS
6665 (progn
6666 (set-buffer ps-spool-buffer)
7da17ab6 6667 (set-buffer-multibyte nil)
915293a2 6668
87a16a06
RS
6669 ;; Get a marker and make it point to the current end of the
6670 ;; buffer, If an error occurs, we'll delete everything from
6671 ;; the end of this marker onwards.
6672 (setq safe-marker (make-marker))
6673 (set-marker safe-marker (point-max))
6674
6675 (goto-char (point-min))
8bd22fcf
KH
6676 (or (looking-at (regexp-quote ps-adobe-tag))
6677 (setq needs-begin-file t))
ea0c615d
GM
6678
6679 (set-buffer ps-source-buffer)
87a16a06 6680 (save-excursion
ea0c615d
GM
6681 (let ((ps-print-page-p t)
6682 ps-even-or-odd-pages)
5167749c 6683 (ps-begin-job genfunc)
70f57a72
GM
6684 (when needs-begin-file
6685 (ps-begin-file)
6686 (ps-mule-initialize))
6687 (ps-mule-begin-job from to)
ea0c615d
GM
6688 (ps-selected-pages)))
6689 (ps-begin-page)
87a16a06
RS
6690 (funcall genfunc from to)
6691 (ps-end-page)
ea0c615d 6692 (ps-end-job needs-begin-file)
87a16a06
RS
6693
6694 ;; Setting this variable tells the unwind form that the
8bd22fcf 6695 ;; the PostScript was generated without error.
87a16a06
RS
6696 (setq completed-safely t))
6697
6698 ;; Unwind form: If some bad mojo occurred while generating
8bd22fcf 6699 ;; PostScript, delete all the PostScript that was generated.
87a16a06
RS
6700 ;; This protects the previously spooled files from getting
6701 ;; corrupted.
8bd22fcf
KH
6702 (and (markerp safe-marker) (not completed-safely)
6703 (progn
6704 (set-buffer ps-spool-buffer)
6705 (delete-region (marker-position safe-marker) (point-max))))))
87a16a06 6706
857686a6 6707 (and ps-razzle-dazzle (message "Formatting...done"))))))
ef2cbb24 6708
e65df0a1 6709
ea0c615d 6710(defun ps-end-job (needs-begin-file)
9dae638c 6711 (let ((ps-print-page-p t))
ea0c615d
GM
6712 (ps-flush-output)
6713 (save-excursion
4b3eb10f 6714 (let ((pages-per-sheet (mod ps-page-printed ps-n-up-printing))
ea0c615d 6715 (total-lines (cdr ps-printing-region))
ef1159c2 6716 (total-pages (ps-page-number)))
ea0c615d 6717 (set-buffer ps-spool-buffer)
ef1159c2
EZ
6718 (let (case-fold-search)
6719 ;; Back to the PS output buffer to set the last page n-up printing
6720 (goto-char (point-max))
6721 (and (> pages-per-sheet 0)
6722 (re-search-backward "^[0-9]+ BeginSheet$" nil t)
6723 (replace-match (format "%d BeginSheet" pages-per-sheet) t))
6724 ;; Back to the PS output buffer to set the page count
6725 (goto-char (point-min))
6726 (while (re-search-forward "^/Lines 0 def\n/PageCount 0 def$" nil t)
6727 (replace-match (format "/Lines %d def\n/PageCount %d def"
6728 total-lines total-pages) t)))))
ea0c615d
GM
6729 ;; Set dummy page
6730 (and ps-spool-duplex (= (mod ps-page-order 2) 1)
6731 (let ((ps-n-up-printing 0))
6732 (ps-header-sheet)
6733 (ps-output "/PrintHeader false def\n/ColumnIndex 0 def\n"
bd7a2e26
GM
6734 "/PrintLineNumber false def\n"
6735 (number-to-string ps-lines-printed) " BeginPage\n")
ea0c615d
GM
6736 (ps-end-page)))
6737 ;; Set end of PostScript file
9dae638c 6738 (ps-end-sheet)
4b3eb10f 6739 (ps-output "\n%%Trailer\n%%Pages: "
ea0c615d
GM
6740 (number-to-string
6741 (if (and needs-begin-file
6742 ps-banner-page-when-duplexing)
6743 (1+ ps-page-order)
6744 ps-page-order))
6745 "\n\nEndDoc\n\n%%EOF\n")
ef1159c2
EZ
6746 (and ps-end-with-control-d
6747 (ps-output "\C-d"))
ea0c615d
GM
6748 (ps-flush-output))
6749 ;; disable selected pages
1fd9b7fe 6750 (setq ps-selected-pages nil))
7d8b7e8e
KH
6751
6752
857686a6 6753;; Permit dynamic evaluation at print time of `ps-lpr-switches'.
ef2cbb24 6754(defun ps-do-despool (filename)
12d89a2e 6755 (if (or (not (boundp 'ps-spool-buffer))
bcc0d457 6756 (not (symbol-value 'ps-spool-buffer)))
12d89a2e 6757 (message "No spooled PostScript to print")
ef2cbb24
RS
6758 (if filename
6759 (save-excursion
857686a6 6760 (and ps-razzle-dazzle (message "Saving..."))
12d89a2e 6761 (set-buffer ps-spool-buffer)
ef2cbb24 6762 (setq filename (expand-file-name filename))
7ffaf659
EZ
6763 (let ((coding-system-for-write 'raw-text-unix))
6764 (write-region (point-min) (point-max) filename))
857686a6 6765 (and ps-razzle-dazzle (message "Wrote %s" filename)))
ef2cbb24 6766 ;; Else, spool to the printer
857686a6 6767 (and ps-razzle-dazzle (message "Printing..."))
ef2cbb24 6768 (save-excursion
12d89a2e 6769 (set-buffer ps-spool-buffer)
200127fd 6770 (let* ((coding-system-for-write 'raw-text-unix)
298bfad9
KH
6771 (ps-printer-name (or ps-printer-name
6772 (and (boundp 'printer-name)
2bd80d73 6773 (symbol-value 'printer-name))))
200127fd 6774 (ps-lpr-switches
3556c6dd
GM
6775 (append ps-lpr-switches
6776 (and (stringp ps-printer-name)
6777 (string< "" ps-printer-name)
6778 (list (concat
6779 (and (stringp ps-printer-name-option)
6780 ps-printer-name-option)
6781 ps-printer-name))))))
c1a1c994
VJL
6782 (or (stringp ps-printer-name)
6783 (setq ps-printer-name nil))
52cf535f
AI
6784 (apply (or ps-print-region-function 'call-process-region)
6785 (point-min) (point-max) ps-lpr-command nil
6786 (and (fboundp 'start-process) 0)
6787 nil
6788 (ps-flatten-list ; dynamic evaluation
6789 (mapcar 'ps-eval-switch ps-lpr-switches)))))
857686a6 6790 (and ps-razzle-dazzle (message "Printing...done")))
12d89a2e
RS
6791 (kill-buffer ps-spool-buffer)))
6792
857686a6
RS
6793;; Dynamic evaluation
6794(defun ps-eval-switch (arg)
6795 (cond ((stringp arg) arg)
6796 ((functionp arg) (apply arg nil))
6797 ((symbolp arg) (symbol-value arg))
6798 ((consp arg) (apply (car arg) (cdr arg)))
6799 (t nil)))
6800
6801;; `ps-flatten-list' is defined here (copied from "message.el" and
6802;; enhanced to handle dotted pairs as well) until we can get some
6803;; sensible autoloads, or `flatten-list' gets put somewhere decent.
6804
6805;; (ps-flatten-list '((a . b) c (d . e) (f g h) i . j))
6806;; => (a b c d e f g h i j)
6807
6808(defun ps-flatten-list (&rest list)
6809 (ps-flatten-list-1 list))
6810
6811(defun ps-flatten-list-1 (list)
6812 (cond ((null list) nil)
6813 ((consp list) (append (ps-flatten-list-1 (car list))
6814 (ps-flatten-list-1 (cdr list))))
6815 (t (list list))))
6816
12d89a2e
RS
6817(defun ps-kill-emacs-check ()
6818 (let (ps-buffer)
8bd22fcf 6819 (and (setq ps-buffer (get-buffer ps-spool-buffer-name))
71efd3c4 6820 (buffer-name ps-buffer) ; check if it's not killed
8bd22fcf
KH
6821 (buffer-modified-p ps-buffer)
6822 (y-or-n-p "Unprinted PostScript waiting; print now? ")
6823 (ps-despool))
6824 (and (setq ps-buffer (get-buffer ps-spool-buffer-name))
71efd3c4 6825 (buffer-name ps-buffer) ; check if it's not killed
8bd22fcf
KH
6826 (buffer-modified-p ps-buffer)
6827 (not (yes-or-no-p "Unprinted PostScript waiting; exit anyway? "))
6828 (error "Unprinted PostScript"))))
12d89a2e 6829
d3ab8dac
KH
6830(cond ((fboundp 'add-hook)
6831 (funcall 'add-hook 'kill-emacs-hook 'ps-kill-emacs-check))
6832 (kill-emacs-hook
6833 (message "Won't override existing `kill-emacs-hook'"))
6834 (t
6835 (setq kill-emacs-hook 'ps-kill-emacs-check)))
ef2cbb24 6836
298bfad9
KH
6837\f
6838;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12d89a2e 6839;;; Sample Setup Code:
ef2cbb24 6840
0a5daee5 6841
12d89a2e 6842;; This stuff is for anybody that's brave enough to look this far,
87a16a06
RS
6843;; and able to figure out how to use it. It isn't really part of
6844;; ps-print, but I'll leave it here in hopes it might be useful:
ef2cbb24 6845
298bfad9
KH
6846;; WARNING!!! The following code is *sample* code only.
6847;; Don't use it unless you understand what it does!
043620f4 6848
cf04718a 6849;; The key `f22' should probably be replaced by `print'. --Stef
00aa16af 6850
a18ed129
RS
6851;; A hook to bind to `rmail-mode-hook' to locally bind prsc and set the
6852;; `ps-left-headers' specially for mail messages.
6853(defun ps-rmail-mode-hook ()
cf04718a 6854 (local-set-key [(f22)] 'ps-rmail-print-message-from-summary)
a18ed129
RS
6855 (setq ps-header-lines 3
6856 ps-left-header
6857 ;; The left headers will display the message's subject, its
6858 ;; author, and the name of the folder it was in.
6859 '(ps-article-subject ps-article-author buffer-name)))
6860
6861;; See `ps-gnus-print-article-from-summary'. This function does the
6862;; same thing for rmail.
6863(defun ps-rmail-print-message-from-summary ()
6864 (interactive)
6865 (ps-print-message-from-summary 'rmail-summary-buffer "RMAIL"))
6866
6867;; Used in `ps-rmail-print-article-from-summary',
6868;; `ps-gnus-print-article-from-summary' and `ps-vm-print-message-from-summary'.
6869(defun ps-print-message-from-summary (summary-buffer summary-default)
6870 (let ((ps-buf (or (and (boundp summary-buffer)
6871 (symbol-value summary-buffer))
6872 summary-default)))
6873 (and (get-buffer ps-buf)
6874 (save-excursion
6875 (set-buffer ps-buf)
6876 (ps-spool-buffer-with-faces)))))
6877
12d89a2e 6878;; Look in an article or mail message for the Subject: line. To be
87a16a06 6879;; placed in `ps-left-headers'.
12d89a2e 6880(defun ps-article-subject ()
ef2cbb24 6881 (save-excursion
12d89a2e 6882 (goto-char (point-min))
45a870d9 6883 (if (re-search-forward "^Subject:[ \t]+\\(.*\\)$" nil t)
edc9cd35 6884 (buffer-substring (match-beginning 1) (match-end 1))
12d89a2e
RS
6885 "Subject ???")))
6886
6887;; Look in an article or mail message for the From: line. Sorta-kinda
6888;; understands RFC-822 addresses and can pull the real name out where
87a16a06 6889;; it's provided. To be placed in `ps-left-headers'.
12d89a2e
RS
6890(defun ps-article-author ()
6891 (save-excursion
6892 (goto-char (point-min))
a97592dd 6893 (if (re-search-forward "^From:[ \t]+\\(.*\\)$" nil t)
edc9cd35 6894 (let ((fromstring (buffer-substring (match-beginning 1) (match-end 1))))
12d89a2e
RS
6895 (cond
6896
6897 ;; Try first to match addresses that look like
6898 ;; thompson@wg2.waii.com (Jim Thompson)
6899 ((string-match ".*[ \t]+(\\(.*\\))" fromstring)
6900 (substring fromstring (match-beginning 1) (match-end 1)))
6901
6902 ;; Next try to match addresses that look like
edc9cd35
GM
6903 ;; Jim Thompson <thompson@wg2.waii.com> or
6904 ;; "Jim Thompson" <thompson@wg2.waii.com>
6905 ((string-match "\\(\"?\\)\\(.*\\)\\1[ \t]+<.*>" fromstring)
6906 (substring fromstring (match-beginning 2) (match-end 2)))
12d89a2e
RS
6907
6908 ;; Couldn't find a real name -- show the address instead.
6909 (t fromstring)))
6910 "From ???")))
6911
a18ed129 6912;; A hook to bind to `gnus-article-prepare-hook'. This will set the
87a16a06
RS
6913;; `ps-left-headers' specially for gnus articles. Unfortunately,
6914;; `gnus-article-mode-hook' is called only once, the first time the *Article*
12d89a2e
RS
6915;; buffer enters that mode, so it would only work for the first time
6916;; we ran gnus. The second time, this hook wouldn't get set up. The
87a16a06 6917;; only alternative is `gnus-article-prepare-hook'.
12d89a2e 6918(defun ps-gnus-article-prepare-hook ()
8bd22fcf
KH
6919 (setq ps-header-lines 3
6920 ps-left-header
12d89a2e
RS
6921 ;; The left headers will display the article's subject, its
6922 ;; author, and the newsgroup it was in.
8bd22fcf 6923 '(ps-article-subject ps-article-author gnus-newsgroup-name)))
12d89a2e 6924
a18ed129
RS
6925;; A hook to bind to `vm-mode-hook' to locally bind prsc and set the
6926;; `ps-left-headers' specially for mail messages.
12d89a2e 6927(defun ps-vm-mode-hook ()
cf04718a 6928 (local-set-key [(f22)] 'ps-vm-print-message-from-summary)
8bd22fcf
KH
6929 (setq ps-header-lines 3
6930 ps-left-header
12d89a2e
RS
6931 ;; The left headers will display the message's subject, its
6932 ;; author, and the name of the folder it was in.
8bd22fcf 6933 '(ps-article-subject ps-article-author buffer-name)))
12d89a2e
RS
6934
6935;; Every now and then I forget to switch from the *Summary* buffer to
6936;; the *Article* before hitting prsc, and a nicely formatted list of
6937;; article subjects shows up at the printer. This function, bound to
6938;; prsc for the gnus *Summary* buffer means I don't have to switch
6939;; buffers first.
87a16a06 6940;; sb: Updated for Gnus 5.
12d89a2e
RS
6941(defun ps-gnus-print-article-from-summary ()
6942 (interactive)
a18ed129 6943 (ps-print-message-from-summary 'gnus-article-buffer "*Article*"))
ef2cbb24 6944
87a16a06 6945;; See `ps-gnus-print-article-from-summary'. This function does the
12d89a2e
RS
6946;; same thing for vm.
6947(defun ps-vm-print-message-from-summary ()
6948 (interactive)
a18ed129 6949 (ps-print-message-from-summary 'vm-mail-buffer ""))
ef2cbb24 6950
87a16a06 6951;; A hook to bind to bind to `gnus-summary-setup-buffer' to locally bind
12d89a2e
RS
6952;; prsc.
6953(defun ps-gnus-summary-setup ()
cf04718a 6954 (local-set-key [(f22)] 'ps-gnus-print-article-from-summary))
12d89a2e
RS
6955
6956;; Look in an article or mail message for the Subject: line. To be
87a16a06 6957;; placed in `ps-left-headers'.
12d89a2e
RS
6958(defun ps-info-file ()
6959 (save-excursion
6960 (goto-char (point-min))
a97592dd 6961 (if (re-search-forward "File:[ \t]+\\([^, \t\n]*\\)" nil t)
edc9cd35 6962 (buffer-substring (match-beginning 1) (match-end 1))
12d89a2e
RS
6963 "File ???")))
6964
6965;; Look in an article or mail message for the Subject: line. To be
87a16a06 6966;; placed in `ps-left-headers'.
12d89a2e
RS
6967(defun ps-info-node ()
6968 (save-excursion
6969 (goto-char (point-min))
a97592dd 6970 (if (re-search-forward "Node:[ \t]+\\([^,\t\n]*\\)" nil t)
edc9cd35 6971 (buffer-substring (match-beginning 1) (match-end 1))
12d89a2e
RS
6972 "Node ???")))
6973
6974(defun ps-info-mode-hook ()
6975 (setq ps-left-header
6976 ;; The left headers will display the node name and file name.
8bd22fcf 6977 '(ps-info-node ps-info-file)))
12d89a2e 6978
043620f4
KH
6979;; WARNING! The following function is a *sample* only, and is *not*
6980;; meant to be used as a whole unless you understand what the effects
87a16a06
RS
6981;; will be! (In fact, this is a copy of Jim's setup for ps-print --
6982;; I'd be very surprised if it was useful to *anybody*, without
043620f4
KH
6983;; modification.)
6984
12d89a2e 6985(defun ps-jts-ps-setup ()
cf04718a
SM
6986 (global-set-key [(f22)] 'ps-spool-buffer-with-faces) ;f22 is prsc
6987 (global-set-key [(shift f22)] 'ps-spool-region-with-faces)
6988 (global-set-key [(control f22)] 'ps-despool)
12d89a2e
RS
6989 (add-hook 'gnus-article-prepare-hook 'ps-gnus-article-prepare-hook)
6990 (add-hook 'gnus-summary-mode-hook 'ps-gnus-summary-setup)
6991 (add-hook 'vm-mode-hook 'ps-vm-mode-hook)
00aa16af 6992 (add-hook 'vm-mode-hooks 'ps-vm-mode-hook)
12d89a2e 6993 (add-hook 'Info-mode-hook 'ps-info-mode-hook)
8bd22fcf
KH
6994 (setq ps-spool-duplex t
6995 ps-print-color-p nil
6996 ps-lpr-command "lpr"
6997 ps-lpr-switches '("-Jjct,duplex_long"))
bcc0d457
RS
6998 'ps-jts-ps-setup)
6999
7000;; WARNING! The following function is a *sample* only, and is *not*
7001;; meant to be used as a whole unless it corresponds to your needs.
7002;; (In fact, this is a copy of Jack's setup for ps-print --
7003;; I would not be that surprised if it was useful to *anybody*,
7004;; without modification.)
7005
7006(defun ps-jack-setup ()
87a16a06 7007 (setq ps-print-color-p nil
bcc0d457 7008 ps-lpr-command "lpr"
8bd22fcf 7009 ps-lpr-switches nil
bcc0d457 7010
87a16a06
RS
7011 ps-paper-type 'a4
7012 ps-landscape-mode t
bcc0d457
RS
7013 ps-number-of-columns 2
7014
7015 ps-left-margin (/ (* 72 1.0) 2.54) ; 1.0 cm
7016 ps-right-margin (/ (* 72 1.0) 2.54) ; 1.0 cm
7017 ps-inter-column (/ (* 72 1.0) 2.54) ; 1.0 cm
7018 ps-bottom-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
7019 ps-top-margin (/ (* 72 1.5) 2.54) ; 1.5 cm
7020 ps-header-offset (/ (* 72 1.0) 2.54) ; 1.0 cm
7021 ps-header-line-pad .15
7022 ps-print-header t
7023 ps-print-header-frame t
7024 ps-header-lines 2
7025 ps-show-n-of-n t
7026 ps-spool-duplex nil
7027
7028 ps-font-family 'Courier
7029 ps-font-size 5.5
7030 ps-header-font-family 'Helvetica
7031 ps-header-font-size 6
7032 ps-header-title-font-size 8)
7033 'ps-jack-setup)
12d89a2e 7034
298bfad9
KH
7035\f
7036;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7037;; To make this file smaller, some commands go in a separate file.
7038;; But autoload them here to make the separation invisible.
231f3e66
SM
7039\f
7040;;;### (autoloads (ps-mule-begin-page ps-mule-begin-job ps-mule-encode-header-string
7041;;;;;; ps-mule-initialize ps-mule-plot-composition ps-mule-plot-string
7042;;;;;; ps-mule-set-ascii-font ps-mule-prepare-ascii-font ps-multibyte-buffer)
5da6890d 7043;;;;;; "ps-mule" "ps-mule.el" "cbb193f9b6bebd27378819035d3788f7")
231f3e66 7044;;; Generated autoloads from ps-mule.el
298bfad9 7045
231f3e66 7046(defvar ps-multibyte-buffer nil "\
5da6890d 7047Specifies the multi-byte buffer handling.
298bfad9 7048
231f3e66 7049Valid values are:
298bfad9 7050
5da6890d
SM
7051 nil This is the value to use the default settings;
7052 by default, this only works to print buffers with
7053 only ASCII and Latin characters. But this default
7054 setting can be changed by setting the variable
231f3e66
SM
7055 `ps-mule-font-info-database-default' differently.
7056 The initial value of this variable is
7057 `ps-mule-font-info-database-latin' (see
7058 documentation).
7059
5da6890d 7060 `non-latin-printer' This is the value to use when you have a Japanese
231f3e66
SM
7061 or Korean PostScript printer and want to print
7062 buffer with ASCII, Latin-1, Japanese (JISX0208 and
7063 JISX0201-Kana) and Korean characters. At present,
5da6890d 7064 it was not tested with the Korean characters printing.
231f3e66
SM
7065 If you have a korean PostScript printer, please,
7066 test it.
7067
5da6890d 7068 `bdf-font' This is the value to use when you want to print
231f3e66
SM
7069 buffer with BDF fonts. BDF fonts include both latin
7070 and non-latin fonts. BDF (Bitmap Distribution
7071 Format) is a format used for distributing X's font
7072 source file. BDF fonts are included in
7073 `intlfonts-1.2' which is a collection of X11 fonts
7074 for all characters supported by Emacs. In order to
7075 use this value, be sure to have installed
7076 `intlfonts-1.2' and set the variable
7077 `bdf-directory-list' appropriately (see ps-bdf.el for
7078 documentation of this variable).
7079
5da6890d 7080 `bdf-font-except-latin' This is like `bdf-font' except that it uses
231f3e66
SM
7081 PostScript default fonts to print ASCII and Latin-1
7082 characters. This is convenient when you want or
7083 need to use both latin and non-latin characters on
7084 the same buffer. See `ps-font-family',
7085 `ps-header-font-family' and `ps-font-info-database'.
7086
7087Any other value is treated as nil.")
7088
7089(custom-autoload (quote ps-multibyte-buffer) "ps-mule" t)
7090
7091(autoload (quote ps-mule-prepare-ascii-font) "ps-mule" "\
7092Setup special ASCII font for STRING.
7093STRING should contain only ASCII characters.
7094
7095\(fn STRING)" nil nil)
7096
7097(autoload (quote ps-mule-set-ascii-font) "ps-mule" "\
7098Not documented
7099
7100\(fn)" nil nil)
7101
7102(autoload (quote ps-mule-plot-string) "ps-mule" "\
7103Generate PostScript code for plotting characters in the region FROM and TO.
298bfad9
KH
7104
7105It is assumed that all characters in this region belong to the same charset.
7106
7107Optional argument BG-COLOR specifies background color.
7108
7109Returns the value:
7110
7111 (ENDPOS . RUN-WIDTH)
7112
7113Where ENDPOS is the end position of the sequence and RUN-WIDTH is the width of
231f3e66
SM
7114the sequence.
7115
7116\(fn FROM TO &optional BG-COLOR)" nil nil)
7117
7118(autoload (quote ps-mule-plot-composition) "ps-mule" "\
7119Generate PostScript code for plotting composition in the region FROM and TO.
7120
7121It is assumed that all characters in this region belong to the same
7122composition.
7123
7124Optional argument BG-COLOR specifies background color.
7125
7126Returns the value:
7127
7128 (ENDPOS . RUN-WIDTH)
7129
7130Where ENDPOS is the end position of the sequence and RUN-WIDTH is the width of
7131the sequence.
7132
7133\(fn FROM TO &optional BG-COLOR)" nil nil)
7134
7135(autoload (quote ps-mule-initialize) "ps-mule" "\
7136Initialize global data for printing multi-byte characters.
7137
7138\(fn)" nil nil)
7139
7140(autoload (quote ps-mule-encode-header-string) "ps-mule" "\
7141Generate PostScript code for ploting STRING by font FONTTAG.
7142FONTTAG should be a string \"/h0\" or \"/h1\".
298bfad9 7143
231f3e66 7144\(fn STRING FONTTAG)" nil nil)
298bfad9 7145
231f3e66
SM
7146(autoload (quote ps-mule-begin-job) "ps-mule" "\
7147Start printing job for multi-byte chars between FROM and TO.
7148This checks if all multi-byte characters in the region are printable or not.
298bfad9 7149
231f3e66 7150\(fn FROM TO)" nil nil)
298bfad9 7151
231f3e66
SM
7152(autoload (quote ps-mule-begin-page) "ps-mule" "\
7153Not documented
6bf5fb46 7154
231f3e66 7155\(fn)" nil nil)
6bf5fb46 7156
231f3e66 7157;;;***
298bfad9
KH
7158\f
7159;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7160
12d89a2e 7161(provide 'ps-print)
b87c5d3d 7162
231f3e66 7163;; arch-tag: fb06a585-1112-4206-885d-a57d95d50579
12d89a2e 7164;;; ps-print.el ends here