tex-mode.el 91.8 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, 1986, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
4
;;   2002, 2003, 2004, 2005 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
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
26 27
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, 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 40 41
(defvar font-lock-comment-face)
(defvar font-lock-doc-face)

42
(require 'shell)
43
(require 'compile)
44

45
(defgroup tex-file nil
46
  "TeX files and directories."
47 48 49 50
  :prefix "tex-"
  :group 'tex)

(defgroup tex-run nil
51
  "Running external commands from TeX mode."
52 53 54 55
  :prefix "tex-"
  :group 'tex)

(defgroup tex-view nil
56
  "Viewing and printing TeX files."
57 58 59
  :prefix "tex-"
  :group 'tex)

Jim Blandy's avatar
Jim Blandy committed
60
;;;###autoload
61 62 63 64 65
(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)
66

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

76
;;;###autoload
77
(defcustom tex-first-line-header-regexp nil
78 79 80
  "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,
81 82 83 84
`tex-region' always includes the first line in the TeX run."
  :type '(choice (const :tag "None" nil)
                 regexp)
  :group 'tex-file)
85

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

Jim Blandy's avatar
Jim Blandy committed
95
;;;###autoload
96 97 98 99
(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
100

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

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

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

125
;;;###autoload
Stefan Monnier's avatar
Stefan Monnier committed
126
(defcustom tex-start-options ""
127
  "*TeX options to use when starting TeX.
Stefan Monnier's avatar
Stefan Monnier committed
128 129 130 131
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
132
  :group 'tex-run
133
  :version "22.1")
134 135 136 137

;;;###autoload
(defcustom tex-start-commands "\\nonstopmode\\input"
  "*TeX commands to use when starting TeX.
Stefan Monnier's avatar
Stefan Monnier committed
138 139
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'."
140 141 142 143 144
  :type '(radio (const :tag "Interactive \(nil\)" nil)
		(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)"
		       "\\nonstopmode\\input")
		(string :tag "String at your choice"))
  :group 'tex-run
145
  :version "22.1")
146

147
(defvar latex-standard-block-names
148 149 150 151 152 153 154 155 156
  '("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")
157 158
  "Standard LaTeX block names.")

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

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

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

Jim Blandy's avatar
Jim Blandy committed
182
;;;###autoload
183
(defcustom tex-alt-dvi-print-command "lpr -d"
184
  "*Command used by \\[tex-print] with a prefix arg to print a .dvi file.
Richard M. Stallman's avatar
Richard M. Stallman committed
185 186
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.
187

Richard M. Stallman's avatar
Richard M. Stallman committed
188 189
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;
190 191 192 193 194 195
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
196 197 198 199
use."
  :type '(choice (string :tag "Command")
		 (sexp :tag "Expression"))
  :group 'tex-view)
root's avatar
root committed
200

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

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

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

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

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

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

246 247 248
(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
249
tex shell terminates.")
250

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

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
261 262 263 264 265

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

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

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

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

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

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

312
(defcustom latex-imenu-indent-string ". "
313 314 315 316 317
  "*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)

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

324 325 326 327 328
(defvar latex-metasection-list
  '("documentstyle" "documentclass"
    "begin{document}" "end{document}"
    "appendix" "frontmatter" "mainmatter" "backmatter"))

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

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

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

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

510 511 512 513 514
(defun tex-font-lock-append-prop (prop)
  (unless (memq (get-text-property (match-end 1) 'face)
		'(font-lock-comment-face tex-verbatim-face))
    prop))

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

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
(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 "{\\(?:[^{}\\]\\|\\\\.\\|{[^}]*}\\)*"))
608
       `((,(concat "[_^] *\\([^\n\\{}#]\\|" slash general "\\|#[0-9]\\|" arg "}\\)")
609 610 611 612
	  (1 (tex-font-lock-suscript (match-beginning 0))
	     append))))))
  "Experimental expressions to highlight in TeX modes.")

613 614
(defvar tex-font-lock-keywords tex-font-lock-keywords-1
  "Default expressions to highlight in TeX modes.")
615

616 617 618 619 620 621
(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 "|")
622 623 624 625 626 627 628
      ;; 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.
629 630
      ;; 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
631
      (,(concat "^\\(\\\\\\)end *{" verbs "}\\(.?\\)") (1 "|") (3 "<"))
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
      ;; ("^\\(\\\\\\)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
649 650
  "Face used for superscripts."
  :group 'tex)
651 652
(defface subscript
  '((t :height 0.8)) ;; :raise -0.3
653 654
  "Face used for subscripts."
  :group 'tex)
655

656
(defface tex-math
657
  '((t :inherit font-lock-string-face))
658 659
  "Face used to highlight TeX math expressions."
  :group 'tex)
660 661 662 663 664
;; backward-compatibility alias
(put 'tex-math-face 'face-alias 'tex-math)
(defvar tex-math-face 'tex-math)

(defface tex-verbatim
665 666
  ;; '((t :inherit font-lock-string-face))
  '((t :family "courier"))
667 668
  "Face used to highlight TeX verbatim environments."
  :group 'tex)
669 670 671
;; backward-compatibility alias
(put 'tex-verbatim-face 'face-alias 'tex-verbatim)
(defvar tex-verbatim-face 'tex-verbatim)
672 673 674

;; Use string syntax but math face for $...$.
(defun tex-font-lock-syntactic-face-function (state)
675 676 677 678 679 680 681 682 683 684 685 686 687 688
  (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))))
689

690

root's avatar
root committed
691
(defun tex-define-common-keys (keymap)
Richard M. Stallman's avatar
Richard M. Stallman committed
692
  "Define the keys that we want defined both in TeX mode and in the TeX shell."
root's avatar
root committed
693 694 695 696 697
  (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)
698 699 700

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

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

(defvar latex-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map tex-mode-map)
756
    (define-key map "\C-c\C-s" 'latex-split-block)
757 758 759 760 761 762 763 764
    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'.")
765

766 767 768 769 770
(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
771
  "Keymap for the TeX shell.
772
Inherits `shell-mode-map' with a few additions.")
root's avatar
root committed
773

774 775 776 777 778 779 780 781 782 783 784 785 786
(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.")

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

817 818 819 820 821 822
;; `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))
823 824 825 826 827 828 829 830 831
;; 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.
832 833 834 835 836
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."
837 838 839 840 841
  (interactive)
  (if delay-mode-hooks
      ;; We're called from one of the children already.
      (tex-mode-internal)
    (tex-guess-mode)))
842

843 844 845 846 847 848 849 850
;; The following three autoloaded aliases appear to conflict with
;; AUCTeX.  However, even though AUCTeX uses the mixed case variants
;; for all mode relevant variables and hooks, the invocation function
;; and setting of `major-mode' themselves need to be lowercase for
;; AUCTeX to provide a fully functional user-level replacement.  So
;; these aliases should remain as they are, in particular since AUCTeX
;; users are likely to use them.

Jim Blandy's avatar
Jim Blandy committed
851
;;;###autoload
852
(defalias 'TeX-mode 'tex-mode)
Jim Blandy's avatar
Jim Blandy committed
853
;;;###autoload
854 855
(defalias 'plain-TeX-mode 'plain-tex-mode)
;;;###autoload
856
(defalias 'LaTeX-mode 'latex-mode)
root's avatar
root committed
857

Roland McGrath's avatar
Roland McGrath committed
858
;;;###autoload
859
(define-derived-mode plain-tex-mode tex-mode "TeX"
root's avatar
root committed
860 861 862 863 864 865 866 867 868 869 870 871 872
  "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.

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

Special commands:
877
\\{plain-tex-mode-map}
root's avatar
root committed
878 879 880 881 882 883 884 885 886

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.
887 888 889
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
890 891 892 893 894 895
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
896 897 898
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."
899 900 901 902
  (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
903

Roland McGrath's avatar
Roland McGrath committed
904
;;;###autoload
905
(define-derived-mode latex-mode tex-mode "LaTeX"
root's avatar
root committed
906 907 908 909 910 911 912 913 914 915 916 917 918
  "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.

919
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
920 921 922
mismatched $'s or braces.

Special commands:
923
\\{latex-mode-map}
root's avatar
root committed
924 925 926 927 928 929 930 931 932

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.
933 934 935
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
936 937 938 939 940 941
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.

942
Entering Latex mode runs the hook `text-mode-hook', then
Richard M. Stallman's avatar
Richard M. Stallman committed
943 944
`tex-mode-hook', and finally `latex-mode-hook'.  When the special
subshell is initiated, `tex-shell-hook' is run."
945 946 947 948
  (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}")
949
  (set (make-local-variable 'tex-trailer) "\\end{document}\n")
950 951 952
  ;; 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.
953
  (setq paragraph-start
954
	(concat "[ \t]*\\(\\$\\$\\|"
955 956 957 958 959 960 961 962
		"\\\\[][]\\|"
		"\\\\" (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)
963
		"\\>\\)"))
964
  (setq paragraph-separate
965
	(concat "[\f%]\\|[ \t]*\\($\\|"
966 967 968 969 970 971 972
		"\\\\[][]\\|"
		"\\\\" (regexp-opt (append
				    (mapcar 'car latex-section-alist)
				    '("begin" "label" "end" )) t)
		"\\>\\|\\\\\\(" (regexp-opt '("item" "bibitem" "newline"
					      "noindent" "newpage" "footnote"
					      "marginpar" "parbox" "caption"))
973 974
		"\\|\\$\\$\\|[a-z]*\\(space\\|skip\\|page[a-z]*\\)"
		"\\>\\)[ \t]*\\($\\|%\\)\\)"))
975 976 977
  (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
978
  (add-hook 'fill-nobreak-predicate 'latex-fill-nobreak-predicate nil t)
Stefan Monnier's avatar
Stefan Monnier committed
979
  (set (make-local-variable 'indent-line-function) 'latex-indent)
980
  (set (make-local-variable 'fill-indent-according-to-mode) t)
981 982
  (set (make-local-variable 'outline-regexp) latex-outline-regexp)
  (set (make-local-variable 'outline-level) 'latex-outline-level)
983
  (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp)
984
  (set (make-local-variable 'skeleton-end-hook) nil))
root's avatar
root committed
985

986
;;;###autoload
987
(define-derived-mode slitex-mode latex-mode "SliTeX"
root's avatar
root committed
988 989 990 991 992 993 994 995 996 997 998 999 1000
  "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.

1001
Use \\[tex-validate-buffer] to check buffer for paragraphs containing
root's avatar
root committed
1002 1003 1004
mismatched $'s or braces.

Special commands:
1005
\\{slitex-mode-map}
root's avatar
root committed
1006 1007 1008 <