(diary-face, holiday-face): Add dark-background variants.
[bpt/emacs.git] / lisp / ps-print.el
index 239fb82..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/07/03 20:16:48 vinicius>
-;; Version:    5.0
+;; 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"
-  "ps-print.el, v 5.0 <99/07/03 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>.
@@ -48,11 +48,10 @@ Please send all bug fixes and enhancements to
 ;; About ps-print
 ;; --------------
 ;;
-;; This package provides printing of Emacs buffers on PostScript
-;; printers; the buffer's bold and italic text attributes are
-;; preserved in the printer output.  ps-print is intended for use with
-;; Emacs 19 or Lucid Emacs, together with a fontifying package such as
-;; font-lock or hilit.
+;; This package provides printing of Emacs buffers on PostScript printers;
+;; the buffer's bold and italic text attributes are preserved in the printer
+;; output.  ps-print is intended for use with Emacs or Lucid Emacs, together
+;; with a fontifying package such as font-lock or hilit.
 ;;
 ;; ps-print uses the same face attributes defined through font-lock or hilit
 ;; to print a PostScript file, but some faces are better seeing on the screen
@@ -184,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
 ;; ---------------
@@ -205,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
@@ -299,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).
@@ -307,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.
@@ -395,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
 ;; ---------------
@@ -529,8 +648,6 @@ Please send all bug fixes and enhancements to
 ;;
 ;; See ps-mule.el for documentation.
 ;;
-;; See ps-print-def.el for definition.
-;;
 ;;
 ;; Line Number
 ;; -----------
@@ -538,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
 ;; -------------
@@ -565,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.
 ;;
@@ -641,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:
 ;;
@@ -723,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
@@ -762,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
 ;; -----------------------------
@@ -770,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.
 ;;
 ;;
@@ -843,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
@@ -875,6 +1088,9 @@ Please send all bug fixes and enhancements to
 ;; NOTE: line folding is not taken into account in this process and could
 ;;       change the results.
 ;;
+;; The command `ps-print-customize' activates a customization buffer for
+;; ps-print options.
+;;
 ;;
 ;; New since version 1.5
 ;; ---------------------
@@ -890,56 +1106,72 @@ Please send all bug fixes and enhancements to
 ;; New since version 2.8
 ;; ---------------------
 ;;
-;; [vinicius] 990703 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; [vinicius] Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;;
-;; Better customization.
-;; `ps-banner-page-when-duplexing' and `ps-zebra-gray'.
+;;    20000821
+;;      `ps-even-or-odd-pages'
 ;;
-;; [vinicius] 990513 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'.
 ;;
-;; N-up printing.
-;; Hook: `ps-print-begin-sheet-hook'.
+;;    20000310
+;;      PostScript error handler.
+;;      `ps-user-defined-prologue' and `ps-error-handler-message'.
 ;;
-;; [keinichi] 990509 Kein'ichi Handa <handa@etl.go.jp>
+;;    19991211
+;;      `ps-print-customize'.
 ;;
-;; `ps-print-region-function'
+;;    19990703
+;;      Better customization.
+;;      `ps-banner-page-when-duplexing' and `ps-zebra-color'.
 ;;
-;; [vinicius] 990301 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;;    19990513
+;;      N-up printing.
+;;      Hook: `ps-print-begin-sheet-hook'.
 ;;
-;; PostScript tumble and setpagedevice.
+;; [keinichi] 19990509 Kein'ichi Handa <handa@etl.go.jp>
 ;;
-;; [vinicius] 980922 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; `ps-print-region-function'
 ;;
-;; PostScript prologue header comment insertion.
-;; Skip invisible text better.
+;; [vinicius] Vinicius Jose Latorre <vinicius@cpqd.com.br>
 ;;
-;; [keinichi] 980819 Kein'ichi Handa <handa@etl.go.jp>
+;;    19990301
+;;      PostScript tumble and setpagedevice.
 ;;
-;; Multi-byte buffer handling.
+;;    19980922
+;;      PostScript prologue header comment insertion.
+;;      Skip invisible text better.
 ;;
-;; [vinicius] 980306 Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; [keinichi] 19980819 Kein'ichi Handa <handa@etl.go.jp>
 ;;
-;; Skip invisible text.
+;; Multi-byte buffer handling.
 ;;
-;; [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.
@@ -972,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.
 ;;
@@ -993,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
@@ -1053,24 +1301,77 @@ Please send all bug fixes and enhancements to
 
 ;;; Code:
 
-(unless (featurep 'lisp-float-type)
-  (error "`ps-print' requires floating point support"))
-
-;; For Emacs 20.2 and the earlier version.
 (eval-and-compile
-  (and (boundp 'mule-version)          ; only if mule package is loaded
-       (string< mule-version "4.0")
-       (progn
-        (defun set-buffer-multibyte (arg)
-          (setq enable-multibyte-characters arg))
-        (defun string-as-unibyte (arg) arg)
-        (defun string-as-multibyte (arg) arg)
-        (defun charset-after (&optional arg)
-          (char-charset (char-after arg))))))
+  (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)))
+
+  (or (fboundp 'string-as-unibyte)
+      (defun string-as-unibyte (arg) arg))
+
+  (or (fboundp 'string-as-multibyte)
+      (defun string-as-multibyte (arg) arg))
+
+  (or (fboundp 'char-charset)
+      (defun char-charset (arg) 'ascii))
+
+  (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))))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; User Variables:
 
+
 ;;; Interface to the command system
 
 (defgroup postscript nil
@@ -1079,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)
@@ -1096,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"
@@ -1151,9 +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.
 
-(require 'ps-vars)                     ; Common definitions
+   `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.
@@ -1179,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
@@ -1231,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.
@@ -1286,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,
@@ -1316,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."
@@ -1369,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)
@@ -1379,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.
@@ -1435,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
@@ -1483,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
@@ -1564,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.
@@ -1572,27 +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 '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:
@@ -1618,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.
@@ -1630,9 +2234,11 @@ For a duplex printer, the `ps-spool-*' and `ps-print-*' commands will insert
 blank pages as needed between print jobs so that the next buffer printed will
 start on the right page.  Also, if headers are turned on, the headers will be
 reversed on duplex printers so that the page numbers fall to the left on
-even-numbered pages."
+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.
@@ -1642,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
 
@@ -1757,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"
@@ -1824,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
@@ -1833,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
@@ -1882,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.
@@ -1900,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)
@@ -1911,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.
@@ -1954,11 +2597,47 @@ 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))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Customization
+
+
+;;;###autoload
+(defun ps-print-customize ()
+  "Customization of ps-print group."
+  (interactive)
+  (customize-group 'ps-print))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; User commands
 
+
 ;;;###autoload
 (defun ps-print-buffer (&optional filename)
   "Generate and print a PostScript image of the buffer.
@@ -2087,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
 
@@ -2108,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
@@ -2120,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
@@ -2127,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
@@ -2165,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)
@@ -2175,16 +2891,21 @@ The table depends on the current ps-print setup."
    ps-n-up-margin
    ps-n-up-border-p
    (ps-print-quote ps-n-up-filling)
-   (ps-print-quote ps-multibyte-buffer)        ; see `ps-mule.el' and `ps-print-def.el'
+   (ps-print-quote ps-multibyte-buffer)        ; see `ps-mule.el'
    (ps-print-quote ps-font-family)
    (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)))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Utility functions and variables:
 
+
 (defun ps-print-quote (sym)
   (cond ((null sym)
         nil)
@@ -2195,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:
 
@@ -2990,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)
@@ -3000,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)
@@ -3040,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)
@@ -3176,10 +3273,11 @@ If EXTENSION is any other symbol, it is ignored."
 ;; However, we try and be back-compatible and respect its value if set except
 ;; for faces where M-x customize has been used to save changes for the face.
 
+
 (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
@@ -3214,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)
@@ -3227,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))
 
 
@@ -3238,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))
 
 
@@ -3262,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)))))
 
@@ -3274,6 +3372,7 @@ file.")
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Internal functions
 
+
 (defsubst ps-font-alist (font-sym)
   (get font-sym 'fonts))
 
@@ -3324,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)
@@ -3347,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)))
@@ -3362,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))
@@ -3390,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)))
@@ -3516,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)
@@ -3589,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))
@@ -3630,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))
@@ -3677,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)
@@ -3738,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"
@@ -3748,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)))
@@ -3760,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))
 
 
@@ -3806,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.
@@ -3887,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)
@@ -3929,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)
@@ -4024,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)
@@ -4261,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
@@ -4274,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
@@ -4297,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)
@@ -4335,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)
@@ -4346,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))
@@ -4362,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))
@@ -4383,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)))))
@@ -4420,20 +4597,60 @@ 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
        (if (string-equal (buffer-name) (file-name-nondirectory fname))
-           (file-name-directory fname)
+           (abbreviate-file-name (file-name-directory fname))
          fname)
       "")))
 
@@ -4467,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)
@@ -4485,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 ()
@@ -4517,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)
@@ -4556,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)
@@ -4574,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)))
@@ -4663,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))
@@ -4704,7 +4958,16 @@ 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)))
+                (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))
+                   (progn
+                     (setq match-point (car composition)
+                           match 0)
+                     (goto-char (nth 1 composition)))
+                 (setq composition nil)))
            (when (< from match-point)
              (ps-mule-set-ascii-font)
              (ps-plot 'ps-basic-plot-string from match-point bg-color))
@@ -4725,14 +4988,19 @@ 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))
+
             ((> match 255)             ; a multi-byte character
-             (let ((charset (char-charset match)))
+             (let* ((charset (char-charset match))
+                    (composition (ps-e-find-composition match-point to))
+                    (stop (if (nth 2 composition) (car composition) to)))
                (or (eq charset 'composition)
-                   (while (eq (charset-after) charset)
+                   (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
@@ -4777,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.
@@ -4817,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))
@@ -4855,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
@@ -4872,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))
 
@@ -4965,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)
@@ -5011,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)
 
@@ -5036,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))))
 
@@ -5053,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)))))
@@ -5145,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.
@@ -5177,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'.
@@ -5213,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)
@@ -5271,6 +5517,7 @@ If FACE is not a valid face name, it is used default face."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Sample Setup Code:
 
+
 ;; This stuff is for anybody that's brave enough to look this far,
 ;; and able to figure out how to use it.  It isn't really part of
 ;; ps-print, but I'll leave it here in hopes it might be useful:
@@ -5318,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
@@ -5328,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
@@ -5338,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)))
@@ -5396,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
@@ -5405,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 ()