(diary-face, holiday-face): Add dark-background variants.
[bpt/emacs.git] / lisp / ps-print.el
index 69bf1fc..8d46574 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ps-print.el --- Print text from the buffer as PostScript
 
-;; Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 2000 Free Software Foundation, Inc.
 
 ;; Author:     Jim Thompson (was <thompson@wg2.waii.com>)
 ;; Author:     Jacques Duthen (was <duthen@cegelec-red.fr>)
@@ -9,16 +9,16 @@
 ;; Maintainer: Kenichi Handa <handa@etl.go.jp> (multi-byte characters)
 ;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;; Keywords:   wp, print, PostScript
-;; Time-stamp: <99/12/11 20:14:41 vinicius>
-;; Version:    5.0.2
+;; Time-stamp: <2000/10/28 23:38:44 Vinicius>
+;; Version:    6.3
+;; X-URL:      http://www.cpqd.com.br/~vinicius/emacs/
 
-(defconst ps-print-version "5.0.2"
-  "ps-print.el, v 5.0.2 <99/12/11 vinicius>
+(defconst ps-print-version "6.3"
+  "ps-print.el, v 6.3 <2000/10/28 vinicius>
 
 Vinicius's last change version -- this file may have been edited as part of
-Emacs without changes to the version number.  When reporting bugs,
-please also report the version of Emacs, if any, that ps-print was
-distributed with.
+Emacs without changes to the version number.  When reporting bugs, please also
+report the version of Emacs, if any, that ps-print was distributed with.
 
 Please send all bug fixes and enhancements to
        Vinicius Jose Latorre <vinicius@cpqd.com.br>.
@@ -183,19 +183,36 @@ Please send all bug fixes and enhancements to
 ;; The variable `ps-printer-name' determines the name of a local printer for
 ;; printing PostScript files.
 ;;
+;; The variable `ps-printer-name-option' determines the option used by some
+;; utilities to indicate the printer name, it's used only when
+;; `ps-printer-name' is a non-empty string.  If you're using lpr utility to
+;; print, for example, `ps-printer-name-option' should be set to "-P".
+;;
 ;; NOTE: `ps-lpr-command' and `ps-lpr-switches' take their initial values
 ;;       from the variables `lpr-command' and `lpr-switches'.  If you have
 ;;       `lpr-command' set to invoke a pretty-printer such as `enscript',
 ;;       then ps-print won't work properly.  `ps-lpr-command' must name
 ;;       a program that does not format the files it prints.
 ;;       `ps-printer-name' takes its initial value from the variable
-;;       `printer-name'.
+;;       `printer-name'.  `ps-printer-name-option' tries to guess which system
+;;       Emacs is running and takes its initial value in accordance with this
+;;       guess.
 ;;
 ;; The variable `ps-print-region-function' specifies a function to print the
 ;; region on a PostScript printer.
 ;; See definition of `call-process-region' for calling conventions.  The fourth
 ;; and the sixth arguments are both nil.
 ;;
+;; The variable `ps-manual-feed' indicates if the printer will manually feed
+;; paper.  If it's nil, automatic feeding takes place.  If it's non-nil, manual
+;; feeding takes place.  The default is nil (automatic feeding).
+;;
+;; If you're using Emacs for Windows 95/98/NT or MS-DOS, don't forget to
+;; customize the following variables: `ps-printer-name',
+;; `ps-printer-name-option', `ps-lpr-command', `ps-lpr-switches' and
+;; `ps-spool-config'.  See these variables documentation in the code or by
+;; typing, for example, C-h v ps-printer-name RET.
+;;
 ;;
 ;; The Page Layout
 ;; ---------------
@@ -204,30 +221,65 @@ Please send all bug fixes and enhancements to
 ;; 1 inch  ==       2.54  cm    ==     72       points
 ;; 1 cm    ==  (/ 1 2.54) inch  ==  (/ 72 2.54) points
 ;;
-;; The variable `ps-paper-type' determines the size of paper ps-print
-;; formats for; it should contain one of the symbols:
-;; `a4' `a3' `letter' `legal' `letter-small' `tabloid'
-;; `ledger' `statement' `executive' `a4small' `b4' `b5'
-;;
-;; The variable `ps-landscape-mode' determines the orientation
-;; of the printing on the page:
-;; nil means `portrait' mode, non-nil means `landscape' mode.
+;; The variable `ps-paper-type' determines the size of paper ps-print formats
+;; for; it should contain one of the symbols: `a4' `a3' `letter' `legal'
+;; `letter-small' `tabloid' `ledger' `statement' `executive' `a4small' `b4'
+;; `b5'.
+;;
+;; If variable `ps-warn-paper-type' is nil, it's *not* given an error if
+;; PostScript printer doesn't have a paper with the size indicated by
+;; `ps-paper-type', instead it uses the default paper size.  If variable
+;; `ps-warn-paper-type' is non-nil, it's given an error if PostScript printer
+;; doesn't have a paper with the size indicated by `ps-paper-type'.  It's used
+;; when `ps-spool-config' is set to `setpagedevice' (see section Duplex
+;; Printers).  The default value is non-nil (it gives an error).
+;;
+;; The variable `ps-landscape-mode' determines the orientation of the printing
+;; on the page: nil means `portrait' mode, non-nil means `landscape' mode.
 ;; There is no oblique mode yet, though this is easy to do in ps.
 ;;
-;; In landscape mode, the text is NOT scaled: you may print 70 lines
-;; in portrait mode and only 50 lignes in landscape mode.
-;; The margins represent margins in the printed paper:
-;; the top margin is the margin between the top of the page
+;; In landscape mode, the text is NOT scaled: you may print 70 lines in portrait
+;; mode and only 50 lines in landscape mode.  The margins represent margins in
+;; the printed paper: the top margin is the margin between the top of the page
 ;; and the printed header, whatever the orientation is.
 ;;
-;; The variable `ps-number-of-columns' determines the number of columns
-;; both in landscape and portrait mode.
+;; The variable `ps-number-of-columns' determines the number of columns both in
+;; landscape and portrait mode.
 ;; You can use:
-;; - (the standard) one column portrait mode
-;; - (my favorite) two columns landscape mode (which spares trees)
-;; but also
+;; - (the standard) one column portrait mode.
+;; - (my favorite) two columns landscape mode (which spares trees).
+;; but also:
 ;; - one column landscape mode for files with very long lines.
-;; - multi-column portrait or landscape mode
+;; - multi-column portrait or landscape mode.
+;;
+;; The variable `ps-print-upside-down' determines other orientation for printing
+;; page: nil means `normal' printing, non-nil means `upside-down' printing.  The
+;; default value is nil (`normal' printing).
+;;
+;; The `upside-down' orientation can be used in portrait or landscape mode.
+;;
+;; The variable `ps-selected-pages' specifies which pages to print.  If it's
+;; nil, all pages are printed.  If it's a list, the list element may be an
+;; integer or a cons cell (FROM . TO) designating FROM page to TO page; any
+;; invalid element is ignored, that is, an integer lesser than one or if FROM
+;; is greater than TO.  Otherwise, it's treated as nil.  The default value is
+;; nil (print all pages).  After ps-print processing `ps-selected-pages' is set
+;; to nil.  But the latest `ps-selected-pages' is saved in
+;; `ps-last-selected-pages' (see it for documentation).  So you can restore the
+;; latest selected pages by using `ps-last-selected-pages' or by calling
+;; `ps-restore-selected-pages' command (see it for documentation).
+;;
+;; The variable `ps-even-or-odd-pages' specifies if it prints even/odd pages.
+;;
+;; Valid values are:
+;;
+;; nil         print all pages.
+;;
+;; even                print only even pages.
+;;
+;; odd         print only odd pages.
+;;
+;; Any other value is treated as nil.  The default value is nil.
 ;;
 ;;
 ;; Horizontal layout
@@ -298,6 +350,17 @@ Please send all bug fixes and enhancements to
 ;; To print only one header at the top of each page,
 ;; set `ps-print-only-one-header' to t.
 ;;
+;; To switch headers, set `ps-switch-header' to:
+;;
+;;    nil      Never switch headers.
+;;
+;;    t                Always switch headers.
+;;
+;;    duplex   Switch headers only when duplexing is on, that is, when
+;;             `ps-spool-duplex' is non-nil (see Duplex Printers).
+;;
+;; Any other value is treated as t.  The default value is `duplex'.
+;;
 ;; The font family and size of text in the header are determined
 ;; by the variables `ps-header-font-family', `ps-header-font-size' and
 ;; `ps-header-title-font-size' (see below).
@@ -306,7 +369,7 @@ Please send all bug fixes and enhancements to
 ;; title line height to insert between the header frame and the text
 ;; it contains, both in the vertical and horizontal directions:
 ;; .5 means half a line.
-
+;;
 ;; Page numbers are printed in `n/m' format, indicating page n of m pages;
 ;; to omit the total page count and just print the page number,
 ;; set `ps-show-n-of-n' to nil.
@@ -394,6 +457,63 @@ Please send all bug fixes and enhancements to
 ;;    Adobe Systems Incorporated
 ;;    Appendix G: Document Structuring Conventions -- Version 3.0
 ;;
+;; It is also possible to add an user defined PostScript prologue code before
+;; all generated prologue code by setting the variable
+;; `ps-user-defined-prologue'.
+;;
+;; `ps-user-defined-prologue' may be a string or a symbol function which returns
+;; a string.  Note that this string is inserted after `ps-adobe-tag' and
+;; PostScript prologue comments, and before ps-print PostScript prologue code
+;; section.  That is, this string is inserted after error handler initialization
+;; and before ps-print settings.
+;;
+;; By default `ps-user-defined-prologue' is nil.
+;;
+;; It's strongly recommended only insert PostScript code and/or comments
+;; specific for your printing system particularities.  For example, some special
+;; initialization that only your printing system needs.
+;;
+;; Do not insert code for duplex printing, n-up printing or error handler,
+;; ps-print handles this in a suitable way.
+;;
+;; For more information about PostScript, see:
+;;    PostScript Language Reference Manual (2nd edition)
+;;    Adobe Systems Incorporated
+;;
+;; As an example for `ps-user-defined-prologue' setting:
+;;
+;;   ;; Setting for HP PostScript printer
+;;   (setq ps-user-defined-prologue
+;;        (concat "<</DeferredMediaSelection true /PageSize [612 792] "
+;;                "/MediaPosition 2 /MediaType (Plain)>> setpagedevice"))
+;;
+;;
+;; PostScript Error Handler
+;; ------------------------
+;;
+;; ps-print instruments generated PostScript code with an error handler.
+;;
+;; The variable `ps-error-handler-message' specifies where the error handler
+;; message should be sent.
+;;
+;; Valid values are:
+;;
+;; none                        catch the error and *DON'T* send any message.
+;;
+;; paper               catch the error and print on paper the error message.
+;;                     This is the default value.
+;;
+;; system              catch the error and send back the error message to
+;;                     printing system.  This is useful only if printing system
+;;                     send back an email reporting the error, or if there is
+;;                     some other alternative way to report back the error from
+;;                     the system to you.
+;;
+;; paper-and-system    catch the error, print on paper the error message and
+;;                     send back the error message to printing system.
+;;
+;; Any other value is treated as `paper'.
+;;
 ;;
 ;; Duplex Printers
 ;; ---------------
@@ -535,6 +655,58 @@ Please send all bug fixes and enhancements to
 ;; The variable `ps-line-number' specifies whether to number each line;
 ;; non-nil means do so.  The default is nil (don't number each line).
 ;;
+;; The variable `ps-line-number-step' specifies the interval that line number is
+;; printed.  For example, if `ps-line-number-step' is set to 2, the printing
+;; will look like:
+;;
+;;    1 one line
+;;      one line
+;;    3 one line
+;;      one line
+;;    5 one line
+;;      one line
+;;      ...
+;;
+;; Valid values are:
+;;
+;; integer     an integer that specifies the interval that line number is
+;;             printed.  If it's lesser than or equal to zero, it's used the
+;;             value 1.
+;;
+;; `zebra'     specifies that only the line number of the first line in a zebra
+;;             stripe is to be printed.
+;;
+;; Any other value is treated as `zebra'.
+;; The default value is 1, so each line number is printed.
+;;
+;; The variable `ps-line-number-start' specifies the starting point in the
+;; interval given by `ps-line-number-step'.  For example, if
+;; `ps-line-number-step' is set to 3 and `ps-line-number-start' is set to 3, the
+;; printing will look like:
+;;
+;;      one line
+;;      one line
+;;    3 one line
+;;      one line
+;;      one line
+;;    6 one line
+;;      one line
+;;      one line
+;;    9 one line
+;;      one line
+;;      ...
+;;
+;; The values for `ps-line-number-start':
+;;
+;;    * If `ps-line-number-step' is an integer, must be between 1 and the value
+;;     of `ps-line-number-step' inclusive.
+;;
+;;    * If `ps-line-number-step' is set to `zebra', must be between 1 and the
+;;     value of `ps-zebra-stripe-height' inclusive.
+;;
+;; The default value is 1, so the line number of the first line of each interval
+;; is printed.
+;;
 ;;
 ;; Zebra Stripes
 ;; -------------
@@ -562,9 +734,39 @@ Please send all bug fixes and enhancements to
 ;; The variable `ps-zebra-stripes' controls whether to print zebra stripes.
 ;; Non-nil means yes, nil means no.  The default is nil.
 ;;
-;; The variable `ps-zebra-gray' controls the zebra stripes gray scale.
-;; It should be a float number between 0.0 (black color) and 1.0 (white color).
-;; The default is 0.95.
+;; The variable `ps-zebra-color' controls the zebra stripes gray scale or RGB
+;; color.  It should be a float number between 0.0 (black color) and 1.0 (white
+;; color), a string which is a color name, or a list of 3 numbers which
+;; corresponds to the Red Green Blue color scale.
+;; The default is 0.95 (or "gray95", or '(0.95 0.95 0.95)).
+;;
+;; The variable `ps-zebra-stripe-follow' specifies if zebra stripe should
+;; continue on next page or restart on each page.  If `ps-zebra-stripe-follow'
+;; is nil, zebra stripe is restarted on each page.  If `ps-zebra-stripe-follow'
+;; is non-nil, zebra stripe continues on next page.  Visually, we have:
+;;
+;;             `ps-zebra-stripe-follow'        `ps-zebra-stripe-follow'
+;;                is nil                          is non-nil
+;; Current Page ------------------------       ------------------------
+;;             1  XXXXXXXXXXXXXXXXXXXXX        1  XXXXXXXXXXXXXXXXXXXXX
+;;             2  XXXXXXXXXXXXXXXXXXXXX        2  XXXXXXXXXXXXXXXXXXXXX
+;;             3  XXXXXXXXXXXXXXXXXXXXX        3  XXXXXXXXXXXXXXXXXXXXX
+;;             4                               4
+;;             5                               5
+;;             6                               6
+;;             7  XXXXXXXXXXXXXXXXXXXXX        7  XXXXXXXXXXXXXXXXXXXXX
+;;             8  XXXXXXXXXXXXXXXXXXXXX        8  XXXXXXXXXXXXXXXXXXXXX
+;;             ------------------------        ------------------------
+;;    Next Page ------------------------       ------------------------
+;;             9  XXXXXXXXXXXXXXXXXXXXX        9  XXXXXXXXXXXXXXXXXXXXX
+;;             10 XXXXXXXXXXXXXXXXXXXXX        10
+;;             11 XXXXXXXXXXXXXXXXXXXXX        11
+;;             12                              12
+;;             13                              13 XXXXXXXXXXXXXXXXXXXXX
+;;             14                              14 XXXXXXXXXXXXXXXXXXXXX
+;;             15 XXXXXXXXXXXXXXXXXXXXX        15 XXXXXXXXXXXXXXXXXXXXX
+;;             16 XXXXXXXXXXXXXXXXXXXXX        16
+;;             ------------------------        ------------------------
 ;;
 ;; See also section How Ps-Print Has A Text And/Or Image On Background.
 ;;
@@ -638,11 +840,11 @@ Please send all bug fixes and enhancements to
 ;; - create a new buffer
 ;; - generate the PostScript image to a file (C-u M-x ps-print-buffer)
 ;; - open this file and find the line:
-;;     `% 3 cm 20 cm moveto  10 /Courier ReportFontInfo  showpage'
+;;     `% 3 cm 20 cm moveto  10/Courier ReportFontInfo  showpage'
 ;; - delete the leading `%' (which is the PostScript comment character)
 ;; - replace in this line `Courier' by the new font (say `Helvetica')
 ;;   to get the line:
-;;     `3 cm 20 cm moveto  10 /Helvetica ReportFontInfo  showpage'
+;;     `3 cm 20 cm moveto  10/Helvetica ReportFontInfo  showpage'
 ;; - send this file to the printer (or to ghostscript).
 ;;   You should read the following on the output page:
 ;;
@@ -720,8 +922,10 @@ Please send all bug fixes and enhancements to
 ;; The PostScript file should be sent to YOUR PostScript printer.
 ;; If you send it to ghostscript or to another PostScript printer,
 ;; you may get slightly different results.
-;; Anyway, as ghostscript fonts are autoload, you won't get
-;; much font info.
+;; Anyway, as ghostscript fonts are autoload, you won't get much font info.
+;;
+;; Note also that ps-print DOESN'T download any font to your printer, instead
+;; it uses the fonts resident in your printer.
 ;;
 ;;
 ;; How Ps-Print Deals With Faces
@@ -759,6 +963,17 @@ Please send all bug fixes and enhancements to
 ;; rebuilt when ps-print is invoked, set the variable
 ;; `ps-always-build-face-reference' to t.
 ;;
+;; If you need to print without worrying about face background color, set the
+;; variable `ps-use-face-background' which specifies if face background should
+;; be used.  Valid values are:
+;;
+;;    t                always use face background color.
+;;    nil      never use face background color.
+;;    (face...)        list of faces whose background color will be used.
+;;
+;; Any other value will be treated as t.
+;; The default value is t.
+;;
 ;;
 ;; How Ps-Print Deals With Color
 ;; -----------------------------
@@ -767,7 +982,7 @@ Please send all bug fixes and enhancements to
 ;; defined and embeds color information in the PostScript image.
 ;; The default foreground and background colors are defined by the
 ;; variables `ps-default-fg' and `ps-default-bg'.
-;; On black-and-white printers, colors are displayed in grayscale.
+;; On black-and-white printers, colors are displayed in gray scale.
 ;; To turn off color output, set `ps-print-color-p' to nil.
 ;;
 ;;
@@ -840,13 +1055,14 @@ Please send all bug fixes and enhancements to
 ;;
 ;; The printing order is:
 ;;
-;;    1. Print zebra stripes
-;;    2. Print background texts that it should be on all pages
-;;    3. Print background images that it should be on all pages
-;;    4. Print background texts only for current page (if any)
-;;    5. Print background images only for current page (if any)
-;;    6. Print header
-;;    7. Print buffer text (with faces, if specified) and line number
+;;    1. Print background color
+;;    2. Print zebra stripes
+;;    3. Print background texts that it should be on all pages
+;;    4. Print background images that it should be on all pages
+;;    5. Print background texts only for current page (if any)
+;;    6. Print background images only for current page (if any)
+;;    7. Print header
+;;    8. Print buffer text (with faces, if specified) and line number
 ;;
 ;;
 ;; Utilities
@@ -890,60 +1106,72 @@ Please send all bug fixes and enhancements to
 ;; New since version 2.8
 ;; ---------------------
 ;;
-;; [vinicius] 991211 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; [vinicius] Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;;
-;; `ps-print-customize'.
+;;    20000821
+;;      `ps-even-or-odd-pages'
 ;;
-;; [vinicius] 990703 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;;    20000617
+;;      `ps-manual-feed', `ps-warn-paper-type', `ps-print-upside-down',
+;;      `ps-selected-pages', `ps-last-selected-pages',
+;;      `ps-restore-selected-pages', `ps-switch-header',
+;;      `ps-line-number-step', `ps-line-number-start',
+;;      `ps-zebra-stripe-follow' and `ps-use-face-background'.
 ;;
-;; Better customization.
-;; `ps-banner-page-when-duplexing' and `ps-zebra-gray'.
+;;    20000310
+;;      PostScript error handler.
+;;      `ps-user-defined-prologue' and `ps-error-handler-message'.
 ;;
-;; [vinicius] 990513 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;;    19991211
+;;      `ps-print-customize'.
 ;;
-;; N-up printing.
-;; Hook: `ps-print-begin-sheet-hook'.
+;;    19990703
+;;      Better customization.
+;;      `ps-banner-page-when-duplexing' and `ps-zebra-color'.
 ;;
-;; [keinichi] 990509 Kein'ichi Handa <handa@etl.go.jp>
+;;    19990513
+;;      N-up printing.
+;;      Hook: `ps-print-begin-sheet-hook'.
 ;;
-;; `ps-print-region-function'
+;; [keinichi] 19990509 Kein'ichi Handa <handa@etl.go.jp>
 ;;
-;; [vinicius] 990301 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; `ps-print-region-function'
 ;;
-;; PostScript tumble and setpagedevice.
+;; [vinicius] Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;;
-;; [vinicius] 980922 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;;    19990301
+;;      PostScript tumble and setpagedevice.
 ;;
-;; PostScript prologue header comment insertion.
-;; Skip invisible text better.
+;;    19980922
+;;      PostScript prologue header comment insertion.
+;;      Skip invisible text better.
 ;;
-;; [keinichi] 980819 Kein'ichi Handa <handa@etl.go.jp>
+;; [keinichi] 19980819 Kein'ichi Handa <handa@etl.go.jp>
 ;;
 ;; Multi-byte buffer handling.
 ;;
-;; [vinicius] 980306 Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;;
-;; Skip invisible text.
-;;
-;; [vinicius] 971130 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; [vinicius] Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;;
-;; Hooks: `ps-print-hook', `ps-print-begin-page-hook' and
-;; `ps-print-begin-column-hook'.
-;; Put one header per page over the columns.
-;; Better database font management.
-;; Better control characters handling.
+;;    19980306
+;;      Skip invisible text.
 ;;
-;; [vinicius] 971121 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;;    19971130
+;;      Hooks: `ps-print-hook', `ps-print-begin-page-hook' and
+;;      `ps-print-begin-column-hook'.
+;;      Put one header per page over the columns.
+;;      Better database font management.
+;;      Better control characters handling.
 ;;
-;; Dynamic evaluation at print time of `ps-lpr-switches'.
-;; Handle control characters.
-;; Face remapping.
-;; New face attributes.
-;; Line number.
-;; Zebra stripes.
-;; Text and/or image on background.
+;;    19971121
+;;      Dynamic evaluation at print time of `ps-lpr-switches'.
+;;      Handle control characters.
+;;      Face remapping.
+;;      New face attributes.
+;;      Line number.
+;;      Zebra stripes.
+;;      Text and/or image on background.
 ;;
-;; [jack] 960517 Jacques Duthen <duthen@cegelec-red.fr>
+;; [jack] 19960517 Jacques Duthen <duthen@cegelec-red.fr>
 ;;
 ;; Font family and float size for text and header.
 ;; Landscape mode.
@@ -976,7 +1204,7 @@ Please send all bug fixes and enhancements to
 ;;
 ;; Faces are always treated as opaque.
 ;;
-;; Epoch and Emacs 18 not supported.  At all.
+;; Epoch and Emacs 19 not supported.  At all.
 ;;
 ;; Fixed-pitch fonts work better for line folding, but are not required.
 ;;
@@ -997,6 +1225,22 @@ Please send all bug fixes and enhancements to
 ;; Acknowledgements
 ;; ----------------
 ;;
+;; Thanks to Gord Wait <Gord_Wait@spectrumsignal.com> for
+;; `ps-user-defined-prologue' example setting for HP PostScript printer.
+;;
+;; Thanks to Paul Furnanz <pfurnanz@synopsys.com> for XEmacs compatibility
+;; suggestion for `ps-postscript-code-directory' variable.
+;;
+;; Thanks to David X Callaway <dxc@xprt.net> for helping debugging PostScript
+;; level 1 compatibility.
+;;
+;; Thanks to Colin Marquardt <colin.marquardt@usa.alcatel.com> for upside-down,
+;; line number step, line number start and zebra stripe follow suggestions, and
+;; for XEmacs beta-tests.
+;;
+;; Thanks to Klaus Berndl <klaus.berndl@sdm.de> for user defined PostScript
+;; prologue code suggestion and for odd/even printing suggestion.
+;;
 ;; Thanks to Kein'ichi Handa <handa@etl.go.jp> for multi-byte buffer handling.
 ;;
 ;; Thanks to Matthew O Persico <Matthew.Persico@lazard.com> for line number on
@@ -1057,25 +1301,71 @@ Please send all bug fixes and enhancements to
 
 ;;; Code:
 
-(unless (featurep 'lisp-float-type)
-  (error "`ps-print' requires floating point support"))
+(eval-and-compile
+  (unless (featurep 'lisp-float-type)
+    (error "`ps-print' requires floating point support"))
+
+
+  ;; For Emacs 20.2 and the earlier version.
 
+  (or (fboundp 'set-buffer-multibyte)
+      (defun set-buffer-multibyte (arg)
+       (setq enable-multibyte-characters arg)))
 
-;; For Emacs 20.2 and the earlier version.
+  (or (fboundp 'string-as-unibyte)
+      (defun string-as-unibyte (arg) arg))
 
-(or (fboundp 'set-buffer-multibyte)
-    (defun set-buffer-multibyte (arg)
-      (setq enable-multibyte-characters arg)))
+  (or (fboundp 'string-as-multibyte)
+      (defun string-as-multibyte (arg) arg))
 
-(or (fboundp 'string-as-unibyte)
-    (defun string-as-unibyte (arg) arg))
+  (or (fboundp 'char-charset)
+      (defun char-charset (arg) 'ascii))
 
-(or (fboundp 'string-as-multibyte)
-    (defun string-as-multibyte (arg) arg))
+  (or (fboundp 'charset-after)
+      (defun charset-after (&optional arg)
+       (char-charset (char-after arg))))
 
-(or (fboundp 'charset-after)
-    (defun charset-after (&optional arg)
-      (char-charset (char-after arg))))
+
+  ;; GNU Emacs
+  (or (fboundp 'line-beginning-position)
+      (defun line-beginning-position (&optional n)
+       (save-excursion
+         (and n (/= n 1) (forward-line (1- n)))
+         (beginning-of-line)
+         (point))))
+
+
+  ;; to avoid compilation gripes
+
+  ;; XEmacs
+  (defalias 'ps-x-color-instance-p              'color-instance-p)
+  (defalias 'ps-x-color-instance-rgb-components 'color-instance-rgb-components)
+  (defalias 'ps-x-color-name                    'color-name)
+  (defalias 'ps-x-color-specifier-p             'color-specifier-p)
+  (defalias 'ps-x-copy-coding-system            'copy-coding-system)
+  (defalias 'ps-x-device-class                  'device-class)
+  (defalias 'ps-x-extent-end-position           'extent-end-position)
+  (defalias 'ps-x-extent-face                   'extent-face)
+  (defalias 'ps-x-extent-priority               'extent-priority)
+  (defalias 'ps-x-extent-start-position         'extent-start-position)
+  (defalias 'ps-x-face-font-instance            'face-font-instance)
+  (defalias 'ps-x-find-coding-system            'find-coding-system)
+  (defalias 'ps-x-font-instance-properties      'font-instance-properties)
+  (defalias 'ps-x-make-color-instance           'make-color-instance)
+  (defalias 'ps-x-map-extents                   'map-extents)
+
+  ;; GNU Emacs
+  (defalias 'ps-e-x-color-values 'x-color-values)
+  (defalias 'ps-e-color-values   'color-values)
+  (if (fboundp 'find-composition)
+      (defalias 'ps-e-find-composition 'find-composition)
+    (defalias 'ps-e-find-composition 'ignore))
+
+
+  (defconst ps-windows-system
+    (memq system-type '(emx win32 w32 mswindows ms-dos windows-nt)))
+  (defconst ps-lp-system
+    (memq system-type '(usq-unix-v dgux hpux irix))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1090,7 +1380,8 @@ Please send all bug fixes and enhancements to
   :group 'emacs)
 
 (defgroup ps-print nil
-  "PostScript generator for Emacs 19"
+  "PostScript generator for Emacs"
+  :link '(emacs-library-link :tag "Source Lisp File" "ps-print.el")
   :prefix "ps-"
   :group 'wp
   :group 'postscript)
@@ -1107,7 +1398,7 @@ Please send all bug fixes and enhancements to
   :tag "Vertical"
   :group 'ps-print)
 
-(defgroup ps-print-header nil
+(defgroup ps-print-headers nil
   "Headers layout"
   :prefix "ps-"
   :tag "Header"
@@ -1162,6 +1453,69 @@ Please send all bug fixes and enhancements to
   :tag "Page"
   :group 'ps-print)
 
+(defgroup ps-print-miscellany nil
+  "Miscellany customization"
+  :prefix "ps-"
+  :tag "Miscellany"
+  :group 'ps-print)
+
+
+(defcustom ps-error-handler-message 'paper
+  "*Specify where the error handler message should be sent.
+
+Valid values are:
+
+   `none'              catch the error and *DON'T* send any message.
+
+   `paper'             catch the error and print on paper the error message.
+
+   `system'            catch the error and send back the error message to
+                       printing system.  This is useful only if printing system
+                       send back an email reporting the error, or if there is
+                       some other alternative way to report back the error from
+                       the system to you.
+
+   `paper-and-system'  catch the error, print on paper the error message and
+                       send back the error message to printing system.
+
+Any other value is treated as `paper'."
+  :type '(choice :menu-tag "Error Handler Message"
+                :tag "Error Handler Message"
+                (const none)   (const paper)
+                (const system) (const paper-and-system))
+  :group 'ps-print-miscellany)
+
+(defcustom ps-user-defined-prologue nil
+  "*User defined PostScript prologue code inserted before all prologue code.
+
+`ps-user-defined-prologue' may be a string or a symbol function which returns a
+string.  Note that this string is inserted after `ps-adobe-tag' and PostScript
+prologue comments, and before ps-print PostScript prologue code section.  That
+is, this string is inserted after error handler initialization and before
+ps-print settings.
+
+It's strongly recommended only insert PostScript code and/or comments specific
+for your printing system particularities.  For example, some special
+initialization that only your printing system needs.
+
+Do not insert code for duplex printing, n-up printing or error handler, ps-print
+handles this in a suitable way.
+
+For more information about PostScript, see:
+   PostScript Language Reference Manual (2nd edition)
+   Adobe Systems Incorporated
+
+As an example for `ps-user-defined-prologue' setting:
+
+   ;; Setting for HP PostScript printer
+   (setq ps-user-defined-prologue
+        (concat \"<</DeferredMediaSelection true /PageSize [612 792] \"
+                \"/MediaPosition 2 /MediaType (Plain)>> setpagedevice\"))
+"
+  :type '(choice :menu-tag "User Defined Prologue"
+                :tag "User Defined Prologue"
+                (const :tag "none" nil) string symbol)
+  :group 'ps-print-miscellany)
 
 (defcustom ps-print-prologue-header nil
   "*PostScript prologue header comments besides that ps-print generates.
@@ -1187,49 +1541,87 @@ For more information about PostScript document comments, see:
    PostScript Language Reference Manual (2nd edition)
    Adobe Systems Incorporated
    Appendix G: Document Structuring Conventions -- Version 3.0"
-  :type '(choice :tag "Prologue Header"
-                string symbol (other :tag "nil" nil))
-  :group 'ps-print)
+  :type '(choice :menu-tag "Prologue Header"
+                :tag "Prologue Header"
+                (const :tag "none" nil) string symbol)
+  :group 'ps-print-miscellany)
 
 (defcustom ps-printer-name (and (boundp 'printer-name)
                                printer-name)
   "*The name of a local printer for printing PostScript files.
 
-On Unix-like systems, a string value should be a name understood by
-lpr's -P option; a value of nil means use the value of `printer-name'
-instead.  Any other value will be ignored.
-
-On MS-DOS and MS-Windows systems, a string value is taken as the name of
-the printer device or port to which PostScript files are written,
-provided `ps-lpr-command' is \"\".  By default it is the same as
-`printer-name'; typical non-default settings would be \"LPT1\" to
-\"LPT3\" for parallel printers, or \"COM1\" to \"COM4\" or \"AUX\" for
-serial printers, or \"//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.  \(Note that `ps-print' package already has
-facilities for printing to a file, so you might as well use them instead
-of changing the setting of this variable.\)  If you want to silently
-discard the printed output, set this to \"NUL\"."
-  :type '(choice :tag "Printer Name"
-                file (other :tag "Pipe to ps-lpr-command" pipe))
+On Unix-like systems, a string value should be a name understood by lpr's -P
+option; a value of nil means use the value of `printer-name' instead.
+
+On MS-DOS and MS-Windows systems, a string value is taken as the name of the
+printer device or port to which PostScript files are written, provided
+`ps-lpr-command' is \"\".  By default it is the same as `printer-name'; typical
+non-default settings would be \"LPT1\" to \"LPT3\" for parallel printers, or
+\"COM1\" to \"COM4\" or \"AUX\" for serial printers, or \"//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.  \(Note that `ps-print'
+package already has facilities for printing to a file, so you might as well use
+them instead of changing the setting of this variable.\)  If you want to
+silently discard the printed output, set this to \"NUL\".
+
+Set to t, if the utility given by `ps-lpr-command' needs an empty printer name.
+
+Any other value is treated as t, that is, an empty printer name.
+
+See also `ps-printer-name-option' for documentation."
+  :type '(choice :menu-tag "Printer Name"
+                :tag "Printer Name"
+                (const :tag "Same as printer-name" nil)
+                (const :tag "No Printer Name" t)
+                (file :tag "Print to file")
+                (string :tag "Pipe to ps-lpr-command"))
+  :group 'ps-print-printer)
+
+(defcustom ps-printer-name-option
+  (cond (ps-windows-system
+        "/D:")
+       (ps-lp-system
+        "-d")
+       (t
+        "-P" ))
+  "*Option for `ps-printer-name' variable (see it).
+
+On Unix-like systems, if it's been used lpr utility, it should be the string
+\"-P\"; if it's been used lp utility, it should be the string \"-d\".
+
+On MS-DOS and MS-Windows systems, if it's been used print utility, it should be
+the string \"/D:\".
+
+For any other printing utility, see the proper manual or documentation.
+
+Set to \"\" or nil, if the utility given by `ps-lpr-command' needs an empty
+option printer name option.
+
+Any other value is treated as nil, that is, an empty printer name option.
+
+This variable is used only when `ps-printer-name' is a non-empty string."
+  :type '(choice :menu-tag "Printer Name Option"
+                :tag "Printer Name Option"
+                (const :tag "None" nil)
+                (string :tag "Option"))
   :group 'ps-print-printer)
 
 (defcustom ps-lpr-command lpr-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 `ps-printer-name'.
-The programs `print' and `nprint' (the standard print programs on Windows
-NT and Novell Netware respectively) are handled specially, using
-`ps-printer-name' as the destination for output; any other program is
-treated like `lpr' except that an explicit filename is given as the last
-argument."
+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 `ps-printer-name'.  The
+programs `print' and `nprint' (the standard print programs on Windows NT and
+Novell Netware respectively) are handled specially, using `ps-printer-name' as
+the destination for output; any other program is treated like `lpr' except that
+an explicit filename is given as the last argument."
   :type 'string
   :group 'ps-print-printer)
 
 (defcustom ps-lpr-switches lpr-switches
   "*A list of extra switches to pass to `ps-lpr-command'."
-  :type '(repeat string)
+  :type '(repeat :tag "PostScript lpr Switches"
+                (choice string symbol (repeat sexp)))
   :group 'ps-print-printer)
 
 (defcustom ps-print-region-function nil
@@ -1239,6 +1631,13 @@ the sixth arguments are both nil."
   :type 'function
   :group 'ps-print-printer)
 
+(defcustom ps-manual-feed nil
+  "*Non-nil means the printer will manually feed paper.
+
+If it's nil, automatic feeding takes place."
+  :type 'boolean
+  :group 'ps-print-printer)
+
 ;;; Page layout
 
 ;; All page dimensions are in PostScript points.
@@ -1294,11 +1693,81 @@ example `letter', `legal' or `a4'."
                               wid)))
   :group 'ps-print-page)
 
+(defcustom ps-warn-paper-type t
+  "*Non-nil means give an error if paper size is not equal to `ps-paper-type'.
+
+It's used when `ps-spool-config' is set to `setpagedevice'."
+  :type 'boolean
+  :group 'ps-print-page)
+
 (defcustom ps-landscape-mode nil
   "*Non-nil means print in landscape mode."
   :type 'boolean
   :group 'ps-print-page)
 
+(defcustom ps-print-upside-down nil
+  "*Non-nil means print upside-down."
+  :type 'boolean
+  :group 'ps-print-page)
+
+(defcustom ps-selected-pages nil
+  "*Specify which pages to print.
+
+If it's nil, all pages are printed.
+
+If it's a list, the list element may be an integer or a cons cell (FROM . TO)
+designating FROM page to TO page; any invalid element is ignored, that is, an
+integer lesser than one or if FROM is greater than TO.
+
+Otherwise, it's treated as nil.
+
+After ps-print processing `ps-selected-pages' is set to nil.  But the latest
+`ps-selected-pages' is saved in `ps-last-selected-pages' (see it for
+documentation).  So you can restore the latest selected pages by using
+`ps-last-selected-pages' or by calling `ps-restore-selected-pages' command (see
+it for documentation).
+
+See also `ps-even-or-odd-pages'."
+  :type '(repeat :tag "Selected Pages"
+                (radio :tag "Page"
+                       (integer :tag "Number")
+                       (cons :tag "Range"
+                             (integer :tag "From")
+                             (integer :tag "To"))))
+  :group 'ps-print-page)
+
+(defcustom ps-even-or-odd-pages nil
+  "*Specify if it prints even/odd pages.
+
+Valid values are:
+
+   nil         print all pages.
+
+   `even'      print only even pages.
+
+   `odd'       print only odd pages.
+
+Any other value is treated as nil.
+
+If you set `ps-selected-pages' (see it for documentation), first the pages are
+filtered by `ps-selected-pages' and then by `ps-even-or-odd-pages'.  For
+example, if we have:
+
+   (setq ps-selected-pages '(1 4 (6 . 10) 12))
+
+We have the following results:
+
+   `ps-even-or-odd-pages'      PAGES PRINTED
+       nil                     1, 4, 6, 7, 8, 9, 10, 12
+       even                    4, 6, 8, 10, 12
+       odd                     1, 7, 9"
+  :type '(choice :menu-tag "Print Even/Odd Pages"
+                :tag "Print Even/Odd Pages"
+                (const :tag "All Pages" nil)
+                (const :tag "Only Even Pages" even)
+                (const :tag "Only Odd Pages" odd))
+  :group 'ps-print-page)
+
 (defcustom ps-print-control-characters 'control-8-bit
   "*Specify the printable form for control and 8-bit characters.
 That is, instead of sending, for example, a ^D (\\004) to printer,
@@ -1324,10 +1793,11 @@ Valid values are:
                  current font.
 
 Any other value is treated as nil."
-  :type '(choice :tag "Control Char"
+  :type '(choice :menu-tag "Control Char"
+                :tag "Control Char"
                 (const 8-bit)   (const control-8-bit)
-                (const control) (other :tag "nil" nil))
-  :group 'ps-print)
+                (const control) (const :tag "nil" nil))
+  :group 'ps-print-miscellany)
 
 (defcustom ps-n-up-printing 1
   "*Specify the number of pages per sheet paper."
@@ -1377,7 +1847,8 @@ using a 3x4 page matrix:
                12 9  6  3                          10 7  4  1
 
 Any other value is treated as `left-top'."
-  :type '(choice :tag "N-Up Filling"
+  :type '(choice :menu-tag "N-Up Filling"
+                :tag "N-Up Filling"
                 (const left-top)  (const left-bottom)
                 (const right-top) (const right-bottom)
                 (const top-left)  (const bottom-left)
@@ -1387,30 +1858,128 @@ Any other value is treated as `left-top'."
 (defcustom ps-number-of-columns (if ps-landscape-mode 2 1)
   "*Specify the number of columns"
   :type 'number
-  :group 'ps-print)
+  :group 'ps-print-miscellany)
 
 (defcustom ps-zebra-stripes nil
   "*Non-nil means print zebra stripes.
-See also documentation for `ps-zebra-stripe-height' and `ps-zebra-gray'."
+See also documentation for `ps-zebra-stripe-height' and `ps-zebra-color'."
   :type 'boolean
   :group 'ps-print-zebra)
 
 (defcustom ps-zebra-stripe-height 3
   "*Number of zebra stripe lines.
-See also documentation for `ps-zebra-stripes' and `ps-zebra-gray'."
+See also documentation for `ps-zebra-stripes' and `ps-zebra-color'."
   :type 'number
   :group 'ps-print-zebra)
 
-(defcustom ps-zebra-gray 0.95
-  "*Zebra stripe gray scale.
+(defcustom ps-zebra-color 0.95
+  "*Zebra stripe gray scale or RGB color.
 See also documentation for `ps-zebra-stripes' and `ps-zebra-stripe-height'."
-  :type 'number
+  :type '(choice :menu-tag "Zebra Gray/Color"
+                :tag "Zebra Gray/Color"
+                (number :tag "Gray Scale" :value 0.95)
+                (string :tag "Color Name" :value "gray95")
+                (list :tag "RGB Color" :value (0.95 0.95 0.95)
+                      (number :tag "Red")
+                      (number :tag "Green")
+                      (number :tag "Blue")))
+  :group 'ps-print-zebra)
+
+(defcustom ps-zebra-stripe-follow nil
+  "*Non-nil means zebra stripe continues on next page.
+
+If `ps-zebra-stripe-follow' is nil, zebra stripe is restarted on each page.
+If `ps-zebra-stripe-follow' is non-nil, zebra stripe continues on next page.
+
+Visually, we have:
+
+               `ps-zebra-stripe-follow'        `ps-zebra-stripe-follow'
+                  is nil                          is non-nil
+   Current Page ------------------------       ------------------------
+               1  XXXXXXXXXXXXXXXXXXXXX        1  XXXXXXXXXXXXXXXXXXXXX
+               2  XXXXXXXXXXXXXXXXXXXXX        2  XXXXXXXXXXXXXXXXXXXXX
+               3  XXXXXXXXXXXXXXXXXXXXX        3  XXXXXXXXXXXXXXXXXXXXX
+               4                               4
+               5                               5
+               6                               6
+               7  XXXXXXXXXXXXXXXXXXXXX        7  XXXXXXXXXXXXXXXXXXXXX
+               8  XXXXXXXXXXXXXXXXXXXXX        8  XXXXXXXXXXXXXXXXXXXXX
+               ------------------------        ------------------------
+      Next Page ------------------------       ------------------------
+               9  XXXXXXXXXXXXXXXXXXXXX        9  XXXXXXXXXXXXXXXXXXXXX
+               10 XXXXXXXXXXXXXXXXXXXXX        10
+               11 XXXXXXXXXXXXXXXXXXXXX        11
+               12                              12
+               13                              13 XXXXXXXXXXXXXXXXXXXXX
+               14                              14 XXXXXXXXXXXXXXXXXXXXX
+               15 XXXXXXXXXXXXXXXXXXXXX        15 XXXXXXXXXXXXXXXXXXXXX
+               16 XXXXXXXXXXXXXXXXXXXXX        16
+               ------------------------        ------------------------"
+  :type 'boolean
   :group 'ps-print-zebra)
 
 (defcustom ps-line-number nil
   "*Non-nil means print line number."
   :type 'boolean
-  :group 'ps-print)
+  :group 'ps-print-miscellany)
+
+(defcustom ps-line-number-step 1
+  "*Specify the interval that line number is printed.
+
+For example, `ps-line-number-step' is set to 2, the printing will look like:
+
+   1 one line
+     one line
+   3 one line
+     one line
+   5 one line
+     one line
+     ...
+
+Valid values are:
+
+   integer     an integer that specifies the interval that line number is
+               printed.  If it's lesser than or equal to zero, it's used the
+               value 1.
+
+   `zebra'     specifies that only the line number of the first line in a zebra
+               stripe is to be printed.
+
+Any other value is treated as `zebra'."
+  :type '(choice :menu-tag "Line Number Step"
+                :tag "Line Number Step"
+                (integer :tag "Step Interval")
+                (const :tag "Synchronize Zebra" zebra))
+  :group 'ps-print-miscellany)
+
+(defcustom ps-line-number-start 1
+  "*Specify the starting point in the interval given by `ps-line-number-step'.
+
+For example, if `ps-line-number-step' is set to 3 and `ps-line-number-start' is
+set to 3, the printing will look like:
+
+      one line
+      one line
+    3 one line
+      one line
+      one line
+    6 one line
+      one line
+      one line
+    9 one line
+      one line
+      ...
+
+The values for `ps-line-number-start':
+
+   * If `ps-line-number-step' is an integer, must be between 1 and the value
+     of `ps-line-number-step' inclusive.
+
+   * If `ps-line-number-step' is set to `zebra', must be between 1 and the
+     value of `ps-zebra-strip-height' inclusive.  Use this combination if you
+     wish that line number be relative to zebra stripes."
+  :type '(integer :tag "Start Step Interval")
+  :group 'ps-print-miscellany)
 
 (defcustom ps-print-background-image nil
   "*EPS image list to be printed on background.
@@ -1443,17 +2012,19 @@ PostScript programming that returns a float or integer value.
 For example, if you wish to print an EPS image on all pages do:
 
    '((\"~/images/EPS-image.ps\"))"
-  :type '(repeat (list (file   :tag "EPS File")
-                      (choice :tag "X" number string (const nil))
-                      (choice :tag "Y" number string (const nil))
-                      (choice :tag "X Scale" number string (const nil))
-                      (choice :tag "Y Scale" number string (const nil))
-                      (choice :tag "Rotation" number string (const nil))
-                      (repeat :tag "Pages" :inline t
-                              (radio (integer :tag "Page")
-                                     (cons :tag "Range"
-                                           (integer :tag "From")
-                                           (integer :tag "To"))))))
+  :type '(repeat
+         (list
+          (file   :tag "EPS File")
+          (choice :tag "X" (const :tag "default" nil) number string)
+          (choice :tag "Y" (const :tag "default" nil) number string)
+          (choice :tag "X Scale" (const :tag "default" nil) number string)
+          (choice :tag "Y Scale" (const :tag "default" nil) number string)
+          (choice :tag "Rotation" (const :tag "default" nil) number string)
+          (repeat :tag "Pages" :inline t
+                  (radio (integer :tag "Page")
+                         (cons :tag "Range"
+                               (integer :tag "From")
+                               (integer :tag "To"))))))
   :group 'ps-print-background)
 
 (defcustom ps-print-background-text nil
@@ -1491,18 +2062,20 @@ PostScript programming that returns a float or integer value.
 For example, if you wish to print text \"Preliminary\" on all pages do:
 
    '((\"Preliminary\"))"
-  :type '(repeat (list (string :tag "Text")
-                      (choice :tag "X" number string (const nil))
-                      (choice :tag "Y" number string (const nil))
-                      (choice :tag "Font" string (const nil))
-                      (choice :tag "Fontsize" number string (const nil))
-                      (choice :tag "Gray" number string (const nil))
-                      (choice :tag "Rotation" number string (const nil))
-                      (repeat :tag "Pages" :inline t
-                              (radio (integer :tag "Page")
-                                     (cons :tag "Range"
-                                           (integer :tag "From")
-                                           (integer :tag "To"))))))
+  :type '(repeat
+         (list
+          (string :tag "Text")
+          (choice :tag "X" (const :tag "default" nil) number string)
+          (choice :tag "Y" (const :tag "default" nil) number string)
+          (choice :tag "Font" (const :tag "default" nil) string)
+          (choice :tag "Fontsize" (const :tag "default" nil) number string)
+          (choice :tag "Gray" (const :tag "default" nil) number string)
+          (choice :tag "Rotation" (const :tag "default" nil) number string)
+          (repeat :tag "Pages" :inline t
+                  (radio (integer :tag "Page")
+                         (cons :tag "Range"
+                               (integer :tag "From")
+                               (integer :tag "To"))))))
   :group 'ps-print-background)
 
 ;;; Horizontal layout
@@ -1572,7 +2145,7 @@ the buffer is visiting a file, the file's directory.  Headers are
 customizable by changing variables `ps-left-header' and
 `ps-right-header'."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-print-only-one-header nil
   "*Non-nil means print only one header at the top of each page.
@@ -1580,29 +2153,49 @@ This is useful when printing more than one column, so it is possible
 to have only one header over all columns or one header per column.
 See also `ps-print-header'."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-print-header-frame t
   "*Non-nil means draw a gaudy frame around the header."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-header-lines 2
   "*Number of lines to display in page header, when generating PostScript."
   :type 'integer
-  :group 'ps-print-header)
-(make-variable-buffer-local 'ps-header-lines)
+  :group 'ps-print-headers)
+
+(defcustom ps-switch-header 'duplex
+  "*Specify if headers are switched or not.
+
+Valid values are:
+
+nil    Never switch headers.
+
+t      Always switch headers.
+
+duplex Switch headers only when duplexing is on, that is, when
+       `ps-spool-duplex' is non-nil.
+
+Any other value is treated as t."
+  :type '(choice :menu-tag "Switch Header"
+                :tag "Switch Header"
+                (const :tag "Never Switch" nil)
+                (const :tag "Always Switch" t)
+                (const :tag "Switch When Duplexing" duplex))
+  :group 'ps-print-headers)
 
 (defcustom ps-show-n-of-n t
   "*Non-nil means show page numbers as N/M, meaning page N of M.
 NOTE: page numbers are displayed as part of headers,
-      see variable `ps-print-headers'."
+      see variable `ps-print-header'."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
-(defcustom ps-spool-config (if (memq system-type '(ms-dos windows-nt))
-                              'setpagedevice
-                            'lpr-switches)
+(defcustom ps-spool-config
+  (if ps-windows-system
+      nil
+    'lpr-switches)
   "*Specify who is responsable for setting duplex and page size switches.
 
 Valid values are:
@@ -1628,10 +2221,11 @@ WARNING: The setpagedevice PostScript operator affects ghostview utility when
         So, if you need to use setpagedevice, set `ps-spool-config' to
         `setpagedevice', generate a test file and send it to your printer; if
         the printed file isn't ok, set `ps-spool-config' to nil."
-  :type '(choice :tag "Spool Config"
+  :type '(choice :menu-tag "Spool Config"
+                :tag "Spool Config"
                 (const lpr-switches) (const setpagedevice)
-                (other :tag "nil" nil))
-  :group 'ps-print-header)
+                (const :tag "nil" nil))
+  :group 'ps-print-headers)
 
 (defcustom ps-spool-duplex nil         ; Not many people have duplex printers,
                                        ; so default to nil.
@@ -1644,7 +2238,7 @@ even-numbered pages.
 
 See also `ps-spool-tumble'."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-spool-tumble nil
   "*Specify how the page images on opposite sides of a sheet are oriented.
@@ -1654,7 +2248,7 @@ the top or bottom.
 
 It has effect only when `ps-spool-duplex' is non-nil."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
 
 ;;; Fonts
 
@@ -1769,11 +2363,14 @@ To get the info for another specific font (say Helvetica), do the following:
 - generate the PostScript image to a file (C-u M-x ps-print-buffer)
 - open this file and delete the leading `%' (which is the PostScript
   comment character) from the line
-          `% 3 cm 20 cm moveto  10 /Courier ReportFontInfo  showpage'
+          `% 3 cm 20 cm moveto  10/Courier ReportFontInfo  showpage'
   to get the line
-          `3 cm 20 cm moveto  10 /Helvetica ReportFontInfo  showpage'
+          `3 cm 20 cm moveto  10/Helvetica ReportFontInfo  showpage'
 - add the values to `ps-font-info-database'.
-You can get all the fonts of YOUR printer using `ReportAllFontInfo'."
+You can get all the fonts of YOUR printer using `ReportAllFontInfo'.
+
+Note also that ps-print DOESN'T download any font to your printer, instead
+it uses the fonts resident in your printer."
   :type '(repeat (list :tag "Font Definition"
                       (symbol :tag "Font Family")
                       (cons :format "%v"
@@ -1836,8 +2433,11 @@ You can get all the fonts of YOUR printer using `ReportAllFontInfo'."
 ;;; Colors
 
 ;; Printing color requires x-color-values.
-(defcustom ps-print-color-p (or (fboundp 'x-color-values) ; Emacs
-                               (fboundp 'color-instance-rgb-components))
+(defcustom ps-print-color-p
+  (or (and (fboundp 'color-values)     ; Emacs
+          (ps-e-color-values "Green"))
+      (fboundp 'x-color-values)                ; Emacs
+      (fboundp 'color-instance-rgb-components))
                                        ; XEmacs
   "*Non-nil means print the buffer's text in color."
   :type 'boolean
@@ -1845,16 +2445,30 @@ You can get all the fonts of YOUR printer using `ReportAllFontInfo'."
 
 (defcustom ps-default-fg '(0.0 0.0 0.0)
   "*RGB values of the default foreground color.  Defaults to black."
-  :type '(list (number :tag "Red") (number :tag "Green") (number :tag "Blue"))
+  :type '(choice :menu-tag "Default Foreground Gray/Color"
+                :tag "Default Foreground Gray/Color"
+                (number :tag "Gray Scale" :value 0.0)
+                (string :tag "Color Name" :value "black")
+                (list :tag "RGB Color" :value (0.0 0.0 0.0)
+                      (number :tag "Red")
+                      (number :tag "Green")
+                      (number :tag "Blue")))
   :group 'ps-print-color)
 
 (defcustom ps-default-bg '(1.0 1.0 1.0)
   "*RGB values of the default background color.  Defaults to white."
-  :type '(list (number :tag "Red") (number :tag "Green") (number :tag "Blue"))
+  :type '(choice :menu-tag "Default Background Gray/Color"
+                :tag "Default Background Gray/Color"
+                (number :tag "Gray Scale" :value 1.0)
+                (string :tag "Color Name" :value "white")
+                (list :tag "RGB Color" :value (1.0 1.0 1.0)
+                      (number :tag "Red")
+                      (number :tag "Green")
+                      (number :tag "Blue")))
   :group 'ps-print-color)
 
 (defcustom ps-auto-font-detect t
-  "*Non-nil means automatically detect bold/italic face attributes.
+  "*Non-nil means automatically detect bold/italic/underline face attributes.
 If nil, we rely solely on the lists `ps-bold-faces', `ps-italic-faces',
 and `ps-underlined-faces'."
   :type 'boolean
@@ -1894,6 +2508,25 @@ This applies to generating PostScript."
   :type '(repeat face)
   :group 'ps-print-face)
 
+(defcustom ps-use-face-background nil
+  "*Specify if face background should be used.
+
+Valid values are:
+
+   t           always use face background color.
+   nil         never use face background color.
+   (face...)   list of faces whose background color will be used.
+
+Any other value will be treated as t."
+  :type '(choice :menu-tag "Use Face Background"
+                :tag "Use Face Background"
+                (const :tag "Always Use Face Background" t)
+                (const :tag "Never Use Face Background" nil)
+                (repeat :menu-tag "Face Background List"
+                        :tag "Face Background List"
+                        face))
+  :group 'ps-print-face)
+
 (defcustom ps-left-header
   (list 'ps-get-buffer-name 'ps-header-dirpart)
   "*The items to display (each on a line) on the left part of the page header.
@@ -1912,8 +2545,7 @@ values, the value should be a string to be inserted into the array.
 In either case, function or variable, the string value has PostScript
 string delimiters added to it."
   :type '(repeat (choice string symbol))
-  :group 'ps-print-header)
-(make-variable-buffer-local 'ps-left-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-right-header
   (list "/pagenumberstring load" 'time-stamp-mon-dd-yyyy 'time-stamp-hh:mm:ss)
@@ -1923,20 +2555,19 @@ This applies to generating PostScript.
 See the variable `ps-left-header' for a description of the format of
 this variable."
   :type '(repeat (choice string symbol))
-  :group 'ps-print-header)
-(make-variable-buffer-local 'ps-right-header)
+  :group 'ps-print-headers)
 
 (defcustom ps-razzle-dazzle t
   "*Non-nil means report progress while formatting buffer."
   :type 'boolean
-  :group 'ps-print)
+  :group 'ps-print-miscellany)
 
 (defcustom ps-adobe-tag "%!PS-Adobe-3.0\n"
   "*Contains the header line identifying the output as PostScript.
 By default, `ps-adobe-tag' contains the standard identifier.  Some
 printers require slightly different versions of this line."
   :type 'string
-  :group 'ps-print)
+  :group 'ps-print-miscellany)
 
 (defcustom ps-build-face-reference t
   "*Non-nil means build the reference face lists.
@@ -1966,7 +2597,30 @@ variable."
   "*Non-nil means the very first page is skipped.
 It's like the very first character of buffer (or region) is ^L (\\014)."
   :type 'boolean
-  :group 'ps-print-header)
+  :group 'ps-print-headers)
+
+(defcustom ps-postscript-code-directory
+  (or (and (fboundp 'locate-data-directory) ; xemacs
+          (locate-data-directory "ps-print"))
+      data-directory)                  ; emacs
+  "*Directory where it's located the PostScript prologue file used by ps-print.
+By default, this directory is the same as in the variable `data-directory'."
+  :type 'directory
+  :group 'ps-print-miscellany)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Selected Pages
+
+
+(defvar ps-last-selected-pages nil
+  "Latest `ps-selected-pages' value.")
+
+
+(defun ps-restore-selected-pages ()
+  "Restore latest `ps-selected-pages' value."
+  (interactive)
+  (setq ps-selected-pages ps-last-selected-pages))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2112,20 +2766,34 @@ The table depends on the current ps-print setup."
   "Return the current PostScript-generation setup."
   (format
    "
+;;; ps-print version %s
+
 \(setq ps-print-color-p         %s
       ps-lpr-command           %S
       ps-lpr-switches          %s
-      ps-printer-name          %S
+      ps-printer-name          %s
+      ps-printer-name-option   %s
       ps-print-region-function %s
+      ps-manual-feed           %S
 
       ps-paper-type          %s
+      ps-warn-paper-type     %s
       ps-landscape-mode      %s
+      ps-print-upside-down   %s
       ps-number-of-columns   %s
 
       ps-zebra-stripes       %s
       ps-zebra-stripe-height %s
-      ps-zebra-gray          %s
+      ps-zebra-stripe-follow %S
+      ps-zebra-color         %s
       ps-line-number         %s
+      ps-line-number-step    %s
+      ps-line-number-start   %S
+
+      ps-default-fg %s
+      ps-default-bg %s
+
+      ps-use-face-background %s
 
       ps-print-control-characters %s
 
@@ -2133,6 +2801,8 @@ The table depends on the current ps-print setup."
 
       ps-print-background-text %s
 
+      ps-error-handler-message %s
+      ps-user-defined-prologue %s
       ps-print-prologue-header %s
 
       ps-left-margin                %s
@@ -2145,6 +2815,7 @@ The table depends on the current ps-print setup."
       ps-print-header               %s
       ps-print-only-one-header      %s
       ps-print-header-frame         %s
+      ps-switch-header              %s
       ps-header-lines               %s
       ps-show-n-of-n                %s
       ps-spool-config               %s
@@ -2152,33 +2823,52 @@ The table depends on the current ps-print setup."
       ps-spool-tumble               %s
       ps-banner-page-when-duplexing %s
 
-      ps-n-up-printing         %s
-      ps-n-up-margin           %s
-      ps-n-up-border-p         %s
-      ps-n-up-filling          %s
+      ps-n-up-printing %s
+      ps-n-up-margin   %s
+      ps-n-up-border-p %s
+      ps-n-up-filling  %s
 
       ps-multibyte-buffer       %s
       ps-font-family            %s
       ps-font-size              %s
       ps-header-font-family     %s
       ps-header-font-size       %s
-      ps-header-title-font-size %s)
+      ps-header-title-font-size %s
+
+      ps-even-or-odd-pages   %s
+      ps-selected-pages      %s
+      ps-last-selected-pages %s)
+
+;;; ps-print - end of settings
 "
+   ps-print-version
    ps-print-color-p
    ps-lpr-command
    (ps-print-quote ps-lpr-switches)
-   ps-printer-name
+   (ps-print-quote ps-printer-name)
+   (ps-print-quote ps-printer-name-option)
    (ps-print-quote ps-print-region-function)
+   ps-manual-feed
    (ps-print-quote ps-paper-type)
+   ps-warn-paper-type
    ps-landscape-mode
+   ps-print-upside-down
    ps-number-of-columns
    ps-zebra-stripes
    ps-zebra-stripe-height
-   ps-zebra-gray
+   ps-zebra-stripe-follow
+   (ps-print-quote ps-zebra-color)
    ps-line-number
+   (ps-print-quote ps-line-number-step)
+   ps-line-number-start
+   (ps-print-quote ps-default-fg)
+   (ps-print-quote ps-default-bg)
+   (ps-print-quote ps-use-face-background)
    (ps-print-quote ps-print-control-characters)
    (ps-print-quote ps-print-background-image)
    (ps-print-quote ps-print-background-text)
+   (ps-print-quote ps-error-handler-message)
+   (ps-print-quote ps-user-defined-prologue)
    (ps-print-quote ps-print-prologue-header)
    ps-left-margin
    ps-right-margin
@@ -2190,6 +2880,7 @@ The table depends on the current ps-print setup."
    ps-print-header
    ps-print-only-one-header
    ps-print-header-frame
+   (ps-print-quote ps-switch-header)
    ps-header-lines
    ps-show-n-of-n
    (ps-print-quote ps-spool-config)
@@ -2205,7 +2896,10 @@ The table depends on the current ps-print setup."
    (ps-print-quote ps-font-size)
    (ps-print-quote ps-header-font-family)
    (ps-print-quote ps-header-font-size)
-   (ps-print-quote ps-header-title-font-size)))
+   (ps-print-quote ps-header-title-font-size)
+   (ps-print-quote ps-even-or-odd-pages)
+   (ps-print-quote ps-selected-pages)
+   (ps-print-quote ps-last-selected-pages)))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2222,788 +2916,160 @@ The table depends on the current ps-print setup."
        (t
         sym)))
 
-(defvar ps-print-emacs-type
-  (cond ((string-match "XEmacs" emacs-version) 'xemacs)
-       ((string-match "Lucid" emacs-version) 'lucid)
-       ((string-match "Epoch" emacs-version) 'epoch)
-       (t 'emacs)))
-
-(if (or (eq ps-print-emacs-type 'lucid)
-       (eq ps-print-emacs-type 'xemacs))
-    (if (< emacs-minor-version 12)
-       (setq ps-print-color-p nil))
-  (require 'faces))                    ; face-font, face-underline-p,
+
+(eval-and-compile
+  (defvar ps-print-emacs-type
+    (cond ((string-match "XEmacs" emacs-version) 'xemacs)
+         ((string-match "Lucid" emacs-version) 'lucid)
+         ((string-match "Epoch" emacs-version) 'epoch)
+         (t 'emacs)))
+
+  (if (memq ps-print-emacs-type '(lucid xemacs))
+      (if (< emacs-minor-version 12)
+         (setq ps-print-color-p nil))
+    (require 'faces))                  ; face-font, face-underline-p,
                                        ; x-font-regexp
 
-;; Return t if the device (which can be changed during an emacs session)
-;; can handle colors.
-;; This is function is not yet implemented for GNU emacs.
-(cond ((and (eq ps-print-emacs-type 'xemacs)
-           (>= emacs-minor-version 12)) ; xemacs
-       (defun ps-color-device ()
-        (eq (device-class) 'color))
-       )
+  ;; Return t if the device (which can be changed during an emacs session)
+  ;; can handle colors.
+  ;; This function is not yet implemented for GNU emacs.
+  (cond ((and (eq ps-print-emacs-type 'xemacs)
+             (>= emacs-minor-version 12)) ; xemacs
+        (defun ps-color-device ()
+          (eq (ps-x-device-class) 'color)))
+
+       (t                              ; emacs
+        (defun ps-color-device ()
+          (if (fboundp 'color-values)
+              (ps-e-color-values "Green")
+            t))))
+
+
+  (defun ps-mapper (extent list)
+    (nconc list
+          (list (list (ps-x-extent-start-position extent) 'push extent)
+                (list (ps-x-extent-end-position extent) 'pull extent)))
+    nil)
+
+  (defun ps-extent-sorter (a b)
+    (< (ps-x-extent-priority a) (ps-x-extent-priority b)))
+
+  (defun ps-xemacs-face-kind-p (face kind kind-regex)
+    (let* ((frame-font (or (ps-x-face-font-instance face)
+                          (ps-x-face-font-instance 'default)))
+          (kind-cons
+           (and frame-font
+                (assq kind
+                      (ps-x-font-instance-properties frame-font))))
+          (kind-spec (cdr-safe kind-cons))
+          (case-fold-search t))
+      (and kind-spec (string-match kind-regex kind-spec))))
+
+  (defun ps-xemacs-color-name (color)
+    (if (ps-x-color-specifier-p color)
+       (ps-x-color-name color)
+      color))
+
+  (cond ((eq ps-print-emacs-type 'emacs) ; emacs
+
+        (defun ps-color-values (x-color)
+          (cond
+           ((fboundp 'color-values)
+            (ps-e-color-values x-color))
+           ((fboundp 'x-color-values)
+            (ps-e-x-color-values x-color))
+           (t
+            (error "No available function to determine X color values."))))
+
+        (defalias 'ps-face-foreground-name 'face-foreground)
+        (defalias 'ps-face-background-name 'face-background)
+
+        (defun ps-face-bold-p (face)
+          (or (face-bold-p face)
+              (memq face ps-bold-faces)))
+
+        (defun ps-face-italic-p (face)
+          (or (face-italic-p face)
+              (memq face ps-italic-faces)))
+        )
+                                       ; xemacs
+                                       ; lucid
+       (t                              ; epoch
 
-      (t                               ; emacs
-       (defun ps-color-device ()
-        t)
-       ))
+        (or (ps-x-find-coding-system 'raw-text-unix)
+            (ps-x-copy-coding-system 'no-conversion-unix 'raw-text-unix))
 
+        (defun ps-color-values (x-color)
+          (let ((color (ps-xemacs-color-name x-color)))
+            (cond
+             ((fboundp 'x-color-values)
+              (ps-e-x-color-values color))
+             ((and (fboundp 'color-instance-rgb-components)
+                   (ps-color-device))
+              (ps-x-color-instance-rgb-components
+               (if (ps-x-color-instance-p x-color)
+                   x-color
+                 (ps-x-make-color-instance color))))
+             (t
+              (error "No available function to determine X color values.")))))
 
-(require 'time-stamp)
+        (defun ps-face-foreground-name (face)
+          (ps-xemacs-color-name (face-foreground face)))
 
-(defconst ps-print-prologue-1
-  "
-% ISOLatin1Encoding stolen from ps_init.ps in GhostScript 2.6.1.4:
-/ISOLatin1Encoding where { pop } {
-% -- The ISO Latin-1 encoding vector isn't known, so define it.
-% -- The first half is the same as the standard encoding,
-% -- except for minus instead of hyphen at code 055.
-/ISOLatin1Encoding
-StandardEncoding 0 45 getinterval aload pop
-    /minus
-StandardEncoding 46 82 getinterval aload pop
-%*** NOTE: the following are missing in the Adobe documentation,
-%*** but appear in the displayed table:
-%*** macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240.
-% 0200 (128)
-    /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
-    /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
-    /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent
-    /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron
-% 0240 (160)
-    /space /exclamdown /cent /sterling
-       /currency /yen /brokenbar /section
-    /dieresis /copyright /ordfeminine /guillemotleft
-       /logicalnot /hyphen /registered /macron
-    /degree /plusminus /twosuperior /threesuperior
-       /acute /mu /paragraph /periodcentered
-    /cedilla /onesuperior /ordmasculine /guillemotright
-       /onequarter /onehalf /threequarters /questiondown
-% 0300 (192)
-    /Agrave /Aacute /Acircumflex /Atilde
-       /Adieresis /Aring /AE /Ccedilla
-    /Egrave /Eacute /Ecircumflex /Edieresis
-       /Igrave /Iacute /Icircumflex /Idieresis
-    /Eth /Ntilde /Ograve /Oacute
-       /Ocircumflex /Otilde /Odieresis /multiply
-    /Oslash /Ugrave /Uacute /Ucircumflex
-       /Udieresis /Yacute /Thorn /germandbls
-% 0340 (224)
-    /agrave /aacute /acircumflex /atilde
-       /adieresis /aring /ae /ccedilla
-    /egrave /eacute /ecircumflex /edieresis
-       /igrave /iacute /icircumflex /idieresis
-    /eth /ntilde /ograve /oacute
-       /ocircumflex /otilde /odieresis /divide
-    /oslash /ugrave /uacute /ucircumflex
-       /udieresis /yacute /thorn /ydieresis
-256 packedarray def
-} ifelse
-
-/reencodeFontISO { %def
-  dup
-  length 12 add dict   % Make a new font (a new dict the same size
-                       % as the old one) with room for our new symbols.
-
-  begin                        % Make the new font the current dictionary.
-
-
-    { 1 index /FID ne
-      { def } { pop pop } ifelse
-    } forall           % Copy each of the symbols from the old dictionary
-                       % to the new one except for the font ID.
-
-    currentdict /FontType get 0 ne {
-      /Encoding ISOLatin1Encoding def  % Override the encoding with
-                                       % the ISOLatin1 encoding.
-    } if
-
-    % Use the font's bounding box to determine the ascent, descent,
-    % and overall height; don't forget that these values have to be
-    % transformed using the font's matrix.
-
-%          ^    (x2 y2)
-%          |       |
-%          |       v
-%          |  +----+ - -
-%          |  |    |   ^
-%          |  |    |   | Ascent (usually > 0)
-%          |  |    |   |
-% (0 0) -> +--+----+-------->
-%             |    |   |
-%             |    |   v Descent (usually < 0)
-% (x1 y1) --> +----+ - -
-
-    currentdict /FontType get 0 ne {
-      /FontBBox load aload pop                 % -- x1 y1 x2 y2
-      FontMatrix transform /Ascent  exch def pop
-      FontMatrix transform /Descent exch def pop
-    } {
-      /PrimaryFont FDepVector 0 get def
-      PrimaryFont /FontBBox get aload pop
-      PrimaryFont /FontMatrix get transform /Ascent exch def pop
-      PrimaryFont /FontMatrix get transform /Descent exch def pop
-    } ifelse
-
-    /FontHeight Ascent Descent sub def % use `sub' because descent < 0
-
-    % Define these in case they're not in the FontInfo
-    % (also, here they're easier to get to).
-    /UnderlinePosition  Descent 0.70 mul def
-    /OverlinePosition   Descent UnderlinePosition sub Ascent add def
-    /StrikeoutPosition  Ascent 0.30 mul def
-    /LineThickness      FontHeight 0.05 mul def
-    /Xshadow            FontHeight  0.08 mul def
-    /Yshadow            FontHeight -0.09 mul def
-    /SpaceBackground    Descent neg UnderlinePosition add def
-    /XBox               Descent neg def
-    /YBox               LineThickness 0.7 mul def
-
-    currentdict                % Leave the new font on the stack
-    end                        % Stop using the font as the current dictionary.
-    definefont         % Put the font into the font dictionary
-    pop                        % Discard the returned font.
-} bind def
-
-/DefFont {                             % Font definition
-  findfont exch scalefont reencodeFontISO
-} def
-
-/F {                                   % Font selection
-  findfont
-  dup /Ascent            get /Ascent            exch def
-  dup /Descent           get /Descent           exch def
-  dup /FontHeight        get /FontHeight        exch def
-  dup /UnderlinePosition get /UnderlinePosition exch def
-  dup /OverlinePosition  get /OverlinePosition  exch def
-  dup /StrikeoutPosition get /StrikeoutPosition exch def
-  dup /LineThickness     get /LineThickness     exch def
-  dup /Xshadow           get /Xshadow           exch def
-  dup /Yshadow           get /Yshadow           exch def
-  dup /SpaceBackground   get /SpaceBackground   exch def
-  dup /XBox              get /XBox              exch def
-  dup /YBox              get /YBox              exch def
-  setfont
-} def
-
-/FG /setrgbcolor load def
-
-/bg false def
-/BG {
-  dup /bg exch def
-  {mark 4 1 roll ]}
-  {[ 1.0 1.0 1.0 ]}
-  ifelse
-  /bgcolor exch def
-} def
-
-%  B    width    C
-%   +-----------+
-%               | Ascent  (usually > 0)
-% A +           +
-%               | Descent (usually < 0)
-%   +-----------+
-%  E    width    D
-
-/dobackground {                                % width --
-  currentpoint                         % -- width x y
-  gsave
-    newpath
-    moveto                             % A (x y)
-    0 Ascent rmoveto                   % B
-    dup 0 rlineto                      % C
-    0 Descent Ascent sub rlineto       % D
-    neg 0 rlineto                      % E
-    closepath
-    bgcolor aload pop setrgbcolor
-    fill
-  grestore
-} def
-
-/eolbg {                               % dobackground until right margin
-  PrintWidth                           % -- x-eol
-  currentpoint pop                     % -- cur-x
-  sub                                  % -- width until eol
-  dobackground
-} def
-
-/PLN {PrintLineNumber {doLineNumber}if} def
-
-/SL {                                  % Soft Linefeed
-  bg { eolbg } if
-  0  currentpoint exch pop LineHeight sub  moveto
-} def
-
-/HL {SL PLN} def                       % Hard Linefeed
-
-% Some debug
-/dcp { currentpoint exch 40 string cvs print (, ) print = } def
-/dp { print 2 copy  exch 40 string cvs print (, ) print = } def
-
-/W {
-  ( ) stringwidth      % Get the width of a space in the current font.
-  pop                  % Discard the Y component.
-  mul                  % Multiply the width of a space
-                       % by the number of spaces to plot
-  bg { dup dobackground } if
-  0 rmoveto
-} def
-
-/Effect 0 def
-/EF {/Effect exch def} def
-
-% stack:  string  |-  --
-% effect: 1  - underline  2   - strikeout  4  - overline
-%         8  - shadow     16  - box        32 - outline
-/S {
-  /xx currentpoint dup Descent add /yy exch def
-  Ascent add /YY exch def def
-  dup stringwidth pop xx add /XX exch def
-  Effect 8 and 0 ne {
-    /yy yy Yshadow add def
-    /XX XX Xshadow add def
-  } if
-  bg {
-    true
-    Effect 16 and 0 ne
-      {SpaceBackground doBox}
-      {xx yy XX YY doRect}
-    ifelse
-  } if                                                 % background
-  Effect 16 and 0 ne {false 0 doBox}if                 % box
-  Effect 8  and 0 ne {dup doShadow}if                  % shadow
-  Effect 32 and 0 ne
-    {true doOutline}                                   % outline
-    {show}                                             % normal text
-  ifelse
-  Effect 1  and 0 ne {UnderlinePosition Hline}if       % underline
-  Effect 2  and 0 ne {StrikeoutPosition Hline}if       % strikeout
-  Effect 4  and 0 ne {OverlinePosition  Hline}if       % overline
-} bind def
-
-% stack:  position  |-  --
-/Hline {
-  currentpoint exch pop add dup
-  gsave
-  newpath
-  xx exch moveto
-  XX exch lineto
-  closepath
-  LineThickness setlinewidth stroke
-  grestore
-} bind def
-
-% stack:  fill-or-not delta  |-  --
-/doBox {
-  /dd exch def
-  xx XBox sub dd sub yy YBox sub dd sub
-  XX XBox add dd add YY YBox add dd add
-  doRect
-} bind def
-
-% stack:  fill-or-not lower-x lower-y upper-x upper-y  |-  --
-/doRect {
-  /rYY exch def
-  /rXX exch def
-  /ryy exch def
-  /rxx exch def
-  gsave
-  newpath
-  rXX rYY moveto
-  rxx rYY lineto
-  rxx ryy lineto
-  rXX ryy lineto
-  closepath
-  % top of stack: fill-or-not
-    {FillBgColor}
-    {LineThickness setlinewidth stroke}
-  ifelse
-  grestore
-} bind def
-
-% stack:  string  |-  --
-/doShadow {
-  gsave
-  Xshadow Yshadow rmoveto
-  false doOutline
-  grestore
-} bind def
-
-/st 1 string def
-
-% stack:  string fill-or-not  |-  --
-/doOutline {
-  /-fillp- exch def
-  /-ox- currentpoint /-oy- exch def def
-  gsave
-  LineThickness setlinewidth
-  {
-    st 0 3 -1 roll put
-    st dup true charpath
-    -fillp- {gsave FillBgColor grestore}if
-    stroke stringwidth
-    -oy- add /-oy- exch def
-    -ox- add /-ox- exch def
-    -ox- -oy- moveto
-  } forall
-  grestore
-  -ox- -oy- moveto
-} bind def
-
-% stack:  --
-/FillBgColor {bgcolor aload pop setrgbcolor fill} bind def
-
-/L0 6 /Times-Italic DefFont
-
-% stack:  --
-/doLineNumber {
-  /LineNumber where
-  {
-    pop
-    currentfont
-    gsave
-    0.0 0.0 0.0 setrgbcolor
-    /L0 findfont setfont
-    LineNumber Lines ge
-      {(end      )}
-      {LineNumber 6 string cvs (      ) strcat}
-    ifelse
-    dup stringwidth pop neg 0 rmoveto
-    show
-    grestore
-    setfont
-    /LineNumber LineNumber 1 add def
-  } if
-} def
-
-% stack: --
-/printZebra {
-  gsave
-  ZebraGray setgray
-  /double-zebra ZebraHeight ZebraHeight add def
-  /yiter double-zebra LineHeight mul neg def
-  /xiter PrintWidth InterColumn add def
-  NumberOfColumns {LinesPerColumn doColumnZebra xiter 0 rmoveto}repeat
-  grestore
-} def
-
-% stack:  lines-per-column |- --
-/doColumnZebra {
-  gsave
-  dup double-zebra idiv {ZebraHeight doZebra 0 yiter rmoveto}repeat
-  double-zebra mod
-  dup 0 le {pop}{dup ZebraHeight gt {pop ZebraHeight}if doZebra}ifelse
-  grestore
-} def
-
-% stack:  zebra-height (in lines) |- --
-/doZebra {
-  /zh exch 0.05 sub LineHeight mul def
-  gsave
-  0 LineHeight 0.65 mul rmoveto
-  PrintWidth 0 rlineto
-  0 zh neg rlineto
-  PrintWidth neg 0 rlineto
-  0 zh rlineto
-  fill
-  grestore
-} def
-
-% tx ty rotation xscale yscale xpos ypos BeginBackImage
-/BeginBackImage {
-  /-save-image- save def
-  /showpage {}def
-  translate
-  scale
-  rotate
-  translate
-} def
-
-/EndBackImage {
-  -save-image- restore
-} def
-
-% string fontsize fontname rotation gray xpos ypos ShowBackText
-/ShowBackText {
-  gsave
-  translate
-  setgray
-  rotate
-  findfont exch dup /-offset- exch -0.25 mul def scalefont setfont
-  0 -offset- moveto
-  /-saveLineThickness- LineThickness def
-  /LineThickness 1 def
-  false doOutline
-  /LineThickness -saveLineThickness- def
-  grestore
-} def
-
-/BeginDoc {
-  % ---- Remember space width of the normal text font `f0'.
-  /SpaceWidth /f0 findfont setfont ( ) stringwidth pop def
-  % ---- save the state of the document (useful for ghostscript!)
-  /docState save def
-  % ---- [andrewi] set PageSize based on chosen dimensions
-  UseSetpagedevice {
-    0
-    {<< /PageSize [PageWidth LandscapePageHeight] >> setpagedevice}
-    CheckConfig
-  }{
-    LandscapeMode {
-      % ---- translate to bottom-right corner of Portrait page
-      LandscapePageHeight 0 translate
-      90 rotate
-    }if
-  }ifelse
-  % ---- [jack] Kludge: my ghostscript window is 21x27.7 instead of 21x29.7
-  /JackGhostscript where {pop 1 27.7 29.7 div scale}if
-  % ---- N-Up printing
-  N-Up 1 gt {
-    % ---- landscape
-    N-Up-Landscape {
-      PageWidth 0 translate
-      90 rotate
-    }if
-    N-Up-Margin dup translate
-    % ---- scale
-    LandscapeMode{
-      /HH PageWidth def
-      /WW LandscapePageHeight def
-    }{
-      /HH LandscapePageHeight def
-      /WW PageWidth def
-    }ifelse
-    WW N-Up-Margin sub N-Up-Margin sub
-    N-Up-Landscape
-     {N-Up-Lines div HH}{N-Up-Columns N-Up-Missing add div WW}ifelse
-    div dup scale
-    0 N-Up-Repeat 1 sub LandscapePageHeight mul translate
-    % ---- go to start position in page matrix
-    N-Up-XStart N-Up-Missing 0.5 mul
-    LandscapeMode{
-      LandscapePageHeight mul N-Up-YStart add
-    }{
-      PageWidth mul add N-Up-YStart
-    }ifelse
-    translate
-  }if
-  /ColumnWidth PrintWidth InterColumn add def
-  % ---- translate to lower left corner of TEXT
-  LeftMargin BottomMargin translate
-  % ---- define where  printing will start
-  /f0 F                                        % this installs Ascent
-  /PrintStartY PrintHeight Ascent sub def
-  /ColumnIndex 1 def
-  /N-Up-Counter N-Up-End 1 sub def
-  SkipFirstPage{save showpage restore}if
-}def
-
-/EndDoc {
-  % ---- restore the state of the document (useful for ghostscript!)
-  docState restore
-}def
-
-/BeginDSCPage {
-  % ---- when 1st column, save the state of the page
-  ColumnIndex 1 eq {
-    /pageState save def
-  }if
-  % ---- save the state of the column
-  /columnState save def
-}def
-
-/PrintHeaderWidth PrintOnlyOneHeader{PrintPageWidth}{PrintWidth}ifelse def
-
-/BeginPage {
-  % ---- when 1st column, print all background effects
-  ColumnIndex 1 eq {
-    0 PrintStartY moveto               % move to where printing will start
-    Zebra {printZebra}if
-    printGlobalBackground
-    printLocalBackground
-  }if
-  PrintHeader {
-    PrintOnlyOneHeader{ColumnIndex 1 eq}{true}ifelse {
-      PrintHeaderFrame {HeaderFrame}if
-      HeaderText
-    }if
-  }if
-  0 PrintStartY moveto                 % move to where printing will start
-  PLN
-}def
-
-/EndPage {
-  bg {eolbg}if
-}def
-
-/EndDSCPage {
-  ColumnIndex NumberOfColumns eq {
-    % ---- restore the state of the page
-    pageState restore
-    /ColumnIndex 1 def
-    % ---- N-up printing
-    N-Up 1 gt {
-      N-Up-Counter 0 gt {
-       % ---- Next page on same row
-       /N-Up-Counter N-Up-Counter 1 sub def
-       N-Up-XColumn N-Up-YColumn
-      }{
-       % ---- Next page on next line
-       /N-Up-Counter N-Up-End 1 sub def
-       N-Up-XLine N-Up-YLine
-      }ifelse
-      translate
-    }if
-  }{ % else
-    % ---- restore the state of the current column
-    columnState restore
-    % ---- and translate to the next column
-    ColumnWidth 0 translate
-    /ColumnIndex ColumnIndex 1 add def
-  }ifelse
-}def
-
-% stack: number-of-pages-per-sheet |- --
-/BeginSheet {
-  /sheetState save def
-  /pages-per-sheet exch def
-  % ---- N-up printing
-  N-Up 1 gt N-Up-Border and pages-per-sheet 0 gt and {
-    % ---- page border
-    gsave
-    0 setgray
-    LeftMargin neg BottomMargin neg moveto
-    N-Up-Repeat
-    {N-Up-End
-     {gsave
-      PageWidth 0 rlineto
-      0 LandscapePageHeight rlineto
-      PageWidth neg 0 rlineto
-      closepath stroke
-      grestore
-      /pages-per-sheet pages-per-sheet 1 sub def
-      pages-per-sheet 0 le{exit}if
-      N-Up-XColumn N-Up-YColumn rmoveto
-     }repeat
-     pages-per-sheet 0 le{exit}if
-     N-Up-XLine N-Up-XColumn sub N-Up-YLine rmoveto
-    }repeat
-    grestore
-  }if
-}def
-
-/EndSheet {
-  showpage
-  sheetState restore
-}def
-
-/SetHeaderLines {                      % nb-lines --
-  /HeaderLines exch def
-  % ---- bottom up
-  HeaderPad
-  HeaderLines 1 sub HeaderLineHeight mul add
-  HeaderTitleLineHeight add
-  HeaderPad add
-  /HeaderHeight exch def
-} def
-
-% |---------|
-% |  tm     |
-% |---------|
-% |  header |
-% |-+-------| <-- (x y)
-% |  ho     |
-% |---------|
-% |  text   |
-% |-+-------| <-- (0 0)
-% |  bm     |
-% |---------|
-
-/HeaderFrameStart {                    % -- x y
-  0  PrintHeight HeaderOffset add
-} def
-
-/HeaderFramePath {
-  PrintHeaderWidth     0                       rlineto
-  0                    HeaderHeight            rlineto
-  PrintHeaderWidth neg 0                       rlineto
-  0                    HeaderHeight neg        rlineto
-} def
-
-/HeaderFrame {
-  gsave
-    0.4 setlinewidth
-    % ---- fill a black rectangle (the shadow of the next one)
-    HeaderFrameStart moveto
-    1 -1 rmoveto
-    HeaderFramePath
-    0 setgray fill
-    % ---- do the next rectangle ...
-    HeaderFrameStart moveto
-    HeaderFramePath
-    gsave 0.9 setgray fill grestore    % filled with grey
-    gsave 0 setgray stroke grestore    % drawn  with black
-  grestore
-} def
-
-/HeaderStart {
-  HeaderFrameStart
-  exch HeaderPad add exch      % horizontal pad
-  % ---- bottom up
-  HeaderPad add                        % vertical   pad
-  HeaderDescent sub
-  HeaderLineHeight HeaderLines 1 sub mul add
-} def
-
-/strcat {
-  dup length 3 -1 roll dup length dup 4 -1 roll add string dup
-  0 5 -1 roll putinterval
-  dup 4 2 roll exch putinterval
-} def
-
-/pagenumberstring {
-  PageNumber 32 string cvs
-  ShowNofN {
-    (/) strcat
-    PageCount 32 string cvs strcat
-  } if
-} def
-
-/HeaderText {
-  HeaderStart moveto
-
-  HeaderLinesRight HeaderLinesLeft     % -- rightLines leftLines
-
-  % ---- hack: `PN 1 and'  ==  `PN 2 modulo'
-
-  % ---- if even page number and duplex, then exchange left and right
-  PageNumber 1 and 0 eq DuplexValue and { exch } if
-
-  { % ---- process the left lines
-    aload pop
-    exch F
-    gsave
-      dup xcheck { exec } if
-      show
-    grestore
-    0 HeaderLineHeight neg rmoveto
-  } forall
-
-  HeaderStart moveto
-
-  { % ---- process the right lines
-    aload pop
-    exch F
-    gsave
-      dup xcheck { exec } if
-      dup stringwidth pop
-      PrintHeaderWidth exch sub HeaderPad 2 mul sub 0 rmoveto
-      show
-    grestore
-    0 HeaderLineHeight neg rmoveto
-  } forall
-} def
-
-/ReportFontInfo {
-  2 copy
-  /t0 3 1 roll DefFont
-  /t0 F
-  /lh FontHeight def
-  /sw ( ) stringwidth pop def
-  /aw (01234567890abcdefghijklmnopqrstuvwxyz) dup length exch
-  stringwidth pop exch div def
-  /t1 12 /Helvetica-Oblique DefFont
-  /t1 F
-  gsave
-    (languagelevel = ) show
-    gs_languagelevel 32 string cvs show
-  grestore
-  0 FontHeight neg rmoveto
-  gsave
-    (For ) show
-    128 string cvs show
-    ( ) show
-    32 string cvs show
-    ( point, the line height is ) show
-    lh 32 string cvs show
-    (, the space width is ) show
-    sw 32 string cvs show
-    (,) show
-  grestore
-  0 FontHeight neg rmoveto
-  gsave
-    (and a crude estimate of average character width is ) show
-    aw 32 string cvs show
-    (.) show
-  grestore
-  0 FontHeight neg rmoveto
-} def
-
-/cm { % cm to point
-  72 mul 2.54 div
-} def
-
-/ReportAllFontInfo {
-  FontDirectory
-  { % key = font name  value = font dictionary
-    pop 10 exch ReportFontInfo
-  } forall
-} def
-
-% 3 cm 20 cm moveto  10 /Courier ReportFontInfo  showpage
-% 3 cm 20 cm moveto  ReportAllFontInfo           showpage
-
-/ErrorMessages
- [(This PostScript printer is not configured with this document page size.)
-  (Duplex printing is not supported on this PostScript printer.)]def
-
-% stack: error-index proc |- --
-/CheckConfig {
-  stopped {
-   1 cm LandscapePageHeight 0.5 mul moveto
-   /Courier findfont 10 scalefont setfont
-   gsave
-    (ps-print error:) show
-   grestore
-   0 -10 rmoveto
-   ErrorMessages exch get show
-   showpage
-   $error /newerror false put
-   stop
-  }if
-} bind def
+        (defun ps-face-background-name (face)
+          (ps-xemacs-color-name (face-background face)))
 
-")
+        (defun ps-face-bold-p (face)
+          (or (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold")
+              (memq face ps-bold-faces))) ; Kludge-compatible
 
-(defconst ps-print-prologue-2
-  "
-% ---- These lines must be kept together because...
+        (defun ps-face-italic-p (face)
+          (or (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o")
+              (ps-xemacs-face-kind-p face 'SLANT "i\\|o")
+              (memq face ps-italic-faces))) ; Kludge-compatible
+        )))
 
-/h0 F
-/HeaderTitleLineHeight FontHeight def
 
-/h1 F
-/HeaderLineHeight FontHeight def
-/HeaderDescent    Descent def
+(defvar ps-print-color-scale 1.0)
 
-% ---- ...because `F' has a side-effect on `FontHeight' and `Descent'
+(defun ps-color-scale (color)
+  ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
+  (mapcar #'(lambda (value) (/ value ps-print-color-scale))
+         (ps-color-values color)))
 
-")
 
-(defconst ps-print-duplex-feature
-  "
-% --- duplex feature verification
-1
-UseSetpagedevice {
-  {<< /Duplex DuplexValue /Tumble TumbleValue >> setpagedevice}
-}{
-  {statusdict begin
-    DuplexValue setduplexmode TumbleValue settumble
-   end}
-}ifelse
-CheckConfig
-")
+(defun ps-face-underlined-p (face)
+  (or (face-underline-p face)
+      (memq face ps-underlined-faces)))
+
+
+(require 'time-stamp)
+
+
+(defun ps-prologue-file (filenumber)
+  (save-excursion
+    (let* ((filename (format "%sps-prin%d.ps"
+                            ps-postscript-code-directory filenumber))
+          (buffer
+           (or (find-file-noselect filename 'no-warn 'rawfile)
+               (error "ps-print PostScript prologue `%s' file was not found."
+                      filename))))
+      (set-buffer buffer)
+      (prog1
+         (buffer-string)
+       (kill-buffer buffer)))))
+
+
+(defvar ps-mark-code-directory nil)
+
+(defvar ps-print-prologue-0 ""
+  "ps-print PostScript error handler.")
+
+(defvar ps-print-prologue-1 ""
+  "ps-print PostScript prologue begin.")
+
+(defvar ps-print-prologue-2 ""
+  "ps-print PostScript prologue end.")
 
 ;; Start Editing Here:
 
@@ -3017,9 +3083,14 @@ CheckConfig
 (defvar ps-page-postscript 0)
 (defvar ps-page-order 0)
 (defvar ps-page-count 0)
+(defvar ps-page-n-up 0)
 (defvar ps-showline-count 1)
+(defvar ps-first-page nil)
+(defvar ps-last-page nil)
+(defvar ps-print-page-p t)
 
 (defvar ps-control-or-escape-regexp nil)
+(defvar ps-n-up-on nil)
 
 (defvar ps-background-pages nil)
 (defvar ps-background-all-pages nil)
@@ -3027,8 +3098,9 @@ CheckConfig
 (defvar ps-background-image-count 0)
 
 (defvar ps-current-font 0)
-(defvar ps-default-color (and ps-print-color-p ps-default-fg)) ; black
-(defvar ps-current-color ps-default-color)
+(defvar ps-default-foreground nil)
+(defvar ps-default-color nil)
+(defvar ps-current-color nil)
 (defvar ps-current-bg nil)
 
 (defvar ps-razchunk 0)
@@ -3067,8 +3139,6 @@ This is in units of points (1/72 inch).")
 (defvar ps-height-remaining nil)
 (defvar ps-width-remaining nil)
 
-(defvar ps-print-color-scale nil)
-
 (defvar ps-font-size-internal nil)
 (defvar ps-header-font-size-internal nil)
 (defvar ps-header-title-font-size-internal nil)
@@ -3207,7 +3277,7 @@ If EXTENSION is any other symbol, it is ignored."
 (defun ps-font-lock-face-attributes ()
   (and (boundp 'font-lock-mode) (symbol-value 'font-lock-mode)
        (boundp 'font-lock-face-attributes)
-       (let ((face-attributes font-lock-face-attributes))
+       (let ((face-attributes (symbol-value 'font-lock-face-attributes)))
         (while face-attributes
           (let* ((face-attribute
                   (car (prog1 face-attributes
@@ -3242,10 +3312,10 @@ If EXTENSION is any other symbol, it is ignored."
 ;; Internal functions and variables
 
 
-(make-local-hook 'ps-print-hook)
-(make-local-hook 'ps-print-begin-sheet-hook)
-(make-local-hook 'ps-print-begin-page-hook)
-(make-local-hook 'ps-print-begin-column-hook)
+(defvar ps-print-hook nil)
+(defvar ps-print-begin-sheet-hook nil)
+(defvar ps-print-begin-page-hook nil)
+(defvar ps-print-begin-column-hook nil)
 
 
 (defun ps-print-without-faces (from to &optional filename region-p)
@@ -3255,7 +3325,7 @@ If EXTENSION is any other symbol, it is ignored."
 
 (defun ps-spool-without-faces (from to &optional region-p)
   (run-hooks 'ps-print-hook)
-  (ps-printing-region region-p)
+  (ps-printing-region region-p from)
   (ps-generate (current-buffer) from to 'ps-generate-postscript))
 
 
@@ -3266,7 +3336,7 @@ If EXTENSION is any other symbol, it is ignored."
 
 (defun ps-spool-with-faces (from to &optional region-p)
   (run-hooks 'ps-print-hook)
-  (ps-printing-region region-p)
+  (ps-printing-region region-p from)
   (ps-generate (current-buffer) from to 'ps-generate-postscript-with-faces))
 
 
@@ -3290,11 +3360,11 @@ file.")
   "Non-nil means ps-print is printing a region.")
 
 
-(defun ps-printing-region (region-p)
+(defun ps-printing-region (region-p from)
   (setq ps-printing-region-p region-p
        ps-printing-region
        (cons (if region-p
-                 (ps-count-lines (point-min) (region-beginning))
+                 (ps-count-lines (point-min) from)
                1)
              (ps-count-lines (point-min) (point-max)))))
 
@@ -3353,22 +3423,31 @@ which long lines wrap around."
   "Display the correspondence between a line length and a font size,
 using the current ps-print setup.
 Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
-  (let ((buf (get-buffer-create "*Line-lengths*"))
-       (ifs ps-font-size-internal)     ; initial font size
-       (icw (ps-avg-char-width 'ps-font-for-text)) ; initial character width
-       (print-width (progn (ps-get-page-dimensions)
-                           ps-print-width))
-       (ps-setup (ps-setup))           ; setup for the current buffer
-       (fs-min 5)                      ; minimum font size
-       cw-min                          ; minimum character width
-       nb-cpl-max                      ; maximum nb of characters per line
-       (fs-max 14)                     ; maximum font size
-       cw-max                          ; maximum character width
-       nb-cpl-min                      ; minimum nb of characters per line
-       fs                              ; current font size
-       cw                              ; current character width
-       nb-cpl                          ; current nb of characters per line
-       )
+  (let* ((ps-font-size-internal
+         (or ps-font-size-internal
+             (ps-get-font-size 'ps-font-size)))
+        (ps-header-font-size-internal
+         (or ps-header-font-size-internal
+             (ps-get-font-size 'ps-header-font-size)))
+        (ps-header-title-font-size-internal
+         (or ps-header-title-font-size-internal
+             (ps-get-font-size 'ps-header-title-font-size)))
+        (buf (get-buffer-create "*Line-lengths*"))
+        (ifs ps-font-size-internal)    ; initial font size
+        (icw (ps-avg-char-width 'ps-font-for-text)) ; initial character width
+        (print-width (progn (ps-get-page-dimensions)
+                            ps-print-width))
+        (ps-setup (ps-setup))          ; setup for the current buffer
+        (fs-min 5)                     ; minimum font size
+        cw-min                         ; minimum character width
+        nb-cpl-max                     ; maximum nb of characters per line
+        (fs-max 14)                    ; maximum font size
+        cw-max                         ; maximum character width
+        nb-cpl-min                     ; minimum nb of characters per line
+        fs                             ; current font size
+        cw                             ; current character width
+        nb-cpl                         ; current nb of characters per line
+        )
     (setq cw-min     (/ (* icw fs-min) ifs)
          nb-cpl-max (floor (/ print-width cw-min))
          cw-max     (/ (* icw fs-max) ifs)
@@ -3376,13 +3455,13 @@ Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
          nb-cpl     nb-cpl-min)
     (set-buffer buf)
     (goto-char (point-max))
-    (or (bolp) (insert "\n"))
+    (or (bobp) (insert "\n" (make-string 75 ?\;) "\n"))
     (insert ps-setup
-           "nb char per line / font size\n")
+           "\nnb char per line / font size\n")
     (while (<= nb-cpl nb-cpl-max)
       (setq cw (/ print-width (float nb-cpl))
            fs (/ (* ifs cw) icw))
-      (insert (format "%3s %s\n" nb-cpl fs))
+      (insert (format "%16d   %s\n" nb-cpl fs))
       (setq nb-cpl (1+ nb-cpl)))
     (insert "\n")
     (display-buffer buf 'not-this-window)))
@@ -3391,25 +3470,34 @@ Try: pr -t file | awk '{printf \"%3d %s\n\", length($0), $0}' | sort -r | head"
   "Display correspondence between font size and the number of pages.
 The correspondence is based on having NB-LINES lines of text,
 and on the current ps-print setup."
-  (let ((buf (get-buffer-create "*Nb-Pages*"))
-       (ifs ps-font-size-internal)     ; initial font size
-       (ilh (ps-line-height 'ps-font-for-text)) ; initial line height
-       (page-height (progn (ps-get-page-dimensions)
-                           ps-print-height))
-       (ps-setup (ps-setup))           ; setup for the current buffer
-       (fs-min 4)                      ; minimum font size
-       lh-min                          ; minimum line height
-       nb-lpp-max                      ; maximum nb of lines per page
-       nb-page-min                     ; minimum nb of pages
-       (fs-max 14)                     ; maximum font size
-       lh-max                          ; maximum line height
-       nb-lpp-min                      ; minimum nb of lines per page
-       nb-page-max                     ; maximum nb of pages
-       fs                              ; current font size
-       lh                              ; current line height
-       nb-lpp                          ; current nb of lines per page
-       nb-page                         ; current nb of pages
-       )
+  (let* ((ps-font-size-internal
+         (or ps-font-size-internal
+             (ps-get-font-size 'ps-font-size)))
+        (ps-header-font-size-internal
+         (or ps-header-font-size-internal
+             (ps-get-font-size 'ps-header-font-size)))
+        (ps-header-title-font-size-internal
+         (or ps-header-title-font-size-internal
+             (ps-get-font-size 'ps-header-title-font-size)))
+        (buf (get-buffer-create "*Nb-Pages*"))
+        (ifs ps-font-size-internal)    ; initial font size
+        (ilh (ps-line-height 'ps-font-for-text)) ; initial line height
+        (page-height (progn (ps-get-page-dimensions)
+                            ps-print-height))
+        (ps-setup (ps-setup))          ; setup for the current buffer
+        (fs-min 4)                     ; minimum font size
+        lh-min                         ; minimum line height
+        nb-lpp-max                     ; maximum nb of lines per page
+        nb-page-min                    ; minimum nb of pages
+        (fs-max 14)                    ; maximum font size
+        lh-max                         ; maximum line height
+        nb-lpp-min                     ; minimum nb of lines per page
+        nb-page-max                    ; maximum nb of pages
+        fs                             ; current font size
+        lh                             ; current line height
+        nb-lpp                         ; current nb of lines per page
+        nb-page                        ; current nb of pages
+        )
     (setq lh-min      (/ (* ilh fs-min) ifs)
          nb-lpp-max  (floor (/ page-height lh-min))
          nb-page-min (ceiling (/ (float nb-lines) nb-lpp-max))
@@ -3419,15 +3507,15 @@ and on the current ps-print setup."
          nb-page     nb-page-min)
     (set-buffer buf)
     (goto-char (point-max))
-    (or (bolp) (insert "\n"))
+    (or (bobp) (insert "\n" (make-string 75 ?\;) "\n"))
     (insert ps-setup
-           (format "%d lines\n" nb-lines)
+           (format "\nThere are %d lines.\n\n" nb-lines)
            "nb page / font size\n")
     (while (<= nb-page nb-page-max)
       (setq nb-lpp (ceiling (/ nb-lines (float nb-page)))
            lh     (/ page-height nb-lpp)
            fs     (/ (* ifs lh) ilh))
-      (insert (format "%s %s\n" nb-page fs))
+      (insert (format "%7d   %s\n" nb-page fs))
       (setq nb-page (1+ nb-page)))
     (insert "\n")
     (display-buffer buf 'not-this-window)))
@@ -3545,25 +3633,28 @@ page-height == bm + print-height + tm - ho - hh
                  ps-header-pad)
               ps-print-height))))
 
-(defun ps-print-preprint (&optional filename)
-  (and filename
-       (or (numberp filename)
-          (listp filename))
+(defun ps-print-preprint (prefix-arg)
+  (and prefix-arg
+       (or (numberp prefix-arg)
+          (listp prefix-arg))
        (let* ((name   (concat (file-name-nondirectory (or (buffer-file-name)
                                                          (buffer-name)))
                              ".ps"))
              (prompt (format "Save PostScript to file: (default %s) " name))
              (res    (read-file-name prompt default-directory name nil)))
-        (while (cond ((not (file-writable-p res))
+        (while (cond ((file-directory-p res)
+                      (ding)
+                      (setq prompt "It's a directory"))
+                     ((not (file-writable-p res))
                       (ding)
-                      (setq prompt "is unwritable"))
+                      (setq prompt "File is unwritable"))
                      ((file-exists-p res)
-                      (setq prompt "exists")
+                      (setq prompt "File exists")
                       (not (y-or-n-p (format "File `%s' exists; overwrite? "
                                              res))))
                      (t nil))
           (setq res (read-file-name
-                     (format "File %s; save PostScript to file: " prompt)
+                     (format "%s; save PostScript to file: " prompt)
                      (file-name-directory res) nil nil
                      (file-name-nondirectory res))))
         (if (file-directory-p res)
@@ -3618,13 +3709,43 @@ page-height == bm + print-height + tm - ho - hh
   (insert ")"))                                ;insert end-string delimiter
 
 (defun ps-init-output-queue ()
-  (setq ps-output-head '("")
+  (setq ps-output-head (list "")
        ps-output-tail ps-output-head))
 
+
+(defun ps-selected-pages ()
+  (while (progn
+          (setq ps-first-page     (car (car ps-selected-pages))
+                ps-last-page      (cdr (car ps-selected-pages))
+                ps-selected-pages (cdr ps-selected-pages))
+          (and ps-selected-pages
+               (< ps-last-page ps-page-postscript)))))
+
+
+(defun ps-print-page-p ()
+  (setq ps-print-page-p
+       (and (cond ((null ps-first-page))
+                  ((<= ps-page-postscript ps-last-page)
+                   (<= ps-first-page ps-page-postscript))
+                  (ps-selected-pages
+                   (ps-selected-pages)
+                   (and (<= ps-first-page ps-page-postscript)
+                        (<= ps-page-postscript ps-last-page)))
+                  (t
+                   nil))
+            (cond ((eq ps-even-or-odd-pages 'even)
+                   (= (logand ps-page-postscript 1) 0))
+                  ((eq ps-even-or-odd-pages 'odd)
+                   (= (logand ps-page-postscript 1) 1))
+                  (t)
+                  ))))
+
+
 (defun ps-output (&rest args)
-  (setcdr ps-output-tail args)
-  (while (cdr ps-output-tail)
-    (setq ps-output-tail (cdr ps-output-tail))))
+  (when ps-print-page-p
+    (setcdr ps-output-tail args)
+    (while (cdr ps-output-tail)
+      (setq ps-output-tail (cdr ps-output-tail)))))
 
 (defun ps-output-string (string)
   (ps-output t string))
@@ -3659,10 +3780,6 @@ page-height == bm + print-height + tm - ho - hh
 
 (defun ps-insert-file (fname)
   (ps-flush-output)
-  ;; Check to see that the file exists and is readable; if not, throw
-  ;; an error.
-  (or (file-readable-p fname)
-      (error "Could not read file `%s'" fname))
   (save-excursion
     (set-buffer ps-spool-buffer)
     (goto-char (point-max))
@@ -3706,9 +3823,8 @@ page-height == bm + print-height + tm - ho - hh
        (ps-output "] def\n"))))
 
 
-(defun ps-output-boolean (name bool &optional no-def)
-  (ps-output (format "/%s %s%s"
-                    name (if bool "true" "false") (if no-def "\n" " def\n"))))
+(defun ps-output-boolean (name bool)
+  (ps-output (format "/%s %s def\n" name (if bool "true" "false"))))
 
 
 (defun ps-background-pages (page-list func)
@@ -3767,7 +3883,7 @@ page-height == bm + print-height + tm - ho - hh
   (mapcar
    #'(lambda (text)
        (setq ps-background-text-count (1+ ps-background-text-count))
-       (ps-output (format "/ShowBackText-%d {\n" ps-background-text-count))
+       (ps-output (format "/ShowBackText-%d{\n" ps-background-text-count))
        (ps-output-string (nth 0 text)) ; text
        (ps-output
        "\n"
@@ -3777,8 +3893,8 @@ page-height == bm + print-height + tm - ho - hh
                         "PrintHeight PrintPageWidth atan") ; rotation
        (ps-float-format (nth 5 text) 0.85) ; gray
        (ps-float-format (nth 1 text) "0") ; x position
-       (ps-float-format (nth 2 text) "BottomMargin") ; y position
-       "\nShowBackText} def\n")
+       (ps-float-format (nth 2 text) "0") ; y position
+       "\nShowBackText}def\n")
        (ps-background-pages (nthcdr 7 text) ; page list
                            (format "ShowBackText-%d\n"
                                    ps-background-text-count)))
@@ -3789,41 +3905,40 @@ page-height == bm + print-height + tm - ho - hh
   (mapcar
    #'(lambda (image)
        (let ((image-file (expand-file-name (nth 0 image))))
-        (if (file-readable-p image-file)
-            (progn
-              (setq ps-background-image-count (1+ ps-background-image-count))
-              (ps-output
-               (format "/ShowBackImage-%d {\n--back-- "
-                       ps-background-image-count)
-               (ps-float-format (nth 5 image) 0.0) ; rotation
-               (ps-float-format (nth 3 image) 1.0) ; x scale
-               (ps-float-format (nth 4 image) 1.0) ; y scale
-               (ps-float-format (nth 1 image) ; x position
-                                "PrintPageWidth 2 div")
-               (ps-float-format (nth 2 image) ; y position
-                                "PrintHeight 2 div BottomMargin add")
-               "\nBeginBackImage\n")
-              (ps-insert-file image-file)
-              ;; coordinate adjustment to centralize image
-              ;; around x and y position
-              (let ((box (ps-get-boundingbox)))
-                (save-excursion
-                  (set-buffer ps-spool-buffer)
-                  (save-excursion
-                    (if (re-search-backward "^--back--" nil t)
-                        (replace-match
-                         (format "%s %s"
-                                 (ps-float-format
-                                  (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
-                                        (aref box 0))))
-                                 (ps-float-format
-                                  (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
-                                        (aref box 1)))))
-                         t)))))
-              (ps-output "\nEndBackImage} def\n")
-              (ps-background-pages (nthcdr 6 image) ; page list
-                                   (format "ShowBackImage-%d\n"
-                                           ps-background-image-count))))))
+        (when (file-readable-p image-file)
+          (setq ps-background-image-count (1+ ps-background-image-count))
+          (ps-output
+           (format "/ShowBackImage-%d{\n--back-- "
+                   ps-background-image-count)
+           (ps-float-format (nth 5 image) 0.0) ; rotation
+           (ps-float-format (nth 3 image) 1.0) ; x scale
+           (ps-float-format (nth 4 image) 1.0) ; y scale
+           (ps-float-format (nth 1 image) ; x position
+                            "PrintPageWidth 2 div")
+           (ps-float-format (nth 2 image) ; y position
+                            "PrintHeight 2 div BottomMargin add")
+           "\nBeginBackImage\n")
+          (ps-insert-file image-file)
+          ;; coordinate adjustment to centralize image
+          ;; around x and y position
+          (let ((box (ps-get-boundingbox)))
+            (save-excursion
+              (set-buffer ps-spool-buffer)
+              (save-excursion
+                (if (re-search-backward "^--back--" nil t)
+                    (replace-match
+                     (format "%s %s"
+                             (ps-float-format
+                              (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
+                                    (aref box 0))))
+                             (ps-float-format
+                              (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
+                                    (aref box 1)))))
+                     t)))))
+          (ps-output "\nEndBackImage}def\n")
+          (ps-background-pages (nthcdr 6 image) ; page list
+                               (format "ShowBackImage-%d\n"
+                                       ps-background-image-count)))))
    ps-print-background-image))
 
 
@@ -3835,10 +3950,10 @@ page-height == bm + print-height + tm - ho - hh
                     (if has-local-background
                         (ps-output (aref range 2))
                       (setq has-local-background t)
-                      (ps-output "/printLocalBackground {\n"
+                      (ps-output "/printLocalBackground{\n"
                                  (aref range 2)))))
            ps-background-pages)
-    (and has-local-background (ps-output "} def\n"))))
+    (and has-local-background (ps-output "}def\n"))))
 
 
 ;; Return a list of the distinct elements of LIST.
@@ -3916,6 +4031,7 @@ page-height == bm + print-height + tm - ho - hh
      (100 nil 10 10 0))
     (letter
      (1   nil 1  1  0)
+     (2   t   1  2  0)                 ; adjusted by PostScript code
      (4   nil 2  2  0)
      (6   t   2  3  0)
      (9   nil 3  3  0)
@@ -3958,6 +4074,7 @@ page-height == bm + print-height + tm - ho - hh
      (100 nil 10 10 0))
     (letter-small
      (1   nil 1  1  0)
+     (2   t   1  2  0)                 ; adjusted by PostScript code
      (4   nil 2  2  0)
      (6   t   2  3  0)
      (9   nil 3  3  0)
@@ -4053,6 +4170,7 @@ page-height == bm + print-height + tm - ho - hh
      (100 nil 10 10 0))
     (executive
      (1   nil 1  1  0)
+     (2   t   1  2  0)                 ; adjusted by PostScript code
      (4   nil 2  2  0)
      (6   t   2  3  0)
      (9   nil 3  3  0)
@@ -4290,10 +4408,20 @@ XSTART YSTART are the relative position for the first page in a sheet.")
 (defmacro ps-n-up-ystart  (init) `(nth 7 ,init))
 
 
+(defconst ps-error-handler-alist
+  '((none             . 0)
+    (paper            . 1)
+    (system           . 2)
+    (paper-and-system . 3))
+  "Alist for error handler message")
+
+
 (defun ps-begin-file ()
   (ps-get-page-dimensions)
   (setq ps-page-postscript 0
        ps-page-order 0
+       ps-page-n-up 0
+       ps-print-page-p t
        ps-background-text-count 0
        ps-background-image-count 0
        ps-background-pages nil
@@ -4303,7 +4431,7 @@ XSTART YSTART are the relative position for the first page in a sheet.")
        (tumble (if ps-landscape-mode (not ps-spool-tumble) ps-spool-tumble))
        (n-up (ps-n-up-printing))
        (n-up-filling (ps-n-up-filling)))
-    (and (> ps-n-up-printing 1) (setq tumble (not tumble)))
+    (and ps-n-up-on (setq tumble (not tumble)))
     (ps-output
      ps-adobe-tag
      "%%Title: " (buffer-name)         ; Take job name from name of
@@ -4326,22 +4454,30 @@ XSTART YSTART are the relative position for the first page in a sheet.")
      (format " %d" (round (ps-page-dimensions-get-height dimensions)))
      " 0 () ()\n%%PageOrder: Ascend\n%%Pages: (atend)\n%%Requirements:"
      (if ps-spool-duplex
-        (format " duplex%s" (if tumble "(tumble)\n" "\n"))
+        (if tumble " duplex(tumble)\n" " duplex\n")
        "\n"))
 
-    (let ((comments (if (functionp ps-print-prologue-header)
-                       (funcall ps-print-prologue-header)
-                     ps-print-prologue-header)))
-      (and (stringp comments)
-          (ps-output comments)))
+    (ps-insert-string ps-print-prologue-header)
+
+    (ps-output "%%EndComments\n%%BeginDefaults\n%%PageMedia: "
+              (ps-page-dimensions-get-media dimensions)
+              "\n%%EndDefaults\n\n%%BeginPrologue\n\n"
+              "/languagelevel where{pop}{/languagelevel 1 def}ifelse\n"
+              (format "/ErrorMessage  %s def\n\n"
+                      (or (cdr (assoc ps-error-handler-message
+                                      ps-error-handler-alist))
+                          1))          ; send to paper
+              ps-print-prologue-0
+              "\n%%BeginProcSet: UserDefinedPrologue\n\n")
 
-    (ps-output "%%EndComments\n\n%%BeginPrologue\n\n"
-              "/gs_languagelevel /languagelevel where {pop languagelevel}{1}ifelse def\n\n")
+    (ps-insert-string ps-user-defined-prologue)
+
+    (ps-output "\n%%EndProcSet\n\n")
 
-    (ps-output-boolean "SkipFirstPage      " ps-banner-page-when-duplexing)
     (ps-output-boolean "LandscapeMode      "
                       (or ps-landscape-mode
                           (eq (ps-n-up-landscape n-up) 'pag)))
+    (ps-output-boolean "UpsideDown         " ps-print-upside-down)
     (ps-output (format "/NumberOfColumns     %d def\n" ps-number-of-columns)
 
               (format "/LandscapePageHeight %s def\n" ps-landscape-page-height)
@@ -4364,9 +4500,10 @@ XSTART YSTART are the relative position for the first page in a sheet.")
     (ps-output-boolean "PrintHeader       " ps-print-header)
     (ps-output-boolean "PrintOnlyOneHeader" ps-print-only-one-header)
     (ps-output-boolean "PrintHeaderFrame  " ps-print-header-frame)
+    (ps-output-boolean "SwitchHeader      " (if (eq ps-switch-header 'duplex)
+                                               ps-spool-duplex
+                                             ps-switch-header))
     (ps-output-boolean "ShowNofN          " ps-show-n-of-n)
-    (ps-output-boolean "DuplexValue       " ps-spool-duplex)
-    (ps-output-boolean "TumbleValue       " tumble)
 
     (let ((line-height (ps-line-height 'ps-font-for-text)))
       (ps-output (format "/LineHeight     %s def\n" line-height)
@@ -4375,15 +4512,26 @@ XSTART YSTART are the relative position for the first page in a sheet.")
                                      (* line-height 0.45))
                                   line-height)))))
 
+    (ps-output-boolean "WarnPaperSize   " ps-warn-paper-type)
     (ps-output-boolean "Zebra           " ps-zebra-stripes)
+    (ps-output-boolean "ZebraFollow     " ps-zebra-stripe-follow)
     (ps-output-boolean "PrintLineNumber " ps-line-number)
-    (ps-output (format "/ZebraHeight      %d def\n" ps-zebra-stripe-height)
-              (format "/ZebraGray        %s def\n" ps-zebra-gray)
-              "/UseSetpagedevice "
+    (ps-output-boolean "SyncLineZebra   " (not (integerp ps-line-number-step)))
+    (ps-output (format "/PrintLineStep    %d def\n"
+                      (if (integerp ps-line-number-step)
+                          ps-line-number-step
+                        ps-zebra-stripe-height))
+              (format "/PrintLineStart   %d def\n" ps-line-number-start)
+              (format "/ZebraHeight      %d def\n" ps-zebra-stripe-height)
+              "/ZebraColor       "
+              (ps-format-color ps-zebra-color 0.95)
+              "def\n/BackgroundColor  "
+              (ps-format-color ps-default-bg 1.0)
+              "def\n/UseSetpagedevice "
               (if (eq ps-spool-config 'setpagedevice)
-                  "/setpagedevice where {pop true}{false}ifelse def\n"
-                "false def\n")
-              "\n/PageWidth "
+                  "/setpagedevice where{pop languagelevel 2 eq}{false}ifelse"
+                "false")
+              " def\n\n/PageWidth "
               "PrintPageWidth LeftMargin add RightMargin add def\n\n"
               (format "/N-Up           %d def\n" ps-n-up-printing))
     (ps-output-boolean "N-Up-Landscape" (eq (ps-n-up-landscape n-up) t))
@@ -4391,8 +4539,8 @@ XSTART YSTART are the relative position for the first page in a sheet.")
     (ps-output (format "/N-Up-Lines     %d def\n" (ps-n-up-lines n-up))
               (format "/N-Up-Columns   %d def\n" (ps-n-up-columns n-up))
               (format "/N-Up-Missing   %d def\n" (ps-n-up-missing n-up))
-              (format "/N-Up-Margin    %s" ps-n-up-margin)
-              " def\n/N-Up-Repeat    "
+              (format "/N-Up-Margin    %s def\n" ps-n-up-margin)
+              "/N-Up-Repeat    "
               (if ps-landscape-mode
                   (ps-n-up-end     n-up-filling)
                 (ps-n-up-repeat  n-up-filling))
@@ -4412,27 +4560,27 @@ XSTART YSTART are the relative position for the first page in a sheet.")
     (setq ps-background-all-pages (nreverse ps-background-all-pages)
          ps-background-pages (nreverse ps-background-pages))
 
-    (ps-output ps-print-prologue-1)
+    (ps-output "\n" ps-print-prologue-1)
 
-    (ps-output "/printGlobalBackground {\n")
+    (ps-output "\n/printGlobalBackground{\n")
     (ps-output-list ps-background-all-pages)
-    (ps-output "} def\n/printLocalBackground {\n} def\n")
+    (ps-output "}def\n/printLocalBackground{\n}def\n")
 
     ;; Header fonts
-    (ps-output (format "/h0 %s (%s) cvn DefFont\n" ; /h0 14 /Helvetica-Bold DefFont
+    (ps-output (format "/h0 %s(%s)cvn DefFont\n" ; /h0 14 /Helvetica-Bold DefFont
                       ps-header-title-font-size-internal
                       (ps-font 'ps-font-for-header 'bold))
-              (format "/h1 %s (%s) cvn DefFont\n" ; /h1 12 /Helvetica DefFont
+              (format "/h1 %s(%s)cvn DefFont\n" ; /h1 12 /Helvetica DefFont
                       ps-header-font-size-internal
                       (ps-font 'ps-font-for-header 'normal)))
 
-    (ps-output ps-print-prologue-2)
+    (ps-output "\n" ps-print-prologue-2 "\n")
 
     ;; Text fonts
     (let ((font (ps-font-alist 'ps-font-for-text))
          (i 0))
       (while font
-       (ps-output (format "/f%d %s (%s) cvn DefFont\n"
+       (ps-output (format "/f%d %s(%s)cvn DefFont\n"
                           i
                           ps-font-size-internal
                           (ps-font 'ps-font-for-text (car (car font)))))
@@ -4449,15 +4597,55 @@ XSTART YSTART are the relative position for the first page in a sheet.")
                 (ps-boolean-capitalized ps-spool-duplex)
                 " *Tumble "
                 (ps-boolean-capitalized tumble)
-                ps-print-duplex-feature
-                "%%EndFeature\n")))
-  (ps-output "\n/Lines 0 def\n/PageCount 0 def\n\nBeginDoc\n%%EndSetup\n"))
+                "\nUseSetpagedevice\n{BMark/Duplex "
+                (ps-boolean-constant ps-spool-duplex)
+                "/Tumble "
+                (ps-boolean-constant tumble)
+                " EMark setpagedevice}\n{statusdict begin "
+                (ps-boolean-constant ps-spool-duplex)
+                " setduplexmode "
+                (ps-boolean-constant tumble)
+                " settumble end}ifelse\n%%EndFeature\n")))
+  (ps-output "\n%%BeginFeature: *ManualFeed "
+            (ps-boolean-capitalized ps-manual-feed)
+            "\nBMark /ManualFeed "
+            (ps-boolean-constant ps-manual-feed)
+            " EMark setpagedevice\n%%EndFeature\n"
+            "\n/Lines 0 def\n/PageCount 0 def\n\nBeginDoc\n%%EndSetup\n")
+  (and ps-banner-page-when-duplexing
+       (ps-output "\n%%Page: banner 0\nsave showpage restore\n")))
+
+
+(defun ps-format-color (color &optional default)
+  (let ((the-color (if (stringp color)
+                      (ps-color-scale color)
+                    color)))
+    (if (and the-color (listp the-color))
+       (concat "["
+               (format ps-color-format
+                       (nth 0 the-color)
+                       (nth 1 the-color)
+                       (nth 2 the-color))
+               "] ")
+      (ps-float-format (if (numberp the-color) the-color default)))))
+
+
+(defun ps-insert-string (prologue)
+  (let ((str (if (functionp prologue)
+                (funcall prologue)
+              prologue)))
+    (and (stringp str)
+        (ps-output str))))
 
 
 (defun ps-boolean-capitalized (bool)
   (if bool "True" "False"))
 
 
+(defun ps-boolean-constant (bool)
+  (if bool "true" "false"))
+
+
 (defun ps-header-dirpart ()
   (let ((fname (buffer-file-name)))
     (if fname
@@ -4496,11 +4684,55 @@ XSTART YSTART are the relative position for the first page in a sheet.")
 
 
 (defun ps-begin-job ()
+  ;; prologue files
+  (let ((last-char (aref ps-postscript-code-directory
+                        (1- (length ps-postscript-code-directory)))))
+    (or (eq last-char ?/)
+       (and ps-windows-system (eq last-char ?\\))
+       (setq ps-postscript-code-directory
+             (concat ps-postscript-code-directory "/"))))
+  (or (equal ps-mark-code-directory ps-postscript-code-directory)
+      (setq ps-print-prologue-0    (ps-prologue-file 0)
+           ps-print-prologue-1    (ps-prologue-file 1)
+           ps-print-prologue-2    (ps-prologue-file 2)
+           ps-mark-code-directory ps-postscript-code-directory))
+  ;; selected pages
+  (let (new page)
+    (while ps-selected-pages
+      (setq page              (car ps-selected-pages)
+           ps-selected-pages (cdr ps-selected-pages))
+      (cond ((integerp page)
+            (and (> page 0)
+                 (setq new (cons (cons page page) new))))
+           ((consp page)
+            (and (integerp (car page)) (integerp (cdr page))
+                 (> (car page) 0)
+                 (<= (car page) (cdr page))
+                 (setq new (cons page new))))))
+    (setq ps-selected-pages      (sort new #'(lambda (one other)
+                                              (< (car one) (car other))))
+         ps-last-selected-pages ps-selected-pages
+         ps-first-page          nil
+         ps-last-page           nil))
+  ;; face background
+  (or (listp ps-use-face-background)
+      (setq ps-use-face-background t))
+  ;; line number
+  (and (integerp ps-line-number-step)
+       (<= ps-line-number-step 0)
+       (setq ps-line-number-step 1))
+  (setq ps-n-up-on           (> ps-n-up-printing 1)
+       ps-line-number-start (max 1 (min ps-line-number-start
+                                        (if (integerp ps-line-number-step)
+                                            ps-line-number-step
+                                          ps-zebra-stripe-height))))
+  ;; spooling buffer
   (save-excursion
     (set-buffer ps-spool-buffer)
     (goto-char (point-max))
     (and (re-search-backward "^%%Trailer$" nil t)
         (delete-region (match-beginning 0) (point-max))))
+  ;; miscellaneous
   (setq ps-showline-count (car ps-printing-region)
        ps-page-count 0
        ps-font-size-internal        (ps-get-font-size 'ps-font-size)
@@ -4514,28 +4746,31 @@ XSTART YSTART are the relative position for the first page in a sheet.")
               (string-as-unibyte "[\000-\037\177-\237]"))
              ((eq ps-print-control-characters 'control)
               "[\000-\037\177]")
-             (t "[\t\n\f]"))))
+             (t "[\t\n\f]"))
+       ps-default-foreground (ps-rgb-color ps-default-fg 0.0)
+       ps-default-color (and ps-print-color-p ps-default-foreground)
+       ps-current-color ps-default-color
+       ;; Set the color scale.  We do it here instead of in the defvar so
+       ;; that ps-print can be dumped into emacs.  This expression can't be
+       ;; evaluated at dump-time because X isn't initialized.
+       ps-color-p           (and ps-print-color-p (ps-color-device))
+       ps-print-color-scale (if ps-color-p
+                                (float (car (ps-color-values "white")))
+                              1.0)))
 
-(defmacro ps-page-number ()
-  `(1+ (/ (1- ps-page-count) ps-number-of-columns)))
 
-(defun ps-end-file ()
-  ;; Back to the PS output buffer to set the last page n-up printing
-  (save-excursion
-    (let ((pages-per-sheet (mod ps-page-postscript ps-n-up-printing))
-         case-fold-search)
-      (set-buffer ps-spool-buffer)
-      (goto-char (point-max))
-      (and (> pages-per-sheet 0)
-          (re-search-backward "^[0-9]+ BeginSheet$" nil t)
-          (replace-match (format "%d BeginSheet" pages-per-sheet) t))))
-  ;; Set dummy page
-  (and ps-spool-duplex (= (mod ps-page-order 2) 1)
-       (ps-dummy-page))
-  ;; Set end of PostScript file
-  (ps-output "EndSheet\n\n%%Trailer\n%%Pages: "
-            (format "%d" ps-page-order)
-            "\n\nEndDoc\n\n%%EOF\n"))
+(defun ps-rgb-color (color default)
+  (cond ((and color (listp color)) color)
+       ((stringp color) (ps-color-scale color))
+       ((numberp color) (list color color color))
+       (t (list default default default))
+       ))
+
+
+(defun ps-page-number ()
+  (if ps-print-only-one-header
+      (1+ (/ (1- ps-page-count) ps-number-of-columns))
+    ps-page-count))
 
 
 (defun ps-next-page ()
@@ -4546,36 +4781,39 @@ XSTART YSTART are the relative position for the first page in a sheet.")
 
 (defun ps-header-sheet ()
   ;; Print only when a new sheet begins.
-  (setq ps-page-postscript (1+ ps-page-postscript)
-       ps-page-order (1+ ps-page-order))
+  (setq ps-page-order (1+ ps-page-order))
   (and (> ps-page-order 1)
        (ps-output "EndSheet\n"))
-  (ps-output (format "\n%%%%Page: %d %d\n"
-                    ps-page-postscript ps-page-order))
-  (ps-output (format "%d BeginSheet\nBeginDSCPage\n" ps-n-up-printing)))
+  (ps-output (if ps-n-up-on
+                (format "\n%%%%Page: (%d \\(%d\\)) %d\n"
+                        ps-page-order ps-page-postscript ps-page-order)
+              (format "\n%%%%Page: %d %d\n"
+                      ps-page-postscript ps-page-order))
+            (format "%d BeginSheet\nBeginDSCPage\n"
+                    ps-n-up-printing)))
 
 
-(defsubst ps-header-page ()
+(defun ps-header-page ()
   ;; set total line and page number when printing has finished
   ;; (see `ps-generate')
-  (run-hooks
-   (if (prog1
-          (zerop (mod ps-page-count ps-number-of-columns))
-        (setq ps-page-count (1+ ps-page-count)))
-       (prog1
-          (if (zerop (mod ps-page-postscript ps-n-up-printing))
-              ;; Print only when a new sheet begins.
-              (progn
-                (ps-header-sheet)
-                'ps-print-begin-sheet-hook)
-            ;; Print only when a new page begins.
-            (setq ps-page-postscript (1+ ps-page-postscript))
-            (ps-output "BeginDSCPage\n")
-            'ps-print-begin-page-hook)
-        (ps-background ps-page-postscript))
-     ;; Print only when a new column begins.
-     (ps-output "BeginDSCPage\n")
-     'ps-print-begin-column-hook)))
+  (if (zerop (mod ps-page-count ps-number-of-columns))
+      (progn
+       (setq ps-page-postscript (1+ ps-page-postscript))
+       (when (ps-print-page-p)
+         (if (zerop (mod ps-page-n-up ps-n-up-printing))
+             ;; Print only when a new sheet begins.
+             (progn
+               (ps-header-sheet)
+               (run-hooks 'ps-print-begin-sheet-hook))
+           ;; Print only when a new page begins.
+           (ps-output "BeginDSCPage\n")
+           (run-hooks 'ps-print-begin-page-hook))
+         (ps-background ps-page-postscript)
+         (setq ps-page-n-up (1+ ps-page-n-up))))
+    ;; Print only when a new column begins.
+    (ps-output "BeginDSCPage\n")
+    (run-hooks 'ps-print-begin-column-hook))
+  (setq ps-page-count (1+ ps-page-count)))
 
 (defun ps-begin-page ()
   (ps-get-page-dimensions)
@@ -4585,9 +4823,7 @@ XSTART YSTART are the relative position for the first page in a sheet.")
   (ps-header-page)
 
   (ps-output (format "/LineNumber %d def\n" ps-showline-count)
-            (format "/PageNumber %d def\n" (if ps-print-only-one-header
-                                               (ps-page-number)
-                                             ps-page-count)))
+            (format "/PageNumber %d def\n" (ps-page-number)))
 
   (when ps-print-header
     (ps-generate-header "HeaderLinesLeft"    ps-left-header)
@@ -4603,17 +4839,6 @@ XSTART YSTART are the relative position for the first page in a sheet.")
 (defun ps-end-page ()
   (ps-output "EndPage\nEndDSCPage\n"))
 
-(defun ps-dummy-page ()
-  (let ((ps-n-up-printing 0))
-    (ps-header-sheet))
-  (ps-output "/PrintHeader false def
-/ColumnIndex 0 def
-/PrintLineNumber false def
-BeginPage
-EndPage
-EndDSCPage\n")
-  (setq ps-page-postscript ps-n-up-printing))
-
 (defun ps-next-line ()
   (setq ps-showline-count (1+ ps-showline-count))
   (let ((lh (ps-line-height 'ps-font-for-text)))
@@ -4692,7 +4917,7 @@ EndDSCPage\n")
     (ps-output "false BG\n")))
 
 (defun ps-set-color (color)
-  (setq ps-current-color (or color ps-default-fg))
+  (setq ps-current-color (or color ps-default-foreground))
   (ps-output (format ps-color-format
                     (nth 0 ps-current-color)
                     (nth 1 ps-current-color) (nth 2 ps-current-color))
@@ -4733,8 +4958,8 @@ EndDSCPage\n")
       (if (re-search-forward ps-control-or-escape-regexp to t)
          ;; region with some control characters or some multi-byte characters
          (let* ((match-point (match-beginning 0))
-                (match (char-after match-point))
-                (composition (find-composition from (1+ match-point))))
+                (match       (char-after match-point))
+                (composition (ps-e-find-composition from (1+ match-point))))
            (if composition
                (if (and (nth 2 composition)
                         (<= (car composition) match-point))
@@ -4763,23 +4988,22 @@ EndDSCPage\n")
             ((= match ?\f)             ; form feed
              ;; do not skip page if previous character is NEWLINE and
              ;; it is a beginning of page.
-             (or (and (= (char-after (1- match-point)) ?\n)
+             (or (and (equal (char-after (1- match-point)) ?\n)
                       (= ps-height-remaining ps-print-height))
                  (ps-next-page)))
 
             (composition               ; a composite sequence
              (ps-plot 'ps-mule-plot-composition match-point (point) bg-color))
 
-                                       ; characters from ^@ to ^_ and
             ((> match 255)             ; a multi-byte character
              (let* ((charset (char-charset match))
-                    (composition (find-composition match-point to))
+                    (composition (ps-e-find-composition match-point to))
                     (stop (if (nth 2 composition) (car composition) to)))
                (or (eq charset 'composition)
                    (while (and (< (point) stop) (eq (charset-after) charset))
                      (forward-char 1)))
                (ps-plot 'ps-mule-plot-string match-point (point) bg-color)))
-
+                                       ; characters from ^@ to ^_ and
             (t                         ; characters from 127 to 255
              (ps-control-character match)))
            (setq from (point)))
@@ -4821,37 +5045,6 @@ EndDSCPage\n")
     (ps-output-string str)
     (ps-output " S\n")))
 
-(defun ps-color-value (x-color-value)
-  ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
-  (/ x-color-value ps-print-color-scale))
-
-
-(cond ((eq ps-print-emacs-type 'emacs)  ; emacs
-
-       (defun ps-color-values (x-color)
-        (if (fboundp 'x-color-values)
-            (x-color-values x-color)
-          (error "No available function to determine X color values.")))
-       )
-                                       ; xemacs
-                                       ; lucid
-      (t                               ; epoch
-       (defun ps-color-values (x-color)
-        (cond ((fboundp 'x-color-values)
-               (x-color-values x-color))
-              ((and (fboundp 'color-instance-rgb-components)
-                    (ps-color-device))
-               (color-instance-rgb-components
-                (if (color-instance-p x-color)
-                    x-color
-                  (make-color-instance
-                   (if (color-specifier-p x-color)
-                       (color-name x-color)
-                     x-color)))))
-              (t
-               (error "No available function to determine X color values."))))
-       ))
-
 
 (defun ps-face-attributes (face)
   "Return face attribute vector.
@@ -4861,30 +5054,70 @@ If FACE is not in `ps-print-face-extension-alist' or in
 return the attribute vector.
 
 If FACE is not a valid face name, it is used default face."
-  (cdr (or (assq face ps-print-face-extension-alist)
-          (assq face ps-print-face-alist)
-          (let* ((the-face (if (facep face) face 'default))
-                 (new-face (ps-screen-to-bit-face the-face)))
-            (or (and (eq the-face 'default)
-                     (assq the-face ps-print-face-alist))
-                (setq ps-print-face-alist (cons new-face ps-print-face-alist)))
-            new-face))))
+  (cond
+   ((symbolp face)
+    (cdr (or (assq face ps-print-face-extension-alist)
+            (assq face ps-print-face-alist)
+            (let* ((the-face (if (facep face) face 'default))
+                   (new-face (ps-screen-to-bit-face the-face)))
+              (or (and (eq the-face 'default)
+                       (assq the-face ps-print-face-alist))
+                  (setq ps-print-face-alist
+                        (cons new-face ps-print-face-alist)))
+              new-face))))
+   ((eq (car face) 'foreground-color)
+    (vector 0 (cdr face) nil))
+   ((eq (car face) 'background-color)
+    (vector 0 nil (cdr face)))
+   (t
+    (vector 0 nil nil))))
+
+
+(defun ps-face-background (face background)
+  (and (or (eq ps-use-face-background t)
+          (cond ((symbolp face)
+                 (memq face ps-use-face-background))
+                ((listp face)
+                 (or (memq (car face) '(foreground-color background-color))
+                     (let (ok)
+                       (while face
+                         (if (or (memq (car face) ps-use-face-background)
+                                 (memq (car face)
+                                       '(foreground-color background-color)))
+                             (setq face nil
+                                   ok   t)
+                           (setq face (cdr face))))
+                       ok)))
+                (t
+                 nil)
+                ))
+       background))
 
 
 (defun ps-face-attribute-list (face-or-list)
-  (if (listp face-or-list)
-      ;; list of faces
-      (let ((effects 0)
-           foreground background face-attr)
-       (while face-or-list
-         (setq face-attr (ps-face-attributes (car face-or-list))
-               effects (logior effects (aref face-attr 0)))
-         (or foreground (setq foreground (aref face-attr 1)))
-         (or background (setq background (aref face-attr 2)))
-         (setq face-or-list (cdr face-or-list)))
-       (vector effects foreground background))
-    ;; simple face
-    (ps-face-attributes face-or-list)))
+  (cond
+   ;; simple face
+   ((not (listp face-or-list))
+    (ps-face-attributes face-or-list))
+   ;; only foreground color, not a `real' face
+   ((eq (car face-or-list) 'foreground-color)
+    (vector 0 (cdr face-or-list) nil))
+   ;; only background color, not a `real' face
+   ((eq (car face-or-list) 'background-color)
+    (vector 0 nil (cdr face-or-list)))
+   ;; list of faces
+   (t
+    (let ((effects 0)
+         foreground background face-attr face)
+      (while face-or-list
+       (setq face         (car face-or-list)
+             face-or-list (cdr face-or-list)
+             face-attr    (ps-face-attributes face)
+             effects      (logior effects (aref face-attr 0)))
+       (or foreground (setq foreground (aref face-attr 1)))
+       (or background
+           (setq background (ps-face-background face (aref face-attr 2)))))
+      (vector effects foreground background)))))
 
 
 (defconst ps-font-type (vector nil 'bold 'italic 'bold-italic))
@@ -4899,14 +5132,12 @@ If FACE is not a valid face name, it is used default face."
     (let* ((face-bit   (ps-face-attribute-list face))
           (effect     (aref face-bit 0))
           (foreground (aref face-bit 1))
-          (background (aref face-bit 2))
+          (background (ps-face-background face (aref face-bit 2)))
           (fg-color (if (and ps-color-p foreground)
-                        (mapcar 'ps-color-value
-                                (ps-color-values foreground))
+                        (ps-color-scale foreground)
                       ps-default-color))
           (bg-color (and ps-color-p background
-                         (mapcar 'ps-color-value
-                                 (ps-color-values background)))))
+                         (ps-color-scale background))))
       (ps-plot-region
        from to
        (ps-font-number 'ps-font-for-text
@@ -4916,47 +5147,6 @@ If FACE is not a valid face name, it is used default face."
   (goto-char to))
 
 
-(defun ps-xemacs-face-kind-p (face kind kind-regex kind-list)
-  (let* ((frame-font (or (face-font-instance face)
-                        (face-font-instance 'default)))
-        (kind-cons (and frame-font
-                        (assq kind
-                              (font-instance-properties frame-font))))
-        (kind-spec (cdr-safe kind-cons))
-        (case-fold-search t))
-    (or (and kind-spec (string-match kind-regex kind-spec))
-       ;; Kludge-compatible:
-       (memq face kind-list))))
-
-
-(cond ((eq ps-print-emacs-type 'emacs)  ; emacs
-
-       (defun ps-face-bold-p (face)
-        (or (face-bold-p face)
-            (memq face ps-bold-faces)))
-
-       (defun ps-face-italic-p (face)
-        (or (face-italic-p face)
-            (memq face ps-italic-faces)))
-       )
-                                       ; xemacs
-                                       ; lucid
-      (t                               ; epoch
-       (defun ps-face-bold-p (face)
-        (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold"
-                               ps-bold-faces))
-
-       (defun ps-face-italic-p (face)
-        (or (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o" ps-italic-faces)
-            (ps-xemacs-face-kind-p face 'SLANT "i\\|o" ps-italic-faces)))
-       ))
-
-
-(defun ps-face-underlined-p (face)
-  (or (face-underline-p face)
-      (memq face ps-underlined-faces)))
-
-
 ;; Ensure that face-list is fbound.
 (or (fboundp 'face-list) (defalias 'face-list 'list-faces))
 
@@ -5009,45 +5199,30 @@ If FACE is not a valid face name, it is used default face."
        (vector (logior (if (ps-face-bold-p face) 1 0) ; bold
                        (if (ps-face-italic-p face) 2 0) ; italic
                        (if (ps-face-underlined-p face) 4 0)) ; underline
-               (face-foreground face)
-               (face-background face))))
-
-
-(cond ((not (eq ps-print-emacs-type 'emacs))
-                                       ; xemacs
-                                       ; lucid
-                                       ; epoch
-       (defun ps-mapper (extent list)
-        (nconc list (list (list (extent-start-position extent) 'push extent)
-                          (list (extent-end-position extent) 'pull extent)))
-        nil)
-
-       (defun ps-extent-sorter (a b)
-        (< (extent-priority a) (extent-priority b)))
-       ))
+               (ps-face-foreground-name face)
+               (ps-face-background-name face))))
 
 
+;; to avoid compilation gripes
 (defun ps-print-ensure-fontified (start end)
-  (and (boundp 'lazy-lock-mode) (symbol-value 'lazy-lock-mode)
-       (lazy-lock-fontify-region start end)))
+  (cond
+   ((and (boundp 'jit-lock-mode) (symbol-value 'jit-lock-mode))
+    (defalias 'ps-jitify 'jit-lock-fontify-now) ; avoid compilation gripes
+    (ps-jitify start end))
+   ((and (boundp 'lazy-lock-mode) (symbol-value 'lazy-lock-mode))
+    (defalias 'ps-lazify 'lazy-lock-fontify-region) ; avoid compilation gripes
+    (ps-lazify start end))))
+
 
 (defun ps-generate-postscript-with-faces (from to)
   ;; Some initialization...
   (setq ps-current-effect 0)
 
   ;; Build the reference lists of faces if necessary.
-  (if (or ps-always-build-face-reference
-         ps-build-face-reference)
-      (progn
-       (message "Collecting face information...")
-       (ps-build-reference-face-lists)))
-  ;; Set the color scale.  We do it here instead of in the defvar so
-  ;; that ps-print can be dumped into emacs.  This expression can't be
-  ;; evaluated at dump-time because X isn't initialized.
-  (setq ps-color-p           (and ps-print-color-p (ps-color-device))
-       ps-print-color-scale (if ps-color-p
-                                (float (car (ps-color-values "white")))
-                              1.0))
+  (when (or ps-always-build-face-reference
+           ps-build-face-reference)
+    (message "Collecting face information...")
+    (ps-build-reference-face-lists))
   ;; Generate some PostScript.
   (save-restriction
     (narrow-to-region from to)
@@ -5055,12 +5230,11 @@ If FACE is not a valid face name, it is used default face."
     (let ((face 'default)
          (position to))
       (cond
-       ((or (eq ps-print-emacs-type 'lucid)
-           (eq ps-print-emacs-type 'xemacs))
+       ((memq ps-print-emacs-type '(xemacs lucid))
        ;; Build the list of extents...
        (let ((a (cons 'dummy nil))
              record type extent extent-list)
-         (map-extents 'ps-mapper nil from to a)
+         (ps-x-map-extents 'ps-mapper nil from to a)
          (setq a (sort (cdr a) 'car-less-than-car)
                extent-list nil)
 
@@ -5080,15 +5254,14 @@ If FACE is not a valid face name, it is used default face."
            ;; XEmacs 19.12: for some reason, we're getting into a
            ;; situation in which some of the records have
            ;; positions less than 'from'.  Since we've narrowed
-           ;; the buffer, this'll generate errors.  This is a
-           ;; hack, but don't call ps-plot-with-face unless from >
-           ;; point-min.
-           (and (>= from (point-min)) (<= position (point-max))
-                (ps-plot-with-face from position face))
+           ;; the buffer, this'll generate errors.  This is a hack,
+           ;; but don't call ps-plot-with-face unless from > point-min.
+           (and (>= from (point-min))
+                (ps-plot-with-face from (min position (point-max)) face))
 
            (cond
             ((eq type 'push)
-             (and (extent-face extent)
+             (and (ps-x-extent-face extent)
                   (setq extent-list (sort (cons extent extent-list)
                                           'ps-extent-sorter))))
 
@@ -5097,7 +5270,7 @@ If FACE is not a valid face name, it is used default face."
                                      'ps-extent-sorter))))
 
            (setq face (if extent-list
-                          (extent-face (car extent-list))
+                          (ps-x-extent-face (car extent-list))
                         'default)
                  from position
                  a (cdr a)))))
@@ -5189,21 +5362,21 @@ If FACE is not a valid face name, it is used default face."
                (goto-char (point-min))
                (or (looking-at (regexp-quote ps-adobe-tag))
                    (setq needs-begin-file t))
-               (save-excursion
-                 (set-buffer ps-source-buffer)
-                 (ps-begin-job)
-                 (when needs-begin-file
-                   (ps-begin-file)
-                   (ps-mule-initialize))
-                 (ps-mule-begin-job from to)
-                 (ps-begin-page))
+
                (set-buffer ps-source-buffer)
+               (save-excursion
+                 (let ((ps-print-page-p t)
+                       ps-even-or-odd-pages)
+                   (ps-begin-job)
+                   (when needs-begin-file
+                     (ps-begin-file)
+                     (ps-mule-initialize))
+                   (ps-mule-begin-job from to)
+                   (ps-selected-pages)))
+               (ps-begin-page)
                (funcall genfunc from to)
                (ps-end-page)
-
-               (ps-end-file)
-               (ps-flush-output)
-               (ps-end-job)
+               (ps-end-job needs-begin-file)
 
                ;; Setting this variable tells the unwind form that the
                ;; the PostScript was generated without error.
@@ -5221,18 +5394,43 @@ If FACE is not a valid face name, it is used default face."
        (and ps-razzle-dazzle (message "Formatting...done"))))))
 
 
-(defun ps-end-job ()
-  (let ((total-lines (cdr ps-printing-region))
-       (total-pages (if ps-print-only-one-header
-                        (ps-page-number)
-                      ps-page-count))
-       case-fold-search)
-    (set-buffer ps-spool-buffer)
-    ;; Back to the PS output buffer to set the page count
-    (goto-char (point-min))
-    (and (re-search-forward "^/Lines 0 def\n/PageCount 0 def$" nil t)
-        (replace-match (format "/Lines %d def\n/PageCount %d def"
-                               total-lines total-pages) t))))
+(defun ps-end-job (needs-begin-file)
+  (let ((ps-print-page-p t))
+    (ps-flush-output)
+    (save-excursion
+      (let ((pages-per-sheet (mod ps-page-n-up ps-n-up-printing))
+           (total-lines (cdr ps-printing-region))
+           (total-pages (ps-page-number))
+           case-fold-search)
+       (set-buffer ps-spool-buffer)
+       ;; Back to the PS output buffer to set the last page n-up printing
+       (goto-char (point-max))
+       (and (> pages-per-sheet 0)
+            (re-search-backward "^[0-9]+ BeginSheet$" nil t)
+            (replace-match (format "%d BeginSheet" pages-per-sheet) t))
+       ;; Back to the PS output buffer to set the page count
+       (goto-char (point-min))
+       (and (re-search-forward "^/Lines 0 def\n/PageCount 0 def$" nil t)
+            (replace-match (format "/Lines %d def\n/PageCount %d def"
+                                   total-lines total-pages) t))))
+    ;; Set dummy page
+    (and ps-spool-duplex (= (mod ps-page-order 2) 1)
+        (let ((ps-n-up-printing 0))
+          (ps-header-sheet)
+          (ps-output "/PrintHeader false def\n/ColumnIndex 0 def\n"
+                     "/PrintLineNumber false def\nBeginPage\n")
+          (ps-end-page)))
+    ;; Set end of PostScript file
+    (ps-output "EndSheet\n\n%%Trailer\n%%Pages: "
+              (number-to-string
+               (if (and needs-begin-file
+                        ps-banner-page-when-duplexing)
+                   (1+ ps-page-order)
+                 ps-page-order))
+              "\n\nEndDoc\n\n%%EOF\n")
+    (ps-flush-output))
+  ;; disable selected pages
+  (setq ps-selected-pages nil))
 
 
 ;; Permit dynamic evaluation at print time of `ps-lpr-switches'.
@@ -5257,9 +5455,13 @@ If FACE is not a valid face name, it is used default face."
                                    (and (boundp 'printer-name)
                                         printer-name)))
               (ps-lpr-switches
-               (append (and (stringp ps-printer-name)
-                            (list (concat "-P" ps-printer-name)))
-                       ps-lpr-switches)))
+               (append ps-lpr-switches
+                       (and (stringp ps-printer-name)
+                            (string< "" ps-printer-name)
+                            (list (concat
+                                   (and (stringp ps-printer-name-option)
+                                        ps-printer-name-option)
+                                   ps-printer-name))))))
          (apply (or ps-print-region-function 'call-process-region)
                 (point-min) (point-max) ps-lpr-command nil
                 (and (fboundp 'start-process) 0)
@@ -5363,7 +5565,7 @@ If FACE is not a valid face name, it is used default face."
   (save-excursion
     (goto-char (point-min))
     (if (re-search-forward "^Subject:[ \t]+\\(.*\\)$" nil t)
-       (buffer-substring-no-properties (match-beginning 1) (match-end 1))
+       (buffer-substring (match-beginning 1) (match-end 1))
       "Subject ???")))
 
 ;; Look in an article or mail message for the From: line.  Sorta-kinda
@@ -5373,8 +5575,7 @@ If FACE is not a valid face name, it is used default face."
   (save-excursion
     (goto-char (point-min))
     (if (re-search-forward "^From:[ \t]+\\(.*\\)$" nil t)
-       (let ((fromstring (buffer-substring-no-properties (match-beginning 1)
-                                                         (match-end 1))))
+       (let ((fromstring (buffer-substring (match-beginning 1) (match-end 1))))
          (cond
 
           ;; Try first to match addresses that look like
@@ -5383,9 +5584,10 @@ If FACE is not a valid face name, it is used default face."
            (substring fromstring (match-beginning 1) (match-end 1)))
 
           ;; Next try to match addresses that look like
-          ;; Jim Thompson <thompson@wg2.waii.com>
-          ((string-match "\\(.*\\)[ \t]+<.*>" fromstring)
-           (substring fromstring (match-beginning 1) (match-end 1)))
+          ;; Jim Thompson <thompson@wg2.waii.com> or
+          ;; "Jim Thompson" <thompson@wg2.waii.com>
+          ((string-match "\\(\"?\\)\\(.*\\)\\1[ \t]+<.*>" fromstring)
+           (substring fromstring (match-beginning 2) (match-end 2)))
 
           ;; Couldn't find a real name -- show the address instead.
           (t fromstring)))
@@ -5441,7 +5643,7 @@ If FACE is not a valid face name, it is used default face."
   (save-excursion
     (goto-char (point-min))
     (if (re-search-forward "File:[ \t]+\\([^, \t\n]*\\)" nil t)
-       (buffer-substring-no-properties (match-beginning 1) (match-end 1))
+       (buffer-substring (match-beginning 1) (match-end 1))
       "File ???")))
 
 ;; Look in an article or mail message for the Subject: line.  To be
@@ -5450,7 +5652,7 @@ If FACE is not a valid face name, it is used default face."
   (save-excursion
     (goto-char (point-min))
     (if (re-search-forward "Node:[ \t]+\\([^,\t\n]*\\)" nil t)
-       (buffer-substring-no-properties (match-beginning 1) (match-end 1))
+       (buffer-substring (match-beginning 1) (match-end 1))
       "Node ???")))
 
 (defun ps-info-mode-hook ()