ron@mlfarm.UUCP (Ronald Florence) (10/24/89)
Some time ago I posted a query about how to do troff formatting and
printing as a background (asynchronous) process under GNU Emacs. I
received some useful suggestions by email, then put together the
attached code (format.el) which provides:
troff-buffer (troff to a printer)
troff-region
nroff-buffer (nroff to a printer)
nroff-region
proof-buffer (nroff proof to an Emacs window)
tproof-buffer (troff ascii proof to an Emacs window)
pr-buffer (pr to a printer)
pr-region
The printer and proof processes all run in the background, and can be
interrupted with kill-print or kill-proof. To use the package,
customize roff-macro, troff-options, nroff-options, and the format
strings to fit your local requirements. If you do much work with troff
or nroff, you may want to load format.el in a new version of Emacs.
Zap-nroff-crap uses a local kluge to invoke expanded print for lines
beginning with ^G.
I welcome suggestions for changes or improvements.
_________________________________
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# format.el
# This archive created: Tue Oct 24 10:41:38 1989
# By: Ronald Florence (Maple Lawn Farm, Stonington, CT)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'format.el'" '(7181 characters)'
if test -f 'format.el'
then
echo shar: "will not over-write existing file 'format.el'"
else
sed 's/^X//' << \SHAR_EOF > 'format.el'
X;; format.el
X;; Copyright 1989 Ronald Florence (ron@mlfarm)
X
X(defvar roff-macro "-mm"
X"*Default macro package to use with troff and nroff.")
X
X(defvar troff-options "-rN2"
X"*Default options to use with troff.")
X
X(defvar nroff-options "-rN2 -rO9"
X"*Default options to use with nroff.")
X
X(setq troff-format-string "\(troff -t %s %s %s 2>&1 \) | lp -ot -n%d")
X(setq nroff-format-string "nroff -Thp %s %s %s | lp -n%d")
X(setq pr-format-string "pr -h %s %s | lp -n%d")
X
X(if (not nroff-mode-map)
X (error "Nroff-mode is not loaded.")
X (progn
X (define-key nroff-mode-map "\C-c\C-n" 'proof-buffer)
X (define-key nroff-mode-map "\C-c\C-t" 'tproof-buffer)
X (define-key nroff-mode-map "\C-c\C-k" 'kill-proof)
X (define-key nroff-mode-map "\C-c\C-i" 'kill-print)))
X
X(setq proof-tmp-file nil
X print-tmp-file nil
X proof-process nil
X print-process nil
X proof-file nil)
X
X(defun nroff-buffer (&optional copies)
X "Print buffer contents after formatting with nroff.
XOptional prefix argument specifies number of copies."
X (interactive "p")
X (format-to-printer-region (point-min) (point-max) "nroff" copies))
X
X(defun nroff-region (start end &optional copies)
X "Print region contents after formatting with nroff.
XOptional prefix argument specifies number of copies."
X (interactive "r\np")
X (format-to-printer-region start end "nroff" copies))
X
X(defun troff-buffer (&optional copies)
X "Typeset buffer after formatting with troff.
XOptional prefix argument specifies number of copies."
X (interactive "p")
X (format-to-printer-region (point-min) (point-max) "troff" copies))
X
X(defun troff-region (start end &optional copies)
X "Typeset region contents after formatting with troff.
XOptional prefix argument specifies number of copies."
X (interactive "r\np")
X (format-to-printer-region start end "troff" copies))
X
X(defun pr-buffer (&optional copies)
X "Print buffer contents after formatting with pr.
XOptional prefix argument specifies number of copies."
X (interactive "p")
X (format-to-printer-region (point-min) (point-max) "pr" copies))
X
X(defun pr-region (start end &optional copies)
X "Print region contents after formatting with pr.
XOptional prefix argument specifies number of copies."
X (interactive "r\np")
X (format-to-printer-region start end "pr" copies))
X
X(defun proof-region (start end)
X "Proof region using nroff."
X (interactive "r")
X (proof-region-to-buffer start end "nroff"))
X
X(defun proof-buffer ()
X "Proof buffer using nroff."
X (interactive)
X (proof-region-to-buffer (point-min) (point-max) "nroff"))
X
X(defun tproof-region (start end)
X "Rough proof region using troff."
X (interactive "r")
X (proof-region-to-buffer start end "troff"))
X
X(defun tproof-buffer ()
X "Rough proof buffer using troff."
X (interactive)
X (proof-region-to-buffer (point-min) (point-max) "troff"))
X
X(defun kill-print ()
X "Kill format-to-printer process."
X (interactive)
X (if print-process
X (interrupt-process print-process)))
X
X(defun kill-proof ()
X "Kill proof process."
X (interactive)
X (if proof-process
X (interrupt-process proof-process)))
X
X(defun format-to-printer-region (start end formatter &optional copies)
X (if print-process
X (if (or
X (not (eq (process-status print-process) 'run))
X (yes-or-no-p "A format-to-printer process is running; kill it? "))
X (condition-case ()
X (let ((print-proc print-process))
X (interrupt-process print-proc)
X (sit-for 1)
X (delete-process print-proc))
X (error nil))
X (error "One format-to-printer process at a time.")))
X (save-excursion
X (setq printer-output-buffer " *printer output*")
X (get-buffer-create printer-output-buffer)
X (set-buffer printer-output-buffer)
X (erase-buffer))
X (if (null copies) (setq copies 1))
X (setq print-tmp-file (concat "/tmp/" (make-temp-name "#pr#")))
X (write-region start end print-tmp-file nil 'nomsg)
X (setq print-command
X (cond ((string= formatter "troff")
X (format troff-format-string
X troff-options roff-macro
X print-tmp-file copies))
X ((string= formatter "nroff")
X (format nroff-format-string
X nroff-options roff-macro
X print-tmp-file copies))
X ((string= formatter "pr")
X (format pr-format-string
X (buffer-name) print-tmp-file copies))))
X (setq print-process
X (start-process formatter printer-output-buffer "sh" "-c"
X print-command))
X (set-process-sentinel print-process 'print-sentinel))
X
X(defun print-sentinel (process msg)
X (delete-file print-tmp-file)
X (save-excursion
X (set-buffer (process-buffer process))
X (if (> (buffer-size) 0)
X (progn
X (goto-char (point-min))
X (end-of-line)
X (message "%s: %s" (process-name process)
X (buffer-substring 1 (point))))
X (message "%s: killed" (process-name process))))
X (setq print-process nil)
X (kill-buffer (process-buffer process)))
X
X(defun proof-region-to-buffer (start end formatter)
X (if proof-process
X (if (or (not (eq (process-status proof-process) 'run))
X (yes-or-no-p "A proof process is running; kill it? "))
X (condition-case ()
X (let ((proof-proc proof-process))
X (interrupt-process proof-proc)
X (sit-for 1)
X (delete-process proof-proc))
X (error nil))
X (error "One proof process at a time.")))
X (setq proof-tmp-file (concat "/tmp/" (make-temp-name "#p#")))
X (save-excursion
X (setq proof-file (buffer-name))
X (setq proof-buffer "*proof*")
X (get-buffer-create proof-buffer)
X (set-buffer proof-buffer)
X (erase-buffer))
X (write-region start end proof-tmp-file nil 'nomsg)
X (setq proof-command
X (if (string= formatter "troff")
X (format "troff -a %s %s %s" troff-options
X roff-macro proof-tmp-file)
X (format "nroff %s %s %s" nroff-options roff-macro proof-tmp-file)))
X (setq proof-process
X (start-process formatter proof-buffer "sh" "-c" proof-command))
X (set-process-sentinel proof-process 'proof-sentinel))
X
X(defun proof-sentinel (process msg)
X (delete-file proof-tmp-file)
X (if (string-match "^exited" msg)
X (message "%s: killed" (process-name process))
X (progn
X (set-buffer (process-buffer process))
X (text-mode)
X (setq mode-name (format "%s:%s"
X (process-name proof-process) proof-file))
X (if (string= (process-name process) "nroff")
X (zap-nroff-crap))
X (goto-char (point-min))
X (display-buffer (process-buffer process))))
X (setq proof-process nil))
X
X(defun zap-nroff-crap ()
X (goto-char (point-min))
X (while (search-forward "\b" nil t)
X (let* ((preceding (char-after (- (point) 2)))
X (following (following-char)))
X ;; x\bx
X (cond ((= preceding following)
X (delete-char -2))
X ;; _\b
X ((= preceding ?\_)
X (delete-char -2))
X ;; \b_
X ((= following ?\_)
X (delete-region (1- (point)) (1+ (point)))))))
X ;; expand ^G lines
X (goto-char (point-min))
X (while (search-forward "\C-g" nil t)
X (delete-char -2)
X (while (not (eolp))
X (insert " ")
X (forward-char 1)))
X ;; zap Esc-8 & Esc-9 vertical motions
X (goto-char (point-min))
X (while (search-forward "\e" nil t)
X (if (or (= (following-char) ?8) (= (following-char) ?9))
X (delete-region (1+ (point)) (1- (point))))))
X
X
X
X
SHAR_EOF
if test 7181 -ne "`wc -c < 'format.el'`"
then
echo shar: "error transmitting 'format.el'" '(should have been 7181 characters)'
fi
fi
exit 0
# End of shell archive
__
Ronald Florence ...{hsi,rayssd}!mlfarm!ron