;; w32-ps-print.el
;; PostScript printing with ghostscript
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Hacked up by Pat Thoyts <patthoyts@users.sourceforge.net> to generalise to
;; w32-ps-print-(buffer)|(region)(-with(out)?-faces)?
;;
;; Tested using 'GNU Emacs 20.3.1 (i386-*-nt4.0) of Wed Aug 26 1998 on ESME'
;;
;; N.B.: (require)ing this file setq's ps-lpr-command and other settings.
;;       If you need to set your own, you should do so AFTER including this
;;       file. (until I fix this that is.).
;;
;;
;; USAGE:
;;   the following code in your .emacs will load the package and set up
;;   some menu items in Tools->Print that will print to file and then
;;   open the file with ghostview.
;;
;;      (progn
;;        (condition-case () (require 'w32-ps-print) (error nil))
;;        (setq printer-name "//PRINTSERVER/printer"
;;              ps-lpr-command "c:\\opt\\gstools\\gsview\\gsview32.exe"
;;              ps-paper-type 'a4
;;              ps-print-color-p 't
;;              ps-lpr-switches nil
;;              w32-ps-command-postfix ""
;;              ps-printer-name nil))
;;
;;
;;;; Original Header: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Hi!
;;
;; I thought I'd send you my solution to printing from emacs under win95
;; using GhostScript (since I don't have a Postscript ptinter - just
;; a DeskJet540). It is based on the one from Pascal and has been tested
;; with gs4.01 (http://www.cs.wisc.edu/~ghost/aladdin/) for Win32 and
;; NTEmacs 19-34-1:
;;
;; ##################################################  win95 - PS-Print
;; A note on the gs options:
;; -q                            quiet
;; -sDEVICE=djet500              the printer - works with HP DeskJet 540
;; -r300                         resolution 300x300
;; -dNOPAUSE                     don't wait for user intervention
;; -IE:\\GSTOOLS\\gs4.01;E:\\GSTOOLS\\gs4.01\\fonts
;;                               the directories needed for gs
;; -c quit                 this is added at the end to terminate gs

(require 'ps-print)

(defun w32-ps-set-landscape ()
  (interactive)
  (setq ps-landscape-mode          't
        ps-number-of-columns       2
        ps-font-size               5.5
        ps-header-font-size        6
        ps-header-title-font-size  8)
  (message "w32-ps-set-landscape"))

(defun w32-ps-set-portrait ()
  (interactive)
  (setq ps-landscape-mode          'nil
        ps-number-of-columns       1
        ps-font-size               8
        ps-header-font-size        8
        ps-header-title-font-size  10)
  (message "w32-ps-set-portrait"))

(defun w32-ps-determine-mode ()
  "Try and decide if the current buffer is text or a source code buffer
by looking at the major mode.
Return either 'text or 'code, so you can then call one of 
`w32-ps-set-text-mode' or `w32-ps-set-code-mode'."
  (let ((mode (symbol-name major-mode)))
    (cond
     ((string-match "[Tt]e[Xx]" mode) 'text)
     ((string-match "fundamental" mode) 'text)
     (t 'code))))
      
(defun w32-ps-set-text-mode ()
  (interactive)
  (setq ps-line-number   'nil
        ps-zebra-stripes 'nil)
  (message "w32-ps-set-text-mode"))

(defun w32-ps-set-code-mode ()
  (interactive)
  (setq ps-line-number   't
        ps-zebra-stripes 't)
  (message "w32-ps-set-code-mode"))

(defvar w32-ps-command-postfix "-c quit"
  "* Specify a string containing any additional argument to `ps-lpr-command'
that might be needed. For example, gswin32 and gswin32c require \"-c quit\"
to get them to exit once completed. GSView32 does not need anything.")

;;;###autoload
(defun w32-ps-print-buffer (&optional filename)
"Generate and print a Postscript image of the buffer.

When called with a numeric prefix argument (C-u), prompts the user for
the name of a file to save the PostScript image in, instead of sending
it to the printer.

More specifically, the FILENAME argument is treated as follows: if it
is nil, send the image to the printer.  If FILENAME is a string, save
the PostScript image in a file with that name.  If FILENAME is a
number, prompt the user for the name of the file to save in."
  (interactive (list (ps-print-preprint current-prefix-arg)))
  (if (not filename) (setq filename ps-lpr-buffer))
  (w32-ps-print-without-faces (point-min) (point-max) filename))

;;;###autoload
(defun w32-ps-print-buffer-with-faces (&optional filename)
  "Generate and print a PostScript image of the buffer.
Like `w32-ps-print-buffer', but includes font, color, and underline
information in the generated image.  This command works only if you
are using a window system, so it has a way to determine color values."
  (interactive (list (ps-print-preprint current-prefix-arg)))
  (if (not filename) (setq filename ps-lpr-buffer))
  (w32-ps-print-with-faces (point-min) (point-max) filename))

;;;###autoload
(defun w32-ps-print-region (from to &optional filename)
  "Generate and print a PostScript image of the region.
Like `w32-ps-print-buffer', but prints just the current region."
  (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
  (if (not filename) (setq filename ps-lpr-buffer))
  (w32-ps-print-without-faces from to filename t))

;;;###autoload
(defun w32-ps-print-region-with-faces (from to &optional filename)
  "Generate and print a PostScript image of the region.
Like `w32-ps-print-region', but includes font, color, and underline
information in the generated image.  This command works only if you
are using a window system, so it has a way to determine color values."
  (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
  (if (not filename) (setq filename ps-lpr-buffer))
  (w32-ps-print-with-faces from to filename t))

;; internal wrapper functions.
(defun w32-ps-print-without-faces (from to &optional filename region-p)
  (if (equal 'code (w32-ps-determine-mode))
      (w32-ps-set-code-mode)
    (w32-ps-set-text-mode))
  (ps-spool-without-faces from to region-p)
  (ps-do-despool filename)
  (if (string-equal filename ps-lpr-buffer)
      (shell-command
       (apply 'concat (append (list ps-lpr-command " ")
			      ps-lpr-switches
			      (list " " ps-lpr-buffer " "
				    w32-ps-command-postfix))))))

(defun w32-ps-print-with-faces (from to &optional filename region-p)
  (if (equal 'code (w32-ps-determine-mode))
      (w32-ps-set-code-mode)
    (w32-ps-set-text-mode))
  (ps-spool-with-faces from to region-p)
  (ps-do-despool filename)
  (if (string-equal filename ps-lpr-buffer)
      (shell-command
       (apply 'concat (append (list ps-lpr-command " ")
			      ps-lpr-switches
			      (list " " ps-lpr-buffer " "
				    w32-ps-command-postfix))))))

(defun w32-ps-init ()
  "LOCAL: Initialize variables for printing with faces, colors, etc.
Also defines a printing menu item for access to our functionality."
  (setq ps-lpr-command    "c:\\opt\\gstools\\gs5.50\\gswin32.exe"
        ps-lpr-switches   '("-sDEVICE=mswinpr2 -q -dBATCH -dNOPAUSE")
	ps-printer-name   'nil
        ps-paper-type     'a4
        ps-lpr-buffer     (concat (cond
				   ((getenv "TMP") (getenv "TMP"))
				   ((getenv "TEMP") (getenv "TEMP"))
				   (t "C:"))
				  "\\ps-spool.ps")
        ps-print-color-p  'nil
;        ps-left-margin   (/ (* 72  1.1) 2.54) ;  1.0 cm
;        ps-right-margin  (/ (* 72  0.5) 2.54) ;  1.0 cm
;        ps-inter-column  (/ (* 72  1.0) 2.54) ;  1.0 cm
;        ps-bottom-margin (/ (* 72  1.0) 2.54) ;  1.0 cm
;        ps-top-margin    (/ (* 72  0.5) 2.54) ;  1.0 cm
;        ps-header-offset (/ (* 72  0.1) 2.54) ;  0.1 cm
;        ps-header-line-pad    .15

        ps-print-header       t
        ps-print-header-frame t
        ps-header-lines       3
        ps-show-n-of-n        t
        ps-spool-duplex       nil       ; only "works" if queue is set to 
					; duplex by default

        ps-font-family             'Courier
        ps-header-font-family      'Helvetica )

  (cond
   ((equal ps-print-emacs-type 'xemacs)
    (add-submenu nil '("Printing"
		       ["Print Postscript Buffer" w32-ps-print-buffer t]
		       ["Spool Postscript Buffer" ps-spool-buffer-with-faces t]
		       ("Options"
			["Portrait"  w32-ps-set-portrait  t]
			["Landscape" w32-ps-set-landscape t]
			"-"
			["Text"      w32-ps-set-text-mode t]
			["Code"      w32-ps-set-code-mode t]
			"-"
			["Show"      w32-ps-setup         t] )) "Apps" ))
   ((equal ps-print-emacs-type 'emacs)
    ;; Change the default menu bar to use our functions.
    (define-key menu-bar-print-menu [ps-print-region]
      '("Ghostscript Print Region" . w32-ps-print-region))
    (define-key menu-bar-print-menu [ps-print-buffer]
      '("Ghostscript Print Buffer" . w32-ps-print-buffer))
    ;; How to insert a new menu item?
    (define-key-after menu-bar-print-menu [w32-ps-print-buffer]
      '("Pretty Print Buffer" . w32-ps-print-buffer-with-faces) t)
    (define-key-after menu-bar-print-menu [w32-ps-print-region]
      '("Pretty Print Region" . w32-ps-print-region-with-faces) t) ))

  (message "End of w32-ps-init")
  'w32-ps-init)

(defun w32-ps-setup ()
  "LOCAL: ps-setup() in a dialog box"
  (interactive)
  (defvar msg "")
  (setq msg "")
  (setq msg (concat msg (ps-setup)))
  'w32-ps-setup )

(w32-ps-init)
(provide 'w32-ps-print)

;; end of w32-ps-print.el
