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