From: Kim F. Storm Date: Fri, 7 Feb 2003 21:06:51 +0000 (+0000) Subject: New file. X-Git-Tag: ttn-vms-21-2-B4~11308 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2c840b907a47e94978b130db0ddd954d645e1eb3;p=emacs.git New file. Assigned by Vinicius Jose Latorre --- diff --git a/lisp/printing.el b/lisp/printing.el new file mode 100644 index 00000000000..c53b41b84d5 --- /dev/null +++ b/lisp/printing.el @@ -0,0 +1,6232 @@ +;;; printing.el --- printing utilities + +;; Copyright (C) 2000, 2001, 2002 +;; Free Software Foundation, Inc. + +;; Author: Vinicius Jose Latorre +;; Maintainer: Vinicius Jose Latorre +;; Keywords: wp, print, PostScript +;; Time-stamp: <2002/09/11 16:59:00 vinicius> +;; Version: 6.7.1 +;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/ + +(defconst pr-version "6.7.1" + "printing.el, v 6.7.1 <2002/09/11 vinicius> + +Please send all bug fixes and enhancements to + Vinicius Jose Latorre +") + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify it under +;; the terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 2, or (at your option) any later +;; version. + +;; GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY +;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +;; details. + +;; You should have received a copy of the GNU General Public License along with +;; GNU Emacs; see the file COPYING. If not, write to the Free Software +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Introduction +;; ------------ +;; +;; This package provides some printing utilities that includes +;; previewing/printing a PostScript file, printing a text file and +;; previewing/printing some major modes (like mh-folder-mode, +;; rmail-summary-mode, gnus-summary-mode, etc). +;; +;; `printing' was inspired on: +;; +;; print-nt.el Frederic Corne +;; Special printing functions for Windows NT +;; +;; mh-e-init.el Tom Vogels +;; PS-print for mail messages +;; +;; win32-ps-print.el Matthew O. Persico +;; PostScript printing with ghostscript +;; +;; ps-print-interface.el Volker Franz +;; Graphical front end for ps-print and previewing +;; +;; `printing' is prepared to run on GNU, Unix and NT systems. +;; On GNU or Unix system, `printing' depends on gs and gv utilities. +;; On NT system, `printing' depends on gstools (gswin32.exe and gsview32.exe). +;; To obtain ghostscript, ghostview and GSview see the URL +;; `http://www.gnu.org/software/ghostscript/ghostscript.html'. +;; +;; `printing' also depends on ps-print and lpr GNU Emacs packages. +;; To download the latest ps-print package see +;; `http://www.cpqd.com.br/~vinicius/emacs/ps-print.tar.gz'. +;; Please, see README file for ps-print installation instructions. +;; +;; +;; Novices (First Users) +;; --------------------- +;; +;; First of all, take a glance of printing documentation only to have an idea +;; of what `printing' is capable. +;; +;; Then try to set the variables: `pr-ps-name', `pr-ps-printer-alist', +;; `pr-txt-name', `pr-txt-printer-alist' and `pr-path-alist'. These variables +;; are the main variables for printing processing. +;; +;; Now, please, see these variables documentation more in deep. You can do +;; this by typing C-h v pr-ps-name RET (for example) if you already loaded +;; printing package, or by browsing printing.el source file. +;; +;; If the documentation isn't clear or if you find a way to improve the +;; documentation, please, send an email to maintainer. All printing users +;; will thank you. +;; +;; One way to set variables is by calling `pr-customize', customize all +;; variables and save the customization by future sessions (see Options +;; section). Other way is by coding your settings on Emacs init file (that is, +;; .emacs file), see below for a first setting template that it should be +;; inserted on your ~/.emacs file (or c:/_emacs, if you're using Windows 9x/NT +;; or MS-DOS): +;; +;; * Example of setting for Windows system: +;; +;; (require 'printing) ; load printing package +;; (setq pr-path-alist +;; '((windows "c:/applications/executables" PATH ghostview mpage) +;; (ghostview "c:/gs/gsview-dir") +;; (mpage "c:/mpage-dir") +;; )) +;; (setq pr-txt-name 'prt_06a) +;; (setq pr-txt-printer-alist +;; '((prt_06a "print" nil "/D:\\\\printers\\prt_06a") +;; (prt_07c nil nil "/D:\\\\printers\\prt_07c") +;; (PRN "" nil "PRN") +;; (standard "redpr.exe" nil "") +;; )) +;; (setq pr-ps-name 'lps_06b) +;; (setq pr-ps-printer-alist +;; '((lps_06a "print" nil "/D:" "\\\\printers\\lps_06a") +;; (lps_06b "print" nil nil "\\\\printers\\lps_06b") +;; (lps_07c "print" nil "" "/D:\\\\printers\\lps_07c") +;; (lps_08c nil nil nil "\\\\printers\\lps_08c") +;; (LPT1 "" nil "" "LPT1:") +;; (PRN "" nil "" "PRN") +;; (standard "redpr.exe" nil "" "") +;; )) +;; (pr-update-menus t) ; update now printer and utility menus +;; +;; * Example of setting for GNU or Unix system: +;; +;; (require 'printing) ; load printing package +;; (setq pr-path-alist +;; '((unix "." "~/bin" ghostview mpage PATH) +;; (ghostview "$HOME/bin/gsview-dir") +;; (mpage "$HOME/bin/mpage-dir") +;; )) +;; (setq pr-txt-name 'prt_06a) +;; (setq pr-txt-printer-alist +;; '((prt_06a "lpr" nil "prt_06a") +;; (prt_07c nil nil "prt_07c") +;; )) +;; (setq pr-ps-name 'lps_06b) +;; (setq pr-ps-printer-alist +;; '((lps_06b "lpr" nil "-P" "lps_06b") +;; (lps_07c "lpr" nil nil "lps_07c") +;; (lps_08c nil nil nil "lps_08c") +;; )) +;; (pr-update-menus t) ; update now printer and utility menus +;; +;; +;; NOTE 1: Don't forget to download and install ghostscript utilities (see +;; Utilities section). +;; +;; NOTE 2: The `printer-name' and `ps-printer-name' variables don't need to be +;; set, as they are implicit set by `pr-ps-printer-alist' and +;; `pr-txt-printer-alist'. +;; +;; NOTE 3: The duplex feature will only work on PostScript printers that +;; support this feature. +;; You can check if your PostScript printer supports duplex feature +;; by checking the printer manual. Or you can try these steps: +;; 1. Open a buffer (or use the *scratch* buffer). +;; 2. Type: +;; First line (on first page) +;; ^L +;; Second line (on second page) +;; 3. Print this buffer with duplex turned on. +;; If it's printed 2 (two) sheets of paper, then your PostScript +;; printer doesn't have duplex feature; otherwise, it's ok, your +;; printer does have duplex feature. +;; +;; +;; Using `printing' +;; ---------------- +;; +;; To use `printing' insert in your ~/.emacs file (or c:/_emacs, if you're +;; using Windows 9x/NT or MS-DOS): +;; +;; (require 'printing) +;; +;; When `printing' is loaded: +;; * On Emacs 20: +;; it replaces the Tools/Print menu by Tools/Printing menu. +;; * On Emacs 21: +;; it replaces the File/Print* menu entries by File/Print menu. +;; Please, see section Menu Layout below for menu explanation. +;; +;; To use `printing' utilities you can use the Printing menu options, type M-x +;; followed by one of the commands below, or type a key associated with the +;; command you want (if there is a key binding). +;; +;; `printing' has the following commands: +;; +;; pr-interface +;; pr-ps-directory-preview +;; pr-ps-directory-using-ghostscript +;; pr-ps-directory-print +;; pr-ps-directory-ps-print +;; pr-ps-buffer-preview +;; pr-ps-buffer-using-ghostscript +;; pr-ps-buffer-print +;; pr-ps-buffer-ps-print +;; pr-ps-region-preview +;; pr-ps-region-using-ghostscript +;; pr-ps-region-print +;; pr-ps-region-ps-print +;; pr-ps-mode-preview +;; pr-ps-mode-using-ghostscript +;; pr-ps-mode-print +;; pr-ps-mode-ps-print +;; pr-ps-file-preview +;; pr-ps-file-up-preview +;; pr-ps-file-using-ghostscript +;; pr-ps-file-print +;; pr-ps-file-ps-print +;; pr-ps-file-up-ps-print +;; pr-ps-fast-fire +;; pr-despool-preview +;; pr-despool-using-ghostscript +;; pr-despool-print +;; pr-despool-ps-print +;; pr-printify-directory +;; pr-printify-buffer +;; pr-printify-region +;; pr-txt-directory +;; pr-txt-buffer +;; pr-txt-region +;; pr-txt-mode +;; pr-txt-fast-fire +;; pr-toggle-file-duplex +;; pr-toggle-file-tumble +;; pr-toggle-file-landscape +;; pr-toggle-ghostscript +;; pr-toggle-faces +;; pr-toggle-spool +;; pr-toggle-duplex +;; pr-toggle-tumble +;; pr-toggle-landscape +;; pr-toggle-upside-down +;; pr-toggle-line +;; pr-toggle-zebra +;; pr-toggle-header +;; pr-toggle-lock +;; pr-toggle-region +;; pr-toggle-mode +;; pr-customize +;; lpr-customize +;; pr-help +;; pr-ps-name +;; pr-txt-name +;; pr-ps-utility +;; pr-show-ps-setup +;; pr-show-pr-setup +;; pr-show-lpr-setup +;; +;; The general meanings of above commands are: +;; +;; PREFIX: +;; `pr-interface' buffer interface for printing package. +;; `pr-help' help for printing package. +;; `pr-ps-name' select interactively a PostScript printer. +;; `pr-txt-name' select interactively a text printer. +;; `pr-ps-utility' select interactively a PostScript utility. +;; `pr-show-*-setup' show current settings. +;; `pr-ps-*' deal with PostScript code generation. +;; `pr-txt-*' deal with text generation. +;; `pr-toggle-*' toggle on/off some boolean variable. +;; `pr-despool-*' despool the PostScript spooling buffer. +;; `pr-printify-*' replace nonprintable ASCII by printable ASCII +;; representation. +;; +;; SUFFIX: +;; `*-customize' customization. +;; `*-preview' preview a PostScript file. +;; `*-using-ghostscript' use ghostscript to print. +;; `*-fast-fire' fast fire command (see it for documentation). +;; `*-print' send PostScript directly to printer. +;; `*-ps-print' send PostScript directly to printer or use +;; ghostscript to print. It depends on +;; `pr-print-using-ghostscript' option. +;; +;; INFIX/SUFFIX: +;; `*-directory*' process a directory. +;; `*-buffer*' process a buffer. +;; `*-region*' process a region. +;; `*-mode*' process a major mode (see explanation below). +;; `*-file-*' process a PostScript file. +;; `*-file-up-*' process a PostScript file using a filter utility. +;; +;; Here are some examples: +;; +;; `pr-ps-buffer-using-ghostscript' +;; Use ghostscript to print a buffer. +;; +;; `pr-ps-file-print' +;; Print a PostScript file. +;; +;; `pr-toggle-spool' +;; Toggle spooling buffer. +;; +;; So you can preview through ghostview, use ghostscript to print (if you don't +;; have a PostScript printer) or send directly to printer a PostScript code +;; generated by `ps-print' package. +;; +;; Besides operating one buffer or region each time, you also can postpone +;; previewing or printing by saving the PostScript code generated in a +;; temporary Emacs buffer. This way you can save banner pages between +;; successive printing. You can toggle on/off spooling by invoking +;; `pr-toggle-spool' interactively or through menu bar. +;; +;; If you type, for example: +;; +;; C-u M-x pr-ps-buffer-print RET +;; +;; The `pr-ps-buffer-print' command prompts you for a n-up printing number and +;; a file name, and save the PostScript code generated to the file name instead +;; of sending to printer. +;; +;; This behavior is similar with the commands that deal with PostScript code +;; generation, that is, with `pr-ps-*' and `pr-despool-*' commands. If +;; spooling is on, only `pr-despool-*' commands prompt for a file name and save +;; the PostScript code spooled in this file. +;; +;; Besides the behavior described above, the `*-directory*' commands also +;; prompt for a directory and a file name regexp. So, it's possible to process +;; all or certain files on a directory at once (see also documentation for +;; `pr-list-directory'). +;; +;; `printing' has also a special way to handle some major mode through +;; `*-mode*' commands. So it's possible to customize a major mode printing, +;; it's only needed to declare the customization in `pr-mode-alist' (see +;; section Options) and invoke some of `*-mode*' commands. An example for +;; major mode usage is when you're using gnus (or mh, or rmail, etc.) and +;; you're in the *Summary* buffer, if you forget to switch to the *Article* +;; buffer before printing, you'll get a nicely formatted list of article +;; subjects shows up at the printer. With major mode printing you don't need +;; to switch from gnus *Summary* buffer first. +;; +;; Current global keyboard mapping for GNU Emacs is: +;; +;; (global-set-key [print] 'pr-ps-fast-fire) +;; (global-set-key [M-print] 'pr-ps-mode-using-ghostscript) +;; (global-set-key [C-print] 'pr-txt-fast-fire) +;; +;; And for XEmacs is: +;; +;; (global-set-key 'f22 'pr-ps-fast-fire) +;; (global-set-key '(meta f22) 'pr-ps-mode-using-ghostscript) +;; (global-set-key '(control f22) 'pr-txt-fast-fire) +;; +;; As a suggestion of global keyboard mapping for some `printing' commands: +;; +;; (global-set-key "\C-ci" 'pr-interface) +;; (global-set-key "\C-cbp" 'pr-ps-buffer-print) +;; (global-set-key "\C-cbx" 'pr-ps-buffer-preview) +;; (global-set-key "\C-cbb" 'pr-ps-buffer-using-ghostscript) +;; (global-set-key "\C-crp" 'pr-ps-region-print) +;; (global-set-key "\C-crx" 'pr-ps-region-preview) +;; (global-set-key "\C-crr" 'pr-ps-region-using-ghostscript) +;; +;; +;; Options +;; ------- +;; +;; Below it's shown a brief description of `printing' options, please, see the +;; options declaration in the code for a long documentation. +;; +;; `pr-path-style' Specify which path style to use for external +;; commands. +;; +;; `pr-path-alist' Specify an alist for command paths. +;; +;; `pr-txt-name' Specify a printer for printing a text file. +;; +;; `pr-txt-printer-alist' Specify an alist of all text printers. +;; +;; `pr-ps-name' Specify a printer for printing a PostScript +;; file. +;; +;; `pr-ps-printer-alist' Specify an alist for all PostScript printers. +;; +;; `pr-temp-dir' Specify a directory for temporary files during +;; printing. +;; +;; `pr-ps-temp-file' Specify PostScript temporary file name. +;; +;; `pr-gv-command' Specify path and name of gsview program. +;; +;; `pr-gs-command' Specify path and name of ghostscript program. +;; +;; `pr-gs-switches' Specify ghostscript switches. +;; +;; `pr-gs-device' Specify ghostscript device switch value. +;; +;; `pr-gs-resolution' Specify ghostscript resolution switch value. +;; +;; `pr-print-using-ghostscript' Non-nil means print using ghostscript. +;; +;; `pr-faces-p' Non-nil means print with face attributes. +;; +;; `pr-spool-p' Non-nil means spool printing in a buffer. +;; +;; `pr-file-landscape' Non-nil means print PostScript file in +;; landscape orientation. +;; +;; `pr-file-duplex' Non-nil means print PostScript file in duplex +;; mode. +;; +;; `pr-file-tumble' Non-nil means print PostScript file in tumble +;; mode. +;; +;; `pr-auto-region' Non-nil means region is automagically detected. +;; +;; `pr-auto-mode' Non-nil means major-mode printing is prefered +;; over normal printing. +;; +;; `pr-mode-alist' Specify an alist for a major-mode and printing +;; function. +;; +;; `pr-ps-utility' Specify PostScript utility processing. +;; +;; `pr-ps-utility-alist' Specify an alist for PostScript utility +;; processing. +;; +;; `pr-menu-lock' Non-nil means menu is locked while selecting +;; toggle options. +;; +;; `pr-menu-char-height' Specify menu char height in pixels. +;; +;; `pr-menu-char-width' Specify menu char width in pixels. +;; +;; `pr-setting-database' Specify an alist for settings in general. +;; +;; `pr-visible-entry-list' Specify a list of Printing menu visible +;; entries. +;; +;; `pr-delete-temp-file' Non-nil means delete temporary files. +;; +;; `pr-list-directory' Non-nil means list directory when processing a +;; directory. +;; +;; `pr-buffer-name' Specify the name of the buffer interface for +;; printing package. +;; +;; `pr-buffer-name-ignore' Specify a regexp list for buffer names to be +;; ignored in interface buffer. +;; +;; `pr-buffer-verbose' Non-nil means to be verbose when editing a +;; field in interface buffer. +;; +;; `pr-shell-file-name' Specify file name to load inferior shells +;; from. +;; +;; To set the above options you may: +;; +;; a) insert the code in your ~/.emacs, like: +;; +;; (setq pr-faces-p t) +;; +;; This way always keep your default settings when you enter a new Emacs +;; session. +;; +;; b) or use `set-variable' in your Emacs session, like: +;; +;; M-x set-variable RET pr-faces-p RET t RET +;; +;; This way keep your settings only during the current Emacs session. +;; +;; c) or use customization, for example: +;; click on menu-bar *Help* option, +;; then click on *Customize*, +;; then click on *Browse Customization Groups*, +;; expand *PostScript* group, +;; expand *Printing* group +;; and then customize `printing' options. +;; Through this way, you may choose if the settings are kept or not when +;; you leave out the current Emacs session. +;; +;; d) or see the option value: +;; +;; C-h v pr-faces-p RET +;; +;; and click the *customize* hypertext button. +;; Through this way, you may choose if the settings are kept or not when +;; you leave out the current Emacs session. +;; +;; e) or invoke: +;; +;; M-x pr-customize RET +;; +;; and then customize `printing' options. +;; Through this way, you may choose if the settings are kept or not when +;; you leave out the current Emacs session. +;; +;; f) or use menu bar, for example: +;; click on menu-bar *File* option, +;; then click on *Printing*, +;; then click on *Customize*, +;; then click on *printing* +;; and then customize `printing' options. +;; Through this way, you may choose if the settings are kept or not when +;; you leave out the current Emacs session. +;; +;; +;; Menu Layout +;; ----------- +;; +;; The `printing' menu (Tools/Printing or File/Print) has the following layout: +;; +;; +-----------------------------+ +;; A 0 | Printing Interface | +;; +-----------------------------+ +-A---------+ +-B------+ +;; I 1 | PostScript Preview >|-------|Directory >|-----|1-up | +;; 2 | PostScript Print >|---- A |Buffer >|-- B |2-up | +;; 3 | PostScript Printer: name >|---- C |Region >|-- B |4-up | +;; +-----------------------------+ |Mode >|-- B |Other...| +;; II 4 | Printify >|-----\ |File >|--\ +--------+ +;; 5 | Print >|---\ | |Despool... | | +;; 6 | Text Printer: name >|-\ | | +-----------+ | +;; +-----------------------------+ | | | +---------+ +------------+ +;; III 7 |[ ]Landscape | | | \-|Directory| | As Is... | Ia +;; 8 |[ ]Print Header | | | |Buffer | +------------+ Ib +;; 9 |[ ]Print Header Frame | | | |Region | | name >|- C +;; 10 |[ ]Line Number | | | +---------+ +------------+ +;; 11 |[ ]Zebra Stripes | | | +---------+ | 1-up... | Ic +;; 12 |[ ]Duplex | | \---|Directory| | 2-up... | +;; 13 |[ ]Tumble | \--\ |Buffer | | 4-up... | +;; 14 |[ ]Upside-Down | | |Region | | Other... | +;; 15 | Print All Pages >|--\ | |Mode | +------------+ +;; +-----------------------------+ | | +---------+ |[ ]Landscape| Id +;; IV 16 |[ ]Spool Buffer | | | +-C-------+ |[ ]Duplex | Ie +;; 17 |[ ]Print with-faces | | \--|( )name A| |[ ]Tumble | If +;; 18 |[ ]Print Using Ghostscript | | |( )name B| +------------+ +;; +-----------------------------+ | |... | +;; V 19 |[ ]Auto Region | | |(*)name | +;; 20 |[ ]Auto Mode | | |... | +;; 21 |[ ]Menu Lock | | +---------+ +--------------+ +;; +-----------------------------+ \------------------|(*)All Pages | +;; VI 22 | Customize >|--- D +-D------+ |( )Even Pages | +;; 23 | Show Settings >|-------|printing| |( )Odd Pages | +;; 24 | Help | |ps-print| |( )Even Sheets| +;; +-----------------------------+ |lpr | |( )Odd Sheets | +;; +--------+ +--------------+ +;; +;; See `pr-visible-entry-list' for hiding some parts of the menu. +;; +;; The menu has the following sections: +;; +;; A. Interface: +;; +;; 0. You can use a buffer interface instead of menus. It looks like the +;; customization buffer. Basically, it has the same options found in the +;; menu and some extra options, all this on a buffer. +;; +;; I. PostScript printing: +;; +;; 1. You can generate a PostScript file (if you type C-u before activating +;; menu) or PostScript temporary file for a directory, a buffer, a region +;; or a major mode, choosing 1-up, 2-up, 4-up or any other n-up printing; +;; after file generation, ghostview is activated using the file generated +;; as argument. This option is disabled if spooling is on (option 16). +;; Also, if you already have a PostScript file you can preview it. +;; Instead of previewing each buffer, region or major mode at once, you +;; can save temporarily the PostScript code generated in a buffer and +;; preview it later. The option `Despool...' despools the PostScript +;; spooling buffer in a temporary file and uses ghostview to preview it. +;; If you type C-u before choosing this option, the PostScript code +;; generated is saved in a file instead of saving in a temporary file. +;; To spool the PostScript code generated you need to turn on the option +;; 16. The option `Despool...' is enabled if spooling is on (option +;; 16). +;; +;; NOTE 1: It's possible to customize a major mode printing, just declare +;; the customization in `pr-mode-alist' and invoke some of +;; `*-mode*' commands or select Mode option in Printing menu. An +;; example for major mode usage is when you're using gnus (or mh, +;; or rmail, etc.) and you're in the *Summary* buffer, if you +;; forget to switch to the *Article* buffer before printing, +;; you'll get a nicely formatted list of article subjects shows +;; up at the printer. With major mode printing you don't need to +;; switch from gnus *Summary* buffer first. +;; +;; NOTE 2: There are the following options for PostScript file +;; processing: +;; Ia. Print the file *as is*, that is, send it directly to +;; PostScript printer. +;; Ib. PostScript utility processing selection. +;; See `pr-ps-utility-alist' and `pr-setting-database' for +;; documentation. +;; Ic. Do n-up processing before printing. +;; Id. Toggle on/off landscape for PostScript file processing. +;; Ie. Toggle on/off duplex for PostScript file processing. +;; If. Toggle on/off tumble for PostScript file processing. +;; +;; NOTE 3: Don't forget to download and install the utilities declared on +;; `pr-ps-utility-alist'. +;; +;; 2. Operate the same way as option 1, but it sends directly the PostScript +;; code (or put in a file, if you've typed C-u) or it uses ghostscript to +;; print the PostScript file generated. It depends on option 18, if it's +;; turned on, it uses ghostscript; otherwise, it sends directly to +;; printer. If spooling is on (option 16), the PostScript code is saved +;; temporarily in a buffer instead of printing it or saving it in a file. +;; Also, if you already have a PostScript file you can print it. Instead +;; of printing each buffer, region or major mode at once, you can save +;; temporarily the PostScript code generated in a buffer and print it +;; later. The option `Despool...' despools the PostScript spooling +;; buffer directly on a printer. If you type C-u before choosing this +;; option, the PostScript code generated is saved in a file instead of +;; sending to printer. To spool the PostScript code generated you need +;; to turn on the option 16. This option is enabled if spooling is on +;; (option 16). See also the NOTE 1, NOTE 2 and NOTE 3 on option 1. +;; +;; 3. You can select a new PostScript printer to send PostScript code +;; generated. For selection it's used all PostScript printers defined +;; in `pr-ps-printer-alist' variable (see it for documentation). +;; See also `pr-setting-database'. +;; +;; II. Text printing: +;; +;; 4. If you have control characters (character code from \000 to \037) in a +;; buffer and you want to print them in a text printer, select this +;; option. All control characters in your buffer or region will be +;; replaced by a printable representation. The printable representations +;; use ^ (for ASCII control characters) or hex. The characters tab, +;; linefeed, space, return and formfeed are not affected. You don't need +;; to select this option if you use any option of section I, the +;; PostScript engine treats control characters properly. +;; +;; 5. If you want to print a directory, buffer, region or major mode in a +;; text printer, select this option. See also the NOTE 1 on option 1. +;; +;; 6. You can select a new text printer to send text generated. For +;; selection it's used all text printers defined in +;; `pr-txt-printer-alist' variable (see it for documentation). +;; See also `pr-setting-database'. +;; +;; III. PostScript page toggle options: +;; +;; 7. If you want a PostScript landscape printing, turn on this option. +;; +;; 8. If you want to have a header in each page in your PostScript code, +;; turn on this option. +;; +;; 9. If you want to draw a gaudy frame around the header, turn on this +;; option. This option is enabled if print header is on (option 8). +;; +;; 10. If you want that the line number is printed in your PostScript code, +;; turn on this option. +;; +;; 11. If you want background zebra stripes in your PostScript code, turn on +;; this option. +;; +;; 12. If you want a duplex printing and your PostScript printer has this +;; feature, turn on this option. +;; +;; 13. If you turned on duplex printing, you can choose if you want to have +;; a printing suitable for binding on the left or right (tumble off), or +;; to have a printing suitable for binding at top or bottom (tumble on). +;; This option is enabled if duplex is on (option 12). +;; +;; 14. If you want a PostScript upside-down printing, turn on this option. +;; +;; 15. With this option, you can choose if you want to print all pages, odd +;; pages, even pages, odd sheets or even sheets. +;; See also `ps-even-or-odd-pages'. +;; +;; IV. PostScript processing toggle options: +;; +;; 16. If you want to spool the PostScript code generated, turn on this +;; option. To spool the PostScript code generated use option 2. You +;; can despool later by choosing option 1 or 2, sub-option `Despool...'. +;; +;; 17. If you use colors in your buffers and want to see these colors on +;; your PostScript code generated, turn on this option. If you have a +;; black/white PostScript printer, these colors are displayed in gray +;; scale by PostScript printer interpreter. +;; +;; 18. If you don't have a PostScript printer to send PostScript files, turn +;; on this option. When this option is on, the ghostscript is used to +;; print PostScript files. In GNU or Unix system, if ghostscript is set +;; as a PostScript filter, you don't need to turn on this option. +;; +;; V. Printing customization: +;; +;; 19. If you want that region is automagically detected, turn on this +;; option. Note that this will only work if you're using transient mark +;; mode. When this option is on, the `*-buffer*' commands will behave +;; like `*-region*' commands, that is, `*-buffer*' commands will print +;; only the region marked instead of all buffer. +;; +;; 20. Turn this option on if you want that when current major-mode is +;; declared in `pr-mode-alist', the `*-buffer*' and `*-region*' commands +;; behave like `*-mode*' commands. +;; +;; 21. If you want that Printing menu stays poped up while you are setting +;; toggle options, turn on this option. The variables +;; `pr-menu-char-height' and `pr-menu-char-width' are used to guess the +;; menu position, so don't forget to adjust these variables if menu +;; position is not ok. +;; +;; VI. Customization: +;; +;; 22. Besides all options in section III, IV and V, you can customize much +;; more PostScript options in `ps-print' option. Or you can customize +;; some `lpr' options for text printing. Or customize `printing' +;; options. +;; +;; 23. Show current settings for `printing', `ps-print' or `lpr'. +;; +;; 24. Quick help for printing menu layout. +;; +;; +;; Option Settings +;; --------------- +;; +;; Below it's shown only the main options that affect all `printing' package. +;; Check all the settings below *BEFORE* running `printing' commands. +;; +;; * Example of setting for GNU or Unix system: +;; +;; (require 'printing) +;; (setq pr-path-alist +;; '((unix "." "~/bin" ghostview mpage PATH) +;; (ghostview "$HOME/bin/gsview-dir") +;; (mpage "$HOME/bin/mpage-dir") +;; )) +;; (setq pr-txt-name 'prt_06a) +;; (setq pr-txt-printer-alist +;; '((prt_06a "lpr" nil "prt_06a") +;; (prt_07c nil nil "prt_07c") +;; )) +;; (setq pr-ps-name 'lps_06b) +;; (setq pr-ps-printer-alist +;; '((lps_06b "lpr" nil "-P" "lps_06b") +;; (lps_07c "lpr" nil nil "lps_07c") +;; (lps_08c nil nil nil "lps_08c") +;; )) +;; (setq pr-temp-dir "/tmp/") +;; (setq pr-gv-command "gv") +;; (setq pr-gs-command "gs") +;; (setq pr-gs-switches '("-q -dNOPAUSE -I/usr/share/ghostscript/5.10")) +;; (setq pr-gs-device "uniprint") +;; (setq pr-gs-resolution 300) +;; (setq pr-ps-utility 'mpage) +;; (setq pr-ps-utility-alist +;; '((mpage "mpage" nil "-b%s" "-%d" "-l" "-t" "-T" ">" nil) +;; (psnup "psnup" ("-q") "-P%s" "-%d" "-l" nil nil " " nil +;; (inherits-from: . no-duplex)) +;; )) +;; (setq pr-setting-database +;; '((no-duplex +;; nil nil nil +;; (pr-file-duplex . nil) +;; (pr-file-tumble . nil)) +;; )) +;; (pr-update-menus t) ; update now printer and utility menus +;; +;; * Example of setting for Windows system: +;; +;; (require 'printing) +;; (setq pr-path-alist +;; '((windows "c:/applications/executables" PATH ghostview mpage) +;; (ghostview "c:/gs/gsview-dir") +;; (mpage "c:/mpage-dir") +;; )) +;; (setq pr-txt-name 'prt_06a) +;; (setq pr-txt-printer-alist +;; '((prt_06a "print" nil "/D:\\\\printers\\prt_06a") +;; (prt_07c nil nil "/D:\\\\printers\\prt_07c") +;; (PRN "" nil "PRN") +;; (standard "redpr.exe" nil "") +;; )) +;; (setq pr-ps-name 'lps_06b) +;; (setq pr-ps-printer-alist +;; '((lps_06a "print" nil "/D:" "\\\\printers\\lps_06a") +;; (lps_06b "print" nil nil "\\\\printers\\lps_06b") +;; (lps_07c "print" nil "" "/D:\\\\printers\\lps_07c") +;; (lps_08c nil nil nil "\\\\printers\\lps_08c") +;; (LPT1 "" nil "" "LPT1:") +;; (PRN "" nil "" "PRN") +;; (standard "redpr.exe" nil "" "") +;; )) +;; (setq pr-temp-dir "C:/WINDOWS/TEMP/") +;; (setq pr-gv-command "c:/gs/gsview/gsview32.exe") +;; (setq pr-gs-command "c:/gs/gswin32.exe") +;; (setq pr-gs-switches '("-q -dNOPAUSE -Ic:/gs/gs5.50;c:/gs/gs5.50/fonts")) +;; (setq pr-gs-device "mswinpr2") +;; (setq pr-gs-resolution 300) +;; (setq pr-ps-utility 'psnup) +;; (setq pr-ps-utility-alist +;; '((psnup "c:/psutils/psnup" ("-q") "-P%s" "-%d" "-l" nil nil " " +;; nil (inherits-from: . no-duplex)) +;; )) +;; (setq pr-setting-database +;; '((no-duplex +;; nil nil nil +;; (pr-file-duplex . nil) +;; (pr-file-tumble . nil)) +;; )) +;; (pr-update-menus t) ; update now printer and utility menus +;; +;; NOTE: Don't forget to download and install the utilities declared on +;; `pr-ps-utility-alist'. +;; +;; +;; Utilities +;; --------- +;; +;; `printing' package has the following utilities: +;; +;; `pr-setup' Return the current `printing' setup. +;; +;; `lpr-setup' Return the current `lpr' setup. +;; +;; `pr-update-menus' Update utility, PostScript and text printer menus. +;; +;; Below are some URL where you can find good utilities. +;; +;; * For `printing' package: +;; +;; printing `http://www.cpqd.com.br/~vinicius/emacs/printing.el.gz' +;; ps-print `http://www.cpqd.com.br/~vinicius/emacs/ps-print.tar.gz' +;; +;; * For GNU or Unix system: +;; +;; gs, gv `http://www.gnu.org/software/ghostscript/ghostscript.html' +;; enscript `http://people.ssh.fi/mtr/genscript/' +;; psnup `http://www.dcs.ed.ac.uk/home/ajcd/psutils/index.html' +;; mpage `http://www.mesa.nl/pub/mpage/' +;; +;; * For Windows system: +;; +;; gswin32, gsview32 +;; `http://www.gnu.org/software/ghostscript/ghostscript.html' +;; enscript `http://people.ssh.fi/mtr/genscript/' +;; psnup `http://www.dcs.ed.ac.uk/home/ajcd/psutils/index.html' +;; redmon `http://www.cs.wisc.edu/~ghost/redmon/' +;; +;; +;; Acknowledgments +;; --------------- +;; +;; Thanks to Drew Adams for directory processing and `pr-path-alist' +;; suggestions. +;; +;; Thanks to Fred Labrosse for XEmacs tests. +;; +;; Thanks to Klaus Berndl for invaluable help/debugging +;; and for suggestions: +;; - even/odd pages printing. +;; - ghostscript parameters for `pr-ps-printer-alist'. +;; - default printer name. +;; - completion functions. +;; - automagic region detection. +;; - menu entry hiding. +;; - fast fire PostScript printing command. +;; - `pr-path-style' variable. +;; +;; Thanks to Kim F. Storm for beta-test and for suggestions: +;; - PostScript Print and PostScript Print Preview merge. +;; - Tools/Printing menu. +;; - replace *-using-preview by *-using-ghostscript. +;; - printer selection. +;; - extra parameters for `pr-ps-printer-alist'. +;; +;; Thanks to: +;; Frederic Corne print-nt.el +;; Tom Vogels mh-e-init.el +;; Matthew O. Persico win32-ps-print.el +;; Volker Franz ps-print-interface.el +;; And to all people who contributed with them. +;; +;; +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Code: + + +(require 'lpr) +(require 'ps-print) + + +(and (string< ps-print-version "6.5.7") + (error "`printing' requires `ps-print' package version 6.5.7 or later.")) + + +(eval-and-compile + (defconst pr-cygwin-system + (and ps-windows-system (getenv "OSTYPE") + (string-match "cygwin" (getenv "OSTYPE"))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; To avoid compilation gripes + + +(eval-and-compile + + (or (fboundp 'subst-char-in-string) + (defun subst-char-in-string (fromchar tochar string &optional inplace) + "Replace FROMCHAR with TOCHAR in STRING each time it occurs. +Unless optional argument INPLACE is non-nil, return a new string." + (let ((i (length string)) + (newstr (if inplace string (copy-sequence string)))) + (while (> (setq i (1- i)) 0) + (if (eq (aref newstr i) fromchar) + (aset newstr i tochar))) + newstr))) + + ;; GNU Emacs + (defalias 'pr-e-frame-char-height 'frame-char-height) + (defalias 'pr-e-frame-char-width 'frame-char-width) + (defalias 'pr-e-mouse-pixel-position 'mouse-pixel-position) + ;; XEmacs + (defalias 'pr-x-add-submenu 'add-submenu) + (defalias 'pr-x-event-function 'event-function) + (defalias 'pr-x-event-object 'event-object) + (defalias 'pr-x-find-menu-item 'find-menu-item) + (defalias 'pr-x-font-height 'font-height) + (defalias 'pr-x-font-width 'font-width) + (defalias 'pr-x-get-popup-menu-response 'get-popup-menu-response) + (defalias 'pr-x-make-event 'make-event) + (defalias 'pr-x-misc-user-event-p 'misc-user-event-p) + (defalias 'pr-x-relabel-menu-item 'relabel-menu-item) + (defalias 'pr-x-event-x-pixel 'event-x-pixel) + (defalias 'pr-x-event-y-pixel 'event-y-pixel) + + (cond + ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + (defvar deactivate-mark nil) + (defalias 'pr-f-set-keymap-parents 'set-keymap-parent) + (defalias 'pr-f-set-keymap-name 'ignore) + (defalias 'pr-f-read-string 'read-string) + (defun pr-keep-region-active () + (setq deactivate-mark nil))) + + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + (defvar current-menubar nil) + (defvar current-mouse-event nil) + (defvar zmacs-region-stays nil) + (defalias 'pr-f-set-keymap-parents 'set-keymap-parents) + (defalias 'pr-f-set-keymap-name 'set-keymap-name) + (defun pr-f-read-string (prompt initial history default) + (let ((str (read-string prompt initial))) + (if (and str (not (string= str ""))) + str + default))) + (defun pr-keep-region-active () + (setq zmacs-region-stays t))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Customization Functions + + +(defun pr-alist-custom-set (symbol value) + "Set the value of custom variables for printer & utility selection." + (set symbol value) + (and (featurep 'printing) ; update only after printing is loaded + (pr-update-menus t))) + + +(defun pr-ps-utility-custom-set (symbol value) + "Update utility menu entry." + (set symbol value) + (and (featurep 'printing) ; update only after printing is loaded + (pr-menu-set-utility-title value))) + + +(defun pr-ps-name-custom-set (symbol value) + "Update `PostScript Printer:' menu entry." + (set symbol value) + (and (featurep 'printing) ; update only after printing is loaded + (pr-menu-set-ps-title value))) + + +(defun pr-txt-name-custom-set (symbol value) + "Update `Text Printer:' menu entry." + (set symbol value) + (and (featurep 'printing) ; update only after printing is loaded + (pr-menu-set-txt-title value))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; User Interface (I) + + +(defgroup printing nil + "Printing Utilities group" + :tag "Printing Utilities" + :link '(emacs-library-link :tag "Source Lisp File" "printing.el") + :prefix "pr-" + :group 'wp + :group 'postscript) + + +(defcustom pr-path-style + (if (and (not pr-cygwin-system) + ps-windows-system) + 'windows + 'unix) + "*Specify which path style to use for external commands. + +Valid values are: + + windows Windows 9x/NT style (\\) + + unix Unix style (/)" + :type '(choice :tag "Path style" + (const :tag "Windows 9x/NT Style (\\)" :value windows) + (const :tag "Unix Style (/)" :value unix)) + :group 'printing) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Internal Functions (I) + + +(defun pr-dosify-path (path) + "Replace unix-style directory separator character with dos/windows one." + (interactive "sPath: ") + (if (eq pr-path-style 'windows) + (subst-char-in-string ?/ ?\\ path) + path)) + + +(defun pr-unixify-path (path) + "Replace dos/windows-style directory separator character with unix one." + (interactive "sPath: ") + (if (eq pr-path-style 'windows) + (subst-char-in-string ?\\ ?/ path) + path)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; User Interface (II) + + +(defcustom pr-path-alist + '((unix PATH) + (cygwin PATH) + (windows PATH)) + "*Specify an alist for command paths. + +It's used to find commands used for printing package, like gv, gs, gsview.exe, +mpage, print.exe, etc. See also `pr-command' function. + +Each element has the form: + + (ENTRY DIRECTORY...) + +Where: + +ENTRY It's a symbol, used to identify this entry. + There must exist at least one of the following entries: + + unix this entry is used when Emacs is running on GNU or + Unix system. + + cygwin this entry is used when Emacs is running on Windows + 95/98/NT/2000 with Cygwin. + + windows this entry is used when Emacs is running on Windows + 95/98/NT/2000. + +DIRECTORY It should be a string or a symbol. If it's a symbol, it should + exist an equal entry in `pr-path-alist'. If it's a string, + it's considered a directory specification. + + The directory specification may contain: + $var environment variable expansion + ~/ tilde expansion + ./ current directory + ../ previous directory + + For example, let's say the home directory is /home/my and the + current directory is /home/my/dir, so: + + THE ENTRY IS EXPANDED TO + ~/entry /home/my/entry + ./entry /home/my/dir/entry + ../entry /home/my/entry + $HOME/entry /home/my/entry + $HOME/~/other/../my/entry /home/my/entry + + SPECIAL SYMBOL: If the symbol `PATH' is used in the directory + list and there isn't a `PATH' entry in `pr-path-alist' or the + `PATH' entry has a null directory list, the PATH environment + variable is used. + +Examples: + +* On GNU or Unix system: + + '((unix \".\" \"~/bin\" ghostview mpage PATH) + (ghostview \"$HOME/bin/gsview-dir\") + (mpage \"$HOME/bin/mpage-dir\") + ) + +* On Windows system: + + '((windows \"c:/applications/executables\" PATH ghostview mpage) + (ghostview \"c:/gs/gsview-dir\") + (mpage \"c:/mpage-dir\") + )" + :type '(repeat + (cons :tag "" + (symbol :tag "Identifier ") + (repeat :tag "Directory List" + (choice :menu-tag "Directory" + :tag "Directory" + (string :value "") + (symbol :value symbol))))) + :group 'printing) + + +(defcustom pr-txt-name 'default + "*Specify a printer for printing a text file. + +The printer name symbol should be defined on `pr-txt-printer-alist' (see it for +documentation). + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update text printer menu." + :type 'symbol + :set 'pr-txt-name-custom-set + :group 'printing) + + +(defcustom pr-txt-printer-alist + (list (list 'default lpr-command nil + (cond ((boundp 'printer-name) printer-name) + (ps-windows-system "PRN") + (t nil) + ))) + ;; Examples: + ;; * On GNU or Unix system: + ;; '((prt_06a "lpr" nil "prt_06a") + ;; (prt_07c nil nil "prt_07c") + ;; ) + ;; * On Windows system: + ;; '((prt_06a "print" nil "/D:\\\\printers\\prt_06a") + ;; (prt_07c nil nil "/D:\\\\printers\\prt_07c") + ;; (PRN "" nil "PRN") + ;; (standard "redpr.exe" nil "") + ;; ) + "*Specify an alist of all text printers (text printer database). + +The alist element has the form: + + (SYMBOL COMMAND SWITCHES NAME) + +Where: + +SYMBOL It's a symbol to identify a text printer. It's for + `pr-txt-name' variable setting and for menu selection. + Examples: + 'prt_06a + 'my_printer + +COMMAND Name of program for printing a text file. On MS-DOS and + MS-Windows systems, if the value is an empty string then Emacs + will write directly to the printer port named by NAME (see text + below), that is, the NAME should be something like \"PRN\" or + \"LPT1:\". + If NAME is something like \"\\\\\\\\host\\\\share-name\" then + COMMAND shouldn't be an empty string. + The programs `print' and `nprint' (the standard print programs + on Windows NT and Novell Netware respectively) are handled + specially, using NAME as the destination for output; any other + program is treated like `lpr' except that an explicit filename + is given as the last argument. + If COMMAND is nil, it's used the default printing program: + `print' for Windows system, `lp' for lp system and `lpr' for + all other systems. See also `pr-path-alist'. + Examples: + \"print\" + \"lpr\" + \"lp\" + +SWITCHES List of sexp's to pass as extra options for text printer + program. It is recommended to set NAME (see text below) + instead of including an explicit switch on this list. + Example: + . for lpr + '(\"-#3\" \"-l\") + nil + +NAME A string that specifies a text printer name. + On Unix-like systems, a string value should be a name + understood by lpr's -P option (or lp's -d option). + On MS-DOS and MS-Windows systems, it is the name of a printer + device or port. Typical non-default settings would be \"LPT1:\" + to \"LPT3:\" for parallel printers, or \"COM1\" to \"COM4\" or + \"AUX\" for serial printers, or \"\\\\\\\\hostname\\\\printer\" + (or \"/D:\\\\\\\\hostname\\\\printer\") for a shared network + printer. You can also set it to a name of a file, in which + case the output gets appended to that file. If you want to + discard the printed output, set this to \"NUL\". + Examples: + . for print.exe + \"/D:\\\\\\\\host\\\\share-name\" + \"LPT1:\" + \"PRN\" + + . for lpr or lp + \"share-name\" + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update text printer menu. + +Examples: + +* On GNU or Unix system: + + '((prt_06a \"lpr\" nil \"prt_06a\") + (prt_07c nil nil \"prt_07c\") + ) + +* On Windows system: + + '((prt_06a \"print\" nil \"/D:\\\\\\\\printers\\\\prt_06a\") + (prt_07c nil nil \"/D:\\\\\\\\printers\\\\prt_07c\") + (PRN \"\" nil \"PRN\") + (standard \"redpr.exe\" nil \"\") + )" + :type '(repeat + (list :tag "Text Printer" + (symbol :tag "Printer Symbol Name") + (string :tag "Printer Command") + (repeat :tag "Printer Switches" + (sexp :tag "Switch" :value "")) + (choice :menu-tag "Printer Name" + :tag "Printer Name" + (const :tag "None" nil) + string))) + :set 'pr-alist-custom-set + :group 'printing) + + +(defcustom pr-ps-name 'default + "*Specify a printer for printing a PostScript file. + +This printer name symbol should be defined on `pr-ps-printer-alist' (see it for +documentation). + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update PostScript printer menu." + :type 'symbol + :set 'pr-ps-name-custom-set + :group 'printing) + + +(defcustom pr-ps-printer-alist + (list (list 'default lpr-command nil + (cond (ps-windows-system nil) + (ps-lp-system "-d") + (t "-P")) + (or (getenv "PRINTER") (getenv "LPDEST") ps-printer-name))) + ;; Examples: + ;; * On GNU or Unix system: + ;; '((lps_06b "lpr" nil "-P" "lps_06b") + ;; (lps_07c "lpr" nil nil "lps_07c") + ;; (lps_08c nil nil nil "lps_08c") + ;; ) + ;; * On Windows system: + ;; '((lps_06a "print" nil "/D:" "\\\\printers\\lps_06a") + ;; (lps_06b "print" nil nil "\\\\printers\\lps_06b") + ;; (lps_07c "print" nil "" "/D:\\\\printers\\lps_07c") + ;; (lps_08c nil nil nil "\\\\printers\\lps_08c") + ;; (LPT1 "" nil "" "LPT1:") + ;; (PRN "" nil "" "PRN") + ;; (standard "redpr.exe" nil "" "") + ;; ) + "*Specify an alist for all PostScript printers (PostScript printer database). + +The alist element has the form: + + (SYMBOL COMMAND SWITCHES PRINTER-SWITCH NAME DEFAULT...) + +Where: + +SYMBOL It's a symbol to identify a PostScript printer. It's for + `pr-ps-name' variable setting and for menu selection. + Examples: + 'prt_06a + 'my_printer + +COMMAND Name of program for printing a PostScript file. On MS-DOS and + MS-Windows systems, if the value is an empty string then Emacs + will write directly to the printer port named by NAME (see text + below), that is, the NAME should be something like \"PRN\" or + \"LPT1:\". + If NAME is something like \"\\\\\\\\host\\\\share-name\" then + COMMAND shouldn't be an empty string. + The programs `print' and `nprint' (the standard print programs + on Windows NT and Novell Netware respectively) are handled + specially, using NAME as the destination for output; any other + program is treated like `lpr' except that an explicit filename + is given as the last argument. + If COMMAND is nil, it's used the default printing program: + `print' for Windows system, `lp' for lp system and `lpr' for + all other systems. See also `pr-path-alist'. + Examples: + \"print\" + \"lpr\" + \"lp\" + \"cp\" + +SWITCHES List of sexp's to pass as extra options for PostScript printer + program. It is recommended to set NAME (see text below) + instead of including an explicit switch on this list. + Example: + . for lpr + '(\"-#3\" \"-l\") + nil + +PRINTER-SWITCH A string that specifies PostScript printer name switch. If + it's necessary to have a space between PRINTER-SWITCH and NAME, + it should be inserted at the end of PRINTER-SWITCH string. + If PRINTER-SWITCH is nil, it's used the default printer name + switch: `/D:' for Windows system, `-d' for lp system and `-P' + for all other systems. + Examples: + . for lpr + \"-P \" + + . for lp + \"-d \" + + . for print.exe + \"/D:\" + +NAME A string that specifies a PostScript printer name. + On Unix-like systems, a string value should be a name + understood by lpr's -P option (or lp's -d option). + On MS-DOS and MS-Windows systems, it is the name of a printer + device or port. Typical non-default settings would be \"LPT1:\" + to \"LPT3:\" for parallel printers, or \"COM1\" to \"COM4\" or + \"AUX\" for serial printers, or \"\\\\\\\\hostname\\\\printer\" + (or \"/D:\\\\\\\\hostname\\\\printer\") for a shared network + printer. You can also set it to a name of a file, in which + case the output gets appended to that file. If you want to + discard the printed output, set this to \"NUL\". + Examples: + . for cp.exe + \"\\\\\\\\host\\\\share-name\" + + . for print.exe + \"/D:\\\\\\\\host\\\\share-name\" + \"\\\\\\\\host\\\\share-name\" + \"LPT1:\" + \"PRN\" + + . for lpr or lp + \"share-name\" + +DEFAULT It's a way to set default values when this entry is selected. + It's a cons like: + + (VARIABLE . VALUE) + + That associates VARIABLE with VALUE. when this entry is + selected, it's executed the following command: + + (set VARIABLE (eval VALUE)) + + Note that VALUE can be any valid lisp expression. So, don't + forget to quote symbols and constant lists. + If VARIABLE is the special keyword `inherits-from:', VALUE must + be a symbol name setting defined in `pr-setting-database' from + which the current setting inherits the context. Take care with + circular inheritance. + Examples: + '(ps-landscape-mode . nil) + '(ps-spool-duplex . t) + '(pr-gs-device . (my-gs-device t)) + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update PostScript printer menu. + +Examples: + +* On GNU or Unix system: + + '((lps_06b \"lpr\" nil \"-P\" \"lps_06b\") + (lps_07c \"lpr\" nil nil \"lps_07c\") + (lps_08c nil nil nil \"lps_08c\") + ) + +* On Windows system: + + '((lps_06a \"print\" nil \"/D:\" \"\\\\\\\\printers\\\\lps_06a\") + (lps_06b \"print\" nil nil \"\\\\\\\\printers\\\\lps_06b\") + (lps_07c \"print\" nil \"\" \"/D:\\\\\\\\printers\\\\lps_07c\") + (lps_08c nil nil nil \"\\\\\\\\printers\\\\lps_08c\") + (LPT1 \"\" nil \"\" \"LPT1:\") + (PRN \"\" nil \"\" \"PRN\") + (standard \"redpr.exe\" nil \"\" \"\") + )" + :type '(repeat + (list + :tag "PostScript Printer" + (symbol :tag "Printer Symbol Name") + (string :tag "Printer Command") + (repeat :tag "Printer Switches" + (sexp :tag "Switch" :value "")) + (choice :menu-tag "Printer Name Switch" + :tag "Printer Name Switch" + (const :tag "None" nil) + string) + (choice :menu-tag "Printer Name" + :tag "Printer Name" + (const :tag "None" nil) + string) + (repeat + :tag "Default Value List" + :inline t + (cons + :tag "" + (choice + :menu-tag "Variable" + :tag "Variable" + (const :tag "Landscape" ps-landscape-mode) + (const :tag "Print Header" ps-print-header) + (const :tag "Print Header Frame" ps-print-header-frame) + (const :tag "Line Number" ps-line-number) + (const :tag "Zebra Stripes" ps-zebra-stripes) + (const :tag "Duplex" ps-spool-duplex) + (const :tag "Tumble" ps-spool-tumble) + (const :tag "Upside-Down" ps-print-upside-down) + (const :tag "PS File Landscape" pr-file-landscape) + (const :tag "PS File Duplex" pr-file-duplex) + (const :tag "PS File Tumble" pr-file-tumble) + (const :tag "Auto Region" pr-auto-region) + (const :tag "Auto Mode" pr-auto-mode) + (const :tag "Ghostscript Device" pr-gs-device) + (const :tag "Ghostscript Resolution" pr-gs-resolution) + (const :tag "inherits-from:" inherits-from:) + (variable :tag "Other")) + (sexp :tag "Value"))) + )) + :set 'pr-alist-custom-set + :group 'printing) + + +(defcustom pr-temp-dir + (pr-dosify-path + (if (boundp 'temporary-file-directory) + (symbol-value 'temporary-file-directory) + ;; hacked from `temporary-file-directory' variable in files.el + (file-name-as-directory + (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") + (cond (ps-windows-system "c:/temp") + ((memq system-type '(vax-vms axp-vms)) "SYS$SCRATCH:") + (t "/tmp") + ))))) + "*Specify a directory for temporary files during printing." + :type '(directory :tag "Temporary Directory") + :group 'printing) + + +(defcustom pr-ps-temp-file "prspool.ps" + "*Specify PostScript temporary file name." + :type '(file :tag "PostScript Temporary File Name") + :group 'printing) + + +(defcustom pr-gv-command + (if ps-windows-system + "gsview32.exe" + "gv") + "*Specify path and name of gsview program. + +See also `pr-path-alist'." + :type '(string :tag "Ghostview Program") + :group 'printing) + + +(defcustom pr-gs-command + (if ps-windows-system + "gswin32.exe" + "gs") + "*Specify path and name of ghostscript program. + +See also `pr-path-alist'." + :type '(string :tag "Ghostscript Program") + :group 'printing) + + +(defcustom pr-gs-switches + (if ps-windows-system + '("-q -dNOPAUSE -Ic:/gs/gs5.50;c:/gs/gs5.50/fonts") + '("-q -dNOPAUSE -I/usr/share/ghostscript/5.10")) + "*Specify ghostscript switches. See the documentation on GS for more info. + +It's a list of strings, where each string is one or more ghostscript switches. + +A note on the gs switches: + +-q quiet +-dNOPAUSE don't wait for user intervention +-Ic:/gs/gs5.50;c:/gs/gs5.50/fonts the directories needed for gs +-c quit it's added at the end to terminate gs + +To see ghostscript documentation for more information: + +* On GNU or Unix system: + - for full documentation, type: man gs + - for brief documentation, type: gs -h + +* On Windows system: + - for full documentation, see in a browser the file + c:/gstools/gs5.50/index.html, that is, the file index.html which is + located in the same directory as gswin32.exe. + - for brief documentation, type: gswin32.exe -h" + :type '(repeat (string :tag "Ghostscript Switch")) + :group 'printing) + + +(defcustom pr-gs-device + (if ps-windows-system + "mswinpr2" + "uniprint") + "*Specify ghostscript device switch value (-sDEVICE=). + +A note on the gs switches: + +-sDEVICE=djet500 the printer - works with HP DeskJet 540 + +See `pr-gs-switches' for documentation. +See also `pr-ps-printer-alist'." + :type '(string :tag "Ghostscript Device") + :group 'printing) + + +(defcustom pr-gs-resolution 300 + "*Specify ghostscript resolution switch value (-r). + +A note on the gs switches: + +-r300 resolution 300x300 + +See `pr-gs-switches' for documentation. +See also `pr-ps-printer-alist'." + :type '(integer :tag "Ghostscript Resolution") + :group 'printing) + + +(defcustom pr-print-using-ghostscript nil + "*Non-nil means print using ghostscript. + +This is useful if you don't have a PostScript printer, so you could use the +ghostscript to print a PostScript file. + +In GNU or Unix system, if ghostscript is set as a PostScript filter, this +variable should be nil." + :type 'boolean + :group 'printing) + + +(defcustom pr-faces-p nil + "*Non-nil means print with face attributes." + :type 'boolean + :group 'printing) + + +(defcustom pr-spool-p nil + "*Non-nil means spool printing in a buffer." + :type 'boolean + :group 'printing) + + +(defcustom pr-file-landscape nil + "*Non-nil means print PostScript file in landscape orientation." + :type 'boolean + :group 'printing) + + +(defcustom pr-file-duplex nil + "*Non-nil means print PostScript file in duplex mode." + :type 'boolean + :group 'printing) + + +(defcustom pr-file-tumble nil + "*Non-nil means print PostScript file in tumble mode. + +If tumble is off, produces a printing suitable for binding on the left or +right. +If tumble is on, produces a printing suitable for binding at the top or +bottom." + :type 'boolean + :group 'printing) + + +(defcustom pr-auto-region t + "*Non-nil means region is automagically detected. + +Note that this will only work if you're using transient mark mode. + +When this variable is non-nil, the `*-buffer*' commands will behave like +`*-region*' commands, that is, `*-buffer*' commands will print only the region +marked instead of all buffer." + :type 'boolean + :group 'printing) + + +(defcustom pr-auto-mode t + "*Non-nil means major-mode printing is prefered over normal printing. + +That is, if current major-mode is declared in `pr-mode-alist', the `*-buffer*' +and `*-region*' commands will behave like `*-mode*' commands; otherwise, +`*-buffer*' commands will print the current buffer and `*-region*' commands +will print the current region." + :type 'boolean + :group 'printing) + + +(defcustom pr-mode-alist + '((mh-folder-mode ; mh summary buffer + pr-mh-lpr-1 pr-mh-print-1 + 2 + (ps-article-author ps-article-subject) + ("/pagenumberstring load" pr-article-date) + nil + ) + (mh-letter-mode ; mh letter buffer + pr-mh-lpr-2 pr-mh-print-2 + 2 + (ps-article-author ps-article-subject) + ("/pagenumberstring load" pr-article-date) + nil + ) + (rmail-summary-mode ; rmail summary buffer + pr-rmail-lpr pr-rmail-print + 3 + (ps-article-subject ps-article-author buffer-name) + nil + nil + ) + (rmail-mode ; rmail buffer + pr-rmail-lpr pr-rmail-print + 3 + (ps-article-subject ps-article-author buffer-name) + nil + nil + ) + (gnus-summary-mode ; gnus summary buffer + pr-gnus-lpr pr-gnus-print + 3 + (ps-article-subject ps-article-author gnus-newsgroup-name) + nil + nil + ) + (gnus-article-mode ; gnus article buffer + pr-gnus-lpr pr-gnus-print + 3 + (ps-article-subject ps-article-author gnus-newsgroup-name) + nil + nil + ) + (Info-mode ; Info buffer + pr-mode-lpr pr-mode-print + 2 + (ps-info-node ps-info-file) + nil + nil + ) + (vm-mode ; vm mode + pr-vm-lpr pr-vm-print + 3 + (ps-article-subject ps-article-author buffer-name) + nil + nil + ) + ) + "*Specify an alist for a major-mode and printing functions. + +To customize a major mode printing, just declare the customization in +`pr-mode-alist' and invoke some of `*-mode*' commands. An example for major +mode usage is when you're using gnus (or mh, or rmail, etc.) and you're in the +*Summary* buffer, if you forget to switch to the *Article* buffer before +printing, you'll get a nicely formatted list of article subjects shows up at +the printer. With major mode printing you don't need to switch from gnus +*Summary* buffer first. + +The elements have the following form: + + (MAJOR-MODE + LPR-PRINT PS-PRINT + HEADER-LINES + LEFT-HEADER + RIGHT-HEADER + KILL-LOCAL-VARIABLE + DEFAULT...) + +Where: + +MAJOR-MODE It's the major mode symbol. + +LPR-PRINT It's a symbol function for text printing. It's invoked with + one argument: + (HEADER-LINES LEFT-HEADER RIGHT-HEADER DEFAULT...). + + Usually LPR-PRINT function prepares the environment or buffer + and then call the function `pr-mode-lpr' which it's used to + process the buffer and send it to text printer. + + The `pr-mode-lpr' definition is: + + (pr-mode-lpr HEADER-LIST &optional FROM TO) + + Where HEADER-LIST is like the argument passed to LPR-PRINT. + FROM and TO are the beginning and end markers, respectively, + for a region. If FROM is nil, it's used (point-min); if TO is + nil, it's used (point-max). + +PS-PRINT It's a symbol function for PostScript printing. It's invoked + with 3 arguments: n-up printing, file name and the list: + (HEADER-LINES LEFT-HEADER RIGHT-HEADER DEFAULT...). + + Usually PS-PRINT function prepares the environment or buffer + and then call the function `pr-mode-print' which it's used to + process the buffer and send it to PostScript printer. + + The `pr-mode-print' definition is: + + (pr-mode-print N-UP FILENAME HEADER-LIST &optional FROM TO) + + Where N-UP, FILENAME and HEADER-LIST are like the arguments + passed to PS-PRINT. FROM and TO are the beginning and end + markers, respectively, for a region. If TO is nil, it's used + (point-max). + +HEADER-LINES It's the number of header lines; if is nil, it uses + `ps-header-lines' value. + +LEFT-HEADER It's the left header part, it's a list of string, variable + symbol or function symbol (with no argument); if is nil, it + uses `ps-left-header' value. + +RIGHT-HEADER It's the right header part, it's a list of string, variable + symbol or function symbol (with no argument); if is nil, it + uses `ps-right-header' value. + +KILL-LOCAL-VARIABLE + Non-nil means to kill all buffer local variable declared in + DEFAULT (see below). + +DEFAULT It's a way to set default values when this entry is selected. + It's a cons like: + + (VARIABLE-SYM . VALUE) + + That associates VARIABLE-SYM with VALUE. when this entry is + selected, it's executed the following command: + + (set (make-local-variable VARIABLE-SYM) (eval VALUE)) + + Note that VALUE can be any valid lisp expression. So, don't + forget to quote symbols and constant lists. + If VARIABLE is the special keyword `inherits-from:', VALUE must + be a symbol name setting defined in `pr-setting-database' from + which the current setting inherits the context. Take care with + circular inheritance. + Examples: + '(ps-landscape-mode . nil) + '(ps-spool-duplex . t) + '(pr-gs-device . (my-gs-device t))" + :type '(repeat + (list + :tag "" + (symbol :tag "Major Mode") + (function :tag "Text Printing Function") + (function :tag "PS Printing Function") + (choice :menu-tag "Number of Header Lines" + :tag "Number of Header Lines" + (integer :tag "Number") + (const :tag "Default Number" nil)) + (repeat :tag "Left Header List" + (choice :menu-tag "Left Header" + :tag "Left Header" + string symbol)) + (repeat :tag "Right Header List" + (choice :menu-tag "Right Header" + :tag "Right Header" + string symbol)) + (boolean :tag "Kill Local Variable At End") + (repeat + :tag "Default Value List" + :inline t + (cons + :tag "" + (choice + :menu-tag "Variable" + :tag "Variable" + (const :tag "Landscape" ps-landscape-mode) + (const :tag "Print Header" ps-print-header) + (const :tag "Print Header Frame" ps-print-header-frame) + (const :tag "Line Number" ps-line-number) + (const :tag "Zebra Stripes" ps-zebra-stripes) + (const :tag "Duplex" ps-spool-duplex) + (const :tag "Tumble" ps-spool-tumble) + (const :tag "Upside-Down" ps-print-upside-down) + (const :tag "PS File Landscape" pr-file-landscape) + (const :tag "PS File Duplex" pr-file-duplex) + (const :tag "PS File Tumble" pr-file-tumble) + (const :tag "Auto Region" pr-auto-region) + (const :tag "Auto Mode" pr-auto-mode) + (const :tag "Ghostscript Device" pr-gs-device) + (const :tag "Ghostscript Resolution" pr-gs-resolution) + (const :tag "inherits-from:" inherits-from:) + (variable :tag "Other")) + (sexp :tag "Value"))) + )) + :group 'printing) + + +(defcustom pr-ps-utility 'mpage + "*Specify PostScript utility symbol. + +This utility symbol should be defined on `pr-ps-utility-alist' (see it for +documentation). + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update PostScript utility menu. + +NOTE: Don't forget to download and install the utilities declared on + `pr-ps-utility-alist'." + :type '(symbol :tag "PS File Utility") + :set 'pr-ps-utility-custom-set + :group 'printing) + + +(defcustom pr-ps-utility-alist + '((mpage "mpage" nil "-b%s" "-%d" "-l" "-t" "-T" ">" nil) + (psnup "psnup" ("-q") "-P%s" "-%d" "-l" nil nil " " nil + (inherits-from: . no-duplex)) + ) + ;; Examples: + ;; * On GNU or Unix system: + ;; '((mpage "mpage" nil "-b%s" "-%d" "-l" "-t" "-T" ">" nil) + ;; (psnup "psnup" ("-q") "-P%s" "-%d" "-l" nil nil " " nil + ;; (pr-file-duplex . nil) (pr-file-tumble . nil)) + ;; ) + ;; * On Windows system: + ;; '((psnup "c:/psutils/psnup" ("-q") "-P%s" "-%d" "-l" nil nil " " nil + ;; (pr-file-duplex . nil) (pr-file-tumble . nil)) + ;; ) + "*Specify an alist for PostScript utility processing (PS utility database). + +The alist element has the form: + + (SYMBOL UTILITY MUST-SWITCHES PAPERSIZE N-UP LANDSCAPE DUPLEX TUMBLE OUTPUT + SWITCHES DEFAULT...) + +Where: + +SYMBOL It's a symbol to identify a PostScript utility. It's for + `pr-ps-utility' variable setting and for menu selection. + Examples: + 'mpage + 'psnup + +UTILITY Name of utility for processing a PostScript file. + See also `pr-path-alist'. + Examples: + . for GNU or Unix system: + \"mpage\" + \"psnup -q\" + + . for Windows system: + \"c:/psutils/psnup -q\" + +MUST-SWITCHES List of sexp's to pass as options for PostScript utility + program. These options are necessary to process the utility + program and must be place before any other switches. + Example: + . for psnup: + '(\"-q\") + +PAPERSIZE It's a format string to specify paper size switch. + Example: + . for mpage + \"-b%s\" + +N-UP It's a format string to specify n-up switch. + Example: + . for psnup + \"-%d\" + +LANDSCAPE It's a string to specify landscape switch. If the utility + doesn't have landscape switch, set to nil. + Example: + . for psnup + \"-l\" + +DUPLEX It's a string to specify duplex switch. If the utility doesn't + have duplex switch, set to nil. + Example: + . for psnup + nil + +TUMBLE It's a string to specify tumble switch. If the utility doesn't + have tumble switch, set to nil. + Example: + . for psnup + nil + +OUTPUT It's a string to specify how to generate an output file. Some + utilities accept an output file option, but some others need + output redirection or some other way to specify an output file. + Example: + . for psnup + \" \" ; psnup ... input output + + . for mpage + \">\" ; mpage ... input > output + +SWITCHES List of sexp's to pass as extra options for PostScript utility + program. + Example: + . for psnup + '(\"-q\") + nil + +DEFAULT It's a way to set default values when this entry is selected. + It's a cons like: + + (VARIABLE . VALUE) + + That associates VARIABLE with VALUE. when this entry is + selected, it's executed the following command: + + (set VARIABLE (eval VALUE)) + + Note that VALUE can be any valid lisp expression. So, don't + forget to quote symbols and constant lists. + If VARIABLE is the special keyword `inherits-from:', VALUE must + be a symbol name setting defined in `pr-setting-database' from + which the current setting inherits the context. Take care with + circular inheritance. + Examples: + '(pr-file-landscape . nil) + '(pr-file-duplex . t) + '(pr-gs-device . (my-gs-device t)) + +This variable should be modified by customization engine. If this variable is +modified by other means (for example, a lisp function), use `pr-update-menus' +function (see it for documentation) to update PostScript utility menu. + +NOTE: Don't forget to download and install the utilities declared on + `pr-ps-utility-alist'. + +Examples: + +* On GNU or Unix system: + + '((mpage \"mpage\" nil \"-b%s\" \"-%d\" \"-l\" \"-t\" \"-T\" \">\" nil) + (psnup \"psnup\" (\"-q\") \"-P%s\" \"-%d\" \"-l\" nil nil \" \" nil + (pr-file-duplex . nil) (pr-file-tumble . nil)) + ) + +* On Windows system: + + '((psnup \"c:/psutils/psnup\" (\"-q\") \"-P%s\" \"-%d\" \"-l\" nil nil \" \" + nil (pr-file-duplex . nil) (pr-file-tumble . nil)) + )" + :type '(repeat + (list :tag "PS File Utility" + (symbol :tag "Utility Symbol") + (string :tag "Utility Name") + (repeat :tag "Must Utility Switches" + (sexp :tag "Switch" :value "")) + (choice :menu-tag "Paper Size" + :tag "Paper Size" + (const :tag "No Paper Size" nil) + (string :tag "Paper Size Format")) + (choice :menu-tag "N-Up" + :tag "N-Up" + (const :tag "No N-Up" nil) + (string :tag "N-Up Format")) + (choice :menu-tag "Landscape" + :tag "Landscape" + (const :tag "No Landscape" nil) + (string :tag "Landscape Switch")) + (choice :menu-tag "Duplex" + :tag "Duplex" + (const :tag "No Duplex" nil) + (string :tag "Duplex Switch")) + (choice :menu-tag "Tumble" + :tag "Tumble" + (const :tag "No Tumble" nil) + (string :tag "Tumble Switch")) + (string :tag "Output Separator") + (repeat :tag "Utility Switches" + (sexp :tag "Switch" :value "")) + (repeat + :tag "Default Value List" + :inline t + (cons + :tag "" + (choice + :menu-tag "Variable" + :tag "Variable" + (const :tag "PS File Landscape" pr-file-landscape) + (const :tag "PS File Duplex" pr-file-duplex) + (const :tag "PS File Tumble" pr-file-tumble) + (const :tag "Ghostscript Device" pr-gs-device) + (const :tag "Ghostscript Resolution" pr-gs-resolution) + (const :tag "inherits-from:" inherits-from:) + (variable :tag "Other")) + (sexp :tag "Value"))) + )) + :set 'pr-alist-custom-set + :group 'printing) + + +(defcustom pr-menu-lock t + "*Non-nil means menu is locked while selecting toggle options. + +See also `pr-menu-char-height' and `pr-menu-char-width'." + :type 'boolean + :group 'printing) + + +(defcustom pr-menu-char-height + (cond ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + (pr-e-frame-char-height)) + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + (pr-x-font-height (face-font 'default)))) + "*Specify menu char height in pixels. + +This variable is used to guess which vertical position should be locked the +menu, so don't forget to adjust it if menu position is not ok. + +See also `pr-menu-lock' and `pr-menu-char-width'." + :type 'integer + :group 'printing) + + +(defcustom pr-menu-char-width + (cond ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + (pr-e-frame-char-width)) + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + (pr-x-font-width (face-font 'default)))) + "*Specify menu char width in pixels. + +This variable is used to guess which horizontal position should be locked the +menu, so don't forget to adjust it if menu position is not ok. + +See also `pr-menu-lock' and `pr-menu-char-height'." + :type 'integer + :group 'printing) + + +(defcustom pr-setting-database + '((no-duplex ; setting symbol name + nil nil nil ; inherits local kill-local + (pr-file-duplex . nil) ; settings + (pr-file-tumble . nil)) + ) + "*Specify an alist for settings in general. + +The elements have the following form: + + (SYMBOL INHERITS LOCAL KILL-LOCAL SETTING...) + +Where: + +SYMBOL It's a symbol to identify the setting group. + +INHERITS Specify the inheritance for SYMBOL group. It's a symbol name + setting from which the current setting inherits the context. + If INHERITS is nil, means that there is no inheritance. + This is a simple inheritance mechanism. + + Let's see an example to illustrate the inheritance mechanism: + + (setq pr-setting-database + '((no-duplex ; setting symbol name + nil ; inherits + nil nil ; local kill-local + (pr-file-duplex . nil) ; settings + (pr-file-tumble . nil) + ) + (no-duplex-and-landscape ; setting symbol name + no-duplex ; inherits + nil nil ; local kill-local + (pr-file-landscape . nil) ; settings + ))) + + The example above has two setting groups: no-duplex and + no-duplex-and-landscape. When setting no-duplex is activated + through `inherits-from:' (see `pr-ps-utility', `pr-mode-alist' + and `pr-ps-printer-alist'), the variables pr-file-duplex and + pr-file-tumble are both set to nil. + + Now when setting no-duplex-and-landscape is activated through + `inherits-from:', the variable pr-file-landscape is set to nil + and also the settings for no-duplex are done, because + no-duplex-and-landscape inherits settings from no-duplex. + + Take care with circular inheritance. It's an error if circular + inheritance happens. + +LOCAL Non-nil means that all settings for SYMBOL group will be + declared local buffer. + +KILL-LOCAL Non-nil means that all settings for SYMBOL group will be + killed at end. It has effect only when LOCAL is non-nil. + +SETTING It's a cons like: + + (VARIABLE . VALUE) + + That associates VARIABLE with VALUE. when this entry is + selected, it's executed the following command: + + * If LOCAL is non-nil: + (set (make-local-variable VARIABLE) (eval VALUE)) + + * If LOCAL is nil: + (set VARIABLE (eval VALUE)) + + Note that VALUE can be any valid lisp expression. So, don't + forget to quote symbols and constant lists. + This setting is ignored if VARIABLE is equal to keyword + `inherits-from:'. + Examples: + '(ps-landscape-mode . nil) + '(ps-spool-duplex . t) + '(pr-gs-device . (my-gs-device t))" + :type '(repeat + (list + :tag "" + (symbol :tag "Setting Name") + (choice :menu-tag "Inheritance" + :tag "Inheritance" + (const :tag "No Inheritance" nil) + (symbol :tag "Inherits From")) + (boolean :tag "Local Buffer Setting") + (boolean :tag "Kill Local Variable At End") + (repeat + :tag "Setting List" + :inline t + (cons + :tag "" + (choice + :menu-tag "Variable" + :tag "Variable" + (const :tag "Landscape" ps-landscape-mode) + (const :tag "Print Header" ps-print-header) + (const :tag "Print Header Frame" ps-print-header-frame) + (const :tag "Line Number" ps-line-number) + (const :tag "Zebra Stripes" ps-zebra-stripes) + (const :tag "Duplex" ps-spool-duplex) + (const :tag "Tumble" ps-spool-tumble) + (const :tag "Upside-Down" ps-print-upside-down) + (const :tag "PS File Landscape" pr-file-landscape) + (const :tag "PS File Duplex" pr-file-duplex) + (const :tag "PS File Tumble" pr-file-tumble) + (const :tag "Auto Region" pr-auto-region) + (const :tag "Auto Mode" pr-auto-mode) + (const :tag "Ghostscript Device" pr-gs-device) + (const :tag "Ghostscript Resolution" pr-gs-resolution) + (variable :tag "Other")) + (sexp :tag "Value"))) + )) + :group 'printing) + + +(defcustom pr-visible-entry-list + '(postscript text postscript-options postscript-process printing help) + "*Specify a list of Printing menu visible entries. + +Valid values with the corresponding menu parts are: + + +------------------------------+ + | Printing Interface | + +------------------------------+ + `postscript' | PostScript Preview >| + | PostScript Print >| + | PostScript Printer: name >| + +------------------------------+ + `text' | Printify >| + | Print >| + | Text Printer: name >| + +------------------------------+ + `postscript-options' |[ ] Landscape | + |[ ] Print Header | + |[ ] Print Header Frame | + |[ ] Line Number | + |[ ] Zebra Stripes | + |[ ] Duplex | + |[ ] Tumble | + |[ ] Upside-Down | + | Print All Pages >| + +------------------------------+ + `postscript-process' |[ ] Spool Buffer | + |[ ] Print with-faces | + |[ ] Print Using Ghostscript | + +------------------------------+ + `printing' |[ ] Auto Region | + |[ ] Auto Mode | + |[ ] Menu Lock | + +------------------------------+ + `help' | Customize >| + | Show Settings >| + | Help | + +------------------------------+ + +Any other value is ignored." + :type '(repeat :tag "Menu Visible Part" + (choice :menu-tag "Menu Part" + :tag "Menu Part" + (const postscript) + (const text) + (const postscript-options) + (const postscript-process) + (const printing) + (const help))) + :group 'printing) + + +(defcustom pr-delete-temp-file t + "*Non-nil means delete temporary files. + +Set `pr-delete-temp-file' to nil, if the following message (or a similar) +happens when printing: + + Error: could not open \"c:\\temp\\prspool.ps\" for reading." + :type 'boolean + :group 'printing) + + +(defcustom pr-list-directory nil + "*Non-nil means list directory when processing a directory. + +That is, any subdirectories (and the superdirectory) of the directory (given as +argument of functions below) are also printed (as dired-mode listings). + +It's used by `pr-ps-directory-preview', `pr-ps-directory-using-ghostscript', +`pr-ps-directory-print', `pr-ps-directory-ps-print', `pr-printify-directory' +and `pr-txt-directory'." + :type 'boolean + :group 'printing) + + +(defcustom pr-buffer-name "*Printing Interface*" + "*Specify the name of the buffer interface for printing package. + +It's used by `pr-interface'." + :type 'string + :group 'printing) + + +(defcustom pr-buffer-name-ignore + (list (regexp-quote pr-buffer-name) ; ignore printing interface buffer + "^ .*$") ; ignore invisible buffers + "*Specify a regexp list for buffer names to be ignored in interface buffer. + +NOTE: Case is important for matching, that is, `case-fold-search' is always + nil. + +It's used by `pr-interface'." + :type '(repeat (regexp :tag "Buffer Name Regexp")) + :group 'printing) + + +(defcustom pr-buffer-verbose t + "*Non-nil means to be verbose when editing a field in interface buffer. + +It's used by `pr-interface'." + :type 'boolean + :group 'printing) + + +(defcustom pr-shell-file-name + (if (eq pr-path-style 'windows) + "cmdproxy.exe" + shell-file-name) + "*Specify file name to load inferior shells from." + :type 'string + :group 'printing) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Internal Variables + + +(defvar pr-txt-command nil + "Name of program for printing a text file. +See `pr-txt-printer-alist'.") + + +(defvar pr-txt-switches nil + "List of sexp's to pass as extra options for text printer program. +See `pr-txt-printer-alist'.") + + +(defvar pr-txt-printer nil + "Specify text printer name. +See `pr-txt-printer-alist'.") + + +(defvar pr-ps-command nil + "Name of program for printing a PostScript file. +See `pr-ps-printer-alist'.") + + +(defvar pr-ps-switches nil + "List of sexp's to pass as extra options for PostScript printer program. +See `pr-ps-printer-alist'.") + + +(defvar pr-ps-printer-switch nil + "Specify PostScript printer name switch. +See `pr-ps-printer-alist'.") + + +(defvar pr-ps-printer nil + "Specify PostScript printer name. +See `pr-ps-printer-alist'.") + + +(defvar pr-menu-bar nil + "Specify Printing menu-bar entry.") + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Keys & Menus + + +(defmacro pr-xemacs-global-menubar (&rest body) + `(save-excursion + (let ((temp (get-buffer-create (make-temp-name " *Temp")))) + ;; be sure to access global menubar + (set-buffer temp) + ,@body + (kill-buffer temp)))) + + +(defun pr-get-symbol (name) + ;; Recent versions of easy-menu downcase names before interning them. + (and (fboundp 'easy-menu-name-match) + (setq name (downcase name))) + (or (intern-soft name) + (make-symbol name))) + + +(defsubst pr-visible-p (key) + (memq key pr-visible-entry-list)) + + +(defsubst pr-mode-alist-p () + (cdr (assq major-mode pr-mode-alist))) + + +(defsubst pr-auto-mode-p () + (and pr-auto-mode (pr-mode-alist-p))) + + +(defsubst pr-using-ghostscript-p () + (and pr-print-using-ghostscript (not pr-spool-p))) + + +(eval-and-compile + (cond + ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + (defsubst pr-region-active-p () + (and pr-auto-region transient-mark-mode mark-active))) + + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + (defsubst pr-region-active-p () + (and pr-auto-region (not zmacs-region-stays) (ps-mark-active-p))))) + + + (defconst pr-menu-spec + (cond + ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + '( + ["Printing Interface" pr-interface + :help "Use buffer interface instead of menu interface"] + "--" + ("PostScript Preview" :visible (pr-visible-p 'postscript) + :help "Preview PostScript instead of sending to printer" + ("Directory" :active (not pr-spool-p) + ["1-up" (pr-ps-directory-preview 1 nil nil t) t] + ["2-up" (pr-ps-directory-preview 2 nil nil t) t] + ["4-up" (pr-ps-directory-preview 4 nil nil t) t] + ["Other..." (pr-ps-directory-preview nil nil nil t) + :keys "\\[pr-ps-buffer-preview]"]) + ("Buffer" :active (not pr-spool-p) + ["1-up" (pr-ps-buffer-preview 1 t) t] + ["2-up" (pr-ps-buffer-preview 2 t) t] + ["4-up" (pr-ps-buffer-preview 4 t) t] + ["Other..." (pr-ps-buffer-preview nil t) + :keys "\\[pr-ps-buffer-preview]"]) + ("Region" :active (and (not pr-spool-p) (ps-mark-active-p)) + ["1-up" (pr-ps-region-preview 1 t) t] + ["2-up" (pr-ps-region-preview 2 t) t] + ["4-up" (pr-ps-region-preview 4 t) t] + ["Other..." (pr-ps-region-preview nil t) + :keys "\\[pr-ps-region-preview]"]) + ("Mode" :active (and (not pr-spool-p) (pr-mode-alist-p)) + ["1-up" (pr-ps-mode-preview 1 t) t] + ["2-up" (pr-ps-mode-preview 2 t) t] + ["4-up" (pr-ps-mode-preview 4 t) t] + ["Other..." (pr-ps-mode-preview nil t) + :keys "\\[pr-ps-mode-preview]"]) + ("File" + ["As Is..." (call-interactively 'pr-ps-file-preview) + :keys "\\[pr-ps-file-preview]" + :help "Preview PostScript file"] + "--" + ["PostScript Utility" pr-update-menus :active pr-ps-utility-alist + :help "Select PostScript utility"] + "--" + ["1-up..." (pr-ps-file-up-preview 1 t t) pr-ps-utility-alist] + ["2-up..." (pr-ps-file-up-preview 2 t t) pr-ps-utility-alist] + ["4-up..." (pr-ps-file-up-preview 4 t t) pr-ps-utility-alist] + ["Other..." (pr-ps-file-up-preview nil t t) + :keys "\\[pr-ps-file-up-preview]" :active pr-ps-utility-alist] + "--" + ["Landscape" pr-toggle-file-landscape + :style toggle :selected pr-file-landscape + :help "Toggle landscape for PostScript file" + :active pr-ps-utility-alist] + ["Duplex" pr-toggle-file-duplex + :style toggle :selected pr-file-duplex + :help "Toggle duplex for PostScript file" + :active pr-ps-utility-alist] + ["Tumble" pr-toggle-file-tumble + :style toggle :selected pr-file-tumble + :help "Toggle tumble for PostScript file" + :active (and pr-file-duplex pr-ps-utility-alist)]) + ["Despool..." (call-interactively 'pr-despool-preview) + :active pr-spool-p :keys "\\[pr-despool-preview]" + :help "Despool PostScript buffer to printer or file (C-u)"]) + ("PostScript Print" :visible (pr-visible-p 'postscript) + :help "Send PostScript to printer or file (C-u)" + ("Directory" + ["1-up" (pr-ps-directory-ps-print 1 nil nil t) t] + ["2-up" (pr-ps-directory-ps-print 2 nil nil t) t] + ["4-up" (pr-ps-directory-ps-print 4 nil nil t) t] + ["Other..." (pr-ps-directory-ps-print nil nil nil t) + :keys "\\[pr-ps-buffer-ps-print]"]) + ("Buffer" + ["1-up" (pr-ps-buffer-ps-print 1 t) t] + ["2-up" (pr-ps-buffer-ps-print 2 t) t] + ["4-up" (pr-ps-buffer-ps-print 4 t) t] + ["Other..." (pr-ps-buffer-ps-print nil t) + :keys "\\[pr-ps-buffer-ps-print]"]) + ("Region" :active (ps-mark-active-p) + ["1-up" (pr-ps-region-ps-print 1 t) t] + ["2-up" (pr-ps-region-ps-print 2 t) t] + ["4-up" (pr-ps-region-ps-print 4 t) t] + ["Other..." (pr-ps-region-ps-print nil t) + :keys "\\[pr-ps-region-ps-print]"]) + ("Mode" :active (pr-mode-alist-p) + ["1-up" (pr-ps-mode-ps-print 1 t) t] + ["2-up" (pr-ps-mode-ps-print 2 t) t] + ["4-up" (pr-ps-mode-ps-print 4 t) t] + ["Other..." (pr-ps-mode-ps-print nil t) + :keys "\\[pr-ps-mode-ps-print]"]) + ("File" + ["As Is..." (call-interactively 'pr-ps-file-ps-print) + :keys "\\[pr-ps-file-ps-print]" + :help "Send PostScript file to printer"] + "--" + ["PostScript Utility" pr-update-menus :active pr-ps-utility-alist + :help "Select PostScript utility"] + "--" + ["1-up..." (pr-ps-file-up-ps-print 1 t t) pr-ps-utility-alist] + ["2-up..." (pr-ps-file-up-ps-print 2 t t) pr-ps-utility-alist] + ["4-up..." (pr-ps-file-up-ps-print 4 t t) pr-ps-utility-alist] + ["Other..." (pr-ps-file-up-ps-print nil t t) + :keys "\\[pr-ps-file-up-ps-print]" :active pr-ps-utility-alist] + "--" + ["Landscape" pr-toggle-file-landscape + :style toggle :selected pr-file-landscape + :help "Toggle landscape for PostScript file" + :active pr-ps-utility-alist] + ["Duplex" pr-toggle-file-duplex + :style toggle :selected pr-file-duplex + :help "Toggle duplex for PostScript file" + :active pr-ps-utility-alist] + ["Tumble" pr-toggle-file-tumble + :style toggle :selected pr-file-tumble + :help "Toggle tumble for PostScript file" + :active (and pr-file-duplex pr-ps-utility-alist)]) + ["Despool..." (call-interactively 'pr-despool-ps-print) + :active pr-spool-p :keys "\\[pr-despool-ps-print]" + :help "Despool PostScript buffer to printer or file (C-u)"]) + ["PostScript Printers" pr-update-menus + :active pr-ps-printer-alist :included (pr-visible-p 'postscript) + :help "Select PostScript printer"] + "--" + ("Printify" :visible (pr-visible-p 'text) + :help "Replace non-printing chars with printable representations." + ["Directory" pr-printify-directory t] + ["Buffer" pr-printify-buffer t] + ["Region" pr-printify-region (ps-mark-active-p)]) + ("Print" :visible (pr-visible-p 'text) + :help "Send text to printer" + ["Directory" pr-txt-directory t] + ["Buffer" pr-txt-buffer t] + ["Region" pr-txt-region (ps-mark-active-p)] + ["Mode" pr-txt-mode (pr-mode-alist-p)]) + ["Text Printers" pr-update-menus + :active pr-txt-printer-alist :included (pr-visible-p 'text) + :help "Select text printer"] + "--" + ["Landscape" pr-toggle-landscape + :style toggle :selected ps-landscape-mode + :included (pr-visible-p 'postscript-options)] + ["Print Header" pr-toggle-header + :style toggle :selected ps-print-header + :included (pr-visible-p 'postscript-options)] + ["Print Header Frame" pr-toggle-header-frame + :style toggle :selected ps-print-header-frame :active ps-print-header + :included (pr-visible-p 'postscript-options)] + ["Line Number" pr-toggle-line + :style toggle :selected ps-line-number + :included (pr-visible-p 'postscript-options)] + ["Zebra Stripes" pr-toggle-zebra + :style toggle :selected ps-zebra-stripes + :included (pr-visible-p 'postscript-options)] + ["Duplex" pr-toggle-duplex + :style toggle :selected ps-spool-duplex + :included (pr-visible-p 'postscript-options)] + ["Tumble" pr-toggle-tumble + :style toggle :selected ps-spool-tumble :active ps-spool-duplex + :included (pr-visible-p 'postscript-options)] + ["Upside-Down" pr-toggle-upside-down + :style toggle :selected ps-print-upside-down + :included (pr-visible-p 'postscript-options)] + ("Print All Pages" :visible (pr-visible-p 'postscript-options) + :help "Select odd/even pages/sheets to print" + ["All Pages" (pr-even-or-odd-pages nil) + :style radio :selected (eq ps-even-or-odd-pages nil)] + ["Even Pages" (pr-even-or-odd-pages 'even-page) + :style radio :selected (eq ps-even-or-odd-pages 'even-page)] + ["Odd Pages" (pr-even-or-odd-pages 'odd-page) + :style radio :selected (eq ps-even-or-odd-pages 'odd-page)] + ["Even Sheets" (pr-even-or-odd-pages 'even-sheet) + :style radio :selected (eq ps-even-or-odd-pages 'even-sheet)] + ["Odd Sheets" (pr-even-or-odd-pages 'odd-sheet) + :style radio :selected (eq ps-even-or-odd-pages 'odd-sheet)]) + "--" + ["Spool Buffer" pr-toggle-spool + :style toggle :selected pr-spool-p + :included (pr-visible-p 'postscript-process) + :help "Toggle PostScript spooling"] + ["Print with-faces" pr-toggle-faces + :style toggle :selected pr-faces-p + :included (pr-visible-p 'postscript-process) + :help "Toggle PostScript printing with faces"] + ["Print Using Ghostscript" pr-toggle-ghostscript + :style toggle :selected pr-print-using-ghostscript + :included (pr-visible-p 'postscript-process) + :help "Toggle PostScript generation using ghostscript"] + "--" + ["Auto Region" pr-toggle-region + :style toggle :selected pr-auto-region + :included (pr-visible-p 'printing)] + ["Auto Mode" pr-toggle-mode + :style toggle :selected pr-auto-mode + :included (pr-visible-p 'printing)] + ["Menu Lock" pr-toggle-lock + :style toggle :selected pr-menu-lock + :included (pr-visible-p 'printing)] + "--" + ("Customize" :visible (pr-visible-p 'help) + ["printing" pr-customize t] + ["ps-print" ps-print-customize t] + ["lpr" lpr-customize t]) + ("Show Settings" :visible (pr-visible-p 'help) + ["printing" pr-show-pr-setup t] + ["ps-print" pr-show-ps-setup t] + ["lpr" pr-show-lpr-setup t]) + ["Help" pr-help :active t :included (pr-visible-p 'help)] + )) + + + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + ;; Menu mapping: + ;; unfortunately XEmacs doesn't support :active or :visible + ;; for submenus, only for items. + ;; It uses :included instead of :active or :visible. + ;; Also, XEmacs doesn't support :help tag. + '( + ["Printing Interface" pr-interface] + "--" + ("PostScript Preview" :included (pr-visible-p 'postscript) + ("Directory" :included (not pr-spool-p) + ["1-up" (pr-ps-directory-preview 1 nil nil t) t] + ["2-up" (pr-ps-directory-preview 2 nil nil t) t] + ["4-up" (pr-ps-directory-preview 4 nil nil t) t] + ["Other..." (pr-ps-directory-preview nil nil nil t) + :keys "\\[pr-ps-buffer-preview]"]) + ("Buffer" :included (not pr-spool-p) + ["1-up" (pr-ps-buffer-preview 1 t) t] + ["2-up" (pr-ps-buffer-preview 2 t) t] + ["4-up" (pr-ps-buffer-preview 4 t) t] + ["Other..." (pr-ps-buffer-preview nil t) + :keys "\\[pr-ps-buffer-preview]"]) + ("Region" :included (and (not pr-spool-p) (ps-mark-active-p)) + ["1-up" (pr-ps-region-preview 1 t) t] + ["2-up" (pr-ps-region-preview 2 t) t] + ["4-up" (pr-ps-region-preview 4 t) t] + ["Other..." (pr-ps-region-preview nil t) + :keys "\\[pr-ps-region-preview]"]) + ("Mode" :included (and (not pr-spool-p) (pr-mode-alist-p)) + ["1-up" (pr-ps-mode-preview 1 t) t] + ["2-up" (pr-ps-mode-preview 2 t) t] + ["4-up" (pr-ps-mode-preview 4 t) t] + ["Other..." (pr-ps-mode-preview nil t) + :keys "\\[pr-ps-mode-preview]"]) + ("File" + ["As Is..." (call-interactively 'pr-ps-file-preview) + :keys "\\[pr-ps-file-preview]"] + "--" + ["PostScript Utility" pr-update-menus :active pr-ps-utility-alist] + "--" + ["1-up..." (pr-ps-file-up-preview 1 t t) pr-ps-utility-alist] + ["2-up..." (pr-ps-file-up-preview 2 t t) pr-ps-utility-alist] + ["4-up..." (pr-ps-file-up-preview 4 t t) pr-ps-utility-alist] + ["Other..." (pr-ps-file-up-preview nil t t) + :keys "\\[pr-ps-file-up-preview]" :active pr-ps-utility-alist] + "--" + ["Landscape" pr-toggle-file-landscape + :style toggle :selected pr-file-landscape + :active pr-ps-utility-alist] + ["Duplex" pr-toggle-file-duplex + :style toggle :selected pr-file-duplex + :active pr-ps-utility-alist] + ["Tumble" pr-toggle-file-tumble + :style toggle :selected pr-file-tumble + :active (and pr-file-duplex pr-ps-utility-alist)]) + ["Despool..." (call-interactively 'pr-despool-preview) + :active pr-spool-p :keys "\\[pr-despool-preview]"]) + ("PostScript Print" :included (pr-visible-p 'postscript) + ("Directory" + ["1-up" (pr-ps-directory-ps-print 1 nil nil t) t] + ["2-up" (pr-ps-directory-ps-print 2 nil nil t) t] + ["4-up" (pr-ps-directory-ps-print 4 nil nil t) t] + ["Other..." (pr-ps-directory-ps-print nil nil nil t) + :keys "\\[pr-ps-buffer-ps-print]"]) + ("Buffer" + ["1-up" (pr-ps-buffer-ps-print 1 t) t] + ["2-up" (pr-ps-buffer-ps-print 2 t) t] + ["4-up" (pr-ps-buffer-ps-print 4 t) t] + ["Other..." (pr-ps-buffer-ps-print nil t) + :keys "\\[pr-ps-buffer-ps-print]"]) + ("Region" :included (ps-mark-active-p) + ["1-up" (pr-ps-region-ps-print 1 t) t] + ["2-up" (pr-ps-region-ps-print 2 t) t] + ["4-up" (pr-ps-region-ps-print 4 t) t] + ["Other..." (pr-ps-region-ps-print nil t) + :keys "\\[pr-ps-region-ps-print]"]) + ("Mode" :included (pr-mode-alist-p) + ["1-up" (pr-ps-mode-ps-print 1 t) t] + ["2-up" (pr-ps-mode-ps-print 2 t) t] + ["4-up" (pr-ps-mode-ps-print 4 t) t] + ["Other..." (pr-ps-mode-ps-print nil t) + :keys "\\[pr-ps-mode-ps-print]"]) + ("File" + ["As Is..." (call-interactively 'pr-ps-file-ps-print) + :keys "\\[pr-ps-file-ps-print]"] + "--" + ["PostScript Utility" pr-update-menus :active pr-ps-utility-alist] + "--" + ["1-up..." (pr-ps-file-up-ps-print 1 t t) pr-ps-utility-alist] + ["2-up..." (pr-ps-file-up-ps-print 2 t t) pr-ps-utility-alist] + ["4-up..." (pr-ps-file-up-ps-print 4 t t) pr-ps-utility-alist] + ["Other..." (pr-ps-file-up-ps-print nil t t) + :keys "\\[pr-ps-file-up-ps-print]" :active pr-ps-utility-alist] + "--" + ["Landscape" pr-toggle-file-landscape + :style toggle :selected pr-file-landscape + :active pr-ps-utility-alist] + ["Duplex" pr-toggle-file-duplex + :style toggle :selected pr-file-duplex + :active pr-ps-utility-alist] + ["Tumble" pr-toggle-file-tumble + :style toggle :selected pr-file-tumble + :active (and pr-file-duplex pr-ps-utility-alist)]) + ["Despool..." (call-interactively 'pr-despool-ps-print) + :active pr-spool-p :keys "\\[pr-despool-ps-print]"]) + ["PostScript Printers" pr-update-menus + :active pr-ps-printer-alist :included (pr-visible-p 'postscript)] + "--" + ("Printify" :included (pr-visible-p 'text) + ["Directory" pr-printify-directory t] + ["Buffer" pr-printify-buffer t] + ["Region" pr-printify-region (ps-mark-active-p)]) + ("Print" :included (pr-visible-p 'text) + ["Directory" pr-txt-directory t] + ["Buffer" pr-txt-buffer t] + ["Region" pr-txt-region (ps-mark-active-p)] + ["Mode" pr-txt-mode (pr-mode-alist-p)]) + ["Text Printers" pr-update-menus + :active pr-txt-printer-alist :included (pr-visible-p 'text)] + "--" + ["Landscape" pr-toggle-landscape + :style toggle :selected ps-landscape-mode + :included (pr-visible-p 'postscript-options)] + ["Print Header" pr-toggle-header + :style toggle :selected ps-print-header + :included (pr-visible-p 'postscript-options)] + ["Print Header Frame" pr-toggle-header-frame + :style toggle :selected ps-print-header-frame :active ps-print-header + :included (pr-visible-p 'postscript-options)] + ["Line Number" pr-toggle-line + :style toggle :selected ps-line-number + :included (pr-visible-p 'postscript-options)] + ["Zebra Stripes" pr-toggle-zebra + :style toggle :selected ps-zebra-stripes + :included (pr-visible-p 'postscript-options)] + ["Duplex" pr-toggle-duplex + :style toggle :selected ps-spool-duplex + :included (pr-visible-p 'postscript-options)] + ["Tumble" pr-toggle-tumble + :style toggle :selected ps-spool-tumble :active ps-spool-duplex + :included (pr-visible-p 'postscript-options)] + ["Upside-Down" pr-toggle-upside-down + :style toggle :selected ps-print-upside-down + :included (pr-visible-p 'postscript-options)] + ("Print All Pages" :included (pr-visible-p 'postscript-options) + ["All Pages" (pr-even-or-odd-pages nil) + :style radio :selected (eq ps-even-or-odd-pages nil)] + ["Even Pages" (pr-even-or-odd-pages 'even-page) + :style radio :selected (eq ps-even-or-odd-pages 'even-page)] + ["Odd Pages" (pr-even-or-odd-pages 'odd-page) + :style radio :selected (eq ps-even-or-odd-pages 'odd-page)] + ["Even Sheets" (pr-even-or-odd-pages 'even-sheet) + :style radio :selected (eq ps-even-or-odd-pages 'even-sheet)] + ["Odd Sheets" (pr-even-or-odd-pages 'odd-sheet) + :style radio :selected (eq ps-even-or-odd-pages 'odd-sheet)]) + "--" + ["Spool Buffer" pr-toggle-spool + :style toggle :selected pr-spool-p + :included (pr-visible-p 'postscript-process)] + ["Print with-faces" pr-toggle-faces + :style toggle :selected pr-faces-p + :included (pr-visible-p 'postscript-process)] + ["Print Using Ghostscript" pr-toggle-ghostscript + :style toggle :selected pr-print-using-ghostscript + :included (pr-visible-p 'postscript-process)] + "--" + ["Auto Region" pr-toggle-region + :style toggle :selected pr-auto-region + :included (pr-visible-p 'printing)] + ["Auto Mode" pr-toggle-mode + :style toggle :selected pr-auto-mode + :included (pr-visible-p 'printing)] + ["Menu Lock" pr-toggle-lock + :style toggle :selected pr-menu-lock + :included (pr-visible-p 'printing)] + "--" + ("Customize" :included (pr-visible-p 'help) + ["printing" pr-customize t] + ["ps-print" ps-print-customize t] + ["lpr" lpr-customize t]) + ("Show Settings" :included (pr-visible-p 'help) + ["printing" pr-show-pr-setup t] + ["ps-print" pr-show-ps-setup t] + ["lpr" pr-show-lpr-setup t]) + ["Help" pr-help :active t :included (pr-visible-p 'help)] + )) + )) + + + (cond + ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + ;; Menu binding + (require 'easymenu) + ;; Replace existing "print" item by "Printing" item. + ;; If you're changing this file, you'll load it a second, + ;; third... time, but "print" item exists only in the first load. + (defvar pr-menu-print-item "print") + (cond + ;; Emacs 20 + ((string< emacs-version "21.") + (easy-menu-change '("tools") "Printing" pr-menu-spec pr-menu-print-item) + (when pr-menu-print-item + (easy-menu-remove-item nil '("tools") pr-menu-print-item) + (setq pr-menu-print-item nil + pr-menu-bar (vector 'menu-bar 'tools + (pr-get-symbol "Printing"))))) + ;; Emacs 21 + (pr-menu-print-item + (easy-menu-change '("files") "Print" pr-menu-spec "print-buffer") + (let ((items '("print-buffer" "print-region" + "ps-print-buffer-faces" "ps-print-region-faces" + "ps-print-buffer" "ps-print-region"))) + (while items + (easy-menu-remove-item nil '("files") (car items)) + (setq items (cdr items))) + (setq pr-menu-print-item nil + pr-menu-bar (vector 'menu-bar 'files + (pr-get-symbol "Print"))))) + (t + (easy-menu-change '("files") "Print" pr-menu-spec))) + + ;; Key binding + (global-set-key [print] 'pr-ps-fast-fire) + (global-set-key [M-print] 'pr-ps-mode-using-ghostscript) + (global-set-key [C-print] 'pr-txt-fast-fire)) + + + ((eq ps-print-emacs-type 'xemacs) ; XEmacs + ;; Menu binding + (pr-xemacs-global-menubar + (pr-x-add-submenu nil (cons "Printing" pr-menu-spec) "Apps")) + + ;; Key binding + (global-set-key 'f22 'pr-ps-fast-fire) + (global-set-key '(meta f22) 'pr-ps-mode-using-ghostscript) + (global-set-key '(control f22) 'pr-txt-fast-fire)))) + + +;;; You can also use something like: +;;;(global-set-key "\C-ci" 'pr-interface) +;;;(global-set-key "\C-cbp" 'pr-ps-buffer-print) +;;;(global-set-key "\C-cbx" 'pr-ps-buffer-preview) +;;;(global-set-key "\C-cbb" 'pr-ps-buffer-using-ghostscript) +;;;(global-set-key "\C-crp" 'pr-ps-region-print) +;;;(global-set-key "\C-crx" 'pr-ps-region-preview) +;;;(global-set-key "\C-crr" 'pr-ps-region-using-ghostscript) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Help Message + + +(defconst pr-help-message + (concat "printing.el version " pr-version + " ps-print.el version " ps-print-version + "\n\n +Menu Layout +----------- + +The `printing' menu (Tools/Printing or File/Print) has the following layout: + + +-----------------------------+ +A 0 | Printing Interface | + +-----------------------------+ +-A---------+ +-B------+ +I 1 | PostScript Preview >|-------|Directory >|-----|1-up | + 2 | PostScript Print >|---- A |Buffer >|-- B |2-up | + 3 | PostScript Printer: name >|---- C |Region >|-- B |4-up | + +-----------------------------+ |Mode >|-- B |Other...| +II 4 | Printify >|-----\\ |File >|--\\ +--------+ + 5 | Print >|---\\ | |Despool... | | + 6 | Text Printer: name >|-\\ | | +-----------+ | + +-----------------------------+ | | | +---------+ +------------+ +III 7 |[ ]Landscape | | | \\-|Directory| | As Is... | Ia + 8 |[ ]Print Header | | | |Buffer | +------------+ Ib + 9 |[ ]Print Header Frame | | | |Region | | name >|- C + 10 |[ ]Line Number | | | +---------+ +------------+ + 11 |[ ]Zebra Stripes | | | +---------+ | 1-up... | Ic + 12 |[ ]Duplex | | \\---|Directory| | 2-up... | + 13 |[ ]Tumble | \\--\\ |Buffer | | 4-up... | + 14 |[ ]Upside-Down | | |Region | | Other... | + 15 | Print All Pages >|--\\ | |Mode | +------------+ + +-----------------------------+ | | +---------+ |[ ]Landscape| Id +IV 16 |[ ]Spool Buffer | | | +-C-------+ |[ ]Duplex | Ie + 17 |[ ]Print with-faces | | \\--|( )name A| |[ ]Tumble | If + 18 |[ ]Print Using Ghostscript | | |( )name B| +------------+ + +-----------------------------+ | |... | +V 19 |[ ]Auto Region | | |(*)name | + 20 |[ ]Auto Mode | | |... | + 21 |[ ]Menu Lock | | +---------+ +--------------+ + +-----------------------------+ \\------------------|(*)All Pages | +VI 22 | Customize >|--- D +-D------+ |( )Even Pages | + 23 | Show Settings >|-------|printing| |( )Odd Pages | + 24 | Help | |ps-print| |( )Even Sheets| + +-----------------------------+ |lpr | |( )Odd Sheets | + +--------+ +--------------+ + +See `pr-visible-entry-list' for hiding some parts of the menu. + +The menu has the following sections: + +A. Interface: + + 0. You can use a buffer interface instead of menus. It looks like the + customization buffer. Basically, it has the same options found in the + menu and some extra options, all this on a buffer. + +I. PostScript printing: + + 1. You can generate a PostScript file (if you type C-u before activating + menu) or PostScript temporary file for a directory, a buffer, a region + or a major mode, choosing 1-up, 2-up, 4-up or any other n-up printing; + after file generation, ghostview is activated using the file generated + as argument. This option is disabled if spooling is on (option 16). + Also, if you already have a PostScript file you can preview it. + Instead of previewing each buffer, region or major mode at once, you + can save temporarily the PostScript code generated in a buffer and + preview it later. The option `Despool...' despools the PostScript + spooling buffer in a temporary file and uses ghostview to preview it. + If you type C-u before choosing this option, the PostScript code + generated is saved in a file instead of saving in a temporary file. To + spool the PostScript code generated you need to turn on the option 16. + The option `Despool...' is enabled if spooling is on (option 16). + + NOTE 1: It's possible to customize a major mode printing, just declare + the customization in `pr-mode-alist' and invoke some of + `*-mode*' commands or select Mode option in Printing menu. An + example for major mode usage is when you're using gnus (or mh, + or rmail, etc.) and you're in the *Summary* buffer, if you + forget to switch to the *Article* buffer before printing, + you'll get a nicely formatted list of article subjects shows + up at the printer. With major mode printing you don't need to + switch from gnus *Summary* buffer first. + + NOTE 2: There are the following options for PostScript file processing: + Ia. Print the file *as is*, that is, send it directly to + PostScript printer. + Ib. PostScript utility processing selection. + See `pr-ps-utility-alist' and `pr-setting-database' for + documentation. + Ic. Do n-up processing before printing. + Id. Toggle on/off landscape for PostScript file processing. + Ie. Toggle on/off duplex for PostScript file processing. + If. Toggle on/off tumble for PostScript file processing. + + NOTE 3: Don't forget to download and install the utilities declared on + `pr-ps-utility-alist'. + + 2. Operate the same way as option 1, but it sends directly the PostScript + code (or put in a file, if you've typed C-u) or it uses ghostscript to + print the PostScript file generated. It depends on option 18, if it's + turned on, it uses ghostscript; otherwise, it sends directly to + printer. If spooling is on (option 16), the PostScript code is saved + temporarily in a buffer instead of printing it or saving it in a file. + Also, if you already have a PostScript file you can print it. + Instead of printing each buffer, region or major mode at once, you can + save temporarily the PostScript code generated in a buffer and print it + later. The option `Despool...' despools the PostScript spooling buffer + directly on a printer. If you type C-u before choosing this option, + the PostScript code generated is saved in a file instead of sending to + printer. To spool the PostScript code generated you need to turn on + the option 16. This option is enabled if spooling is on (option 16). + See also the NOTE 1, NOTE 2 and NOTE 3 on option 1. + + 3. You can select a new PostScript printer to send PostScript code + generated. For selection it's used all PostScript printers defined + in `pr-ps-printer-alist' variable (see it for documentation). + See also `pr-setting-database'. + +II. Text printing: + + 4. If you have control characters (character code from \\000 to \\037) in a + buffer and you want to print them in a text printer, select this + option. All control characters in your buffer or region will be + replaced by a printable representation. The printable representations + use ^ (for ASCII control characters) or hex. The characters tab, + linefeed, space, return and formfeed are not affected. + You don't need to select this option if you use any option of section + I, the PostScript engine treats control characters properly. + + 5. If you want to print a directory, buffer, region or major mode in a + text printer, select this option. See also the NOTE 1 on option 1. + + 6. You can select a new text printer to send text generated. For + selection it's used all text printers defined in `pr-txt-printer-alist' + variable (see it for documentation). + See also `pr-setting-database'. + +III. PostScript page toggle options: + + 7. If you want a PostScript landscape printing, turn on this option. + + 8. If you want to have a header in each page in your PostScript code, + turn on this option. + + 9. If you want to draw a gaudy frame around the header, turn on this + option. This option is enabled if print header is on (option 8). + + 10. If you want that the line number is printed in your PostScript code, + turn on this option. + + 11. If you want background zebra stripes in your PostScript code, turn on + this option. + + 12. If you want a duplex printing and your PostScript printer has this + feature, turn on this option. + + 13. If you turned on duplex printing, you can choose if you want to have a + printing suitable for binding on the left or right (tumble off), or to + have a printing suitable for binding at top or bottom (tumble on). + This option is enabled if duplex is on (option 12). + + 14. If you want a PostScript upside-down printing, turn on this option. + + 15. With this option, you can choose if you want to print all pages, odd + pages, even pages, odd sheets or even sheets. + See also `ps-even-or-odd-pages'. + +IV. PostScript processing toggle options: + + 16. If you want to spool the PostScript code generated, turn on this + option. To spool the PostScript code generated use option 2. You can + despool later by choosing option 1 or 2, sub-option `Despool...'. + + 17. If you use colors in your buffers and want to see these colors on your + PostScript code generated, turn on this option. If you have a + black/white PostScript printer, these colors are displayed in gray + scale by PostScript printer interpreter. + + 18. If you don't have a PostScript printer to send PostScript files, turn + on this option. When this option is on, the ghostscript is used to + print PostScript files. In GNU or Unix system, if ghostscript is set + as a PostScript filter, you don't need to turn on this option. + +V. Printing customization: + + 19. If you want that region is automagically detected, turn on this + option. Note that this will only work if you're using transient mark + mode. When this option is on, the `*-buffer*' commands will behave + like `*-region*' commands, that is, `*-buffer*' commands will print + only the region marked instead of all buffer. + + 20. Turn this option on if you want that when current major-mode is + declared in `pr-mode-alist', the `*-buffer*' and `*-region*' commands + behave like `*-mode*' commands. + + 21. If you want that Printing menu stays poped while you are setting + toggle options, turn on this option. The variables + `pr-menu-char-height' and `pr-menu-char-width' are used to guess the + menu position, so don't forget to adjust these variables if menu + position is not ok. + +VI. Customization: + + 22. Besides all options in section III, IV and V, you can customize much + more PostScript options in `ps-print' option. Or you can customize + some `lpr' options for text printing. Or customize `printing' + options. + + 23. Show current settings for `printing', `ps-print' or `lpr'. + + 24. Quick help for printing menu layout. +") + "Printing help message.") + + +(defconst pr-interface-help-message + (concat "printing.el version " pr-version + " ps-print.el version " ps-print-version + "\n\n +The printing interface buffer has the same functionality as the printing menu. +The major difference is that the states (like sending PostScript generated to a +file, n-up printing, etc.) are set and saved between priting buffer +activation. Also, the landscape, duplex and tumble values are the same for +PostScript file and directory/buffer/region/mode processing; using menu, there +are different value sets for PostScript file and directory/buffer/region/mode +processing. + +The printing interface buffer has the following sections: + +1. Print: + + Here you can choose to print/preview a buffer, a directory or a PostScript + file: + + 1a. Buffer: + + * Buffer List: + Select a buffer from the current buffer list. + + * Region: + If it's on, this means that the selected buffer has an active region, + so you can turn on/off, as you wish. + If it's off when a buffer is selected, this means that the selected + buffer has no active region, so it'll not be possible to turn it on. + If you want to process the region, let this option on. + If you want to process the whole buffer, let this option off. + + * Mode: + If it's on, this means that the selected buffer major mode is declared + for major mode processing, so you can turn on/off, as you wish. + If it's off when a buffer is selected, this means that the selected + buffer major mode isn't declared for major mode processing, so it'll + not be possible to turn it on. + If you want the major mode processing, let this option on. + If you don't want the major mode processing, let this option off. + + NOTE 1: It's possible to customize a major mode printing, just declare + the customization in `pr-mode-alist' and invoke some of + `*-mode*' commands or select Mode option in Printing menu. An + example for major mode usage is when you're using gnus (or mh, + or rmail, etc.) and you're in the *Summary* buffer, if you + forget to switch to the *Article* buffer before printing, + you'll get a nicely formatted list of article subjects shows + up at the printer. With major mode printing you don't need to + switch from gnus *Summary* buffer first. + + 1b. Directory: + + * Directory: + Specify a valid directory path. + + * File Regexp: + Specify a file name regexp. All file names in the directory that + match with regexp will be printed/previewed. An empty file name + regexp means to print/preview all files in the directory. + + * List Directory Entry: + If it's turned on, list directory entries besides file entries. + + 1c. PostScript file: + + * PostScript File: + Specify an existent PostScript file to print/preview. + + * PostScript Utility: + Select a PostScript utility. + See `pr-ps-utility-alist' and `pr-setting-database' for documentation. + + NOTE 2: Don't forget to download and install the utilities declared on + `pr-ps-utility-alist'. + + * Use It AS-IS : + If it's turned on, don't use the PostScript utility to preprocess the + PostScript file before printing/previewing. + +2. PostScript printer: + + * PostScript Printer: + You can select a new PostScript printer to send PostScript code + generated. For selection it's used all PostScript printers defined + in `pr-ps-printer-alist' variable (see it for documentation). + See also `pr-setting-database'. + + * Despool: + If spooling is on, you can turn it on/off, as you wish. + If spooling is off, it'll not be possible to turn it on. + If it's turned on, specify to despools the PostScript spooling buffer in + a temporary file or in the selected PostScript file when + printing/previewing. + + * Preview: + Preview the PostScript generated. + + * Print: + Print the PostScript generated. + + * Quit: + Quit from printing interface buffer. + + * Send to Printer/Temporary File: + If it's turned on, the PostScript generated is sent directly to + PostScript printer or, for previewing, to a temporary file. + + * Send to File: + Specify a file name to send the PostScript generated. + + * N-Up: + Specify n-up printing. + +3. Text printer: + + * Text Printer: + Select a new text printer to send text generated. For selection it's used + all text printers defined in `pr-txt-printer-alist' variable (see it for + documentation). See also `pr-setting-database'. + + * Printify: + If you have control characters (character code from \\000 to \\037) in a + buffer and you want to print them in a text printer, select this + option. All control characters in your buffer or region will be + replaced by a printable representation. The printable representations + use ^ (for ASCII control characters) or hex. The characters tab, + linefeed, space, return and formfeed are not affected. + You don't need to select this option if you use any option of section + I, the PostScript engine treats control characters properly. + + * Print: + To print a directory, buffer, region or major mode in a + text printer, select this option. See also the NOTE 1 on section 1. + + * Quit: + Quit from printing interface buffer. + +4. Settings: + + There are 3 setting columns: + + 4a. First column (left column): + + * Landscape: + PostScript landscape printing. + + * Print Header: + To have a header in each page in your PostScript code. + + * Print Header Frame: + To draw a gaudy frame around the header. + + * Line Number: + The line number is printed in your PostScript code. + + * Zebra Stripes: + Background zebra stripes in your PostScript code. + + * Duplex: + Duplex printing (if your PostScript printer has this feature). + + * Tumble: + If duplex printing is on, you can choose if you want to have a + printing suitable for binding on the left or right (tumble off), or to + have a printing suitable for binding at top or bottom (tumble on). + + * Upside-Down: + PostScript upside-down printing. + + 4b. Second column (middle column): + + * Auto Region: + If you want that region is automagically detected, turn on this + option. Note that this will only work if you're using transient mark + mode. When this option is on, the `*-buffer*' commands will behave + like `*-region*' commands, that is, `*-buffer*' commands will print + only the region marked instead of all buffer. + + * Auto Mode: + Turn this option on if you want that when current major-mode is + declared in `pr-mode-alist', the `*-buffer*' and `*-region*' commands + behave like `*-mode*' commands. + + * Menu Lock: + If you want that Printing menu stays poped while you are setting + toggle options, turn on this option. The variables + `pr-menu-char-height' and `pr-menu-char-width' are used to guess the + menu position, so don't forget to adjust these variables if menu + position is not ok. + + * Spool Buffer: + To spool the PostScript code generated. You can despool later by + setting Despool option on PostScript printer section. + + * Print with-faces: + If you use colors in your buffers and want to see these colors on your + PostScript code generated, turn on this option. If you have a + black/white PostScript printer, these colors are displayed in gray + scale by PostScript printer interpreter. + + * Print Using Ghostscript: + If you don't have a PostScript printer to send PostScript files, turn + on this option. When this option is on, the ghostscript is used to + print PostScript files. In GNU or Unix system, if ghostscript is set + as a PostScript filter, you don't need to turn on this option. + + * Parity Page Menu: + To print all pages, odd pages, even pages, odd sheets or even sheets. + See also `ps-even-or-odd-pages'. + + 4c. Third column (right column): + + * Verbose: + That is, to be verbose when editing a field in interface buffer. + +5. Customize: + + Besides all options in section 4, you can customize much more PostScript + options in `ps-print' option. Or you can customize some `lpr' options for + text printing. Or customize `printing' options. + +6. Show settings: + + Show current settings for `printing', `ps-print' or `lpr'. + +7. Help: + + Quick help for printing interface buffer and printing menu layout. You can + also quit the printing interface buffer or kill all printing help buffer. +") + "Printing buffer interface help message.") + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Commands + + +;;;###autoload +(defun pr-interface (&optional buffer) + "Activate the printing interface buffer. + +If BUFFER is nil, it uses the current buffer for printing. + +For more informations, type \\[pr-interface-help]." + (interactive) + (save-excursion + (set-buffer (or buffer (current-buffer))) + (pr-create-interface))) + + +;;;###autoload +(defun pr-ps-directory-preview (n-up dir file-regexp &optional filename) + "Preview directory using ghostview. + +Interactively, the command prompts for N-UP printing number, a directory, a +file name regexp for matching and, when you use a prefix argument (C-u), the +command prompts the user for a file name, and saves the PostScript image in +that file instead of saving it in a temporary file. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. If DIR is +nil, prompts for DIRectory. If FILE-REGEXP is nil, prompts for +FILE(name)-REGEXP. The argument FILENAME is treated as follows: if it's nil, +save the image in a temporary file. If FILENAME is a string, save the +PostScript image in a file with that name. If FILENAME is t, prompts for a +file name. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-ps-dir-args (pr-prompt "PS preview dir"))) + (pr-set-ps-dir-args 'n-up 'dir 'file-regexp 'filename + (pr-prompt "PS preview dir")) + (setq filename (pr-ps-file filename)) + (pr-ps-file-list n-up dir file-regexp filename) + (or pr-spool-p + (pr-ps-file-preview filename))) + + +;;;###autoload +(defun pr-ps-directory-using-ghostscript (n-up dir file-regexp &optional filename) + "Print directory using PostScript through ghostscript. + +Interactively, the command prompts for N-UP printing number, a directory, a +file name regexp for matching and, when you use a prefix argument (C-u), the +command prompts the user for a file name, and saves the PostScript image in +that file instead of saving it in a temporary file. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. If DIR is +nil, prompts for DIRectory. If FILE-REGEXP is nil, prompts for +FILE(name)-REGEXP. The argument FILENAME is treated as follows: if it's nil, +save the image in a temporary file. If FILENAME is a string, save the +PostScript image in a file with that name. If FILENAME is t, prompts for a +file name. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-ps-dir-args (pr-prompt "PS print dir GS"))) + (pr-set-ps-dir-args 'n-up 'dir 'file-regexp 'filename + (pr-prompt "PS print dir GS")) + (let ((file (pr-ps-file filename))) + (pr-ps-file-list n-up dir file-regexp file) + (pr-ps-file-using-ghostscript file) + (or filename (pr-delete-file file)))) + + +;;;###autoload +(defun pr-ps-directory-print (n-up dir file-regexp &optional filename) + "Print directory using PostScript printer. + +Interactively, the command prompts for N-UP printing number, a directory, a +file name regexp for matching and, when you use a prefix argument (C-u), the +command prompts the user for a file name, and saves the PostScript image in +that file instead of saving it in a temporary file. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. If DIR is +nil, prompts for DIRectory. If FILE-REGEXP is nil, prompts for +FILE(name)-REGEXP. The argument FILENAME is treated as follows: if it's nil, +save the image in a temporary file. If FILENAME is a string, save the +PostScript image in a file with that name. If FILENAME is t, prompts for a +file name. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-ps-dir-args (pr-prompt "PS print dir"))) + (pr-set-ps-dir-args 'n-up 'dir 'file-regexp 'filename + (pr-prompt "PS print dir")) + (let ((file (pr-ps-file filename))) + (pr-ps-file-list n-up dir file-regexp file) + (pr-ps-file-print file) + (or filename (pr-delete-file file)))) + + +;;;###autoload +(defun pr-ps-directory-ps-print (n-up dir file-regexp &optional filename) + "Print directory using PostScript printer or through ghostscript. + +It depends on `pr-print-using-ghostscript'. + +Interactively, the command prompts for N-UP printing number, a directory, a +file name regexp for matching and, when you use a prefix argument (C-u), the +command prompts the user for a file name, and saves the PostScript image in +that file instead of saving it in a temporary file. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. If DIR is +nil, prompts for DIRectory. If FILE-REGEXP is nil, prompts for +FILE(name)-REGEXP. The argument FILENAME is treated as follows: if it's nil, +save the image in a temporary file. If FILENAME is a string, save the +PostScript image in a file with that name. If FILENAME is t, prompts for a +file name. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-ps-dir-args + (pr-prompt (pr-prompt-gs "PS print dir")))) + (pr-set-ps-dir-args 'n-up 'dir 'file-regexp 'filename + (pr-prompt (pr-prompt-gs "PS print dir"))) + (if (pr-using-ghostscript-p) + (pr-ps-directory-using-ghostscript n-up dir file-regexp filename) + (pr-ps-directory-print n-up dir file-regexp filename))) + + +;;;###autoload +(defun pr-ps-buffer-preview (n-up &optional filename) + "Preview buffer using ghostview. + +Interactively, the command prompts for N-UP printing number and, when you use a +prefix argument (C-u), the command prompts the user for a file name, and saves +the PostScript image in that file instead of saving it in a temporary file. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. The +argument FILENAME is treated as follows: if it's nil, save the image in a +temporary file. If FILENAME is a string, save the PostScript image in a file +with that name. If FILENAME is t, prompts for a file name." + (interactive (pr-interactive-n-up-file (pr-prompt "PS preview"))) + (if (pr-auto-mode-p) + (pr-ps-mode-preview n-up filename) + (pr-ps-preview (pr-region-active-symbol) n-up filename + (pr-region-active-string "PS preview")))) + + +;;;###autoload +(defun pr-ps-buffer-using-ghostscript (n-up &optional filename) + "Print buffer using PostScript through ghostscript. + +Interactively, the command prompts for N-UP printing number and, when you use a +prefix argument (C-u), the command prompts the user for a file name, and saves +the PostScript image in that file instead of sending it to the printer. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. The +argument FILENAME is treated as follows: if it's nil, send the image to the +printer. If FILENAME is a string, save the PostScript image in a file with +that name. If FILENAME is t, prompts for a file name." + (interactive (pr-interactive-n-up-file (pr-prompt "PS print GS"))) + (if (pr-auto-mode-p) + (pr-ps-mode-using-ghostscript n-up filename) + (pr-ps-using-ghostscript (pr-region-active-symbol) n-up filename + (pr-region-active-string "PS print GS")))) + + +;;;###autoload +(defun pr-ps-buffer-print (n-up &optional filename) + "Print buffer using PostScript printer. + +Interactively, the command prompts for N-UP printing number and, when you use a +prefix argument (C-u), the command prompts the user for a file name, and saves +the PostScript image in that file instead of sending it to the printer. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. The +argument FILENAME is treated as follows: if it's nil, send the image to the +printer. If FILENAME is a string, save the PostScript image in a file with +that name. If FILENAME is t, prompts for a file name." + (interactive (pr-interactive-n-up-file (pr-prompt "PS print"))) + (if (pr-auto-mode-p) + (pr-ps-mode-print n-up filename) + (pr-ps-print (pr-region-active-symbol) n-up filename + (pr-region-active-string "PS print")))) + + +;;;###autoload +(defun pr-ps-buffer-ps-print (n-up &optional filename) + "Print buffer using PostScript printer or through ghostscript. + +It depends on `pr-print-using-ghostscript'. + +Interactively, the command prompts for N-UP printing number and, when you use a +prefix argument (C-u), the command prompts the user for a file name, and saves +the PostScript image in that file instead of sending it to the printer. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. The +argument FILENAME is treated as follows: if it's nil, send the image to the +printer. If FILENAME is a string, save the PostScript image in a file with +that name. If FILENAME is t, prompts for a file name." + (interactive (pr-interactive-n-up-file + (pr-prompt (pr-prompt-gs "PS print")))) + (cond ((pr-auto-mode-p) + (pr-ps-mode-ps-print n-up filename)) + ((pr-using-ghostscript-p) + (pr-ps-using-ghostscript (pr-region-active-symbol) n-up filename + (pr-region-active-string "PS print GS"))) + (t + (pr-ps-print (pr-region-active-symbol) n-up filename + (pr-region-active-string "PS print"))))) + + +;;;###autoload +(defun pr-ps-region-preview (n-up &optional filename) + "Preview region using ghostview. + +See also `pr-ps-buffer-preview'." + (interactive (pr-interactive-n-up-file (pr-prompt-region "PS preview"))) + (if (pr-auto-mode-p) + (let ((pr-auto-region t)) + (pr-ps-mode-preview n-up filename)) + (pr-ps-preview 'region n-up filename "PS preview region"))) + + +;;;###autoload +(defun pr-ps-region-using-ghostscript (n-up &optional filename) + "Print region using PostScript through ghostscript. + +See also `pr-ps-buffer-using-ghostscript'." + (interactive (pr-interactive-n-up-file (pr-prompt-region "PS print GS"))) + (if (pr-auto-mode-p) + (let ((pr-auto-region t)) + (pr-ps-mode-using-ghostscript n-up filename)) + (pr-ps-using-ghostscript 'region n-up filename "PS print GS region"))) + + +;;;###autoload +(defun pr-ps-region-print (n-up &optional filename) + "Print region using PostScript printer. + +See also `pr-ps-buffer-print'." + (interactive (pr-interactive-n-up-file (pr-prompt-region "PS print"))) + (if (pr-auto-mode-p) + (let ((pr-auto-region t)) + (pr-ps-mode-print n-up filename)) + (pr-ps-print 'region n-up filename "PS print region"))) + + +;;;###autoload +(defun pr-ps-region-ps-print (n-up &optional filename) + "Print region using PostScript printer or through ghostscript. + +See also `pr-ps-buffer-ps-print'." + (interactive (pr-interactive-n-up-file + (pr-prompt-region (pr-prompt-gs "PS print")))) + (cond ((pr-auto-mode-p) + (let ((pr-auto-region t)) + (pr-ps-mode-ps-print n-up filename))) + ((pr-using-ghostscript-p) + (pr-ps-using-ghostscript 'region n-up filename "PS print GS region")) + (t + (pr-ps-print 'region n-up filename "PS print region")))) + + +;;;###autoload +(defun pr-ps-mode-preview (n-up &optional filename) + "Preview major mode using ghostview. + +See also `pr-ps-buffer-preview'." + (interactive (pr-interactive-n-up-file "PS preview mode")) + (pr-set-n-up-and-filename 'n-up 'filename "PS preview mode") + (let ((file (pr-ps-file filename))) + (and (pr-ps-mode n-up file) + (not pr-spool-p) + (pr-ps-file-preview file)))) + + +;;;###autoload +(defun pr-ps-mode-using-ghostscript (n-up &optional filename) + "Print major mode using PostScript through ghostscript. + +See also `pr-ps-buffer-using-ghostscript'." + (interactive (pr-interactive-n-up-file "PS print GS mode")) + (pr-set-n-up-and-filename 'n-up 'filename "PS print GS mode") + (let ((file (pr-ps-file filename))) + (when (and (pr-ps-mode n-up file) + (not pr-spool-p)) + (pr-ps-file-using-ghostscript file) + (or filename (pr-delete-file file))))) + + +;;;###autoload +(defun pr-ps-mode-print (n-up &optional filename) + "Print major mode using PostScript printer. + +See also `pr-ps-buffer-print'." + (interactive (pr-interactive-n-up-file "PS print mode")) + (pr-set-n-up-and-filename 'n-up 'filename "PS print mode") + (pr-ps-mode n-up filename)) + + +;;;###autoload +(defun pr-ps-mode-ps-print (n-up &optional filename) + "Print major mode using PostScript or through ghostscript. + +See also `pr-ps-buffer-ps-print'." + (interactive (pr-interactive-n-up-file (pr-prompt-gs "PS print mode"))) + (if (pr-using-ghostscript-p) + (pr-ps-mode-using-ghostscript n-up filename) + (pr-ps-mode-print n-up filename))) + + +;;;###autoload +(defun pr-printify-directory (&optional dir file-regexp) + "Replace nonprinting characters in directory with printable representations. +The printable representations use ^ (for ASCII control characters) or hex. +The characters tab, linefeed, space, return and formfeed are not affected. + +Interactively, the command prompts for a directory and a file name regexp for +matching. + +Noninteractively, if DIR is nil, prompts for DIRectory. If FILE-REGEXP is nil, +prompts for FILE(name)-REGEXP. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-dir-args "Printify dir")) + (pr-set-dir-args 'dir 'file-regexp "Printify dir") + (pr-file-list dir file-regexp 'pr-printify-buffer)) + + +;;;###autoload +(defun pr-printify-buffer () + "Replace nonprinting characters in buffer with printable representations. +The printable representations use ^ (for ASCII control characters) or hex. +The characters tab, linefeed, space, return and formfeed are not affected." + (interactive "*") + (if (pr-region-active-p) + (pr-printify-region) + (printify-region (point-min) (point-max)))) + + +;;;###autoload +(defun pr-printify-region () + "Replace nonprinting characters in region with printable representations. +The printable representations use ^ (for ASCII control characters) or hex. +The characters tab, linefeed, space, return and formfeed are not affected." + (interactive "*") + (printify-region (point) (mark))) + + +;;;###autoload +(defun pr-txt-directory (&optional dir file-regexp) + "Print directory using text printer. + +Interactively, the command prompts for a directory and a file name regexp for +matching. + +Noninteractively, if DIR is nil, prompts for DIRectory. If FILE-REGEXP is nil, +prompts for FILE(name)-REGEXP. + +See also documentation for `pr-list-directory'." + (interactive (pr-interactive-dir-args "Print dir")) + (pr-set-dir-args 'dir 'file-regexp "Print dir") + (pr-file-list dir file-regexp 'pr-txt-buffer)) + + +;;;###autoload +(defun pr-txt-buffer () + "Print buffer using text printer." + (interactive) + (cond ((pr-auto-mode-p) + (pr-txt-mode)) + ((pr-region-active-p) + (pr-txt-region)) + (t + (pr-txt-print (point-min) (point-max))))) + + +;;;###autoload +(defun pr-txt-region () + "Print region using text printer." + (interactive) + (if (pr-auto-mode-p) + (let ((pr-auto-region t)) + (pr-txt-mode)) + (pr-txt-print (point) (mark)))) + + +;;;###autoload +(defun pr-txt-mode () + "Print major mode using text printer." + (interactive) + (let ((args (pr-mode-alist-p))) + (if args + (funcall (car args) (nthcdr 2 args)) + (ding) + (message "`%s' major mode not declared." major-mode)))) + + +;;;###autoload +(defun pr-despool-preview (&optional filename) + "Preview spooled PostScript. + +Interactively, when you use a prefix argument (C-u), the command prompts the +user for a file name, and saves the spooled PostScript image in that file +instead of saving it in a temporary file. + +Noninteractively, the argument FILENAME is treated as follows: if it is nil, +save the image in a temporary file. If FILENAME is a string, save the +PostScript image in a file with that name." + (interactive (list (ps-print-preprint current-prefix-arg))) + (let ((file (pr-ps-file filename))) + (when (stringp file) + (pr-despool-print file) + (pr-ps-file-preview file)))) + + +;;;###autoload +(defun pr-despool-using-ghostscript (&optional filename) + "Print spooled PostScript using ghostscript. + +Interactively, when you use a prefix argument (C-u), the command prompts the +user for a file name, and saves the spooled PostScript image in that file +instead of sending it to the printer. + +Noninteractively, the argument FILENAME is treated as follows: if it is nil, +send the image to the printer. If FILENAME is a string, save the PostScript +image in a file with that name." + (interactive (list (ps-print-preprint current-prefix-arg))) + (let ((file (pr-ps-file filename))) + (when (stringp file) + (pr-despool-print file) + (pr-ps-file-using-ghostscript file) + (or filename (pr-delete-file file))))) + + +;;;###autoload +(defun pr-despool-print (&optional filename) + "Send the spooled PostScript to the printer. + +Interactively, when you use a prefix argument (C-u), the command prompts the +user for a file name, and saves the spooled PostScript image in that file +instead of sending it to the printer. + +Noninteractively, the argument FILENAME is treated as follows: if it is nil, +send the image to the printer. If FILENAME is a string, save the PostScript +image in a file with that name." + (interactive (list (ps-print-preprint current-prefix-arg))) + (let ((ps-lpr-command (pr-command pr-ps-command)) + (ps-lpr-switches pr-ps-switches) + (ps-printer-name-option pr-ps-printer-switch) + (ps-printer-name pr-ps-printer)) + (ps-despool filename))) + + +;;;###autoload +(defun pr-despool-ps-print (&optional filename) + "Send the spooled PostScript to the printer or use ghostscript to print it. + +Interactively, when you use a prefix argument (C-u), the command prompts the +user for a file name, and saves the spooled PostScript image in that file +instead of sending it to the printer. + +Noninteractively, the argument FILENAME is treated as follows: if it is nil, +send the image to the printer. If FILENAME is a string, save the PostScript +image in a file with that name." + (interactive (list (ps-print-preprint current-prefix-arg))) + (if pr-print-using-ghostscript + (pr-despool-using-ghostscript filename) + (pr-despool-print filename))) + + +;;;###autoload +(defun pr-ps-file-preview (filename) + "Preview PostScript file FILENAME." + (interactive (list (pr-ps-infile-preprint "Preview "))) + (and (stringp filename) (file-exists-p filename) + (let ((shell-file-name pr-shell-file-name)) + (start-process-shell-command "PREVIEW" "*Messages*" + (pr-command pr-gv-command) filename)))) + + +;;;###autoload +(defun pr-ps-file-up-preview (n-up ifilename &optional ofilename) + "Preview PostScript file FILENAME." + (interactive (pr-interactive-n-up-inout "PS preview")) + (let ((outfile (pr-ps-utility-args 'n-up 'ifilename 'ofilename + "PS preview "))) + (pr-ps-utility-process n-up ifilename outfile) + (pr-ps-file-preview outfile))) + + +;;;###autoload +(defun pr-ps-file-using-ghostscript (filename) + "Print PostScript file FILENAME using ghostscript." + (interactive (list (pr-ps-infile-preprint "Print preview "))) + (and (stringp filename) (file-exists-p filename) + (let* ((file (pr-expand-file-name filename)) + (tempfile (pr-dosify-path (make-temp-name file)))) + ;; gs use + (pr-shell-command + (concat (pr-command pr-gs-command) + " -sDEVICE=" pr-gs-device + " -r" (int-to-string pr-gs-resolution) + " " (pr-switches-string pr-gs-switches "pr-gs-switches") + " -sOutputFile=" tempfile " " file " -c quit")) + ;; printing + (pr-ps-file-print tempfile) + ;; deleting + (pr-delete-file tempfile)))) + + +;;;###autoload +(defun pr-ps-file-print (filename) + "Print PostScript file FILENAME." + (interactive (list (pr-ps-infile-preprint "Print "))) + (and (stringp filename) (file-exists-p filename) + ;; printing + (let ((file (pr-expand-file-name filename))) + (if (string-equal pr-ps-command "") + (let ((ps-spool-buffer (get-buffer-create ps-spool-buffer-name))) + (save-excursion + (set-buffer ps-spool-buffer) + (erase-buffer) + (insert-file-contents-literally file)) + (pr-despool-print)) + (pr-shell-command + (concat (pr-command pr-ps-command) " " + (pr-switches-string pr-ps-switches "pr-gs-switches") " " + (if (string-match "cp" pr-ps-command) + ;; for "cp" (cmd in out) + (concat "\"" file "\" " + pr-ps-printer-switch pr-ps-printer) + ;; else, for others (cmd out in) + (concat pr-ps-printer-switch pr-ps-printer + " \"" file "\"")))))))) + + +;;;###autoload +(defun pr-ps-file-ps-print (filename) + "Send PostScript file FILENAME to printer or use ghostscript to print it." + (interactive (list (pr-ps-infile-preprint + (if pr-print-using-ghostscript + "Print preview " + "Print ")))) + (if pr-print-using-ghostscript + (pr-ps-file-using-ghostscript filename) + (pr-ps-file-print filename))) + + +;;;###autoload +(defun pr-ps-file-up-ps-print (n-up ifilename &optional ofilename) + "Process a PostScript file IFILENAME and send it to printer. + +Interactively, the command prompts for N-UP printing number, for an input +PostScript file IFILENAME and, when you use a prefix argument (C-u), the +command prompts the user for an output PostScript file name OFILENAME, and +saves the PostScript image in that file instead of sending it to the printer. + +Noninteractively, if N-UP is nil, prompts for N-UP printing number. The +argument IFILENAME is treated as follows: if it's t, prompts for an input +PostScript file name; otherwise, it *must* be a string that it's an input +PostScript file name. The argument OFILENAME is treated as follows: if it's +nil, send the image to the printer. If OFILENAME is a string, save the +PostScript image in a file with that name. If OFILENAME is t, prompts for a +file name." + (interactive (pr-interactive-n-up-inout + (if pr-print-using-ghostscript + "PS print GS" + "PS print"))) + (let ((outfile (pr-ps-utility-args 'n-up 'ifilename 'ofilename + (if pr-print-using-ghostscript + "PS print GS " + "PS print ")))) + (pr-ps-utility-process n-up ifilename outfile) + (unless ofilename + (pr-ps-file-ps-print outfile) + (pr-delete-file outfile)))) + + +;;;###autoload +(defun pr-toggle-file-duplex () + "Toggle duplex for PostScript file." + (interactive) + (pr-toggle 'pr-file-duplex "PS file duplex" nil 7 5 nil + '("PostScript Print" "File"))) + + +;;;###autoload +(defun pr-toggle-file-tumble () + "Toggle tumble for PostScript file. + +If tumble is off, produces a printing suitable for binding on the left or +right. +If tumble is on, produces a printing suitable for binding at the top or +bottom." + (interactive) + (pr-toggle 'pr-file-tumble "PS file tumble" nil 8 5 nil + '("PostScript Print" "File"))) + + +;;;###autoload +(defun pr-toggle-file-landscape () + "Toggle landscape for PostScript file." + (interactive) + (pr-toggle 'pr-file-landscape "PS file landscape" nil 6 5 nil + '("PostScript Print" "File"))) + + +;;;###autoload +(defun pr-toggle-ghostscript () + "Toggle printing using ghostscript." + (interactive) + (pr-toggle 'pr-print-using-ghostscript "Printing using ghostscript" + 'postscript-process 2 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-faces () + "Toggle printing with faces." + (interactive) + (pr-toggle 'pr-faces-p "Printing with-faces" + 'postscript-process 1 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-spool () + "Toggle spooling." + (interactive) + (pr-toggle 'pr-spool-p "Spooling printing" + 'postscript-process 0 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-duplex () + "Toggle duplex." + (interactive) + (pr-toggle 'ps-spool-duplex "Printing duplex" + 'postcsript-options 5 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-tumble () + "Toggle tumble. + +If tumble is off, produces a printing suitable for binding on the left or +right. +If tumble is on, produces a printing suitable for binding at the top or +bottom." + (interactive) + (pr-toggle 'ps-spool-tumble "Tumble" + 'postscript-options 6 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-landscape () + "Toggle landscape." + (interactive) + (pr-toggle 'ps-landscape-mode "Landscape" + 'postscript-options 0 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-upside-down () + "Toggle upside-down." + (interactive) + (pr-toggle 'ps-print-upside-down "Upside-Down" + 'postscript-options 7 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-line () + "Toggle line number." + (interactive) + (pr-toggle 'ps-line-number "Line number" + 'postscript-options 3 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-zebra () + "Toggle zebra stripes." + (interactive) + (pr-toggle 'ps-zebra-stripes "Zebra stripe" + 'postscript-options 4 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-header () + "Toggle printing header." + (interactive) + (pr-toggle 'ps-print-header "Print header" + 'postscript-options 1 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-header-frame () + "Toggle printing header frame." + (interactive) + (pr-toggle 'ps-print-header-frame "Print header frame" + 'postscript-options 2 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-lock () + "Toggle menu lock." + (interactive) + (pr-toggle 'pr-menu-lock "Menu lock" + 'printing 2 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-region () + "Toggle auto region." + (interactive) + (pr-toggle 'pr-auto-region "Auto region" + 'printing 0 12 'toggle)) + + +;;;###autoload +(defun pr-toggle-mode () + "Toggle auto mode." + (interactive) + (pr-toggle 'pr-auto-mode "Auto mode" + 'printing 1 12 'toggle)) + + +;;;###autoload +(defun pr-customize (&rest ignore) + "Customization of `printing' group." + (interactive) + (customize-group 'printing)) + + +;;;###autoload +(defun lpr-customize (&rest ignore) + "Customization of `lpr' group." + (interactive) + (customize-group 'lpr)) + + +;;;###autoload +(defun pr-help (&rest ignore) + "Help for printing package." + (interactive) + (pr-show-setup pr-help-message "*Printing Help*")) + + +;;;###autoload +(defun pr-ps-name () + "Select interactively a PostScript printer." + (interactive) + (pr-menu-set-ps-title + (pr-complete-alist "PostScript printer" pr-ps-printer-alist pr-ps-name))) + + +;;;###autoload +(defun pr-txt-name () + "Select interactively a text printer." + (interactive) + (pr-menu-set-txt-title + (pr-complete-alist "Text printer" pr-txt-printer-alist pr-txt-name))) + + +;;;###autoload +(defun pr-ps-utility () + "Select interactively a PostScript utility." + (interactive) + (pr-menu-set-utility-title + (pr-complete-alist "Postscript utility" pr-ps-utility-alist pr-ps-utility))) + + +;;;###autoload +(defun pr-show-ps-setup (&rest ignore) + "Show current ps-print settings." + (interactive) + (pr-show-setup (ps-setup) "*PS Setup*")) + + +;;;###autoload +(defun pr-show-pr-setup (&rest ignore) + "Show current printing settings." + (interactive) + (pr-show-setup (pr-setup) "*PR Setup*")) + + +;;;###autoload +(defun pr-show-lpr-setup (&rest ignore) + "Show current lpr settings." + (interactive) + (pr-show-setup (lpr-setup) "*LPR Setup*")) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Fast Commands + + +;;;###autoload +(defun pr-ps-fast-fire (n-up &optional select) + "Fast fire function for PostScript printing. + +If a region is active, the region will be printed instead of the whole buffer. +Also if the current major-mode is defined in `pr-mode-alist', the settings in +`pr-mode-alist' will be used, that is, the current buffer or region will be +printed using `pr-ps-mode-ps-print'. + + +Interactively, you have the following situations: + + M-x pr-ps-fast-fire RET + The command prompts the user for a N-UP value and printing will + immediatelly be done using the current active printer. + + C-u M-x pr-ps-fast-fire RET + C-u 0 M-x pr-ps-fast-fire RET + The command prompts the user for a N-UP value and also for a current + PostScript printer, then printing will immediatelly be done using the new + current active printer. + + C-u 1 M-x pr-ps-fast-fire RET + The command prompts the user for a N-UP value and also for a file name, + and saves the PostScript image in that file instead of sending it to the + printer. + + C-u 2 M-x pr-ps-fast-fire RET + The command prompts the user for a N-UP value, then for a current + PostScript printer and, finally, for a file name. Then change the active + printer to that choosen by user and saves the PostScript image in + that file instead of sending it to the printer. + + +Noninteractively, the argument N-UP should be a positive integer greater than +zero and the argument SELECT is treated as follows: + + If it's nil, send the image to the printer. + + If it's a list or an integer lesser or equal to zero, the command prompts + the user for a current PostScript printer, then printing will immediatelly + be done using the new current active printer. + + If it's an integer equal to 1, the command prompts the user for a file name + and saves the PostScript image in that file instead of sending it to the + printer. + + If it's an integer greater or equal to 2, the command prompts the user for a + current PostScript printer and for a file name. Then change the active + printer to that choosen by user and saves the PostScript image in that file + instead of sending it to the printer. + + If it's a symbol which it's defined in `pr-ps-printer-alist', it's the new + active printer and printing will immediatelly be done using the new active + printer. + + Otherwise, send the image to the printer. + + +Note that this command always behaves as if `pr-auto-region' and `pr-auto-mode' +are both set to t." + (interactive (list (pr-interactive-n-up (pr-prompt-gs "PS print fast")) + current-prefix-arg)) + (let ((pr-auto-region t) + (pr-auto-mode t) + filename) + (cond ((null select)) + ((listp select) + (pr-ps-name)) + ((and (symbolp select) + (assq select pr-ps-printer-alist)) + (pr-menu-set-ps-title select)) + ((integerp select) + (and (/= select 1) + (pr-ps-name)) + (and (>= select 1) (not pr-spool-p) + (setq filename (pr-ps-outfile-preprint + (if pr-print-using-ghostscript + "Fast GS " + "Fast ")))))) + (pr-ps-buffer-ps-print + (if (integerp n-up) + (min (max n-up 1) 100) + (error "n-up must be an integer greater than zero.")) + filename))) + + +;;;###autoload +(defun pr-txt-fast-fire (&optional select-printer) + "Fast fire function for text printing. + +If a region is active, the region will be printed instead of the whole buffer. +Also if the current major-mode is defined in `pr-mode-alist', the settings in +`pr-mode-alist' will be used, that is, the current buffer or region will be +printed using `pr-txt-mode'. + +Interactively, when you use a prefix argument (C-u), the command prompts the +user for a new active text printer. + +Noninteractively, the argument SELECT-PRINTER is treated as follows: + + If it's nil, the printing is sent to the current active text printer. + + If it's a symbol which it's defined in `pr-txt-printer-alist', it's the new + active printer and printing will immediatelly be done using the new active + printer. + + If it's non-nil, the command prompts the user for a new active text printer. + +Note that this command always behaves as if `pr-auto-region' and `pr-auto-mode' +are both set to t." + (interactive (list current-prefix-arg)) + (cond ((null select-printer)) + ((and (symbolp select-printer) + (assq select-printer pr-txt-printer-alist)) + (pr-menu-set-txt-title select-printer)) + (t + (pr-txt-name))) + (let ((pr-auto-region t) + (pr-auto-mode t)) + (pr-txt-buffer))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Utilities + + +(defun pr-setup () + "Return the current `printing' setup. + +This is *not* an interactive command. +One way to see `printing' setup is to switch to a *Scratch* buffer and type: + + M-: (insert (pr-setup)) RET + +Or choose the menu option Printing/Show Settings/printing." + (let (ps-prefix-quote) + (mapconcat + #'ps-print-quote + (list + (concat "\n;;; printing.el version " pr-version "\n") + '(19 . pr-shell-file-name) + '(19 . pr-path-style) + '(19 . pr-path-alist) + nil + '(21 . pr-txt-name) + '(21 . pr-txt-printer-alist) + nil + '(20 . pr-ps-name) + '(20 . pr-ps-printer-alist) + nil + '(20 . pr-temp-dir) + '(20 . pr-ps-temp-file) + '(20 . pr-delete-temp-file) + '(20 . pr-list-directory) + nil + '(17 . pr-gv-command) + '(17 . pr-gs-command) + '(17 . pr-gs-switches) + '(17 . pr-gs-device) + '(17 . pr-gs-resolution) + nil + '(27 . pr-print-using-ghostscript) + '(27 . pr-faces-p) + '(27 . pr-spool-p) + '(27 . pr-file-landscape) + '(27 . pr-file-duplex) + '(27 . pr-file-tumble) + '(27 . pr-auto-region) + '(27 . pr-auto-mode) + nil + '(20 . pr-ps-utility) + '(20 . pr-ps-utility-alist) + nil + '(14 . pr-mode-alist) + nil + '(20 . pr-menu-lock) + '(20 . pr-menu-char-height) + '(20 . pr-menu-char-width) + nil + '(20 . pr-setting-database) + nil + '(22 . pr-visible-entry-list) + nil + '(22 . pr-buffer-verbose) + '(22 . pr-buffer-name) + '(22 . pr-buffer-name-ignore) + ")\n\n;;; printing.el - end of settings\n") + "\n"))) + + +(defun lpr-setup () + "Return the current `lpr' setup. + +This is *not* an interactive command. +One way to see `lpr' setup is to switch to a *Scratch* buffer and type: + + M-: (insert (lpr-setup)) RET + +Or choose the menu option Printing/Show Settings/lpr." + (let (ps-prefix-quote) + (mapconcat + #'ps-print-quote + '("\n;;; lpr.el settings\n" + (25 . printer-name) + (25 . lpr-switches) + (25 . lpr-add-switches) + (25 . lpr-command) + (25 . lpr-headers-switches) + (25 . print-region-function) + (25 . lpr-page-header-program) + (25 . lpr-page-header-switches) + ")\n\n;;; lpr.el - end of settings\n") + "\n"))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; mh-e (adapted from mh-e-init.el -- Tom Vogels ) + + +(defalias 'pr-mh-get-msg-num 'mh-get-msg-num) +(defalias 'pr-mh-show 'mh-show) +(defalias 'pr-mh-start-of-uncleaned-message 'mh-start-of-uncleaned-message) +(defvar mh-show-buffer nil) + + +(defun pr-article-date () + "Find the date of an article or mail message in current buffer. +Return only the dayname, if present, weekday, month, and year." + (save-excursion + (goto-char (point-min)) + (if (re-search-forward + "^Date:[ \t]+\\(\\([A-Za-z]+, \\)?[0-9]+ [A-Za-z]+ [0-9]+\\)" nil t) + (buffer-substring (match-beginning 1) (match-end 1)) + (format-time-string "%Y/%m/%d")))) + + +(defun pr-mh-current-message () + "Go to mh-inbox current message." + (let ((msg (or (pr-mh-get-msg-num nil) 0))) + (pr-mh-show) + (set-buffer mh-show-buffer) + (goto-char (point-min)) + (pr-mh-start-of-uncleaned-message) + (message "Printing message %d" msg))) + + +(defun pr-mh-print-1 (n-up filename header-list) + "Print mh-inbox current message in PostScript." + (save-excursion + (save-window-excursion + (pr-mh-current-message) + (pr-mode-print n-up filename header-list (point))))) + + +(defun pr-mh-lpr-1 (header-list) + "Print mh-inbox current message in text printer." + (save-excursion + (save-window-excursion + (pr-mh-current-message) + (pr-mode-lpr header-list (point))))) + + +(defalias 'pr-mh-print-2 'pr-mode-print) + + +(defalias 'pr-mh-lpr-2 'pr-mode-lpr) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; rmail (hacked from ps-print.el) + + +(defun pr-rmail-lpr (header-list) + "Print RMAIL current message in text printer." + (pr-lpr-message-from-summary header-list + 'rmail-buffer 'rmail-summary-buffer)) + + +(defun pr-rmail-print (n-up filename header-list) + "Print RMAIL current message in PostScript." + (pr-ps-message-from-summary n-up filename header-list + 'rmail-buffer 'rmail-summary-buffer)) + + +(defun pr-ps-message-from-summary (n-up filename header-list + summary-buffer summary-default) + "Print current message in PostScript." + (let ((buf (or (and (boundp summary-buffer) + (symbol-value summary-buffer)) + (symbol-value summary-default)))) + (and (get-buffer buf) + (save-excursion + (set-buffer buf) + (pr-mode-print n-up filename header-list))))) + + +(defun pr-lpr-message-from-summary (header-list summary-buffer summary-default) + "Print current message in text printer." + (let ((buf (or (and (boundp summary-buffer) + (symbol-value summary-buffer)) + (symbol-value summary-default)))) + (and (get-buffer buf) + (save-excursion + (set-buffer buf) + (pr-mode-lpr header-list))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; gnus (hacked from ps-print.el) + + +(defvar pr-gnus-article "*Article*") + + +(defun pr-gnus-print (n-up filename header-list) + "Print *Article* current message in PostScript." + (pr-ps-message-from-summary n-up filename header-list + 'gnus-article-buffer 'pr-gnus-article)) + + +(defun pr-gnus-lpr (header-list) + "Print *Article* current message in text printer." + (pr-lpr-message-from-summary header-list + 'gnus-article-buffer 'pr-gnus-article)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; vm (hacked from ps-print.el) + + +(defvar pr-vm-summary "") + + +(defun pr-vm-print (n-up filename header-list) + "Print current vm message in PostScript." + (pr-ps-message-from-summary n-up filename header-list + 'vm-mail-buffer 'pr-vm-summary)) + + +(defun pr-vm-lpr (header-list) + "Print current vm message in text printer." + (pr-lpr-message-from-summary header-list + 'vm-mail-buffer 'pr-vm-summary)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Mode Functions + + +(defun pr-ps-mode (n-up filename) + "If current major mode is declared, print it in PostScript." + (let ((args (pr-mode-alist-p))) + (if args + (let ((fun (cdr args))) + (funcall (car fun) n-up filename (cdr fun)) + t) + (ding) + (message "`%s' major mode not declared." major-mode) + nil))) + + +(defmacro pr-local-variable (header-list &rest body) + `(save-excursion + (let ((ps-header-lines (or (nth 0 ,header-list) ps-header-lines)) + (ps-left-header (or (nth 1 ,header-list) ps-left-header)) + (ps-right-header (or (nth 2 ,header-list) ps-right-header)) + ps-razzle-dazzle) + (let ((local-var-list (pr-eval-local-alist (nthcdr 4 ,header-list)))) + ,@body + (and (nth 3 ,header-list) + (pr-kill-local-variable local-var-list)))))) + + +(defun pr-mode-print (n-up filename header-list &optional from to) + "Print current major mode in PostScript." + (pr-local-variable + header-list + (let ((file (pr-ps-file filename)) + (start (cond (from) + ((pr-region-active-p) (region-beginning)) + (t nil) + ))) + (pr-text2ps (pr-region-active-symbol start) n-up file start + (cond (to) + ((pr-region-active-p) (region-end)) + (from (point-max)) + )) + (unless (or pr-spool-p filename) + (pr-ps-file-print file) + (pr-delete-file file))))) + + +(defun pr-mode-lpr (header-list &optional from to) + "Print current major mode in text printer." + (pr-local-variable + header-list + (pr-txt-print (cond (from) + ((pr-region-active-p) (region-beginning)) + (t (point-min))) + (cond (to) + ((pr-region-active-p) (region-end)) + (t (point-max)))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Menu Lock + + +(defconst pr-menu-entry-alist + '((postscript . 3) + (text . 3) + (postscript-options . 9) + (postscript-process . 3) + (printing . 3) + (help . 3) + ) + "Alist that associates menu part with number of items per part. + +It's used by `pr-menu-index'. + +Each element has the form: + + (MENU-PART . NUMBER-OF-ITEMS) + +See `pr-visible-entry-alist'.") + + +(defun pr-menu-index (entry index) + (let ((base-list + (cond ((eq entry 'text) + '(postscript)) + ((eq entry 'postscript-options) + '(postscript text)) + ((eq entry 'postscript-process) + '(postscript text postscript-options)) + ((eq entry 'printing) + '(postscript text postscript-options postscript-process)) + (t + nil) + )) + key) + (while base-list + (setq key (car base-list) + base-list (cdr base-list)) + (and (pr-visible-p key) + (setq index (+ index + (cdr (assq key pr-menu-entry-alist))))))) + (+ index 2)) + + +(eval-and-compile + (cond + ((eq ps-print-emacs-type 'xemacs) + ;; XEmacs + (defun pr-menu-position (entry index horizontal) + (pr-x-make-event + 'button-release + (list 'button 1 + 'x (- (pr-x-event-x-pixel current-mouse-event) ; X + (* horizontal pr-menu-char-width)) + 'y (- (pr-x-event-y-pixel current-mouse-event) ; Y + (* (pr-menu-index entry index) pr-menu-char-height))))) + ) + (ps-windows-system + ;; GNU Emacs for Windows 9x/NT + (defun pr-menu-position (entry index horizontal) + (let ((pos (cdr (pr-e-mouse-pixel-position)))) + (list + (list (car pos) ; X + (- (cdr pos) ; Y + (* (pr-menu-index entry index) pr-menu-char-height))) + (selected-frame)))) ; frame + ) + (t + ;; GNU Emacs + (defun pr-menu-position (entry index horizontal) + (let ((pos (cdr (pr-e-mouse-pixel-position)))) + (list + (list (- (car pos) ; X + (* horizontal pr-menu-char-width)) + (- (cdr pos) ; Y + (* (pr-menu-index entry index) pr-menu-char-height))) + (selected-frame)))) ; frame + ))) + + +(defvar pr-menu-position nil) +(defvar pr-menu-state nil) + + +(cond + ((eq ps-print-emacs-type 'emacs) + ;; GNU Emacs + (defun pr-menu-lock (entry index horizontal state path) + (when (and (not (interactive-p)) pr-menu-lock) + (or (and pr-menu-position (eq state pr-menu-state)) + (setq pr-menu-position (pr-menu-position entry index horizontal) + pr-menu-state state)) + (let* ((menu (pr-menu-lookup path)) + (result (x-popup-menu pr-menu-position menu))) + (and result + (let ((command (lookup-key menu (vconcat result)))) + (if (fboundp command) + (funcall command) + (eval command))))) + (setq pr-menu-position nil))) + + ;; GNU Emacs + (defun pr-menu-lookup (path) + (let ((ipath pr-menu-bar)) + (lookup-key global-map + (if path + (vconcat ipath + (mapcar 'pr-get-symbol + (if (listp path) + path + (list path)))) + ipath))))) + + + ((eq ps-print-emacs-type 'xemacs) + ;; XEmacs + (defun pr-menu-lock (entry index horizontal state path) + (when (and (not (interactive-p)) pr-menu-lock) + (or (and pr-menu-position (eq state pr-menu-state)) + (setq pr-menu-position (pr-menu-position entry index horizontal) + pr-menu-state state)) + (let* ((menu (pr-menu-lookup path)) + (result (pr-x-get-popup-menu-response menu pr-menu-position))) + (and (pr-x-misc-user-event-p result) + (funcall (pr-x-event-function result) + (pr-x-event-object result)))) + (setq pr-menu-position nil))) + + ;; XEmacs + (defun pr-menu-lookup (path) + (car (pr-x-find-menu-item current-menubar (cons "Printing" path)))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Printer & Utility Selection + + +(defun pr-update-var (var-sym alist) + (or (assq (symbol-value var-sym) alist) + (set var-sym (car (car alist))))) + + +(defun pr-update-menus (&optional force) + "Update utility, PostScript and text printer menus. + +If FORCE is non-nil, update menus doesn't matter if `pr-ps-printer-alist', +`pr-txt-printer-alist' or `pr-ps-utility-alist' were modified or not; +otherwise, update PostScript printer menu iff `pr-ps-printer-menu-modified' is +non-nil, update text printer menu iff `pr-txt-printer-menu-modified' is +non-nil, and update PostScript File menus iff `pr-ps-utility-menu-modified' is +non-nil." + (interactive) + (pr-update-var 'pr-ps-name pr-ps-printer-alist) + (pr-update-var 'pr-txt-name pr-txt-printer-alist) + (pr-update-var 'pr-ps-utility pr-ps-utility-alist) + (pr-do-update-menus force)) + + +(defvar pr-ps-printer-menu-modified t + "Non-nil means `pr-ps-printer-alist' was modified and need to update menu.") +(defvar pr-txt-printer-menu-modified t + "Non-nil means `pr-txt-printer-alist' was modified and need to update menu.") +(defvar pr-ps-utility-menu-modified t + "Non-nil means `pr-ps-utility-alist' was modified and need to update menu.") + + +(defconst pr-even-or-odd-alist + '((nil . "Print All Pages") + (even-page . "Print Even Pages") + (odd-page . "Print Odd Pages") + (even-sheet . "Print Even Sheets") + (odd-sheet . "Print Odd Sheets"))) + + +(defun pr-menu-create (name alist var-sym fun entry index) + (cons name + (mapcar + #'(lambda (elt) + (let ((sym (car elt))) + (vector + (symbol-name sym) + (list fun (list 'quote sym) nil (list 'quote entry) index) + :style 'radio + :selected (list 'eq var-sym (list 'quote sym))))) + alist))) + + +(eval-and-compile + (cond + ((eq ps-print-emacs-type 'emacs) + ;; GNU Emacs + (defalias 'pr-update-mode-line 'force-mode-line-update) + + ;; GNU Emacs + (defun pr-do-update-menus (&optional force) + (pr-menu-alist pr-ps-printer-alist + 'pr-ps-name + 'pr-menu-set-ps-title + "PostScript Printers" + 'pr-ps-printer-menu-modified + force + "PostScript Printers" + 'postscript 2) + (pr-menu-alist pr-txt-printer-alist + 'pr-txt-name + 'pr-menu-set-txt-title + "Text Printers" + 'pr-txt-printer-menu-modified + force + "Text Printers" + 'text 2) + (let ((save-var pr-ps-utility-menu-modified)) + (pr-menu-alist pr-ps-utility-alist + 'pr-ps-utility + 'pr-menu-set-utility-title + '("PostScript Print" "File" "PostScript Utility") + 'save-var + force + "PostScript Utility" + nil 1)) + (pr-menu-alist pr-ps-utility-alist + 'pr-ps-utility + 'pr-menu-set-utility-title + '("PostScript Preview" "File" "PostScript Utility") + 'pr-ps-utility-menu-modified + force + "PostScript Utility" + nil 1) + (pr-even-or-odd-pages ps-even-or-odd-pages force)) + + ;; GNU Emacs + (defvar pr-temp-menu nil) + + ;; GNU Emacs + (defun pr-menu-alist (alist var-sym fun menu-path modified-sym force name + entry index) + (when (and alist (or force (symbol-value modified-sym))) + (easy-menu-define pr-temp-menu nil "" + (pr-menu-create name alist var-sym fun entry index)) + (let ((item (pr-menu-get-item menu-path))) + (and item + (let* ((binding (nthcdr 3 item)) + (key-binding (cdr binding))) + (setcar binding pr-temp-menu) + (and key-binding (listp (car key-binding)) + (setcdr binding (cdr key-binding))) ; skip KEY-BINDING + (funcall fun (symbol-value var-sym) item)))) + (set modified-sym nil))) + + ;; GNU Emacs + (defun pr-menu-set-ps-title (value &optional item entry index) + (pr-menu-set-item-name (or item + (pr-menu-get-item "PostScript Printers")) + (format "PostScript Printer: %s" value)) + (pr-ps-set-printer value) + (and index + (pr-menu-lock entry index 12 'toggle nil))) + + ;; GNU Emacs + (defun pr-menu-set-txt-title (value &optional item entry index) + (pr-menu-set-item-name (or item + (pr-menu-get-item "Text Printers")) + (format "Text Printer: %s" value)) + (pr-txt-set-printer value) + (and index + (pr-menu-lock entry index 12 'toggle nil))) + + ;; GNU Emacs + (defun pr-menu-set-utility-title (value &optional item entry index) + (let ((name (symbol-name value))) + (if item + (pr-menu-set-item-name item name) + (pr-menu-set-item-name + (pr-menu-get-item + '("PostScript Print" "File" "PostScript Utility")) + name) + (pr-menu-set-item-name + (pr-menu-get-item + '("PostScript Preview" "File" "PostScript Utility")) + name))) + (pr-ps-set-utility value) + (and index + (pr-menu-lock entry index 5 nil '("PostScript Print" "File")))) + + ;; GNU Emacs + (defun pr-even-or-odd-pages (value &optional no-lock) + (pr-menu-set-item-name (pr-menu-get-item "Print All Pages") + (cdr (assq value pr-even-or-odd-alist))) + (setq ps-even-or-odd-pages value) + (or no-lock + (pr-menu-lock 'postscript-options 8 12 'toggle nil)))) + + + ((eq ps-print-emacs-type 'xemacs) + ;; XEmacs + (defalias 'pr-update-mode-line 'set-menubar-dirty-flag) + + ;; XEmacs + (defvar pr-ps-name-old "PostScript Printers") + (defvar pr-txt-name-old "Text Printers") + (defvar pr-ps-utility-old "PostScript Utility") + (defvar pr-even-or-odd-old "Print All Pages") + + ;; XEmacs + (defun pr-do-update-menus (&optional force) + (pr-menu-alist pr-ps-printer-alist + 'pr-ps-name + 'pr-menu-set-ps-title + '("Printing") + 'pr-ps-printer-menu-modified + force + pr-ps-name-old + 'postscript 2) + (pr-menu-alist pr-txt-printer-alist + 'pr-txt-name + 'pr-menu-set-txt-title + '("Printing") + 'pr-txt-printer-menu-modified + force + pr-txt-name-old + 'text 2) + (let ((save-var pr-ps-utility-menu-modified)) + (pr-menu-alist pr-ps-utility-alist + 'pr-ps-utility + 'pr-menu-set-utility-title + '("Printing" "PostScript Print" "File") + 'save-var + force + pr-ps-utility-old + nil 1)) + (pr-menu-alist pr-ps-utility-alist + 'pr-ps-utility + 'pr-menu-set-utility-title + '("Printing" "PostScript Preview" "File") + 'pr-ps-utility-menu-modified + force + pr-ps-utility-old + nil 1) + (pr-even-or-odd-pages ps-even-or-odd-pages force)) + + ;; XEmacs + (defun pr-menu-alist (alist var-sym fun menu-path modified-sym force name + entry index) + (when (and alist (or force (symbol-value modified-sym))) + (pr-xemacs-global-menubar + (pr-x-add-submenu menu-path + (pr-menu-create name alist var-sym + fun entry index))) + (funcall fun (symbol-value var-sym)) + (set modified-sym nil))) + + ;; XEmacs + (defun pr-menu-set-ps-title (value &optional item entry index) + (pr-relabel-menu-item (format "PostScript Printer: %s" value) + 'pr-ps-name-old) + (pr-ps-set-printer value) + (and index + (pr-menu-lock entry index 12 'toggle nil))) + + ;; XEmacs + (defun pr-menu-set-txt-title (value &optional item entry index) + (pr-relabel-menu-item (format "Text Printer: %s" value) + 'pr-txt-name-old) + (pr-txt-set-printer value) + (and index + (pr-menu-lock entry index 12 'toggle nil))) + + ;; XEmacs + (defun pr-menu-set-utility-title (value &optional item entry index) + (pr-xemacs-global-menubar + (let ((newname (format "%s" value))) + (pr-x-relabel-menu-item + (list "Printing" "PostScript Print" "File" pr-ps-utility-old) + newname) + (pr-x-relabel-menu-item + (list "Printing" "PostScript Preview" "File" pr-ps-utility-old) + newname) + (setq pr-ps-utility-old newname))) + (pr-ps-set-utility value) + (and index + (pr-menu-lock entry index 5 nil '("PostScript Print" "File")))) + + ;; XEmacs + (defun pr-even-or-odd-pages (value &optional no-lock) + (pr-relabel-menu-item (cdr (assq value pr-even-or-odd-alist)) + 'pr-even-or-odd-old) + (setq ps-even-or-odd-pages value) + (or no-lock + (pr-menu-lock 'postscript-options 8 12 'toggle nil)))))) + +;; XEmacs +(defun pr-relabel-menu-item (newname var-sym) + (pr-xemacs-global-menubar + (pr-x-relabel-menu-item + (list "Printing" (symbol-value var-sym)) + newname) + (set var-sym newname))) + + +(defun pr-menu-set-item-name (item name) + (and item + (setcar (nthcdr 2 item) name))) ; ITEM-NAME + + +(defun pr-menu-get-item (name-list) + ;; NAME-LIST is a string or a list of strings. + (let ((ipath pr-menu-bar) + (len (and (listp name-list) (length name-list)))) + (and len (= len 1) + (setq name-list (car name-list))) + (cond + ((null name-list) + ;; nil + nil) + ((listp name-list) + ;; list and (length list) > 1 + (let* ((copy (copy-sequence name-list)) + (name (pr-get-symbol (nth (1- len) copy))) + (path (progn + (setcdr (nthcdr (- len 2) copy) nil) + copy)) + (menu (lookup-key + global-map + (if path + (vconcat ipath + (mapcar 'pr-get-symbol path)) + ipath)))) + (assq name (nthcdr 2 menu)))) + (t + ;; string + (let ((name (pr-get-symbol name-list)) + (menu (lookup-key global-map ipath))) + (assq name (nthcdr 2 menu))))))) + + +(defun pr-ps-set-utility (value) + (let ((item (cdr (assq value pr-ps-utility-alist)))) + (or item + (error + "Invalid PostScript utility name `%s' for variable `pr-ps-utility'." + value)) + (setq pr-ps-utility value) + (pr-eval-alist (nthcdr 9 item))) + (pr-update-mode-line)) + + +(defun pr-ps-set-printer (value) + (let ((ps (cdr (assq value pr-ps-printer-alist)))) + (or ps + (error + "Invalid PostScript printer name `%s' for variable `pr-ps-name'." + value)) + (setq pr-ps-name value + pr-ps-command (pr-dosify-path (nth 0 ps)) + pr-ps-switches (nth 1 ps) + pr-ps-printer-switch (nth 2 ps) + pr-ps-printer (pr-dosify-path (nth 3 ps))) + (or (stringp pr-ps-command) + (setq pr-ps-command + (cond (ps-windows-system "print") + (ps-lp-system "lp") + (t "lpr") + ))) + (or (stringp pr-ps-printer-switch) + (setq pr-ps-printer-switch + (cond (ps-windows-system "/D:") + (ps-lp-system "-d") + (t "-P") + ))) + (pr-eval-alist (nthcdr 4 ps))) + (pr-update-mode-line)) + + +(defun pr-txt-set-printer (value) + (let ((txt (cdr (assq value pr-txt-printer-alist)))) + (or txt + (error "Invalid text printer name `%s' for variable `pr-txt-name'." + value)) + (setq pr-txt-name value + pr-txt-command (pr-dosify-path (nth 0 txt)) + pr-txt-switches (nth 1 txt) + pr-txt-printer (pr-dosify-path (nth 2 txt)))) + (or (stringp pr-txt-command) + (setq pr-txt-command + (cond (ps-windows-system "print") + (ps-lp-system "lp") + (t "lpr") + ))) + (pr-update-mode-line)) + + +(defun pr-eval-alist (alist) + (mapcar #'(lambda (option) + (let ((var-sym (car option)) + (value (cdr option))) + (if (eq var-sym 'inherits-from:) + (pr-eval-setting-alist value 'global) + (set var-sym (eval value))))) + alist)) + + +(defun pr-eval-local-alist (alist) + (let (local-list) + (mapcar #'(lambda (option) + (let ((var-sym (car option)) + (value (cdr option))) + (setq local-list + (if (eq var-sym 'inherits-from:) + (nconc (pr-eval-setting-alist value) local-list) + (set (make-local-variable var-sym) (eval value)) + (cons var-sym local-list))))) + alist) + local-list)) + + +(defun pr-eval-setting-alist (key &optional global old) + (let ((setting (cdr (assq key pr-setting-database)))) + (and setting + (let ((inherits (nth 0 setting)) + (local (nth 1 setting)) + (kill (nth 2 setting)) + local-list) + (and local global + (progn + (ding) + (message "There are local buffer settings for `%S'." key) + (setq global nil))) + (and inherits + (if (memq inherits old) + (error "Circular inheritance for `%S'." inherits) + (setq local-list + (pr-eval-setting-alist inherits global + (cons inherits old))))) + (mapcar + (cond ((not local) ; global settings + #'(lambda (option) + (let ((var-sym (car option))) + (or (eq var-sym 'inherits-from:) + (set var-sym (eval (cdr option))))))) + (kill ; local settings with killing + #'(lambda (option) + (let ((var-sym (car option))) + (unless (eq var-sym 'inherits-from:) + (setq local-list (cons var-sym local-list)) + (set (make-local-variable var-sym) + (eval (cdr option))))))) + (t ; local settings without killing + #'(lambda (option) + (let ((var-sym (car option))) + (or (eq var-sym 'inherits-from:) + (set (make-local-variable var-sym) + (eval (cdr option)))))))) + (nthcdr 3 setting)) + local-list)))) + + +(defun pr-kill-local-variable (local-var-list) + (mapcar 'kill-local-variable local-var-list)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Internal Functions (II) + + +(defun pr-prompt (str) + (if (pr-auto-mode-p) + (concat str " mode") + (pr-region-active-string str))) + + +(defun pr-prompt-region (str) + (concat str (if (pr-auto-mode-p) + " mode" + " region"))) + + +(defun pr-prompt-gs (str) + (if (pr-using-ghostscript-p) + (concat str " GS") + str)) + + +(defun pr-region-active-symbol (&optional region-p) + (if (or region-p (pr-region-active-p)) + 'region + 'buffer)) + + +(defun pr-region-active-string (prefix) + (concat prefix + (if (pr-region-active-p) + " region" + " buffer"))) + + +(defun pr-show-setup (settings buffer-name) + (with-output-to-temp-buffer buffer-name + (princ settings) + (print-help-return-message))) + + +(defun pr-complete-alist (prompt alist default) + (let ((collection (mapcar #'(lambda (elt) + (setq elt (car elt)) + (cons (symbol-name elt) elt)) + alist))) + (cdr (assoc (completing-read (concat prompt ": ") + collection nil t + (symbol-name default) nil + (symbol-name default)) + collection)))) + + +(defun pr-delete-file (file) + (and pr-delete-temp-file (delete-file file))) + + +(defun pr-expand-file-name (filename) + (pr-dosify-path (expand-file-name filename))) + + +(defun pr-ps-outfile-preprint (&optional mess) + (let* ((prompt (format "%soutput PostScript file name: " (or mess ""))) + (res (read-file-name prompt default-directory "" nil))) + (while (cond ((not (file-writable-p res)) + (ding) + (setq prompt "is unwritable")) + ((file-directory-p res) + (ding) + (setq prompt "is a directory")) + ((file-exists-p res) + (ding) + (setq prompt "exists") + (not (y-or-n-p (format "File `%s' exists; overwrite? " + res)))) + (t nil)) + (setq res (read-file-name + (format "File %s; PostScript file: " prompt) + (file-name-directory res) nil nil + (file-name-nondirectory res)))) + (pr-expand-file-name res))) + + +(defun pr-ps-infile-preprint (&optional mess) + (let* ((prompt (format "%sinput PostScript file name: " (or mess ""))) + (res (read-file-name prompt default-directory "" nil))) + (while (cond ((not (file-exists-p res)) + (ding) + (setq prompt "doesn't exist")) + ((not (file-readable-p res)) + (ding) + (setq prompt "is unreadable")) + ((file-directory-p res) + (ding) + (setq prompt "is a directory")) + (t nil)) + (setq res (read-file-name + (format "File %s; PostScript file: " prompt) + (file-name-directory res) nil nil + (file-name-nondirectory res)))) + (pr-expand-file-name res))) + + +(defun pr-toggle (var-sym mess entry index horizontal state &optional path) + (set var-sym (not (symbol-value var-sym))) + (message "%s is %s" mess (if (symbol-value var-sym) "on" "off")) + (pr-menu-lock entry index horizontal state path)) + + +(defun pr-ps-utility-args (n-up-sym infile-sym outfile-sym prompt) + ;; n-up + (or (symbol-value n-up-sym) + (set n-up-sym (pr-interactive-n-up prompt))) + (and (eq (symbol-value infile-sym) t) + (set infile-sym (and (not (interactive-p)) + (pr-ps-infile-preprint prompt)))) + ;; input file + (or (symbol-value infile-sym) + (error "%s: input PostScript file name is missing" prompt)) + (set infile-sym (pr-dosify-path (symbol-value infile-sym))) + ;; output file + (and (eq (symbol-value outfile-sym) t) + (set outfile-sym (and (not (interactive-p)) + current-prefix-arg + (pr-ps-outfile-preprint prompt)))) + (and (symbol-value outfile-sym) + (set outfile-sym (pr-dosify-path (symbol-value outfile-sym)))) + (pr-ps-file (symbol-value outfile-sym))) + + +(defun pr-ps-utility-process (n-up infile outfile) + (let (item) + (and (stringp infile) (file-exists-p infile) + (setq item (cdr (assq pr-ps-utility pr-ps-utility-alist))) + (pr-shell-command + (concat (pr-command (nth 0 item)) " " + (pr-switches-string (nth 1 item) + "pr-ps-utility-alist entry") + " " + (pr-switches-string (nth 8 item) + "pr-ps-utility-alist entry") + " " + (and (nth 2 item) + (format (nth 2 item) ps-paper-type)) + " " (format (nth 3 item) n-up) " " + (and pr-file-landscape (nth 4 item)) " " + (and pr-file-duplex (nth 5 item)) " " + (and pr-file-tumble (nth 6 item)) + " \"" (pr-expand-file-name infile) "\" " + (nth 7 item) + " \"" (pr-expand-file-name outfile) "\""))))) + + +(defun pr-shell-command (command) + (let ((shell-file-name pr-shell-file-name)) + (shell-command command))) + + +(defun pr-txt-print (from to) + (let ((lpr-command (pr-command pr-txt-command)) + (lpr-switches (pr-switches pr-txt-switches "pr-txt-switches")) + (printer-name pr-txt-printer)) + (lpr-region from to))) + + +(defun pr-switches-string (switches mess) + (mapconcat 'identity (pr-switches switches mess) " ")) + + +(defun pr-switches (switches mess) + (or (listp switches) + (error "%S should have a list of strings." mess)) + (ps-flatten-list ; dynamic evaluation + (mapcar 'ps-eval-switch switches))) + + +(defun pr-ps-preview (kind n-up filename mess) + (pr-set-n-up-and-filename 'n-up 'filename mess) + (let ((file (pr-ps-file filename))) + (pr-text2ps kind n-up file) + (or pr-spool-p (pr-ps-file-preview file)))) + + +(defun pr-ps-using-ghostscript (kind n-up filename mess) + (pr-set-n-up-and-filename 'n-up 'filename mess) + (let ((file (pr-ps-file filename))) + (pr-text2ps kind n-up file) + (unless (or pr-spool-p filename) + (pr-ps-file-using-ghostscript file) + (pr-delete-file file)))) + + +(defun pr-ps-print (kind n-up filename mess) + (pr-set-n-up-and-filename 'n-up 'filename mess) + (let ((file (pr-ps-file filename))) + (pr-text2ps kind n-up file) + (unless (or pr-spool-p filename) + (pr-ps-file-print file) + (pr-delete-file file)))) + + +(defun pr-ps-file (&optional filename) + (pr-dosify-path (or filename + (convert-standard-filename + (expand-file-name pr-ps-temp-file pr-temp-dir))))) + + +(defun pr-interactive-n-up (mess) + (or (stringp mess) (setq mess "*")) + (save-match-data + (let* ((fmt-prompt "%s[%s] N-up printing: (default 1) ") + (prompt "") + (str (pr-f-read-string (format fmt-prompt prompt mess) "1" nil "1")) + int) + (while (if (string-match "^\\s *[0-9]+$" str) + (setq int (string-to-int str) + prompt (cond ((< int 1) "Integer below 1; ") + ((> int 100) "Integer above 100; ") + (t nil))) + (setq prompt "Invalid integer syntax; ")) + (ding) + (setq str + (pr-f-read-string (format fmt-prompt prompt mess) str nil "1"))) + int))) + + +(defun pr-interactive-dir (mess) + (let* ((dir-name (file-name-directory (or (buffer-file-name) + default-directory))) + (fmt-prompt (concat "%s[" mess "] Directory to print: ")) + (dir (read-file-name (format fmt-prompt "") + "" dir-name nil dir-name)) + prompt) + (while (cond ((not (file-directory-p dir)) + (ding) + (setq prompt "It's not a directory! ")) + ((not (file-readable-p dir)) + (ding) + (setq prompt "Directory is unreadable! ")) + (t nil)) + (setq dir-name (file-name-directory dir) + dir (read-file-name (format fmt-prompt prompt) + "" dir-name nil dir-name))) + (file-name-as-directory dir))) + + +(defun pr-interactive-regexp (mess) + (pr-f-read-string (format "[%s] File regexp to print: " mess) "" nil "")) + + +(defun pr-interactive-dir-args (mess) + (list + ;; get directory argument + (pr-interactive-dir mess) + ;; get file name regexp + (pr-interactive-regexp mess))) + + +(defun pr-interactive-ps-dir-args (mess) + (list + ;; get n-up argument + (pr-interactive-n-up mess) + ;; get directory argument + (pr-interactive-dir mess) + ;; get file name regexp + (pr-interactive-regexp mess) + ;; get output file name + (and (not pr-spool-p) + (ps-print-preprint current-prefix-arg)))) + + +(defun pr-interactive-n-up-file (mess) + (list + ;; get n-up argument + (pr-interactive-n-up mess) + ;; get output file name + (and (not pr-spool-p) + (ps-print-preprint current-prefix-arg)))) + + +(defun pr-interactive-n-up-inout (mess) + (list + ;; get n-up argument + (pr-interactive-n-up mess) + ;; get input file name + (pr-ps-infile-preprint (concat mess " ")) + ;; get output file name + (ps-print-preprint current-prefix-arg))) + + +(defun pr-set-outfilename (filename-sym) + (and (not pr-spool-p) + (eq (symbol-value filename-sym) t) + (set filename-sym (and (not (interactive-p)) + current-prefix-arg + (ps-print-preprint current-prefix-arg)))) + (and (symbol-value filename-sym) + (set filename-sym (pr-dosify-path (symbol-value filename-sym))))) + + +(defun pr-set-n-up-and-filename (n-up-sym filename-sym mess) + ;; n-up + (or (symbol-value n-up-sym) + (set n-up-sym (pr-interactive-n-up mess))) + ;; output file + (pr-set-outfilename filename-sym)) + + +(defun pr-set-dir-args (dir-sym regexp-sym mess) + ;; directory + (or (symbol-value dir-sym) + (set dir-sym (pr-interactive-dir mess))) + ;; file name regexp + (or (symbol-value regexp-sym) + (set regexp-sym (pr-interactive-regexp mess)))) + + +(defun pr-set-ps-dir-args (n-up-sym dir-sym regexp-sym filename-sym mess) + ;; n-up + (or (symbol-value n-up-sym) + (set n-up-sym (pr-interactive-n-up mess))) + ;; directory & file name regexp + (pr-set-dir-args dir-sym regexp-sym mess) + ;; output file + (pr-set-outfilename filename-sym)) + + +(defun pr-find-buffer-visiting (file) + (if (not (file-directory-p file)) + (find-buffer-visiting (if ps-windows-system + (downcase file) + file)) + (let ((truename (file-truename file)) + (blist (buffer-list)) + found) + (while (and (not found) blist) + (save-excursion + (set-buffer (car blist)) + (and (eq major-mode 'dired-mode) + (save-excursion + (goto-char (point-min)) + (string= (buffer-substring-no-properties + (+ (point-min) 2) + (progn + (end-of-line) + (1- (point)))) + truename)) + (setq found (car blist)))) + (setq blist (cdr blist))) + found))) + + +(defun pr-file-list (dir file-regexp fun) + (mapcar #'(lambda (file) + (and (or pr-list-directory + (not (file-directory-p file))) + (let ((buffer (pr-find-buffer-visiting file)) + pop-up-windows + pop-up-frames) + (and (or buffer + (file-readable-p file)) + (save-excursion + (set-buffer (or buffer + (find-file-noselect file))) + (funcall fun) + (or buffer + (kill-buffer (current-buffer)))))))) + (directory-files dir t file-regexp))) + + +(defun pr-delete-file-if-exists (filename) + (and (not pr-spool-p) (stringp filename) (file-exists-p filename) + (delete-file filename))) + + +(defun pr-ps-file-list (n-up dir file-regexp filename) + (pr-delete-file-if-exists (setq filename (pr-expand-file-name filename))) + (let ((pr-spool-p t)) + (pr-file-list dir file-regexp + #'(lambda () + (if (pr-auto-mode-p) + (pr-ps-mode n-up filename) + (pr-text2ps 'buffer n-up filename))))) + (or pr-spool-p + (pr-despool-print filename))) + + +(defun pr-text2ps (kind n-up filename &optional from to) + (let ((ps-n-up-printing n-up) + (ps-spool-config (and (eq ps-spool-config 'setpagedevice) + 'setpagedevice))) + (pr-delete-file-if-exists filename) + (cond (pr-faces-p + (cond (pr-spool-p + ;; pr-faces-p and pr-spool-p + ;; here FILENAME arg is ignored + (cond ((eq kind 'buffer) + (ps-spool-buffer-with-faces)) + ((eq kind 'region) + (ps-spool-region-with-faces (or from (point)) + (or to (mark)))) + )) + ;; pr-faces-p and not pr-spool-p + ((eq kind 'buffer) + (ps-print-buffer-with-faces filename)) + ((eq kind 'region) + (ps-print-region-with-faces (or from (point)) + (or to (mark)) filename)) + )) + (pr-spool-p + ;; not pr-faces-p and pr-spool-p + ;; here FILENAME arg is ignored + (cond ((eq kind 'buffer) + (ps-spool-buffer)) + ((eq kind 'region) + (ps-spool-region (or from (point)) (or to (mark)))) + )) + ;; not pr-faces-p and not pr-spool-p + ((eq kind 'buffer) + (ps-print-buffer filename)) + ((eq kind 'region) + (ps-print-region (or from (point)) (or to (mark)) filename)) + ))) + + +(defun pr-command (command) + "Return absolute file name specification for COMMAND. + +If COMMAND is already an absolute file name specification, return it. +Else it uses `pr-path-alist' to find COMMAND, if find it then return it; +otherwise, gives an error. + +When using `pr-path-alist' to find COMMAND, the entries `cygwin', `windows' and +`unix' are used (see `pr-path-alist' for documentation). + +If Emacs is running on Windows 95/98/NT/2000, tries to find COMMAND, +COMMAND.exe, COMMAND.bat and COMMAND.com in this order." + (pr-dosify-path + (or (pr-find-command command) + (pr-path-command (cond (pr-cygwin-system 'cygwin) + (ps-windows-system 'windows) + (t 'unix)) + (file-name-nondirectory command) + nil) + (error "Command not found: %s" (file-name-nondirectory command))))) + + +(defun pr-path-command (symbol command sym-list) + (let ((lpath (cdr (assq symbol pr-path-alist))) + cmd) + ;; PATH expansion + (and (eq symbol 'PATH) (null lpath) + (setq lpath (parse-colon-path (getenv "PATH")))) + (while (and lpath + (not + (setq cmd + (let ((path (car lpath))) + (cond + ;; symbol expansion + ((symbolp path) + (and (not (memq path sym-list)) + (pr-path-command path command + (cons path sym-list)))) + ;; normal path + ((stringp path) + (pr-find-command + (expand-file-name + (substitute-in-file-name + (concat (file-name-as-directory path) + command))))) + ))))) + (setq lpath (cdr lpath))) + cmd)) + + +(defun pr-find-command (cmd) + (if ps-windows-system + ;; windows system + (let ((ext (cons (file-name-extension cmd t) + (list ".exe" ".bat" ".com"))) + found) + (setq cmd (file-name-sans-extension cmd)) + (while (and ext + (setq found (concat cmd (car ext))) + (not (and (file-regular-p found) + (file-executable-p found)))) + (setq ext (cdr ext) + found nil)) + found) + ;; non-windows systems + (and (file-regular-p cmd) + (file-executable-p cmd) + cmd))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Printing Interface (inspired on ps-print-interface.el) + + +(require 'widget) +(require 'wid-edit) +(require 'cus-edit) + + +(defvar pr-i-window-configuration nil) + +(defvar pr-i-buffer nil) +(defvar pr-i-region nil) +(defvar pr-i-mode nil) +(defvar pr-i-despool nil) +(defvar pr-i-ps-as-is t) +(defvar pr-i-n-up 1) +(defvar pr-i-directory "./") +(defvar pr-i-regexp "") +(defvar pr-i-ps-file "") +(defvar pr-i-out-file "") +(defvar pr-i-answer-yes nil) +(defvar pr-i-process 'buffer) +(defvar pr-i-ps-send 'printer) + + +(defvar pr-interface-map nil + "Keymap for pr-interface.") + +(if pr-interface-map + nil + (setq pr-interface-map (make-sparse-keymap)) + (cond ((eq ps-print-emacs-type 'xemacs) ; XEmacs + (pr-f-set-keymap-parents pr-interface-map (list widget-keymap)) + (pr-f-set-keymap-name pr-interface-map 'pr-interface-map)) + ((eq ps-print-emacs-type 'emacs) ; GNU Emacs + (pr-f-set-keymap-parents pr-interface-map widget-keymap))) + (define-key pr-interface-map "q" 'pr-interface-quit) + (define-key pr-interface-map "?" 'pr-interface-help)) + + +(defmacro pr-interface-save (&rest body) + `(save-excursion + (set-buffer pr-i-buffer) + ,@body)) + + +(defun pr-create-interface () + "Create the front end for printing package." + (setq pr-i-buffer (buffer-name (current-buffer)) + pr-i-region (ps-mark-active-p) + pr-i-mode (pr-mode-alist-p) + pr-i-window-configuration (current-window-configuration)) + + (put 'pr-i-process 'pr-widget-list nil) + (put 'pr-i-ps-send 'pr-widget-list nil) + + (delete-other-windows) + (kill-buffer (get-buffer-create pr-buffer-name)) + (switch-to-buffer (get-buffer-create pr-buffer-name)) + + ;; header + (let ((versions (concat "printing v" pr-version + " ps-print v" ps-print-version))) + (widget-insert (make-string (- 79 (length versions)) ?\ ) versions)) + (pr-insert-italic "\nCurrent Directory : " 1) + (pr-insert-italic default-directory) + + (pr-insert-section-1) ; 1. Print + (pr-insert-section-2) ; 2. PostScript Printer + (pr-insert-section-3) ; 3. Text Printer + + ;; separator + (widget-insert "\n\n " (make-string 77 ?-)) + + (pr-insert-section-4) ; 4. Settings + (pr-insert-section-5) ; 5. Customize + (pr-insert-section-6) ; 6. Show Settings + (pr-insert-section-7) ; 7. Help + + (use-local-map pr-interface-map) + (widget-setup) + (goto-char (point-min)) + + (and pr-i-region ; let region activated + (pr-keep-region-active))) + + +(defun pr-insert-section-1 () + ;; 1. Print: + (pr-insert-italic "\nPrint :" 1) + + ;; 1a. Buffer: + ;; 1a. Buffer: Buffer List + (pr-insert-radio-button 'pr-i-process 'buffer) + (pr-insert-menu "Buffer List" 'pr-i-buffer + (let ((blist (buffer-list)) + case-fold-search choices) + (while blist + (let ((name (buffer-name (car blist))) + (ignore pr-buffer-name-ignore) + found) + (setq blist (cdr blist)) + (while (and ignore (not found)) + (setq found (string-match (car ignore) name) + ignore (cdr ignore))) + (or found + (setq choices + (cons (list 'quote + (list 'choice-item + :format "%[%t%]" + name)) + choices))))) + (nreverse choices)) + " Buffer : " nil + '(progn + (pr-interface-save + (setq pr-i-region (ps-mark-active-p) + pr-i-mode (pr-mode-alist-p))) + (pr-update-checkbox 'pr-i-region) + (pr-update-checkbox 'pr-i-mode))) + ;; 1a. Buffer: Region + (put 'pr-i-region 'pr-widget + (pr-insert-checkbox + "\n " + 'pr-i-region + #'(lambda (widget &rest ignore) + (let ((region-p (pr-interface-save + (ps-mark-active-p)))) + (cond ((null (widget-value widget)) ; widget is nil + (setq pr-i-region nil)) + (region-p ; widget is true and there is a region + (setq pr-i-region t) + (widget-value-set widget t) + (widget-setup)) ; MUST be called after widget-value-set + (t ; widget is true and there is no region + (ding) + (message "There is no region active") + (setq pr-i-region nil) + (widget-value-set widget nil) + (widget-setup))))) ; MUST be called after widget-value-set + " Region")) + ;; 1a. Buffer: Mode + (put 'pr-i-mode 'pr-widget + (pr-insert-checkbox + " " + 'pr-i-mode + #'(lambda (widget &rest ignore) + (let ((mode-p (pr-interface-save + (pr-mode-alist-p)))) + (cond + ((null (widget-value widget)) ; widget is nil + (setq pr-i-mode nil)) + (mode-p ; widget is true and there is a `mode' + (setq pr-i-mode t) + (widget-value-set widget t) + (widget-setup)) ; MUST be called after widget-value-set + (t ; widget is true and there is no `mode' + (ding) + (message + "This buffer isn't in a mode that printing treats specially.") + (setq pr-i-mode nil) + (widget-value-set widget nil) + (widget-setup))))) ; MUST be called after widget-value-set + " Mode\n")) + + ;; 1b. Directory: + (pr-insert-radio-button 'pr-i-process 'directory) + (widget-create + 'directory + :size 58 + :format " Directory : %v" + :notify 'pr-interface-directory + :action (lambda (widget &optional event) + (if (pr-interface-directory widget) + (pr-widget-field-action widget event) + (ding) + (message "It should be a readable directory"))) + pr-i-directory) + ;; 1b. Directory: File Regexp + (widget-create 'regexp + :size 58 + :format "\n File Regexp : %v\n" + :notify (lambda (widget &rest ignore) + (setq pr-i-regexp (widget-value widget))) + pr-i-regexp) + ;; 1b. Directory: List Directory Entry + (widget-insert " ") + (pr-insert-toggle 'pr-list-directory " List Directory Entry\n") + + ;; 1c. PostScript File: + (pr-insert-radio-button 'pr-i-process 'file) + (widget-create + 'file + :size 51 + :format " PostScript File : %v" + :notify 'pr-interface-infile + :action (lambda (widget &rest event) + (if (pr-interface-infile widget) + (pr-widget-field-action widget event) + (ding) + (message "It should be a readable PostScript file"))) + pr-i-ps-file) + ;; 1c. PostScript File: PostScript Utility + (pr-insert-menu "PostScript Utility" 'pr-ps-utility + (pr-choice-alist pr-ps-utility-alist) + "\n PostScript Utility : " + " ") + ;; 1c. PostScript File: Use It AS-IS + (pr-insert-toggle 'pr-i-ps-as-is " Use It ") + (pr-insert-italic "AS-IS")) + + +(defun pr-insert-section-2 () + ;; 2. PostScript Printer: + ;; 2. PostScript Printer: PostScript Printer List + (pr-insert-italic "\n\nPostScript Printer : " 2 20) + (pr-insert-menu "PostScript Printer" 'pr-ps-name + (pr-choice-alist pr-ps-printer-alist)) + ;; 2. PostScript Printer: Despool + (put 'pr-i-despool 'pr-widget + (pr-insert-checkbox + " " + 'pr-i-despool + #'(lambda (widget &rest ignore) + (if pr-spool-p + (setq pr-i-despool (not pr-i-despool)) + (ding) + (message "It despool only when it's spooling") + (setq pr-i-despool nil)) + (widget-value-set widget pr-i-despool) + (widget-setup)) ; MUST be called after widget-value-set + " Despool ")) + ;; 2. PostScript Printer: Preview Print Quit + (pr-insert-button 'pr-interface-preview "Preview" " ") + (pr-insert-button 'pr-interface-ps-print "Print" " ") + (pr-insert-button 'pr-interface-quit "Quit") + ;; 2. PostScript Printer: Send to Printer/Temporary File + (pr-insert-radio-button 'pr-i-ps-send 'printer) + (widget-insert " Send to Printer/Temporary File") + ;; 2. PostScript Printer: Send to File + (pr-insert-radio-button 'pr-i-ps-send 'file) + (widget-create + 'file + :size 57 + :format " Send to File : %v" + :notify 'pr-interface-outfile + :action (lambda (widget &rest event) + (if (and (pr-interface-outfile widget) + (or (not (file-exists-p pr-i-out-file)) + (setq pr-i-answer-yes + (y-or-n-p "File exists; overwrite? ")))) + (pr-widget-field-action widget event) + (ding) + (message "It should be a writable PostScript file"))) + pr-i-out-file) + ;; 2. PostScript Printer: N-Up + (widget-create + 'integer + :size 3 + :format "\n N-Up : %v" + :notify (lambda (widget &rest ignore) + (let ((value (if (string= (widget-apply widget :value-get) "") + 0 + (widget-value widget)))) + (if (and (integerp value) + (<= 1 value) (<= value 100)) + (progn + (message " ") + (setq pr-i-n-up value)) + (ding) + (message "It should be an integer between 1 and 100")))) + pr-i-n-up)) + + +(defun pr-insert-section-3 () + ;; 3. Text Printer: + (pr-insert-italic "\n\nText Printer : " 2 14) + (pr-insert-menu "Text Printer" 'pr-txt-name + (pr-choice-alist pr-txt-printer-alist) + nil " ") + (pr-insert-button 'pr-interface-printify "Printify" " ") + (pr-insert-button 'pr-interface-txt-print "Print" " ") + (pr-insert-button 'pr-interface-quit "Quit")) + + +(defun pr-insert-section-4 () + ;; 4. Settings: + ;; 4. Settings: Landscape Auto Region Verbose + (pr-insert-checkbox "\n\n " 'ps-landscape-mode + #'(lambda (&rest ignore) + (setq ps-landscape-mode (not ps-landscape-mode) + pr-file-landscape ps-landscape-mode)) + " Landscape ") + (pr-insert-toggle 'pr-auto-region " Auto Region ") + (pr-insert-toggle 'pr-buffer-verbose " Verbose\n ") + + ;; 4. Settings: Print Header Auto Mode + (pr-insert-toggle 'ps-print-header " Print Header ") + (pr-insert-toggle 'pr-auto-mode " Auto Mode\n ") + + ;; 4. Settings: Print Header Frame Menu Lock + (pr-insert-toggle 'ps-print-header-frame " Print Header Frame ") + (pr-insert-toggle 'pr-menu-lock " Menu Lock\n ") + + ;; 4. Settings: Line Number + (pr-insert-toggle 'ps-line-number " Line Number\n ") + + ;; 4. Settings: Zebra Stripes Spool Buffer + (pr-insert-toggle 'ps-zebra-stripes " Zebra Stripes") + (pr-insert-checkbox " " + 'pr-spool-p + #'(lambda (&rest ignore) + (setq pr-spool-p (not pr-spool-p)) + (unless pr-spool-p + (setq pr-i-despool nil) + (pr-update-checkbox 'pr-i-despool))) + " Spool Buffer") + + ;; 4. Settings: Duplex Print with-faces + (pr-insert-checkbox "\n " + 'ps-spool-duplex + #'(lambda (&rest ignore) + (setq ps-spool-duplex (not ps-spool-duplex) + pr-file-duplex ps-spool-duplex)) + " Duplex ") + (pr-insert-toggle 'pr-faces-p " Print with-faces") + + ;; 4. Settings: Tumble Print Using Ghostscript + (pr-insert-checkbox "\n " + 'ps-spool-tumble + #'(lambda (&rest ignore) + (setq ps-spool-tumble (not ps-spool-tumble) + pr-file-tumble ps-spool-tumble)) + " Tumble ") + (pr-insert-toggle 'pr-print-using-ghostscript " Print Using Ghostscript\n ") + + ;; 4. Settings: Upside-Down Page Parity + (pr-insert-toggle 'ps-print-upside-down " Upside-Down ") + (pr-insert-menu "Page Parity" 'ps-even-or-odd-pages + (mapcar #'(lambda (alist) + (list 'quote + (list 'choice-item + :format "%[%t%]" + :tag (cdr alist) + :value (car alist)))) + pr-even-or-odd-alist))) + + +(defun pr-insert-section-5 () + ;; 5. Customize: + (pr-insert-italic "\n\nCustomize : " 2 11) + (pr-insert-button 'pr-customize "printing" " ") + (pr-insert-button #'(lambda (&rest ignore) (ps-print-customize)) + "ps-print" " ") + (pr-insert-button 'lpr-customize "lpr")) + + +(defun pr-insert-section-6 () + ;; 6. Show Settings: + (pr-insert-italic "\nShow Settings : " 1 14) + (pr-insert-button 'pr-show-pr-setup "printing" " ") + (pr-insert-button 'pr-show-ps-setup "ps-print" " ") + (pr-insert-button 'pr-show-lpr-setup "lpr")) + + +(defun pr-insert-section-7 () + ;; 7. Help: + (pr-insert-italic "\nHelp : " 1 5) + (pr-insert-button 'pr-interface-help "Interface Help" " ") + (pr-insert-button 'pr-help "Menu Help" " ") + (pr-insert-button 'pr-interface-quit "Quit" "\n ") + (pr-insert-button 'pr-kill-help "Kill All Printing Help Buffer")) + + +(defun pr-kill-help (&rest ignore) + "Kill all printing help buffer." + (interactive) + (let ((help '("*Printing Interface Help*" "*Printing Help*" + "*LPR Setup*" "*PR Setup*" "*PS Setup*"))) + (while help + (let ((buffer (get-buffer (car help)))) + (setq help (cdr help)) + (when buffer + (delete-windows-on buffer) + (kill-buffer buffer))))) + (recenter (- (window-height) 2))) + + +(defun pr-interface-quit (&rest ignore) + "Kill the printing buffer interface and quit." + (interactive) + (kill-buffer pr-buffer-name) + (set-window-configuration pr-i-window-configuration)) + + +(defun pr-interface-help (&rest ignore) + "printing buffer interface help." + (interactive) + (pr-show-setup pr-interface-help-message "*Printing Interface Help*")) + + +(defun pr-interface-txt-print (&rest ignore) + "Print using lpr package." + (interactive) + (condition-case data + (cond + ((eq pr-i-process 'directory) + (pr-i-directory) + (pr-interface-save + (pr-txt-directory pr-i-directory pr-i-regexp))) + ((eq pr-i-process 'buffer) + (pr-interface-save + (cond (pr-i-region + (let ((pr-auto-mode pr-i-mode)) + (pr-txt-region))) + (pr-i-mode + (let (pr-auto-region) + (pr-txt-mode))) + (t + (let (pr-auto-mode pr-auto-region) + (pr-txt-buffer))) + ))) + ((eq pr-i-process 'file) + (error "It should be a text file")) + (t + (error "Internal error: `pr-i-process' = %S" pr-i-process)) + ) + ;; handlers + ((quit error) + (ding) + (message (error-message-string data))))) + + +(defun pr-interface-printify (&rest ignore) + "Printify a buffer." + (interactive) + (condition-case data + (cond + ((eq pr-i-process 'directory) + (pr-i-directory) + (pr-interface-save + (pr-printify-directory pr-i-directory pr-i-regexp))) + ((eq pr-i-process 'buffer) + (pr-interface-save + (if pr-i-region + (pr-printify-region) + (pr-printify-buffer)))) + ((eq pr-i-process 'file) + (error "It can't printify a PostScript file")) + (t + (error "Internal error: `pr-i-process' = %S" pr-i-process)) + ) + ;; handlers + ((quit error) + (ding) + (message (error-message-string data))))) + + +(defun pr-interface-ps-print (&rest ignore) + "Print using ps-print package." + (interactive) + (pr-interface-ps 'pr-despool-ps-print 'pr-ps-directory-ps-print + 'pr-ps-file-ps-print 'pr-ps-file-up-ps-print + 'pr-ps-region-ps-print 'pr-ps-mode-ps-print + 'pr-ps-buffer-ps-print)) + + +(defun pr-interface-preview (&rest ignore) + "Preview a PostScript file." + (interactive) + (pr-interface-ps 'pr-despool-preview 'pr-ps-directory-preview + 'pr-ps-file-preview 'pr-ps-file-up-preview + 'pr-ps-region-preview 'pr-ps-mode-preview + 'pr-ps-buffer-preview)) + + +(defun pr-interface-ps (ps-despool ps-directory ps-file ps-file-up ps-region + ps-mode ps-buffer) + (condition-case data + (let ((outfile (or (and (eq pr-i-process 'file) pr-i-ps-as-is) + (pr-i-ps-send)))) + (cond + ((and pr-i-despool pr-spool-p) + (pr-interface-save + (funcall ps-despool outfile)) + (setq pr-i-despool nil) + (pr-update-checkbox 'pr-i-despool)) + ((eq pr-i-process 'directory) + (pr-i-directory) + (pr-interface-save + (funcall ps-directory + pr-i-n-up pr-i-directory pr-i-regexp outfile))) + ((eq pr-i-process 'file) + (cond ((or (file-directory-p pr-i-ps-file) + (not (file-readable-p pr-i-ps-file))) + (error "It should be a readable PostScript file")) + (pr-i-ps-as-is + (pr-interface-save + (funcall ps-file pr-i-ps-file))) + (t + (pr-interface-save + (funcall ps-file-up pr-i-n-up pr-i-ps-file outfile))) + )) + ((eq pr-i-process 'buffer) + (pr-interface-save + (cond (pr-i-region + (let ((pr-auto-mode pr-i-mode)) + (funcall ps-region pr-i-n-up outfile))) + (pr-i-mode + (let (pr-auto-region) + (funcall ps-mode pr-i-n-up outfile))) + (t + (let (pr-auto-mode pr-auto-region) + (funcall ps-buffer pr-i-n-up outfile))) + ))) + (t + (error "Internal error: `pr-i-process' = %S" pr-i-process)) + )) + ;; handlers + ((quit error) + (ding) + (message (error-message-string data))))) + + +(defun pr-i-ps-send () + (cond ((eq pr-i-ps-send 'printer) + nil) + ((not (eq pr-i-ps-send 'file)) + (error "Internal error: `pr-i-ps-send' = %S" pr-i-ps-send)) + ((or (file-directory-p pr-i-out-file) + (not (file-writable-p pr-i-out-file))) + (error "It should be a writable PostScript file")) + ((or (not (file-exists-p pr-i-out-file)) + pr-i-answer-yes + (setq pr-i-answer-yes + (y-or-n-p (format "File `%s' exists; overwrite? " + pr-i-out-file)))) + pr-i-out-file) + (t + (error "File already exists")))) + + +(defun pr-i-directory () + (or (and (file-directory-p pr-i-directory) + (file-readable-p pr-i-directory)) + (error "It should be a readable directory"))) + + +(defun pr-interface-directory (widget &rest ignore) + (and pr-buffer-verbose + (message "Type M-TAB or ESC TAB for file completion")) + (let ((dir (widget-value widget))) + (and (file-directory-p dir) + (file-readable-p dir) + (setq pr-i-directory dir)))) + + +(defun pr-interface-infile (widget &rest ignore) + (and pr-buffer-verbose + (message "Type M-TAB or ESC TAB for file completion")) + (let ((file (widget-value widget))) + (and (not (file-directory-p file)) + (file-readable-p file) + (setq pr-i-ps-file file)))) + + +(defun pr-interface-outfile (widget &rest ignore) + (setq pr-i-answer-yes nil) + (and pr-buffer-verbose + (message "Type M-TAB or ESC TAB for file completion")) + (let ((file (widget-value widget))) + (and (not (file-directory-p file)) + (file-writable-p file) + (setq pr-i-out-file file)))) + + +(defun pr-widget-field-action (widget event) + (and (get-buffer "*Completions*") ; clean frame window + (delete-windows-on "*Completions*")) + (message " ") ; clean echo area + (widget-field-action widget event)) + + +(defun pr-insert-italic (str &optional from to) + (let ((len (length str))) + (put-text-property (if from (max from 0) 0) + (if to (max to len) len) + 'face 'italic str) + (widget-insert str))) + + +(defun pr-insert-checkbox (before var-sym fun label) + (widget-insert before) + (prog1 + (widget-create 'checkbox + :notify fun + (symbol-value var-sym)) + (widget-insert label))) + + +(defun pr-insert-toggle (var-sym label) + (widget-create 'checkbox + :notify `(lambda (&rest ignore) + (setq ,var-sym (not ,var-sym))) + (symbol-value var-sym)) + (widget-insert label)) + + +(defun pr-insert-button (fun label &optional separator) + (widget-create 'push-button + :notify fun + label) + (and separator + (widget-insert separator))) + + +(defun pr-insert-menu (tag var-sym choices &optional before after &rest body) + (and before (widget-insert before)) + (eval `(widget-create 'menu-choice + :tag ,tag + :format "%v" + :inline t + :value ,var-sym + :notify (lambda (widget &rest ignore) + (setq ,var-sym (widget-value widget)) + ,@body) + :void '(choice-item :format "%[%t%]" + :tag "Can not display value!") + ,@choices)) + (and after (widget-insert after))) + + +(defun pr-insert-radio-button (var-sym sym) + (widget-insert "\n") + (let ((wid-list (get var-sym 'pr-widget-list)) + (wid (eval `(widget-create + 'radio-button + :format " %[%v%]" + :value (eq ,var-sym (quote ,sym)) + :notify (lambda (&rest ignore) + (setq ,var-sym (quote ,sym)) + (pr-update-radio-button (quote ,var-sym))))))) + (put var-sym 'pr-widget-list (cons (cons wid sym) wid-list)))) + + +(defun pr-update-radio-button (var-sym) + (let ((wid-list (get var-sym 'pr-widget-list))) + (while wid-list + (let ((wid (car (car wid-list))) + (value (cdr (car wid-list)))) + (setq wid-list (cdr wid-list)) + (widget-value-set wid (eq (symbol-value var-sym) value)))) + (widget-setup))) + + +(defun pr-update-checkbox (var-sym) + (let ((wid (get var-sym 'pr-widget))) + (when wid + (widget-value-set wid (symbol-value var-sym)) + (widget-setup)))) + + +(defun pr-choice-alist (alist) + (let ((max (apply 'max (mapcar #'(lambda (alist) + (length (symbol-name (car alist)))) + alist)))) + (mapcar #'(lambda (alist) + (let* ((sym (car alist)) + (name (symbol-name sym))) + (list + 'quote + (list + 'choice-item + :format "%[%t%]" + :tag (concat name + (make-string (- max (length name)) ?_)) + :value sym)))) + alist))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(pr-update-menus t) + + +(provide 'printing) + + +;;; printing.el ends here