tex-mode.el 90.6 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 4
;; Copyright (C) 1985, 1986, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
;;   2002, 2003, 2004  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
  :version "22.1")
131 132 133 134

;;;###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
  :type '(radio (const :tag "Interactive \(nil\)" nil)
		(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)"
		       "\\nonstopmode\\input")
		(string :tag "String at your choice"))
  :group 'tex-run
142
  :version "22.1")
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 200 201
(defcustom tex-dvi-view-command
  '(cond
    ((eq window-system 'x) "xdvi")
202
    ((eq window-system 'w32) "yap")
203
    (t "dvi2tty * | cat -s"))
Richard M. Stallman's avatar
Richard M. Stallman committed
204
  "*Command used by \\[tex-view] to display a `.dvi' file.
205
If it is a string, that specifies the command directly.
Richard M. Stallman's avatar
Richard M. Stallman committed
206
If this string contains an asterisk (`*'), that is replaced by the file name;
207
otherwise, the file name, preceded by a space, is added at the end.
208

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

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

Jim Blandy's avatar
Jim Blandy committed
220
;;;###autoload
221
(defcustom tex-default-mode 'latex-mode
root's avatar
root committed
222 223 224
  "*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.
225 226 227
Normally set to either `plain-tex-mode' or `latex-mode'."
  :type 'function
  :group 'tex)
root's avatar
root committed
228

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

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

243 244 245
(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
246
tex shell terminates.")
247

Stefan Monnier's avatar
Stefan Monnier committed
248
(defvar tex-command "tex"
249
  "*Command to run TeX.
Stefan Monnier's avatar
Stefan Monnier committed
250
If this string contains an asterisk \(`*'\), that is replaced by the file name;
251 252 253
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.
254 255 256 257

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
258 259 260 261 262

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

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

(defvar tex-end-of-header nil
266
  "Regular expression used by \\[tex-region] to find end of file's header.")
root's avatar
root committed
267 268 269

(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
270
The value of `tex-directory' is appended to this, separated by a space.")
root's avatar
root committed
271 272 273 274 275 276 277 278 279 280 281 282

(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].")

283 284 285 286 287 288 289 290 291 292
(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)
293 294
    ;; ~ 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}).
295 296 297 298 299 300 301 302
    (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
303
  "Syntax table used while in TeX mode.")
304 305 306 307

;;;;
;;;; Imenu support
;;;;
root's avatar
root committed
308

309
(defcustom latex-imenu-indent-string ". "
310 311 312 313 314
  "*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)

315 316 317 318 319 320
(defvar latex-section-alist
  '(("part" . 0) ("chapter" . 1)
    ("section" . 2) ("subsection" . 3)
    ("subsubsection" . 4)
    ("paragraph" . 5) ("subparagraph" . 6)))

321 322 323 324 325
(defvar latex-metasection-list
  '("documentstyle" "documentclass"
    "begin{document}" "end{document}"
    "appendix" "frontmatter" "mainmatter" "backmatter"))

326
(defun latex-imenu-create-index ()
327 328 329 330 331 332 333
  "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)
334 335 336 337 338 339 340 341 342 343 344 345
    (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))
346
      (while (search-forward-regexp section-regexp nil t)
347 348 349 350 351
	(let ((start (match-beginning 0))
	      (here (point))
	      (i (cdr (assoc (buffer-substring-no-properties
			      (match-beginning 1)
			      (match-end 1))
352
			     latex-section-alist))))
353 354 355 356 357 358
	  (backward-char 1)
	  (condition-case err
	      (progn
		;; Using sexps allows some use of matching {...} inside
		;; titles.
		(forward-sexp 1)
359 360 361 362 363 364 365 366
		(push (cons (concat (apply 'concat
					   (make-list
					    (max 0 (- i i0))
					    latex-imenu-indent-string))
				    (buffer-substring-no-properties
				     here (1- (point))))
			    start)
		      menu))
367 368 369 370 371 372
	    (error nil))))

      ;; Look for included material.
      (goto-char (point-min))
      (while (search-forward-regexp
	      "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\
373
\[ \t]*{\\([^}\n]+\\)}"
374
	      nil t)
375 376 377 378 379 380 381 382
	(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))
383 384 385

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

      ;; Sort in increasing buffer position order.
      (sort menu (function (lambda (a b) (< (cdr a) (cdr b))))))))
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 444 445 446 447

;;;;
;;;; 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"
448 449 450
			"newcommand" "renewcommand" "providecommand"
			"newenvironment" "renewenvironment"
			"newtheorem" "renewtheorem")
451 452 453 454 455 456 457 458
		      t))
	   (variables (regexp-opt
		       '("newcounter" "newcounter*" "setcounter" "addtocounter"
			 "setlength" "addtolength" "settowidth")
		       t))
	   (includes (regexp-opt
		      '("input" "include" "includeonly" "bibliography"
			"epsfig" "psfig" "epsf" "nofiles" "usepackage"
459
			"documentstyle" "documentclass" "verbatiminput"
460 461
			"includegraphics" "includegraphics*"
			"url" "nolinkurl")
462 463 464
		      t))
	   ;; Miscellany.
	   (slash "\\\\")
465 466 467 468
	   (opt " *\\(\\[[^]]*\\] *\\)*")
	   ;; This would allow highlighting \newcommand\CMD but requires
	   ;; adapting subgroup numbers below.
	   ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)"))
469
	   (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
470
      (list
471 472 473 474
       ;; font-lock-syntactic-keywords causes the \ of \end{verbatim} to be
       ;; highlighted as tex-verbatim-face.  Let's undo that.
       ;; This is ugly and brittle :-(  --Stef
       '("^\\(\\\\\\)end" (1 (get-text-property (match-end 1) 'face) t))
Stefan Monnier's avatar
Stefan Monnier committed
475 476 477 478 479 480
       ;; 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)
481 482
       ;; Heading args.
       (list (concat slash headings "\\*?" opt arg)
483 484 485 486 487 488 489 490 491 492
	     ;; 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
493 494
	     ;; as improves the behavior in the very rare case where you do
	     ;; have a comment in ARG.
495
	     3 'font-lock-function-name-face 'keep)
496 497
       (list (concat slash "\\(?:provide\\|\\(?:re\\)?new\\)command\\** *\\(\\\\[A-Za-z@]+\\)")
	     1 'font-lock-function-name-face 'keep)
498
       ;; Variable args.
499
       (list (concat slash variables " *" arg) 2 'font-lock-variable-name-face)
500 501 502
       ;; Include args.
       (list (concat slash includes opt arg) 3 'font-lock-builtin-face)
       ;; Definitions.  I think.
503
       '("^[ \t]*\\\\def *\\\\\\(\\(\\w\\|@\\)+\\)"
504
	 1 font-lock-function-name-face))))
505 506
  "Subdued expressions to highlight in TeX modes.")

507 508 509 510 511
(defun tex-font-lock-append-prop (prop)
  (unless (memq (get-text-property (match-end 1) 'face)
		'(font-lock-comment-face tex-verbatim-face))
    prop))

512 513 514 515 516
(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.
517
	    (bold (regexp-opt '("textbf" "textsc" "textup"
518
				"boldsymbol" "pmb") t))
519
	    (italic (regexp-opt '("textit" "textsl" "emph") t))
520 521
	    ;; FIXME: unimplemented yet.
	    ;; (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t))
522 523 524 525
	    ;;
	    ;; Names of commands whose arg should be fontified as a citation.
	    (citations (regexp-opt
			'("label" "ref" "pageref" "vref" "eqref"
526
			  "cite" "nocite" "index" "glossary" "bibitem"
527 528 529
			  ;; These are text, rather than citations.
			  ;; "caption" "footnote" "footnotemark" "footnotetext"
			  )
530 531 532
			t))
	    ;;
	    ;; Names of commands that should be fontified.
533 534 535 536 537 538
	    (specials-1 (regexp-opt '("\\" "\\*") t)) ;; "-"
	    (specials-2 (regexp-opt
			 '("linebreak" "nolinebreak" "pagebreak" "nopagebreak"
			   "newline" "newpage" "clearpage" "cleardoublepage"
			   "displaybreak" "allowdisplaybreaks"
			   "enlargethispage") t))
539 540 541 542
	    (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)")
	    ;;
	    ;; Miscellany.
	    (slash "\\\\")
543
	    (opt " *\\(\\[[^]]*\\] *\\)*")
544
	    (args "\\(\\(?:[^{}&\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")
545
	    (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
546 547 548 549 550
       (list
	;;
	;; Citation args.
	(list (concat slash citations opt arg) 3 'font-lock-constant-face)
	;;
551
	;; Text between `` quotes ''.
Stefan Monnier's avatar
Stefan Monnier committed
552
	(cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "«") t)
553
		      "[^'\">{]+"	;a bit pessimistic
Stefan Monnier's avatar
Stefan Monnier committed
554
		      (regexp-opt `("''" "\">" "\"'" ">>" "»") t))
555 556
	      'font-lock-string-face)
	;;
557
	;; Command names, special and general.
558 559 560
	(cons (concat slash specials-1) 'font-lock-warning-face)
	(list (concat "\\(" slash specials-2 "\\)\\([^a-zA-Z@]\\|\\'\\)")
	      1 'font-lock-warning-face)
561 562 563 564
	(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.
565 566 567 568
	(list (concat slash bold " *" arg) 2
	      '(tex-font-lock-append-prop 'bold) 'append)
	(list (concat slash italic " *" arg) 2
	      '(tex-font-lock-append-prop 'italic) 'append)
569
	;; (list (concat slash type arg) 2 '(quote bold-italic) 'append)
570 571
	;;
	;; Old-style bf/em/it/sl.  Stop at `\\' and un-escaped `&', for tables.
572
	(list (concat "\\\\\\(em\\|it\\|sl\\)\\>" args)
573
	      2 '(tex-font-lock-append-prop 'italic) 'append)
574 575
	;; This is separate from the previous one because of cases like
	;; {\em foo {\bf bar} bla} where both match.
576 577
	(list (concat "\\\\\\(bf\\)\\>" args)
	      2 '(tex-font-lock-append-prop 'bold) 'append)))))
578 579
   "Gaudy expressions to highlight in TeX modes.")

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
(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.")

610 611
(defvar tex-font-lock-keywords tex-font-lock-keywords-1
  "Default expressions to highlight in TeX modes.")
612

613 614 615 616 617 618
(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 "|")
619 620 621 622 623 624 625
      ;; Technically, we'd like to put the "|" property on the \n preceding
      ;; the \end, but this would have 2 disadvantages:
      ;; 1 - it's wrong if the verbatim env is empty (the same \n is used to
      ;;     start and end the fenced-string).
      ;; 2 - font-lock considers the preceding \n as being part of the
      ;;     preceding line, so things gets screwed every time the previous
      ;;     line is re-font-locked on its own.
626 627
      ;; There's a hack in tex-font-lock-keywords-1 to remove the verbatim
      ;; face from the \ but C-M-f still jumps to the wrong spot :-(  --Stef
628
      (,(concat "^\\(\\\\\\)end *{" verbs "}\\(.?\\)") (1 "|") (3 "<"))
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
      ;; ("^\\(\\\\\\)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.")
650 651 652 653 654

(defface tex-math-face
  '((t :inherit font-lock-string-face))
  "Face used to highlight TeX math expressions.")
(defvar tex-math-face 'tex-math-face)
655 656 657 658 659
(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)
660 661 662

;; Use string syntax but math face for $...$.
(defun tex-font-lock-syntactic-face-function (state)
663 664 665 666 667 668 669 670 671 672 673 674 675 676
  (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))))
677

678

root's avatar
root committed
679
(defun tex-define-common-keys (keymap)
Richard M. Stallman's avatar
Richard M. Stallman committed
680
  "Define the keys that we want defined both in TeX mode and in the TeX shell."
root's avatar
root committed
681 682 683 684 685
  (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)
686 687 688

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

689 690
  (define-key keymap [menu-bar tex tex-kill-job]
    '(menu-item "Tex Kill" tex-kill-job :enable (tex-shell-running)))
691
  (define-key keymap [menu-bar tex tex-recenter-output-buffer]
692 693
    '(menu-item "Tex Recenter" tex-recenter-output-buffer
                :enable (get-buffer "*tex-shell*")))
694 695
  (define-key keymap [menu-bar tex tex-show-print-queue]
    '("Show Print Queue" . tex-show-print-queue))
696
  (define-key keymap [menu-bar tex tex-alt-print]
697 698 699 700 701 702 703 704 705
    '(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)))
706
    (set-keymap-parent map text-mode-map)
707 708 709 710 711 712 713 714 715 716 717 718 719
    (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)
720
    (define-key map "\C-c\C-c" 'tex-compile)
721
    (define-key map "\C-c\C-i" 'tex-bibtex-file)
722 723
    (define-key map "\C-c\C-o" 'latex-insert-block)
    (define-key map "\C-c\C-e" 'latex-close-block)
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
    (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)
739 740 741 742 743
 "Keymap shared by TeX modes.")

(defvar latex-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map tex-mode-map)
744
    (define-key map "\C-c\C-s" 'latex-split-block)
745 746 747 748 749 750 751 752
    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'.")
753

754 755 756 757 758
(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
759
  "Keymap for the TeX shell.
760
Inherits `shell-mode-map' with a few additions.")
root's avatar
root committed
761

762 763 764 765 766 767 768 769 770 771 772 773 774
(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.")

775 776
;; This would be a lot simpler if we just used a regexp search,
;; but then it would be too slow.
777
(defun tex-guess-mode ()
778
  (let ((mode tex-default-mode) slash comment)
root's avatar
root committed
779 780 781 782 783 784 785
    (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))))))
786 787 788 789 790 791
      (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
792
				    "begin" "subsection" "section"
793 794
				    "part" "chapter" "newcommand"
				    "renewcommand") 'words)
795
		      "\\|NeedsTeXFormat{LaTeX")))
796 797 798 799
		  (if (and (looking-at
			    "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
			   ;; SliTeX is almost never used any more nowadays.
			   (tex-executable-exists-p slitex-run-command))
800 801 802
		      'slitex-mode
		    'latex-mode)
		'plain-tex-mode))))
803
    (funcall mode)))
804

805 806 807 808 809 810
;; `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))
811 812 813 814 815 816 817 818 819
;; 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.
820 821 822 823 824
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."
825 826 827 828 829
  (interactive)
  (if delay-mode-hooks
      ;; We're called from one of the children already.
      (tex-mode-internal)
    (tex-guess-mode)))
830

Jim Blandy's avatar
Jim Blandy committed
831
;;;###autoload
832
(defalias 'TeX-mode 'tex-mode)
Jim Blandy's avatar
Jim Blandy committed
833
;;;###autoload
834 835
(defalias 'plain-TeX-mode 'plain-tex-mode)
;;;###autoload
836
(defalias 'LaTeX-mode 'latex-mode)
root's avatar
root committed
837

Roland McGrath's avatar
Roland McGrath committed
838
;;;###autoload
839
(define-derived-mode plain-tex-mode tex-mode "TeX"
root's avatar
root committed
840 841 842 843 844 845 846 847 848 849 850 851 852
  "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.

853
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
854 855 856
mismatched $'s or braces.

Special commands:
857
\\{plain-tex-mode-map}
root's avatar
root committed
858 859 860 861 862 863 864 865 866

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.
867 868 869
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
870 871 872 873 874 875
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
876 877 878
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."
879 880 881 882
  (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
883

Roland McGrath's avatar
Roland McGrath committed
884
;;;###autoload
885
(define-derived-mode latex-mode tex-mode "LaTeX"
root's avatar
root committed
886 887 888 889 890 891 892 893 894 895 896 897 898
  "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.

899
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
900 901 902
mismatched $'s or braces.

Special commands:
903
\\{latex-mode-map}
root's avatar
root committed
904 905 906 907 908 909 910 911 912

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.
913 914 915
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
916 917 918 919 920 921
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.

922
Entering Latex mode runs the hook `text-mode-hook', then
Richard M. Stallman's avatar
Richard M. Stallman committed
923 924
`tex-mode-hook', and finally `latex-mode-hook'.  When the special
subshell is initiated, `tex-shell-hook' is run."
925 926 927 928
  (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}")
929
  (set (make-local-variable 'tex-trailer) "\\end{document}\n")
930 931 932
  ;; 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.
933
  (setq paragraph-start
934
	(concat "[ \t]*\\(\\$\\$\\|"
935 936 937 938 939 940 941 942
		"\\\\[][]\\|"
		"\\\\" (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)
943
		"\\>\\)"))
944
  (setq paragraph-separate
945
	(concat "[\f%]\\|[ \t]*\\($\\|"
946 947 948 949 950 951 952
		"\\\\[][]\\|"
		"\\\\" (regexp-opt (append
				    (mapcar 'car latex-section-alist)
				    '("begin" "label" "end" )) t)
		"\\>\\|\\\\\\(" (regexp-opt '("item" "bibitem" "newline"
					      "noindent" "newpage" "footnote"
					      "marginpar" "parbox" "caption"))
953 954
		"\\|\\$\\$\\|[a-z]*\\(space\\|skip\\|page[a-z]*\\)"
		"\\>\\)[ \t]*\\($\\|%\\)\\)"))
955 956 957
  (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
958
  (add-hook 'fill-nobreak-predicate 'latex-fill-nobreak-predicate nil t)
Stefan Monnier's avatar
Stefan Monnier committed
959
  (set (make-local-variable 'indent-line-function) 'latex-indent)
960
  (set (make-local-variable 'fill-indent-according-to-mode) t)
961 962
  (set (make-local-variable 'outline-regexp) latex-outline-regexp)
  (set (make-local-variable 'outline-level) 'latex-outline-level)
963
  (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp)
964
  (set (make-local-variable 'skeleton-end-hook) nil))
root's avatar
root committed
965

966
;;;###autoload
967
(define-derived-mode slitex-mode latex-mode "SliTeX"
root's avatar
root committed
968 969 970 971 972 973 974 975 976 977 978 979 980
  "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.

981
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
982 983 984
mismatched $'s or braces.

Special commands:
985
\\{slitex-mode-map}
root's avatar
root committed
986 987 988 989 990 991 992 993 994

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.
995 996 997
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
998 999 1000 1001 1002 1003
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
1004 1005 1006 1007
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
1008
  (setq tex-command slitex-run-command)
1009
  (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}"))
root's avatar
root committed
1010 1011

(defun tex-common-initialization ()
1012
  ;; Regexp isearch should accept newline and formfeed as whitespace.
1013
  (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+")
1014
  ;; A line containing just $$ is treated as a paragraph separator.
1015 1016
  (set (make-local-variable 'paragraph-start)
       "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$")
1017 1018
  ;; A line starting with $$ starts a paragraph,
  ;; but does not separate paragraphs if it has more stuff on it.
1019 1020 1021 1022 1023
  (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)
1024
       "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
  (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)
1037 1038
       '((tex-font-lock-keywords tex-font-lock-keywords-1
	  tex-font-lock-keywords-2 tex-font-lock-keywords-3)
1039 1040
	 nil nil ((?$ . "\"")) nil
	 ;; Who ever uses that anyway ???
1041 1042
	 (font-lock-mark-block-function . mark-paragraph)
	 (font-lock-syntactic-face-function
1043 1044 1045 1046 1047 1048
	  . 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
1049 1050
  ;; TABs in verbatim environments don't do what you think.
  (set (make-local-variable 'indent-tabs-mode) nil)
Stefan Monnier's avatar