Annotation of 43BSDReno/contrib/emacs-18.55/lisp/tex-mode.el, revision 1.1

1.1     ! root        1: ;; TeX mode commands.
        !             2: ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
        !             3: ;; Rewritten following contributions by William F. Schelter
        !             4: ;; and Dick King (king@kestrel).
        !             5: ;; Modified August 1986 by Stephen Gildea <mit-erl!gildea> and
        !             6: ;; Michael Prange <mit-erl!prange> to add LaTeX support and enhance
        !             7: ;; TeX-region.
        !             8: ;; Added TeX-directory and reorganized somewhat  gildea 21 Nov 86
        !             9: 
        !            10: ;; This file is part of GNU Emacs.
        !            11: 
        !            12: ;; GNU Emacs is distributed in the hope that it will be useful,
        !            13: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !            14: ;; accepts responsibility to anyone for the consequences of using it
        !            15: ;; or for whether it serves any particular purpose or works at all,
        !            16: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            17: ;; License for full details.
        !            18: 
        !            19: ;; Everyone is granted permission to copy, modify and redistribute
        !            20: ;; GNU Emacs, but only under the conditions described in the
        !            21: ;; GNU Emacs General Public License.   A copy of this license is
        !            22: ;; supposed to have been given to you along with GNU Emacs so you
        !            23: ;; can know your rights and responsibilities.  It should be in a
        !            24: ;; file named COPYING.  Among other things, the copyright notice
        !            25: ;; and this notice must be preserved on all copies.
        !            26: 
        !            27: ;; Still to do:
        !            28: ;;  Make TAB indent correctly for TeX code.  Then we can make linefeed
        !            29: ;;  do something more useful.
        !            30: ;;
        !            31: ;;  Have spell understand TeX instead of assuming the entire world
        !            32: ;;  uses nroff.
        !            33: ;;
        !            34: ;;  The code for finding matching $ needs to be fixed.
        !            35: 
        !            36: (provide 'tex-mode)
        !            37: 
        !            38: (defvar TeX-directory "/tmp/"
        !            39:   "*Directory in which to run TeX subjob.  Temporary files are
        !            40: created in this directory.")
        !            41: (defvar TeX-dvi-print-command "lpr -d"
        !            42:   "*Command string used by \\[TeX-print] to print a .dvi file.")
        !            43: (defvar TeX-show-queue-command "lpq"
        !            44:   "*Command string used by \\[TeX-show-print-queue] to show the print queue
        !            45: that \\[TeX-print] put your job on.")
        !            46: (defvar TeX-default-mode 'plain-TeX-mode
        !            47:   "*Mode to enter for a new file when it can't be determined whether
        !            48: the file is plain TeX or LaTeX or what.")
        !            49: 
        !            50: (defvar TeX-command nil
        !            51:   "The command to run TeX on a file.  The name of the file will be appended
        !            52: to this string, separated by a space.")
        !            53: (defvar TeX-trailer nil
        !            54:   "String appended after the end of a region sent to TeX by \\[TeX-region].")
        !            55: (defvar TeX-start-of-header nil
        !            56:   "String used by \\[TeX-region] to delimit the start of the file's header.")
        !            57: (defvar TeX-end-of-header nil
        !            58:   "String used by \\[TeX-region] to delimit the end of the file's header.")
        !            59: (defvar TeX-shell-cd-command "cd"
        !            60:   "Command to give to shell running TeX to change directory.  The value of
        !            61: TeX-directory will be appended to this, separated by a space.")
        !            62: (defvar TeX-zap-file nil
        !            63:   "Temporary file name used for text being sent as input to TeX.
        !            64: Should be a simple file name with no extension or directory specification.")
        !            65: 
        !            66: (defvar TeX-mode-syntax-table nil
        !            67:   "Syntax table used while in TeX mode.")
        !            68: 
        !            69: (defun TeX-define-common-keys (keymap)
        !            70:   "Define the keys that we want defined both in TeX-mode
        !            71: and in the TeX-shell."
        !            72:   (define-key keymap "\C-c\C-k" 'TeX-kill-job)
        !            73:   (define-key keymap "\C-c\C-l" 'TeX-recenter-output-buffer)
        !            74:   (define-key keymap "\C-c\C-q" 'TeX-show-print-queue)
        !            75:   (define-key keymap "\C-c\C-p" 'TeX-print)
        !            76:   )
        !            77: 
        !            78: (defvar TeX-mode-map nil "Keymap for TeX mode")
        !            79: 
        !            80: (if TeX-mode-map 
        !            81:     nil
        !            82:   (setq TeX-mode-map (make-sparse-keymap))
        !            83:   (TeX-define-common-keys TeX-mode-map)
        !            84:   (define-key TeX-mode-map "\"" 'TeX-insert-quote)
        !            85:   (define-key TeX-mode-map "\n" 'TeX-terminate-paragraph)
        !            86:   (define-key TeX-mode-map "\e}" 'up-list)
        !            87:   (define-key TeX-mode-map "\e{" 'TeX-insert-braces)
        !            88:   (define-key TeX-mode-map "\C-c\C-r" 'TeX-region)
        !            89:   (define-key TeX-mode-map "\C-c\C-b" 'TeX-buffer)
        !            90:   (define-key TeX-mode-map "\C-c\C-f" 'TeX-close-LaTeX-block)
        !            91:   )
        !            92: 
        !            93: (defvar TeX-shell-map nil
        !            94:   "Keymap for the TeX shell.  A shell-mode-map with a few additions")
        !            95: 
        !            96: ;(fset 'TeX-mode 'tex-mode)            ;in loaddefs.
        !            97: 
        !            98: ;;; This would be a lot simpler if we just used a regexp search,
        !            99: ;;; but then it would be too slow.
        !           100: (defun tex-mode ()
        !           101:   "Major mode for editing files of input for TeX or LaTeX.
        !           102: Trys to intuit whether this file is for plain TeX or LaTeX and
        !           103: calls plain-tex-mode or latex-mode.  If it cannot be determined
        !           104: \(e.g., there are no commands in the file), the value of
        !           105: TeX-default-mode is used."
        !           106:   (interactive)
        !           107:   (let (mode slash comment)
        !           108:     (save-excursion
        !           109:       (goto-char (point-min))
        !           110:       (while (and (setq slash (search-forward "\\" nil t))
        !           111:                  (setq comment (let ((search-end (point)))
        !           112:                                  (save-excursion
        !           113:                                    (beginning-of-line)
        !           114:                                    (search-forward "%" search-end t))))))
        !           115:       (if (and slash (not comment))
        !           116:          (setq mode (if (looking-at "documentstyle")
        !           117:                         'latex-mode
        !           118:                       'plain-tex-mode))))
        !           119:     (if mode (funcall mode)
        !           120:       (funcall TeX-default-mode))))
        !           121: 
        !           122: (fset 'plain-TeX-mode 'plain-tex-mode)
        !           123: (fset 'LaTeX-mode 'latex-mode)
        !           124: 
        !           125: (defun plain-tex-mode ()
        !           126:   "Major mode for editing files of input for plain TeX.
        !           127: Makes $ and } display the characters they match.
        !           128: Makes \" insert `` when it seems to be the beginning of a quotation,
        !           129: and '' when it appears to be the end; it inserts \" only after a \\.
        !           130: 
        !           131: Use \\[TeX-region] to run TeX on the current region, plus a \"header\"
        !           132: copied from the top of the file (containing macro definitions, etc.),
        !           133: running TeX under a special subshell.  \\[TeX-buffer] does the whole buffer.
        !           134: \\[TeX-print] prints the .dvi file made by either of these.
        !           135: 
        !           136: Use \\[validate-TeX-buffer] to check buffer for paragraphs containing
        !           137: mismatched $'s or braces.
        !           138: 
        !           139: Special commands:
        !           140: \\{TeX-mode-map}
        !           141: 
        !           142: Mode variables:
        !           143: TeX-directory
        !           144:        Directory in which to create temporary files for TeX jobs
        !           145:        run by \\[TeX-region] or \\[TeX-buffer].
        !           146: TeX-dvi-print-command
        !           147:        Command string used by \\[TeX-print] to print a .dvi file.
        !           148: TeX-show-queue-command
        !           149:        Command string used by \\[TeX-show-print-queue] to show the print
        !           150:        queue that \\[TeX-print] put your job on.
        !           151: 
        !           152: Entering plain-TeX mode calls the value of text-mode-hook,
        !           153: then the value of TeX-mode-hook, and then the value
        !           154: of plain-TeX-mode-hook."
        !           155:   (interactive)
        !           156:   (TeX-common-initialization)
        !           157:   (setq mode-name "TeX")
        !           158:   (setq major-mode 'plain-TeX-mode)
        !           159:   (setq TeX-command "tex")
        !           160:   (setq TeX-start-of-header "%**start of header")
        !           161:   (setq TeX-end-of-header "%**end of header")
        !           162:   (setq TeX-trailer "\\bye\n")
        !           163:   (run-hooks 'text-mode-hook 'TeX-mode-hook 'plain-TeX-mode-hook))
        !           164: 
        !           165: (defun latex-mode ()
        !           166:   "Major mode for editing files of input for LaTeX.
        !           167: Makes $ and } display the characters they match.
        !           168: Makes \" insert `` when it seems to be the beginning of a quotation,
        !           169: and '' when it appears to be the end; it inserts \" only after a \\.
        !           170: 
        !           171: Use \\[TeX-region] to run LaTeX on the current region, plus the preamble
        !           172: copied from the top of the file (containing \\documentstyle, etc.),
        !           173: running LaTeX under a special subshell.  \\[TeX-buffer] does the whole buffer.
        !           174: \\[TeX-print] prints the .dvi file made by either of these.
        !           175: 
        !           176: Use \\[validate-TeX-buffer] to check buffer for paragraphs containing
        !           177: mismatched $'s or braces.
        !           178: 
        !           179: Special commands:
        !           180: \\{TeX-mode-map}
        !           181: 
        !           182: Mode variables:
        !           183: TeX-directory
        !           184:        Directory in which to create temporary files for TeX jobs
        !           185:        run by \\[TeX-region] or \\[TeX-buffer].
        !           186: TeX-dvi-print-command
        !           187:        Command string used by \\[TeX-print] to print a .dvi file.
        !           188: TeX-show-queue-command
        !           189:        Command string used by \\[TeX-show-print-queue] to show the print
        !           190:        queue that \\[TeX-print] put your job on.
        !           191: 
        !           192: Entering LaTeX mode calls the value of text-mode-hook,
        !           193: then the value of TeX-mode-hook, and then the value
        !           194: of LaTeX-mode-hook."
        !           195:   (interactive)
        !           196:   (TeX-common-initialization)
        !           197:   (setq mode-name "LaTeX")
        !           198:   (setq major-mode 'LaTeX-mode)
        !           199:   (setq TeX-command "latex")
        !           200:   (setq TeX-start-of-header "\\documentstyle")
        !           201:   (setq TeX-end-of-header "\\begin{document}")
        !           202:   (setq TeX-trailer "\\end{document}\n")
        !           203:   (run-hooks 'text-mode-hook 'TeX-mode-hook 'LaTeX-mode-hook))
        !           204: 
        !           205: (defun TeX-common-initialization ()
        !           206:   (kill-all-local-variables)
        !           207:   (use-local-map TeX-mode-map)
        !           208:   (setq local-abbrev-table text-mode-abbrev-table)
        !           209:   (if (null TeX-mode-syntax-table)
        !           210:       (progn
        !           211:        (setq TeX-mode-syntax-table (make-syntax-table))
        !           212:        (set-syntax-table TeX-mode-syntax-table)
        !           213:        (modify-syntax-entry ?\\ ".")
        !           214:        (modify-syntax-entry ?\f ">")
        !           215:        (modify-syntax-entry ?\n ">")
        !           216:        (modify-syntax-entry ?$ "$$")
        !           217:        (modify-syntax-entry ?% "<")
        !           218:        (modify-syntax-entry ?\" ".")
        !           219:        (modify-syntax-entry ?& ".")
        !           220:        (modify-syntax-entry ?_ ".")
        !           221:        (modify-syntax-entry ?@ "_")
        !           222:        (modify-syntax-entry ?~ " ")
        !           223:        (modify-syntax-entry ?' "w"))
        !           224:     (set-syntax-table TeX-mode-syntax-table))
        !           225:   (make-local-variable 'paragraph-start)
        !           226:   (setq paragraph-start "^[ \t]*$\\|^[\f\\\\%]")
        !           227:   (make-local-variable 'paragraph-separate)
        !           228:   (setq paragraph-separate paragraph-start)
        !           229:   (make-local-variable 'comment-start)
        !           230:   (setq comment-start "%")
        !           231:   (make-local-variable 'comment-start-skip)
        !           232:   (setq comment-start-skip "\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
        !           233:   (make-local-variable 'comment-indent-hook)
        !           234:   (setq comment-indent-hook 'TeX-comment-indent)
        !           235:   (make-local-variable 'TeX-command)
        !           236:   (make-local-variable 'TeX-start-of-header)
        !           237:   (make-local-variable 'TeX-end-of-header)
        !           238:   (make-local-variable 'TeX-trailer))
        !           239: 
        !           240: (defun TeX-comment-indent ()
        !           241:   (if (looking-at "%%%")
        !           242:       (current-column)
        !           243:     (skip-chars-backward " \t")
        !           244:     (max (if (bolp) 0 (1+ (current-column)))
        !           245:         comment-column)))
        !           246: 
        !           247: (defun TeX-insert-quote (arg)
        !           248:   "Insert ``, '' or \" according to preceding character.
        !           249: With prefix argument, always insert \" characters."
        !           250:   (interactive "P")
        !           251:   (if arg
        !           252:       (let ((count (prefix-numeric-value arg)))
        !           253:        (if (listp arg)
        !           254:            (self-insert-command 1)     ;C-u always inserts just one
        !           255:          (self-insert-command count)))
        !           256:     (insert
        !           257:      (cond
        !           258:       ((or (bobp)
        !           259:           (save-excursion
        !           260:             (forward-char -1)
        !           261:             (looking-at "[ \t\n]\\|\\s(")))
        !           262:        "``")
        !           263:       ((= (preceding-char) ?\\)
        !           264:        ?\")
        !           265:       (t "''")))))
        !           266: 
        !           267: (defun validate-TeX-buffer ()
        !           268:   "Check current buffer for paragraphs containing mismatched $'s.
        !           269: As each such paragraph is found, a mark is pushed at its beginning,
        !           270: and the location is displayed for a few seconds."
        !           271:   (interactive)
        !           272:   (let ((opoint (point)))
        !           273:     (goto-char (point-max))
        !           274:     ;; Does not use save-excursion
        !           275:     ;; because we do not want to save the mark.
        !           276:     (unwind-protect
        !           277:        (while (and (not (input-pending-p)) (not (bobp)))
        !           278:          (let ((end (point)))
        !           279:            (search-backward "\n\n" nil 'move)
        !           280:            (or (TeX-validate-paragraph (point) end)
        !           281:                (progn
        !           282:                  (push-mark (point))
        !           283:                  (message "Mismatch found in pararaph starting here")
        !           284:                  (sit-for 4)))))
        !           285:       (goto-char opoint))))
        !           286: 
        !           287: (defun TeX-validate-paragraph (start end)
        !           288:   (condition-case ()
        !           289:       (save-excursion
        !           290:        (save-restriction
        !           291:          (narrow-to-region start end)
        !           292:          (goto-char start)
        !           293:          (forward-sexp (- end start))
        !           294:          t))
        !           295:     (error nil)))
        !           296: 
        !           297: (defun TeX-terminate-paragraph (inhibit-validation)
        !           298:   "Insert two newlines, breaking a paragraph for TeX.
        !           299: Check for mismatched braces/$'s in paragraph being terminated.
        !           300: A prefix arg inhibits the checking."
        !           301:   (interactive "P")
        !           302:   (or inhibit-validation
        !           303:       (TeX-validate-paragraph
        !           304:        (save-excursion
        !           305:         (search-backward "\n\n" nil 'move)
        !           306:         (point))
        !           307:        (point))
        !           308:       (message "Paragraph being closed appears to contain a mismatch"))
        !           309:   (insert "\n\n"))
        !           310: 
        !           311: (defun TeX-insert-braces ()
        !           312:   "Make a pair of braces and be poised to type inside of them."
        !           313:   (interactive)
        !           314:   (insert ?\{)
        !           315:   (save-excursion
        !           316:     (insert ?})))
        !           317: 
        !           318: ;;; Like TeX-insert-braces, but for LaTeX.
        !           319: (defun TeX-close-LaTeX-block ()
        !           320:   "Creates an \\end{...} to match \\begin{...} on the current line and
        !           321: puts point on the blank line between them."
        !           322:   (interactive "*")
        !           323:   (let ((fail-point (point)))
        !           324:     (end-of-line)
        !           325:     (if (re-search-backward "\\\\begin{\\([^}\n]*\\)}"
        !           326:                            (save-excursion (beginning-of-line) (point)) t)
        !           327:        (let ((text (buffer-substring (match-beginning 1) (match-end 1)))
        !           328:              (indentation (current-column)))
        !           329:          (end-of-line)
        !           330:          (delete-horizontal-space)
        !           331:          (insert "\n\n")
        !           332:          (indent-to indentation)
        !           333:          (insert "\\end{" text "}")
        !           334:          (forward-line -1))
        !           335:       (goto-char fail-point)
        !           336:       (ding))))
        !           337: 
        !           338: ;;; Invoking TeX in an inferior shell.
        !           339: 
        !           340: ;;; Why use a shell instead of running TeX directly?  Because if TeX
        !           341: ;;; gets stuck, the user can switch to the shell window and type at it.
        !           342: 
        !           343: ;;; The utility functions:
        !           344: 
        !           345: (defun TeX-start-shell ()
        !           346:   (require 'shell)
        !           347:   (save-excursion
        !           348:     (set-buffer (make-shell "TeX-shell" nil nil "-v"))
        !           349:     (setq TeX-shell-map (copy-keymap shell-mode-map))
        !           350:     (TeX-define-common-keys TeX-shell-map)
        !           351:     (use-local-map TeX-shell-map)
        !           352:     (if (zerop (buffer-size))
        !           353:        (sleep-for 1))))
        !           354: 
        !           355: (defun set-buffer-directory (buffer directory)
        !           356:   "Set BUFFER's default directory to be DIRECTORY."
        !           357:   (setq directory (file-name-as-directory (expand-file-name directory)))
        !           358:   (if (not (file-directory-p directory))
        !           359:       (error "%s is not a directory" directory)
        !           360:     (save-excursion
        !           361:       (set-buffer buffer)
        !           362:       (setq default-directory directory))))
        !           363: 
        !           364: ;;; The commands:
        !           365: 
        !           366: ;;; It's a kludge that we have to create a special buffer just 
        !           367: ;;; to write out the TeX-trailer.  It would nice if there were a
        !           368: ;;; function like write-region that would write literal strings.
        !           369: 
        !           370: (defun TeX-region (beg end)
        !           371:   "Run TeX on the current region.  A temporary file (TeX-zap-file) is
        !           372: written in directory TeX-directory, and TeX is run in that directory.
        !           373: If the buffer has a header, it is written to the temporary file before
        !           374: the region itself.  The buffer's header is all lines between the
        !           375: strings defined by TeX-start-of-header and TeX-end-of-header
        !           376: inclusive.  The header must start in the first 100 lines.  The value
        !           377: of TeX-trailer is appended to the temporary file after the region."
        !           378:   (interactive "r")
        !           379:   (if (get-buffer "*TeX-shell*")
        !           380:       (TeX-kill-job)
        !           381:     (TeX-start-shell))
        !           382:   (or TeX-zap-file (setq TeX-zap-file (make-temp-name "#tz")))
        !           383:   (let ((tex-out-file (concat TeX-zap-file ".tex"))
        !           384:        (temp-buffer (get-buffer-create " TeX-Output-Buffer"))
        !           385:        (zap-directory
        !           386:         (file-name-as-directory (expand-file-name TeX-directory))))
        !           387:     (save-excursion
        !           388:       (save-restriction
        !           389:        (widen)
        !           390:        (goto-char (point-min))
        !           391:        (forward-line 100)
        !           392:        (let ((search-end (point))
        !           393:              (hbeg (point-min)) (hend (point-min))
        !           394:              (default-directory zap-directory))
        !           395:          (goto-char (point-min))
        !           396:          ;; Initialize the temp file with either the header or nothing
        !           397:          (if (search-forward TeX-start-of-header search-end t)
        !           398:              (progn
        !           399:                (beginning-of-line)
        !           400:                (setq hbeg (point))     ;mark beginning of header
        !           401:                (if (search-forward TeX-end-of-header nil t)
        !           402:                    (progn (forward-line 1)
        !           403:                           (setq hend (point))) ;mark end of header
        !           404:                  (setq hbeg (point-min))))) ;no header
        !           405:          (write-region (min hbeg beg) hend tex-out-file nil nil)
        !           406:          (write-region (max beg hend) end tex-out-file t nil))
        !           407:        (let ((local-tex-trailer TeX-trailer))
        !           408:          (set-buffer temp-buffer)
        !           409:          (erase-buffer)
        !           410:          ;; make sure trailer isn't hidden by a comment
        !           411:          (insert-string "\n")
        !           412:          (if local-tex-trailer (insert-string local-tex-trailer))
        !           413:          (set-buffer-directory temp-buffer zap-directory)
        !           414:          (write-region (point-min) (point-max) tex-out-file t nil))))
        !           415:     (set-buffer-directory "*TeX-shell*" zap-directory)
        !           416:     (send-string "TeX-shell" (concat TeX-shell-cd-command " "
        !           417:                                     zap-directory "\n"))
        !           418:     (send-string "TeX-shell" (concat TeX-command " \""
        !           419:                                     tex-out-file "\"\n")))
        !           420:   (TeX-recenter-output-buffer 0))
        !           421: 
        !           422: (defun TeX-buffer ()
        !           423:   "Run TeX on current buffer.  See \\[TeX-region] for more information."
        !           424:   (interactive)
        !           425:   (TeX-region (point-min) (point-max)))
        !           426: 
        !           427: (defun TeX-kill-job ()
        !           428:   "Kill the currently running TeX job."
        !           429:   (interactive)
        !           430:   (quit-process "TeX-shell" t))
        !           431: 
        !           432: (defun TeX-recenter-output-buffer (linenum)
        !           433:   "Redisplay buffer of TeX job output so that most recent output can be seen.
        !           434: The last line of the buffer is displayed on
        !           435: line LINE of the window, or centered if LINE is nil."
        !           436:   (interactive "P")
        !           437:   (let ((tex-shell (get-buffer "*TeX-shell*"))
        !           438:        (old-buffer (current-buffer)))
        !           439:     (if (null tex-shell)
        !           440:        (message "No TeX output buffer")
        !           441:       (pop-to-buffer tex-shell)
        !           442:       (bury-buffer tex-shell)
        !           443:       (goto-char (point-max))
        !           444:       (recenter (if linenum
        !           445:                    (prefix-numeric-value linenum)
        !           446:                  (/ (window-height) 2)))
        !           447:       (pop-to-buffer old-buffer)
        !           448:       )))
        !           449: 
        !           450: (defun TeX-print ()
        !           451:   "Print the .dvi file made by \\[TeX-region] or \\[TeX-buffer].
        !           452: Runs the shell command defined by TeX-dvi-print-command."
        !           453:   (interactive)
        !           454:   (send-string "TeX-shell"
        !           455:               (concat TeX-dvi-print-command " \"" TeX-zap-file ".dvi\"\n"))
        !           456:   (TeX-recenter-output-buffer nil))
        !           457: 
        !           458: (defun TeX-show-print-queue ()
        !           459:   "Show the print queue that \\[TeX-print] put your job on.
        !           460: Runs the shell command defined by TeX-show-queue-command."
        !           461:   (interactive)
        !           462:   (if (not (get-buffer "*TeX-shell*"))
        !           463:       (TeX-start-shell))
        !           464:   (send-string "TeX-shell" (concat TeX-show-queue-command "\n"))
        !           465:   (TeX-recenter-output-buffer nil))
        !           466: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.