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