home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / packages / MouseAndMenuEmacs / TeX-mode.el < prev    next >
Encoding:
Text File  |  1990-05-31  |  31.6 KB  |  845 lines

  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. ;; Added TeX-screen-print and TeX-screen-print-command for bit-map screens.
  10. ;;    Russell A. Ritchie <russell@uk.ac.strath.hci> Fri Aug  7 16:20:51 1987
  11. ;; Added TeX-spell-{buffer,region} using 'detex' and 'delatex' from
  12. ;; '=contributions' in the tex82 distribution. See note below for details.
  13. ;;     Russell A. Ritchie <russell@uk.ac.strath.hci> Wed Sep 22 09:26:54 1976
  14. ;; Modified TeX-spell-{buffer,region} to use Kamal's "detex" program from the
  15. ;; TeX 2.5 distribution.
  16. ;; Added LaTeX-{chapter,section,label,reference,typestyle,verbatim}
  17. ;; and the building blocks for them: LaTeX-{block,wrap,insert}.
  18. ;; Should any of these be TeX functions, I never use the raw thing so..?
  19. ;;     Russell A. Ritchie <russell@uk.ac.strath.hci> Tue Oct 12 11:47:41 1976
  20. ;; Added TeX-bufferp and TeX-spell-all-TeX-buffers.
  21. ;;     Russell A. Ritchie <russell@uk.ac.strath.hci> Tue Apr  5 12:02:31 1988
  22. ;; Added SUN mouse menu facility for TeX commands. See 'sun-menus.el'.
  23. ;;     Russell A. Ritchie <russell@uk.ac.strath.hci> Fri Apr  8 10:01:01 1988
  24. ;; Modded TeX-screen-print to prompt for filename if TeX-zap-file is nil.
  25. ;;     Russell A. Ritchie <russell@uk.ac.strath.hci> Thu Sep  8 14:50:53 1988
  26. ;; Added (provide 'TeX-mode).
  27. ;;     Russell A. Ritchie, <russell@uk.ac.strath.hci> Tue Feb 14 10:22:11 1989
  28. ;; Modified TeX-screen-print-command to conditionalise on window-system.
  29. ;;     Russell A. Ritchie, <russell@uk.ac.strath.hci> Tue Feb 14 10:23:10 1989
  30. ;; Modified TeX-screen-print-command to default to "xdvi", and modded
  31. ;; display algorithm to work around the fact that XtInitialise thinks
  32. ;; that command line arguments starting with a "#" are geometry
  33. ;; specifications and strips them out.
  34. ;;     Russell A. Ritchie, <russell@uk.ac.strath.hci> Mon Mar 13 14:52:03 1989
  35. ;; Added TeX-BibTeX-command and TeX-BibTeX-buffer.
  36. ;;     Russell A. Ritchie, <russell@uk.ac.strath.hci> Mon Mar 13 14:52:03 1989
  37. ;; Added interactive personal word-list maintenance to TeX-spell-region.
  38. ;; Define env var SPELLDICT to point to a spell word hash list file
  39. ;; (usually created using "cp /usr/dict/hlistb $SPELLDICT" for we Brits.)
  40. ;; and use in association with a tex-spell-command consisting of:
  41. ;;
  42. ;; #!/bin/sh
  43. ;; # Run detex on ARG then pipe output to spell
  44. ;; if ( `test -w $SPELLDICT` ) then
  45. ;;    detex -i < $1 | spell -d $SPELLDICT
  46. ;; else
  47. ;;    detex -i < $1 | spell -b
  48. ;; fi
  49. ;;     Russell A. Ritchie, <russell@uk.ac.strath.hci> Wed Mar 15 16:22:32 1989
  50. ;; Added miscellaneous functions to support severely augmented Menu interface.
  51. ;;     Russell Ritchie, <russell@uk.ac.strath.hci> Thu May 10 14:50:06 1990
  52.  
  53.  
  54.  
  55. ;; This file is part of GNU Emacs.
  56.  
  57. ;; GNU Emacs is distributed in the hope that it will be useful,
  58. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  59. ;; accepts responsibility to anyone for the consequences of using it
  60. ;; or for whether it serves any particular purpose or works at all,
  61. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  62. ;; License for full details.
  63.  
  64. ;; Everyone is granted permission to copy, modify and redistribute
  65. ;; GNU Emacs, but only under the conditions described in the
  66. ;; GNU Emacs General Public License.   A copy of this license is
  67. ;; supposed to have been given to you along with GNU Emacs so you
  68. ;; can know your rights and responsibilities.  It should be in a
  69. ;; file named COPYING.  Among other things, the copyright notice
  70. ;; and this notice must be preserved on all copies.
  71.  
  72. ;; Still to do:
  73. ;;  Make TAB indent correctly for TeX code.  Then we can make linefeed
  74. ;;  do something more useful.
  75. ;;
  76. ;;  Have spell understand TeX instead of assuming the entire world
  77. ;;  uses nroff.
  78. ;;  Done! See TeX-spell-{region,buffer}. <russell@uk.ac.strath.hci>.
  79. ;;  TeX commands inside words cause problems still - they are stripped out and
  80. ;;  the misspellings found ok but the replace-string can't find them in the
  81. ;;  original document, because they're not there...  Use recursive edit as a
  82. ;;  workaround OR don't try to print things fancy-fashion until you know how
  83. ;;  to spell them...
  84. ;;
  85. ;;  The code for finding matching $ needs to be fixed.
  86.  
  87. (provide 'TeX-mode)
  88.  
  89. (defvar TeX-directory "/tmp/"
  90.   "*Directory in which to run TeX subjob.  Temporary files are
  91. created in this directory.")
  92. (defvar TeX-dvi-print-remove-command "lprm"
  93.   "*Command used to remove a job from the print queue (see lpr-switches).")
  94. (defvar TeX-dvi-print-command "lpr -d"
  95.   "*Command string used by \\[TeX-print] to print a .dvi file.")
  96. (defvar TeX-show-queue-command "lpq -Plw"
  97.   "*Command string used by \\[TeX-show-print-queue] to show the print queue
  98. that \\[TeX-print] put your job on.")
  99. (defvar TeX-default-mode 'plain-TeX-mode
  100.   "*Mode to enter for a new file when it can't be determined whether
  101. the file is plain TeX or LaTeX or what.")
  102. (defvar TeX-screen-print-command
  103.   (if (eq window-system 'x)
  104.       "xdvi"
  105.     "texsun")
  106.   "*Command used by \\[TeX-screen-print] to show a .dvi file on the screen.")
  107. (defvar TeX-BibTeX-command "bibtex"
  108.   "*The command used to generate \".bbl\" files for TeX and LaTeX, usually bibtex.")
  109.  
  110.  
  111. (defvar TeX-command nil
  112.   "The command to run TeX on a file.  The name of the file will be appended
  113. to this string, separated by a space.")
  114. (defvar TeX-trailer nil
  115.   "String appended after the end of a region sent to TeX by \\[TeX-region].")
  116. (defvar TeX-start-of-header nil
  117.   "String used by \\[TeX-region] to delimit the start of the file's header.")
  118. (defvar TeX-end-of-header nil
  119.   "String used by \\[TeX-region] to delimit the end of the file's header.")
  120. (defvar TeX-shell-cd-command "cd"
  121.   "Command to give to shell running TeX to change directory.  The value of
  122. TeX-directory will be appended to this, separated by a space.")
  123. (defvar TeX-zap-file nil
  124.   "Temporary file name used for text being sent as input to TeX.
  125. Should be a simple file name with no extension or directory specification.")
  126. (defvar TeX-spell-command "texspell"
  127.   "The command used to strip TeX (or LaTeX) contructs prior to 'spell'ing
  128. usually it will just be a shell script that does 'detex -i < $1 | spell'")
  129.  
  130. (defvar TeX-mode-syntax-table nil
  131.   "Syntax table used while in TeX mode.")
  132.  
  133. (defvar TeX-mode-map nil)
  134.  
  135. (defun TeX-define-common-keys (keymap)
  136.   "Define the keys that we want defined both in TeX-mode
  137. and in the TeX-shell."
  138.   (define-key keymap "\C-c\C-k" 'TeX-kill-job)
  139.   (define-key keymap "\C-c\C-l" 'TeX-recenter-output-buffer)
  140.   (define-key keymap "\C-c\C-q" 'TeX-show-print-queue)
  141.   (define-key keymap "\C-c\C-p" 'TeX-print)
  142.   (define-key keymap "\C-c\C-s" 'TeX-screen-print)
  143.   )
  144.  
  145. (if TeX-mode-map 
  146.     nil
  147.   (setq TeX-mode-map (make-sparse-keymap))
  148.   (TeX-define-common-keys TeX-mode-map)
  149.   (define-key TeX-mode-map "\"" 'TeX-insert-quote)
  150.   (define-key TeX-mode-map "\n" 'TeX-terminate-paragraph)
  151.   (define-key TeX-mode-map "\e}" 'up-list)
  152.   (define-key TeX-mode-map "\e{" 'TeX-insert-braces)
  153.   (define-key TeX-mode-map "\C-c\C-r" 'TeX-region)
  154.   (define-key TeX-mode-map "\C-c\C-b" 'TeX-buffer)
  155.   (define-key TeX-mode-map "\C-c\C-c" 'TeX-spell-buffer) ; For "C"heck spelling.
  156.   (define-key TeX-mode-map "\C-c\C-f" 'TeX-close-LaTeX-block)
  157.   )
  158.  
  159. ;(fset 'TeX-mode 'tex-mode) in loaddefs.
  160. (defun tex-mode ()
  161.   "Major mode for editing files of input for TeX or LaTeX.
  162. Trys to intuit whether this file is for plain TeX or LaTeX and
  163. calls plain-tex-mode or latex-mode.  If it cannot be determined
  164. \(e.g., the file is empty), the value of TeX-default-mode is used."
  165.   (interactive)
  166.   (let ((mode
  167.      (save-excursion
  168.        (goto-char (point-min))
  169.        (while (and (search-forward "\\" nil t)
  170.                (let ((search-end (point)))
  171.              (save-excursion (beginning-of-line)
  172.                      (search-forward "%" search-end t)))))
  173.        (if (not (eobp))
  174.            (if (looking-at "documentstyle")
  175.            'latex-mode
  176.          'plain-tex-mode)))))
  177.     (if mode (funcall mode)
  178.       (funcall TeX-default-mode))))
  179.  
  180. (fset 'plain-TeX-mode 'plain-tex-mode)
  181. (fset 'LaTeX-mode 'latex-mode)
  182.  
  183. (defun plain-tex-mode ()
  184.   "Major mode for editing files of input for plain TeX.
  185. Makes $ and } display the characters they match.
  186. Makes \" insert `` when it seems to be the beginning of a quotation,
  187. and '' when it appears to be the end; it inserts \" only after a \\.
  188.  
  189. Use \\[TeX-region] to run TeX on the current region, plus a \"header\"
  190. copied from the top of the file (containing macro definitions, etc.),
  191. running TeX under a special subshell.  \\[TeX-buffer] does the whole buffer.
  192. \\[TeX-print] prints the .dvi file made by either of these.
  193. \\[TeX-screen-print] shows the .dvi file on the screen.
  194.  
  195. Use \\[validate-TeX-buffer] to check buffer for paragraphs containing
  196. mismatched $'s or braces.
  197.  
  198. Use \\[TeX-spell-buffer] or \\[TeX-spell-region] to check/fix spelling, and
  199. \\[TeX-spell-all-TeX-buffers] if you've got lots of TeX buffers on the go.       
  200.  
  201. Special commands:
  202. \\{TeX-mode-map}
  203.  
  204. Mode variables:
  205. TeX-directory
  206.     Directory in which to create temporary files for TeX jobs
  207.     run by \\[TeX-region] or \\[TeX-buffer].
  208. TeX-dvi-print-command
  209.     Command string used by \\[TeX-print] to print a .dvi file.
  210. TeX-show-queue-command
  211.     Command string used by \\[TeX-show-print-queue] to show the print
  212.     queue that \\[TeX-print] put your job on.
  213. TeX-screen-print-command
  214.     Command string used by \\[TeX-screen-print] to print a .dvi file on the screen.
  215.  
  216. Entering plain-TeX mode calls the value of text-mode-hook,
  217. then the value of TeX-mode-hook, and then the value
  218. of plain-TeX-mode-hook."
  219.   (interactive)
  220.   (TeX-common-initialization)
  221.   (setq mode-name "TeX")
  222.   (setq major-mode 'plain-TeX-mode)
  223.   (make-local-variable 'TeX-command)
  224.   (setq TeX-command "tex")
  225.   (make-local-variable 'TeX-start-of-header)
  226.   (setq TeX-start-of-header "%**start of header")
  227.   (make-local-variable 'TeX-end-of-header)
  228.   (setq TeX-end-of-header "%**end of header")
  229.   (make-local-variable 'TeX-trailer)
  230.   (setq TeX-trailer "\\bye\n")
  231.   (run-hooks 'text-mode-hook 'TeX-mode-hook 'plain-TeX-mode-hook))
  232.  
  233. (defun latex-mode ()
  234.   "Major mode for editing files of input for LaTeX.
  235. Makes $ and } display the characters they match.
  236. Makes \" insert `` when it seems to be the beginning of a quotation,
  237. and '' when it appears to be the end; it inserts \" only after a \\.
  238.  
  239. Use \\[TeX-region] to run LaTeX on the current region, plus the preamble
  240. copied from the top of the file (containing \\documentstyle, etc.),
  241. running LaTeX under a special subshell.  \\[TeX-buffer] does the whole buffer.
  242. \\[TeX-print] prints the .dvi file made by either of these.
  243. \\[TeX-screen-print] shows the .dvi file on the screen.
  244.  
  245. Use \\[validate-TeX-buffer] to check buffer for paragraphs containing
  246. mismatched $'s or braces.
  247.  
  248. Use \\[TeX-spell-buffer] or \\[TeX-spell-region] to check/fix spelling and
  249. \\[TeX-spell-all-TeX-buffers] if you've got lots of LaTeX buffers. Do a 
  250. \\[describe-function] TeX-spell-all-TeX-buffers for more details.
  251.  
  252. Special commands:
  253. \\{TeX-mode-map}
  254.  
  255. Mode variables:
  256. TeX-directory
  257.     Directory in which to create temporary files for TeX jobs
  258.     run by \\[TeX-region] or \\[TeX-buffer].
  259. TeX-dvi-print-command
  260.     Command string used by \\[TeX-print] to print a .dvi file.
  261. TeX-show-queue-command
  262.     Command string used by \\[TeX-show-print-queue] to show the print
  263.     queue that \\[TeX-print] put your job on.
  264. TeX-screen-print-command
  265.     Command string used by \\[TeX-screen-print] to print a .dvi file on the screen.
  266.  
  267. Entering LaTeX mode calls the value of text-mode-hook,
  268. then the value of TeX-mode-hook, and then the value
  269. of LaTeX-mode-hook."
  270.   (interactive)
  271.   (TeX-common-initialization)
  272.   (setq mode-name "LaTeX")
  273.   (setq major-mode 'LaTeX-mode)
  274.   (make-local-variable 'TeX-command)
  275.   (setq TeX-command "latex")
  276.   (make-local-variable 'TeX-start-of-header)
  277.   (setq TeX-start-of-header "\\documentstyle")
  278.   (make-local-variable 'TeX-end-of-header)
  279.   (setq TeX-end-of-header "\\begin{document}")
  280.   (make-local-variable 'TeX-trailer)
  281.   (setq TeX-trailer "\\end{document}\n")
  282.   (run-hooks 'text-mode-hook 'TeX-mode-hook 'LaTeX-mode-hook))
  283.  
  284. (defun TeX-common-initialization ()
  285.   (kill-all-local-variables)
  286.   (use-local-map TeX-mode-map)
  287.   (setq local-abbrev-table text-mode-abbrev-table)
  288.   (if (null TeX-mode-syntax-table)
  289.       (progn
  290.     (setq TeX-mode-syntax-table (make-syntax-table))
  291.     (set-syntax-table TeX-mode-syntax-table)
  292.     (modify-syntax-entry ?\\ ".")
  293.     (modify-syntax-entry ?\f ">")
  294.     (modify-syntax-entry ?\n ">")
  295.     (modify-syntax-entry ?$ "$$")
  296.     (modify-syntax-entry ?% "<")
  297.     (modify-syntax-entry ?\" ".")
  298.     (modify-syntax-entry ?& ".")
  299.     (modify-syntax-entry ?_ ".")
  300.     (modify-syntax-entry ?@ "_")
  301.     (modify-syntax-entry ?~ " ")
  302.     (modify-syntax-entry ?' "w"))
  303.     (set-syntax-table TeX-mode-syntax-table))
  304.   (make-local-variable 'paragraph-start)
  305.   (setq paragraph-start "^[ \t]*$\\|^[\f\\\\]")
  306.   (make-local-variable 'paragraph-separate)
  307.   (setq paragraph-separate paragraph-start)
  308.   (make-local-variable 'comment-start)
  309.   (setq comment-start "%")
  310.   (make-local-variable 'comment-start-skip)
  311.   (setq comment-start-skip "[^\\]\\(\\\\\\\\\\)*%+ *")
  312.   (make-local-variable 'comment-indent-hook)
  313.   (setq comment-indent-hook 'TeX-comment-indent))
  314.  
  315. (defun TeX-comment-indent ()
  316.   (if (looking-at "%%%")
  317.       (current-column)
  318.     (skip-chars-backward " \t")
  319.     (max (if (bolp) 0 (1+ (current-column)))
  320.      comment-column)))
  321.  
  322. (defun TeX-insert-quote (arg)
  323.   "Insert ``, '' or \" according to preceding character.
  324. With prefix argument, always insert \" characters."
  325.   (interactive "P")
  326.   (if arg
  327.       (let ((count (prefix-numeric-value arg)))
  328.     (if (listp arg)
  329.         (self-insert-command 1)    ;C-u always inserts just one
  330.       (self-insert-command count)))
  331.     (insert
  332.      (cond
  333.       ((or (bobp)
  334.        (save-excursion
  335.          (forward-char -1)
  336.          (looking-at "[ \t\n]\\|\\s(")))
  337.        "``")
  338.       ((= (preceding-char) ?\\)
  339.        ?\")
  340.       (t "''")))))
  341.  
  342. (defun validate-TeX-buffer ()
  343.   "Check current buffer for paragraphs containing mismatched $'s.
  344. As each such paragraph is found, a mark is pushed at its beginning,
  345. and the location is displayed for a few seconds."
  346.   (interactive)
  347.   (let ((opoint (point)))
  348.     (goto-char (point-max))
  349.     ;; Does not use save-excursion
  350.     ;; because we do not want to save the mark.
  351.     (unwind-protect
  352.     (while (and (not (input-pending-p)) (not (bobp)))
  353.       (let ((end (point)))
  354.         (search-backward "\n\n" nil 'move)
  355.         (or (TeX-validate-paragraph (point) end)
  356.         (progn
  357.           (push-mark (point))
  358.           (message "Mismatch found in pararaph starting here")
  359.           (sit-for 4)))))
  360.       (goto-char opoint))))
  361.  
  362. (defun TeX-validate-paragraph (start end)
  363.   (condition-case ()
  364.       (save-excursion
  365.     (save-restriction
  366.       (narrow-to-region start end)
  367.       (goto-char start)
  368.       (forward-sexp (- end start))
  369.       t))
  370.     (error nil)))
  371.  
  372. (defun TeX-terminate-paragraph (inhibit-validation)
  373.   "Insert two newlines, breaking a paragraph for TeX.
  374. Check for mismatched braces/$'s in paragraph being terminated.
  375. A prefix arg inhibits the checking."
  376.   (interactive "P")
  377.   (or inhibit-validation
  378.       (TeX-validate-paragraph
  379.        (save-excursion
  380.      (search-backward "\n\n" nil 'move)
  381.      (point))
  382.        (point))
  383.       (message "Paragraph being closed appears to contain a mismatch"))
  384.   (insert "\n\n"))
  385.  
  386. (defun TeX-insert-braces ()
  387.   "Make a pair of braces and be poised to type inside of them."
  388.   (interactive)
  389.   (insert ?\{)
  390.   (save-excursion
  391.     (insert ?})))
  392.  
  393. ;;; Like TeX-insert-braces, but for LaTeX.
  394. ;;; By Michael Prange and Stephen Gildea.
  395. (defun TeX-close-LaTeX-block ()
  396.   "Creates an \\end{...} to match \\begin{...} on the current line and
  397. puts point on the blank line between them."
  398.   (interactive "*")
  399.   (let ((fail-point (point)))
  400.     (end-of-line)
  401.     (if (re-search-backward "\\\\begin{\\([^}\n]*\\)}"
  402.                 (save-excursion (beginning-of-line) (point)) t)
  403.     (let ((text (buffer-substring (match-beginning 1) (match-end 1)))
  404.           (indentation (current-column)))
  405.       (end-of-line)
  406.       (delete-horizontal-space)
  407.       (insert "\n\n")
  408.       (indent-to indentation)
  409.       (insert "\\end{" text "}")
  410.       (forward-line -1))
  411.       (goto-char fail-point)
  412.       (ding))))
  413.  
  414. ;;; Invoking TeX in an inferior shell.
  415.  
  416. ;;; Why use a shell instead of running TeX directly?  Because if TeX
  417. ;;; gets stuck, the user can switch to the shell window and type at it.
  418.  
  419. ;;; It's kludge that we have to create a special buffer just 
  420. ;;; to write out the TeX-trailer.  It would nice if there were a
  421. ;;; function like write-region that would write literal strings.
  422.  
  423. (defun TeX-region (beg end)
  424.   "Run TeX on the current region.  A temporary file (TeX-zap-file) is
  425. written in directory TeX-directory, and TeX is run in that directory.
  426. If the buffer has a header, it is written to the temporary file before
  427. the region itself.  The buffer's header is all lines between the
  428. strings defined by TeX-start-of-header and TeX-end-of-header
  429. inclusive.  The header must start in the first 100 lines.  The value
  430. of TeX-trailer is appended to the temporary file after the region."
  431.   (interactive "r")
  432.   (if (get-buffer "*TeX-shell*")
  433.       (TeX-kill-job)
  434.     (TeX-start-shell))
  435.   (or TeX-zap-file (setq TeX-zap-file (make-temp-name "#tz")))
  436.   (let ((tex-out-file (concat TeX-zap-file ".tex"))
  437.     (temp-buffer (get-buffer-create " TeX-Output-Buffer"))
  438.     (zap-directory (expand-directory-name TeX-directory)))
  439.     (save-excursion
  440.       (save-restriction
  441.     (widen)
  442.     (goto-char (point-min))
  443.     (forward-line 100)
  444.     (let ((search-end (point))
  445.           (hbeg (point-min)) (hend (point-min))
  446.           (default-directory zap-directory))
  447.       (goto-char (point-min))
  448.       ;; Initialize the temp file with either the header or nothing
  449.       (if (search-forward TeX-start-of-header search-end t)
  450.           (progn
  451.         (forward-line -1)
  452.         (setq hbeg (point))    ;mark beginning of header
  453.         (if (search-forward TeX-end-of-header nil t)
  454.             (progn (forward-line 1)
  455.                (setq hend (point)))    ;mark end of header
  456.           (setq hbeg (point-min))))) ;no header
  457.       (write-region (min hbeg beg) hend tex-out-file nil 'quietly)
  458.       (write-region (max beg hend) end tex-out-file t  'quietly))
  459.     (let ((local-tex-trailer TeX-trailer))
  460.       (set-buffer temp-buffer)
  461.       (erase-buffer)
  462.       ;; make sure trailer isn't hidden by a comment
  463.       (insert-string "\n")
  464.       (if local-tex-trailer (insert-string local-tex-trailer))
  465.       (set-buffer-directory temp-buffer zap-directory)
  466.       (write-region (point-min) (point-max) tex-out-file t 'quietly))))
  467.     (set-buffer-directory "*TeX-shell*" zap-directory)
  468.     (send-string "TeX-shell" (concat TeX-shell-cd-command " "
  469.                      zap-directory "\n"))
  470.     (send-string "TeX-shell" (concat TeX-command " \""
  471.                      tex-out-file "\"\n")))
  472.   (TeX-recenter-output-buffer 0))
  473.  
  474. (defun TeX-start-shell ()
  475.   (require 'shell)
  476.   (save-excursion
  477.     (set-buffer (make-shell "TeX-shell" "csh" "/dev/null" "-v"))
  478.     (TeX-define-common-keys (current-local-map))))
  479.  
  480. (defun set-buffer-directory (buffer directory)
  481.   "Set BUFFER's default directory to be DIRECTORY."
  482.   (setq directory (expand-directory-name directory))
  483.   (if (not (file-directory-p directory))
  484.       (error "%s is not a directory" directory)
  485.     (save-excursion
  486.       (set-buffer buffer)
  487.       (setq default-directory directory))))
  488.  
  489. ;;; On Emacs version 18, this should use file-name-as-directory.
  490. (defun expand-directory-name (name)
  491.   "Like expand-file-name, but returns a directory name."
  492.   (file-name-as-directory name))    ; ok!?
  493.  
  494. (defun TeX-buffer ()
  495.   "Run TeX on current buffer.  See  TeX-region  for more information."
  496.   (interactive)
  497.   (TeX-region (point-min) (point-max)))
  498.  
  499. (defun TeX-kill-job ()
  500.   "Kill the currently running TeX job."
  501.   (interactive)
  502.   (quit-process "TeX-shell" t))
  503.  
  504. (defun TeX-recenter-output-buffer (linenum)
  505.   "Redisplay buffer showing current TeX job so that most recent
  506. output can be seen.  The last line of the buffer is displayed on
  507. line LINE of the window, or centered if LINE is nil."
  508.   (interactive "P")
  509.   (let ((tex-shell (get-buffer "*TeX-shell*"))
  510.     (old-buffer (current-buffer)))
  511.     (if (null tex-shell)
  512.     (message "No TeX output buffer")
  513.       (pop-to-buffer tex-shell)
  514.       (bury-buffer tex-shell)
  515.       (goto-char (point-max))
  516.       (recenter (if linenum
  517.             (prefix-numeric-value linenum)
  518.           (/ (window-height) 2)))
  519.       (pop-to-buffer old-buffer)
  520.       )))
  521.  
  522. (defun TeX-print ()
  523.   "Print the .dvi file made by \\[TeX-region] or \\[TeX-buffer].
  524. Runs the shell command defined by TeX-dvi-print-command."
  525.   (interactive)
  526.   (let ((dvi-files
  527.      (mapcar (function list) (directory-files default-directory nil ".*\.dvi$"))))
  528.     (if (and (null TeX-zap-file) (null dvi-files))
  529.     (error "You must run %s to produce a \".dvi\" file to print." mode-name)
  530.       (send-string "TeX-shell"
  531.            (format
  532.             "%s \"%s\"\n"
  533.             TeX-dvi-print-command
  534.             (if TeX-zap-file
  535.             (concat TeX-zap-file ".dvi")
  536.               (completing-read "Show which dvi file: " dvi-files (function identity) t))))
  537.       (TeX-recenter-output-buffer nil))))
  538.  
  539. (defun TeX-show-print-queue ()
  540.   "Show the print queue that \\[TeX-print] put your job on.
  541. Runs the shell command defined by TeX-show-queue-command."
  542.   (interactive)
  543.   (if (not (get-buffer "*TeX-shell*"))
  544.       (TeX-start-shell))
  545.   (send-string "TeX-shell" (concat TeX-show-queue-command "\n"))
  546.   (TeX-recenter-output-buffer nil))
  547.  
  548. (defun TeX-screen-print ()
  549.   "Show the .dvi file made by \\[TeX-region] or \\[TeX-buffer] on the screen.
  550. Runs the shell command defined by TeX-screen-print-command.
  551. Tries to start at page number specified by absolute value of prefix argument PAGENUMBER"
  552.   (interactive)
  553.   (send-string
  554.    "TeX-shell"
  555.    (format "%s \"%s\"\n" 
  556.        TeX-screen-print-command
  557.        (concat
  558.         "./"
  559.         ;; Hack to get aroung Xdvi's gobbling of
  560.         ;; command-line args that begin with "#" as
  561.         ;; geometry specifications, even though it realises
  562.         ;; that they are invalid and ignores them, it
  563.         ;; doesn't put them back into the argv.
  564.         (if TeX-zap-file
  565.         (concat TeX-zap-file ".dvi")
  566.           (completing-read
  567.            "Show which dvi file: "
  568.            (mapcar (function list) (directory-files default-directory nil ".*\.dvi$"))
  569.            (function identity)
  570.            t))))))
  571.  
  572. (defun TeX-spell-buffer ()
  573.   "Run TeX-spell-filter-command on buffer, then spell"
  574.   (interactive)
  575.   (TeX-spell-region (point-min)(point-max) (buffer-name)))
  576.  
  577. (defun TeX-spell-region (beg end &optional description)
  578.   "Run TeX-spell-filter-command on current region, then spell"
  579.   (interactive "r")
  580.   (let ((buf (get-buffer-create " *temp*")))
  581.     (save-excursion
  582.      (set-buffer buf)
  583.      (widen)
  584.      (erase-buffer))
  585.     (message "Filtering out the %s constructs in %s..."
  586.          mode-name (or description "the region"))
  587.     (if (= ?\n (char-after (1- end)))
  588.     (call-process-region beg end TeX-spell-command nil buf)
  589.       (let ((oldbuf (current-buffer)))
  590.     (save-excursion
  591.      (set-buffer buf)
  592.      (insert-buffer-substring oldbuf beg end)
  593.      (insert ?\n)
  594.      (call-process-region (point-min) (point-max) TeX-spell-command t buf))))
  595.     (message "Checking spelling of %s...%s"
  596.          (or description "region")
  597.          (if (save-excursion
  598.           (set-buffer buf)
  599.           (> (buffer-size) 0))
  600.          "not correct"
  601.            "correct"))
  602.     (let (word newword
  603.       (case-fold-search t)
  604.       (case-replace t)
  605.       (new-word-buf (get-buffer-create "*New Words*")))
  606.       (save-excursion
  607.     (set-buffer new-word-buf)
  608.     (widen)
  609.     (erase-buffer))
  610.       (while (save-excursion
  611.           (set-buffer buf)
  612.           (> (buffer-size) 0))
  613.     (save-excursion
  614.      (set-buffer buf)
  615.      (goto-char (point-min))
  616.      (setq word (buffer-substring (point)
  617.                       (progn (end-of-line) (point))))
  618.      (forward-char 1)
  619.      (delete-region (point-min) (point))
  620.      (setq newword (read-input (concat "Replacement for " word ": ")
  621.                    word))
  622.      (flush-lines (concat "^" (regexp-quote word) "$")))
  623.     (if (not (equal word newword))
  624.         (progn
  625.          (goto-char (point-min))
  626.          (query-replace-regexp (concat "\\b" (regexp-quote word) "\\b")
  627.                    newword))
  628.       ;; If user has a local dictionary (filename specified by (getenv "SPELLDICT")) 
  629.       ;; Save words that user says don't need changing, then offer to add them
  630.       ;; to local dictionary. 
  631.       (save-excursion
  632.         (set-buffer new-word-buf)
  633.         (insert newword "\n")))))
  634.     (save-excursion
  635.       (let ((new-word-buf (get-buffer-create "*New Words*"))
  636.         (pop-up-windows t))
  637.     (save-window-excursion
  638.       (pop-to-buffer new-word-buf)
  639.       (if (and (> (buffer-size) 0) (getenv "SPELLDICT"))
  640.           ;; We have some new words and the user has a personal
  641.           ;; dictionary, offer to save the new spellings.
  642.           (let* ((users-dict (getenv "SPELLDICT"))
  643.              (users-dict-full-path (expand-file-name users-dict)))
  644.         (if (yes-or-no-p (format "Add these words to %s? " users-dict))
  645.             (let ((message (format "Merging new words with words in %s..." users-dict)))
  646.               (message message)
  647.               (call-process-region
  648.                (point-min) (point-max) "spellin" t t nil users-dict)
  649.               (write-region (point-min) (point-max) users-dict-full-path nil nil)
  650.               (message (concat message "done")))))))
  651.     (kill-buffer new-word-buf)))))
  652.  
  653. (defun TeX-bufferp (&optional buffer)
  654.   "Return buffer-name if it is a TeX (or LaTeX) buffer, or nil otherwise.
  655. One optional arg, BUFFER, the buffer to test (or name of one), default is current."
  656.   (if buffer
  657.       ;; Pop to the desired buffer and test it instead of the current one.
  658.       (save-excursion
  659.     (set-buffer buffer)
  660.     (TeX-bufferp))
  661.     ;; This is the desired buffer, is it TeX or LaTeX?
  662.     (if (or (eq major-mode 'tex-mode)
  663.         (eq major-mode 'TeX-mode)
  664.         (eq major-mode 'latex-mode)
  665.         (eq major-mode 'LaTeX-mode))
  666.     (buffer-name))))
  667.  
  668. (defun TeX-spell-all-TeX-buffers ()
  669.   "Apply TeX-spell-buffer to all TeX (or LaTeX) buffers that can be found.
  670.  
  671.  This should really grap the contents of all the TeX buffers into a single
  672.  temporary buffer (with appropriate 'invisible' begin--end marks) and run
  673.  TeX-spell-buffer on that. This would save having to repeat corrections 
  674.  for regularly misspelt words like misspelled (or vice versa ?!).
  675.  Afterwards the altered regions would be put back in the correct buffers.
  676.  The 'detex' program used by TeX-spell understands about '\include{file}',
  677.  and runs itself recursively on the specified files. Some extra brainpower
  678.  should be added here, to avoid duplicated effort. A combination of (pwd)
  679.  and (buffer-file-name) should allow the '\include' files to be visited.
  680.  The corresponding '\include{file}' command should either be diked out of
  681.  the temporary buffer, or an appropriate flag passed to 'detex' to avoid
  682.  the recursive runs. At the moment (Tue Apr 5 14:58:18 1988) the flag that
  683.  is passed to 'detex' to stop this is '-i'. For extra hack-value it should
  684.  also figure out what 'bib' files are being used (if any) and dike out any
  685.  defined citation references from the misspelt word list. Any volunteers?
  686. "
  687.   (interactive)
  688.   (let ((TeX-buffer-names
  689.       (apply (function nconc)
  690.          (mapcar (function (lambda (x) (if (TeX-bufferp x) (list x))))
  691.              (buffer-list)))))
  692.     (save-excursion
  693.       (while TeX-buffer-names
  694.     (let ((this-buffer (car TeX-buffer-names)))
  695.       (switch-to-buffer this-buffer t) ; Show the one we're doing.
  696.       (TeX-spell-buffer)        ; and do it...
  697.       (setq TeX-buffer-names (cdr TeX-buffer-names)))))))
  698.  
  699. (defun TeX-BibTeX-buffer ()
  700.   "Run the command specified by  TeX-BibTeX-command  on the current buffer."
  701.   (interactive)
  702.   (if (null TeX-zap-file)
  703.       (error "You must run %s on the whole buffer before you can use BibTeX."
  704.          mode-name)
  705.     (send-string "TeX-shell"
  706.          (concat TeX-BibTeX-command " \"" TeX-zap-file "\"\n"))
  707.     (TeX-recenter-output-buffer nil)))
  708.  
  709. ;;; To do: Modify wrappers to work with regions for sectioning/typestyling...
  710. ;;; Use one LaTeX-wrap-region function that takes wrap-thing & in/prefix flag.
  711.  
  712. (defun LaTeX-block(block)
  713.   "Surround the word at (or before) point with \\BLOCK{ and } and move past }"
  714.   (LaTeX-insert (concat "\\" block "{")))
  715.  
  716. (defun LaTeX-wrap(type)
  717.   "Wrap {\TYPE and } around the word at or before point, and move past }"
  718.   (LaTeX-insert (concat "{\\" type " ")))
  719.  
  720. (defun LaTeX-insert(start)
  721.   "Put START before word at point, move to end of word and add \"} \""
  722.   (forward-word -1)
  723.   (insert start)
  724.   (forward-word 1)
  725.   (insert "} "))
  726.  
  727. (defun LaTeX-cite()
  728.   "Make word at point a bibliographic citation, bound to \\[LaTeX-cite]"
  729.   (interactive)
  730.   (LaTeX-block "cite")
  731.   (forward-word -2)
  732.   (forward-char -1)
  733.   (delete-horizontal-space)
  734.   (insert "~")
  735.   (forward-word 2)
  736.   (forward-char 1))
  737.  
  738. (defun LaTeX-section(arg)
  739.   "Make word at point chapter name, bound to \\[LaTeX-section]
  740. One \C-u makes it a section, two make it a subsection, three a subsubsection."
  741.   (interactive "p")
  742.   (cond ((eq arg 1) (LaTeX-block "chapter"))
  743.     ((eq arg 4) (LaTeX-block "section"))
  744.     ((eq arg 16) (LaTeX-block "subsection"))
  745.     (t (LaTeX-block "subsubsection"))))
  746.  
  747. (defun LaTeX-label()
  748.   "Make word at point a label, bound to \\[LaTeX-label]"
  749.   (interactive)
  750.   (LaTeX-block "label"))
  751.  
  752. (defun LaTeX-index()
  753.   "Make word at point an index entry, bound to \\[LaTeX-index]"
  754.   (interactive)
  755.   (LaTeX-block "index"))
  756.  
  757. (defun LaTeX-reference(arg)
  758.   "Make current word a LaTeX reference, according to table:
  759.  
  760.        __________________________________________________
  761.        | Prefix Argument Value        | Reference       |
  762.        |-------------------------------------------------
  763.        | 1 (default if no prefix arg) |  bibliographic    |
  764.        | >3 (use \C-u once)          |  page number    |
  765.        | >15 (use \C-u twice)          |  figure        |
  766.        | >63 (use \C-u thrice)          |  table        |
  767.        --------------------------------------------------"
  768.   (interactive "p")
  769.   (if (eq arg 4) (LaTeX-block "pageref") (LaTeX-block "ref"))
  770.   (save-excursion
  771.     (forward-word -2)
  772.     (forward-char -1)
  773.     (delete-horizontal-space)
  774.     (insert (concat (cond ((eq arg 1) "")
  775.               ((eq arg 4) " page")
  776.               ((eq arg 16) " figure")
  777.               ((eq arg 64) " table")) "~"))))
  778.  
  779. (defun LaTeX-typestyle(arg)
  780.   "Make current word change type style depending on prefix arg table below:
  781.        ________________________________________________
  782.        | Prefix Argument Value        | Type Style    |
  783.        |-----------------------------------------------
  784.        | 1 (default if no prefix arg) |  bold         |
  785.        | >3 (use \C-u once)          |  emphasise    |
  786.        | >15 (use \C-u twice)          |  italics      |
  787.        | >63 (use \C-u thrice)          |  sans-serif   |
  788.        ------------------------------------------------"
  789.   (interactive "p")
  790.   (cond ((eq arg 1) (LaTeX-wrap "bf"))
  791.     ((eq arg 4) (LaTeX-wrap "em"))
  792.     ((eq arg 16) (LaTeX-wrap "it"))
  793.     ((eq arg 64) (LaTeX-wrap "sf"))))
  794.  
  795. (defun LaTeX-verbatim(char)
  796.   "Make region delimited by (prompted for) CHAR an in-text verbatim entry."
  797.   (interactive "sDelimited by what?: ")
  798.   (save-excursion
  799.     (let ((point (point)))
  800.       (search-backward char (point-min) t 2)
  801.       (if (eq point (point))        ; We haven't moved.
  802.       (error (concat "I couldn't find 2 '" char "'s"))
  803.     (insert "\\verb")))))
  804.  
  805. (defun TeX-typeface-region (typeface)
  806.   "Insert \"{\\TYPEFACE\" and \"}\" around current region.
  807. Where TYPEFACE is a known LaTeX type style."
  808.   (save-excursion
  809.     (goto-char (region-beginning))
  810.     (insert "{\\" typeface)
  811.     (goto-char (region-end)))
  812.     (insert "}"))
  813.  
  814. (defun TeX-new-section (type text)
  815.   (interactive "sSection type: \nsSection text: ")
  816.   (insert-string "\n\\" type "{" text "}\n"))
  817.  
  818. (defun TeX-new-heading (type)
  819.   (interactive)
  820.   (TeX-new-section type (read-string "Heading text: ")))
  821.  
  822. (defun TeX-remove-from-print-queue (jobnumber)
  823.   (interactive "nRemove Printer Job number: ")
  824.   (apply 'start-process "Print Queue Removal" nil
  825.      TeX-dvi-print-remove-command
  826.      (append lpr-switches (list (format "%s" jobnumber))))
  827.   (message
  828.    "Removing Job %s from Printer Queue %s..." jobnumber
  829.    (mapconcat 
  830.     'identity
  831.     (append (list "using" TeX-dvi-print-remove-command) lpr-switches) " ")))
  832.  
  833. (defun TeX-suspend-job ()
  834.   "Stop the *TeX-shell*'s current subjob."
  835.   (save-excursion
  836.     (set-buffer "*TeX-shell*")
  837.     (stop-shell-subjob)))
  838.  
  839. (defun TeX-continue-job ()
  840.   "Continue the *TeX-shell*'s current subjob."
  841.   (save-excursion
  842.     (set-buffer "*TeX-shell*")
  843.     (continue-shell-subjob)))
  844.  
  845.