;;; ps-mode.el --- PostScript mode for GNU Emacs. ;; Author: Peter Kleiweg ;; Created: 20 Aug 1997 ;; Version: ps-mode.el, v1.0d 1998/12/19 ;; Keywords: PostScript, languages ;; LCD Archive Entry: ;; ps-mode|Peter Kleiweg|p.c.j.kleiweg@rug.nl| ;; PostScript mode for GNU Emacs| ;; 1998/12/19|1.0d|~/modes/ps-mode.el.Z| ;;; Commentary: ;; A major mode for editing PostScript ;; Requires: easymenu, hilit19 ;;; Code: (if window-system (require 'hilit19)) (require 'easymenu) ;; user options (defvar ps-tab 4 "User option: number of spaces to use when indenting.") (defvar ps-auto-indent t "User option: t means use autoindent.") (defvar ps-paper-size '(595 842) "User option: default paper size. When inserting an EPSF template the values of ps-paper-size are used to set the boundingbox to include the whole page. When the figure is finished these values should be replaced. Some often used papersizes are listed below. a4: 595 842 legal: 612 1008 letter: 612 792 note: 540 720 ") (defvar ps-run-tmp-dir nil "User option: name of directory to place temporary file. If nil, the following are tried in turn, until success: 1. \"$TEMP\" 2. \"$TMP\" 3. \"$HOME/tmp\" 4. \"/tmp\" ") (defvar ps-run-prompt "\\(GS\\(<[0-9]+\\)?>\\)+" "User option: regexp to match prompt in interactive PostScript.") (defvar ps-run-x '("gs" "-r72" "-sPAPERSIZE=a4") "User option: command as list to run PostScript with graphic display.") (defvar ps-run-dumb '("gs" "-dNODISPLAY") "User option: command as list to run PostScript without graphic display.") (defvar ps-run-init nil "User option: string of commands to send to PostScript to start interactive. Example: \"executive\\n\" You won't need this option for Ghostscript. ") (defvar ps-run-error-line-numbers nil "User option: t means: error messages contain line numbers. nil means: error messages contain byte counts.") (defvar ps-print-function 'lpr-buffer "User option: name of Lisp function to print current buffer as PostScript. This function will be used to print regions as well. Example: (setq ps-print-function '(lambda () (let ( (lpr-switches nil) (lpr-command \"lpr\")) (lpr-buffer)))) ") ;; (defvar ps-mode-map nil "Local keymap to use in ps-mode.") (defvar ps-mode-syntax-table nil "Syntax table used while in ps-mode.") (defvar ps-run-mode-map nil "Local keymap to use in ps-run-mode.") (defvar ps-tmp-file nil "Name of temporary file, set by ps-run.") (defvar ps-run-mark nil "Mark to start of region sent to PostScript.") (defvar ps-run-parent nil "Parent window of interactive PostScript.") ;; ;;;###autoload (defun ps-mode () "Major mode for editing PostScript with GNU Emacs. Entry to this mode calls `ps-mode-hook'. Things to add to your .emacs file: (autoload 'ps-mode \"ps-mode\" \"Major mode for editing PostScript\" t) (setq auto-mode-alist (append '((\"\\\\.ps$\" . ps-mode) (\"\\\\.eps$\" . ps-mode) (\"\\\\.epsf$\" . ps-mode)) auto-mode-alist)) The following variables hold user options, and could be given other values from within your .emacs file: ps-auto-indent ps-tab ps-paper-size ps-run-tmp-dir ps-run-prompt ps-run-x ps-run-dumb ps-run-init ps-run-error-line-numbers ps-print-function Type \\[describe-variable] for documentation on these options. \\{ps-mode-map} When starting an interactive PostScript process with \\[ps-run-start], a second window will be displayed, and `ps-run-mode-hook' will be called. The keymap for this second window is: \\{ps-run-mode-map} When Ghostscript encounters an error it displays an error message with a file position. Clicking mouse-2 on this number will bring point to the corresponding spot in the PostScript window, if input to the interpreter was sent from that window. Typing \\\\[ps-run-goto-error] when the cursor is at the number has the same effect. " (interactive) (setq major-mode 'ps-mode mode-name "PostScript") (use-local-map ps-mode-map) (set-syntax-table ps-mode-syntax-table) (run-hooks 'ps-mode-hook)) ;; key-handlers (defun ps-newline () "Insert newline, indent if after begin group." (interactive) (if (not ps-auto-indent) (insert "\n") (progn (let ( (here (point)) pos ) (if (re-search-backward "\\({\\|\\[\\|<<\\)\\=" (- here 2) t) (progn (beginning-of-line) (looking-at "[ \t]*") (goto-char (match-end 0)) (setq pos (current-column)) (goto-char here) (insert "\n" (make-string (/ (+ pos ps-tab) tab-width) ?\t) (make-string (mod (+ pos ps-tab) tab-width) ?\ ))) (progn (goto-char here) (insert "\n") ; copy leading whitespace from previous line (setq here (point)) (forward-line -1) (looking-at "[ \t]*") (forward-line 1) (insert (buffer-substring (match-beginning 0) (match-end 0)))))) ; remove trailing whitespace previous line (save-excursion (forward-line -1) (beginning-of-line) (if (looking-at "[ \t]*$") (replace-match "") (if (looking-at "\\(.*[^ \t\n]\\)[ \t]+$") (replace-match "\\1")))) (if (looking-at "[ \t]+") (replace-match ""))))) (defun ps-r-brace () "INSERT `}' and perform balance." (interactive) (insert "}") (ps-r-balance "{" "}")) (defun ps-r-angle () "Insert `]' and perform balance." (interactive) (insert "]") (ps-r-balance "[" "]")) (defun ps-r-gt () "Insert `>' and perform balance." (interactive) (insert ">") (ps-r-balance "<<" ">>")) (defun ps-r-balance (left right) "Put RIGHT below start of line matching LEFT if only leading whitespace." (if ps-auto-indent (save-excursion (let ( (here (point)) (len (length right)) begin end ) (setq end (- here len)) (beginning-of-line) (if (looking-at (concat "[ \t]*" (regexp-quote right))) (if (= (match-end 0) here) (progn (goto-char here) (backward-sexp 1) (setq begin (point)) (if (looking-at (regexp-quote left)) (progn (beginning-of-line) (looking-at "[ \t]*") (goto-char end) (beginning-of-line) (insert (buffer-substring (match-beginning 0) (match-end 0))) (looking-at "[ \t]*") (replace-match ""))))))))) (blink-matching-open)) (defun ps-other-newline () "Perform newline in *ps run* buffer" (interactive) (let ((buf (current-buffer))) (set-buffer "*ps run*") (ps-run-newline) (set-buffer buf))) ;; print PostScript (defun ps-print-buffer () "Print buffer as PostScript" (interactive) (eval (list ps-print-function))) (defun ps-print-region (begin end) "Print region as PostScript, %!PS prepended, showpage appended" (interactive "r") (let ((oldbuf (current-buffer)) (tmpbuf (get-buffer-create "*ps print*"))) (copy-to-buffer tmpbuf begin end) (set-buffer tmpbuf) (goto-char 1) (insert "%!PS\n") (goto-char (point-max)) (insert "\nshowpage\n") (eval (list ps-print-function)) (set-buffer oldbuf) (kill-buffer tmpbuf))) ;; convert 8-bit to octal codes (defun ps-octal-buffer () "Change 8-bit characters to octal codes in buffer." (interactive) (ps-octal-region (point-min) (point-max))) (defun ps-octal-region (begin end) "Change 8-bit characters to octal codes in region." (interactive "r") (if buffer-read-only (progn (ding) (message "Buffer is read only")) (save-excursion (let (endm i) (setq endm (make-marker)) (set-marker endm end) (goto-char begin) (setq i 0) (while (re-search-forward "[\200-\377]" (marker-position endm) t) (setq i (1+ i)) (backward-char) (insert (format "\\%03o" (string-to-char (buffer-substring (point) (1+ (point)))))) (delete-char 1)) (message (format "%d change%s made" i (if (= i 1) "" "s"))) (setq endm nil))))) ;; cookbook (defun ps-center () "Insert /center." (interactive) (insert "/center { dup stringwidth pop 2 div neg 0 rmoveto } bind def ")) (defun ps-right () "Insert /right." (interactive) (insert "/right { dup stringwidth pop neg 0 rmoveto } bind def ")) (defun ps-RE () "Insert /RE." (interactive) (insert "% `new-font-name' `encoding-vector' `old-font-name' RE - /RE { findfont dup maxlength dict begin { 1 index /FID ne { def } { pop pop } ifelse } forall /Encoding exch def dup /FontName exch def currentdict end definefont pop } bind def ")) (defun ps-latin-extended () "Insert /ISOLatin1Extended This encoding vector contains all the entries from ISOLatin1Encoding plus the usually uncoded characters inserted on positions 1 through 28. " (interactive) (insert "% ISOLatin1Encoding, extended with remaining uncoded glyphs /ISOLatin1Extended [ /.notdef /Lslash /lslash /OE /oe /Scaron /scaron /Zcaron /zcaron /Ydieresis /trademark /bullet /dagger /daggerdbl /ellipsis /emdash /endash /fi /fl /florin /fraction /guilsinglleft /guilsinglright /perthousand /quotedblbase /quotedblleft /quotedblright /quotesinglbase /quotesingle /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /minus /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.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 /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 /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 /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 ] def ")) (defun ps-heapsort () "Insert /Heapsort." (interactive) (insert "% `array-element' Heapsort-cvi-or-cvr-or-cvs `number-or-string' /Heapsort-cvi-or-cvr-or-cvs { % 0 get } bind def % `array' Heapsort `sorted-array' /Heapsort { dup length /hsR exch def /hsL hsR 2 idiv 1 add def { hsR 2 lt { exit } if hsL 1 gt { /hsL hsL 1 sub def } { /hsR hsR 1 sub def dup dup dup 0 get exch dup hsR get 0 exch put hsR exch put } ifelse dup hsL 1 sub get /hsT exch def /hsJ hsL def { /hsS hsJ def /hsJ hsJ dup add def hsJ hsR gt { exit } if hsJ hsR lt { dup dup hsJ 1 sub get Heapsort-cvi-or-cvr-or-cvs exch hsJ get Heapsort-cvi-or-cvr-or-cvs lt { /hsJ hsJ 1 add def } if } if dup hsJ 1 sub get Heapsort-cvi-or-cvr-or-cvs hsT Heapsort-cvi-or-cvr-or-cvs le { exit } if dup dup hsS 1 sub exch hsJ 1 sub get put } loop dup hsS 1 sub hsT put } loop } bind def ")) ;; epsf document lay-out (defun ps-epsf-sparse () "Insert sparse EPSF template." (interactive) (goto-char (point-max)) (if (not (re-search-backward "%%EOF[ \t\n]*\\'" nil t)) (progn (goto-char (point-max)) (insert "\n%%EOF\n"))) (goto-char (point-max)) (if (not (re-search-backward "\\bshowpage[ \t\n]+%%EOF[ \t\n]*\\'" nil t)) (progn (re-search-backward "%%EOF") (insert "showpage\n"))) (goto-char (point-max)) (if (not (re-search-backward "\\bend[ \t\n]+\\bshowpage[ \t\n]+%%EOF[ \t\n]*\\'" nil t)) (progn (re-search-backward "showpage") (insert "\nend\n"))) (goto-char (point-min)) (insert "%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 ") (insert (format "%d %d\n\n" (car ps-paper-size) (car (cdr ps-paper-size)))) (insert "64 dict begin\n\n")) (defun ps-epsf-rich () "Insert rich EPSF template." (interactive) (ps-epsf-sparse) (forward-line -3) (if buffer-file-name (insert "%%Title: " (file-name-nondirectory buffer-file-name) "\n")) (insert "%%Creator: " (user-full-name) "\n") (insert "%%CreationDate: " (current-time-string) "\n") (insert "%%EndComments\n") (forward-line 3) ) ;; Interactive PostScript interpreter (defun ps-run-running () "Error if not in ps-mode or not running PostScript." (if (not (equal major-mode 'ps-mode)) (error "This function can only be called from PostScript mode")) (if (not (equal (process-status "ps-run") 'run)) (error "No PostScript process running"))) (defun ps-run-start () "Start interactive PostScript." (interactive) (let ( (command (if (and window-system ps-run-x) ps-run-x ps-run-dumb)) (init-file nil) (process-connection-type nil) (oldbuf (current-buffer)) (oldwin (selected-window)) i ) (if (not command) (error "No command specified to run interactive PostScript")) (if (or (not ps-run-mark) (not (markerp ps-run-mark))) (setq ps-run-mark (make-marker))) (if ps-run-init (progn (setq init-file (ps-run-make-tmp-filename)) (write-region ps-run-init 0 init-file) (setq init-file (list init-file)))) (pop-to-buffer "*ps run*") (ps-run-mode) (if (process-status "ps-run") (delete-process "ps-run")) (erase-buffer) (setq i (append command init-file)) (while i (insert (car i) (if (cdr i) " " "\n")) (setq i (cdr i))) (eval (append '(start-process "ps-run" "*ps run*") command init-file)) (select-window oldwin))) (defun ps-run-quit () "Quit interactive PostScript." (interactive) (ps-run-send-string "quit" t) (ps-run-cleanup)) (defun ps-run-kill () "Kill interactive PostScript." (interactive) (delete-process "ps-run") (ps-run-cleanup)) (defun ps-run-clear () "Clear/reset PostScript graphics." (interactive) (ps-run-send-string "showpage" t) (sit-for 1) (ps-run-send-string "" t)) (defun ps-run-buffer () "Send buffer to PostScript interpreter." (interactive) (ps-run-region (point-min) (point-max))) (defun ps-run-region (begin end) "Send region to PostScript interpreter." (interactive "r") (ps-run-running) (setq ps-run-parent (buffer-name)) (let ((f (ps-run-make-tmp-filename))) (set-marker ps-run-mark begin) (write-region begin end f) (ps-run-send-string (format "(%s) run" f) t))) (defun ps-run-boundingbox () "View BoundingBox" (interactive) (ps-run-running) (let ( x1 y1 x2 y2 f (buf (current-buffer)) ) (save-excursion (goto-char 1) (re-search-forward "^%%BoundingBox:[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)") (setq x1 (buffer-substring (match-beginning 1) (match-end 1))) (setq y1 (buffer-substring (match-beginning 2) (match-end 2))) (setq x2 (buffer-substring (match-beginning 3) (match-end 3))) (setq y2 (buffer-substring (match-beginning 4) (match-end 4)))) (if (not (< (string-to-number x1) (string-to-number x2))) (error "x1 (%s) should be less than x2 (%s)" x1 x2)) (if (not (< (string-to-number y1) (string-to-number y2))) (error "y1 (%s) should be less than y2 (%s)" y1 y2)) (setq f (ps-run-make-tmp-filename)) (write-region (format "gsave initgraphics 2 setlinewidth %s %s moveto %s %s lineto %s %s lineto %s %s lineto closepath gsave [ 4 20 ] 0 setdash 1 0 0 setrgbcolor stroke grestore gsave [ 4 20 ] 8 setdash 0 1 0 setrgbcolor stroke grestore [ 4 20 ] 16 setdash 0 0 1 setrgbcolor stroke grestore " x1 y1 x2 y1 x2 y2 x1 y2) 0 f) (ps-run-send-string (format "(%s) run" f) t) (set-buffer buf))) (defun ps-run-send-string (string &optional echo) (let ((oldwin (selected-window))) (pop-to-buffer "*ps run*") (goto-char (point-max)) (if echo (insert string "\n")) (set-marker (process-mark (get-process "ps-run")) (point)) (process-send-string "ps-run" (concat string "\n")) (select-window oldwin))) ; (defun ps-run-make-tmp-filename () (if (not ps-tmp-file) (progn (if (not ps-run-tmp-dir) (if (not (setq ps-run-tmp-dir (getenv "TEMP"))) (if (not (setq ps-run-tmp-dir (getenv "TMP"))) (if (setq ps-run-tmp-dir (getenv "HOME")) (progn (setq ps-run-tmp-dir (concat (file-name-as-directory ps-run-tmp-dir) "tmp")) (if (not (file-directory-p ps-run-tmp-dir)) (setq ps-run-tmp-dir nil))))))) (if (not ps-run-tmp-dir) (setq ps-run-tmp-dir "/tmp")) (setq ps-tmp-file (make-temp-name (concat (if ps-run-tmp-dir (file-name-as-directory ps-run-tmp-dir) "") "ps-run"))))) ps-tmp-file) ; Remove temporary file ; This shouldn't fail twice, because it is called at kill-emacs (defun ps-run-cleanup () (if ps-tmp-file (let ((i ps-tmp-file)) (setq ps-tmp-file nil) (if (file-exists-p i) (delete-file i))))) ; (defun ps-run-mode () "Major mode in interactive PostScript window. This mode is invoked from ps-mode and should not be called directly. \\{ps-run-mode-map} " (setq major-mode 'ps-run-mode mode-name "Interactive PS" mode-line-process '(":%s")) (use-local-map ps-run-mode-map) (run-hooks 'ps-run-mode-hook)) (defun ps-run-mouse-goto-error (event) "Set point at mouse click, then call ps-run-goto-error." (interactive "e") (mouse-set-point event) (ps-run-goto-error)) (defun ps-run-newline () "Process newline in PostScript interpreter window." (interactive) (end-of-line) (insert "\n") (forward-line -1) (if (looking-at ps-run-prompt) (goto-char (match-end 0))) (looking-at ".*") (goto-char (1+ (match-end 0))) (ps-run-send-string (buffer-substring (match-beginning 0) (match-end 0)))) (defun ps-run-goto-error () "Jump to buffer position read as integer at point. Use line numbers if ps-run-error-line-numbers is not nil" (interactive) (let ((p (point))) (if (not (looking-at "[0-9]")) (goto-char (max 1 (1- (point))))) (if (looking-at "[0-9]") (progn (forward-char 1) (forward-word -1) (if (looking-at "[0-9]+") (let (i) (setq i (string-to-int (buffer-substring (match-beginning 0) (match-end 0)))) (goto-char p) (pop-to-buffer ps-run-parent) (if ps-run-error-line-numbers (progn (goto-char (marker-position ps-run-mark)) (forward-line (1- i))) (goto-char (+ i (marker-position ps-run-mark)))))))))) ;; highlighting (if window-system (hilit-set-mode-patterns 'ps-mode '(("\\`%!.*$" nil define) ("^%%BoundingBox:[ \t]+-?[0-9]+[ \t]+-?[0-9]+[ \t]+-?[0-9]+[ \t]+-?[0-9]+" nil define) ("%.*$" nil comment) ("<<\\|>>" nil defun) ("(\\(\\\\)\\|[^)]\\)*)" nil string) ("<[ \t\n0-9a-fA-F]*>" nil string) ("<~" "~>" string) ("^/[^][ \t\n{}()<>/]*" nil defun) ; ("/[^][ \t\n{}()<>/]*" nil decl) ("\\b\\(bind\\|def\\|dict\\|begin\\|end\\|mark\\)\\b" nil keyword) ("\\bshowpage\\b" nil keyword) ("\\b\\(exec\\|exit\\|if\\|ifelse\\|for\\|forall\\|repeat\\|loop\\)\\b" nil keyword) ("\\b\\(stop\\|stopped\\|quit\\|start\\)\\b" nil keyword) ("\\b\\(gsave\\|grestore\\|save\\|restore\\)\\b" nil keyword) ("\\b\\(null\\|true\\|false\\)\\b" nil keyword) ))) ;; mouse menu (defconst ps-mode-menu-main '("PostScript" ["EPSF template, sparse" ps-epsf-sparse t] ["EPSF template, rich" ps-epsf-rich t] "---" ("Cookbook" ["RE" ps-RE t] ["ISOLatin1Extended" ps-latin-extended t] ["center" ps-center t] ["right" ps-right t] ["Heapsort" ps-heapsort t]) ("Fonts (1)" ["Times-Roman" (insert "/Times-Roman ") t] ["Times-Bold" (insert "/Times-Bold ") t] ["Times-Italic" (insert "/Times-Italic ") t] ["Times-BoldItalic" (insert "/Times-BoldItalic ") t] ["Helvetica" (insert "/Helvetica ") t] ["Helvetica-Bold" (insert "/Helvetica-Bold ") t] ["Helvetica-Oblique" (insert "/Helvetica-Oblique ") t] ["Helvetica-BoldOblique" (insert "/Helvetica-BoldOblique ") t] ["Courier" (insert "/Courier ") t] ["Courier-Bold" (insert "/Courier-Bold ") t] ["Courier-Oblique" (insert "/Courier-Oblique ") t] ["Courier-BoldOblique" (insert "/Courier-BoldOblique ") t] ["Symbol" (insert "/Symbol") t ]) ("Fonts (2)" ["AvantGarde-Book" (insert "/AvantGarde-Book ") t] ["AvantGarde-Demi" (insert "/AvantGarde-Demi ") t] ["AvantGarde-BookOblique" (insert "/AvantGarde-BookOblique ") t] ["AvantGarde-DemiOblique" (insert "/AvantGarde-DemiOblique ") t] ["Bookman-Light" (insert "/Bookman-Light ") t] ["Bookman-Demi" (insert "/Bookman-Demi ") t] ["Bookman-LightItalic" (insert "/Bookman-LightItalic ") t] ["Bookman-DemiItalic" (insert "/Bookman-DemiItalic ") t] ["Helvetica-Narrow" (insert "/Helvetica-Narrow ") t] ["Helvetica-Narrow-Bold" (insert "/Helvetica-Narrow-Bold ") t] ["Helvetica-Narrow-Oblique" (insert "/Helvetica-Narrow-Oblique ") t] ["Helvetica-Narrow-BoldOblique" (insert "/Helvetica-Narrow-BoldOblique ") t] ["NewCenturySchlbk-Roman" (insert "/NewCenturySchlbk-Roman ") t] ["NewCenturySchlbk-Bold" (insert "/NewCenturySchlbk-Bold ") t] ["NewCenturySchlbk-Italic" (insert "/NewCenturySchlbk-Italic ") t] ["NewCenturySchlbk-BoldItalic" (insert "/NewCenturySchlbk-BoldItalic ") t] ["Palatino-Roman" (insert "/Palatino-Roman ") t] ["Palatino-Bold" (insert "/Palatino-Bold ") t] ["Palatino-Italic" (insert "/Palatino-Italic ") t] ["Palatino-BoldItalic" (insert "/Palatino-BoldItalic ") t] ["ZapfChancery-MediumItalic" (insert "/ZapfChancery-MediumItalic ") t] ["ZapfDingbats" (insert "/ZapfDingbats ") t]) "---" ["8-bit to octal buffer" ps-octal-buffer t] ["8-bit to octal region" ps-octal-region (mark t)] "---" ("Auto indent" ["On" (setq ps-auto-indent t) (not ps-auto-indent)] ["Off" (setq ps-auto-indent nil) ps-auto-indent]) "---" ["Start PostScript" ps-run-start (not (equal (process-status "ps-run") 'run))] ["Quit PostScript" ps-run-quit (process-status "ps-run")] ["Kill PostScript" ps-run-kill (process-status "ps-run")] ["Send buffer to interpreter" ps-run-buffer (process-status "ps-run")] ["Send region to interpreter" ps-run-region (and (mark t) (process-status "ps-run"))] ["View BoundingBox" ps-run-boundingbox (process-status "ps-run")] ["Clear/Reset PostScript graphics" ps-run-clear (process-status "ps-run")] "---" ["Print buffer as PostScript" ps-print-buffer t] ["Print region as PostScript" ps-print-region (mark t)])) ;; keys (if (not ps-mode-syntax-table) (progn (setq ps-mode-syntax-table (make-syntax-table)) (modify-syntax-entry ?\" "w " ps-mode-syntax-table) (modify-syntax-entry ?\% "< " ps-mode-syntax-table) (modify-syntax-entry ?\n "> " ps-mode-syntax-table) (modify-syntax-entry ?\r "> " ps-mode-syntax-table) (modify-syntax-entry ?\f "> " ps-mode-syntax-table) (modify-syntax-entry ?\< "(>" ps-mode-syntax-table) (modify-syntax-entry ?\> ")<" ps-mode-syntax-table))) (if ps-mode-map nil (progn (setq ps-mode-map (make-sparse-keymap)) (define-key ps-mode-map [return] 'ps-newline) (define-key ps-mode-map "\177" 'backward-delete-char-untabify) (define-key ps-mode-map "\r" 'ps-newline) (define-key ps-mode-map "}" 'ps-r-brace) (define-key ps-mode-map "]" 'ps-r-angle) (define-key ps-mode-map ">" 'ps-r-gt) (define-key ps-mode-map "\C-c\C-j" 'ps-other-newline) (define-key ps-mode-map "\C-c\C-t" 'ps-epsf-rich) (define-key ps-mode-map "\C-c\C-s" 'ps-run-start) (define-key ps-mode-map "\C-c\C-q" 'ps-run-quit) (define-key ps-mode-map "\C-c\C-k" 'ps-run-kill) (define-key ps-mode-map "\C-c\C-b" 'ps-run-buffer) (define-key ps-mode-map "\C-c\C-r" 'ps-run-region) (define-key ps-mode-map "\C-c\C-v" 'ps-run-boundingbox) (define-key ps-mode-map "\C-c\C-c" 'ps-run-clear) (define-key ps-mode-map "\C-c\C-p" 'ps-print-buffer) (easy-menu-define ps-mode-main ps-mode-map "PostScript" ps-mode-menu-main))) (if ps-run-mode-map nil (progn (setq ps-run-mode-map (make-sparse-keymap)) (define-key ps-run-mode-map [return] 'ps-run-newline) (define-key ps-run-mode-map "\r" 'ps-run-newline) (define-key ps-run-mode-map "\C-c\C-q" 'ps-run-quit) (define-key ps-run-mode-map "\C-c\C-k" 'ps-run-kill) (define-key ps-run-mode-map "\C-c\C-e" 'ps-run-goto-error) (define-key ps-run-mode-map [mouse-2] 'ps-run-mouse-goto-error))) (add-hook 'kill-emacs-hook 'ps-run-cleanup) (provide 'ps-mode) ;;; ps-mode.el ends here