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