(tags-find-table-in-list): Only recurse if (tags-included-tables) returns
[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
a0e9c22a 29(require 'shell)
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")
ab2c9f54
RS
385 ;; A line containing just $$ is treated as a paragraph separator.
386 ;; A line starting with $$ starts a paragraph,
387 ;; but does not separate paragraphs if it has more stuff on it.
388 (setq paragraph-start "^[ \t]*$\\|^[\f%]\\|^[ \t]*\\$\\$\\|\
389^\\\\begin\\>\\|^\\\\label\\>\\|^\\\\end\\>\\|^\\\\\\[\\|\
390^\\\\chapter\\>\\|^\\\\section\\>\\|\
391^\\\\subsection\\>\\|^\\\\subsubsection\\>\\|\
392^\\\\paragraph\\>\\|^\\\\subparagraph\\>\\|\
393^\\\\item\\>\\|^\\\\bibitem\\>\\|^\\\\newline\\>\\|^\\\\noindent\\>\\|\
394^\\\\[a-z]*space\\>\\|^\\\\[a-z]*skip\\>\\|\
395^\\\\newpage\\>\\|^\\\\[a-z]*page\\|^\\\\footnote\\>\\|\
396^\\\\marginpar\\>\\|^\\\\parbox\\>\\|^\\\\caption\\>")
397 (setq paragraph-separate "^[ \t]*$\\|^[\f\\\\%]\\|^[ \t]*\\$\\$[ \t]*$\\|\
398^\\\\begin\\>\\|^\\\\label\\>\\|^\\\\end\\>\\|^\\\\\\[\\|\
399^\\\\chapter\\>\\|^\\\\section\\>\\|\
400^\\\\subsection\\>\\|^\\\\subsubsection\\>\\|\
401^\\\\paragraph\\>\\|^\\\\subparagraph\\>\\|\
402^\\\\item[ \t]*$\\|^\\\\bibitem[ \t]*$\\|^\\\\newline[ \t]*$\\|^\\\\noindent[ \t]*$\\|\
403^\\\\[a-z]*space[ \t]*$\\|^\\\\[a-z]*skip[ \t]*$\\|\
404^\\\\newpage[ \t]*$\\|^\\\\[a-z]*page[a-z]*[ \t]*$\\|^\\\\footnote[ \t]*$\\|\
405^\\\\marginpar[ \t]*$\\|^\\\\parbox[ \t]*$\\|^\\\\caption[ \t]*$")
869bff31 406 (run-hooks 'text-mode-hook 'tex-mode-hook 'latex-mode-hook))
407
bd2f2323 408;;;###autoload
869bff31 409(defun slitex-mode ()
410 "Major mode for editing files of input for SliTeX.
411Makes $ and } display the characters they match.
412Makes \" insert `` when it seems to be the beginning of a quotation,
413and '' when it appears to be the end; it inserts \" only after a \\.
414
415Use \\[tex-region] to run SliTeX on the current region, plus the preamble
416copied from the top of the file (containing \\documentstyle, etc.),
417running SliTeX under a special subshell. \\[tex-buffer] does the whole buffer.
418\\[tex-file] saves the buffer and then processes the file.
419\\[tex-print] prints the .dvi file made by any of these.
420\\[tex-view] previews the .dvi file made by any of these.
421\\[tex-bibtex-file] runs bibtex on the file of the current buffer.
422
423Use \\[validate-tex-buffer] to check buffer for paragraphs containing
424mismatched $'s or braces.
425
426Special commands:
427\\{tex-mode-map}
428
429Mode variables:
430slitex-run-command
431 Command string used by \\[tex-region] or \\[tex-buffer].
432tex-directory
433 Directory in which to create temporary files for SliTeX jobs
434 run by \\[tex-region] or \\[tex-buffer].
435tex-dvi-print-command
436 Command string used by \\[tex-print] to print a .dvi file.
528415e7
RS
437tex-alt-dvi-print-command
438 Alternative command string used by \\[tex-print] (when given a prefix
439 argument) to print a .dvi file.
869bff31 440tex-dvi-view-command
441 Command string used by \\[tex-view] to preview a .dvi file.
442tex-show-queue-command
443 Command string used by \\[tex-show-print-queue] to show the print
444 queue that \\[tex-print] put your job on.
445
8241d7b9
ER
446Entering SliTeX mode calls the value of `text-mode-hook', then the value of
447`tex-mode-hook', then the value of `latex-mode-hook', and then the value of
448`slitex-mode-hook'. When the special subshell is initiated, the value of
449`tex-shell-hook' is called."
869bff31 450 (interactive)
451 (tex-common-initialization)
452 (setq mode-name "SliTeX")
453 (setq major-mode 'slitex-mode)
454 (setq tex-command slitex-run-command)
455 (setq tex-start-of-header "\\documentstyle{slides}")
456 (setq tex-end-of-header "\\begin{document}")
457 (setq tex-trailer "\\end{document}\n")
ab2c9f54
RS
458 ;; A line containing just $$ is treated as a paragraph separator.
459 ;; A line starting with $$ starts a paragraph,
460 ;; but does not separate paragraphs if it has more stuff on it.
461 (setq paragraph-start "^[ \t]*$\\|^[\f%]\\|^[ \t]*\\$\\$\\|\
462^\\\\begin\\>\\|^\\\\label\\>\\|^\\\\end\\>\\|^\\\\\\[\\|\
463^\\\\chapter\\>\\|^\\\\section\\>\\|\
464^\\\\subsection\\>\\|^\\\\subsubsection\\>\\|\
465^\\\\paragraph\\>\\|^\\\\subparagraph\\>\\|\
466^\\\\item\\>\\|^\\\\bibitem\\>\\|^\\\\newline\\>\\|^\\\\noindent\\>\\|\
467^\\\\[a-z]*space\\>\\|^\\\\[a-z]*skip\\>\\|\
468^\\\\newpage\\>\\|^\\\\[a-z]*page\\|^\\\\footnote\\>\\|\
469^\\\\marginpar\\>\\|^\\\\parbox\\>\\|^\\\\caption\\>")
470 (setq paragraph-separate "^[ \t]*$\\|^[\f\\\\%]\\|^[ \t]*\\$\\$[ \t]*$\\|\
471^\\\\begin\\>\\|^\\\\label\\>\\|^\\\\end\\>\\|^\\\\\\[\\|\
472^\\\\chapter\\>\\|^\\\\section\\>\\|\
473^\\\\subsection\\>\\|^\\\\subsubsection\\>\\|\
474^\\\\paragraph\\>\\|^\\\\subparagraph\\>\\|\
475^\\\\item[ \t]*$\\|^\\\\bibitem[ \t]*$\\|^\\\\newline[ \t]*$\\|^\\\\noindent[ \t]*$\\|\
476^\\\\[a-z]*space[ \t]*$\\|^\\\\[a-z]*skip[ \t]*$\\|\
477^\\\\newpage[ \t]*$\\|^\\\\[a-z]*page[a-z]*[ \t]*$\\|^\\\\footnote[ \t]*$\\|\
478^\\\\marginpar[ \t]*$\\|^\\\\parbox[ \t]*$\\|^\\\\caption[ \t]*$")
869bff31 479 (run-hooks
480 'text-mode-hook 'tex-mode-hook 'latex-mode-hook 'slitex-mode-hook))
481
482(defun tex-common-initialization ()
483 (kill-all-local-variables)
484 (use-local-map tex-mode-map)
485 (setq local-abbrev-table text-mode-abbrev-table)
486 (if (null tex-mode-syntax-table)
487 (let ((char 0))
488 (setq tex-mode-syntax-table (make-syntax-table))
489 (set-syntax-table tex-mode-syntax-table)
490 (while (< char ? )
491 (modify-syntax-entry char ".")
492 (setq char (1+ char)))
493 (modify-syntax-entry ?\C-@ "w")
494 (modify-syntax-entry ?\t " ")
495 (modify-syntax-entry ?\n ">")
496 (modify-syntax-entry ?\f ">")
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 ?@ "_")
504 (modify-syntax-entry ?~ " ")
505 (modify-syntax-entry ?' "w"))
506 (set-syntax-table tex-mode-syntax-table))
507 (make-local-variable 'paragraph-start)
64db2461 508 ;; A line containing just $$ is treated as a paragraph separator.
ab2c9f54 509 (setq paragraph-start "^[ \t]*$\\|^[\f\\\\%]\\|^[ \t]*\\$\\$")
869bff31 510 (make-local-variable 'paragraph-separate)
ab2c9f54
RS
511 ;; A line starting with $$ starts a paragraph,
512 ;; but does not separate paragraphs if it has more stuff on it.
513 (setq paragraph-separate "^[ \t]*$\\|^[\f\\\\%]\\|^[ \t]*\\$\\$[ \t]*$")
869bff31 514 (make-local-variable 'comment-start)
515 (setq comment-start "%")
516 (make-local-variable 'comment-start-skip)
517 (setq comment-start-skip "\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
e41b2db1
ER
518 (make-local-variable 'comment-indent-function)
519 (setq comment-indent-function 'tex-comment-indent)
2e0b53ad
RS
520 (make-local-variable 'parse-sexp-ignore-comments)
521 (setq parse-sexp-ignore-comments t)
869bff31 522 (make-local-variable 'compare-windows-whitespace)
523 (setq compare-windows-whitespace 'tex-categorize-whitespace)
524 (make-local-variable 'tex-command)
525 (make-local-variable 'tex-start-of-header)
526 (make-local-variable 'tex-end-of-header)
527 (make-local-variable 'tex-trailer))
528
529(defun tex-comment-indent ()
530 (if (looking-at "%%%")
531 (current-column)
532 (skip-chars-backward " \t")
533 (max (if (bolp) 0 (1+ (current-column)))
534 comment-column)))
535
536(defun tex-categorize-whitespace (backward-limit)
537 ;; compare-windows-whitespace is set to this.
538 ;; This is basically a finite-state machine.
539 ;; Returns a symbol telling how TeX would treat
540 ;; the whitespace we are looking at: null, space, or par.
541 (let ((category 'null)
542 (not-finished t))
543 (skip-chars-backward " \t\n\f" backward-limit)
544 (while not-finished
545 (cond ((looking-at "[ \t]+")
546 (goto-char (match-end 0))
547 (if (eql category 'null)
548 (setq category 'space)))
549 ((looking-at "\n")
550 (cond ((eql category 'newline)
551 (setq category 'par)
552 (setq not-finished nil))
553 (t
554 (setq category 'newline) ;a strictly internal state
555 (goto-char (match-end 0)))))
556 ((looking-at "\f+")
557 (setq category 'par)
558 (setq not-finished nil))
559 (t
560 (setq not-finished nil))))
561 (skip-chars-forward " \t\n\f")
562 (if (eql category 'newline)
563 'space ;TeX doesn't distinguish
564 category)))
565
566(defun tex-insert-quote (arg)
567 "Insert the appropriate quote marks for TeX.
08348502
RS
568Inserts the value of `tex-open-quote' (normally ``) or `tex-close-quote'
569\(normally '') depending on the context. With prefix argument, always
869bff31 570inserts \" characters."
528415e7 571 (interactive "*P")
869bff31 572 (if arg
573 (self-insert-command (prefix-numeric-value arg))
574 (insert
575 (cond ((or (bobp)
576 (save-excursion
577 (forward-char -1)
578 (looking-at "\\s(\\|\\s \\|\\s>")))
579 tex-open-quote)
580 ((= (preceding-char) ?\\)
581 ?\")
582 (t
583 tex-close-quote)))))
584
585(defun validate-tex-buffer ()
8241d7b9 586 "Check current buffer for paragraphs containing mismatched $s.
bbd93e41
RS
587Their positions are recorded in the buffer `*Occur*'.
588To find a particular invalidity from `*Occur*',
589switch to to that buffer and type C-c C-c on the line
590for the invalidity you want to see."
869bff31 591 (interactive)
bbd93e41
RS
592 (let ((buffer (current-buffer))
593 (prevpos (point-min))
594 (linenum nil))
595 (with-output-to-temp-buffer "*Occur*"
596 (princ "Mismatches:\n")
597 (save-excursion
598 (set-buffer standard-output)
599 (occur-mode)
600 (setq occur-buffer buffer)
601 (setq occur-nlines 0)
602 (setq occur-pos-list nil))
603 (save-excursion
604 (goto-char (point-max))
869bff31 605 (while (and (not (input-pending-p)) (not (bobp)))
606 (let ((end (point)))
bbd93e41 607 ;; Scan the previous paragraph for invalidities.
869bff31 608 (search-backward "\n\n" nil 'move)
609 (or (tex-validate-region (point) end)
bbd93e41
RS
610 (let* ((end (save-excursion (forward-line 1) (point)))
611 start tem)
612 (beginning-of-line)
613 (setq start (point))
614 ;; Keep track of line number as we scan,
615 ;; in a cumulative fashion.
616 (if linenum
617 (setq linenum (- linenum (count-lines prevpos (point))))
618 (setq linenum (1+ (count-lines 1 start))))
619 (setq prevpos (point))
620 ;; Mention this mismatch in *Occur*.
621 ;; Since we scan from end of buffer to beginning,
622 ;; add each mismatch at the beginning of *Occur*
623 ;; and at the beginning of occur-pos-list.
624 (save-excursion
625 (setq tem (point-marker))
626 (set-buffer standard-output)
627 (goto-char (point-min))
628 ;; Skip "Mismatches:" header line.
629 (forward-line 1)
630 (setq occur-pos-list (cons tem occur-pos-list))
631 (insert-buffer-substring buffer start end)
632 (forward-char (- start end))
633 (insert (format "%3d: " linenum))))))))
634 (save-excursion
635 (set-buffer standard-output)
636 (if (null occur-pos-list)
637 (insert "None!\n"))
638 (if (interactive-p)
639 (message "%d mismatches found" (length occur-pos-list)))))))
869bff31 640
641(defun tex-validate-region (start end)
642 "Check for mismatched braces or $'s in region.
643Returns t if no mismatches. Returns nil and moves point to suspect
644area if a mismatch is found."
645 (interactive "r")
646 (let ((failure-point nil) (max-possible-sexps (- end start)))
647 (save-excursion
648 (condition-case ()
649 (save-restriction
650 (narrow-to-region start end)
651 (goto-char start)
652 (while (< 0 (setq max-possible-sexps (1- max-possible-sexps)))
653 (forward-sexp 1)))
654 (error
655 (setq failure-point (point)))))
656 (if failure-point
657 (progn
658 (goto-char failure-point)
659 nil)
660 t)))
661
662(defun tex-terminate-paragraph (inhibit-validation)
663 "Insert two newlines, breaking a paragraph for TeX.
664Check for mismatched braces/$'s in paragraph being terminated.
665A prefix arg inhibits the checking."
528415e7 666 (interactive "*P")
869bff31 667 (or inhibit-validation
668 (save-excursion
669 (tex-validate-region
670 (save-excursion
671 (search-backward "\n\n" nil 'move)
672 (point))
673 (point)))
674 (message "Paragraph being closed appears to contain a mismatch"))
675 (insert "\n\n"))
676
677(defun tex-insert-braces ()
678 "Make a pair of braces and be poised to type inside of them."
528415e7 679 (interactive "*")
869bff31 680 (insert ?\{)
681 (save-excursion
682 (insert ?})))
683
684;;; Like tex-insert-braces, but for LaTeX.
685(defun tex-latex-block (name)
686 "Creates a matching pair of lines \\begin{NAME} and \\end{NAME} at point.
687Puts point on a blank line between them."
528415e7
RS
688 (interactive
689 (prog2
690 (barf-if-buffer-read-only)
691 (list
692 (completing-read "LaTeX block name: "
693 (mapcar 'list
694 (append standard-latex-block-names
695 latex-block-names))))))
869bff31 696 (let ((col (current-column)))
697 (insert (format "\\begin{%s}\n" name))
698 (indent-to col)
699 (save-excursion
700 (insert ?\n)
701 (indent-to col)
702 (insert-string (format "\\end{%s}" name))
703 (if (eobp) (insert ?\n)))))
704
705(defun tex-last-unended-begin ()
706 "Leave point at the beginning of the last \\begin{...} that is unended."
707 (while (and (re-search-backward "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)")
708 (looking-at "\\\\end{"))
709 (tex-last-unended-begin)))
710
711(defun tex-close-latex-block ()
712 "Creates an \\end{...} to match the last unclosed \\begin{...}."
713 (interactive "*")
714 (let ((new-line-needed (bolp))
715 text indentation)
716 (save-excursion
528415e7 717 (condition-case nil
869bff31 718 (tex-last-unended-begin)
719 (error (error "Couldn't find unended \\begin")))
720 (setq indentation (current-column))
721 (re-search-forward "\\\\begin\\(\\s *{[^}\n]*}\\)")
722 (setq text (buffer-substring (match-beginning 1) (match-end 1))))
723 (indent-to indentation)
724 (insert "\\end" text)
725 (if new-line-needed (insert ?\n))))
726\f
2f3067de
ER
727(defun tex-compilation-parse-errors ()
728 "Parse the current buffer as error messages.
729This makes a list of error descriptors, compilation-error-list.
730For each source-file, line-number pair in the buffer,
731the source file is read in, and the text location is saved in
8241d7b9 732compilation-error-list. The function `next-error', assigned to
2f3067de
ER
733\\[next-error], takes the next error off the list and visits its location.
734
735This function works on TeX compilations only. It is necessary for
736that purpose, since TeX does not put file names on the same line as
737line numbers for the errors."
738 (setq compilation-error-list nil)
739 (message "Parsing error messages...")
740 (modify-syntax-entry ?\{ "_")
741 (modify-syntax-entry ?\} "_")
742 (modify-syntax-entry ?\[ "_")
743 (modify-syntax-entry ?\] "_")
2f3067de
ER
744 (let (text-buffer
745 last-filename last-linenum)
746 ;; Don't reparse messages already seen at last parse.
747 (goto-char compilation-parsing-end)
748 ;; Don't parse the first two lines as error messages.
749 ;; This matters for grep.
750 (if (bobp)
751 (forward-line 2))
8241d7b9 752 (while (re-search-forward "^l\.[0-9]+ " nil t)
2f3067de
ER
753 (let (linenum filename
754 error-marker text-marker)
755 ;; Extract file name and line number from error message.
756 ;; Line number is 2 away from beginning of line: "l.23"
757 (beginning-of-line)
758 (goto-char (+ (point) 2))
759 (setq linenum (read (current-buffer)))
760 ;; The file is the one that was opened last and is still open.
761 ;; We need to find the last open parenthesis.
762 (insert ?\))
763 (backward-sexp)
764 (forward-char)
8241d7b9 765 (setq filename (current-word))
2f3067de
ER
766 ;; Locate the erring file and line.
767 (if (and (equal filename last-filename)
768 (= linenum last-linenum))
769 nil
770 (skip-chars-backward "^(")
771 (backward-char)
772 (forward-sexp)
773 (backward-delete-char 1)
774 (setq error-marker (point-marker))
775 ;; text-buffer gets the buffer containing this error's file.
776 (if (not (equal filename last-filename))
777 (setq text-buffer
778 (and (file-exists-p (setq last-filename filename))
779 (find-file-noselect filename))
780 last-linenum 0))
781 (if text-buffer
782 ;; Go to that buffer and find the erring line.
783 (save-excursion
784 (set-buffer text-buffer)
785 (if (zerop last-linenum)
786 (progn
787 (goto-char 1)
788 (setq last-linenum 1)))
789 (forward-line (- linenum last-linenum))
790 (setq last-linenum linenum)
791 (setq text-marker (point-marker))
792 (setq compilation-error-list
793 (cons (list error-marker text-marker)
794 compilation-error-list)))))
795 (forward-line 1)))
796 (setq compilation-parsing-end (point-max)))
797 (message "Parsing error messages...done")
798 (setq compilation-error-list (nreverse compilation-error-list)))
799\f
869bff31 800;;; Invoking TeX in an inferior shell.
801
802;;; Why use a shell instead of running TeX directly? Because if TeX
803;;; gets stuck, the user can switch to the shell window and type at it.
804
805;;; The utility functions:
806
807(defun tex-start-shell ()
808 (save-excursion
528415e7
RS
809 (set-buffer
810 (make-comint
811 "tex-shell"
812 (or tex-shell-file-name (getenv "ESHELL") (getenv "SHELL") "/bin/sh")
4cdc1d4b 813 nil))
528415e7
RS
814 (let ((proc (get-process "tex-shell")))
815 (set-process-sentinel proc 'tex-shell-sentinel)
816 (process-kill-without-query proc)
a0e9c22a 817 (setq tex-shell-map (copy-keymap shell-mode-map))
528415e7
RS
818 (tex-define-common-keys tex-shell-map)
819 (use-local-map tex-shell-map)
820 (run-hooks 'tex-shell-hook)
821 (while (zerop (buffer-size))
822 (sleep-for 1)))))
823
824(defun tex-shell-sentinel (proc msg)
825 (cond ((null (buffer-name (process-buffer proc)))
826 ;; buffer killed
827 (set-process-buffer proc nil)
828 (tex-delete-last-temp-files))
829 ((memq (process-status proc) '(signal exit))
830 (tex-delete-last-temp-files))))
831
832(defun tex-set-buffer-directory (buffer directory)
869bff31 833 "Set BUFFER's default directory to be DIRECTORY."
834 (setq directory (file-name-as-directory (expand-file-name directory)))
835 (if (not (file-directory-p directory))
836 (error "%s is not a directory" directory)
837 (save-excursion
838 (set-buffer buffer)
839 (setq default-directory directory))))
840
30803a05
RS
841(defvar tex-send-command-modified-tick 0)
842(make-variable-buffer-local 'tex-send-command-modified-tick)
843
528415e7 844(defun tex-send-command (command &optional file background)
4cdc1d4b 845 "Send COMMAND to TeX shell process, substituting optional FILE for *.
8241d7b9
ER
846Do this in background if optional BACKGROUND is t. If COMMAND has no *,
847FILE will be appended, preceded by a blank, to COMMAND. If FILE is nil, no
848substitution will be made in COMMAND. COMMAND can be any expression that
849evaluates to a command string."
528415e7
RS
850 (save-excursion
851 (let* ((cmd (eval command))
4cdc1d4b 852 (proc (get-process "tex-shell"))
64db2461 853 (buf (process-buffer proc))
4f45adda 854 (star (string-match "\\*" cmd))
4cdc1d4b
RS
855 (string
856 (concat
857 (if file
858 (if star (concat (substring cmd 0 star)
859 file (substring cmd (1+ star)))
860 (concat cmd " " file))
861 cmd)
862 (if background "&" ""))))
64db2461
RS
863 ;; Switch to buffer before checking for subproc output in it.
864 (set-buffer buf)
30803a05
RS
865 ;; If text is unchanged since previous tex-send-command,
866 ;; we haven't got any output. So wait for output now.
64db2461 867 (if (= (buffer-modified-tick buf) tex-send-command-modified-tick)
30803a05 868 (accept-process-output proc))
4cdc1d4b
RS
869 (goto-char (process-mark proc))
870 (insert string)
30803a05 871 (comint-send-input)
64db2461 872 (setq tex-send-command-modified-tick (buffer-modified-tick buf)))))
528415e7 873
a15849cb
RS
874(defun tex-delete-last-temp-files (&optional not-all)
875 "Delete any junk files from last temp file.
876If NOT-ALL is non-nil, save the `.dvi' file."
528415e7
RS
877 (if tex-last-temp-file
878 (let* ((dir (file-name-directory tex-last-temp-file))
879 (list (file-name-all-completions
880 (file-name-nondirectory tex-last-temp-file) dir)))
881 (while list
a15849cb
RS
882 (if not-all
883 (and
884 ;; If arg is non-nil, don't delete the .dvi file.
885 (not (string-match "\\.dvi$" (car list)))
886 (delete-file (concat dir (car list))))
887 (delete-file (concat dir (car list))))
528415e7
RS
888 (setq list (cdr list))))))
889
99621a14 890(add-hook 'kill-emacs-hook 'tex-delete-last-temp-files)
869bff31 891
528415e7 892;;; The commands:
869bff31 893
894(defun tex-region (beg end)
895 "Run TeX on the current region, via a temporary file.
896The file's name comes from the variable `tex-zap-file' and the
897variable `tex-directory' says where to put it.
898
899If the buffer has a header, the header is given to TeX before the
900region itself. The buffer's header is all lines between the strings
901defined by `tex-start-of-header' and `tex-end-of-header' inclusive.
902The header must start in the first 100 lines of the buffer.
903
904The value of `tex-trailer' is given to TeX as input after the region.
905
906The value of `tex-command' specifies the command to use to run TeX."
907 (interactive "r")
908 (if (tex-shell-running)
909 (tex-kill-job)
910 (tex-start-shell))
911 (or tex-zap-file
912 (setq tex-zap-file (tex-generate-zap-file-name)))
528415e7
RS
913 (let* ((temp-buffer (get-buffer-create " TeX-Output-Buffer"))
914 ; Temp file will be written and TeX will be run in zap-directory.
915 ; If the TEXINPUTS file has relative directories or if the region has
916 ; \input of files, this must be the same directory as the file for
917 ; TeX to access the correct inputs. That's why it's safest if
918 ; tex-directory is ".".
919 (zap-directory
920 (file-name-as-directory (expand-file-name tex-directory)))
921 (tex-out-file (concat zap-directory tex-zap-file)))
a15849cb 922 (tex-delete-last-temp-files t)
869bff31 923 ;; Write the new temp file.
924 (save-excursion
925 (save-restriction
926 (widen)
927 (goto-char (point-min))
928 (forward-line 100)
929 (let ((search-end (point))
930 (hbeg (point-min)) (hend (point-min))
931 (default-directory zap-directory))
932 (goto-char (point-min))
933 ;; Initialize the temp file with either the header or nothing
934 (if (search-forward tex-start-of-header search-end t)
935 (progn
936 (beginning-of-line)
937 (setq hbeg (point)) ;mark beginning of header
938 (if (search-forward tex-end-of-header nil t)
939 (progn (forward-line 1)
940 (setq hend (point))) ;mark end of header
941 (setq hbeg (point-min))))) ;no header
528415e7
RS
942 (write-region (min hbeg beg) hend
943 (concat tex-out-file ".tex") nil nil)
944 (write-region (max beg hend) end (concat tex-out-file ".tex") t nil))
869bff31 945 (let ((local-tex-trailer tex-trailer))
946 (set-buffer temp-buffer)
947 (erase-buffer)
948 ;; make sure trailer isn't hidden by a comment
949 (insert-string "\n")
950 (if local-tex-trailer (insert-string local-tex-trailer))
528415e7
RS
951 (tex-set-buffer-directory temp-buffer zap-directory)
952 (write-region (point-min) (point-max)
953 (concat tex-out-file ".tex") t nil))))
954 ;; Record the file name to be deleted afterward.
955 (setq tex-last-temp-file tex-out-file)
956 (tex-send-command tex-shell-cd-command zap-directory)
957 (tex-send-command tex-command tex-out-file)
958 (setq tex-print-file tex-out-file)
959 (setq tex-last-buffer-texed (current-buffer))))
869bff31 960
961(defun tex-buffer ()
962 "Run TeX on current buffer. See \\[tex-region] for more information.
528415e7
RS
963Does not save the buffer, so it's useful for trying experimental versions.
964See \\[tex-file] for an alternative."
869bff31 965 (interactive)
966 (tex-region (point-min) (point-max)))
967
968(defun tex-file ()
969 "Prompt to save all buffers and run TeX (or LaTeX) on current buffer's file.
970This function is more useful than \\[tex-buffer] when you need the
971`.aux' file of LaTeX to have the correct name."
972 (interactive)
973 (let ((tex-out-file
974 (if (buffer-file-name)
975 (file-name-nondirectory (buffer-file-name))
976 (error "Buffer does not seem to be associated with any file")))
977 (file-dir (file-name-directory (buffer-file-name))))
7047ec77 978 (if tex-offer-save
99621a14 979 (save-some-buffers))
869bff31 980 (if (tex-shell-running)
981 (tex-kill-job)
982 (tex-start-shell))
528415e7
RS
983 (tex-send-command tex-shell-cd-command file-dir)
984 (tex-send-command tex-command tex-out-file))
869bff31 985 (setq tex-last-buffer-texed (current-buffer))
528415e7 986 (setq tex-print-file (buffer-file-name)))
869bff31 987
988(defun tex-generate-zap-file-name ()
989 "Generate a unique name suitable for use as a file name."
990 ;; Include the shell process number and host name
991 ;; in case there are multiple shells (for same or different user).
992 (format "#tz%d%s"
993 (process-id (get-buffer-process "*tex-shell*"))
994 (tex-strip-dots (system-name))))
995
996(defun tex-strip-dots (s)
997 (setq s (copy-sequence s))
998 (while (string-match "\\." s)
999 (aset s (match-beginning 0) ?-))
1000 s)
1001
1002;; This will perhaps be useful for modifying TEXINPUTS.
1003;; Expand each file name, separated by colons, in the string S.
1004(defun tex-expand-files (s)
1005 (let (elts (start 0))
1006 (while (string-match ":" s start)
1007 (setq elts (cons (substring s start (match-beginning 0)) elts))
1008 (setq start (match-end 0)))
1009 (or (= start 0)
1010 (setq elts (cons (substring s start) elts)))
1011 (mapconcat 'expand-file-name (nreverse elts) ":")))
1012
1013(defun tex-shell-running ()
1014 (and (get-process "tex-shell")
1015 (eq (process-status (get-process "tex-shell")) 'run)))
1016
1017(defun tex-kill-job ()
1018 "Kill the currently running TeX job."
1019 (interactive)
528415e7 1020 (quit-process (get-process "tex-shell") t))
869bff31 1021
1022(defun tex-recenter-output-buffer (linenum)
1023 "Redisplay buffer of TeX job output so that most recent output can be seen.
1024The last line of the buffer is displayed on
1025line LINE of the window, or centered if LINE is nil."
1026 (interactive "P")
1027 (let ((tex-shell (get-buffer "*tex-shell*"))
1028 (old-buffer (current-buffer)))
1029 (if (null tex-shell)
1030 (message "No TeX output buffer")
1031 (pop-to-buffer tex-shell)
1032 (bury-buffer tex-shell)
1033 (goto-char (point-max))
1034 (recenter (if linenum
1035 (prefix-numeric-value linenum)
1036 (/ (window-height) 2)))
528415e7 1037 (pop-to-buffer old-buffer))))
869bff31 1038
528415e7 1039(defun tex-print (&optional alt)
869bff31 1040 "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file].
1433a222
CZ
1041Runs the shell command defined by `tex-dvi-print-command'. If prefix argument
1042is provided, use the alternative command, `tex-alt-dvi-print-command'."
528415e7 1043 (interactive "P")
869bff31 1044 (let ((print-file-name-dvi (tex-append tex-print-file ".dvi"))
1045 test-name)
1046 (if (and (not (equal (current-buffer) tex-last-buffer-texed))
1047 (file-newer-than-file-p
1048 (setq test-name (tex-append (buffer-file-name) ".dvi"))
528415e7 1049 print-file-name-dvi))
869bff31 1050 (setq print-file-name-dvi test-name))
528415e7
RS
1051 (if (not (file-exists-p print-file-name-dvi))
1052 (error "No appropriate `.dvi' file could be found")
1053 (tex-send-command
1054 (if alt tex-alt-dvi-print-command tex-dvi-print-command)
1055 print-file-name-dvi t))))
869bff31 1056
cf6d6e8a
RS
1057(defun tex-alt-print ()
1058 "Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file].
1059Runs the shell command defined by tex-alt-dvi-print-command."
1060 (interactive)
1061 (tex-print t))
1062
869bff31 1063(defun tex-view ()
1064 "Preview the last `.dvi' file made by running TeX under Emacs.
1065This means, made using \\[tex-region], \\[tex-buffer] or \\[tex-file].
1066The variable `tex-dvi-view-command' specifies the shell command for preview."
1067 (interactive)
1068 (let ((tex-dvi-print-command tex-dvi-view-command))
1069 (tex-print)))
1070
1071(defun tex-append (file-name suffix)
1072 "Append to FILENAME the suffix SUFFIX, using same algorithm TeX uses.
cf6d6e8a 1073Pascal-based TeX scans for the first period, C TeX uses the last.
869bff31 1074No period is retained immediately before SUFFIX,
1075so normally SUFFIX starts with one."
1076 (if (stringp file-name)
cf6d6e8a
RS
1077 (let ((file (file-name-nondirectory file-name))
1078 trial-name)
1079 ;; try spliting on first period
1080 (setq trial-name
1081 (concat (file-name-directory file-name)
1082 (substring file 0
1083 (string-match "\\." file))
1084 suffix))
1085 (if (or (file-exists-p trial-name)
1086 (file-exists-p (concat trial-name ".aux"))) ;for BibTeX files
1087 trial-name
1088 ;; not found, so split on last period
1089 (concat (file-name-directory file-name)
1090 (substring file 0
1091 (string-match "\\.[^.]*$" file))
1092 suffix)))
869bff31 1093 " "))
1094
1095(defun tex-show-print-queue ()
1096 "Show the print queue that \\[tex-print] put your job on.
1433a222 1097Runs the shell command defined by `tex-show-queue-command'."
869bff31 1098 (interactive)
1099 (if (tex-shell-running)
1100 (tex-kill-job)
1101 (tex-start-shell))
528415e7 1102 (tex-send-command tex-show-queue-command))
869bff31 1103
1104(defun tex-bibtex-file ()
1105 "Run BibTeX on the current buffer's file."
1106 (interactive)
1107 (if (tex-shell-running)
1108 (tex-kill-job)
1109 (tex-start-shell))
1110 (let ((tex-out-file
1111 (tex-append (file-name-nondirectory (buffer-file-name)) ""))
1112 (file-dir (file-name-directory (buffer-file-name))))
528415e7 1113 (tex-send-command tex-shell-cd-command file-dir)
8241d7b9 1114 (tex-send-command tex-bibtex-command tex-out-file)))
528415e7
RS
1115
1116(run-hooks 'tex-mode-load-hook)
869bff31 1117
49116ac0
JB
1118(provide 'tex-mode)
1119
d501f516 1120;;; tex-mode.el ends here
99621a14 1121