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