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