]> git.eshelyaron.com Git - emacs.git/commitdiff
New file.
authorKim F. Storm <storm@cua.dk>
Fri, 7 Feb 2003 21:06:51 +0000 (21:06 +0000)
committerKim F. Storm <storm@cua.dk>
Fri, 7 Feb 2003 21:06:51 +0000 (21:06 +0000)
Assigned by Vinicius Jose Latorre <vinicius@cpqd.com.br>

lisp/printing.el [new file with mode: 0644]

diff --git a/lisp/printing.el b/lisp/printing.el
new file mode 100644 (file)
index 0000000..c53b41b
--- /dev/null
@@ -0,0 +1,6232 @@
+;;; printing.el --- printing utilities
+
+;; Copyright (C) 2000, 2001, 2002
+;; Free Software Foundation, Inc.
+
+;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; 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 <vinicius@cpqd.com.br>
+")
+
+;; 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 <frederic.corne@erli.fr>
+;;      Special printing functions for Windows NT
+;;
+;;    mh-e-init.el           Tom Vogels <tov@ece.cmu.edu>
+;;      PS-print for mail messages
+;;
+;;    win32-ps-print.el              Matthew O. Persico <mpersico@erols.com>
+;;      PostScript printing with ghostscript
+;;
+;;    ps-print-interface.el   Volker Franz <volker.franz@tuebingen.mpg.de>
+;;      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 <f.labrosse@maths.bath.ac.uk> for XEmacs tests.
+;;
+;; Thanks to Klaus Berndl <klaus.berndl@sdm.de> 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 <storm@filanet.dk> 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 <frederic.corne@erli.fr>          print-nt.el
+;;    Tom Vogels <tov@ece.cmu.edu>                     mh-e-init.el
+;;    Matthew O. Persico <mpersico@erols.com>          win32-ps-print.el
+;;    Volker Franz <volker.franz@tuebingen.mpg.de>     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 <tov@ece.cmu.edu>)
+
+
+(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