tex-mode.el 88 KB
Newer Older
Stefan Monnier's avatar
Stefan Monnier committed
1
;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- coding: utf-8 -*-
Eric S. Raymond's avatar
Eric S. Raymond committed
2

3
;; Copyright (C) 1985,86,89,92,94,95,96,97,98,1999,2002,03,2004
4
;;       Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

Richard M. Stallman's avatar
Richard M. Stallman committed
6
;; Maintainer: FSF
Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Keywords: tex
Eric S. Raymond's avatar
Eric S. Raymond committed
8

9
;; Contributions over the years by William F. Schelter, Dick King,
Richard M. Stallman's avatar
Richard M. Stallman committed
10
;; Stephen Gildea, Michael Prange, Jacob Gore, and Edward M. Reingold.
11

root's avatar
root committed
12 13 14 15
;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
Eric S. Raymond's avatar
Eric S. Raymond committed
16
;; the Free Software Foundation; either version 2, or (at your option)
root's avatar
root committed
17 18 19 20 21 22 23 24
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
25 26 27
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
root's avatar
root committed
28

29 30
;;; Commentary:

Eric S. Raymond's avatar
Eric S. Raymond committed
31 32
;;; Code:

33 34 35
;; Pacify the byte-compiler
(eval-when-compile
  (require 'compare-w)
Stefan Monnier's avatar
Stefan Monnier committed
36
  (require 'cl)
37 38
  (require 'skeleton))

39
(require 'shell)
40
(require 'compile)
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
(defgroup tex-file nil
  "TeX files and directories"
  :prefix "tex-"
  :group 'tex)

(defgroup tex-run nil
  "Running external commands from TeX mode"
  :prefix "tex-"
  :group 'tex)

(defgroup tex-view nil
  "Viewing and printing TeX files"
  :prefix "tex-"
  :group 'tex)

Jim Blandy's avatar
Jim Blandy committed
57
;;;###autoload
58 59 60 61 62
(defcustom tex-shell-file-name nil
  "*If non-nil, the shell file name to run in the subshell used to run TeX."
  :type '(choice (const :tag "None" nil)
		 string)
  :group 'tex-run)
63

Jim Blandy's avatar
Jim Blandy committed
64
;;;###autoload
65
(defcustom tex-directory "."
66
  "*Directory in which temporary files are written.
Richard M. Stallman's avatar
Richard M. Stallman committed
67
You can make this `/tmp' if your TEXINPUTS has no relative directories in it
68
and you don't try to apply \\[tex-region] or \\[tex-buffer] when there are
69 70 71
`\\input' commands with relative directories."
  :type 'directory
  :group 'tex-file)
root's avatar
root committed
72

73
;;;###autoload
74
(defcustom tex-first-line-header-regexp nil
75 76 77
  "Regexp for matching a first line which `tex-region' should include.
If this is non-nil, it should be a regular expression string;
if it matches the first line of the file,
78 79 80 81
`tex-region' always includes the first line in the TeX run."
  :type '(choice (const :tag "None" nil)
                 regexp)
  :group 'tex-file)
82

83
;;;###autoload
84
(defcustom tex-main-file nil
85
  "*The main TeX source file which includes this buffer's file.
86 87
The command `tex-file' runs TeX on the file specified by `tex-main-file'
if the variable is non-nil."
88 89 90
  :type '(choice (const :tag "None" nil)
                 file)
  :group 'tex-file)
91

Jim Blandy's avatar
Jim Blandy committed
92
;;;###autoload
93 94 95 96
(defcustom tex-offer-save t
  "*If non-nil, ask about saving modified buffers before \\[tex-file] is run."
  :type 'boolean
  :group 'tex-file)
root's avatar
root committed
97

Jim Blandy's avatar
Jim Blandy committed
98
;;;###autoload
99
(defcustom tex-run-command "tex"
root's avatar
root committed
100
  "*Command used to run TeX subjob.
101 102
TeX Mode sets `tex-command' to this string.
See the documentation of that variable."
103 104
  :type 'string
  :group 'tex-run)
root's avatar
root committed
105

Jim Blandy's avatar
Jim Blandy committed
106
;;;###autoload
107
(defcustom latex-run-command "latex"
root's avatar
root committed
108
  "*Command used to run LaTeX subjob.
109 110
LaTeX Mode sets `tex-command' to this string.
See the documentation of that variable."
111 112
  :type 'string
  :group 'tex-run)
113

114 115 116
;;;###autoload
(defcustom slitex-run-command "slitex"
  "*Command used to run SliTeX subjob.
117 118
SliTeX Mode sets `tex-command' to this string.
See the documentation of that variable."
119 120 121
  :type 'string
  :group 'tex-run)

122
;;;###autoload
Stefan Monnier's avatar
Stefan Monnier committed
123
(defcustom tex-start-options ""
124
  "*TeX options to use when starting TeX.
Stefan Monnier's avatar
Stefan Monnier committed
125 126 127 128
These immediately precede the commands in `tex-start-commands'
and the input file name, with no separating space and are not shell-quoted.
If nil, TeX runs with no options.  See the documentation of `tex-command'."
  :type 'string
129
  :group 'tex-run
130 131 132 133 134
  :version "21.4")

;;;###autoload
(defcustom tex-start-commands "\\nonstopmode\\input"
  "*TeX commands to use when starting TeX.
Stefan Monnier's avatar
Stefan Monnier committed
135 136
They are shell-quoted and precede the input file name, with a separating space.
If nil, no commands are used.  See the documentation of `tex-command'."
137 138 139 140 141 142
  :type '(radio (const :tag "Interactive \(nil\)" nil)
		(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)"
		       "\\nonstopmode\\input")
		(string :tag "String at your choice"))
  :group 'tex-run
  :version "21.4")
143

144
(defvar latex-standard-block-names
145 146 147 148 149 150 151 152 153
  '("abstract"		"array"		"center"	"description"
    "displaymath"	"document"	"enumerate"	"eqnarray"
    "eqnarray*"		"equation"	"figure"	"figure*"
    "flushleft"		"flushright"	"itemize"	"letter"
    "list"		"minipage"	"picture"	"quotation"
    "quote"		"slide"		"sloppypar"	"tabbing"
    "table"		"table*"	"tabular"	"tabular*"
    "thebibliography"	"theindex*"	"titlepage"	"trivlist"
    "verbatim"		"verbatim*"	"verse"		"math")
154 155
  "Standard LaTeX block names.")

Jim Blandy's avatar
Jim Blandy committed
156
;;;###autoload
157
(defcustom latex-block-names nil
158
  "*User defined LaTeX block names.
159
Combined with `latex-standard-block-names' for minibuffer completion."
160 161
  :type '(repeat string)
  :group 'tex-run)
root's avatar
root committed
162

Jim Blandy's avatar
Jim Blandy committed
163
;;;###autoload
164
(defcustom tex-bibtex-command "bibtex"
165
  "*Command used by `tex-bibtex-file' to gather bibliographic data.
Richard M. Stallman's avatar
Richard M. Stallman committed
166
If this string contains an asterisk (`*'), that is replaced by the file name;
167 168 169
otherwise, the file name, preceded by blank, is added at the end."
  :type 'string
  :group 'tex-run)
root's avatar
root committed
170

Jim Blandy's avatar
Jim Blandy committed
171
;;;###autoload
172
(defcustom tex-dvi-print-command "lpr -d"
173
  "*Command used by \\[tex-print] to print a .dvi file.
Richard M. Stallman's avatar
Richard M. Stallman committed
174
If this string contains an asterisk (`*'), that is replaced by the file name;
175 176 177
otherwise, the file name, preceded by blank, is added at the end."
  :type 'string
  :group 'tex-view)
178

Jim Blandy's avatar
Jim Blandy committed
179
;;;###autoload
180
(defcustom tex-alt-dvi-print-command "lpr -d"
181
  "*Command used by \\[tex-print] with a prefix arg to print a .dvi file.
Richard M. Stallman's avatar
Richard M. Stallman committed
182 183
If this string contains an asterisk (`*'), that is replaced by the file name;
otherwise, the file name, preceded by blank, is added at the end.
184

Richard M. Stallman's avatar
Richard M. Stallman committed
185 186
If two printers are not enough of a choice, you can set the variable
`tex-alt-dvi-print-command' to an expression that asks what you want;
187 188 189 190 191 192
for example,

    (setq tex-alt-dvi-print-command
         '(format \"lpr -P%s\" (read-string \"Use printer: \")))

would tell \\[tex-print] with a prefix argument to ask you which printer to
193 194 195 196
use."
  :type '(choice (string :tag "Command")
		 (sexp :tag "Expression"))
  :group 'tex-view)
root's avatar
root committed
197

Jim Blandy's avatar
Jim Blandy committed
198
;;;###autoload
199
(defcustom tex-dvi-view-command '(if (eq window-system 'x) "xdvi" "dvi2tty * | cat -s")
Richard M. Stallman's avatar
Richard M. Stallman committed
200
  "*Command used by \\[tex-view] to display a `.dvi' file.
201
If it is a string, that specifies the command directly.
Richard M. Stallman's avatar
Richard M. Stallman committed
202
If this string contains an asterisk (`*'), that is replaced by the file name;
203
otherwise, the file name, preceded by a space, is added at the end.
204

205 206
If the value is a form, it is evaluated to get the command to use."
  :type '(choice (const nil) string sexp)
207
  :group 'tex-view)
root's avatar
root committed
208

Jim Blandy's avatar
Jim Blandy committed
209
;;;###autoload
210
(defcustom tex-show-queue-command "lpq"
211
  "*Command used by \\[tex-show-print-queue] to show the print queue.
212 213 214
Should show the queue(s) that \\[tex-print] puts jobs on."
  :type 'string
  :group 'tex-view)
root's avatar
root committed
215

Jim Blandy's avatar
Jim Blandy committed
216
;;;###autoload
217
(defcustom tex-default-mode 'latex-mode
root's avatar
root committed
218 219 220
  "*Mode to enter for a new file that might be either TeX or LaTeX.
This variable is used when it can't be determined whether the file
is plain TeX or LaTeX or what because the file contains no commands.
221 222 223
Normally set to either `plain-tex-mode' or `latex-mode'."
  :type 'function
  :group 'tex)
root's avatar
root committed
224

Jim Blandy's avatar
Jim Blandy committed
225
;;;###autoload
226 227 228
(defcustom tex-open-quote "``"
  "*String inserted by typing \\[tex-insert-quote] to open a quotation."
  :type 'string
Stefan Monnier's avatar
Stefan Monnier committed
229
  :options '("``" "\"<" "\"`" "<<" "«")
230
  :group 'tex)
root's avatar
root committed
231

Jim Blandy's avatar
Jim Blandy committed
232
;;;###autoload
233 234 235
(defcustom tex-close-quote "''"
  "*String inserted by typing \\[tex-insert-quote] to close a quotation."
  :type 'string
Stefan Monnier's avatar
Stefan Monnier committed
236
  :options '("''" "\">" "\"'" ">>" "»")
237
  :group 'tex)
root's avatar
root committed
238

239 240 241
(defvar tex-last-temp-file nil
  "Latest temporary file generated by \\[tex-region] and \\[tex-buffer].
Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the
Richard M. Stallman's avatar
Richard M. Stallman committed
242
tex shell terminates.")
243

Stefan Monnier's avatar
Stefan Monnier committed
244
(defvar tex-command "tex"
245
  "*Command to run TeX.
Stefan Monnier's avatar
Stefan Monnier committed
246
If this string contains an asterisk \(`*'\), that is replaced by the file name;
247 248 249
otherwise the value of `tex-start-options', the \(shell-quoted\)
value of `tex-start-commands', and the file name are added at the end
with blanks as separators.
250 251 252 253

In TeX, LaTeX, and SliTeX Mode this variable becomes buffer local.
In these modes, use \\[set-variable] if you want to change it for the
current buffer.")
root's avatar
root committed
254 255 256 257 258

(defvar tex-trailer nil
  "String appended after the end of a region sent to TeX by \\[tex-region].")

(defvar tex-start-of-header nil
259
  "Regular expression used by \\[tex-region] to find start of file's header.")
root's avatar
root committed
260 261

(defvar tex-end-of-header nil
262
  "Regular expression used by \\[tex-region] to find end of file's header.")
root's avatar
root committed
263 264 265

(defvar tex-shell-cd-command "cd"
  "Command to give to shell running TeX to change directory.
Richard M. Stallman's avatar
Richard M. Stallman committed
266
The value of `tex-directory' is appended to this, separated by a space.")
root's avatar
root committed
267 268 269 270 271 272 273 274 275 276 277 278

(defvar tex-zap-file nil
  "Temporary file name used for text being sent as input to TeX.
Should be a simple file name with no extension or directory specification.")

(defvar tex-last-buffer-texed nil
  "Buffer which was last TeXed.")

(defvar tex-print-file nil
  "File name that \\[tex-print] prints.
Set by \\[tex-region], \\[tex-buffer], and \\[tex-file].")

279 280 281 282 283 284 285 286 287 288
(defvar tex-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?% "<" st)
    (modify-syntax-entry ?\n ">" st)
    (modify-syntax-entry ?\f ">" st)
    (modify-syntax-entry ?\C-@ "w" st)
    (modify-syntax-entry ?' "w" st)
    (modify-syntax-entry ?@ "_" st)
    (modify-syntax-entry ?* "_" st)
    (modify-syntax-entry ?\t " " st)
289 290
    ;; ~ is printed by TeX as a space, but it's semantics in the syntax
    ;; of TeX is not `whitespace' (i.e. it's just like \hspace{foo}).
291 292 293 294 295 296 297 298
    (modify-syntax-entry ?~ "." st)
    (modify-syntax-entry ?$ "$$" st)
    (modify-syntax-entry ?\\ "/" st)
    (modify-syntax-entry ?\" "." st)
    (modify-syntax-entry ?& "." st)
    (modify-syntax-entry ?_ "." st)
    (modify-syntax-entry ?^ "." st)
    st)
root's avatar
root committed
299
  "Syntax table used while in TeX mode.")
300 301 302 303

;;;;
;;;; Imenu support
;;;;
root's avatar
root committed
304

305
(defcustom latex-imenu-indent-string ". "
306 307 308 309 310
  "*String to add repeated in front of nested sectional units for Imenu.
An alternative value is \" . \", if you use a font with a narrow period."
  :type 'string
  :group 'tex)

311 312 313 314 315 316
(defvar latex-section-alist
  '(("part" . 0) ("chapter" . 1)
    ("section" . 2) ("subsection" . 3)
    ("subsubsection" . 4)
    ("paragraph" . 5) ("subparagraph" . 6)))

317 318 319 320 321
(defvar latex-metasection-list
  '("documentstyle" "documentclass"
    "begin{document}" "end{document}"
    "appendix" "frontmatter" "mainmatter" "backmatter"))

322
(defun latex-imenu-create-index ()
323 324 325 326 327 328 329
  "Generate an alist for imenu from a LaTeX buffer."
  (let ((section-regexp
	 (concat "\\\\" (regexp-opt (mapcar 'car latex-section-alist) t)
		 "\\*?[ \t]*{"))
	(metasection-regexp
	 (concat "\\\\" (regexp-opt latex-metasection-list t)))
	i0 menu case-fold-search)
330 331 332 333 334 335 336 337 338 339 340 341
    (save-excursion
      ;; Find the top-most level in this file but don't allow it to be
      ;; any deeper than "section" (which is top-level in an article).
      (goto-char (point-min))
      (if (search-forward-regexp "\\\\part\\*?[ \t]*{" nil t)
	  (setq i0 0)
	(if (search-forward-regexp "\\\\chapter\\*?[ \t]*{" nil t)
	    (setq i0 1)
	  (setq i0 2)))

      ;; Look for chapters and sections.
      (goto-char (point-min))
342
      (while (search-forward-regexp section-regexp nil t)
343 344 345 346 347
	(let ((start (match-beginning 0))
	      (here (point))
	      (i (cdr (assoc (buffer-substring-no-properties
			      (match-beginning 1)
			      (match-end 1))
348
			     latex-section-alist))))
349 350 351 352 353 354
	  (backward-char 1)
	  (condition-case err
	      (progn
		;; Using sexps allows some use of matching {...} inside
		;; titles.
		(forward-sexp 1)
355 356 357 358 359 360 361 362
		(push (cons (concat (apply 'concat
					   (make-list
					    (max 0 (- i i0))
					    latex-imenu-indent-string))
				    (buffer-substring-no-properties
				     here (1- (point))))
			    start)
		      menu))
363 364 365 366 367 368
	    (error nil))))

      ;; Look for included material.
      (goto-char (point-min))
      (while (search-forward-regexp
	      "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\
369
\[ \t]*{\\([^}\n]+\\)}"
370
	      nil t)
371 372 373 374 375 376 377 378
	(push (cons (concat "<<" (buffer-substring-no-properties
				  (match-beginning 2)
				  (match-end 2))
			    (if (= (char-after (match-beginning 1)) ?b)
				".bbl"
			      ".tex"))
		    (match-beginning 0))
	      menu))
379 380 381

      ;; Look for \frontmatter, \mainmatter, \backmatter, and \appendix.
      (goto-char (point-min))
382 383
      (while (search-forward-regexp metasection-regexp nil t)
	(push (cons "--" (match-beginning 0)) menu))
384 385 386

      ;; Sort in increasing buffer position order.
      (sort menu (function (lambda (a b) (< (cdr a) (cdr b))))))))
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443

;;;;
;;;; Outline support
;;;;

(defvar latex-outline-regexp
  (concat "\\\\"
	  (regexp-opt (append latex-metasection-list
			      (mapcar 'car latex-section-alist)) t)))

(defun latex-outline-level ()
  (if (looking-at latex-outline-regexp)
      (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1))
    1000))

;;;;
;;;; Font-Lock support
;;;;

;(defvar tex-font-lock-keywords
;  ;; Regexps updated with help from Ulrik Dickow <dickow@nbi.dk>.
;  '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
;     2 font-lock-function-name-face)
;    ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
;     2 font-lock-constant-face)
;    ;; It seems a bit dubious to use `bold' and `italic' faces since we might
;    ;; not be able to display those fonts.
;    ("{\\\\bf\\([^}]+\\)}" 1 'bold keep)
;    ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep)
;    ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face)
;    ("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep))
;  ;; Rewritten and extended for LaTeX2e by Ulrik Dickow <dickow@nbi.dk>.
;  '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
;     2 font-lock-function-name-face)
;    ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
;     2 font-lock-constant-face)
;    ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face)
;    "\\\\\\([a-zA-Z@]+\\|.\\)"
;    ;; It seems a bit dubious to use `bold' and `italic' faces since we might
;    ;; not be able to display those fonts.
;    ;; LaTeX2e: \emph{This is emphasized}.
;    ("\\\\emph{\\([^}]+\\)}" 1 'italic keep)
;    ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...}
;    ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}"
;     3 (if (match-beginning 2) 'bold 'italic) keep)
;    ;; Old-style bf/em/it/sl.  Stop at `\\' and un-escaped `&', for tables.
;    ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)"
;     3 (if (match-beginning 2) 'bold 'italic) keep))

;; Rewritten with the help of Alexandra Bac <abac@welcome.disi.unige.it>.
(defconst tex-font-lock-keywords-1
  (eval-when-compile
    (let* (;; Names of commands whose arg should be fontified as heading, etc.
	   (headings (regexp-opt
		      '("title"  "begin" "end" "chapter" "part"
			"section" "subsection" "subsubsection"
			"paragraph" "subparagraph" "subsubparagraph"
444 445 446
			"newcommand" "renewcommand" "providecommand"
			"newenvironment" "renewenvironment"
			"newtheorem" "renewtheorem")
447 448 449 450 451 452 453 454
		      t))
	   (variables (regexp-opt
		       '("newcounter" "newcounter*" "setcounter" "addtocounter"
			 "setlength" "addtolength" "settowidth")
		       t))
	   (includes (regexp-opt
		      '("input" "include" "includeonly" "bibliography"
			"epsfig" "psfig" "epsf" "nofiles" "usepackage"
455
			"documentstyle" "documentclass" "verbatiminput"
456 457 458 459
			"includegraphics" "includegraphics*")
		      t))
	   ;; Miscellany.
	   (slash "\\\\")
460 461 462 463
	   (opt " *\\(\\[[^]]*\\] *\\)*")
	   ;; This would allow highlighting \newcommand\CMD but requires
	   ;; adapting subgroup numbers below.
	   ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)"))
464
	   (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
465
      (list
Stefan Monnier's avatar
Stefan Monnier committed
466 467 468 469 470 471
       ;; display $$ math $$
       ;; We only mark the match between $$ and $$ because the $$ delimiters
       ;; themselves have already been marked (along with $..$) by syntactic
       ;; fontification.  Also this is done at the very beginning so as to
       ;; interact with the other keywords in the same way as $...$ does.
       (list "\\$\\$\\([^$]+\\)\\$\\$" 1 'tex-math-face)
472 473
       ;; Heading args.
       (list (concat slash headings "\\*?" opt arg)
474 475 476 477 478 479 480 481 482 483
	     ;; If ARG ends up matching too much (if the {} don't match, f.ex)
	     ;; jit-lock will do funny things: when updating the buffer
	     ;; the re-highlighting is only done locally so it will just
	     ;; match the local line, but defer-contextually will
	     ;; match more lines at a time, so ARG will end up matching
	     ;; a lot more, which might suddenly include a comment
	     ;; so you get things highlighted bold when you type them
	     ;; but they get turned back to normal a little while later
	     ;; because "there's already a face there".
	     ;; Using `keep' works around this un-intuitive behavior as well
484 485
	     ;; as improves the behavior in the very rare case where you do
	     ;; have a comment in ARG.
486
	     3 'font-lock-function-name-face 'keep)
487 488
       (list (concat slash "\\(?:provide\\|\\(?:re\\)?new\\)command\\** *\\(\\\\[A-Za-z@]+\\)")
	     1 'font-lock-function-name-face 'keep)
489
       ;; Variable args.
490
       (list (concat slash variables " *" arg) 2 'font-lock-variable-name-face)
491 492 493
       ;; Include args.
       (list (concat slash includes opt arg) 3 'font-lock-builtin-face)
       ;; Definitions.  I think.
494
       '("^[ \t]*\\\\def *\\\\\\(\\(\\w\\|@\\)+\\)"
495
	 1 font-lock-function-name-face))))
496 497 498 499 500 501 502
  "Subdued expressions to highlight in TeX modes.")

(defconst tex-font-lock-keywords-2
  (append tex-font-lock-keywords-1
   (eval-when-compile
     (let* (;;
	    ;; Names of commands whose arg should be fontified with fonts.
503
	    (bold (regexp-opt '("textbf" "textsc" "textup"
504
				"boldsymbol" "pmb") t))
505
	    (italic (regexp-opt '("textit" "textsl" "emph") t))
506 507
	    ;; FIXME: unimplemented yet.
	    ;; (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t))
508 509 510 511
	    ;;
	    ;; Names of commands whose arg should be fontified as a citation.
	    (citations (regexp-opt
			'("label" "ref" "pageref" "vref" "eqref"
512
			  "cite" "nocite" "index" "glossary" "bibitem"
513 514 515
			  ;; These are text, rather than citations.
			  ;; "caption" "footnote" "footnotemark" "footnotetext"
			  )
516 517 518
			t))
	    ;;
	    ;; Names of commands that should be fontified.
519 520 521 522 523 524
	    (specials-1 (regexp-opt '("\\" "\\*") t)) ;; "-"
	    (specials-2 (regexp-opt
			 '("linebreak" "nolinebreak" "pagebreak" "nopagebreak"
			   "newline" "newpage" "clearpage" "cleardoublepage"
			   "displaybreak" "allowdisplaybreaks"
			   "enlargethispage") t))
525 526 527 528
	    (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)")
	    ;;
	    ;; Miscellany.
	    (slash "\\\\")
529
	    (opt " *\\(\\[[^]]*\\] *\\)*")
530
	    (args "\\(\\(?:[^{}&\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")
531
	    (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
532 533 534 535 536
       (list
	;;
	;; Citation args.
	(list (concat slash citations opt arg) 3 'font-lock-constant-face)
	;;
537
	;; Text between `` quotes ''.
Stefan Monnier's avatar
Stefan Monnier committed
538
	(cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "«") t)
539
		      "[^'\">{]+"	;a bit pessimistic
Stefan Monnier's avatar
Stefan Monnier committed
540
		      (regexp-opt `("''" "\">" "\"'" ">>" "»") t))
541 542
	      'font-lock-string-face)
	;;
543
	;; Command names, special and general.
544 545 546
	(cons (concat slash specials-1) 'font-lock-warning-face)
	(list (concat "\\(" slash specials-2 "\\)\\([^a-zA-Z@]\\|\\'\\)")
	      1 'font-lock-warning-face)
547 548 549 550
	(concat slash general)
	;;
	;; Font environments.  It seems a bit dubious to use `bold' etc. faces
	;; since we might not be able to display those fonts.
551 552
	(list (concat slash bold " *" arg) 2 '(quote bold) 'append)
	(list (concat slash italic " *" arg) 2 '(quote italic) 'append)
553
	;; (list (concat slash type arg) 2 '(quote bold-italic) 'append)
554 555
	;;
	;; Old-style bf/em/it/sl.  Stop at `\\' and un-escaped `&', for tables.
556 557 558 559 560
	(list (concat "\\\\\\(em\\|it\\|sl\\)\\>" args)
	      2 '(quote italic) 'append)
	;; This is separate from the previous one because of cases like
	;; {\em foo {\bf bar} bla} where both match.
	(list (concat "\\\\bf\\>" args) 1 '(quote bold) 'append)))))
561 562
   "Gaudy expressions to highlight in TeX modes.")

563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
(defun tex-font-lock-suscript (pos)
  (unless (or (memq (get-text-property pos 'face)
		    '(font-lock-constant-face font-lock-builtin-face
		      font-lock-comment-face tex-verbatim-face))
	      ;; Check for backslash quoting
	      (let ((odd nil)
		    (pos pos))
		(while (eq (char-before pos) ?\\)
		  (setq pos (1- pos) odd (not odd)))
		odd))
    (if (eq (char-after pos) ?_)
	'(face subscript display (raise -0.3))
      '(face superscript display (raise +0.3)))))

(defconst tex-font-lock-keywords-3
  (append tex-font-lock-keywords-2
   (eval-when-compile
     (let ((general "\\([a-zA-Z@]+\\|[^ \t\n]\\)")
	   (slash "\\\\")
	   ;; This is not the same regexp as before: it has a `+' removed.
	   ;; The + makes the matching faster in the above cases (where we can
	   ;; exit as soon as the match fails) but would make this matching
	   ;; degenerate to nasty complexity (because we try to match the
	   ;; closing brace, which forces trying all matching combinations).
	   (arg "{\\(?:[^{}\\]\\|\\\\.\\|{[^}]*}\\)*"))
       `((,(concat "[_^] *\\([^\n\\{}]\\|" slash general "\\|" arg "}\\)")
	  (1 (tex-font-lock-suscript (match-beginning 0))
	     append))))))
  "Experimental expressions to highlight in TeX modes.")

593 594
(defvar tex-font-lock-keywords tex-font-lock-keywords-1
  "Default expressions to highlight in TeX modes.")
595

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
(defvar tex-verbatim-environments
  '("verbatim" "verbatim*"))

(defvar tex-font-lock-syntactic-keywords
  (let ((verbs (regexp-opt tex-verbatim-environments t)))
    `((,(concat "^\\\\begin *{" verbs "}.*\\(\n\\)") 2 "|")
      (,(concat "^\\\\end *{" verbs "}\\(.?\\)") 2
       (unless (<= (match-beginning 0) (point-min))
	 (put-text-property (1- (match-beginning 0)) (match-beginning 0)
			    'syntax-table (string-to-syntax "|"))
	 "<"))
      ;; ("^\\(\\\\\\)begin *{comment}" 1 "< b")
      ;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b")
      ("\\\\verb\\**\\([^a-z@*]\\)" 1 "\""))))

(defun tex-font-lock-unfontify-region (beg end)
  (font-lock-default-unfontify-region beg end)
  (while (< beg end)
    (let ((next (next-single-property-change beg 'display nil end))
	  (prop (get-text-property beg 'display)))
      (if (and (eq (car-safe prop) 'raise)
	       (member (car-safe (cdr prop)) '(-0.3 +0.3))
	       (null (cddr prop)))
	  (put-text-property beg next 'display nil))
      (setq beg next))))

(defface superscript
  '((t :height 0.8)) ;; :raise 0.3
  "Face used for superscripts.")
(defface subscript
  '((t :height 0.8)) ;; :raise -0.3
  "Face used for subscripts.")
628 629 630 631 632

(defface tex-math-face
  '((t :inherit font-lock-string-face))
  "Face used to highlight TeX math expressions.")
(defvar tex-math-face 'tex-math-face)
633 634 635 636 637
(defface tex-verbatim-face
  ;; '((t :inherit font-lock-string-face))
  '((t :family "courier"))
  "Face used to highlight TeX verbatim environments.")
(defvar tex-verbatim-face 'tex-verbatim-face)
638 639 640

;; Use string syntax but math face for $...$.
(defun tex-font-lock-syntactic-face-function (state)
641 642 643 644 645 646 647 648 649 650 651 652 653 654
  (let ((char (nth 3 state)))
    (cond
     ((not char) font-lock-comment-face)
     ((eq char ?$) tex-math-face)
     (t
      (when (char-valid-p char)
	;; This is a \verb?...? construct.  Let's find the end and mark it.
	(save-excursion
	  (skip-chars-forward (string ?^ char)) ;; Use `end' ?
	  (when (eq (char-syntax (preceding-char)) ?/)
	    (put-text-property (1- (point)) (point) 'syntax-table '(1)))
	  (unless (eobp)
	    (put-text-property (point) (1+ (point)) 'syntax-table '(7)))))
      tex-verbatim-face))))
655

656

root's avatar
root committed
657
(defun tex-define-common-keys (keymap)
Richard M. Stallman's avatar
Richard M. Stallman committed
658
  "Define the keys that we want defined both in TeX mode and in the TeX shell."
root's avatar
root committed
659 660 661 662 663
  (define-key keymap "\C-c\C-k" 'tex-kill-job)
  (define-key keymap "\C-c\C-l" 'tex-recenter-output-buffer)
  (define-key keymap "\C-c\C-q" 'tex-show-print-queue)
  (define-key keymap "\C-c\C-p" 'tex-print)
  (define-key keymap "\C-c\C-v" 'tex-view)
664 665 666

  (define-key keymap [menu-bar tex] (cons "TeX" (make-sparse-keymap "TeX")))

667 668
  (define-key keymap [menu-bar tex tex-kill-job]
    '(menu-item "Tex Kill" tex-kill-job :enable (tex-shell-running)))
669
  (define-key keymap [menu-bar tex tex-recenter-output-buffer]
670 671
    '(menu-item "Tex Recenter" tex-recenter-output-buffer
                :enable (get-buffer "*tex-shell*")))
672 673
  (define-key keymap [menu-bar tex tex-show-print-queue]
    '("Show Print Queue" . tex-show-print-queue))
674
  (define-key keymap [menu-bar tex tex-alt-print]
675 676 677 678 679 680 681 682 683
    '(menu-item "Tex Print (alt printer)" tex-alt-print
                :enable (stringp tex-print-file)))
  (define-key keymap [menu-bar tex tex-print]
    '(menu-item "Tex Print" tex-print :enable (stringp tex-print-file)))
  (define-key keymap [menu-bar tex tex-view]
    '(menu-item "Tex View" tex-view :enable (stringp tex-print-file))))

(defvar tex-mode-map
  (let ((map (make-sparse-keymap)))
684
    (set-keymap-parent map text-mode-map)
685 686 687 688 689 690 691 692 693 694 695 696 697
    (tex-define-common-keys map)
    (define-key map "\"" 'tex-insert-quote)
    (define-key map "(" 'skeleton-pair-insert-maybe)
    (define-key map "{" 'skeleton-pair-insert-maybe)
    (define-key map "[" 'skeleton-pair-insert-maybe)
    (define-key map "$" 'skeleton-pair-insert-maybe)
    (define-key map "\n" 'tex-terminate-paragraph)
    (define-key map "\M-\r" 'latex-insert-item)
    (define-key map "\C-c}" 'up-list)
    (define-key map "\C-c{" 'tex-insert-braces)
    (define-key map "\C-c\C-r" 'tex-region)
    (define-key map "\C-c\C-b" 'tex-buffer)
    (define-key map "\C-c\C-f" 'tex-file)
698
    (define-key map "\C-c\C-c" 'tex-compile)
699
    (define-key map "\C-c\C-i" 'tex-bibtex-file)
700 701
    (define-key map "\C-c\C-o" 'latex-insert-block)
    (define-key map "\C-c\C-e" 'latex-close-block)
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
    (define-key map "\C-c\C-u" 'tex-goto-last-unclosed-latex-block)
    (define-key map "\C-c\C-m" 'tex-feed-input)
    (define-key map [(control return)] 'tex-feed-input)
    (define-key map [menu-bar tex tex-bibtex-file]
      '("BibTeX File" . tex-bibtex-file))
    (define-key map [menu-bar tex tex-validate-region]
      '(menu-item "Validate Region" tex-validate-region :enable mark-active))
    (define-key map [menu-bar tex tex-validate-buffer]
      '("Validate Buffer" . tex-validate-buffer))
    (define-key map [menu-bar tex tex-region]
      '(menu-item "TeX Region" tex-region :enable mark-active))
    (define-key map [menu-bar tex tex-buffer]
      '("TeX Buffer" . tex-buffer))
    (define-key map [menu-bar tex tex-file] '("TeX File" . tex-file))
    map)
717 718 719 720 721
 "Keymap shared by TeX modes.")

(defvar latex-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map tex-mode-map)
722
    (define-key map "\C-c\C-s" 'latex-split-block)
723 724 725 726 727 728 729 730
    map)
  "Keymap for `latex-mode'.  See also `tex-mode-map'.")

(defvar plain-tex-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map tex-mode-map)
    map)
  "Keymap for `plain-tex-mode'.  See also `tex-mode-map'.")
731

732 733 734 735 736
(defvar tex-shell-map
  (let ((m (make-sparse-keymap)))
    (set-keymap-parent m shell-mode-map)
    (tex-define-common-keys m)
    m)
Richard M. Stallman's avatar
Richard M. Stallman committed
737
  "Keymap for the TeX shell.
738
Inherits `shell-mode-map' with a few additions.")
root's avatar
root committed
739

740 741 742 743 744 745 746 747 748 749 750 751 752
(defvar tex-face-alist
  '((bold . "{\\bf ")
    (italic . "{\\it ")
    (bold-italic . "{\\bi ")		; hypothetical
    (underline . "\\underline{")
    (default . "{\\rm "))
  "Alist of face and TeX font name for facemenu.")

(defvar tex-latex-face-alist
  `((italic . "{\\em ")
    ,@tex-face-alist)
  "Alist of face and LaTeX font name for facemenu.")

753 754
;; This would be a lot simpler if we just used a regexp search,
;; but then it would be too slow.
755
(defun tex-guess-mode ()
756
  (let ((mode tex-default-mode) slash comment)
root's avatar
root committed
757 758 759 760 761 762 763
    (save-excursion
      (goto-char (point-min))
      (while (and (setq slash (search-forward "\\" nil t))
		  (setq comment (let ((search-end (point)))
				  (save-excursion
				    (beginning-of-line)
				    (search-forward "%" search-end t))))))
764 765 766 767 768 769
      (when (and slash (not comment))
	(setq mode
	      (if (looking-at
		   (eval-when-compile
		     (concat
		      (regexp-opt '("documentstyle" "documentclass"
Stefan Monnier's avatar
Stefan Monnier committed
770
				    "begin" "subsection" "section"
771 772
				    "part" "chapter" "newcommand"
				    "renewcommand") 'words)
773 774 775 776 777 778
		      "\\|NeedsTeXFormat{LaTeX")))
		  (if (looking-at
		       "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
		      'slitex-mode
		    'latex-mode)
		'plain-tex-mode))))
779
    (funcall mode)))
780

781 782 783 784 785 786
;; `tex-mode' plays two roles: it's the parent of several sub-modes
;; but it's also the function that chooses between those submodes.
;; To tell the difference between those two cases where the function
;; might be called, we check `delay-mode-hooks'.
(define-derived-mode tex-mode text-mode "generic-TeX"
  (tex-common-initialization))
787 788 789 790 791 792 793 794 795
;; We now move the function and define it again.  This gives a warning
;; in the byte-compiler :-( but it's difficult to avoid because
;; `define-derived-mode' will necessarily define the function once
;; and we need to define it a second time for `autoload' to get the
;; proper docstring.
(defalias 'tex-mode-internal (symbol-function 'tex-mode))
;;;###autoload
(defun tex-mode ()
  "Major mode for editing files of input for TeX, LaTeX, or SliTeX.
796 797 798 799 800
Tries to determine (by looking at the beginning of the file) whether
this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode',
`latex-mode', or `slitex-mode', respectively.  If it cannot be determined,
such as if there are no commands in the file, the value of `tex-default-mode'
says which mode to use."
801 802 803 804 805
  (interactive)
  (if delay-mode-hooks
      ;; We're called from one of the children already.
      (tex-mode-internal)
    (tex-guess-mode)))
806

Jim Blandy's avatar
Jim Blandy committed
807
;;;###autoload
808
(defalias 'TeX-mode 'tex-mode)
Jim Blandy's avatar
Jim Blandy committed
809
;;;###autoload
810 811
(defalias 'plain-TeX-mode 'plain-tex-mode)
;;;###autoload
812
(defalias 'LaTeX-mode 'latex-mode)
root's avatar
root committed
813

Roland McGrath's avatar
Roland McGrath committed
814
;;;###autoload
815
(define-derived-mode plain-tex-mode tex-mode "TeX"
root's avatar
root committed
816 817 818 819 820 821 822 823 824 825 826 827 828
  "Major mode for editing files of input for plain TeX.
Makes $ and } display the characters they match.
Makes \" insert `` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.

Use \\[tex-region] to run TeX on the current region, plus a \"header\"
copied from the top of the file (containing macro definitions, etc.),
running TeX under a special subshell.  \\[tex-buffer] does the whole buffer.
\\[tex-file] saves the buffer and then processes the file.
\\[tex-print] prints the .dvi file made by any of these.
\\[tex-view] previews the .dvi file made by any of these.
\\[tex-bibtex-file] runs bibtex on the file of the current buffer.

829
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
830 831 832
mismatched $'s or braces.

Special commands:
833
\\{plain-tex-mode-map}
root's avatar
root committed
834 835 836 837 838 839 840 841 842

Mode variables:
tex-run-command
	Command string used by \\[tex-region] or \\[tex-buffer].
tex-directory
	Directory in which to create temporary files for TeX jobs
	run by \\[tex-region] or \\[tex-buffer].
tex-dvi-print-command
	Command string used by \\[tex-print] to print a .dvi file.
843 844 845
tex-alt-dvi-print-command
	Alternative command string used by \\[tex-print] (when given a prefix
	argument) to print a .dvi file.
root's avatar
root committed
846 847 848 849 850 851
tex-dvi-view-command
	Command string used by \\[tex-view] to preview a .dvi file.
tex-show-queue-command
	Command string used by \\[tex-show-print-queue] to show the print
	queue that \\[tex-print] put your job on.

Richard M. Stallman's avatar
Richard M. Stallman committed
852 853 854
Entering Plain-tex mode runs the hook `text-mode-hook', then the hook
`tex-mode-hook', and finally the hook `plain-tex-mode-hook'.  When the
special subshell is initiated, the hook `tex-shell-hook' is run."
855 856 857 858
  (set (make-local-variable 'tex-command) tex-run-command)
  (set (make-local-variable 'tex-start-of-header) "%\\*\\*start of header")
  (set (make-local-variable 'tex-end-of-header) "%\\*\\*end of header")
  (set (make-local-variable 'tex-trailer) "\\bye\n"))
root's avatar
root committed
859

Roland McGrath's avatar
Roland McGrath committed
860
;;;###autoload
861
(define-derived-mode latex-mode tex-mode "LaTeX"
root's avatar
root committed
862 863 864 865 866 867 868 869 870 871 872 873 874
  "Major mode for editing files of input for LaTeX.
Makes $ and } display the characters they match.
Makes \" insert `` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.

Use \\[tex-region] to run LaTeX on the current region, plus the preamble
copied from the top of the file (containing \\documentstyle, etc.),
running LaTeX under a special subshell.  \\[tex-buffer] does the whole buffer.
\\[tex-file] saves the buffer and then processes the file.
\\[tex-print] prints the .dvi file made by any of these.
\\[tex-view] previews the .dvi file made by any of these.
\\[tex-bibtex-file] runs bibtex on the file of the current buffer.

875
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
876 877 878
mismatched $'s or braces.

Special commands:
879
\\{latex-mode-map}
root's avatar
root committed
880 881 882 883 884 885 886 887 888

Mode variables:
latex-run-command
	Command string used by \\[tex-region] or \\[tex-buffer].
tex-directory
	Directory in which to create temporary files for LaTeX jobs
	run by \\[tex-region] or \\[tex-buffer].
tex-dvi-print-command
	Command string used by \\[tex-print] to print a .dvi file.
889 890 891
tex-alt-dvi-print-command
	Alternative command string used by \\[tex-print] (when given a prefix
	argument) to print a .dvi file.
root's avatar
root committed
892 893 894 895 896 897
tex-dvi-view-command
	Command string used by \\[tex-view] to preview a .dvi file.
tex-show-queue-command
	Command string used by \\[tex-show-print-queue] to show the print
	queue that \\[tex-print] put your job on.

898
Entering Latex mode runs the hook `text-mode-hook', then
Richard M. Stallman's avatar
Richard M. Stallman committed
899 900
`tex-mode-hook', and finally `latex-mode-hook'.  When the special
subshell is initiated, `tex-shell-hook' is run."
901 902 903 904
  (set (make-local-variable 'tex-command) latex-run-command)
  (set (make-local-variable 'tex-start-of-header)
       "\\\\document\\(style\\|class\\)")
  (set (make-local-variable 'tex-end-of-header) "\\\\begin\\s-*{document}")
905
  (set (make-local-variable 'tex-trailer) "\\end{document}\n")
906 907 908
  ;; A line containing just $$ is treated as a paragraph separator.
  ;; A line starting with $$ starts a paragraph,
  ;; but does not separate paragraphs if it has more stuff on it.
909
  (setq paragraph-start
910
	(concat "[ \t]*\\(\\$\\$\\|"
911 912 913 914 915 916 917 918
		"\\\\[][]\\|"
		"\\\\" (regexp-opt (append
				    (mapcar 'car latex-section-alist)
				    '("begin" "label" "end"
				      "item" "bibitem" "newline" "noindent"
				      "newpage" "footnote" "marginpar"
				      "parbox" "caption")) t)
		"\\>\\|\\\\[a-z]*" (regexp-opt '("space" "skip" "page") t)
919
		"\\>\\)"))
920
  (setq paragraph-separate
921
	(concat "[\f%]\\|[ \t]*\\($\\|"
922 923 924 925 926 927 928
		"\\\\[][]\\|"
		"\\\\" (regexp-opt (append
				    (mapcar 'car latex-section-alist)
				    '("begin" "label" "end" )) t)
		"\\>\\|\\\\\\(" (regexp-opt '("item" "bibitem" "newline"
					      "noindent" "newpage" "footnote"
					      "marginpar" "parbox" "caption"))
929 930
		"\\|\\$\\$\\|[a-z]*\\(space\\|skip\\|page[a-z]*\\)"
		"\\>\\)[ \t]*\\($\\|%\\)\\)"))
931 932 933
  (set (make-local-variable 'imenu-create-index-function)
       'latex-imenu-create-index)
  (set (make-local-variable 'tex-face-alist) tex-latex-face-alist)
Stefan Monnier's avatar
Stefan Monnier committed
934
  (add-hook 'fill-nobreak-predicate 'latex-fill-nobreak-predicate nil t)
Stefan Monnier's avatar
Stefan Monnier committed
935
  (set (make-local-variable 'indent-line-function) 'latex-indent)
936
  (set (make-local-variable 'fill-indent-according-to-mode) t)
937 938
  (set (make-local-variable 'outline-regexp) latex-outline-regexp)
  (set (make-local-variable 'outline-level) 'latex-outline-level)
939
  (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp)
940
  (set (make-local-variable 'skeleton-end-hook) nil))
root's avatar
root committed
941

942
;;;###autoload
943
(define-derived-mode slitex-mode latex-mode "SliTeX"
root's avatar
root committed
944 945 946 947 948 949 950 951 952 953 954 955 956
  "Major mode for editing files of input for SliTeX.
Makes $ and } display the characters they match.
Makes \" insert `` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.

Use \\[tex-region] to run SliTeX on the current region, plus the preamble
copied from the top of the file (containing \\documentstyle, etc.),
running SliTeX under a special subshell.  \\[tex-buffer] does the whole buffer.
\\[tex-file] saves the buffer and then processes the file.
\\[tex-print] prints the .dvi file made by any of these.
\\[tex-view] previews the .dvi file made by any of these.
\\[tex-bibtex-file] runs bibtex on the file of the current buffer.

957
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
958 959 960
mismatched $'s or braces.

Special commands:
961
\\{slitex-mode-map}
root's avatar
root committed
962 963 964 965 966 967 968 969 970

Mode variables:
slitex-run-command
	Command string used by \\[tex-region] or \\[tex-buffer].
tex-directory
	Directory in which to create temporary files for SliTeX jobs
	run by \\[tex-region] or \\[tex-buffer].
tex-dvi-print-command
	Command string used by \\[tex-print] to print a .dvi file.
971 972 973
tex-alt-dvi-print-command
	Alternative command string used by \\[tex-print] (when given a prefix
	argument) to print a .dvi file.
root's avatar
root committed
974 975 976 977 978 979
tex-dvi-view-command
	Command string used by \\[tex-view] to preview a .dvi file.
tex-show-queue-command
	Command string used by \\[tex-show-print-queue] to show the print
	queue that \\[tex-print] put your job on.

Richard M. Stallman's avatar
Richard M. Stallman committed
980 981 982 983
Entering SliTeX mode runs the hook `text-mode-hook', then the hook
`tex-mode-hook', then the hook `latex-mode-hook', and finally the hook
`slitex-mode-hook'.  When the special subshell is initiated, the hook
`tex-shell-hook' is run."
root's avatar
root committed
984
  (setq tex-command slitex-run-command)
985
  (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}"))
root's avatar
root committed
986 987

(defun tex-common-initialization ()
988
  ;; Regexp isearch should accept newline and formfeed as whitespace.
989
  (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+")
990
  ;; A line containing just $$ is treated as a paragraph separator.
991 992
  (set (make-local-variable 'paragraph-start)
       "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$")
993 994
  ;; A line starting with $$ starts a paragraph,
  ;; but does not separate paragraphs if it has more stuff on it.
995 996 997 998 999
  (set (make-local-variable 'paragraph-separate)
	"[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$[ \t]*$")
  (set (make-local-variable 'comment-start) "%")
  (set (make-local-variable 'comment-add) 1)
  (set (make-local-variable 'comment-start-skip)
1000
       "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
  (set (make-local-variable 'parse-sexp-ignore-comments) t)
  (set (make-local-variable 'compare-windows-whitespace)
       'tex-categorize-whitespace)
  (set (make-local-variable 'facemenu-add-face-function)
       (lambda (face end)
	 (let ((face-text (cdr (assq face tex-face-alist))))
	   (if face-text
	       face-text
	     (error "Face %s not configured for %s mode" face mode-name)))))
  (set (make-local-variable 'facemenu-end-add-face) "}")
  (set (make-local-variable 'facemenu-remove-face-function) t)
  (set (make-local-variable 'font-lock-defaults)
1013 1014
       '((tex-font-lock-keywords tex-font-lock-keywords-1
	  tex-font-lock-keywords-2 tex-font-lock-keywords-3)
1015 1016
	 nil nil ((?$ . "\"")) nil
	 ;; Who ever uses that anyway ???
1017 1018
	 (font-lock-mark-block-function . mark-paragraph)
	 (font-lock-syntactic-face-function
1019 1020 1021 1022 1023 1024
	  . tex-font-lock-syntactic-face-function)
	 (font-lock-unfontify-region-function
	  . tex-font-lock-unfontify-region)
	 (font-lock-syntactic-keywords
	  . tex-font-lock-syntactic-keywords)
	 (parse-sexp-lookup-properties . t)))
Stefan Monnier's avatar
Stefan Monnier committed
1025 1026
  ;; TABs in verbatim environments don't do what you think.
  (set (make-local-variable 'indent-tabs-mode) nil)
1027
  ;; Other vars that should be buffer-local.
root's avatar
root committed
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
  (make-local-variable 'tex-command)
  (make-local-variable 'tex-start-of-header)
  (make-local-variable 'tex-end-of-header)
  (make-local-variable 'tex-trailer))

(defun tex-categorize-whitespace (backward-limit)
  ;; compare-windows-whitespace is set to this.
  ;; This is basically a finite-state machine.
  ;; Returns a symbol telling how TeX would treat
  ;; the whitespace we are looking at: null, space, or par.
  (let ((category 'null)
	(not-finished t))
    (skip-chars-backward " \t\n\f" backward-limit)
    (while not-finished
      (cond ((looking-at "[ \t]+")
	     (goto-char (match-end 0))
1044
	     (if (eq category 'null)
root's avatar
root committed
1045 1046
		 (setq category 'space)))
	    ((looking-at "\n")
1047
	     (cond ((eq category 'newline)
root's avatar
root committed
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
		    (setq category 'par)
		    (setq not-finished nil))
		   (t
		    (setq category 'newline) ;a strictly internal state
		    (goto-char (match-end 0)))))
	    ((looking-at "\f+")
	     (setq category 'par)
	     (setq not-finished nil))
	    (t
	     (setq not-finished nil))))
    (skip-chars-forward " \t\n\f")
Richard M. Stallman's avatar