diff options
| author | Richard M. Stallman | 1995-01-20 06:09:03 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-01-20 06:09:03 +0000 |
| commit | 12d89a2e57a3775b5322252cd0f43fa708c562ee (patch) | |
| tree | 726dc60ddbd130dab3aa60a9273b743dc7f6e1e1 | |
| parent | 2be55c9c825bd6dff3e6c6984d1c53713b94b261 (diff) | |
| download | emacs-12d89a2e57a3775b5322252cd0f43fa708c562ee.tar.gz emacs-12d89a2e57a3775b5322252cd0f43fa708c562ee.zip | |
*** empty log message ***
| -rw-r--r-- | lisp/ps-print.el | 2292 |
1 files changed, 1636 insertions, 656 deletions
diff --git a/lisp/ps-print.el b/lisp/ps-print.el index cd089a8b448..1aa9f0b28ae 100644 --- a/lisp/ps-print.el +++ b/lisp/ps-print.el | |||
| @@ -1,10 +1,12 @@ | |||
| 1 | ;; Jim's Pretty-Good PostScript Generator for Emacs 19 (ps-print). | 1 | ;;; ps-print.el --- Jim's Pretty-Good PostScript Generator for Emacs 19. |
| 2 | |||
| 2 | ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
| 3 | 4 | ||
| 4 | ;; Author: James C. Thompson <thompson@wg2.waii.com> | 5 | ;; Author: Jim Thompson <thompson@wg2.waii.com> |
| 5 | ;; Keywords: faces, postscript, printing | 6 | ;; Version: 1.10 |
| 7 | ;; Keywords: print, PostScript | ||
| 6 | 8 | ||
| 7 | ;; This file is part of GNU Emacs. | 9 | ;; This file is not yet part of GNU Emacs. |
| 8 | 10 | ||
| 9 | ;; GNU Emacs is free software; you can redistribute it and/or modify | 11 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 10 | ;; it under the terms of the GNU General Public License as published by | 12 | ;; it under the terms of the GNU General Public License as published by |
| @@ -20,25 +22,16 @@ | |||
| 20 | ;; along with GNU Emacs; see the file COPYING. If not, write to | 22 | ;; along with GNU Emacs; see the file COPYING. If not, write to |
| 21 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
| 22 | 24 | ||
| 23 | ;; Acknowledgements | 25 | ;; LCD Archive Entry: |
| 24 | ;; ---------------- | 26 | ;; ps-print|James C. Thompson|thompson@wg2.waii.com| |
| 25 | ;; Thanks to Avishai Yacobi, avishaiy@mcil.comm.mot.com, for writing | 27 | ;; Jim's Pretty-Good PostScript Generator for Emacs 19 (ps-print)| |
| 26 | ;; the Emacs 19 port. | 28 | ;; 26-Feb-1994|1.6|~/packages/ps-print.el| |
| 27 | ;; | 29 | |
| 28 | ;; Thanks to Remi Houdaille and Michel Train, michel@metasoft.fdn.org, | 30 | ;;; Commentary: |
| 29 | ;; for adding underline support and title code. (Titling will appear | ||
| 30 | ;; in the next release.) | ||
| 31 | ;; | ||
| 32 | ;; Thanks to Heiko Muenkel, muenkel@tnt.uni-hannover.de, for showing | ||
| 33 | ;; me how to handle ISO-8859/1 characters. | ||
| 34 | ;; | ||
| 35 | ;; Code to handle ISO-8859/1 characters borrowed from the mp prologue | ||
| 36 | ;; file mp.pro.ps, used with permission of Rich Burridge of Sun | ||
| 37 | ;; Microsystems (Rich.Burridge@eng.sun.com). | ||
| 38 | 31 | ||
| 39 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 32 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 40 | ;; | 33 | ;; |
| 41 | ;; About ps-print: | 34 | ;; About ps-print |
| 42 | ;; -------------- | 35 | ;; -------------- |
| 43 | ;; This package provides printing of Emacs buffers on PostScript | 36 | ;; This package provides printing of Emacs buffers on PostScript |
| 44 | ;; printers; the buffer's bold and italic text attributes are | 37 | ;; printers; the buffer's bold and italic text attributes are |
| @@ -46,180 +39,520 @@ | |||
| 46 | ;; Emacs 19 (Lucid or FSF) and a fontifying package such as font-lock | 39 | ;; Emacs 19 (Lucid or FSF) and a fontifying package such as font-lock |
| 47 | ;; or hilit. | 40 | ;; or hilit. |
| 48 | ;; | 41 | ;; |
| 49 | ;; Installing ps-print: | 42 | ;; Installing ps-print |
| 50 | ;; ------------------- | 43 | ;; ------------------- |
| 51 | ;; Place ps-print somewhere in your load-path and byte-compile it. | ||
| 52 | ;; Load ps-print with (require 'ps-print). | ||
| 53 | ;; | 44 | ;; |
| 54 | ;; Using ps-print: | 45 | ;; 1. Place ps-print.el somewhere in your load-path and byte-compile |
| 46 | ;; it. You can ignore all byte-compiler warnings; they are the | ||
| 47 | ;; result of multi-Emacs support. This step is necessary only if | ||
| 48 | ;; you're installing your own ps-print; if ps-print came with your | ||
| 49 | ;; copy of Emacs, this been done already. | ||
| 50 | ;; | ||
| 51 | ;; 2. Place in your .emacs file the line | ||
| 52 | ;; | ||
| 53 | ;; (require 'ps-print) | ||
| 54 | ;; | ||
| 55 | ;; to load ps-print. Or you may cause any of the ps-print commands | ||
| 56 | ;; to be autoloaded with an autoload command such as: | ||
| 57 | ;; | ||
| 58 | ;; (autoload 'ps-print-buffer "ps-print" | ||
| 59 | ;; "Generate and print a PostScript image of the buffer..." t) | ||
| 60 | ;; | ||
| 61 | ;; 3. Make sure that the variables ps-lpr-command and ps-lpr-switches | ||
| 62 | ;; contain appropriate values for your system; see the usage notes | ||
| 63 | ;; below and the documentation of these variables. | ||
| 64 | ;; | ||
| 65 | ;; Using ps-print | ||
| 55 | ;; -------------- | 66 | ;; -------------- |
| 56 | ;; The variables ps-bold-faces and ps-italic-faces *must* contain | ||
| 57 | ;; lists of the faces that you wish to print in bold or italic font. | ||
| 58 | ;; These variables already contain some default values, but most users | ||
| 59 | ;; will probably have to add some of their own. To add a face to one | ||
| 60 | ;; of these lists, put code something like the following into your | ||
| 61 | ;; .emacs startup file: | ||
| 62 | ;; | 67 | ;; |
| 63 | ;; (setq ps-bold-faces (cons 'my-bold-face ps-bold-faces)) | 68 | ;; The Commands |
| 69 | ;; | ||
| 70 | ;; Ps-print provides eight commands for generating PostScript images | ||
| 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: | ||
| 64 | ;; | 89 | ;; |
| 65 | ;; Ps-print's printer interface is governed by the variables ps-lpr- | 90 | ;; print - The PostScript image is immediately sent to the |
| 66 | ;; command and ps-lpr-switches; these are analogous to the variables | 91 | ;; printer; |
| 67 | ;; lpr-command and lpr-switches in the Emacs lpr package. | ||
| 68 | ;; | 92 | ;; |
| 69 | ;; To use ps-print, invoke the command ps-print-buffer-with-faces. | 93 | ;; spool - The PostScript image is saved temporarily in an |
| 70 | ;; This will generate a PostScript image of the current buffer and | 94 | ;; Emacs buffer. Many images may be spooled locally |
| 71 | ;; send it to the printer. Precede this command with a numeric prefix | 95 | ;; before printing them. To send the spooled images |
| 72 | ;; (C-u), and the PostScript output will be saved in a file; you will | 96 | ;; to the printer, use the command ps-despool. |
| 73 | ;; be prompted for a filename. Also see the functions ps-print- | ||
| 74 | ;; buffer, ps-print-region, and ps-print-region-with-faces. | ||
| 75 | ;; | 97 | ;; |
| 76 | ;; I recommend binding ps-print-buffer-with-faces to a key sequence; | 98 | ;; The spooling mechanism was designed for printing lots of small |
| 77 | ;; on a Sun 4 keyboard, for example, you can bind to the PrSc key (aka | 99 | ;; files (mail messages or netnews articles) to save paper that would |
| 78 | ;; r22): | 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). | ||
| 103 | ;; | ||
| 104 | ;; Ps-print has a hook in the kill-emacs-hooks so that you won't | ||
| 105 | ;; accidently quit from Emacs while you have unprinted PostScript | ||
| 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 | ||
| 79 | ;; | 141 | ;; |
| 80 | ;; (global-set-key 'f22 'ps-print-buffer-with-faces) | 142 | ;; To print your buffer, type |
| 81 | ;; (global-set-key '(shift f22) 'ps-print-region-with-faces) | ||
| 82 | ;; | 143 | ;; |
| 83 | ;; Or, as I now prefer, you can also bind the ps-spool- functions to | 144 | ;; M-x ps-print-buffer |
| 84 | ;; keys; here's my bindings: | ||
| 85 | ;; | 145 | ;; |
| 86 | ;; (global-set-key 'f22 'ps-spool-buffer-with-faces) | 146 | ;; or substitute one of the other seven ps-print- commands. The |
| 147 | ;; command will generate the PostScript image and print or spool it as | ||
| 148 | ;; specified. By giving the command a prefix argument | ||
| 149 | ;; | ||
| 150 | ;; C-u M-x ps-print-buffer | ||
| 151 | ;; | ||
| 152 | ;; it will save the PostScript image to a file instead of sending it | ||
| 153 | ;; to the printer; you will be prompted for the name of the file to | ||
| 154 | ;; save the image to. The prefix argument is ignored by the commands | ||
| 155 | ;; that spool their images, but you may save the spooled images to a | ||
| 156 | ;; file by giving a prefix argument to ps-despool: | ||
| 157 | ;; | ||
| 158 | ;; C-u M-x ps-despool | ||
| 159 | ;; | ||
| 160 | ;; When invoked this way, ps-despool will prompt you for the name of | ||
| 161 | ;; the file to save to. | ||
| 162 | ;; | ||
| 163 | ;; Any of the ps-print- commands can be bound to keys; I recommend | ||
| 164 | ;; binding ps-spool-buffer-with-faces, ps-spool-region-with-faces, and | ||
| 165 | ;; ps-despool. Here are the bindings I use on my Sun 4 keyboard: | ||
| 166 | ;; | ||
| 167 | ;; (global-set-key 'f22 'ps-spool-buffer-with-faces) ;f22 is prsc | ||
| 87 | ;; (global-set-key '(shift f22) 'ps-spool-region-with-faces) | 168 | ;; (global-set-key '(shift f22) 'ps-spool-region-with-faces) |
| 88 | ;; (global-set-key '(control f22) 'ps-despool) | 169 | ;; (global-set-key '(control f22) 'ps-despool) |
| 89 | ;; | 170 | ;; |
| 90 | ;; Using ps-print with other Emacses: | 171 | ;; |
| 91 | ;; --------------------------------- | 172 | ;; The Printer Interface |
| 92 | ;; Although it was intended for use with Emacs 19, ps-print will also work | 173 | ;; |
| 93 | ;; with Emacs version 18; you won't get fancy fontified output, but it | 174 | ;; The variables ps-lpr-command and ps-lpr-switches determine what |
| 94 | ;; should work. | 175 | ;; command is used to send the PostScript images to the printer, and |
| 176 | ;; what arguments to give the command. These are analogous to lpr- | ||
| 177 | ;; command and lpr-switches. | ||
| 178 | ;; | ||
| 179 | ;; NOTE: ps-lpr-command and ps-lpr-switches take their initial values | ||
| 180 | ;; from the variables lpr-command and lpr-switches. If you have | ||
| 181 | ;; lpr-command set to invoke a pretty-printer such as enscript, | ||
| 182 | ;; then ps-print won't work properly. Ps-lpr-command must name | ||
| 183 | ;; a program that does not format the files it prints. | ||
| 184 | ;; | ||
| 185 | ;; | ||
| 186 | ;; How Ps-Print Deals With Fonts | ||
| 187 | ;; | ||
| 188 | ;; The ps-print-*-with-faces commands attempt to determine which faces | ||
| 189 | ;; should be printed in bold or italic, but their guesses aren't | ||
| 190 | ;; always right. For example, you might want to map colors into faces | ||
| 191 | ;; so that blue faces print in bold, and red faces in italic. | ||
| 192 | ;; | ||
| 193 | ;; It is possible to force ps-print to consider specific faces bold or | ||
| 194 | ;; italic, no matter what font they are displayed in, by setting the | ||
| 195 | ;; variables ps-bold-faces and ps-italic-faces. These variables | ||
| 196 | ;; contain lists of faces that ps-print should consider bold or | ||
| 197 | ;; italic; to set them, put code like the following into your .emacs | ||
| 198 | ;; file: | ||
| 199 | ;; | ||
| 200 | ;; (setq ps-bold-faces '(my-blue-face)) | ||
| 201 | ;; (setq ps-red-faces '(my-red-face)) | ||
| 202 | ;; | ||
| 203 | ;; Ps-print does not attempt to guess the sizes of fonts; all text is | ||
| 204 | ;; rendered using the Courier font family, in 10 point size. To | ||
| 205 | ;; change the font family, change the variables ps-font, ps-font-bold, | ||
| 206 | ;; ps-font-italic, and ps-font-bold-italic; fixed-pitch fonts work | ||
| 207 | ;; best, but are not required. To change the font size, change the | ||
| 208 | ;; variable ps-font-size. | ||
| 209 | ;; | ||
| 210 | ;; If you change the font family or size, you MUST also change the | ||
| 211 | ;; variables ps-line-height, ps-avg-char-width, and ps-space-width, or | ||
| 212 | ;; ps-print cannot correctly place line and page breaks. | ||
| 213 | ;; | ||
| 214 | ;; Ps-print keeps internal lists of which fonts are bold and which are | ||
| 215 | ;; italic; these lists are built the first time you invoke ps-print. | ||
| 216 | ;; For the sake of efficiency, the lists are built only once; the same | ||
| 217 | ;; lists are referred in later invokations of ps-print. | ||
| 218 | ;; | ||
| 219 | ;; Because these lists are built only once, it's possible for them to | ||
| 220 | ;; get out of sync, if a face changes, or if new faces are added. To | ||
| 221 | ;; get the lists back in sync, you can set the variable | ||
| 222 | ;; ps-build-face-reference to t, and the lists will be rebuilt the | ||
| 223 | ;; next time ps-print is invoked. | ||
| 224 | ;; | ||
| 225 | ;; | ||
| 226 | ;; How Ps-Print Deals With Color | ||
| 227 | ;; | ||
| 228 | ;; Ps-print detects faces with foreground and background colors | ||
| 229 | ;; defined and embeds color information in the PostScript image. The | ||
| 230 | ;; default foreground and background colors are defined by the | ||
| 231 | ;; variables ps-default-fg and ps-default-bg. On black-and-white | ||
| 232 | ;; printers, colors are displayed in grayscale. To turn off color | ||
| 233 | ;; output, set ps-print-color-p to nil. | ||
| 234 | ;; | ||
| 235 | ;; | ||
| 236 | ;; Headers | ||
| 237 | ;; | ||
| 238 | ;; Ps-print can print headers at the top of each page; the default | ||
| 239 | ;; headers contain the following four items: on the left, the name of | ||
| 240 | ;; the buffer and, if the buffer is visiting a file, the file's | ||
| 241 | ;; directory; on the right, the page number and date of printing. The | ||
| 242 | ;; default headers look something like this: | ||
| 243 | ;; | ||
| 244 | ;; ps-print.el 1/21 | ||
| 245 | ;; /home/jct/emacs-lisp/ps/new 94/12/31 | ||
| 246 | ;; | ||
| 247 | ;; When printing on duplex printers, left and right are reversed so | ||
| 248 | ;; that the page numbers are toward the outside. | ||
| 249 | ;; | ||
| 250 | ;; Headers are configurable. To turn them off completely, set | ||
| 251 | ;; ps-print-header to nil. To turn off the header's gaudy framing | ||
| 252 | ;; box, set ps-print-header-frame to nil. Page numbers are printed in | ||
| 253 | ;; "n/m" format, indicating page n of m pages; to omit the total page | ||
| 254 | ;; count and just print the page number, set ps-show-n-of-n to nil. | ||
| 255 | ;; | ||
| 256 | ;; The amount of information in the header can be changed by changing | ||
| 257 | ;; the number of lines. To show less, set ps-header-lines to 1, and | ||
| 258 | ;; the header will show only the buffer name and page number. To show | ||
| 259 | ;; more, set ps-header-lines to 3, and the header will show the time of | ||
| 260 | ;; printing below the date. | ||
| 261 | ;; | ||
| 262 | ;; To change the content of the headers, change the variables | ||
| 263 | ;; ps-left-header and ps-right-header. These variables are lists, | ||
| 264 | ;; specifying top-to-bottom the text to display on the left or right | ||
| 265 | ;; side of the header. Each element of the list should be a string or | ||
| 266 | ;; a symbol. Strings are inserted directly into the PostScript | ||
| 267 | ;; arrays, and should contain the PostScript string delimiters '(' and | ||
| 268 | ;; ')'. | ||
| 269 | ;; | ||
| 270 | ;; Symbols in the header format lists can either represent functions | ||
| 271 | ;; or variables. Functions are called, and should return a string to | ||
| 272 | ;; show in the header. Variables should contain strings to display in | ||
| 273 | ;; the header. In either case, function or variable, the PostScript | ||
| 274 | ;; strings delimeters are added by ps-print, and should not be part of | ||
| 275 | ;; the returned value. | ||
| 276 | ;; | ||
| 277 | ;; Here's an example: say we want the left header to display the text | ||
| 278 | ;; | ||
| 279 | ;; Moe | ||
| 280 | ;; Larry | ||
| 281 | ;; Curly | ||
| 282 | ;; | ||
| 283 | ;; where we have a function to return "Moe" | ||
| 284 | ;; | ||
| 285 | ;; (defun moe-func () | ||
| 286 | ;; "Moe") | ||
| 287 | ;; | ||
| 288 | ;; a variable specifying "Larry" | ||
| 289 | ;; | ||
| 290 | ;; (setq larry-var "Larry") | ||
| 291 | ;; | ||
| 292 | ;; and a literal for "Curly". Here's how ps-left-header should be | ||
| 293 | ;; set: | ||
| 294 | ;; | ||
| 295 | ;; (setq ps-left-header (list 'moe-func 'larry-var "(Curly)")) | ||
| 296 | ;; | ||
| 297 | ;; Note that Curly has the PostScript string delimiters inside his | ||
| 298 | ;; quotes -- those aren't misplaced lisp delimiters! Without them, | ||
| 299 | ;; PostScript would attempt to call the undefined function Curly, | ||
| 300 | ;; which would result in a PostScript error. Since most printers | ||
| 301 | ;; don't report PostScript errors except by aborting the print job, | ||
| 302 | ;; this kind of error can be hard to track down. Consider yourself | ||
| 303 | ;; warned. | ||
| 304 | ;; | ||
| 305 | ;; | ||
| 306 | ;; Duplex Printers | ||
| 307 | ;; | ||
| 308 | ;; If you have a duplex-capable printer (one that prints both sides of | ||
| 309 | ;; the paper), set ps-spool-duplex to t. Ps-print will insert blank | ||
| 310 | ;; pages to make sure each buffer starts on the correct side of the | ||
| 311 | ;; paper. Don't forget to set ps-lpr-switches to select duplex | ||
| 312 | ;; printing for your printer. | ||
| 95 | ;; | 313 | ;; |
| 96 | ;; A few words about support: | 314 | ;; |
| 97 | ;; ------------------------- | 315 | ;; Paper Size |
| 98 | ;; Despite its appearance, with comment blocks, usage instructions, and | 316 | ;; |
| 99 | ;; documentation strings, ps-print is not a supported package. That's all | 317 | ;; The variable ps-paper-type determines the size of paper ps-print |
| 100 | ;; a masquerade. Ps-print is something I threw together in my spare time-- | 318 | ;; formats for; it should contain one of the symbols ps-letter, |
| 101 | ;; an evening here, a Saturday there--to make my printouts look like my | 319 | ;; ps-legal, or ps-a4. The default is ps-letter. |
| 102 | ;; Emacs buffers. It works, but is not complete. | 320 | ;; |
| 103 | ;; | 321 | ;; |
| 104 | ;; Unfortunately, supporting elisp code is not my job and, now that I have | 322 | ;; New in version 1.6 |
| 105 | ;; what I need out of ps-print, additional support is going to be up to | ||
| 106 | ;; you, the user. But that's the spirit of Emacs, isn't it? I call on | ||
| 107 | ;; all who use this package to help in developing it further. If you | ||
| 108 | ;; notice a bug, fix it and send me the patches. If you add a feature, | ||
| 109 | ;; again, send me the patches. I will collect all such contributions and | ||
| 110 | ;; periodically post the updates to the appropriate places. | ||
| 111 | ;; | ||
| 112 | ;; A few more words about support: | ||
| 113 | ;; ------------------------------ | ||
| 114 | ;; The response to my call for public support of ps-print has been | ||
| 115 | ;; terrific. With the exception of the spooling mechanism, all the new | ||
| 116 | ;; features in this version of ps-print were contributed by users. I have | ||
| 117 | ;; some contributed code for printing headers that I'll add to the next | ||
| 118 | ;; release of ps-print, but there are still other features that users can | ||
| 119 | ;; write. See the "Features to Add" list a little further on, and keep | ||
| 120 | ;; that elisp rolling in. | ||
| 121 | ;; | ||
| 122 | ;; Please send all bug fixes and enhancements to me, thompson@wg2.waii.com. | ||
| 123 | ;; | ||
| 124 | ;; New in version 1.5 | ||
| 125 | ;; ------------------ | 323 | ;; ------------------ |
| 126 | ;; Support for Emacs 19. Works with both overlays and text | 324 | ;; Color output capability. |
| 127 | ;; properties. | 325 | ;; |
| 326 | ;; Automatic detection of font attributes (bold, italic). | ||
| 128 | ;; | 327 | ;; |
| 129 | ;; Underlining. | 328 | ;; Configurable headers with page numbers. |
| 130 | ;; | 329 | ;; |
| 131 | ;; Local spooling; see function ps-spool-buffer. | 330 | ;; Slightly faster. |
| 132 | ;; | 331 | ;; |
| 133 | ;; Support for ISO8859-1 character set. | 332 | ;; Support for different paper sizes. |
| 134 | ;; | 333 | ;; |
| 135 | ;; Page breaks are now handled correctly. | 334 | ;; Better conformance to PostScript Document Structure Conventions. |
| 136 | ;; | 335 | ;; |
| 137 | ;; Percentages reported while formatting are now correct. | ||
| 138 | ;; | 336 | ;; |
| 139 | ;; Known bugs and limitations of ps-print: | 337 | ;; Known bugs and limitations of ps-print: |
| 140 | ;; -------------------------------------- | 338 | ;; -------------------------------------- |
| 141 | ;; Slow. (Byte-compiling helps.) | 339 | ;; Color output doesn't yet work in XEmacs. |
| 340 | ;; | ||
| 341 | ;; Slow. Because XEmacs implements certain functions, such as | ||
| 342 | ;; next-property-change, in lisp, printing with faces is several times | ||
| 343 | ;; slower in XEmacs. In Emacs, these functions are implemented in C, | ||
| 344 | ;; so Emacs is somewhat faster. | ||
| 142 | ;; | 345 | ;; |
| 143 | ;; The PostScript needs review/cleanup/enhancing by a PS expert. | ||
| 144 | ;; | ||
| 145 | ;; ASCII Control characters other than tab, linefeed and pagefeed are | 346 | ;; ASCII Control characters other than tab, linefeed and pagefeed are |
| 146 | ;; not handled. | 347 | ;; not handled. |
| 147 | ;; | 348 | ;; |
| 148 | ;; The mechanism for determining whether a stretch of characters | 349 | ;; Default background color isn't working. |
| 149 | ;; should be printed bold, italic, or plain is crude and extremely | ||
| 150 | ;; limited. | ||
| 151 | ;; | 350 | ;; |
| 152 | ;; Faces are always treated as opaque. | 351 | ;; Faces are always treated as opaque. |
| 153 | ;; | 352 | ;; |
| 154 | ;; Font names are hardcoded. | 353 | ;; Epoch and Emacs 18 not supported. At all. |
| 155 | ;; | ||
| 156 | ;; Epoch not fully supported. | ||
| 157 | ;; | 354 | ;; |
| 158 | ;; Tested with only one PostScript printer. | ||
| 159 | ;; | 355 | ;; |
| 160 | ;; Features to add: | 356 | ;; Features to add: |
| 161 | ;; --------------- | 357 | ;; --------------- |
| 358 | ;; 2-up and 4-up capability. | ||
| 359 | ;; | ||
| 162 | ;; Line numbers. | 360 | ;; Line numbers. |
| 163 | ;; | 361 | ;; |
| 164 | ;; Simple headers with date, filename, and page numbers. | 362 | ;; Wide-print (landscape) capability. |
| 165 | ;; | 363 | ;; |
| 166 | ;; Gaudy headers a`la enscript and mp. | ||
| 167 | ;; | 364 | ;; |
| 168 | ;; 2-up and 4-up capability. | 365 | ;; Acknowledgements |
| 366 | ;; ---------------- | ||
| 367 | ;; Thanks to Kevin Rodgers <kevinr@ihs.com> for adding support for | ||
| 368 | ;; color and the invisible property. | ||
| 169 | ;; | 369 | ;; |
| 170 | ;; Wide-print capability. | 370 | ;; Thanks to Avishai Yacobi, avishaiy@mcil.comm.mot.com, for writing |
| 371 | ;; the initial port to Emacs 19. His code is no longer part of | ||
| 372 | ;; ps-print, but his work is still appreciated. | ||
| 171 | ;; | 373 | ;; |
| 374 | ;; Thanks to Remi Houdaille and Michel Train, michel@metasoft.fdn.org, | ||
| 375 | ;; for adding underline support. Their code also is no longer part of | ||
| 376 | ;; ps-print, but their efforts are not forgotten. | ||
| 377 | ;; | ||
| 378 | ;; Thanks also to all of you who mailed code to add features to | ||
| 379 | ;; ps-print; although I didn't use your code, I still appreciate your | ||
| 380 | ;; sharing it with me. | ||
| 381 | ;; | ||
| 382 | ;; Thanks to all who mailed comments, encouragement, and criticism. | ||
| 383 | ;; Thanks also to all who responded to my survey; I had too many | ||
| 384 | ;; responses to reply to them all, but I greatly appreciate your | ||
| 385 | ;; interest. | ||
| 386 | ;; | ||
| 387 | ;; Jim | ||
| 388 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 172 | 389 | ||
| 173 | ;;; Code: | 390 | ;;; Code: |
| 174 | 391 | ||
| 175 | (defconst ps-print-version (substring "$Revision: 1.5 $" 11 -2) | 392 | (defconst ps-print-version "1.10" |
| 176 | "$Id: ps-print.el,v 1.5 1994/04/22 13:25:18 jct Exp $ | 393 | "ps-print.el,v 1.10 1995/01/09 14:45:03 jct Exp |
| 177 | 394 | ||
| 178 | Please send all bug fixes and enhancements to Jim Thompson, | 395 | Please send all bug fixes and enhancements to |
| 179 | thompson@wg2.waii.com.") | 396 | Jim Thompson <thompson@wg2.waii.com>.") |
| 180 | 397 | ||
| 181 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 398 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 182 | (defvar ps-lpr-command (if (memq system-type | 399 | ;; User Variables: |
| 183 | '(usg-unix-v hpux silicon-graphics-unix)) | 400 | |
| 184 | "lp" "lpr") | 401 | (defvar ps-lpr-command lpr-command |
| 185 | "The shell command for printing a PostScript file.") | 402 | "*The shell command for printing a PostScript file.") |
| 186 | 403 | ||
| 187 | (defvar ps-lpr-switches nil | 404 | (defvar ps-lpr-switches lpr-switches |
| 188 | "A list of extra switches to pass to ps-lpr-command.") | 405 | "*A list of extra switches to pass to `ps-lpr-command'.") |
| 189 | 406 | ||
| 190 | (defvar ps-bold-faces | 407 | (defvar ps-spool-duplex nil ; Not many people have duplex |
| 191 | '(bold | 408 | ; printers, so default to nil. |
| 192 | bold-italic | 409 | "*Non-nil indicates spooling is for a two-sided printer. |
| 193 | font-lock-function-name-face | 410 | For a duplex printer, the `ps-spool-*' commands will insert blank pages |
| 194 | message-headers | 411 | as needed between print jobs so that the next buffer printed will |
| 195 | ) | 412 | start on the right page. Also, if headers are turned on, the headers |
| 196 | "A list of the faces that should be printed italic.") | 413 | will be reversed on duplex printers so that the page numbers fall to |
| 197 | 414 | the left on even-numbered pages.") | |
| 198 | (defvar ps-italic-faces | 415 | |
| 199 | '(italic | 416 | (defvar ps-paper-type 'ps-letter |
| 200 | bold-italic | 417 | "*Specifies the size of paper to format for. Should be one of |
| 201 | font-lock-function-name-face | 418 | 'ps-letter, 'ps-legal, or 'ps-a4.") |
| 202 | font-lock-string-face | 419 | |
| 203 | font-lock-comment-face | 420 | (defvar ps-print-header t |
| 204 | message-header-contents | 421 | "*Non-nil means print a header at the top of each page. By default, |
| 205 | message-highlighted-header-contents | 422 | the header displays the buffer name, page number, and, if the buffer |
| 206 | message-cited-text | 423 | is visiting a file, the file's directory. Headers are customizable by |
| 207 | ) | 424 | changing variables `ps-header-left' and `ps-header-right'.") |
| 208 | "A list of the faces that should be printed bold.") | 425 | |
| 209 | 426 | (defvar ps-print-header-frame t | |
| 210 | (defvar ps-underline-faces | 427 | "*Non-nil means draw a gaudy frame around the header.") |
| 211 | '(underline | 428 | |
| 212 | font-lock-string-face) | 429 | (defvar ps-show-n-of-n t |
| 213 | "A list of the faces that should be printed underline.") | 430 | "*Non-nil means show page numbers as \"n/m\", meaning page n of m. |
| 431 | Note: page numbers are displayed as part of headers, see variable `ps- | ||
| 432 | print-headers'.") | ||
| 433 | |||
| 434 | (defvar ps-print-color-p (and (fboundp 'x-color-values) | ||
| 435 | (fboundp 'float)) | ||
| 436 | ; Printing color requires both floating point and x-color-values. | ||
| 437 | "*If non-nil, print the buffer's text in color.") | ||
| 438 | |||
| 439 | (defvar ps-default-fg '(0.0 0.0 0.0) | ||
| 440 | "*RGB values of the default foreground color. Defaults to black.") | ||
| 441 | |||
| 442 | (defvar ps-default-bg '(1.0 1.0 1.0) | ||
| 443 | "*RGB values of the default background color. Defaults to white.") | ||
| 444 | |||
| 445 | (defvar ps-font-size 10 | ||
| 446 | "*Specifies the size, in points, of the font to print text in.") | ||
| 447 | |||
| 448 | (defvar ps-font "Courier" | ||
| 449 | "*Specifies the name of the font family to print text in.") | ||
| 450 | |||
| 451 | (defvar ps-font-bold "Courier-Bold" | ||
| 452 | "*Specifies the name of the font family to print bold text in.") | ||
| 453 | |||
| 454 | (defvar ps-font-italic "Courier-Oblique" | ||
| 455 | "*Specifies the name of the font family to print italic text in.") | ||
| 456 | |||
| 457 | (defvar ps-font-bold-italic "Courier-BoldOblique" | ||
| 458 | "*Specifies the name of the font family to print bold-italic text in.") | ||
| 459 | |||
| 460 | (defvar ps-avg-char-width (if (fboundp 'float) 5.6 6) | ||
| 461 | "*Specifies the average width, in points, of a character. This is the | ||
| 462 | value that ps-print uses to determine the length, x-dimension, of the | ||
| 463 | text it has printed, and thus affects the point at which long lines | ||
| 464 | wrap around. Note that if you change the font or font size, you will | ||
| 465 | probably have to adjust this value to match.") | ||
| 466 | |||
| 467 | (defvar ps-space-width (if (fboundp 'float) 5.6 6) | ||
| 468 | "*Specifies the width of a space character. This value is used in | ||
| 469 | expanding tab characters.") | ||
| 470 | |||
| 471 | (defvar ps-line-height (if (fboundp 'float) 11.29 11) | ||
| 472 | "*Specifies the height of a line. This is the value that ps-print | ||
| 473 | uses to determine the height, y-dimension, of the lines of text it has | ||
| 474 | printed, and thus affects the point at which page-breaks are placed. | ||
| 475 | Note that if you change the font or font size, you will probably have | ||
| 476 | to adjust this value to match. Note also that the line-height is | ||
| 477 | *not* the same as the point size of the font.") | ||
| 478 | |||
| 479 | (defvar ps-auto-font-detect t | ||
| 480 | "*Non-nil means automatically detect bold/italic face attributes. | ||
| 481 | Nil means rely solely on the lists `ps-bold-faces', `ps-italic-faces', | ||
| 482 | and `ps-underlined-faces'.") | ||
| 483 | |||
| 484 | (defvar ps-bold-faces '() | ||
| 485 | "*A list of the \(non-bold\) faces that should be printed in bold font.") | ||
| 486 | |||
| 487 | (defvar ps-italic-faces '() | ||
| 488 | "*A list of the \(non-italic\) faces that should be printed in italic font.") | ||
| 489 | |||
| 490 | (defvar ps-underlined-faces '() | ||
| 491 | "*A list of the \(non-underlined\) faces that should be printed underlined.") | ||
| 492 | |||
| 493 | (defvar ps-header-lines 2 | ||
| 494 | "*The number of lines to display in the page header.") | ||
| 495 | (make-variable-buffer-local 'ps-header-lines) | ||
| 496 | |||
| 497 | (defvar ps-left-header | ||
| 498 | (list 'ps-get-buffer-name 'ps-header-dirpart) | ||
| 499 | "*The items to display on the right part of the page header. | ||
| 500 | |||
| 501 | Should contain a list of strings and symbols, each representing an | ||
| 502 | entry in the PostScript array HeaderLinesLeft. | ||
| 503 | |||
| 504 | Strings are inserted unchanged into the array; those representing | ||
| 505 | PostScript string literals should be delimited with PostScript string | ||
| 506 | delimiters '(' and ')'. | ||
| 507 | |||
| 508 | For symbols with bound functions, the function is called and should | ||
| 509 | return a string to be inserted into the array. For symbols with bound | ||
| 510 | values, the value should be a string to be inserted into the array. | ||
| 511 | In either case, function or variable, the string value has PostScript | ||
| 512 | string delimiters added to it.") | ||
| 513 | (make-variable-buffer-local 'ps-left-header) | ||
| 514 | |||
| 515 | (defvar ps-right-header | ||
| 516 | (list "/pagenumberstring load" 'time-stamp-yy/mm/dd 'time-stamp-hh:mm:ss) | ||
| 517 | "*The items to display on the left part of the page header. | ||
| 518 | |||
| 519 | See the variable ps-left-header for a description of the format of | ||
| 520 | this variable.") | ||
| 521 | (make-variable-buffer-local 'ps-right-header) | ||
| 214 | 522 | ||
| 215 | (defvar ps-razzle-dazzle t | 523 | (defvar ps-razzle-dazzle t |
| 216 | "Non-nil means report progress while formatting buffer") | 524 | "*Non-nil means report progress while formatting buffer.") |
| 525 | |||
| 526 | (defvar ps-adobe-tag "%!PS-Adobe-1.0\n" | ||
| 527 | "*Contains the header line identifying the output as PostScript. | ||
| 528 | By default, `ps-adobe-tag' contains the standard identifier. Some | ||
| 529 | printers require slightly different versions of this line.") | ||
| 530 | |||
| 531 | (defvar ps-build-face-reference t | ||
| 532 | "*Non-nil means build the reference face lists. | ||
| 533 | |||
| 534 | Ps-print sets this value to nil after it builds its internal reference | ||
| 535 | lists of bold and italic faces. By settings its value back to t, you | ||
| 536 | can force ps-print to rebuild the lists the next time you invoke one | ||
| 537 | of the -with-faces commands. | ||
| 538 | |||
| 539 | You should set this value back to t after you change the attributes of | ||
| 540 | any face, or create new faces. Most users shouldn't have to worry | ||
| 541 | about its setting, though.") | ||
| 542 | |||
| 543 | (defvar ps-always-build-face-reference nil | ||
| 544 | "*Non-nil means always rebuild the reference face lists. | ||
| 545 | |||
| 546 | If this variable is non-nil, ps-print will rebuild its internal | ||
| 547 | reference lists of bold and italic faces *every* time one of the | ||
| 548 | -with-faces commands is called. Most users shouldn't need to set this | ||
| 549 | variable.") | ||
| 217 | 550 | ||
| 218 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 551 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 552 | ;; User commands | ||
| 219 | 553 | ||
| 220 | (defun ps-print-buffer (&optional filename) | 554 | (defun ps-print-buffer (&optional filename) |
| 221 | 555 | "Generate and print a PostScript image of the buffer. | |
| 222 | "Generate and print a PostScript image of the buffer. | ||
| 223 | 556 | ||
| 224 | When called with a numeric prefix argument (C-u), prompt the user for | 557 | When called with a numeric prefix argument (C-u), prompt the user for |
| 225 | the name of a file to save the PostScript image in, instead of sending | 558 | the name of a file to save the PostScript image in, instead of sending |
| @@ -228,220 +561,99 @@ it to the printer. | |||
| 228 | More specifically, the FILENAME argument is treated as follows: if it | 561 | More specifically, the FILENAME argument is treated as follows: if it |
| 229 | is nil, send the image to the printer. If FILENAME is a string, save | 562 | is nil, send the image to the printer. If FILENAME is a string, save |
| 230 | the PostScript image in a file with that name. If FILENAME is a | 563 | the PostScript image in a file with that name. If FILENAME is a |
| 231 | number, prompt the user for the name of the file to save in. | 564 | number, prompt the user for the name of the file to save in." |
| 232 | |||
| 233 | The image is rendered using the PostScript font Courier. | ||
| 234 | |||
| 235 | See also: ps-print-buffer-with-faces | ||
| 236 | ps-spool-buffer | ||
| 237 | ps-spool-buffer-with-faces" | ||
| 238 | 565 | ||
| 239 | (interactive "P") | 566 | (interactive "P") |
| 240 | (setq filename (ps-preprint filename)) | 567 | (setq filename (ps-print-preprint filename)) |
| 241 | (ps-generate (current-buffer) (point-min) (point-max) | 568 | (ps-generate (current-buffer) (point-min) (point-max) |
| 242 | 'ps-generate-postscript) | 569 | 'ps-generate-postscript) |
| 243 | (ps-do-despool filename)) | 570 | (ps-do-despool filename)) |
| 244 | 571 | ||
| 245 | 572 | ||
| 246 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 247 | |||
| 248 | (defun ps-print-buffer-with-faces (&optional filename) | 573 | (defun ps-print-buffer-with-faces (&optional filename) |
| 574 | "Generate and print a PostScript image of the buffer. | ||
| 249 | 575 | ||
| 250 | "Generate and print a PostScript image of the buffer. | 576 | Like `ps-print-buffer', but includes font, color, and underline |
| 251 | 577 | information in the generated image." | |
| 252 | This function works like ps-print-buffer, with the additional benefit | ||
| 253 | that any bold/italic formatting information present in the buffer | ||
| 254 | (contained in extents and faces) will be retained in the PostScript | ||
| 255 | image. In other words, WYSIAWYG -- What You See Is (Almost) What You | ||
| 256 | Get. | ||
| 257 | |||
| 258 | Ps-print uses three lists to determine which faces should be printed | ||
| 259 | bold, italic, and/or underlined; the lists are named ps-bold-faces, ps- | ||
| 260 | italic-faces, and ps-underline-faces. A given face should appear on as | ||
| 261 | many lists as are appropriate; for example, face bold-italic is in both | ||
| 262 | the lists ps-bold-faces and ps-italic-faces. The lists are pre-built | ||
| 263 | with the standard bold, italic, and bold-italic faces, with font-lock's | ||
| 264 | faces, and with the faces used by gnus and rmail. | ||
| 265 | |||
| 266 | The image is rendered using the PostScript fonts Courier, Courier-Bold, | ||
| 267 | Courier-Oblique, and Courier-BoldOblique. | ||
| 268 | |||
| 269 | See also: ps-print-buffer | ||
| 270 | ps-spool-buffer | ||
| 271 | ps-spool-buffer-with-faces." | ||
| 272 | |||
| 273 | (interactive "P") | 578 | (interactive "P") |
| 274 | (setq filename (ps-preprint filename)) | 579 | (setq filename (ps-print-preprint filename)) |
| 275 | (ps-generate (current-buffer) (point-min) (point-max) | 580 | (ps-generate (current-buffer) (point-min) (point-max) |
| 276 | 'ps-generate-postscript-with-faces) | 581 | 'ps-generate-postscript-with-faces) |
| 277 | (ps-do-despool filename)) | 582 | (ps-do-despool filename)) |
| 278 | 583 | ||
| 279 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 280 | 584 | ||
| 281 | (defun ps-print-region (from to &optional filename) | 585 | (defun ps-print-region (from to &optional filename) |
| 586 | "Generate and print a PostScript image of the region. | ||
| 282 | 587 | ||
| 283 | "Generate and print a PostScript image of the region. | 588 | Like `ps-print-buffer', but prints just the current region." |
| 284 | |||
| 285 | When called with a numeric prefix argument (C-u), prompt the user for | ||
| 286 | the name of a file to save the PostScript image in, instead of sending | ||
| 287 | it to the printer. | ||
| 288 | |||
| 289 | This function is essentially the same as ps-print-buffer except that it | ||
| 290 | prints just a region, and not the entire buffer. For more information, | ||
| 291 | see the function ps-print-buffer. | ||
| 292 | 589 | ||
| 293 | See also: ps-print-region-with-faces | ||
| 294 | ps-spool-region | ||
| 295 | ps-spool-region-with-faces" | ||
| 296 | |||
| 297 | (interactive "r\nP") | 590 | (interactive "r\nP") |
| 298 | (setq filename (ps-preprint filename)) | 591 | (setq filename (ps-print-preprint filename)) |
| 299 | (ps-generate (current-buffer) from to | 592 | (ps-generate (current-buffer) from to |
| 300 | 'ps-generate-postscript) | 593 | 'ps-generate-postscript) |
| 301 | (ps-do-despool filename)) | 594 | (ps-do-despool filename)) |
| 302 | 595 | ||
| 303 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 304 | 596 | ||
| 305 | (defun ps-print-region-with-faces (from to &optional filename) | 597 | (defun ps-print-region-with-faces (from to &optional filename) |
| 598 | "Generate and print a PostScript image of the region. | ||
| 306 | 599 | ||
| 307 | "Generate and print a PostScript image of the region. | 600 | Like `ps-print-region', but includes font, color, and underline |
| 308 | 601 | information in the generated image." | |
| 309 | This function is essentially the same as ps-print-buffer except that it | ||
| 310 | prints just a region, and not the entire buffer. See the functions | ||
| 311 | ps-print-region and ps-print-buffer-with-faces for | ||
| 312 | more information. | ||
| 313 | 602 | ||
| 314 | See also: ps-print-region | ||
| 315 | ps-spool-region | ||
| 316 | ps-spool-region-with-faces" | ||
| 317 | |||
| 318 | (interactive "r\nP") | 603 | (interactive "r\nP") |
| 319 | (setq filename (ps-preprint filename)) | 604 | (setq filename (ps-print-preprint filename)) |
| 320 | (ps-generate (current-buffer) from to | 605 | (ps-generate (current-buffer) from to |
| 321 | 'ps-generate-postscript-with-faces) | 606 | 'ps-generate-postscript-with-faces) |
| 322 | (ps-do-despool filename)) | 607 | (ps-do-despool filename)) |
| 323 | 608 | ||
| 324 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 325 | 609 | ||
| 326 | (defun ps-spool-buffer () | 610 | (defun ps-spool-buffer () |
| 611 | "Generate and spool a PostScript image of the buffer. | ||
| 327 | 612 | ||
| 328 | "Generate and spool a PostScript image of the buffer. | 613 | Like `ps-print-buffer' except that the PostScript image is saved in a |
| 329 | 614 | local buffer to be sent to the printer later. | |
| 330 | This function is essentially the same as function ps-print-buffer | ||
| 331 | except that the PostScript image is saved in a local buffer to be sent | ||
| 332 | to the printer later. | ||
| 333 | |||
| 334 | Each time you call one of the ps-spool- functions, the generated | ||
| 335 | PostScript is appended to a buffer named *PostScript*; to send the | ||
| 336 | spooled PostScript to the printer, or save it to a file, use the command | ||
| 337 | ps-despool. | ||
| 338 | |||
| 339 | If the variable ps-spool-duplex is non-nil, then the spooled PostScript | ||
| 340 | is padded with blank pages, when needed, so that each printed buffer | ||
| 341 | will start on a front page when printed on a duplex printer (a printer | ||
| 342 | that prints on both sides on the paper). Users of non-duplex printers | ||
| 343 | will want to leave ps-spool-duplex nil. | ||
| 344 | |||
| 345 | The spooling mechanism was designed for printing lots of small files | ||
| 346 | (mail messages or netnews articles) to save paper that would otherwise | ||
| 347 | be wasted on banner pages, and to make it easier to find your output at | ||
| 348 | the printer (it's easier to pick up one 50-page printout than to find 50 | ||
| 349 | single-page printouts). | ||
| 350 | |||
| 351 | Ps-print has a hook in the kill-emacs-hook list so that you won't | ||
| 352 | accidently quit from Emacs while you have unprinted PostScript waiting | ||
| 353 | in the spool buffer. If you do attempt to exit with spooled PostScript, | ||
| 354 | you'll be asked if you want to print it, and if you decline, you'll be | ||
| 355 | asked to confirm the exit; this is modeled on the confirmation that | ||
| 356 | Emacs uses for modified buffers. | ||
| 357 | |||
| 358 | See also: ps-despool | ||
| 359 | ps-print-buffer | ||
| 360 | ps-print-buffer-with-faces | ||
| 361 | ps-spool-buffer-with-faces" | ||
| 362 | 615 | ||
| 616 | Use the command `ps-despool' to send the spooled images to the printer." | ||
| 363 | (interactive) | 617 | (interactive) |
| 364 | (ps-generate (current-buffer) (point-min) (point-max) | 618 | (ps-generate (current-buffer) (point-min) (point-max) |
| 365 | 'ps-generate-postscript)) | 619 | 'ps-generate-postscript)) |
| 366 | 620 | ||
| 367 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 368 | 621 | ||
| 369 | (defun ps-spool-buffer-with-faces () | 622 | (defun ps-spool-buffer-with-faces () |
| 623 | "Generate and spool a PostScript image of the buffer. | ||
| 370 | 624 | ||
| 371 | "Generate and spool PostScript image of the buffer. | 625 | Like `ps-spool-buffer', but includes font, color, and underline |
| 372 | 626 | information in the generated image. | |
| 373 | This function is essentially the same as function ps-print-buffer-with- | ||
| 374 | faces except that the PostScript image is saved in a local buffer to be | ||
| 375 | sent to the printer later. | ||
| 376 | 627 | ||
| 377 | Use the function ps-despool to send the spooled images to the printer. | 628 | Use the command `ps-despool' to send the spooled images to the printer." |
| 378 | See the function ps-spool-buffer for a description of the spooling | ||
| 379 | mechanism. | ||
| 380 | |||
| 381 | See also: ps-despool | ||
| 382 | ps-spool-buffer | ||
| 383 | ps-print-buffer | ||
| 384 | ps-print-buffer-with-faces" | ||
| 385 | 629 | ||
| 386 | (interactive) | 630 | (interactive) |
| 387 | (ps-generate (current-buffer) (point-min) (point-max) | 631 | (ps-generate (current-buffer) (point-min) (point-max) |
| 388 | 'ps-generate-postscript-with-faces)) | 632 | 'ps-generate-postscript-with-faces)) |
| 389 | 633 | ||
| 390 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 391 | 634 | ||
| 392 | (defun ps-spool-region (from to) | 635 | (defun ps-spool-region (from to) |
| 636 | "Generate a PostScript image of the region and spool locally. | ||
| 393 | 637 | ||
| 394 | "Generate PostScript image of the region and spool locally. | 638 | Like `ps-spool-buffer', but spools just the current region. |
| 395 | |||
| 396 | This function is essentially the same as function ps-print-region except | ||
| 397 | that the PostScript image is saved in a local buffer to be sent to the | ||
| 398 | printer later. | ||
| 399 | |||
| 400 | Use the function ps-despool to send the spooled images to the printer. | ||
| 401 | See the function ps-spool-buffer for a description of the spooling | ||
| 402 | mechanism. | ||
| 403 | |||
| 404 | See also: ps-despool | ||
| 405 | ps-spool-buffer | ||
| 406 | ps-print-buffer | ||
| 407 | ps-print-buffer-with-faces" | ||
| 408 | 639 | ||
| 640 | Use the command `ps-despool' to send the spooled images to the printer." | ||
| 409 | (interactive "r") | 641 | (interactive "r") |
| 410 | (ps-generate (current-buffer) from to | 642 | (ps-generate (current-buffer) from to |
| 411 | 'ps-generate-postscript)) | 643 | 'ps-generate-postscript)) |
| 412 | 644 | ||
| 413 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 414 | 645 | ||
| 415 | (defun ps-spool-region-with-faces (from to) | 646 | (defun ps-spool-region-with-faces (from to) |
| 647 | "Generate a PostScript image of the region and spool locally. | ||
| 416 | 648 | ||
| 417 | "Generate PostScript image of the region and spool locally. | 649 | Like `ps-spool-region', but includes font, color, and underline |
| 418 | 650 | information in the generated image. | |
| 419 | This function is essentially the same as function ps-print-region-with- | ||
| 420 | faces except that the PostScript image is saved in a local buffer to be | ||
| 421 | sent to the printer later. | ||
| 422 | |||
| 423 | Use the function ps-despool to send the spooled images to the printer. | ||
| 424 | See the function ps-spool-buffer for a description of the spooling | ||
| 425 | mechanism. | ||
| 426 | |||
| 427 | See also: ps-despool | ||
| 428 | ps-spool-buffer | ||
| 429 | ps-print-buffer | ||
| 430 | ps-print-buffer-with-faces" | ||
| 431 | 651 | ||
| 652 | Use the command `ps-despool' to send the spooled images to the printer." | ||
| 432 | (interactive "r") | 653 | (interactive "r") |
| 433 | (ps-generate (current-buffer) from to | 654 | (ps-generate (current-buffer) from to |
| 434 | 'ps-generate-postscript-with-faces)) | 655 | 'ps-generate-postscript-with-faces)) |
| 435 | 656 | ||
| 436 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 437 | |||
| 438 | (defvar ps-spool-duplex nil ; Not many people have duplex | ||
| 439 | ; printers, so default to nil. | ||
| 440 | "*Non-nil indicates spooling is for a two-sided printer. | ||
| 441 | For a duplex printer, the ps-spool functions will insert blank pages | ||
| 442 | as needed between print jobs so that the next buffer printed will | ||
| 443 | start on the right page.") | ||
| 444 | |||
| 445 | (defun ps-despool (&optional filename) | 657 | (defun ps-despool (&optional filename) |
| 446 | "Send the spooled PostScript to the printer. | 658 | "Send the spooled PostScript to the printer. |
| 447 | 659 | ||
| @@ -453,302 +665,945 @@ More specifically, the FILENAME argument is treated as follows: if it | |||
| 453 | is nil, send the image to the printer. If FILENAME is a string, save | 665 | is nil, send the image to the printer. If FILENAME is a string, save |
| 454 | the PostScript image in a file with that name. If FILENAME is a | 666 | the PostScript image in a file with that name. If FILENAME is a |
| 455 | number, prompt the user for the name of the file to save in." | 667 | number, prompt the user for the name of the file to save in." |
| 456 | |||
| 457 | (interactive "P") | 668 | (interactive "P") |
| 669 | (ps-do-despool (ps-print-preprint filename))) | ||
| 670 | |||
| 671 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 672 | ;; Utility functions and variables: | ||
| 673 | |||
| 674 | (if (featurep 'emacs-vers) | ||
| 675 | nil | ||
| 676 | (defvar emacs-type (cond ((string-match "XEmacs" emacs-version) 'xemacs) | ||
| 677 | ((string-match "Lucid" emacs-version) 'lucid) | ||
| 678 | ((string-match "Epoch" emacs-version) 'epoch) | ||
| 679 | (t 'fsf)))) | ||
| 680 | |||
| 681 | (if (or (eq emacs-type 'lucid) | ||
| 682 | (eq emacs-type 'xemacs)) | ||
| 683 | (setq ps-print-color-p nil) | ||
| 684 | (require 'faces)) ; face-font, face-underline-p, | ||
| 685 | ; x-font-regexp | ||
| 686 | |||
| 687 | (require 'time-stamp) | ||
| 688 | |||
| 689 | (defvar ps-print-prologue "% ISOLatin1Encoding stolen from ps_init.ps in GhostScript 2.6.1.4: | ||
| 690 | % If the ISOLatin1Encoding vector isn't known, define it. | ||
| 691 | /ISOLatin1Encoding where { pop } { | ||
| 692 | % Define the ISO Latin-1 encoding vector. | ||
| 693 | % The first half is the same as the standard encoding, | ||
| 694 | % except for minus instead of hyphen at code 055. | ||
| 695 | /ISOLatin1Encoding | ||
| 696 | StandardEncoding 0 45 getinterval aload pop | ||
| 697 | /minus | ||
| 698 | StandardEncoding 46 82 getinterval aload pop | ||
| 699 | %*** NOTE: the following are missing in the Adobe documentation, | ||
| 700 | %*** but appear in the displayed table: | ||
| 701 | %*** macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240. | ||
| 702 | % \20x | ||
| 703 | /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef | ||
| 704 | /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef | ||
| 705 | /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent | ||
| 706 | /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron | ||
| 707 | % \24x | ||
| 708 | /space /exclamdown /cent /sterling | ||
| 709 | /currency /yen /brokenbar /section | ||
| 710 | /dieresis /copyright /ordfeminine /guillemotleft | ||
| 711 | /logicalnot /hyphen /registered /macron | ||
| 712 | /degree /plusminus /twosuperior /threesuperior | ||
| 713 | /acute /mu /paragraph /periodcentered | ||
| 714 | /cedilla /onesuperior /ordmasculine /guillemotright | ||
| 715 | /onequarter /onehalf /threequarters /questiondown | ||
| 716 | % \30x | ||
| 717 | /Agrave /Aacute /Acircumflex /Atilde | ||
| 718 | /Adieresis /Aring /AE /Ccedilla | ||
| 719 | /Egrave /Eacute /Ecircumflex /Edieresis | ||
| 720 | /Igrave /Iacute /Icircumflex /Idieresis | ||
| 721 | /Eth /Ntilde /Ograve /Oacute | ||
| 722 | /Ocircumflex /Otilde /Odieresis /multiply | ||
| 723 | /Oslash /Ugrave /Uacute /Ucircumflex | ||
| 724 | /Udieresis /Yacute /Thorn /germandbls | ||
| 725 | % \34x | ||
| 726 | /agrave /aacute /acircumflex /atilde | ||
| 727 | /adieresis /aring /ae /ccedilla | ||
| 728 | /egrave /eacute /ecircumflex /edieresis | ||
| 729 | /igrave /iacute /icircumflex /idieresis | ||
| 730 | /eth /ntilde /ograve /oacute | ||
| 731 | /ocircumflex /otilde /odieresis /divide | ||
| 732 | /oslash /ugrave /uacute /ucircumflex | ||
| 733 | /udieresis /yacute /thorn /ydieresis | ||
| 734 | 256 packedarray def | ||
| 735 | } ifelse | ||
| 736 | |||
| 737 | /reencodeFontISO { %def | ||
| 738 | dup | ||
| 739 | length 5 add dict % Make a new font (a new dict | ||
| 740 | % the same size as the old | ||
| 741 | % one) with room for our new | ||
| 742 | % symbols. | ||
| 743 | |||
| 744 | begin % Make the new font the | ||
| 745 | % current dictionary. | ||
| 746 | |||
| 747 | |||
| 748 | { 1 index /FID ne | ||
| 749 | { def } { pop pop } ifelse | ||
| 750 | } forall % Copy each of the symbols | ||
| 751 | % from the old dictionary to | ||
| 752 | % the new except for the font | ||
| 753 | % ID. | ||
| 754 | |||
| 755 | /Encoding ISOLatin1Encoding def % Override the encoding with | ||
| 756 | % the ISOLatin1 encoding. | ||
| 757 | |||
| 758 | % Use the font's bounding box to determine the ascent, descent, | ||
| 759 | % and overall height; don't forget that these values have to be | ||
| 760 | % transformed using the font's matrix. | ||
| 761 | FontBBox | ||
| 762 | FontMatrix transform /Ascent exch def pop | ||
| 763 | FontMatrix transform /Descent exch def pop | ||
| 764 | /FontHeight Ascent Descent sub def | ||
| 765 | |||
| 766 | % Define these in case they're not in the FontInfo (also, here | ||
| 767 | % they're easier to get to. | ||
| 768 | /UnderlinePosition 1 def | ||
| 769 | /UnderlineThickness 1 def | ||
| 770 | |||
| 771 | % Get the underline position and thickness if they're defined. | ||
| 772 | currentdict /FontInfo known { | ||
| 773 | FontInfo | ||
| 774 | |||
| 775 | dup /UnderlinePosition known { | ||
| 776 | dup /UnderlinePosition get | ||
| 777 | 0 exch FontMatrix transform exch pop | ||
| 778 | /UnderlinePosition exch def | ||
| 779 | } if | ||
| 780 | |||
| 781 | dup /UnderlineThickness known { | ||
| 782 | /UnderlineThickness get | ||
| 783 | 0 exch FontMatrix transform exch pop | ||
| 784 | /UnderlineThickness exch def | ||
| 785 | } if | ||
| 786 | |||
| 787 | } if | ||
| 788 | |||
| 789 | currentdict % Leave the new font on the | ||
| 790 | % stack | ||
| 791 | |||
| 792 | end % Stop using the font as the | ||
| 793 | % current dictionary. | ||
| 794 | |||
| 795 | definefont % Put the font into the font | ||
| 796 | % dictionary | ||
| 797 | |||
| 798 | pop % Discard the returned font. | ||
| 799 | } bind def | ||
| 458 | 800 | ||
| 459 | ;; If argument FILENAME is nil, send the image to the printer; if | 801 | /Font { |
| 460 | ;; FILENAME is a string, save the PostScript image in that filename; | 802 | findfont exch scalefont reencodeFontISO |
| 461 | ;; if FILENAME is a number, prompt the user for the name of the file | 803 | } def |
| 462 | ;; to save in. | 804 | |
| 805 | /F { % Font select | ||
| 806 | findfont | ||
| 807 | dup /Ascent get /Ascent exch def | ||
| 808 | dup /Descent get /Descent exch def | ||
| 809 | dup /FontHeight get /LineHeight exch def | ||
| 810 | dup /UnderlinePosition get /UnderlinePosition exch def | ||
| 811 | dup /UnderlineThickness get /UnderlineThickness exch def | ||
| 812 | setfont | ||
| 813 | } def | ||
| 814 | |||
| 815 | /FG /setrgbcolor load def | ||
| 816 | |||
| 817 | /bg false def | ||
| 818 | /BG { | ||
| 819 | dup /bg exch def | ||
| 820 | { mark 4 1 roll ] /bgcolor exch def } if | ||
| 821 | } def | ||
| 822 | |||
| 823 | /dobackground { % width -- | ||
| 824 | currentpoint | ||
| 825 | gsave | ||
| 826 | newpath | ||
| 827 | moveto | ||
| 828 | 0 Ascent rmoveto | ||
| 829 | dup 0 rlineto | ||
| 830 | 0 Descent Ascent sub rlineto | ||
| 831 | neg 0 rlineto | ||
| 832 | closepath | ||
| 833 | bgcolor aload pop setrgbcolor | ||
| 834 | fill | ||
| 835 | grestore | ||
| 836 | } def | ||
| 837 | |||
| 838 | /dobackgroundstring { % string -- | ||
| 839 | stringwidth pop | ||
| 840 | dobackground | ||
| 841 | } def | ||
| 842 | |||
| 843 | /dounderline { % fromx fromy -- | ||
| 844 | currentpoint | ||
| 845 | gsave | ||
| 846 | UnderlineThickness setlinewidth | ||
| 847 | 4 2 roll | ||
| 848 | UnderlinePosition add moveto | ||
| 849 | UnderlinePosition add lineto | ||
| 850 | stroke | ||
| 851 | grestore | ||
| 852 | } def | ||
| 853 | |||
| 854 | /eolbg { | ||
| 855 | currentpoint pop | ||
| 856 | PrintWidth LeftMargin add exch sub dobackground | ||
| 857 | } def | ||
| 858 | |||
| 859 | /eolul { | ||
| 860 | currentpoint exch pop | ||
| 861 | PrintWidth LeftMargin add exch dounderline | ||
| 862 | } def | ||
| 863 | |||
| 864 | /SL { % Soft Linefeed | ||
| 865 | bg { eolbg } if | ||
| 866 | ul { eolul } if | ||
| 867 | currentpoint LineHeight sub LeftMargin exch moveto pop | ||
| 868 | } def | ||
| 869 | |||
| 870 | /HL /SL load def % Hard Linefeed | ||
| 871 | |||
| 872 | /sp1 { currentpoint 3 -1 roll } def | ||
| 873 | |||
| 874 | % Some debug | ||
| 875 | /dcp { currentpoint exch 40 string cvs print (, ) print = } def | ||
| 876 | /dp { print 2 copy | ||
| 877 | exch 40 string cvs print (, ) print = } def | ||
| 878 | |||
| 879 | /S { | ||
| 880 | bg { dup dobackgroundstring } if | ||
| 881 | ul { sp1 } if | ||
| 882 | show | ||
| 883 | ul { dounderline } if | ||
| 884 | } def | ||
| 885 | |||
| 886 | /W { | ||
| 887 | ul { sp1 } if | ||
| 888 | ( ) stringwidth % Get the width of a space | ||
| 889 | pop % Discard the Y component | ||
| 890 | mul % Multiply the width of a | ||
| 891 | % space by the number of | ||
| 892 | % spaces to plot | ||
| 893 | bg { dup dobackground } if | ||
| 894 | 0 rmoveto | ||
| 895 | ul { dounderline } if | ||
| 896 | } def | ||
| 897 | |||
| 898 | /BeginDSCPage { | ||
| 899 | /vmstate save def | ||
| 900 | } def | ||
| 901 | |||
| 902 | /BeginPage { | ||
| 903 | PrintHeader { | ||
| 904 | PrintHeaderFrame { HeaderFrame } if | ||
| 905 | HeaderText | ||
| 906 | } if | ||
| 907 | LeftMargin | ||
| 908 | BottomMargin PrintHeight add | ||
| 909 | moveto % move to where printing will | ||
| 910 | % start. | ||
| 911 | } def | ||
| 912 | |||
| 913 | /EndPage { | ||
| 914 | bg { eolbg } if | ||
| 915 | ul { eolul } if | ||
| 916 | showpage % Spit out a page | ||
| 917 | } def | ||
| 918 | |||
| 919 | /EndDSCPage { | ||
| 920 | vmstate restore | ||
| 921 | } def | ||
| 922 | |||
| 923 | /ul false def | ||
| 924 | |||
| 925 | /UL { /ul exch def } def | ||
| 926 | |||
| 927 | /h0 14 /Helvetica-Bold Font | ||
| 928 | /h1 12 /Helvetica Font | ||
| 929 | |||
| 930 | /h1 F | ||
| 931 | |||
| 932 | /HeaderLineHeight LineHeight def | ||
| 933 | /HeaderDescent Descent def | ||
| 934 | /HeaderPad 2 def | ||
| 935 | |||
| 936 | /SetHeaderLines { | ||
| 937 | /HeaderOffset TopMargin 2 div def | ||
| 938 | /HeaderLines exch def | ||
| 939 | /HeaderHeight HeaderLines HeaderLineHeight mul HeaderPad 2 mul add def | ||
| 940 | /PrintHeight PrintHeight HeaderHeight sub def | ||
| 941 | } def | ||
| 942 | |||
| 943 | /HeaderFrameStart { | ||
| 944 | LeftMargin BottomMargin PrintHeight add HeaderOffset add | ||
| 945 | } def | ||
| 946 | |||
| 947 | /HeaderFramePath { | ||
| 948 | PrintWidth 0 rlineto | ||
| 949 | 0 HeaderHeight rlineto | ||
| 950 | PrintWidth neg 0 rlineto | ||
| 951 | 0 HeaderHeight neg rlineto | ||
| 952 | } def | ||
| 953 | |||
| 954 | /HeaderFrame { | ||
| 955 | gsave | ||
| 956 | 0.4 setlinewidth | ||
| 957 | HeaderFrameStart moveto | ||
| 958 | 1 -1 rmoveto | ||
| 959 | HeaderFramePath | ||
| 960 | 0 setgray fill | ||
| 961 | HeaderFrameStart moveto | ||
| 962 | HeaderFramePath | ||
| 963 | gsave 0.9 setgray fill grestore | ||
| 964 | gsave 0 setgray stroke grestore | ||
| 965 | grestore | ||
| 966 | } def | ||
| 967 | |||
| 968 | /HeaderStart { | ||
| 969 | HeaderFrameStart | ||
| 970 | exch HeaderPad add exch | ||
| 971 | HeaderLineHeight HeaderLines 1 sub mul add HeaderDescent sub HeaderPad add | ||
| 972 | } def | ||
| 973 | |||
| 974 | /strcat { | ||
| 975 | dup length 3 -1 roll dup length dup 4 -1 roll add string dup | ||
| 976 | 0 5 -1 roll putinterval | ||
| 977 | dup 4 2 roll exch putinterval | ||
| 978 | } def | ||
| 979 | |||
| 980 | /pagenumberstring { | ||
| 981 | PageNumber 32 string cvs | ||
| 982 | ShowNofN { | ||
| 983 | (/) strcat | ||
| 984 | PageCount 32 string cvs strcat | ||
| 985 | } if | ||
| 986 | } def | ||
| 987 | |||
| 988 | /HeaderText { | ||
| 989 | HeaderStart moveto | ||
| 990 | |||
| 991 | HeaderLinesRight HeaderLinesLeft | ||
| 992 | Duplex PageNumber 1 and 0 eq and { exch } if | ||
| 993 | |||
| 994 | { | ||
| 995 | aload pop | ||
| 996 | exch F | ||
| 997 | gsave | ||
| 998 | dup xcheck { exec } if | ||
| 999 | show | ||
| 1000 | grestore | ||
| 1001 | 0 HeaderLineHeight neg rmoveto | ||
| 1002 | } forall | ||
| 1003 | |||
| 1004 | HeaderStart moveto | ||
| 1005 | |||
| 1006 | { | ||
| 1007 | aload pop | ||
| 1008 | exch F | ||
| 1009 | gsave | ||
| 1010 | dup xcheck { exec } if | ||
| 1011 | dup stringwidth pop | ||
| 1012 | PrintWidth exch sub HeaderPad 2 mul sub 0 rmoveto | ||
| 1013 | show | ||
| 1014 | grestore | ||
| 1015 | 0 HeaderLineHeight neg rmoveto | ||
| 1016 | } forall | ||
| 1017 | } def | ||
| 1018 | |||
| 1019 | /ReportFontInfo { | ||
| 1020 | 2 copy | ||
| 1021 | /t0 3 1 roll Font | ||
| 1022 | /t0 F | ||
| 1023 | /lh LineHeight def | ||
| 1024 | /sw ( ) stringwidth pop def | ||
| 1025 | /aw (01234567890abcdefghijklmnopqrstuvwxyz) dup length exch | ||
| 1026 | stringwidth pop exch div def | ||
| 1027 | /t1 12 /Helvetica-Oblique Font | ||
| 1028 | /t1 F | ||
| 1029 | 72 72 moveto | ||
| 1030 | gsave | ||
| 1031 | (For ) show | ||
| 1032 | 128 string cvs show | ||
| 1033 | ( ) show | ||
| 1034 | 32 string cvs show | ||
| 1035 | ( point, the line height is ) show | ||
| 1036 | lh 32 string cvs show | ||
| 1037 | (, the space width is ) show | ||
| 1038 | sw 32 string cvs show | ||
| 1039 | (,) show | ||
| 1040 | grestore | ||
| 1041 | 0 LineHeight neg rmoveto | ||
| 1042 | (and a crude estimate of average character width is ) show | ||
| 1043 | aw 32 string cvs show | ||
| 1044 | (.) show | ||
| 1045 | showpage | ||
| 1046 | } def | ||
| 1047 | |||
| 1048 | % 10 /Courier ReportFontInfo | ||
| 1049 | ") | ||
| 1050 | |||
| 1051 | ;; Start Editing Here: | ||
| 463 | 1052 | ||
| 464 | (setq filename (ps-preprint filename)) | 1053 | (defvar ps-source-buffer nil) |
| 465 | (ps-do-despool filename)) | 1054 | (defvar ps-spool-buffer-name "*PostScript*") |
| 1055 | (defvar ps-spool-buffer nil) | ||
| 466 | 1056 | ||
| 467 | ;; Here end the definitions that users need to know about; proceed | 1057 | (defvar ps-output-head nil) |
| 468 | ;; further at your own risk! | 1058 | (defvar ps-output-tail nil) |
| 469 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 470 | 1059 | ||
| 471 | (defun ps-kill-emacs-check () | 1060 | (defvar ps-page-count 0) |
| 472 | (if (and (setq ps-buffer (get-buffer ps-spool-buffer-name)) | 1061 | (defvar ps-showpage-count 0) |
| 473 | (buffer-modified-p ps-buffer)) | ||
| 474 | (if (y-or-n-p "Unprinted PostScript waiting... print now? ") | ||
| 475 | (ps-despool))) | ||
| 476 | 1062 | ||
| 477 | (if (and (setq ps-buffer (get-buffer ps-spool-buffer-name)) | 1063 | (defvar ps-current-font 0) |
| 478 | (buffer-modified-p ps-buffer)) | 1064 | (defvar ps-current-underline-p nil) |
| 479 | (if (yes-or-no-p "Unprinted PostScript waiting; exit anyway? ") | 1065 | (defvar ps-default-color (if ps-print-color-p ps-default-fg)) ; black |
| 480 | nil | 1066 | (defvar ps-current-color ps-default-color) |
| 481 | (error "Unprinted PostScript")))) | 1067 | (defvar ps-current-bg nil) |
| 1068 | |||
| 1069 | (defvar ps-razchunk 0) | ||
| 1070 | |||
| 1071 | (defvar ps-color-format (if (eq emacs-type 'fsf) | ||
| 1072 | |||
| 1073 | ;;Emacs understands the %f format; we'll | ||
| 1074 | ;;use it to limit color RGB values to | ||
| 1075 | ;;three decimals to cut down some on the | ||
| 1076 | ;;size of the PostScript output. | ||
| 1077 | "%0.3f %0.3f %0.3f" | ||
| 1078 | |||
| 1079 | ;; Lucid emacsen will have to make do with | ||
| 1080 | ;; %s (princ) for floats. | ||
| 1081 | "%s %s %s")) | ||
| 1082 | |||
| 1083 | ;; These values determine how much print-height to deduct when headers | ||
| 1084 | ;; are turned on. This is a pretty clumsy way of handling it, but | ||
| 1085 | ;; it'll do for now. | ||
| 1086 | (defvar ps-header-title-line-height (if (fboundp 'float) 16.0 16));Helvetica 14 | ||
| 1087 | (defvar ps-header-line-height (if (fboundp 'float) 13.7 14));Helvetica 12 | ||
| 1088 | (defvar ps-header-pad 2) | ||
| 1089 | |||
| 1090 | ;; LetterSmall 7.68 inch 10.16 inch | ||
| 1091 | ;; Tabloid 11.0 inch 17.0 inch | ||
| 1092 | ;; Ledger 17.0 inch 11.0 inch | ||
| 1093 | ;; Statement 5.5 inch 8.5 inch | ||
| 1094 | ;; Executive 7.5 inch 10.0 inch | ||
| 1095 | ;; A3 11.69 inch 16.5 inch | ||
| 1096 | ;; A4Small 7.47 inch 10.85 inch | ||
| 1097 | ;; B4 10.125 inch 14.33 inch | ||
| 1098 | ;; B5 7.16 inch 10.125 inch | ||
| 1099 | |||
| 1100 | ;; All page dimensions are in PostScript points. | ||
| 1101 | |||
| 1102 | (defvar ps-left-margin 72) ; 1 inch | ||
| 1103 | (defvar ps-right-margin 72) ; 1 inch | ||
| 1104 | (defvar ps-bottom-margin 36) ; 1/2 inch | ||
| 1105 | (defvar ps-top-margin 72) ; 1 inch | ||
| 1106 | |||
| 1107 | ;; Letter 8.5 inch x 11.0 inch | ||
| 1108 | (defvar ps-letter-page-height 792) ; 11 inches | ||
| 1109 | (defvar ps-letter-page-width 612) ; 8.5 inches | ||
| 1110 | |||
| 1111 | ;; Legal 8.5 inch x 14.0 inch | ||
| 1112 | (defvar ps-legal-page-height 1008) ; 14.0 inches | ||
| 1113 | (defvar ps-legal-page-width 612) ; 8.5 inches | ||
| 1114 | |||
| 1115 | ;; A4 8.26 inch x 11.69 inch | ||
| 1116 | (defvar ps-a4-page-height 842) ; 11.69 inches | ||
| 1117 | (defvar ps-a4-page-width 595) ; 8.26 inches | ||
| 1118 | |||
| 1119 | (defvar ps-pages-alist | ||
| 1120 | (list (list 'ps-letter ps-letter-page-width ps-letter-page-height) | ||
| 1121 | (list 'ps-legal ps-legal-page-width ps-legal-page-height) | ||
| 1122 | (list 'ps-a4 ps-a4-page-width ps-a4-page-height))) | ||
| 1123 | |||
| 1124 | ;; Define some constants to index into the page lists. | ||
| 1125 | (defvar ps-page-width-i 1) | ||
| 1126 | (defvar ps-page-height-i 2) | ||
| 1127 | |||
| 1128 | (defvar ps-page-dimensions nil) | ||
| 1129 | (defvar ps-print-width nil) | ||
| 1130 | (defvar ps-print-height nil) | ||
| 1131 | |||
| 1132 | (defvar ps-height-remaining) | ||
| 1133 | (defvar ps-width-remaining) | ||
| 1134 | |||
| 1135 | (defvar ps-ref-bold-faces nil) | ||
| 1136 | (defvar ps-ref-italic-faces nil) | ||
| 1137 | (defvar ps-ref-underlined-faces nil) | ||
| 482 | 1138 | ||
| 483 | (if (fboundp 'add-hook) | 1139 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 484 | (add-hook 'kill-emacs-hook 'ps-kill-emacs-check) | 1140 | ;; Internal functions |
| 485 | (if kill-emacs-hook | 1141 | |
| 486 | (message "Won't override existing kill-emacs-hook.") | 1142 | (defun ps-get-page-dimensions () |
| 487 | (setq kill-emacs-hook 'ps-kill-emacs-check))) | 1143 | (setq ps-page-dimensions (assq ps-paper-type ps-pages-alist)) |
| 1144 | (let ((ps-page-width (nth ps-page-width-i ps-page-dimensions)) | ||
| 1145 | (ps-page-height (nth ps-page-height-i ps-page-dimensions))) | ||
| 1146 | (setq ps-print-height (- ps-page-height ps-top-margin ps-bottom-margin)) | ||
| 1147 | (setq ps-print-width (- ps-page-width ps-left-margin ps-right-margin)))) | ||
| 488 | 1148 | ||
| 489 | (defun ps-preprint (&optional filename) | 1149 | (defun ps-print-preprint (&optional filename) |
| 490 | (if (and filename | 1150 | (if (and filename |
| 491 | (or (numberp filename) | 1151 | (or (numberp filename) |
| 492 | (listp filename))) | 1152 | (listp filename))) |
| 493 | (setq filename | 1153 | (let* ((name (concat (buffer-name) ".ps")) |
| 494 | (let* ((name (concat (buffer-name) ".ps")) | 1154 | (prompt (format "Save PostScript to file: (default %s) " |
| 495 | (prompt (format "Save PostScript to file: (default %s) " | 1155 | name))) |
| 496 | name))) | 1156 | (read-file-name prompt default-directory |
| 497 | (read-file-name prompt default-directory | 1157 | name nil)))) |
| 498 | name nil))))) | 1158 | |
| 1159 | ;; The following functions implement a simple list-buffering scheme so | ||
| 1160 | ;; that ps-print doesn't have to repeatedly switch between buffers | ||
| 1161 | ;; while spooling. The functions ps-output and ps-output-string build | ||
| 1162 | ;; up the lists; the function ps-flush-output takes the lists and | ||
| 1163 | ;; insert its contents into the spool buffer (*PostScript*). | ||
| 1164 | |||
| 1165 | (defun ps-output-string-prim (string) | ||
| 1166 | (insert "(") ;insert start-string delimiter | ||
| 1167 | (save-excursion ;insert string | ||
| 1168 | (insert string)) | ||
| 1169 | |||
| 1170 | ;; Find and quote special characters as necessary for PS | ||
| 1171 | (while (re-search-forward "[()\\]" nil t) | ||
| 1172 | (save-excursion | ||
| 1173 | (forward-char -1) | ||
| 1174 | (insert "\\"))) | ||
| 499 | 1175 | ||
| 500 | (defvar ps-spool-buffer-name "*PostScript*") | 1176 | (goto-char (point-max)) |
| 1177 | (insert ")")) ;insert end-string delimiter | ||
| 501 | 1178 | ||
| 502 | (defvar ps-col 0) | 1179 | (defun ps-init-output-queue () |
| 503 | (defvar ps-row 0) | 1180 | (setq ps-output-head (list "")) |
| 504 | (defvar ps-xpos 0) | 1181 | (setq ps-output-tail ps-output-head)) |
| 505 | (defvar ps-ypos 0) | ||
| 506 | 1182 | ||
| 507 | (defvar ps-chars-per-line 80) | 1183 | (defun ps-output (&rest args) |
| 508 | (defvar ps-lines-per-page 66) | 1184 | (setcdr ps-output-tail args) |
| 1185 | (while (cdr ps-output-tail) | ||
| 1186 | (setq ps-output-tail (cdr ps-output-tail)))) | ||
| 509 | 1187 | ||
| 510 | (defvar ps-page-start-ypos 745) | 1188 | (defun ps-output-string (string) |
| 511 | (defvar ps-line-start-xpos 40) | 1189 | (ps-output t string)) |
| 512 | 1190 | ||
| 513 | (defvar ps-char-xpos-inc 6) | 1191 | (defun ps-flush-output () |
| 514 | (defvar ps-line-ypos-inc 11) | 1192 | (save-excursion |
| 1193 | (set-buffer ps-spool-buffer) | ||
| 1194 | (goto-char (point-max)) | ||
| 1195 | (while ps-output-head | ||
| 1196 | (let ((it (car ps-output-head))) | ||
| 1197 | (if (not (eq t it)) | ||
| 1198 | (insert it) | ||
| 1199 | (setq ps-output-head (cdr ps-output-head)) | ||
| 1200 | (ps-output-string-prim (car ps-output-head)))) | ||
| 1201 | (setq ps-output-head (cdr ps-output-head)))) | ||
| 1202 | (ps-init-output-queue)) | ||
| 1203 | |||
| 1204 | (defun ps-insert-file (fname) | ||
| 1205 | (ps-flush-output) | ||
| 1206 | |||
| 1207 | ;; Check to see that the file exists and is readable; if not, throw | ||
| 1208 | ;; and error. | ||
| 1209 | (if (not (file-readable-p fname)) | ||
| 1210 | (error "Could not read file `%s'" fname)) | ||
| 515 | 1211 | ||
| 516 | (defvar ps-current-font 0) | 1212 | (save-excursion |
| 1213 | (set-buffer ps-spool-buffer) | ||
| 1214 | (goto-char (point-max)) | ||
| 1215 | (insert-file fname))) | ||
| 1216 | |||
| 1217 | ;; These functions insert the arrays that define the contents of the | ||
| 1218 | ;; headers. | ||
| 517 | 1219 | ||
| 518 | (defvar ps-multiple nil) | 1220 | (defun ps-generate-header-line (fonttag &optional content) |
| 519 | (defvar ps-virtual-page-number 0) | 1221 | (ps-output " [ " fonttag " ") |
| 1222 | (cond | ||
| 1223 | ;; Literal strings should be output as is -- the string must | ||
| 1224 | ;; contain its own PS string delimiters, '(' and ')', if necessary. | ||
| 1225 | ((stringp content) | ||
| 1226 | (ps-output content)) | ||
| 1227 | |||
| 1228 | ;; Functions are called -- they should return strings; they will be | ||
| 1229 | ;; inserted as strings and the PS string delimiters added. | ||
| 1230 | ((and (symbolp content) (fboundp content)) | ||
| 1231 | (ps-output-string (funcall content))) | ||
| 1232 | |||
| 1233 | ;; Variables will have their contents inserted. They should | ||
| 1234 | ;; contain strings, and will be inserted as strings. | ||
| 1235 | ((and (symbolp content) (boundp content)) | ||
| 1236 | (ps-output-string (symbol-value content))) | ||
| 1237 | |||
| 1238 | ;; Anything else will get turned into an empty string. | ||
| 1239 | (t | ||
| 1240 | (ps-output-string ""))) | ||
| 1241 | (ps-output " ]\n")) | ||
| 1242 | |||
| 1243 | (defun ps-generate-header (name contents) | ||
| 1244 | (ps-output "/" name " [\n") | ||
| 1245 | (if (> ps-header-lines 0) | ||
| 1246 | (let ((count 1)) | ||
| 1247 | (ps-generate-header-line "/h0" (car contents)) | ||
| 1248 | (while (and (< count ps-header-lines) | ||
| 1249 | (setq contents (cdr contents))) | ||
| 1250 | (ps-generate-header-line "/h1" (car contents)) | ||
| 1251 | (setq count (+ count 1))) | ||
| 1252 | (ps-output "] def\n")))) | ||
| 1253 | |||
| 1254 | (defun ps-output-boolean (name bool) | ||
| 1255 | (ps-output (format "/%s %s def\n" name (if bool "true" "false")))) | ||
| 520 | 1256 | ||
| 521 | (defun ps-begin-file () | 1257 | (defun ps-begin-file () |
| 522 | (save-excursion | 1258 | (setq ps-showpage-count 0) |
| 523 | (set-buffer ps-output-buffer) | 1259 | |
| 524 | (goto-char (point-min)) | 1260 | (ps-output ps-adobe-tag) |
| 525 | (setq ps-real-page-number 1) | 1261 | (ps-output "%%Title: " (buffer-name) "\n") ;Take job name from name of |
| 526 | (insert | 1262 | ;first buffer printed |
| 527 | "%!PS-Adobe-1.0 | 1263 | (ps-output "%%Creator: " (user-full-name) "\n") |
| 528 | 1264 | (ps-output "%%CreationDate: " | |
| 529 | /S /show load def | 1265 | (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy) "\n") |
| 530 | /M /moveto load def | 1266 | (ps-output "%% DocumentFonts: Helvetica Helvetica-Bold " |
| 531 | /L { gsave newpath 3 1 roll 1 sub M 0 rlineto closepath stroke grestore } def | 1267 | ps-font " " ps-font-bold " " ps-font-italic " " |
| 532 | 1268 | ps-font-bold-italic "\n") | |
| 533 | /F{$fd exch get setfont}def | 1269 | (ps-output "%%Pages: (atend)\n") |
| 534 | 1270 | (ps-output "%%EndComments\n\n") | |
| 535 | /StartPage{/svpg save def}def | 1271 | |
| 536 | /EndPage{svpg restore showpage}def | 1272 | (ps-output-boolean "Duplex" ps-spool-duplex) |
| 537 | 1273 | (ps-output-boolean "PrintHeader" ps-print-header) | |
| 538 | /SetUpFonts | 1274 | (ps-output-boolean "PrintHeaderFrame" ps-print-header-frame) |
| 539 | {dup/$fd exch array def{findfont exch scalefont $fd 3 1 roll put}repeat}def | 1275 | (ps-output-boolean "ShowNofN" ps-show-n-of-n) |
| 540 | 1276 | ||
| 541 | % Define /ISOLatin1Encoding only if it's not already there. | 1277 | (ps-output (format "/LeftMargin %d def\n" ps-left-margin)) |
| 542 | /ISOLatin1Encoding where { pop save true }{ false } ifelse | 1278 | (ps-output (format "/RightMargin %d def\n" ps-right-margin)) |
| 543 | /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus | 1279 | (ps-output (format "/BottomMargin %d def\n" ps-bottom-margin)) |
| 544 | StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute | 1280 | (ps-output (format "/TopMargin %d def\n" ps-top-margin)) |
| 545 | /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring | 1281 | |
| 546 | /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown /cent | 1282 | (ps-get-page-dimensions) |
| 547 | /sterling /currency /yen /brokenbar /section /dieresis /copyright | 1283 | (ps-output (format "/PrintWidth %d def\n" ps-print-width)) |
| 548 | /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron | 1284 | (ps-output (format "/PrintHeight %d def\n" ps-print-height)) |
| 549 | /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph | 1285 | |
| 550 | /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright | 1286 | (ps-output ps-print-prologue) |
| 551 | /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute | 1287 | |
| 552 | /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute | 1288 | (ps-output (format "/f0 %d /%s Font\n" ps-font-size ps-font)) |
| 553 | /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth | 1289 | (ps-output (format "/f1 %d /%s Font\n" ps-font-size ps-font-bold)) |
| 554 | /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply | 1290 | (ps-output (format "/f2 %d /%s Font\n" ps-font-size ps-font-italic)) |
| 555 | /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn | 1291 | (ps-output (format "/f3 %d /%s Font\n" ps-font-size |
| 556 | /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae | 1292 | ps-font-bold-italic)) |
| 557 | /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute | 1293 | |
| 558 | /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex | 1294 | (ps-output "%%EndPrologue\n")) |
| 559 | /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex | ||
| 560 | /udieresis /yacute /thorn /ydieresis ] def | ||
| 561 | { restore } if | ||
| 562 | |||
| 563 | /reencodeISO { %def | ||
| 564 | findfont dup length dict begin | ||
| 565 | { 1 index /FID ne { def }{ pop pop } ifelse } forall | ||
| 566 | /Encoding ISOLatin1Encoding def | ||
| 567 | currentdict end definefont pop | ||
| 568 | } bind def | ||
| 569 | 1295 | ||
| 570 | /CourierISO /Courier reencodeISO | 1296 | (defun ps-header-dirpart () |
| 571 | /Courier-ObliqueISO /Courier-Oblique reencodeISO | 1297 | (let ((fname (buffer-file-name))) |
| 572 | /Courier-BoldISO /Courier-Bold reencodeISO | 1298 | (if fname |
| 573 | /Courier-BoldObliqueISO /Courier-BoldOblique reencodeISO | 1299 | (if (string-equal (buffer-name) (file-name-nondirectory fname)) |
| 1300 | (file-name-directory fname) | ||
| 1301 | fname) | ||
| 1302 | ""))) | ||
| 574 | 1303 | ||
| 575 | 3 10 /Courier-BoldObliqueISO | 1304 | (defun ps-get-buffer-name () |
| 576 | 2 10 /Courier-ObliqueISO | 1305 | ;; Indulge me this little easter egg: |
| 577 | 1 10 /Courier-BoldISO | 1306 | (if (string= (buffer-name) "ps-print.el") |
| 578 | 0 10 /CourierISO | 1307 | "Hey, Cool! It's ps-print.el!!!" |
| 579 | 4 SetUpFonts | 1308 | (buffer-name))) |
| 580 | 1309 | ||
| 581 | .4 setlinewidth | 1310 | (defun ps-begin-job () |
| 582 | "))) | 1311 | (setq ps-page-count 0)) |
| 583 | 1312 | ||
| 584 | (defun ps-end-file () | 1313 | (defun ps-end-file () |
| 585 | ) | 1314 | (ps-output "%%Trailer\n") |
| 1315 | (ps-output "%%Pages: " (format "%d\n" ps-showpage-count))) | ||
| 586 | 1316 | ||
| 587 | (defun ps-next-page () | 1317 | (defun ps-next-page () |
| 588 | (ps-end-page) | 1318 | (ps-end-page) |
| 589 | (ps-begin-page) | 1319 | (ps-flush-output) |
| 1320 | (ps-begin-page)) | ||
| 1321 | |||
| 1322 | (defun ps-begin-page (&optional dummypage) | ||
| 1323 | (ps-get-page-dimensions) | ||
| 1324 | (setq ps-width-remaining ps-print-width) | ||
| 1325 | (setq ps-height-remaining ps-print-height) | ||
| 1326 | |||
| 1327 | ;; If headers are turned on, deduct the height of the header from | ||
| 1328 | ;; the print height remaining. Clumsy clumsy clumsy. | ||
| 1329 | (if ps-print-header | ||
| 1330 | (setq ps-height-remaining | ||
| 1331 | (- ps-height-remaining | ||
| 1332 | ps-header-title-line-height | ||
| 1333 | (* ps-header-line-height (- ps-header-lines 1)) | ||
| 1334 | (* 2 ps-header-pad)))) | ||
| 1335 | |||
| 1336 | (setq ps-page-count (+ ps-page-count 1)) | ||
| 1337 | |||
| 1338 | (ps-output "\n%%Page: " | ||
| 1339 | (format "%d %d\n" ps-page-count (+ 1 ps-showpage-count))) | ||
| 1340 | (ps-output "BeginDSCPage\n") | ||
| 1341 | (ps-output (format "/PageNumber %d def\n" ps-page-count)) | ||
| 1342 | (ps-output "/PageCount 0 def\n") | ||
| 1343 | |||
| 1344 | (if ps-print-header | ||
| 1345 | (progn | ||
| 1346 | (ps-generate-header "HeaderLinesLeft" ps-left-header) | ||
| 1347 | (ps-generate-header "HeaderLinesRight" ps-right-header) | ||
| 1348 | (ps-output (format "%d SetHeaderLines\n" ps-header-lines)))) | ||
| 1349 | |||
| 1350 | (ps-output "BeginPage\n") | ||
| 590 | (ps-set-font ps-current-font) | 1351 | (ps-set-font ps-current-font) |
| 591 | (ps-init-page)) | 1352 | (ps-set-bg ps-current-bg) |
| 592 | 1353 | (ps-set-color ps-current-color) | |
| 593 | (defun ps-top-of-page () (ps-next-page)) | 1354 | (ps-set-underline ps-current-underline-p)) |
| 594 | |||
| 595 | (defun ps-init-page () | ||
| 596 | (setq ps-row 0) | ||
| 597 | (setq ps-col 0) | ||
| 598 | (setq ps-ypos ps-page-start-ypos) | ||
| 599 | (setq ps-xpos ps-line-start-xpos) | ||
| 600 | (ps-set-font)) | ||
| 601 | |||
| 602 | (defun ps-begin-page () | ||
| 603 | (save-excursion | ||
| 604 | (set-buffer ps-output-buffer) | ||
| 605 | (goto-char (point-max)) | ||
| 606 | (insert (format "%%%%Page: ? %d\n" ps-real-page-number)) | ||
| 607 | (setq ps-real-page-number (+ 1 ps-real-page-number)) | ||
| 608 | (insert "StartPage\n0.4 setlinewidth\n"))) | ||
| 609 | 1355 | ||
| 610 | (defun ps-end-page () | 1356 | (defun ps-end-page () |
| 611 | (save-excursion | 1357 | (setq ps-showpage-count (+ 1 ps-showpage-count)) |
| 612 | (set-buffer ps-output-buffer) | 1358 | (ps-output "EndPage\n") |
| 613 | (goto-char (point-max)) | 1359 | (ps-output "EndDSCPage\n")) |
| 614 | (insert "EndPage\n"))) | 1360 | |
| 615 | 1361 | (defun ps-dummy-page () | |
| 1362 | (setq ps-showpage-count (+ 1 ps-showpage-count)) | ||
| 1363 | (ps-output "%%Page: " (format "- %d\n" ps-showpage-count) | ||
| 1364 | "BeginDSCPage | ||
| 1365 | /PrintHeader false def | ||
| 1366 | BeginPage | ||
| 1367 | EndPage | ||
| 1368 | EndDSCPage\n")) | ||
| 1369 | |||
| 616 | (defun ps-next-line () | 1370 | (defun ps-next-line () |
| 617 | (setq ps-row (+ ps-row 1)) | 1371 | (if (< ps-height-remaining ps-line-height) |
| 618 | (if (>= ps-row ps-lines-per-page) | ||
| 619 | (ps-next-page) | 1372 | (ps-next-page) |
| 620 | (setq ps-col 0) | 1373 | (setq ps-width-remaining ps-print-width) |
| 621 | (setq ps-xpos ps-line-start-xpos) | 1374 | (setq ps-height-remaining (- ps-height-remaining ps-line-height)) |
| 622 | (setq ps-ypos (- ps-ypos ps-line-ypos-inc)))) | 1375 | (ps-hard-lf))) |
| 623 | 1376 | ||
| 624 | (defun ps-continue-line () | 1377 | (defun ps-continue-line () |
| 625 | (ps-next-line)) | 1378 | (if (< ps-height-remaining ps-line-height) |
| 626 | 1379 | (ps-next-page) | |
| 627 | (defvar ps-source-buffer nil) | 1380 | (setq ps-width-remaining ps-print-width) |
| 628 | (defvar ps-output-buffer nil) | 1381 | (setq ps-height-remaining (- ps-height-remaining ps-line-height)) |
| 629 | 1382 | (ps-soft-lf))) | |
| 630 | (defun ps-basic-plot-string (from to &optional underline-p) | 1383 | |
| 631 | (setq text (buffer-substring from to)) | 1384 | (defun ps-hard-lf () |
| 632 | (save-excursion | 1385 | (ps-output "HL\n")) |
| 633 | (set-buffer ps-output-buffer) | 1386 | |
| 634 | (goto-char (point-max)) | 1387 | (defun ps-soft-lf () |
| 635 | (setq count (- to from)) | 1388 | (ps-output "SL\n")) |
| 636 | 1389 | ||
| 637 | (if underline-p | 1390 | (defun ps-find-wrappoint (from to char-width) |
| 638 | (insert (format "%d %d %d L\n" ps-xpos ps-ypos | 1391 | (let ((avail (truncate (/ ps-width-remaining char-width))) |
| 639 | (* count ps-char-xpos-inc)))) | 1392 | (todo (- to from))) |
| 640 | 1393 | (if (< todo avail) | |
| 641 | (insert (format "%d %d M (" ps-xpos ps-ypos)) | 1394 | (cons to (* todo char-width)) |
| 642 | (save-excursion | 1395 | (cons (+ from avail) ps-width-remaining)))) |
| 643 | (insert text)) | 1396 | |
| 644 | 1397 | (defun ps-basic-plot-string (from to &optional bg-color) | |
| 645 | (while (re-search-forward "[()\\]" nil t) | 1398 | (let* ((wrappoint (ps-find-wrappoint from to ps-avg-char-width)) |
| 646 | (save-excursion | 1399 | (to (car wrappoint)) |
| 647 | (forward-char -1) | 1400 | (string (buffer-substring from to))) |
| 648 | (insert "\\"))) | 1401 | (ps-output-string string) |
| 649 | 1402 | (ps-output " S\n") ; | |
| 650 | (end-of-line) | 1403 | wrappoint)) |
| 651 | (insert ") S\n") | 1404 | |
| 652 | 1405 | (defun ps-basic-plot-whitespace (from to &optional bg-color) | |
| 653 | (setq ps-xpos (+ ps-xpos (* count ps-char-xpos-inc))))) | 1406 | (let* ((wrappoint (ps-find-wrappoint from to ps-space-width)) |
| 654 | 1407 | (to (car wrappoint))) | |
| 655 | (defun ps-basic-plot-whitespace (from to underline-p) | 1408 | |
| 656 | (setq count (- to from)) | 1409 | (ps-output (format "%d W\n" (- to from))) |
| 657 | (setq ps-xpos (+ ps-xpos (* count ps-char-xpos-inc)))) | 1410 | wrappoint)) |
| 658 | 1411 | ||
| 659 | (defun ps-plot (plotfunc from to &optional underline-p) | 1412 | (defun ps-plot (plotfunc from to &optional bg-color) |
| 660 | |||
| 661 | (while (< from to) | 1413 | (while (< from to) |
| 662 | (setq count (- to from)) | 1414 | (let* ((wrappoint (funcall plotfunc from to bg-color)) |
| 663 | ;; Test to see whether this region will fit on the current line | 1415 | (plotted-to (car wrappoint)) |
| 664 | (if (<= (+ ps-col count) ps-chars-per-line) | 1416 | (plotted-width (cdr wrappoint))) |
| 665 | (progn | 1417 | (setq from plotted-to) |
| 666 | ;; It fits; plot it. | 1418 | (setq ps-width-remaining (- ps-width-remaining plotted-width)) |
| 667 | (funcall plotfunc from to underline-p) | 1419 | (if (< from to) |
| 668 | (setq from to)) | 1420 | (ps-continue-line)))) |
| 669 | |||
| 670 | ;; It needs to be wrapped; plot part of it, then loop | ||
| 671 | (setq chars-that-will-fit (- ps-chars-per-line ps-col)) | ||
| 672 | (funcall plotfunc from (+ from chars-that-will-fit)) | ||
| 673 | |||
| 674 | (ps-continue-line) | ||
| 675 | |||
| 676 | (setq from (+ from chars-that-will-fit)))) | ||
| 677 | |||
| 678 | (if ps-razzle-dazzle | 1421 | (if ps-razzle-dazzle |
| 679 | (let* ((q-todo (- (point-max) (point-min))) | 1422 | (let* ((q-todo (- (point-max) (point-min))) |
| 680 | (q-done (- to (point-min))) | 1423 | (q-done (- (point) (point-min))) |
| 681 | (chunkfrac (/ q-todo 8)) | 1424 | (chunkfrac (/ q-todo 8)) |
| 682 | (chunksize (if (> chunkfrac 10000) 10000 chunkfrac))) | 1425 | (chunksize (if (> chunkfrac 1000) 1000 chunkfrac))) |
| 683 | (if (> (- q-done ps-razchunk) chunksize) | 1426 | (if (> (- q-done ps-razchunk) chunksize) |
| 684 | (progn | 1427 | (progn |
| 685 | (setq ps-razchunk q-done) | 1428 | (setq ps-razchunk q-done) |
| 686 | (setq foo | 1429 | (setq foo |
| 687 | (if (< q-todo 100) | 1430 | (if (< q-todo 100) |
| 688 | (* (/ q-done q-todo) 100) | 1431 | (/ (* 100 q-done) q-todo) |
| 689 | (setq basis (/ q-todo 100)) | 1432 | (/ q-done (/ q-todo 100)))) |
| 690 | (/ q-done basis))) | 1433 | (message "Formatting...%d%%" foo)))))) |
| 691 | 1434 | ||
| 692 | (message "Formatting... %d%%" foo)))))) | 1435 | (defun ps-set-font (font) |
| 693 | 1436 | (setq ps-current-font font) | |
| 694 | (defun ps-set-font (&optional font) | 1437 | (ps-output (format "/f%d F\n" ps-current-font))) |
| 695 | (save-excursion | 1438 | |
| 696 | (set-buffer ps-output-buffer) | 1439 | (defvar ps-print-color-scale (if ps-print-color-p |
| 697 | (goto-char (point-max)) | 1440 | (float (car (x-color-values "white"))) |
| 698 | (insert (format "%d F\n" (if font font ps-current-font)))) | 1441 | 1.0)) |
| 699 | (if font | 1442 | |
| 700 | (setq ps-current-font font))) | 1443 | (defun ps-set-bg (color) |
| 701 | 1444 | (if (setq ps-current-bg color) | |
| 702 | (defun ps-plot-region (from to font &optional underline-p) | 1445 | (ps-output (format ps-color-format (nth 0 color) (nth 1 color) |
| 703 | 1446 | (nth 2 color)) | |
| 704 | (ps-set-font font) | 1447 | " true BG\n") |
| 1448 | (ps-output "false BG\n"))) | ||
| 1449 | |||
| 1450 | (defun ps-set-color (color) | ||
| 1451 | (if (setq ps-current-color color) | ||
| 1452 | (ps-output (format ps-color-format (nth 0 ps-current-color) | ||
| 1453 | (nth 1 ps-current-color) (nth 2 ps-current-color)) | ||
| 1454 | " FG\n"))) | ||
| 1455 | |||
| 1456 | (defun ps-set-underline (underline-p) | ||
| 1457 | (ps-output (if underline-p "true" "false") " UL\n") | ||
| 1458 | (setq ps-current-underline-p underline-p)) | ||
| 1459 | |||
| 1460 | (defun ps-plot-region (from to font fg-color &optional bg-color underline-p) | ||
| 1461 | |||
| 1462 | (if (not (equal font ps-current-font)) | ||
| 1463 | (ps-set-font font)) | ||
| 1464 | |||
| 1465 | ;; Specify a foreground color only if one's specified and it's | ||
| 1466 | ;; different than the current. | ||
| 1467 | (if (not (equal fg-color ps-current-color)) | ||
| 1468 | (ps-set-color fg-color)) | ||
| 1469 | |||
| 1470 | (if (not (equal bg-color ps-current-bg)) | ||
| 1471 | (ps-set-bg bg-color)) | ||
| 1472 | |||
| 1473 | ;; Toggle underlining if different. | ||
| 1474 | (if (not (equal underline-p ps-current-underline-p)) | ||
| 1475 | (ps-set-underline underline-p)) | ||
| 705 | 1476 | ||
| 1477 | ;; Starting at the beginning of the specified region... | ||
| 706 | (save-excursion | 1478 | (save-excursion |
| 707 | (goto-char from) | 1479 | (goto-char from) |
| 1480 | |||
| 1481 | ;; ...break the region up into chunks separated by tabs, linefeeds, | ||
| 1482 | ;; and pagefeeds, and plot each chunk. | ||
| 708 | (while (< from to) | 1483 | (while (< from to) |
| 709 | (if (re-search-forward "[\t\n\014]" to t) | 1484 | (if (re-search-forward "[\t\n\f]" to t) |
| 710 | (let ((match (char-after (match-beginning 0)))) | 1485 | (let ((match (char-after (match-beginning 0)))) |
| 711 | (cond | 1486 | (cond |
| 712 | ((= match ?\n) | 1487 | ((= match ?\t) |
| 713 | (ps-plot 'ps-basic-plot-string from (- (point) 1) underline-p) | 1488 | (let ((linestart |
| 714 | (ps-next-line)) | 1489 | (save-excursion (beginning-of-line) (point)))) |
| 715 | 1490 | (ps-plot 'ps-basic-plot-string from (- (point) 1) | |
| 716 | ((= match ?\t) | 1491 | bg-color) |
| 717 | (ps-plot 'ps-basic-plot-string from (- (point) 1) underline-p) | 1492 | (forward-char -1) |
| 718 | (setq linestart (save-excursion (beginning-of-line) (point))) | 1493 | (setq from (+ linestart (current-column))) |
| 719 | (forward-char -1) | 1494 | (if (re-search-forward "[ \t]+" to t) |
| 720 | (setq from (+ linestart (current-column))) | 1495 | (ps-plot 'ps-basic-plot-whitespace |
| 721 | (if (re-search-forward "[ \t]+" to t) | 1496 | from (+ linestart (current-column)) |
| 722 | (ps-plot 'ps-basic-plot-whitespace from | 1497 | bg-color)))) |
| 723 | (+ linestart (current-column))))) | 1498 | |
| 724 | 1499 | ((= match ?\n) | |
| 725 | ((= match ?\014) | 1500 | (ps-plot 'ps-basic-plot-string from (- (point) 1) |
| 726 | (ps-plot 'ps-basic-plot-string from (- (point) 1) underline-p) | 1501 | bg-color) |
| 727 | (ps-top-of-page))) | 1502 | (ps-next-line) |
| 1503 | ) | ||
| 1504 | |||
| 1505 | ((= match ?\f) | ||
| 1506 | (ps-plot 'ps-basic-plot-string from (- (point) 1) | ||
| 1507 | bg-color) | ||
| 1508 | (ps-next-page))) | ||
| 728 | (setq from (point))) | 1509 | (setq from (point))) |
| 729 | 1510 | (ps-plot 'ps-basic-plot-string from to bg-color) | |
| 730 | (ps-plot 'ps-basic-plot-string from to underline-p) | ||
| 731 | (setq from to))))) | 1511 | (setq from to))))) |
| 732 | 1512 | ||
| 733 | (defun ps-format-buffer () | 1513 | (defun ps-color-value (x-color-value) |
| 734 | (interactive) | 1514 | ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval. |
| 735 | 1515 | (/ x-color-value ps-print-color-scale)) | |
| 736 | (setq ps-source-buffer (current-buffer)) | ||
| 737 | (setq ps-output-buffer (get-buffer-create "%PostScript%")) | ||
| 738 | |||
| 739 | (save-excursion | ||
| 740 | (set-buffer ps-output-buffer) | ||
| 741 | (delete-region (point-max) (point-min))) | ||
| 742 | 1516 | ||
| 743 | (ps-begin-file) | 1517 | (defun ps-plot-with-face (from to face) |
| 744 | (ps-begin-page) | 1518 | (if face |
| 745 | (ps-init-page) | 1519 | (let* ((bold-p (memq face ps-ref-bold-faces)) |
| 746 | 1520 | (italic-p (memq face ps-ref-italic-faces)) | |
| 747 | (ps-plot-region (point-min) (point-max) 0) | 1521 | (underline-p (memq face ps-ref-underlined-faces)) |
| 748 | 1522 | (foreground (face-foreground face)) | |
| 749 | (ps-end-page) | 1523 | (background (face-background face)) |
| 750 | (ps-end-file) | 1524 | (fg-color (if (and ps-print-color-p foreground) |
| 751 | ) | 1525 | (mapcar 'ps-color-value |
| 1526 | (x-color-values foreground)) | ||
| 1527 | ps-default-color)) | ||
| 1528 | (bg-color (if (and ps-print-color-p background) | ||
| 1529 | (mapcar 'ps-color-value | ||
| 1530 | (x-color-values background))))) | ||
| 1531 | (ps-plot-region from to | ||
| 1532 | (cond ((and bold-p italic-p) 3) | ||
| 1533 | (italic-p 2) | ||
| 1534 | (bold-p 1) | ||
| 1535 | (t 0)) | ||
| 1536 | ; (or fg-color '(0.0 0.0 0.0)) | ||
| 1537 | fg-color | ||
| 1538 | bg-color underline-p)) | ||
| 1539 | (goto-char to))) | ||
| 1540 | |||
| 1541 | |||
| 1542 | (defun ps-fsf-face-kind-p (face kind kind-regex kind-list) | ||
| 1543 | (let ((frame-font (face-font face)) | ||
| 1544 | (face-defaults (face-font face t))) | ||
| 1545 | (or | ||
| 1546 | ;; Check FACE defaults: | ||
| 1547 | (and (listp face-defaults) | ||
| 1548 | (memq kind face-defaults)) | ||
| 1549 | |||
| 1550 | ;; Check the user's preferences | ||
| 1551 | (memq face kind-list)))) | ||
| 1552 | |||
| 1553 | (defun ps-xemacs-face-kind-p (face kind kind-regex kind-list) | ||
| 1554 | (let* ((frame-font (or (face-font face) (face-font 'default))) | ||
| 1555 | (kind-cons (assq kind (x-font-properties frame-font))) | ||
| 1556 | (kind-spec (cdr-safe kind-cons)) | ||
| 1557 | (case-fold-search t)) | ||
| 1558 | |||
| 1559 | (or (and kind-spec (string-match kind-regex kind-spec)) | ||
| 1560 | ;; Kludge-compatible: | ||
| 1561 | (memq face kind-list)))) | ||
| 1562 | |||
| 1563 | (defun ps-face-bold-p (face) | ||
| 1564 | (if (eq emacs-type 'fsf) | ||
| 1565 | (ps-fsf-face-kind-p face 'bold "-\\(bold\\|demibold\\)-" | ||
| 1566 | ps-bold-faces) | ||
| 1567 | (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold" | ||
| 1568 | ps-bold-faces))) | ||
| 1569 | |||
| 1570 | (defun ps-face-italic-p (face) | ||
| 1571 | (if (eq emacs-type 'fsf) | ||
| 1572 | (ps-fsf-face-kind-p face 'italic "-[io]-" ps-italic-faces) | ||
| 1573 | (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o" ps-italic-faces))) | ||
| 1574 | |||
| 1575 | (defun ps-face-underlined-p (face) | ||
| 1576 | (or (face-underline-p face) | ||
| 1577 | (memq face ps-underlined-faces))) | ||
| 1578 | |||
| 1579 | (defun ps-faces-list () | ||
| 1580 | (if (or (eq emacs-type 'lucid) (eq emacs-type 'xemacs)) | ||
| 1581 | (list-faces) | ||
| 1582 | (face-list))) | ||
| 1583 | |||
| 1584 | (defun ps-build-reference-face-lists () | ||
| 1585 | (if ps-auto-font-detect | ||
| 1586 | (let ((faces (ps-faces-list)) | ||
| 1587 | the-face) | ||
| 1588 | (setq ps-ref-bold-faces nil | ||
| 1589 | ps-ref-italic-faces nil | ||
| 1590 | ps-ref-underlined-faces nil) | ||
| 1591 | (while faces | ||
| 1592 | (setq the-face (car faces)) | ||
| 1593 | (if (ps-face-italic-p the-face) | ||
| 1594 | (setq ps-ref-italic-faces | ||
| 1595 | (cons the-face ps-ref-italic-faces))) | ||
| 1596 | (if (ps-face-bold-p the-face) | ||
| 1597 | (setq ps-ref-bold-faces | ||
| 1598 | (cons the-face ps-ref-bold-faces))) | ||
| 1599 | (if (ps-face-underlined-p the-face) | ||
| 1600 | (setq ps-ref-underlined-faces | ||
| 1601 | (cons the-face ps-ref-underlined-faces))) | ||
| 1602 | (setq faces (cdr faces)))) | ||
| 1603 | (setq ps-ref-bold-faces ps-bold-faces) | ||
| 1604 | (setq ps-ref-italic-faces ps-italic-faces) | ||
| 1605 | (setq ps-ref-underlined-faces ps-underlined-faces)) | ||
| 1606 | (setq ps-build-face-reference nil)) | ||
| 752 | 1607 | ||
| 753 | (defun ps-mapper (extent list) | 1608 | (defun ps-mapper (extent list) |
| 754 | (nconc list (list (list (extent-start-position extent) 'push extent) | 1609 | (nconc list (list (list (extent-start-position extent) 'push extent) |
| @@ -757,42 +1612,21 @@ number, prompt the user for the name of the file to save in." | |||
| 757 | 1612 | ||
| 758 | (defun ps-sorter (a b) | 1613 | (defun ps-sorter (a b) |
| 759 | (< (car a) (car b))) | 1614 | (< (car a) (car b))) |
| 760 | 1615 | ||
| 761 | (defun ps-extent-sorter (a b) | ||
| 762 | (< (extent-priority a) (extent-priority b))) | ||
| 763 | |||
| 764 | (defun overlay-priority (p) | ||
| 765 | (if (setq priority (overlay-get p 'priority)) priority 0)) | ||
| 766 | |||
| 767 | (defun ps-overlay-sorter (a b) | ||
| 768 | (> (overlay-priority a) (overlay-priority b))) | ||
| 769 | |||
| 770 | (defun ps-plot-with-face (from to face) | ||
| 771 | |||
| 772 | (setq bold-p (memq face ps-bold-faces)) | ||
| 773 | (setq italic-p (memq face ps-italic-faces)) | ||
| 774 | (setq underline-p (memq face ps-underline-faces)) | ||
| 775 | |||
| 776 | (cond | ||
| 777 | ((and bold-p italic-p) | ||
| 778 | (ps-plot-region from to 3 underline-p)) | ||
| 779 | (italic-p | ||
| 780 | (ps-plot-region from to 2 underline-p)) | ||
| 781 | (bold-p | ||
| 782 | (ps-plot-region from to 1 underline-p)) | ||
| 783 | (t | ||
| 784 | (ps-plot-region from to 0 underline-p)))) | ||
| 785 | |||
| 786 | |||
| 787 | (defun ps-generate-postscript-with-faces (from to) | 1616 | (defun ps-generate-postscript-with-faces (from to) |
| 788 | 1617 | (if (or ps-always-build-face-reference | |
| 1618 | ps-build-face-reference) | ||
| 1619 | (progn | ||
| 1620 | (message "Collecting face information...") | ||
| 1621 | (ps-build-reference-face-lists))) | ||
| 789 | (save-restriction | 1622 | (save-restriction |
| 790 | (narrow-to-region from to) | 1623 | (narrow-to-region from to) |
| 791 | (setq face 'default) | 1624 | (let ((face 'default) |
| 792 | 1625 | (position to)) | |
| 793 | (cond ((string-match "Lucid" emacs-version) | 1626 | (cond ((or (eq emacs-type 'lucid) (eq emacs-type 'xemacs)) |
| 794 | ;; Build the list of extents... | 1627 | ;; Build the list of extents... |
| 795 | (let ((a (cons 'dummy nil))) | 1628 | (let ((a (cons 'dummy nil)) |
| 1629 | record type extent extent-list) | ||
| 796 | (map-extents 'ps-mapper nil from to a) | 1630 | (map-extents 'ps-mapper nil from to a) |
| 797 | (setq a (cdr a)) | 1631 | (setq a (cdr a)) |
| 798 | (setq a (sort a 'ps-sorter)) | 1632 | (setq a (sort a 'ps-sorter)) |
| @@ -831,132 +1665,278 @@ number, prompt the user for the name of the file to save in." | |||
| 831 | (setq from position) | 1665 | (setq from position) |
| 832 | (setq a (cdr a))))) | 1666 | (setq a (cdr a))))) |
| 833 | 1667 | ||
| 834 | ((string-match "^19" emacs-version) | 1668 | ((eq emacs-type 'fsf) |
| 835 | 1669 | (let ((property-change from) | |
| 836 | (while (< from to) | 1670 | (overlay-change from)) |
| 837 | 1671 | (while (< from to) | |
| 838 | (setq prop-position | 1672 | (if (< property-change to) ; Don't search for property change |
| 839 | (if (setq p (next-property-change from)) | 1673 | ; unless previous search succeeded. |
| 840 | (if (> p to) to p) | 1674 | (setq property-change |
| 841 | to)) | 1675 | (next-property-change from nil to))) |
| 842 | 1676 | (if (< overlay-change to) ; Don't search for overlay change | |
| 843 | (setq over-position | 1677 | ; unless previous search succeeded. |
| 844 | (if (setq p (next-overlay-change from)) | 1678 | (setq overlay-change |
| 845 | (if (> p to) to p) | 1679 | (min (next-overlay-change from) to))) |
| 846 | to)) | 1680 | (setq position |
| 847 | 1681 | (min property-change overlay-change)) | |
| 848 | (setq position | 1682 | (setq face |
| 849 | (if (< prop-position over-position) | 1683 | (cond ((get-text-property from 'invisible) nil) |
| 850 | prop-position | 1684 | ((get-text-property from 'face)) |
| 851 | over-position)) | 1685 | (t 'default))) |
| 852 | 1686 | (let ((overlays (overlays-at from)) | |
| 853 | (setq face | 1687 | (face-priority -1)) ; text-property |
| 854 | (if (setq f (get-text-property from 'face)) f 'default)) | ||
| 855 | |||
| 856 | (if (setq overlays (overlays-at from)) | ||
| 857 | (progn | ||
| 858 | (setq overlays (sort overlays 'ps-overlay-sorter)) | ||
| 859 | (while overlays | 1688 | (while overlays |
| 860 | (if (setq face (overlay-get (car overlays) 'face)) | 1689 | (let* ((overlay (car overlays)) |
| 861 | (setq overlays nil) | 1690 | (overlay-face (overlay-get overlay 'face)) |
| 862 | (setq overlays (cdr overlays)))))) | 1691 | (overlay-invisible (overlay-get overlay 'invisible)) |
| 863 | 1692 | (overlay-priority (or (overlay-get overlay | |
| 864 | ;; Plot up to this record. | 1693 | 'priority) |
| 865 | (ps-plot-with-face from position face) | 1694 | 0))) |
| 866 | 1695 | (if (and (or overlay-invisible overlay-face) | |
| 867 | (setq from position)))) | 1696 | (> overlay-priority face-priority)) |
| 868 | 1697 | (setq face (cond (overlay-invisible nil) | |
| 869 | (ps-plot-with-face from to face))) | 1698 | ((and face overlay-face))) |
| 1699 | face-priority overlay-priority))) | ||
| 1700 | (setq overlays (cdr overlays)))) | ||
| 1701 | ;; Plot up to this record. | ||
| 1702 | (ps-plot-with-face from position face) | ||
| 1703 | (setq from position))))) | ||
| 1704 | (ps-plot-with-face from to face)))) | ||
| 870 | 1705 | ||
| 871 | (defun ps-generate-postscript (from to) | 1706 | (defun ps-generate-postscript (from to) |
| 872 | (ps-plot-region from to 0)) | 1707 | (ps-plot-region from to 0 nil)) |
| 873 | 1708 | ||
| 874 | (defun ps-generate (buffer from to genfunc) | 1709 | (defun ps-generate (buffer from to genfunc) |
| 875 | |||
| 876 | (save-restriction | 1710 | (save-restriction |
| 877 | (narrow-to-region from to) | 1711 | (narrow-to-region from to) |
| 878 | (if ps-razzle-dazzle | 1712 | (if ps-razzle-dazzle |
| 879 | (message "Formatting... %d%%" (setq ps-razchunk 0))) | 1713 | (message "Formatting...%d%%" (setq ps-razchunk 0))) |
| 880 | |||
| 881 | (set-buffer buffer) | 1714 | (set-buffer buffer) |
| 882 | (setq ps-source-buffer buffer) | 1715 | (setq ps-source-buffer buffer) |
| 883 | (setq ps-output-buffer (get-buffer-create ps-spool-buffer-name)) | 1716 | (setq ps-spool-buffer (get-buffer-create ps-spool-buffer-name)) |
| 884 | 1717 | (ps-init-output-queue) | |
| 885 | (unwind-protect | 1718 | (let (safe-marker completed-safely needs-begin-file) |
| 886 | (progn | 1719 | (unwind-protect |
| 887 | 1720 | (progn | |
| 888 | (set-buffer ps-output-buffer) | 1721 | (set-buffer ps-spool-buffer) |
| 889 | (goto-char (point-min)) | ||
| 890 | (if (looking-at (regexp-quote "%!PS-Adobe-1.0")) | ||
| 891 | (ps-set-font ps-current-font) | ||
| 892 | (ps-begin-file)) | ||
| 893 | (ps-begin-page) | ||
| 894 | (ps-init-page) | ||
| 895 | |||
| 896 | (goto-char (point-max)) | ||
| 897 | (if (and ps-spool-duplex | ||
| 898 | (re-search-backward "^%%Page") | ||
| 899 | (looking-at "^%%Page.*[24680]$")) | ||
| 900 | (ps-next-page)) | ||
| 901 | 1722 | ||
| 902 | (set-buffer ps-source-buffer) | 1723 | ;; Get a marker and make it point to the current end of the |
| 903 | (funcall genfunc from to) | 1724 | ;; buffer, If an error occurs, we'll delete everything from |
| 904 | 1725 | ;; the end of this marker onwards. | |
| 905 | (ps-end-page))) | 1726 | (setq safe-marker (make-marker)) |
| 1727 | (set-marker safe-marker (point-max)) | ||
| 1728 | |||
| 1729 | (goto-char (point-min)) | ||
| 1730 | (if (looking-at (regexp-quote "%!PS-Adobe-1.0")) | ||
| 1731 | nil | ||
| 1732 | (setq needs-begin-file t)) | ||
| 1733 | (save-excursion | ||
| 1734 | (set-buffer ps-source-buffer) | ||
| 1735 | (if needs-begin-file (ps-begin-file)) | ||
| 1736 | (ps-begin-job) | ||
| 1737 | (ps-begin-page)) | ||
| 1738 | (set-buffer ps-source-buffer) | ||
| 1739 | (funcall genfunc from to) | ||
| 1740 | (ps-end-page) | ||
| 1741 | |||
| 1742 | (if (and ps-spool-duplex | ||
| 1743 | (= (mod ps-page-count 2) 1)) | ||
| 1744 | (ps-dummy-page)) | ||
| 1745 | (ps-flush-output) | ||
| 1746 | |||
| 1747 | ;; Back to the PS output buffer to set the page count | ||
| 1748 | (set-buffer ps-spool-buffer) | ||
| 1749 | (goto-char (point-max)) | ||
| 1750 | (while (re-search-backward "^/PageCount 0 def$" nil t) | ||
| 1751 | (replace-match (format "/PageCount %d def" ps-page-count) t)) | ||
| 1752 | |||
| 1753 | ;; Setting this variable tells the unwind form that the | ||
| 1754 | ;; the postscript was generated without error. | ||
| 1755 | (setq completed-safely t)) | ||
| 1756 | |||
| 1757 | ;; Unwind form: If some bad mojo ocurred while generating | ||
| 1758 | ;; postscript, delete all the postscript that was generated. | ||
| 1759 | ;; This protects the previously spooled files from getting | ||
| 1760 | ;; corrupted. | ||
| 1761 | (if (and (markerp safe-marker) (not completed-safely)) | ||
| 1762 | (progn | ||
| 1763 | (set-buffer ps-spool-buffer) | ||
| 1764 | (delete-region (marker-position safe-marker) (point-max)))))) | ||
| 906 | 1765 | ||
| 907 | (if ps-razzle-dazzle | 1766 | (if ps-razzle-dazzle |
| 908 | (message "Formatting... Done.")))) | 1767 | (message "Formatting...done")))) |
| 909 | 1768 | ||
| 910 | (defun ps-do-despool (filename) | 1769 | (defun ps-do-despool (filename) |
| 911 | 1770 | (if (or (not (boundp 'ps-spool-buffer)) | |
| 912 | (if (or (not (boundp 'ps-output-buffer)) | 1771 | (not ps-spool-buffer)) |
| 913 | (not ps-output-buffer)) | 1772 | (message "No spooled PostScript to print") |
| 914 | (message "No spooled PostScript to print.") | ||
| 915 | |||
| 916 | (ps-end-file) | 1773 | (ps-end-file) |
| 917 | 1774 | (ps-flush-output) | |
| 918 | (if filename | 1775 | (if filename |
| 919 | (save-excursion | 1776 | (save-excursion |
| 920 | (if ps-razzle-dazzle | 1777 | (if ps-razzle-dazzle |
| 921 | (message "Saving...")) | 1778 | (message "Saving...")) |
| 922 | 1779 | (set-buffer ps-spool-buffer) | |
| 923 | (set-buffer ps-output-buffer) | ||
| 924 | (setq filename (expand-file-name filename)) | 1780 | (setq filename (expand-file-name filename)) |
| 925 | (write-region (point-min) (point-max) filename) | 1781 | (write-region (point-min) (point-max) filename) |
| 926 | |||
| 927 | (if ps-razzle-dazzle | 1782 | (if ps-razzle-dazzle |
| 928 | (message "Wrote %s" filename))) | 1783 | (message "Wrote %s" filename))) |
| 929 | |||
| 930 | ;; Else, spool to the printer | 1784 | ;; Else, spool to the printer |
| 931 | (if ps-razzle-dazzle | 1785 | (if ps-razzle-dazzle |
| 932 | (message "Printing...")) | 1786 | (message "Printing...")) |
| 933 | |||
| 934 | (save-excursion | 1787 | (save-excursion |
| 935 | (set-buffer ps-output-buffer) | 1788 | (set-buffer ps-spool-buffer) |
| 936 | (apply 'call-process-region | 1789 | (apply 'call-process-region |
| 937 | (point-min) (point-max) ps-lpr-command nil 0 nil | 1790 | (point-min) (point-max) ps-lpr-command nil 0 nil |
| 938 | ps-lpr-switches)) | 1791 | ps-lpr-switches)) |
| 939 | |||
| 940 | (if ps-razzle-dazzle | 1792 | (if ps-razzle-dazzle |
| 941 | (message "Printing... Done."))) | 1793 | (message "Printing...done"))) |
| 1794 | (kill-buffer ps-spool-buffer))) | ||
| 1795 | |||
| 1796 | (defun ps-kill-emacs-check () | ||
| 1797 | (let (ps-buffer) | ||
| 1798 | (if (and (setq ps-buffer (get-buffer ps-spool-buffer-name)) | ||
| 1799 | (buffer-modified-p ps-buffer)) | ||
| 1800 | (if (y-or-n-p "Unprinted PostScript waiting; print now? ") | ||
| 1801 | (ps-despool))) | ||
| 1802 | (if (and (setq ps-buffer (get-buffer ps-spool-buffer-name)) | ||
| 1803 | (buffer-modified-p ps-buffer)) | ||
| 1804 | (if (yes-or-no-p "Unprinted PostScript waiting; exit anyway? ") | ||
| 1805 | nil | ||
| 1806 | (error "Unprinted PostScript"))))) | ||
| 1807 | |||
| 1808 | (if (fboundp 'add-hook) | ||
| 1809 | (add-hook 'kill-emacs-hook 'ps-kill-emacs-check) | ||
| 1810 | (if kill-emacs-hook | ||
| 1811 | (message "Won't override existing kill-emacs-hook") | ||
| 1812 | (setq kill-emacs-hook 'ps-kill-emacs-check))) | ||
| 942 | 1813 | ||
| 943 | (kill-buffer ps-output-buffer))) | 1814 | ;;; Sample Setup Code: |
| 944 | 1815 | ||
| 945 | (defun ps-testpattern () | 1816 | ;; This stuff is for anybody that's brave enough to look this far, |
| 946 | (setq foo 1) | 1817 | ;; and able to figure out how to use it. It isn't really part of ps- |
| 947 | (while (< foo 60) | 1818 | ;; print, but I'll leave it here in hopes it might be useful: |
| 948 | (insert "|" (make-string foo ?\ ) (format "%d\n" foo)) | ||
| 949 | (setq foo (+ 1 foo)))) | ||
| 950 | 1819 | ||
| 951 | (defun pts (stuff) | 1820 | ;; Look in an article or mail message for the Subject: line. To be |
| 1821 | ;; placed in ps-left-headers. | ||
| 1822 | (defun ps-article-subject () | ||
| 952 | (save-excursion | 1823 | (save-excursion |
| 953 | (set-buffer "*scratch*") | 1824 | (goto-char (point-min)) |
| 954 | (goto-char (point-max)) | 1825 | (if (re-search-forward "^Subject:[ \t]+\\(.*\\)$") |
| 955 | (insert "---------------------------------\n" | 1826 | (buffer-substring (match-beginning 1) (match-end 1)) |
| 956 | (symbol-name stuff) ":\n" | 1827 | "Subject ???"))) |
| 957 | (prin1-to-string (symbol-value stuff)) | 1828 | |
| 958 | "\n"))) | 1829 | ;; Look in an article or mail message for the From: line. Sorta-kinda |
| 1830 | ;; understands RFC-822 addresses and can pull the real name out where | ||
| 1831 | ;; it's provided. To be placed in ps-left-headers. | ||
| 1832 | (defun ps-article-author () | ||
| 1833 | (save-excursion | ||
| 1834 | (goto-char (point-min)) | ||
| 1835 | (if (re-search-forward "^From:[ \t]+\\(.*\\)$") | ||
| 1836 | (let ((fromstring (buffer-substring (match-beginning 1) (match-end 1)))) | ||
| 1837 | (cond | ||
| 1838 | |||
| 1839 | ;; Try first to match addresses that look like | ||
| 1840 | ;; thompson@wg2.waii.com (Jim Thompson) | ||
| 1841 | ((string-match ".*[ \t]+(\\(.*\\))" fromstring) | ||
| 1842 | (substring fromstring (match-beginning 1) (match-end 1))) | ||
| 1843 | |||
| 1844 | ;; Next try to match addresses that look like | ||
| 1845 | ;; Jim Thompson <thompson@wg2.waii.com> | ||
| 1846 | ((string-match "\\(.*\\)[ \t]+<.*>" fromstring) | ||
| 1847 | (substring fromstring (match-beginning 1) (match-end 1))) | ||
| 1848 | |||
| 1849 | ;; Couldn't find a real name -- show the address instead. | ||
| 1850 | (t fromstring))) | ||
| 1851 | "From ???"))) | ||
| 1852 | |||
| 1853 | ;; A hook to bind to gnus-Article-prepare-hook. This will set the ps- | ||
| 1854 | ;; left-headers specially for gnus articles. Unfortunately, gnus- | ||
| 1855 | ;; article-mode-hook is called only once, the first time the *Article* | ||
| 1856 | ;; buffer enters that mode, so it would only work for the first time | ||
| 1857 | ;; we ran gnus. The second time, this hook wouldn't get set up. The | ||
| 1858 | ;; only alternative is gnus-article-prepare-hook. | ||
| 1859 | (defun ps-gnus-article-prepare-hook () | ||
| 1860 | (setq ps-header-lines 3) | ||
| 1861 | (setq ps-left-header | ||
| 1862 | ;; The left headers will display the article's subject, its | ||
| 1863 | ;; author, and the newsgroup it was in. | ||
| 1864 | (list 'ps-article-subject 'ps-article-author 'gnus-newsgroup-name))) | ||
| 1865 | |||
| 1866 | ;; A hook to bind to vm-mode-hook to locally bind prsc and set the ps- | ||
| 1867 | ;; left-headers specially for mail messages. This header setup would | ||
| 1868 | ;; also work, I think, for RMAIL. | ||
| 1869 | (defun ps-vm-mode-hook () | ||
| 1870 | (local-set-key 'f22 'ps-vm-print-message-from-summary) | ||
| 1871 | (setq ps-header-lines 3) | ||
| 1872 | (setq ps-left-header | ||
| 1873 | ;; The left headers will display the message's subject, its | ||
| 1874 | ;; author, and the name of the folder it was in. | ||
| 1875 | (list 'ps-article-subject 'ps-article-author 'buffer-name))) | ||
| 1876 | |||
| 1877 | ;; Every now and then I forget to switch from the *Summary* buffer to | ||
| 1878 | ;; the *Article* before hitting prsc, and a nicely formatted list of | ||
| 1879 | ;; article subjects shows up at the printer. This function, bound to | ||
| 1880 | ;; prsc for the gnus *Summary* buffer means I don't have to switch | ||
| 1881 | ;; buffers first. | ||
| 1882 | (defun ps-gnus-print-article-from-summary () | ||
| 1883 | (interactive) | ||
| 1884 | (if (get-buffer "*Article*") | ||
| 1885 | (save-excursion | ||
| 1886 | (set-buffer "*Article*") | ||
| 1887 | (ps-spool-buffer-with-faces)))) | ||
| 959 | 1888 | ||
| 960 | (provide 'ps-print) | 1889 | ;; See ps-gnus-print-article-from-summary. This function does the |
| 1890 | ;; same thing for vm. | ||
| 1891 | (defun ps-vm-print-message-from-summary () | ||
| 1892 | (interactive) | ||
| 1893 | (if vm-mail-buffer | ||
| 1894 | (save-excursion | ||
| 1895 | (set-buffer vm-mail-buffer) | ||
| 1896 | (ps-spool-buffer-with-faces)))) | ||
| 961 | 1897 | ||
| 962 | ;; ps-print.el ends here | 1898 | ;; A hook to bind to bind to gnus-summary-setup-buffer to locally bind |
| 1899 | ;; prsc. | ||
| 1900 | (defun ps-gnus-summary-setup () | ||
| 1901 | (local-set-key 'f22 'ps-gnus-print-article-from-summary)) | ||
| 1902 | |||
| 1903 | ;; File: lispref.info, Node: Standard Errors | ||
| 1904 | |||
| 1905 | ;; Look in an article or mail message for the Subject: line. To be | ||
| 1906 | ;; placed in ps-left-headers. | ||
| 1907 | (defun ps-info-file () | ||
| 1908 | (save-excursion | ||
| 1909 | (goto-char (point-min)) | ||
| 1910 | (if (re-search-forward "File:[ \t]+\\([^, \t\n]*\\)") | ||
| 1911 | (buffer-substring (match-beginning 1) (match-end 1)) | ||
| 1912 | "File ???"))) | ||
| 1913 | |||
| 1914 | ;; Look in an article or mail message for the Subject: line. To be | ||
| 1915 | ;; placed in ps-left-headers. | ||
| 1916 | (defun ps-info-node () | ||
| 1917 | (save-excursion | ||
| 1918 | (goto-char (point-min)) | ||
| 1919 | (if (re-search-forward "Node:[ \t]+\\([^,\t\n]*\\)") | ||
| 1920 | (buffer-substring (match-beginning 1) (match-end 1)) | ||
| 1921 | "Node ???"))) | ||
| 1922 | |||
| 1923 | (defun ps-info-mode-hook () | ||
| 1924 | (setq ps-left-header | ||
| 1925 | ;; The left headers will display the node name and file name. | ||
| 1926 | (list 'ps-info-node 'ps-info-file))) | ||
| 1927 | |||
| 1928 | (defun ps-jts-ps-setup () | ||
| 1929 | (global-set-key 'f22 'ps-spool-buffer-with-faces) ;f22 is prsc | ||
| 1930 | (global-set-key '(shift f22) 'ps-spool-region-with-faces) | ||
| 1931 | (global-set-key '(control f22) 'ps-despool) | ||
| 1932 | (add-hook 'gnus-article-prepare-hook 'ps-gnus-article-prepare-hook) | ||
| 1933 | (add-hook 'gnus-summary-mode-hook 'ps-gnus-summary-setup) | ||
| 1934 | (add-hook 'vm-mode-hook 'ps-vm-mode-hook) | ||
| 1935 | (add-hook 'Info-mode-hook 'ps-info-mode-hook) | ||
| 1936 | (setq ps-spool-duplex t) | ||
| 1937 | (setq ps-print-color-p nil) | ||
| 1938 | (setq ps-lpr-command "lpr") | ||
| 1939 | (setq ps-lpr-switches '("-Jjct,duplex_long"))) | ||
| 1940 | |||
| 1941 | (provide 'ps-print) | ||
| 1942 | ;;; ps-print.el ends here | ||