1 ;; Jim's Pretty-Good PostScript Generator for Emacs 19 (ps-print).
2 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 ;; Author: James C. Thompson <thompson@wg2.waii.com>
5 ;; Keywords: faces, postscript, printing
7 ;; This file is part of GNU Emacs.
9 ;; 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
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 ;; Thanks to Avishai Yacobi, avishaiy@mcil.comm.mot.com, for writing
28 ;; Thanks to Remi Houdaille and Michel Train, michel@metasoft.fdn.org,
29 ;; for adding underline support and title code. (Titling will appear
30 ;; in the next release.)
32 ;; Thanks to Heiko Muenkel, muenkel@tnt.uni-hannover.de, for showing
33 ;; me how to handle ISO-8859/1 characters.
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).
39 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
43 ;; This package provides printing of Emacs buffers on PostScript
44 ;; printers; the buffer's bold and italic text attributes are
45 ;; preserved in the printer output. Ps-print is intended for use with
46 ;; Emacs 19 (Lucid or FSF) and a fontifying package such as font-lock
49 ;; Installing ps-print:
50 ;; -------------------
51 ;; Place ps-print somewhere in your load-path and byte-compile it.
52 ;; Load ps-print with (require 'ps-print).
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:
63 ;; (setq ps-bold-faces (cons 'my-bold-face ps-bold-faces))
65 ;; Ps-print's printer interface is governed by the variables ps-lpr-
66 ;; command and ps-lpr-switches; these are analogous to the variables
67 ;; lpr-command and lpr-switches in the Emacs lpr package.
69 ;; To use ps-print, invoke the command ps-print-buffer-with-faces.
70 ;; This will generate a PostScript image of the current buffer and
71 ;; send it to the printer. Precede this command with a numeric prefix
72 ;; (C-u), and the PostScript output will be saved in a file; you will
73 ;; be prompted for a filename. Also see the functions ps-print-
74 ;; buffer, ps-print-region, and ps-print-region-with-faces.
76 ;; I recommend binding ps-print-buffer-with-faces to a key sequence;
77 ;; on a Sun 4 keyboard, for example, you can bind to the PrSc key (aka
80 ;; (global-set-key 'f22 'ps-print-buffer-with-faces)
81 ;; (global-set-key '(shift f22) 'ps-print-region-with-faces)
83 ;; Or, as I now prefer, you can also bind the ps-spool- functions to
84 ;; keys; here's my bindings:
86 ;; (global-set-key 'f22 'ps-spool-buffer-with-faces)
87 ;; (global-set-key '(shift f22) 'ps-spool-region-with-faces)
88 ;; (global-set-key '(control f22) 'ps-despool)
90 ;; Using ps-print with other Emacses:
91 ;; ---------------------------------
92 ;; Although it was intended for use with Emacs 19, ps-print will also work
93 ;; with Emacs version 18; you won't get fancy fontified output, but it
96 ;; A few words about support:
97 ;; -------------------------
98 ;; Despite its appearance, with comment blocks, usage instructions, and
99 ;; documentation strings, ps-print is not a supported package. That's all
100 ;; a masquerade. Ps-print is something I threw together in my spare time--
101 ;; an evening here, a Saturday there--to make my printouts look like my
102 ;; Emacs buffers. It works, but is not complete.
104 ;; Unfortunately, supporting elisp code is not my job and, now that I have
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.
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.
122 ;; Please send all bug fixes and enhancements to me, thompson@wg2.waii.com.
124 ;; New in version 1.5
125 ;; ------------------
126 ;; Support for Emacs 19. Works with both overlays and text
131 ;; Local spooling; see function ps-spool-buffer.
133 ;; Support for ISO8859-1 character set.
135 ;; Page breaks are now handled correctly.
137 ;; Percentages reported while formatting are now correct.
139 ;; Known bugs and limitations of ps-print:
140 ;; --------------------------------------
141 ;; Slow. (Byte-compiling helps.)
143 ;; The PostScript needs review/cleanup/enhancing by a PS expert.
145 ;; ASCII Control characters other than tab, linefeed and pagefeed are
148 ;; The mechanism for determining whether a stretch of characters
149 ;; should be printed bold, italic, or plain is crude and extremely
152 ;; Faces are always treated as opaque.
154 ;; Font names are hardcoded.
156 ;; Epoch not fully supported.
158 ;; Tested with only one PostScript printer.
164 ;; Simple headers with date, filename, and page numbers.
166 ;; Gaudy headers a`la enscript and mp.
168 ;; 2-up and 4-up capability.
170 ;; Wide-print capability.
175 (defconst ps-print-version
(substring "$Revision: 1.5 $" 11 -
2)
176 "$Id: ps-print.el,v 1.5 1994/04/22 13:25:18 jct Exp $
178 Please send all bug fixes and enhancements to Jim Thompson,
179 thompson@wg2.waii.com.")
181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
182 (defvar ps-lpr-command
(if (memq system-type
183 '(usg-unix-v hpux silicon-graphics-unix
))
185 "The shell command for printing a PostScript file.")
187 (defvar ps-lpr-switches nil
188 "A list of extra switches to pass to ps-lpr-command.")
190 (defvar ps-bold-faces
193 font-lock-function-name-face
196 "A list of the faces that should be printed italic.")
198 (defvar ps-italic-faces
201 font-lock-function-name-face
202 font-lock-string-face
203 font-lock-comment-face
204 message-header-contents
205 message-highlighted-header-contents
208 "A list of the faces that should be printed bold.")
210 (defvar ps-underline-faces
212 font-lock-string-face
)
213 "A list of the faces that should be printed underline.")
215 (defvar ps-razzle-dazzle t
216 "Non-nil means report progress while formatting buffer")
218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
220 (defun ps-print-buffer (&optional filename
)
222 "Generate and print a PostScript image of the buffer.
224 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
228 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
230 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.
233 The image is rendered using the PostScript font Courier.
235 See also: ps-print-buffer-with-faces
237 ps-spool-buffer-with-faces"
240 (setq filename
(ps-preprint filename
))
241 (ps-generate (current-buffer) (point-min) (point-max)
242 'ps-generate-postscript
)
243 (ps-do-despool filename
))
246 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
248 (defun ps-print-buffer-with-faces (&optional filename
)
250 "Generate and print a PostScript image of the buffer.
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
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.
266 The image is rendered using the PostScript fonts Courier, Courier-Bold,
267 Courier-Oblique, and Courier-BoldOblique.
269 See also: ps-print-buffer
271 ps-spool-buffer-with-faces."
274 (setq filename
(ps-preprint filename
))
275 (ps-generate (current-buffer) (point-min) (point-max)
276 'ps-generate-postscript-with-faces
)
277 (ps-do-despool filename
))
279 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
281 (defun ps-print-region (from to
&optional filename
)
283 "Generate and print a PostScript image of the region.
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
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.
293 See also: ps-print-region-with-faces
295 ps-spool-region-with-faces"
298 (setq filename
(ps-preprint filename
))
299 (ps-generate (current-buffer) from to
300 'ps-generate-postscript
)
301 (ps-do-despool filename
))
303 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
305 (defun ps-print-region-with-faces (from to
&optional filename
)
307 "Generate and print a PostScript image of the region.
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
314 See also: ps-print-region
316 ps-spool-region-with-faces"
319 (setq filename
(ps-preprint filename
))
320 (ps-generate (current-buffer) from to
321 'ps-generate-postscript-with-faces
)
322 (ps-do-despool filename
))
324 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326 (defun ps-spool-buffer ()
328 "Generate and spool a PostScript image of the buffer.
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.
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
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.
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).
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.
360 ps-print-buffer-with-faces
361 ps-spool-buffer-with-faces"
364 (ps-generate (current-buffer) (point-min) (point-max)
365 'ps-generate-postscript
))
367 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369 (defun ps-spool-buffer-with-faces ()
371 "Generate and spool PostScript image of the buffer.
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.
377 Use the function ps-despool to send the spooled images to the printer.
378 See the function ps-spool-buffer for a description of the spooling
384 ps-print-buffer-with-faces"
387 (ps-generate (current-buffer) (point-min) (point-max)
388 'ps-generate-postscript-with-faces
))
390 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
392 (defun ps-spool-region (from to
)
394 "Generate PostScript image of the region and spool locally.
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
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
407 ps-print-buffer-with-faces"
410 (ps-generate (current-buffer) from to
411 'ps-generate-postscript
))
413 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
415 (defun ps-spool-region-with-faces (from to
)
417 "Generate PostScript image of the region and spool locally.
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.
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
430 ps-print-buffer-with-faces"
433 (ps-generate (current-buffer) from to
434 'ps-generate-postscript-with-faces
))
436 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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.")
445 (defun ps-despool (&optional filename
)
446 "Send the spooled PostScript to the printer.
448 When called with a numeric prefix argument (C-u), prompt the user for
449 the name of a file to save the spooled PostScript in, instead of sending
452 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
454 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."
459 ;; If argument FILENAME is nil, send the image to the printer; if
460 ;; FILENAME is a string, save the PostScript image in that filename;
461 ;; if FILENAME is a number, prompt the user for the name of the file
464 (setq filename
(ps-preprint filename
))
465 (ps-do-despool filename
))
467 ;; Here end the definitions that users need to know about; proceed
468 ;; further at your own risk!
469 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
471 (defun ps-kill-emacs-check ()
472 (if (and (setq ps-buffer
(get-buffer ps-spool-buffer-name
))
473 (buffer-modified-p ps-buffer
))
474 (if (y-or-n-p "Unprinted PostScript waiting... print now? ")
477 (if (and (setq ps-buffer
(get-buffer ps-spool-buffer-name
))
478 (buffer-modified-p ps-buffer
))
479 (if (yes-or-no-p "Unprinted PostScript waiting; exit anyway? ")
481 (error "Unprinted PostScript"))))
483 (if (fboundp 'add-hook
)
484 (add-hook 'kill-emacs-hook
'ps-kill-emacs-check
)
486 (message "Won't override existing kill-emacs-hook.")
487 (setq kill-emacs-hook
'ps-kill-emacs-check
)))
489 (defun ps-preprint (&optional filename
)
491 (or (numberp filename
)
494 (let* ((name (concat (buffer-name) ".ps"))
495 (prompt (format "Save PostScript to file: (default %s) "
497 (read-file-name prompt default-directory
500 (defvar ps-spool-buffer-name
"*PostScript*")
507 (defvar ps-chars-per-line
80)
508 (defvar ps-lines-per-page
66)
510 (defvar ps-page-start-ypos
745)
511 (defvar ps-line-start-xpos
40)
513 (defvar ps-char-xpos-inc
6)
514 (defvar ps-line-ypos-inc
11)
516 (defvar ps-current-font
0)
518 (defvar ps-multiple nil
)
519 (defvar ps-virtual-page-number
0)
521 (defun ps-begin-file ()
523 (set-buffer ps-output-buffer
)
524 (goto-char (point-min))
525 (setq ps-real-page-number
1)
531 /L { gsave newpath 3 1 roll 1 sub M 0 rlineto closepath stroke grestore } def
533 /F{$fd exch get setfont}def
535 /StartPage{/svpg save def}def
536 /EndPage{svpg restore showpage}def
539 {dup/$fd exch array def{findfont exch scalefont $fd 3 1 roll put}repeat}def
541 % Define /ISOLatin1Encoding only if it's not already there.
542 /ISOLatin1Encoding where { pop save true }{ false } ifelse
543 /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus
544 StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute
545 /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring
546 /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown /cent
547 /sterling /currency /yen /brokenbar /section /dieresis /copyright
548 /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
549 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph
550 /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright
551 /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute
552 /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute
553 /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth
554 /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
555 /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn
556 /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae
557 /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute
558 /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex
559 /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex
560 /udieresis /yacute /thorn /ydieresis ] 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
570 /CourierISO /Courier reencodeISO
571 /Courier-ObliqueISO /Courier-Oblique reencodeISO
572 /Courier-BoldISO /Courier-Bold reencodeISO
573 /Courier-BoldObliqueISO /Courier-BoldOblique reencodeISO
575 3 10 /Courier-BoldObliqueISO
576 2 10 /Courier-ObliqueISO
577 1 10 /Courier-BoldISO
584 (defun ps-end-file ()
587 (defun ps-next-page ()
590 (ps-set-font ps-current-font
)
593 (defun ps-top-of-page () (ps-next-page))
595 (defun ps-init-page ()
598 (setq ps-ypos ps-page-start-ypos
)
599 (setq ps-xpos ps-line-start-xpos
)
602 (defun ps-begin-page ()
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")))
610 (defun ps-end-page ()
612 (set-buffer ps-output-buffer
)
613 (goto-char (point-max))
614 (insert "EndPage\n")))
616 (defun ps-next-line ()
617 (setq ps-row
(+ ps-row
1))
618 (if (>= ps-row ps-lines-per-page
)
621 (setq ps-xpos ps-line-start-xpos
)
622 (setq ps-ypos
(- ps-ypos ps-line-ypos-inc
))))
624 (defun ps-continue-line ()
627 (defvar ps-source-buffer nil
)
628 (defvar ps-output-buffer nil
)
630 (defun ps-basic-plot-string (from to
&optional underline-p
)
631 (setq text
(buffer-substring from to
))
633 (set-buffer ps-output-buffer
)
634 (goto-char (point-max))
635 (setq count
(- to from
))
638 (insert (format "%d %d %d L\n" ps-xpos ps-ypos
639 (* count ps-char-xpos-inc
))))
641 (insert (format "%d %d M (" ps-xpos ps-ypos
))
645 (while (re-search-forward "[()\\]" nil t
)
653 (setq ps-xpos
(+ ps-xpos
(* count ps-char-xpos-inc
)))))
655 (defun ps-basic-plot-whitespace (from to underline-p
)
656 (setq count
(- to from
))
657 (setq ps-xpos
(+ ps-xpos
(* count ps-char-xpos-inc
))))
659 (defun ps-plot (plotfunc from to
&optional underline-p
)
662 (setq count
(- to from
))
663 ;; Test to see whether this region will fit on the current line
664 (if (<= (+ ps-col count
) ps-chars-per-line
)
667 (funcall plotfunc from to underline-p
)
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
))
676 (setq from
(+ from chars-that-will-fit
))))
679 (let* ((q-todo (- (point-max) (point-min)))
680 (q-done (- to
(point-min)))
681 (chunkfrac (/ q-todo
8))
682 (chunksize (if (> chunkfrac
10000) 10000 chunkfrac
)))
683 (if (> (- q-done ps-razchunk
) chunksize
)
685 (setq ps-razchunk q-done
)
688 (* (/ q-done q-todo
) 100)
689 (setq basis
(/ q-todo
100))
692 (message "Formatting... %d%%" foo
))))))
694 (defun ps-set-font (&optional font
)
696 (set-buffer ps-output-buffer
)
697 (goto-char (point-max))
698 (insert (format "%d F\n" (if font font ps-current-font
))))
700 (setq ps-current-font font
)))
702 (defun ps-plot-region (from to font
&optional underline-p
)
709 (if (re-search-forward "[\t\n\014]" to t
)
710 (let ((match (char-after (match-beginning 0))))
713 (ps-plot 'ps-basic-plot-string from
(- (point) 1) underline-p
)
717 (ps-plot 'ps-basic-plot-string from
(- (point) 1) underline-p
)
718 (setq linestart
(save-excursion (beginning-of-line) (point)))
720 (setq from
(+ linestart
(current-column)))
721 (if (re-search-forward "[ \t]+" to t
)
722 (ps-plot 'ps-basic-plot-whitespace from
723 (+ linestart
(current-column)))))
726 (ps-plot 'ps-basic-plot-string from
(- (point) 1) underline-p
)
730 (ps-plot 'ps-basic-plot-string from to underline-p
)
733 (defun ps-format-buffer ()
736 (setq ps-source-buffer
(current-buffer))
737 (setq ps-output-buffer
(get-buffer-create "%PostScript%"))
740 (set-buffer ps-output-buffer
)
741 (delete-region (point-max) (point-min)))
747 (ps-plot-region (point-min) (point-max) 0)
753 (defun ps-mapper (extent list
)
754 (nconc list
(list (list (extent-start-position extent
) 'push extent
)
755 (list (extent-end-position extent
) 'pull extent
)))
758 (defun ps-sorter (a b
)
761 (defun ps-extent-sorter (a b
)
762 (< (extent-priority a
) (extent-priority b
)))
764 (defun overlay-priority (p)
765 (if (setq priority
(overlay-get p
'priority
)) priority
0))
767 (defun ps-overlay-sorter (a b
)
768 (> (overlay-priority a
) (overlay-priority b
)))
770 (defun ps-plot-with-face (from to face
)
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
))
777 ((and bold-p italic-p
)
778 (ps-plot-region from to
3 underline-p
))
780 (ps-plot-region from to
2 underline-p
))
782 (ps-plot-region from to
1 underline-p
))
784 (ps-plot-region from to
0 underline-p
))))
787 (defun ps-generate-postscript-with-faces (from to
)
790 (narrow-to-region from to
)
793 (cond ((string-match "Lucid" emacs-version
)
794 ;; Build the list of extents...
795 (let ((a (cons 'dummy nil
)))
796 (map-extents 'ps-mapper nil from to a
)
798 (setq a
(sort a
'ps-sorter
))
800 (setq extent-list nil
)
802 ;; Loop through the extents...
804 (setq record
(car a
))
806 (setq position
(car record
))
807 (setq record
(cdr record
))
809 (setq type
(car record
))
810 (setq record
(cdr record
))
812 (setq extent
(car record
))
814 ;; Plot up to this record.
815 (ps-plot-with-face from position face
)
819 (setq extent-list
(sort (cons extent extent-list
)
823 (setq extent-list
(sort (delq extent extent-list
)
824 'ps-extent-sorter
))))
828 (extent-face (car extent-list
))
834 ((string-match "^19" emacs-version
)
839 (if (setq p
(next-property-change from
))
844 (if (setq p
(next-overlay-change from
))
849 (if (< prop-position over-position
)
854 (if (setq f
(get-text-property from
'face
)) f
'default
))
856 (if (setq overlays
(overlays-at from
))
858 (setq overlays
(sort overlays
'ps-overlay-sorter
))
860 (if (setq face
(overlay-get (car overlays
) 'face
))
862 (setq overlays
(cdr overlays
))))))
864 ;; Plot up to this record.
865 (ps-plot-with-face from position face
)
867 (setq from position
))))
869 (ps-plot-with-face from to face
)))
871 (defun ps-generate-postscript (from to
)
872 (ps-plot-region from to
0))
874 (defun ps-generate (buffer from to genfunc
)
877 (narrow-to-region from to
)
879 (message "Formatting... %d%%" (setq ps-razchunk
0)))
882 (setq ps-source-buffer buffer
)
883 (setq ps-output-buffer
(get-buffer-create ps-spool-buffer-name
))
888 (set-buffer ps-output-buffer
)
889 (goto-char (point-min))
890 (if (looking-at (regexp-quote "%!PS-Adobe-1.0"))
891 (ps-set-font ps-current-font
)
896 (goto-char (point-max))
897 (if (and ps-spool-duplex
898 (re-search-backward "^%%Page")
899 (looking-at "^%%Page.*[24680]$"))
902 (set-buffer ps-source-buffer
)
903 (funcall genfunc from to
)
908 (message "Formatting... Done."))))
910 (defun ps-do-despool (filename)
912 (if (or (not (boundp 'ps-output-buffer
))
913 (not ps-output-buffer
))
914 (message "No spooled PostScript to print.")
921 (message "Saving..."))
923 (set-buffer ps-output-buffer
)
924 (setq filename
(expand-file-name filename
))
925 (write-region (point-min) (point-max) filename
)
928 (message "Wrote %s" filename
)))
930 ;; Else, spool to the printer
932 (message "Printing..."))
935 (set-buffer ps-output-buffer
)
936 (apply 'call-process-region
937 (point-min) (point-max) ps-lpr-command nil
0 nil
941 (message "Printing... Done.")))
943 (kill-buffer ps-output-buffer
)))
945 (defun ps-testpattern ()
948 (insert "|" (make-string foo ?\
) (format "%d\n" foo
))
949 (setq foo
(+ 1 foo
))))
953 (set-buffer "*scratch*")
954 (goto-char (point-max))
955 (insert "---------------------------------\n"
956 (symbol-name stuff
) ":\n"
957 (prin1-to-string (symbol-value stuff
))
962 ;; ps-print.el ends here