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