(mail-default-reply-to): Add autoload cookie.
[bpt/emacs.git] / lisp / textmodes / tex-mode.el
CommitLineData
d501f516
ER
1;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands.
2
eea8d4ef
ER
3;; Copyright (C) 1985, 1986, 1989, 1992 Free Software Foundation, Inc.
4
e5167999 5;; Maintainer: Edward M. Reingold <reingold@cs.uiuc.edu>
d7b4d18f 6;; Keywords: tex
e5167999 7
528415e7 8;; Contributions over the years by William F. Schelter, Dick King,
2f3067de 9;; Stephen Gildea, Michael Prange, and Jacob Gore.
528415e7 10
869bff31 11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
e5167999 15;; the Free Software Foundation; either version 2, or (at your option)
869bff31 16;; any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs; see the file COPYING. If not, write to
25;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26
e5167999
ER
27;;; Code:
28
8241d7b9 29(require 'comint)
2f3067de 30(require 'compile)
528415e7 31
7e1dae73 32;;;###autoload
528415e7
RS
33(defvar tex-shell-file-name nil
34 "*If non-nil, is file name to use for the subshell in which TeX is run.")
35
7e1dae73 36;;;###autoload
528415e7
RS
37(defvar tex-directory "."
38 "*Directory in which temporary files are left.
39You can make this /tmp if your TEXINPUTS has no relative directories in it
40and you don't try to apply \\[tex-region] or \\[tex-buffer] when there are
41\\input commands with relative directories.")
869bff31 42
7e1dae73 43;;;###autoload
528415e7
RS
44(defvar tex-offer-save t
45 "*If non-nil, ask about saving modified buffers before \\[tex-file] is run.")
869bff31 46
7e1dae73 47;;;###autoload
869bff31 48(defvar tex-run-command "tex"
49 "*Command used to run TeX subjob.
528415e7
RS
50If this string contains an asterisk (*), it will be replaced by the
51filename; if not, the name of the file, preceded by blank, will be added to
52this string.")
869bff31 53
7e1dae73 54;;;###autoload
869bff31 55(defvar latex-run-command "latex"
56 "*Command used to run LaTeX subjob.
528415e7
RS
57If this string contains an asterisk (*), it will be replaced by the
58filename; if not, the name of the file, preceded by blank, will be added to
59this string.")
60
61(defvar standard-latex-block-names
62 '("abstract" "array" "center" "description"
63 "displaymath" "document" "enumerate" "eqnarray"
64 "eqnarray*" "equation" "figure" "figure*"
65 "flushleft" "flushright" "itemize" "letter"
66 "list" "minipage" "picture" "quotation"
67 "quote" "slide" "sloppypar" "tabbing"
68 "table" "table*" "tabular" "tabular*"
69 "thebibliography" "theindex*" "titlepage" "trivlist"
70 "verbatim" "verbatim*" "verse")
71 "Standard LaTeX block names.")
72
7e1dae73 73;;;###autoload
528415e7
RS
74(defvar latex-block-names nil
75 "*User defined LaTeX block names.
76Combined with `standard-latex-block-names' for minibuffer completion.")
869bff31 77
7e1dae73 78;;;###autoload
869bff31 79(defvar slitex-run-command "slitex"
80 "*Command used to run SliTeX subjob.
528415e7
RS
81If this string contains an asterisk (*), it will be replaced by the
82filename; if not, the name of the file, preceded by blank, will be added to
83this string.")
869bff31 84
7e1dae73 85;;;###autoload
869bff31 86(defvar tex-bibtex-command "bibtex"
528415e7
RS
87 "*Command used by `tex-bibtex-file' to gather bibliographic data.
88If this string contains an asterisk (*), it will be replaced by the
89filename; if not, the name of the file, preceded by blank, will be added to
90this string.")
869bff31 91
7e1dae73 92;;;###autoload
869bff31 93(defvar tex-dvi-print-command "lpr -d"
528415e7
RS
94 "*Command used by \\[tex-print] to print a .dvi file.
95If this string contains an asterisk (*), it will be replaced by the
96filename; if not, the name of the file, preceded by blank, will be added to
97this string.")
98
7e1dae73 99;;;###autoload
528415e7
RS
100(defvar tex-alt-dvi-print-command "lpr -d"
101 "*Command used by \\[tex-print] with a prefix arg to print a .dvi file.
102If this string contains an asterisk (*), it will be replaced by the
103filename; if not, the name of the file, preceded by blank, will be added to
104this string.
105
106If two printers are not enough of a choice, you can define the value
107of tex-alt-dvi-print-command to be an expression that asks what you want;
108for example,
109
110 (setq tex-alt-dvi-print-command
111 '(format \"lpr -P%s\" (read-string \"Use printer: \")))
112
113would tell \\[tex-print] with a prefix argument to ask you which printer to
114use.")
869bff31 115
7e1dae73 116;;;###autoload
869bff31 117(defvar tex-dvi-view-command nil
528415e7
RS
118 "*Command used by \\[tex-view] to display a .dvi file.
119If this string contains an asterisk (*), it will be replaced by the
120filename; if not, the name of the file, preceded by blank, will be added to
121this string.
122
123This can be set conditionally so that the previewer used is suitable for the
124window system being used. For example,
125
126 (setq tex-dvi-view-command
127 (if (eq window-system 'x) \"xdvi\" \"dvi2tty * | cat -s\"))
128
129would tell \\[tex-view] use xdvi under X windows and to use dvi2tty
130otherwise.")
869bff31 131
7e1dae73 132;;;###autoload
869bff31 133(defvar tex-show-queue-command "lpq"
528415e7
RS
134 "*Command used by \\[tex-show-print-queue] to show the print queue.
135Should show the queue(s) that \\[tex-print] puts jobs on.")
869bff31 136
7e1dae73 137;;;###autoload
869bff31 138(defvar tex-default-mode 'plain-tex-mode
139 "*Mode to enter for a new file that might be either TeX or LaTeX.
140This variable is used when it can't be determined whether the file
141is plain TeX or LaTeX or what because the file contains no commands.
142Normally set to either 'plain-tex-mode or 'latex-mode.")
143
7e1dae73 144;;;###autoload
869bff31 145(defvar tex-open-quote "``"
146 "*String inserted by typing \\[tex-insert-quote] to open a quotation.")
147
7e1dae73 148;;;###autoload
869bff31 149(defvar tex-close-quote "''"
150 "*String inserted by typing \\[tex-insert-quote] to close a quotation.")
151
528415e7
RS
152(defvar tex-last-temp-file nil
153 "Latest temporary file generated by \\[tex-region] and \\[tex-buffer].
154Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the
155tex-shell goes away.")
156
869bff31 157(defvar tex-command nil
158 "Command to run TeX.
528415e7 159The name of the file, preceded by a blank, will be added to this string.")
869bff31 160
161(defvar tex-trailer nil
162 "String appended after the end of a region sent to TeX by \\[tex-region].")
163
164(defvar tex-start-of-header nil
165 "String used by \\[tex-region] to delimit the start of the file's header.")
166
167(defvar tex-end-of-header nil
168 "String used by \\[tex-region] to delimit the end of the file's header.")
169
170(defvar tex-shell-cd-command "cd"
171 "Command to give to shell running TeX to change directory.
172The value of tex-directory will be appended to this, separated by a space.")
173
174(defvar tex-zap-file nil
175 "Temporary file name used for text being sent as input to TeX.
176Should be a simple file name with no extension or directory specification.")
177
178(defvar tex-last-buffer-texed nil
179 "Buffer which was last TeXed.")
180
181(defvar tex-print-file nil
182 "File name that \\[tex-print] prints.
183Set by \\[tex-region], \\[tex-buffer], and \\[tex-file].")
184
185(defvar tex-mode-syntax-table nil
186 "Syntax table used while in TeX mode.")
187
188(defun tex-define-common-keys (keymap)
189 "Define the keys that we want defined both in TeX mode and in the tex-shell."
190 (define-key keymap "\C-c\C-k" 'tex-kill-job)
191 (define-key keymap "\C-c\C-l" 'tex-recenter-output-buffer)
192 (define-key keymap "\C-c\C-q" 'tex-show-print-queue)
193 (define-key keymap "\C-c\C-p" 'tex-print)
194 (define-key keymap "\C-c\C-v" 'tex-view)
62a24cb5
RS
195
196 (define-key keymap [menu-bar tex] (cons "TeX" (make-sparse-keymap "TeX")))
197
198 (define-key keymap [menu-bar tex tex-kill-job] '("Tex Kill" . tex-kill-job))
cf6d6e8a
RS
199 (define-key keymap [menu-bar tex tex-recenter-output-buffer]
200 '("Tex Recenter" . tex-recenter-output-buffer))
62a24cb5
RS
201 (define-key keymap [menu-bar tex tex-show-print-queue]
202 '("Show Print Queue" . tex-show-print-queue))
cf6d6e8a
RS
203 (define-key keymap [menu-bar tex tex-alt-print]
204 '("Tex Print (alt printer)" . tex-alt-print))
62a24cb5 205 (define-key keymap [menu-bar tex tex-print] '("Tex Print" . tex-print))
cf6d6e8a 206 (define-key keymap [menu-bar tex tex-view] '("Tex View" . tex-view))
869bff31 207 )
208
209(defvar tex-mode-map nil "Keymap for TeX mode.")
210
211(if tex-mode-map
212 nil
213 (setq tex-mode-map (make-sparse-keymap))
214 (tex-define-common-keys tex-mode-map)
215 (define-key tex-mode-map "\"" 'tex-insert-quote)
216 (define-key tex-mode-map "\n" 'tex-terminate-paragraph)
217 (define-key tex-mode-map "\C-c}" 'up-list)
218 (define-key tex-mode-map "\C-c{" 'tex-insert-braces)
219 (define-key tex-mode-map "\C-c\C-r" 'tex-region)
220 (define-key tex-mode-map "\C-c\C-b" 'tex-buffer)
221 (define-key tex-mode-map "\C-c\C-f" 'tex-file)
222 (define-key tex-mode-map "\C-c\C-i" 'tex-bibtex-file)
223 (define-key tex-mode-map "\C-c\C-o" 'tex-latex-block)
cf6d6e8a
RS
224 (define-key tex-mode-map "\C-c\C-e" 'tex-close-latex-block)
225 (define-key tex-mode-map [menu-bar tex tex-validate-region]
226 '("Validate Region" . tex-validate-region))
227 (define-key tex-mode-map [menu-bar tex validate-tex-buffer]
228 '("Validate Buffer" . validate-tex-buffer))
229 (define-key tex-mode-map [menu-bar tex tex-region]
230 '("Tex Region" . tex-region))
231 (define-key tex-mode-map [menu-bar tex tex-buffer]
232 '("Tex Buffer" . tex-buffer))
233 (define-key tex-mode-map [menu-bar tex tex-file] '("Tex File" . tex-file)))
234
235(put 'tex-region 'menu-enable 'mark-active)
236(put 'tex-validate-region 'menu-enable 'mark-active)
237(put 'tex-print 'menu-enable '(stringp tex-print-file))
238(put 'tex-alt-print 'menu-enable '(stringp tex-print-file))
239(put 'tex-view 'menu-enable '(stringp tex-print-file))
240(put 'tex-recenter-output-buffer 'menu-enable '(get-buffer "*tex-shell*"))
241(put 'tex-kill-job 'menu-enable '(tex-shell-running))
242
869bff31 243
244(defvar tex-shell-map nil
528415e7 245 "Keymap for the tex-shell. A comint-mode-map with a few additions.")
869bff31 246
8241d7b9
ER
247(defvar compare-windows-whitespace nil) ; Pacify the byte-compiler
248
869bff31 249;;; This would be a lot simpler if we just used a regexp search,
250;;; but then it would be too slow.
7229064d 251;;;###autoload
869bff31 252(defun tex-mode ()
253 "Major mode for editing files of input for TeX, LaTeX, or SliTeX.
254Tries to determine (by looking at the beginning of the file) whether
255this file is for plain TeX, LaTeX, or SliTeX and calls plain-tex-mode,
256latex-mode, or slitex-mode, respectively. If it cannot be determined,
257such as if there are no commands in the file, the value of tex-default-mode
258is used."
259 (interactive)
260 (let (mode slash comment)
261 (save-excursion
262 (goto-char (point-min))
263 (while (and (setq slash (search-forward "\\" nil t))
264 (setq comment (let ((search-end (point)))
265 (save-excursion
266 (beginning-of-line)
267 (search-forward "%" search-end t))))))
268 (if (and slash (not comment))
269 (setq mode (if (looking-at "documentstyle")
270 (if (looking-at "documentstyle{slides}")
271 'slitex-mode
272 'latex-mode)
273 'plain-tex-mode))))
274 (if mode (funcall mode)
275 (funcall tex-default-mode))))
e4c8c838 276
6503cec3 277;;;###autoload
31e1d920 278(defalias 'TeX-mode 'tex-mode)
6503cec3 279;;;###autoload
31e1d920 280(defalias 'LaTeX-mode 'latex-mode)
869bff31 281
7229064d 282;;;###autoload
869bff31 283(defun plain-tex-mode ()
284 "Major mode for editing files of input for plain TeX.
285Makes $ and } display the characters they match.
286Makes \" insert `` when it seems to be the beginning of a quotation,
287and '' when it appears to be the end; it inserts \" only after a \\.
288
289Use \\[tex-region] to run TeX on the current region, plus a \"header\"
290copied from the top of the file (containing macro definitions, etc.),
291running TeX under a special subshell. \\[tex-buffer] does the whole buffer.
292\\[tex-file] saves the buffer and then processes the file.
293\\[tex-print] prints the .dvi file made by any of these.
294\\[tex-view] previews the .dvi file made by any of these.
295\\[tex-bibtex-file] runs bibtex on the file of the current buffer.
296
297Use \\[validate-tex-buffer] to check buffer for paragraphs containing
298mismatched $'s or braces.
299
300Special commands:
301\\{tex-mode-map}
302
303Mode variables:
304tex-run-command
305 Command string used by \\[tex-region] or \\[tex-buffer].
306tex-directory
307 Directory in which to create temporary files for TeX jobs
308 run by \\[tex-region] or \\[tex-buffer].
309tex-dvi-print-command
310 Command string used by \\[tex-print] to print a .dvi file.
528415e7
RS
311tex-alt-dvi-print-command
312 Alternative command string used by \\[tex-print] (when given a prefix
313 argument) to print a .dvi file.
869bff31 314tex-dvi-view-command
315 Command string used by \\[tex-view] to preview a .dvi file.
316tex-show-queue-command
317 Command string used by \\[tex-show-print-queue] to show the print
318 queue that \\[tex-print] put your job on.
319
8241d7b9
ER
320Entering Plain-tex mode calls the value of `text-mode-hook', then the value
321of `tex-mode-hook', and then the value of `plain-tex-mode-hook'. When the
322special subshell is initiated, the value of `tex-shell-hook' is called."
323
869bff31 324 (interactive)
325 (tex-common-initialization)
326 (setq mode-name "TeX")
327 (setq major-mode 'plain-tex-mode)
328 (setq tex-command tex-run-command)
329 (setq tex-start-of-header "%**start of header")
330 (setq tex-end-of-header "%**end of header")
331 (setq tex-trailer "\\bye\n")
332 (run-hooks 'text-mode-hook 'tex-mode-hook 'plain-tex-mode-hook))
6503cec3 333;;;###autoload
31e1d920 334(defalias 'plain-TeX-mode 'plain-tex-mode)
869bff31 335
7229064d 336;;;###autoload
869bff31 337(defun latex-mode ()
338 "Major mode for editing files of input for LaTeX.
339Makes $ and } display the characters they match.
340Makes \" insert `` when it seems to be the beginning of a quotation,
341and '' when it appears to be the end; it inserts \" only after a \\.
342
343Use \\[tex-region] to run LaTeX on the current region, plus the preamble
344copied from the top of the file (containing \\documentstyle, etc.),
345running LaTeX under a special subshell. \\[tex-buffer] does the whole buffer.
346\\[tex-file] saves the buffer and then processes the file.
347\\[tex-print] prints the .dvi file made by any of these.
348\\[tex-view] previews the .dvi file made by any of these.
349\\[tex-bibtex-file] runs bibtex on the file of the current buffer.
350
351Use \\[validate-tex-buffer] to check buffer for paragraphs containing
352mismatched $'s or braces.
353
354Special commands:
355\\{tex-mode-map}
356
357Mode variables:
358latex-run-command
359 Command string used by \\[tex-region] or \\[tex-buffer].
360tex-directory
361 Directory in which to create temporary files for LaTeX jobs
362 run by \\[tex-region] or \\[tex-buffer].
363tex-dvi-print-command
364 Command string used by \\[tex-print] to print a .dvi file.
528415e7
RS
365tex-alt-dvi-print-command
366 Alternative command string used by \\[tex-print] (when given a prefix
367 argument) to print a .dvi file.
869bff31 368tex-dvi-view-command
369 Command string used by \\[tex-view] to preview a .dvi file.
370tex-show-queue-command
371 Command string used by \\[tex-show-print-queue] to show the print
372 queue that \\[tex-print] put your job on.
373
374Entering Latex mode calls the value of text-mode-hook, then the value of
375tex-mode-hook, and then the value of latex-mode-hook. When the special
376subshell is initiated, the value of tex-shell-hook is called."
377 (interactive)
378 (tex-common-initialization)
379 (setq mode-name "LaTeX")
380 (setq major-mode 'latex-mode)
381 (setq tex-command latex-run-command)
382 (setq tex-start-of-header "\\documentstyle")
383 (setq tex-end-of-header "\\begin{document}")
384 (setq tex-trailer "\\end{document}\n")
385 (run-hooks 'text-mode-hook 'tex-mode-hook 'latex-mode-hook))
386
bd2f2323 387;;;###autoload
869bff31 388(defun slitex-mode ()
389 "Major mode for editing files of input for SliTeX.
390Makes $ and } display the characters they match.
391Makes \" insert `` when it seems to be the beginning of a quotation,
392and '' when it appears to be the end; it inserts \" only after a \\.
393
394Use \\[tex-region] to run SliTeX on the current region, plus the preamble
395copied from the top of the file (containing \\documentstyle, etc.),
396running SliTeX under a special subshell. \\[tex-buffer] does the whole buffer.
397\\[tex-file] saves the buffer and then processes the file.
398\\[tex-print] prints the .dvi file made by any of these.
399\\[tex-view] previews the .dvi file made by any of these.
400\\[tex-bibtex-file] runs bibtex on the file of the current buffer.
401
402Use \\[validate-tex-buffer] to check buffer for paragraphs containing
403mismatched $'s or braces.
404
405Special commands:
406\\{tex-mode-map}
407
408Mode variables:
409slitex-run-command
410 Command string used by \\[tex-region] or \\[tex-buffer].
411tex-directory
412 Directory in which to create temporary files for SliTeX jobs
413 run by \\[tex-region] or \\[tex-buffer].
414tex-dvi-print-command
415 Command string used by \\[tex-print] to print a .dvi file.
528415e7
RS
416tex-alt-dvi-print-command
417 Alternative command string used by \\[tex-print] (when given a prefix
418 argument) to print a .dvi file.
869bff31 419tex-dvi-view-command
420 Command string used by \\[tex-view] to preview a .dvi file.
421tex-show-queue-command
422 Command string used by \\[tex-show-print-queue] to show the print
423 queue that \\[tex-print] put your job on.
424
8241d7b9
ER
425Entering SliTeX mode calls the value of `text-mode-hook', then the value of
426`tex-mode-hook', then the value of `latex-mode-hook', and then the value of
427`slitex-mode-hook'. When the special subshell is initiated, the value of
428`tex-shell-hook' is called."
869bff31 429 (interactive)
430 (tex-common-initialization)
431 (setq mode-name "SliTeX")
432 (setq major-mode 'slitex-mode)
433 (setq tex-command slitex-run-command)
434 (setq tex-start-of-header "\\documentstyle{slides}")
435 (setq tex-end-of-header "\\begin{document}")
436 (setq tex-trailer "\\end{document}\n")
437 (run-hooks
438 'text-mode-hook 'tex-mode-hook 'latex-mode-hook 'slitex-mode-hook))
439
440(defun tex-common-initialization ()
441 (kill-all-local-variables)
442 (use-local-map tex-mode-map)
443 (setq local-abbrev-table text-mode-abbrev-table)
444 (if (null tex-mode-syntax-table)
445 (let ((char 0))
446 (setq tex-mode-syntax-table (make-syntax-table))
447 (set-syntax-table tex-mode-syntax-table)
448 (while (< char ? )
449 (modify-syntax-entry char ".")
450 (setq char (1+ char)))
451 (modify-syntax-entry ?\C-@ "w")
452 (modify-syntax-entry ?\t " ")
453 (modify-syntax-entry ?\n ">")
454 (modify-syntax-entry ?\f ">")
455 (modify-syntax-entry ?$ "$$")
456 (modify-syntax-entry ?% "<")
457 (modify-syntax-entry ?\\ "/")
458 (modify-syntax-entry ?\" ".")
459 (modify-syntax-entry ?& ".")
460 (modify-syntax-entry ?_ ".")
461 (modify-syntax-entry ?@ "_")
462 (modify-syntax-entry ?~ " ")
463 (modify-syntax-entry ?' "w"))
464 (set-syntax-table tex-mode-syntax-table))
465 (make-local-variable 'paragraph-start)
466 (setq paragraph-start "^[ \t]*$\\|^[\f\\\\%]")
467 (make-local-variable 'paragraph-separate)
468 (setq paragraph-separate paragraph-start)
469 (make-local-variable 'comment-start)
470 (setq comment-start "%")
471 (make-local-variable 'comment-start-skip)
472 (setq comment-start-skip "\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
e41b2db1
ER
473 (make-local-variable 'comment-indent-function)
474 (setq comment-indent-function 'tex-comment-indent)
869bff31 475 (make-local-variable 'compare-windows-whitespace)
476 (setq compare-windows-whitespace 'tex-categorize-whitespace)
477 (make-local-variable 'tex-command)
478 (make-local-variable 'tex-start-of-header)
479 (make-local-variable 'tex-end-of-header)
480 (make-local-variable 'tex-trailer))
481
482(defun tex-comment-indent ()
483 (if (looking-at "%%%")
484 (current-column)
485 (skip-chars-backward " \t")
486 (max (if (bolp) 0 (1+ (current-column)))
487 comment-column)))
488
489(defun tex-categorize-whitespace (backward-limit)
490 ;; compare-windows-whitespace is set to this.
491 ;; This is basically a finite-state machine.
492 ;; Returns a symbol telling how TeX would treat
493 ;; the whitespace we are looking at: null, space, or par.
494 (let ((category 'null)
495 (not-finished t))
496 (skip-chars-backward " \t\n\f" backward-limit)
497 (while not-finished
498 (cond ((looking-at "[ \t]+")
499 (goto-char (match-end 0))
500 (if (eql category 'null)
501 (setq category 'space)))
502 ((looking-at "\n")
503 (cond ((eql category 'newline)
504 (setq category 'par)
505 (setq not-finished nil))
506 (t
507 (setq category 'newline) ;a strictly internal state
508 (goto-char (match-end 0)))))
509 ((looking-at "\f+")
510 (setq category 'par)
511 (setq not-finished nil))
512 (t
513 (setq not-finished nil))))
514 (skip-chars-forward " \t\n\f")
515 (if (eql category 'newline)
516 'space ;TeX doesn't distinguish
517 category)))
518
519(defun tex-insert-quote (arg)
520 "Insert the appropriate quote marks for TeX.
08348502
RS
521Inserts the value of `tex-open-quote' (normally ``) or `tex-close-quote'
522\(normally '') depending on the context. With prefix argument, always
869bff31 523inserts \" characters."
528415e7 524 (interactive "*P")
869bff31 525 (if arg
526 (self-insert-command (prefix-numeric-value arg))
527 (insert
528 (cond ((or (bobp)
529 (save-excursion
530 (forward-char -1)
531 (looking-at "\\s(\\|\\s \\|\\s>")))
532 tex-open-quote)
533 ((= (preceding-char) ?\\)
534 ?\")
535 (t
536 tex-close-quote)))))
537
538(defun validate-tex-buffer ()
8241d7b9 539 "Check current buffer for paragraphs containing mismatched $s.
bbd93e41
RS
540Their positions are recorded in the buffer `*Occur*'.
541To find a particular invalidity from `*Occur*',
542switch to to that buffer and type C-c C-c on the line
543for the invalidity you want to see."
869bff31 544 (interactive)
bbd93e41
RS
545 (let ((buffer (current-buffer))
546 (prevpos (point-min))
547 (linenum nil))
548 (with-output-to-temp-buffer "*Occur*"
549 (princ "Mismatches:\n")
550 (save-excursion
551 (set-buffer standard-output)
552 (occur-mode)
553 (setq occur-buffer buffer)
554 (setq occur-nlines 0)
555 (setq occur-pos-list nil))
556 (save-excursion
557 (goto-char (point-max))
869bff31 558 (while (and (not (input-pending-p)) (not (bobp)))
559 (let ((end (point)))
bbd93e41 560 ;; Scan the previous paragraph for invalidities.
869bff31 561 (search-backward "\n\n" nil 'move)
562 (or (tex-validate-region (point) end)
bbd93e41
RS
563 (let* ((end (save-excursion (forward-line 1) (point)))
564 start tem)
565 (beginning-of-line)
566 (setq start (point))
567 ;; Keep track of line number as we scan,
568 ;; in a cumulative fashion.
569 (if linenum
570 (setq linenum (- linenum (count-lines prevpos (point))))
571 (setq linenum (1+ (count-lines 1 start))))
572 (setq prevpos (point))
573 ;; Mention this mismatch in *Occur*.
574 ;; Since we scan from end of buffer to beginning,
575 ;; add each mismatch at the beginning of *Occur*
576 ;; and at the beginning of occur-pos-list.
577 (save-excursion
578 (setq tem (point-marker))
579 (set-buffer standard-output)
580 (goto-char (point-min))
581 ;; Skip "Mismatches:" header line.
582 (forward-line 1)
583 (setq occur-pos-list (cons tem occur-pos-list))
584 (insert-buffer-substring buffer start end)
585 (forward-char (- start end))
586 (insert (format "%3d: " linenum))))))))
587 (save-excursion
588 (set-buffer standard-output)
589 (if (null occur-pos-list)
590 (insert "None!\n"))
591 (if (interactive-p)
592 (message "%d mismatches found" (length occur-pos-list)))))))
869bff31 593
594(defun tex-validate-region (start end)
595 "Check for mismatched braces or $'s in region.
596Returns t if no mismatches. Returns nil and moves point to suspect
597area if a mismatch is found."
598 (interactive "r")
599 (let ((failure-point nil) (max-possible-sexps (- end start)))
600 (save-excursion
601 (condition-case ()
602 (save-restriction
603 (narrow-to-region start end)
604 (goto-char start)
605 (while (< 0 (setq max-possible-sexps (1- max-possible-sexps)))
606 (forward-sexp 1)))
607 (error
608 (setq failure-point (point)))))
609 (if failure-point
610 (progn
611 (goto-char failure-point)
612 nil)
613 t)))
614
615(defun tex-terminate-paragraph (inhibit-validation)
616 "Insert two newlines, breaking a paragraph for TeX.
617Check for mismatched braces/$'s in paragraph being terminated.
618A prefix arg inhibits the checking."
528415e7 619 (interactive "*P")
869bff31 620 (or inhibit-validation
621 (save-excursion
622 (tex-validate-region
623 (save-excursion
624 (search-backward "\n\n" nil 'move)
625 (point))
626 (point)))
627 (message "Paragraph being closed appears to contain a mismatch"))
628 (insert "\n\n"))
629
630(defun tex-insert-braces ()
631 "Make a pair of braces and be poised to type inside of them."
528415e7 632 (interactive "*")
869bff31 633 (insert ?\{)
634 (save-excursion
635 (insert ?})))
636
637;;; Like tex-insert-braces, but for LaTeX.
638(defun tex-latex-block (name)
639 "Creates a matching pair of lines \\begin{NAME} and \\end{NAME} at point.
640Puts point on a blank line between them."
528415e7
RS
641 (interactive
642 (prog2
643 (barf-if-buffer-read-only)
644 (list
645 (completing-read "LaTeX block name: "
646 (mapcar 'list
647 (append standard-latex-block-names
648 latex-block-names))))))
869bff31 649 (let ((col (current-column)))
650 (insert (format "\\begin{%s}\n" name))
651 (indent-to col)
652 (save-excursion
653 (insert ?\n)
654 (indent-to col)
655 (insert-string (format "\\end{%s}" name))
656 (if (eobp) (insert ?\n)))))
657
658(defun tex-last-unended-begin ()
659 "Leave point at the beginning of the last \\begin{...} that is unended."
660 (while (and (re-search-backward "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)")
661 (looking-at "\\\\end{"))
662 (tex-last-unended-begin)))
663
664(defun tex-close-latex-block ()
665 "Creates an \\end{...} to match the last unclosed \\begin{...}."
666 (interactive "*")
667 (let ((new-line-needed (bolp))
668 text indentation)
669 (save-excursion
528415e7 670 (condition-case nil
869bff31 671 (tex-last-unended-begin)
672 (error (error "Couldn't find unended \\begin")))
673 (setq indentation (current-column))
674 (re-search-forward "\\\\begin\\(\\s *{[^}\n]*}\\)")
675 (setq text (buffer-substring (match-beginning 1) (match-end 1))))
676 (indent-to indentation)
677 (insert "\\end" text)
678 (if new-line-needed (insert ?\n))))
679\f
2f3067de
ER
680(defun tex-compilation-parse-errors ()
681 "Parse the current buffer as error messages.
682This makes a list of error descriptors, compilation-error-list.
683For each source-file, line-number pair in the buffer,
684the source file is read in, and the text location is saved in
8241d7b9 685compilation-error-list. The function `next-error', assigned to
2f3067de
ER
686\\[next-error], takes the next error off the list and visits its location.
687
688This function works on TeX compilations only. It is necessary for
689that purpose, since TeX does not put file names on the same line as
690line numbers for the errors."
691 (setq compilation-error-list nil)
692 (message "Parsing error messages...")
693 (modify-syntax-entry ?\{ "_")
694 (modify-syntax-entry ?\} "_")
695 (modify-syntax-entry ?\[ "_")
696 (modify-syntax-entry ?\] "_")
2f3067de
ER
697 (let (text-buffer
698 last-filename last-linenum)
699 ;; Don't reparse messages already seen at last parse.
700 (goto-char compilation-parsing-end)
701 ;; Don't parse the first two lines as error messages.
702 ;; This matters for grep.
703 (if (bobp)
704 (forward-line 2))
8241d7b9 705 (while (re-search-forward "^l\.[0-9]+ " nil t)
2f3067de
ER
706 (let (linenum filename
707 error-marker text-marker)
708 ;; Extract file name and line number from error message.
709 ;; Line number is 2 away from beginning of line: "l.23"
710 (beginning-of-line)
711 (goto-char (+ (point) 2))
712 (setq linenum (read (current-buffer)))
713 ;; The file is the one that was opened last and is still open.
714 ;; We need to find the last open parenthesis.
715 (insert ?\))
716 (backward-sexp)
717 (forward-char)
8241d7b9 718 (setq filename (current-word))
2f3067de
ER
719 ;; Locate the erring file and line.
720 (if (and (equal filename last-filename)
721 (= linenum last-linenum))
722 nil
723 (skip-chars-backward "^(")
724 (backward-char)
725 (forward-sexp)
726 (backward-delete-char 1)
727 (setq error-marker (point-marker))
728 ;; text-buffer gets the buffer containing this error's file.
729 (if (not (equal filename last-filename))
730 (setq text-buffer
731 (and (file-exists-p (setq last-filename filename))
732 (find-file-noselect filename))
733 last-linenum 0))
734 (if text-buffer
735 ;; Go to that buffer and find the erring line.
736 (save-excursion
737 (set-buffer text-buffer)
738 (if (zerop last-linenum)
739 (progn
740 (goto-char 1)
741 (setq last-linenum 1)))
742 (forward-line (- linenum last-linenum))
743 (setq last-linenum linenum)
744 (setq text-marker (point-marker))
745 (setq compilation-error-list
746 (cons (list error-marker text-marker)
747 compilation-error-list)))))
748 (forward-line 1)))
749 (setq compilation-parsing-end (point-max)))
750 (message "Parsing error messages...done")
751 (setq compilation-error-list (nreverse compilation-error-list)))
752\f
869bff31 753;;; Invoking TeX in an inferior shell.
754
755;;; Why use a shell instead of running TeX directly? Because if TeX
756;;; gets stuck, the user can switch to the shell window and type at it.
757
758;;; The utility functions:
759
760(defun tex-start-shell ()
761 (save-excursion
528415e7
RS
762 (set-buffer
763 (make-comint
764 "tex-shell"
765 (or tex-shell-file-name (getenv "ESHELL") (getenv "SHELL") "/bin/sh")
4cdc1d4b 766 nil))
528415e7
RS
767 (let ((proc (get-process "tex-shell")))
768 (set-process-sentinel proc 'tex-shell-sentinel)
769 (process-kill-without-query proc)
770 (setq tex-shell-map (copy-keymap comint-mode-map))
771 (tex-define-common-keys tex-shell-map)
772 (use-local-map tex-shell-map)
773 (run-hooks 'tex-shell-hook)
774 (while (zerop (buffer-size))
775 (sleep-for 1)))))
776
777(defun tex-shell-sentinel (proc msg)
778 (cond ((null (buffer-name (process-buffer proc)))
779 ;; buffer killed
780 (set-process-buffer proc nil)
781 (tex-delete-last-temp-files))
782 ((memq (process-status proc) '(signal exit))
783 (tex-delete-last-temp-files))))
784
785(defun tex-set-buffer-directory (buffer directory)
869bff31 786 "Set BUFFER's default directory to be DIRECTORY."
787 (setq directory (file-name-as-directory (expand-file-name directory)))
788 (if (not (file-directory-p directory))
789 (error "%s is not a directory" directory)
790 (save-excursion
791 (set-buffer buffer)
792 (setq default-directory directory))))
793
30803a05
RS
794(defvar tex-send-command-modified-tick 0)
795(make-variable-buffer-local 'tex-send-command-modified-tick)
796
528415e7 797(defun tex-send-command (command &optional file background)
4cdc1d4b 798 "Send COMMAND to TeX shell process, substituting optional FILE for *.
8241d7b9
ER
799Do this in background if optional BACKGROUND is t. If COMMAND has no *,
800FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no
801substitution will be made in COMMAND. COMMAND can be any expression that
802evaluates to a command string."
528415e7
RS
803 (save-excursion
804 (let* ((cmd (eval command))
4cdc1d4b 805 (proc (get-process "tex-shell"))
4f45adda 806 (star (string-match "\\*" cmd))
4cdc1d4b
RS
807 (string
808 (concat
809 (if file
810 (if star (concat (substring cmd 0 star)
811 file (substring cmd (1+ star)))
812 (concat cmd " " file))
813 cmd)
814 (if background "&" ""))))
30803a05
RS
815 ;; If text is unchanged since previous tex-send-command,
816 ;; we haven't got any output. So wait for output now.
817 (if (= (buffer-modified-tick) tex-send-command-modified-tick)
818 (accept-process-output proc))
4cdc1d4b
RS
819 (set-buffer (process-buffer proc))
820 (goto-char (process-mark proc))
821 (insert string)
30803a05
RS
822 (comint-send-input)
823 (setq tex-send-command-modified-tick (buffer-modified-tick)))))
528415e7
RS
824
825(defun tex-delete-last-temp-files ()
826 "Delete any junk files from last temp file."
827 (if tex-last-temp-file
828 (let* ((dir (file-name-directory tex-last-temp-file))
829 (list (file-name-all-completions
830 (file-name-nondirectory tex-last-temp-file) dir)))
831 (while list
832 (delete-file (concat dir (car list)))
833 (setq list (cdr list))))))
834
99621a14 835(add-hook 'kill-emacs-hook 'tex-delete-last-temp-files)
869bff31 836
528415e7 837;;; The commands:
869bff31 838
839(defun tex-region (beg end)
840 "Run TeX on the current region, via a temporary file.
841The file's name comes from the variable `tex-zap-file' and the
842variable `tex-directory' says where to put it.
843
844If the buffer has a header, the header is given to TeX before the
845region itself. The buffer's header is all lines between the strings
846defined by `tex-start-of-header' and `tex-end-of-header' inclusive.
847The header must start in the first 100 lines of the buffer.
848
849The value of `tex-trailer' is given to TeX as input after the region.
850
851The value of `tex-command' specifies the command to use to run TeX."
852 (interactive "r")
853 (if (tex-shell-running)
854 (tex-kill-job)
855 (tex-start-shell))
856 (or tex-zap-file
857 (setq tex-zap-file (tex-generate-zap-file-name)))
528415e7
RS
858 (let* ((temp-buffer (get-buffer-create " TeX-Output-Buffer"))
859 ; Temp file will be written and TeX will be run in zap-directory.
860 ; If the TEXINPUTS file has relative directories or if the region has
861 ; \input of files, this must be the same directory as the file for
862 ; TeX to access the correct inputs. That's why it's safest if
863 ; tex-directory is ".".
864 (zap-directory
865 (file-name-as-directory (expand-file-name tex-directory)))
866 (tex-out-file (concat zap-directory tex-zap-file)))
867 (tex-delete-last-temp-files)
869bff31 868 ;; Write the new temp file.
869 (save-excursion
870 (save-restriction
871 (widen)
872 (goto-char (point-min))
873 (forward-line 100)
874 (let ((search-end (point))
875 (hbeg (point-min)) (hend (point-min))
876 (default-directory zap-directory))
877 (goto-char (point-min))
878 ;; Initialize the temp file with either the header or nothing
879 (if (search-forward tex-start-of-header search-end t)
880 (progn
881 (beginning-of-line)
882 (setq hbeg (point)) ;mark beginning of header
883 (if (search-forward tex-end-of-header nil t)
884 (progn (forward-line 1)
885 (setq hend (point))) ;mark end of header
886 (setq hbeg (point-min))))) ;no header
528415e7
RS
887 (write-region (min hbeg beg) hend
888 (concat tex-out-file ".tex") nil nil)
889 (write-region (max beg hend) end (concat tex-out-file ".tex") t nil))
869bff31 890 (let ((local-tex-trailer tex-trailer))
891 (set-buffer temp-buffer)
892 (erase-buffer)
893 ;; make sure trailer isn't hidden by a comment
894 (insert-string "\n")
895 (if local-tex-trailer (insert-string local-tex-trailer))
528415e7
RS
896 (tex-set-buffer-directory temp-buffer zap-directory)
897 (write-region (point-min) (point-max)
898 (concat tex-out-file ".tex") t nil))))
899 ;; Record the file name to be deleted afterward.
900 (setq tex-last-temp-file tex-out-file)
901 (tex-send-command tex-shell-cd-command zap-directory)
902 (tex-send-command tex-command tex-out-file)
903 (setq tex-print-file tex-out-file)
904 (setq tex-last-buffer-texed (current-buffer))))
869bff31 905
906(defun tex-buffer ()
907 "Run TeX on current buffer. See \\[tex-region] for more information.
528415e7
RS
908Does not save the buffer, so it's useful for trying experimental versions.
909See \\[tex-file] for an alternative."
869bff31 910 (interactive)
911 (tex-region (point-min) (point-max)))
912
913(defun tex-file ()
914 "Prompt to save all buffers and run TeX (or LaTeX) on current buffer's file.
915This function is more useful than \\[tex-buffer] when you need the
916`.aux' file of LaTeX to have the correct name."
917 (interactive)
918 (let ((tex-out-file
919 (if (buffer-file-name)
920 (file-name-nondirectory (buffer-file-name))
921 (error "Buffer does not seem to be associated with any file")))
922 (file-dir (file-name-directory (buffer-file-name))))
7047ec77 923 (if tex-offer-save
99621a14 924 (save-some-buffers))
869bff31 925 (if (tex-shell-running)
926 (tex-kill-job)
927 (tex-start-shell))
528415e7
RS
928 (tex-send-command tex-shell-cd-command file-dir)
929 (tex-send-command tex-command tex-out-file))
869bff31 930 (setq tex-last-buffer-texed (current-buffer))
528415e7 931 (setq tex-print-file (buffer-file-name)))
869bff31 932
933(defun tex-generate-zap-file-name ()
934 "Generate a unique name suitable for use as a file name."
935 ;; Include the shell process number and host name
936 ;; in case there are multiple shells (for same or different user).
937 (format "#tz%d%s"
938 (process-id (get-buffer-process "*tex-shell*"))
939 (tex-strip-dots (system-name))))
940
941(defun tex-strip-dots (s)
942 (setq s (copy-sequence s))
943 (while (string-match "\\." s)
944 (aset s (match-beginning 0) ?-))
945 s)
946
947;; This will perhaps be useful for modifying TEXINPUTS.
948;; Expand each file name, separated by colons, in the string S.
949(defun tex-expand-files (s)
950 (let (elts (start 0))
951 (while (string-match ":" s start)
952 (setq elts (cons (substring s start (match-beginning 0)) elts))
953 (setq start (match-end 0)))
954 (or (= start 0)
955 (setq elts (cons (substring s start) elts)))
956 (mapconcat 'expand-file-name (nreverse elts) ":")))
957
958(defun tex-shell-running ()
959 (and (get-process "tex-shell")
960 (eq (process-status (get-process "tex-shell")) 'run)))
961
962(defun tex-kill-job ()
963 "Kill the currently running TeX job."
964 (interactive)
528415e7 965 (quit-process (get-process "tex-shell") t))
869bff31 966
967(defun tex-recenter-output-buffer (linenum)
968 "Redisplay buffer of TeX job output so that most recent output can be seen.
969The last line of the buffer is displayed on
970line LINE of the window, or centered if LINE is nil."
971 (interactive "P")
972 (let ((tex-shell (get-buffer "*tex-shell*"))
973 (old-buffer (current-buffer)))
974 (if (null tex-shell)
975 (message "No TeX output buffer")
976 (pop-to-buffer tex-shell)
977 (bury-buffer tex-shell)
978 (goto-char (point-max))
979 (recenter (if linenum
980 (prefix-numeric-value linenum)
981 (/ (window-height) 2)))
528415e7 982 (pop-to-buffer old-buffer))))
869bff31 983
528415e7 984(defun tex-print (&optional alt)
869bff31 985 "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file].
1433a222
CZ
986Runs the shell command defined by `tex-dvi-print-command'. If prefix argument
987is provided, use the alternative command, `tex-alt-dvi-print-command'."
528415e7 988 (interactive "P")
869bff31 989 (let ((print-file-name-dvi (tex-append tex-print-file ".dvi"))
990 test-name)
991 (if (and (not (equal (current-buffer) tex-last-buffer-texed))
992 (file-newer-than-file-p
993 (setq test-name (tex-append (buffer-file-name) ".dvi"))
528415e7 994 print-file-name-dvi))
869bff31 995 (setq print-file-name-dvi test-name))
528415e7
RS
996 (if (not (file-exists-p print-file-name-dvi))
997 (error "No appropriate `.dvi' file could be found")
998 (tex-send-command
999 (if alt tex-alt-dvi-print-command tex-dvi-print-command)
1000 print-file-name-dvi t))))
869bff31 1001
cf6d6e8a
RS
1002(defun tex-alt-print ()
1003 "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file].
1004Runs the shell command defined by tex-alt-dvi-print-command."
1005 (interactive)
1006 (tex-print t))
1007
869bff31 1008(defun tex-view ()
1009 "Preview the last `.dvi' file made by running TeX under Emacs.
1010This means, made using \\[tex-region], \\[tex-buffer] or \\[tex-file].
1011The variable `tex-dvi-view-command' specifies the shell command for preview."
1012 (interactive)
1013 (let ((tex-dvi-print-command tex-dvi-view-command))
1014 (tex-print)))
1015
1016(defun tex-append (file-name suffix)
1017 "Append to FILENAME the suffix SUFFIX, using same algorithm TeX uses.
cf6d6e8a 1018Pascal-based TeX scans for the first period, C TeX uses the last.
869bff31 1019No period is retained immediately before SUFFIX,
1020so normally SUFFIX starts with one."
1021 (if (stringp file-name)
cf6d6e8a
RS
1022 (let ((file (file-name-nondirectory file-name))
1023 trial-name)
1024 ;; try spliting on first period
1025 (setq trial-name
1026 (concat (file-name-directory file-name)
1027 (substring file 0
1028 (string-match "\\." file))
1029 suffix))
1030 (if (or (file-exists-p trial-name)
1031 (file-exists-p (concat trial-name ".aux"))) ;for BibTeX files
1032 trial-name
1033 ;; not found, so split on last period
1034 (concat (file-name-directory file-name)
1035 (substring file 0
1036 (string-match "\\.[^.]*$" file))
1037 suffix)))
869bff31 1038 " "))
1039
1040(defun tex-show-print-queue ()
1041 "Show the print queue that \\[tex-print] put your job on.
1433a222 1042Runs the shell command defined by `tex-show-queue-command'."
869bff31 1043 (interactive)
1044 (if (tex-shell-running)
1045 (tex-kill-job)
1046 (tex-start-shell))
528415e7 1047 (tex-send-command tex-show-queue-command))
869bff31 1048
1049(defun tex-bibtex-file ()
1050 "Run BibTeX on the current buffer's file."
1051 (interactive)
1052 (if (tex-shell-running)
1053 (tex-kill-job)
1054 (tex-start-shell))
1055 (let ((tex-out-file
1056 (tex-append (file-name-nondirectory (buffer-file-name)) ""))
1057 (file-dir (file-name-directory (buffer-file-name))))
528415e7 1058 (tex-send-command tex-shell-cd-command file-dir)
8241d7b9 1059 (tex-send-command tex-bibtex-command tex-out-file)))
528415e7
RS
1060
1061(run-hooks 'tex-mode-load-hook)
869bff31 1062
49116ac0
JB
1063(provide 'tex-mode)
1064
d501f516 1065;;; tex-mode.el ends here
99621a14 1066