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