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