root/trunk/lisp/textmodes/tex-mode.el

Revision 4220, 94.5 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- coding: utf-8 -*-
2
3 ;; Copyright (C) 1985, 1986, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
4 ;;   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Maintainer: FSF
7 ;; Keywords: tex
8
9 ;; Contributions over the years by William F. Schelter, Dick King,
10 ;; Stephen Gildea, Michael Prange, Jacob Gore, and Edward M. Reingold.
11
12 ;; This file is part of GNU Emacs.
13
14 ;; GNU Emacs is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; any later version.
18
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;; GNU General Public License for more details.
23
24 ;; 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
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
28
29 ;;; Commentary:
30
31 ;;; Code:
32
33 ;; Pacify the byte-compiler
34 (eval-when-compile
35   (require 'compare-w)
36   (require 'cl)
37   (require 'skeleton))
38
39 (defvar font-lock-comment-face)
40 (defvar font-lock-doc-face)
41
42 (require 'shell)
43 (require 'compile)
44
45 (defgroup tex-file nil
46   "TeX files and directories."
47   :prefix "tex-"
48   :group 'tex)
49
50 (defgroup tex-run nil
51   "Running external commands from TeX mode."
52   :prefix "tex-"
53   :group 'tex)
54
55 (defgroup tex-view nil
56   "Viewing and printing TeX files."
57   :prefix "tex-"
58   :group 'tex)
59
60 ;;;###autoload
61 (defcustom tex-shell-file-name nil
62   "*If non-nil, the shell file name to run in the subshell used to run TeX."
63   :type '(choice (const :tag "None" nil)
64                  string)
65   :group 'tex-run)
66
67 ;;;###autoload
68 (defcustom tex-directory "."
69   "*Directory in which temporary files are written.
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 `\\input' commands with relative directories."
73   :type 'directory
74   :group 'tex-file)
75
76 ;;;###autoload
77 (defcustom tex-first-line-header-regexp nil
78   "Regexp for matching a first line which `tex-region' should include.
79 If this is non-nil, it should be a regular expression string;
80 if it matches the first line of the file,
81 `tex-region' always includes the first line in the TeX run."
82   :type '(choice (const :tag "None" nil)
83                  regexp)
84   :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 The command `tex-file' runs TeX on the file specified by `tex-main-file'
90 if the variable is non-nil."
91   :type '(choice (const :tag "None" nil)
92                  file)
93   :group 'tex-file)
94
95 ;;;###autoload
96 (defcustom tex-offer-save t
97   "*If non-nil, ask about saving modified buffers before \\[tex-file] is run."
98   :type 'boolean
99   :group 'tex-file)
100
101 ;;;###autoload
102 (defcustom tex-run-command "tex"
103   "*Command used to run TeX subjob.
104 TeX Mode sets `tex-command' to this string.
105 See the documentation of that variable."
106   :type 'string
107   :group 'tex-run)
108
109 ;;;###autoload
110 (defcustom latex-run-command "latex"
111   "*Command used to run LaTeX subjob.
112 LaTeX Mode sets `tex-command' to this string.
113 See the documentation of that variable."
114   :type 'string
115   :group 'tex-run)
116
117 ;;;###autoload
118 (defcustom slitex-run-command "slitex"
119   "*Command used to run SliTeX subjob.
120 SliTeX Mode sets `tex-command' to this string.
121 See the documentation of that variable."
122   :type 'string
123   :group 'tex-run)
124
125 ;;;###autoload
126 (defcustom tex-start-options ""
127   "*TeX options to use when starting TeX.
128 These immediately precede the commands in `tex-start-commands'
129 and the input file name, with no separating space and are not shell-quoted.
130 If nil, TeX runs with no options.  See the documentation of `tex-command'."
131   :type 'string
132   :group 'tex-run
133   :version "22.1")
134
135 ;;;###autoload
136 (defcustom tex-start-commands "\\nonstopmode\\input"
137   "*TeX commands to use when starting TeX.
138 They are shell-quoted and precede the input file name, with a separating space.
139 If nil, no commands are used.  See the documentation of `tex-command'."
140   :type '(radio (const :tag "Interactive \(nil\)" nil)
141                 (const :tag "Nonstop \(\"\\nonstopmode\\input\"\)"
142                        "\\nonstopmode\\input")
143                 (string :tag "String at your choice"))
144   :group 'tex-run
145   :version "22.1")
146
147 (defvar latex-standard-block-names
148   '("abstract"          "array"         "center"        "description"
149     "displaymath"       "document"      "enumerate"     "eqnarray"
150     "eqnarray*"         "equation"      "figure"        "figure*"
151     "flushleft"         "flushright"    "itemize"       "letter"
152     "list"              "minipage"      "picture"       "quotation"
153     "quote"             "slide"         "sloppypar"     "tabbing"
154     "table"             "table*"        "tabular"       "tabular*"
155     "thebibliography"   "theindex*"     "titlepage"     "trivlist"
156     "verbatim"          "verbatim*"     "verse"         "math")
157   "Standard LaTeX block names.")
158
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   :type '(repeat string)
164   :group 'tex-run)
165
166 ;;;###autoload
167 (defcustom tex-bibtex-command "bibtex"
168   "*Command used by `tex-bibtex-file' to gather bibliographic data.
169 If this string contains an asterisk (`*'), that is replaced by the file name;
170 otherwise, the file name, preceded by blank, is added at the end."
171   :type 'string
172   :group 'tex-run)
173
174 ;;;###autoload
175 (defcustom tex-dvi-print-command "lpr -d"
176   "*Command used by \\[tex-print] to print a .dvi file.
177 If this string contains an asterisk (`*'), that is replaced by the file name;
178 otherwise, the file name, preceded by blank, is added at the end."
179   :type 'string
180   :group 'tex-view)
181
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.
185 If this string contains an asterisk (`*'), that is replaced by the file name;
186 otherwise, the file name, preceded by blank, is added at the end.
187
188 If two printers are not enough of a choice, you can set the variable
189 `tex-alt-dvi-print-command' to an expression that asks what you want;
190 for example,
191
192     (setq tex-alt-dvi-print-command
193          '(format \"lpr -P%s\" (read-string \"Use printer: \")))
194
195 would tell \\[tex-print] with a prefix argument to ask you which printer to
196 use."
197   :type '(choice (string :tag "Command")
198                  (sexp :tag "Expression"))
199   :group 'tex-view)
200
201 ;;;###autoload
202 (defcustom tex-dvi-view-command
203   '(cond
204     ((eq window-system 'x) "xdvi")
205     ((eq window-system 'w32) "yap")
206     (t "dvi2tty * | cat -s"))
207   "*Command used by \\[tex-view] to display a `.dvi' file.
208 If it is a string, that specifies the command directly.
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 If the value is a form, it is evaluated to get the command to use."
213   :type '(choice (const nil) string sexp)
214   :group 'tex-view)
215
216 ;;;###autoload
217 (defcustom tex-show-queue-command "lpq"
218   "*Command used by \\[tex-show-print-queue] to show the print queue.
219 Should show the queue(s) that \\[tex-print] puts jobs on."
220   :type 'string
221   :group 'tex-view)
222
223 ;;;###autoload
224 (defcustom tex-default-mode 'latex-mode
225   "*Mode to enter for a new file that might be either TeX or LaTeX.
226 This variable is used when it can't be determined whether the file
227 is plain TeX or LaTeX or what because the file contains no commands.
228 Normally set to either `plain-tex-mode' or `latex-mode'."
229   :type 'function
230   :group 'tex)
231
232 ;;;###autoload
233 (defcustom tex-open-quote "``"
234   "*String inserted by typing \\[tex-insert-quote] to open a quotation."
235   :type 'string
236   :options '("``" "\"<" "\"`" "<<" "«")
237   :group 'tex)
238
239 ;;;###autoload
240 (defcustom tex-close-quote "''"
241   "*String inserted by typing \\[tex-insert-quote] to close a quotation."
242   :type 'string
243   :options '("''" "\">" "\"'" ">>" "»")
244   :group 'tex)
245
246 (defvar tex-last-temp-file nil
247   "Latest temporary file generated by \\[tex-region] and \\[tex-buffer].
248 Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the
249 tex shell terminates.")
250
251 (defvar tex-command "tex"
252   "*Command to run TeX.
253 If this string contains an asterisk \(`*'\), that is replaced by the file name;
254 otherwise the value of `tex-start-options', the \(shell-quoted\)
255 value of `tex-start-commands', and the file name are added at the end
256 with blanks as separators.
257
258 In TeX, LaTeX, and SliTeX Mode this variable becomes buffer local.
259 In these modes, use \\[set-variable] if you want to change it for the
260 current buffer.")
261
262 (defvar tex-trailer nil
263   "String appended after the end of a region sent to TeX by \\[tex-region].")
264
265 (defvar tex-start-of-header nil
266   "Regular expression used by \\[tex-region] to find start of file's header.")
267
268 (defvar tex-end-of-header nil
269   "Regular expression used by \\[tex-region] to find end of file's header.")
270
271 (defvar tex-shell-cd-command "cd"
272   "Command to give to shell running TeX to change directory.
273 The value of `tex-directory' is appended to this, separated by a space.")
274
275 (defvar tex-zap-file nil
276   "Temporary file name used for text being sent as input to TeX.
277 Should be a simple file name with no extension or directory specification.")
278
279 (defvar tex-last-buffer-texed nil
280   "Buffer which was last TeXed.")
281
282 (defvar tex-print-file nil
283   "File name that \\[tex-print] prints.
284 Set by \\[tex-region], \\[tex-buffer], and \\[tex-file].")
285
286 (defvar tex-mode-syntax-table
287   (let ((st (make-syntax-table)))
288     (modify-syntax-entry ?% "<" st)
289     (modify-syntax-entry ?\n ">" st)
290     (modify-syntax-entry ?\f ">" st)
291     (modify-syntax-entry ?\C-@ "w" st)
292     (modify-syntax-entry ?' "w" st)
293     (modify-syntax-entry ?@ "_" st)
294     (modify-syntax-entry ?* "_" st)
295     (modify-syntax-entry ?\t " " st)
296     ;; ~ is printed by TeX as a space, but it's semantics in the syntax
297     ;; of TeX is not `whitespace' (i.e. it's just like \hspace{foo}).
298     (modify-syntax-entry ?~ "." st)
299     (modify-syntax-entry ?$ "$$" st)
300     (modify-syntax-entry ?\\ "/" st)
301     (modify-syntax-entry ?\" "." st)
302     (modify-syntax-entry ?& "." st)
303     (modify-syntax-entry ?_ "." st)
304     (modify-syntax-entry ?^ "." st)
305     st)
306   "Syntax table used while in TeX mode.")
307
308 ;;;;
309 ;;;; Imenu support
310 ;;;;
311
312 (defcustom latex-imenu-indent-string ". "
313   "*String to add repeated in front of nested sectional units for Imenu.
314 An alternative value is \" . \", if you use a font with a narrow period."
315   :type 'string
316   :group 'tex)
317
318 (defvar latex-section-alist
319   '(("part" . 0) ("chapter" . 1)
320     ("section" . 2) ("subsection" . 3)
321     ("subsubsection" . 4)
322     ("paragraph" . 5) ("subparagraph" . 6)))
323
324 (defvar latex-metasection-list
325   '("documentstyle" "documentclass"
326     "begin{document}" "end{document}"
327     "appendix" "frontmatter" "mainmatter" "backmatter"))
328
329 (defun latex-imenu-create-index ()
330   "Generate an alist for imenu from a LaTeX buffer."
331   (let ((section-regexp
332          (concat "\\\\" (regexp-opt (mapcar 'car latex-section-alist) t)
333                  "\\*?[ \t]*{"))
334         (metasection-regexp
335          (concat "\\\\" (regexp-opt latex-metasection-list t)))
336         i0 menu case-fold-search)
337     (save-excursion
338       ;; Find the top-most level in this file but don't allow it to be
339       ;; any deeper than "section" (which is top-level in an article).
340       (goto-char (point-min))
341       (if (search-forward-regexp "\\\\part\\*?[ \t]*{" nil t)
342           (setq i0 0)
343         (if (search-forward-regexp "\\\\chapter\\*?[ \t]*{" nil t)
344             (setq i0 1)
345           (setq i0 2)))
346
347       ;; Look for chapters and sections.
348       (goto-char (point-min))
349       (while (search-forward-regexp section-regexp nil t)
350         (let ((start (match-beginning 0))
351               (here (point))
352               (i (cdr (assoc (buffer-substring-no-properties
353                               (match-beginning 1)
354                               (match-end 1))
355                              latex-section-alist))))
356           (backward-char 1)
357           (condition-case err
358               (progn
359                 ;; Using sexps allows some use of matching {...} inside
360                 ;; titles.
361                 (forward-sexp 1)
362                 (push (cons (concat (apply 'concat
363                                            (make-list
364                                             (max 0 (- i i0))
365                                             latex-imenu-indent-string))
366                                     (buffer-substring-no-properties
367                                      here (1- (point))))
368                             start)
369                       menu))
370             (error nil))))
371
372       ;; Look for included material.
373       (goto-char (point-min))
374       (while (search-forward-regexp
375               "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\
376 \[ \t]*{\\([^}\n]+\\)}"
377               nil t)
378         (push (cons (concat "<<" (buffer-substring-no-properties
379                                   (match-beginning 2)
380                                   (match-end 2))
381                             (if (= (char-after (match-beginning 1)) ?b)
382                                 ".bbl"
383                               ".tex"))
384                     (match-beginning 0))
385               menu))
386
387       ;; Look for \frontmatter, \mainmatter, \backmatter, and \appendix.
388       (goto-char (point-min))
389       (while (search-forward-regexp metasection-regexp nil t)
390         (push (cons "--" (match-beginning 0)) menu))
391
392       ;; Sort in increasing buffer position order.
393       (sort menu (function (lambda (a b) (< (cdr a) (cdr b))))))))
394
395 ;;;;
396 ;;;; Outline support
397 ;;;;
398
399 (defvar latex-outline-regexp
400   (concat "\\\\"
401           (regexp-opt (append latex-metasection-list
402                               (mapcar 'car latex-section-alist)) t)))
403
404 (defun latex-outline-level ()
405   (if (looking-at latex-outline-regexp)
406       (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1))
407     1000))
408
409 ;;;;
410 ;;;; Font-Lock support
411 ;;;;
412
413 ;(defvar tex-font-lock-keywords
414 ;  ;; Regexps updated with help from Ulrik Dickow <dickow@nbi.dk>.
415 ;  '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
416 ;     2 font-lock-function-name-face)
417 ;    ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
418 ;     2 font-lock-constant-face)
419 ;    ;; It seems a bit dubious to use `bold' and `italic' faces since we might
420 ;    ;; not be able to display those fonts.
421 ;    ("{\\\\bf\\([^}]+\\)}" 1 'bold keep)
422 ;    ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep)
423 ;    ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face)
424 ;    ("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep))
425 ;  ;; Rewritten and extended for LaTeX2e by Ulrik Dickow <dickow@nbi.dk>.
426 ;  '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
427 ;     2 font-lock-function-name-face)
428 ;    ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
429 ;     2 font-lock-constant-face)
430 ;    ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face)
431 ;    "\\\\\\([a-zA-Z@]+\\|.\\)"
432 ;    ;; It seems a bit dubious to use `bold' and `italic' faces since we might
433 ;    ;; not be able to display those fonts.
434 ;    ;; LaTeX2e: \emph{This is emphasized}.
435 ;    ("\\\\emph{\\([^}]+\\)}" 1 'italic keep)
436 ;    ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...}
437 ;    ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}"
438 ;     3 (if (match-beginning 2) 'bold 'italic) keep)
439 ;    ;; Old-style bf/em/it/sl.  Stop at `\\' and un-escaped `&', for tables.
440 ;    ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)"
441 ;     3 (if (match-beginning 2) 'bold 'italic) keep))
442
443 ;; Rewritten with the help of Alexandra Bac <abac@welcome.disi.unige.it>.
444 (defconst tex-font-lock-keywords-1
445   (eval-when-compile
446     (let* (;; Names of commands whose arg should be fontified as heading, etc.
447            (headings (regexp-opt
448                       '("title"  "begin" "end" "chapter" "part"
449                         "section" "subsection" "subsubsection"
450                         "paragraph" "subparagraph" "subsubparagraph"
451                         "newcommand" "renewcommand" "providecommand"
452                         "newenvironment" "renewenvironment"
453                         "newtheorem" "renewtheorem")
454                       t))
455            (variables (regexp-opt
456                        '("newcounter" "newcounter*" "setcounter" "addtocounter"
457                          "setlength" "addtolength" "settowidth")
458                        t))
459            (includes (regexp-opt
460                       '("input" "include" "includeonly" "bibliography"
461                         "epsfig" "psfig" "epsf" "nofiles" "usepackage"
462                         "documentstyle" "documentclass" "verbatiminput"
463                         "includegraphics" "includegraphics*"
464                         "url" "nolinkurl")
465                       t))
466            ;; Miscellany.
467            (slash "\\\\")
468            (opt " *\\(\\[[^]]*\\] *\\)*")
469            ;; This would allow highlighting \newcommand\CMD but requires
470            ;; adapting subgroup numbers below.
471            ;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)"))
472            (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
473       (list
474        ;; font-lock-syntactic-keywords causes the \ of \end{verbatim} to be
475        ;; highlighted as tex-verbatim face.  Let's undo that.
476        ;; This is ugly and brittle :-(  --Stef
477        '("^\\(\\\\\\)end" (1 (get-text-property (match-end 1) 'face) t))
478        ;; display $$ math $$
479        ;; We only mark the match between $$ and $$ because the $$ delimiters
480        ;; themselves have already been marked (along with $..$) by syntactic
481        ;; fontification.  Also this is done at the very beginning so as to
482        ;; interact with the other keywords in the same way as $...$ does.
483        (list "\\$\\$\\([^$]+\\)\\$\\$" 1 'tex-math-face)
484        ;; Heading args.
485        (list (concat slash headings "\\*?" opt arg)
486              ;; If ARG ends up matching too much (if the {} don't match, f.ex)
487              ;; jit-lock will do funny things: when updating the buffer
488              ;; the re-highlighting is only done locally so it will just
489              ;; match the local line, but defer-contextually will
490              ;; match more lines at a time, so ARG will end up matching
491              ;; a lot more, which might suddenly include a comment
492              ;; so you get things highlighted bold when you type them
493              ;; but they get turned back to normal a little while later
494              ;; because "there's already a face there".
495              ;; Using `keep' works around this un-intuitive behavior as well
496              ;; as improves the behavior in the very rare case where you do
497              ;; have a comment in ARG.
498              3 'font-lock-function-name-face 'keep)
499        (list (concat slash "\\(?:provide\\|\\(?:re\\)?new\\)command\\** *\\(\\\\[A-Za-z@]+\\)")
500              1 'font-lock-function-name-face 'keep)
501        ;; Variable args.
502        (list (concat slash variables " *" arg) 2 'font-lock-variable-name-face)
503        ;; Include args.
504        (list (concat slash includes opt arg) 3 'font-lock-builtin-face)
505        ;; Definitions.  I think.
506        '("^[ \t]*\\\\def *\\\\\\(\\(\\w\\|@\\)+\\)"
507          1 font-lock-function-name-face))))
508   "Subdued expressions to highlight in TeX modes.")
509
510 (defun tex-font-lock-append-prop (prop)
511   (unless (memq (get-text-property (match-end 1) 'face)
512                 '(font-lock-comment-face tex-verbatim))
513     prop))
514
515 (defconst tex-font-lock-keywords-2
516   (append tex-font-lock-keywords-1
517    (eval-when-compile
518      (let* (;;
519             ;; 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             ;; FIXME: unimplemented yet.
524             ;; (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t))
525             ;;
526             ;; Names of commands whose arg should be fontified as a citation.
527             (citations (regexp-opt
528                         '("label" "ref" "pageref" "vref" "eqref"
529                           "cite" "nocite" "index" "glossary" "bibitem"
530                           ;; These are text, rather than citations.
531                           ;; "caption" "footnote" "footnotemark" "footnotetext"
532                           )
533                         t))
534             ;;
535             ;; Names of commands that should be fontified.
536             (specials-1 (regexp-opt '("\\" "\\*") t)) ;; "-"
537             (specials-2 (regexp-opt
538                          '("linebreak" "nolinebreak" "pagebreak" "nopagebreak"
539                            "newline" "newpage" "clearpage" "cleardoublepage"
540                            "displaybreak" "allowdisplaybreaks"
541                            "enlargethispage") t))
542             (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)")
543             ;;
544             ;; Miscellany.
545             (slash "\\\\")
546             (opt " *\\(\\[[^]]*\\] *\\)*")
547             (args "\\(\\(?:[^{}&\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")
548             (arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)"))
549        (list
550         ;;
551         ;; Citation args.
552         (list (concat slash citations opt arg) 3 'font-lock-constant-face)
553         ;;
554         ;; Text between `` quotes ''.
555         (cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "«") t)
556                       "[^'\">{]+"       ;a bit pessimistic
557                       (regexp-opt `("''" "\">" "\"'" ">>" "»") t))
558               'font-lock-string-face)
559         ;;
560         ;; Command names, special and general.
561         (cons (concat slash specials-1) 'font-lock-warning-face)
562         (list (concat "\\(" slash specials-2 "\\)\\([^a-zA-Z@]\\|\\'\\)")
563               1 'font-lock-warning-face)
564         (concat slash general)
565         ;;
566         ;; Font environments.  It seems a bit dubious to use `bold' etc. faces
567         ;; since we might not be able to display those fonts.
568         (list (concat slash bold " *" arg) 2
569               '(tex-font-lock-append-prop 'bold) 'append)
570         (list (concat slash italic " *" arg) 2
571               '(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         ;; This is separate from the previous one because of cases like
578         ;; {\em foo {\bf bar} bla} where both match.
579         (list (concat "\\\\\\(bf\\(series\\)?\\)\\>" args)
580               3 '(tex-font-lock-append-prop 'bold) 'append)))))
581    "Gaudy expressions to highlight in TeX modes.")
582
583 (defun tex-font-lock-suscript (pos)
584   (unless (or (memq (get-text-property pos 'face)
585                     '(font-lock-constant-face font-lock-builtin-face
586                       font-lock-comment-face tex-verbatim))
587               ;; Check for backslash quoting
588               (let ((odd nil)
589                     (pos pos))
590                 (while (eq (char-before pos) ?\\)
591                   (setq pos (1- pos) odd (not odd)))
592                 odd))
593     (if (eq (char-after pos) ?_)
594         '(face subscript display (raise -0.3))
595       '(face superscript display (raise +0.3)))))
596
597 (defun tex-font-lock-match-suscript (limit)
598   "Match subscript and superscript patterns up to LIMIT."
599   (when (re-search-forward "[_^] *\\([^\n\\{}]\\|\
600 \\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t)
601     (when (match-end 3)
602       (let ((beg (match-beginning 3))
603             (end (save-restriction
604                    (narrow-to-region (point-min) limit)
605                    (condition-case nil (scan-lists (point) 1 1) (error nil)))))
606         (store-match-data (if end
607                               (list (match-beginning 0) end beg end)
608                             (list beg beg beg beg)))))
609     t))
610
611 (defconst tex-font-lock-keywords-3
612   (append tex-font-lock-keywords-2
613           '((tex-font-lock-match-suscript
614              (1 (tex-font-lock-suscript (match-beginning 0)) append))))
615   "Experimental expressions to highlight in TeX modes.")
616
617 (defvar tex-font-lock-keywords tex-font-lock-keywords-1
618   "Default expressions to highlight in TeX modes.")
619
620 (defvar tex-verbatim-environments
621   '("verbatim" "verbatim*"))
622
623 (defvar tex-font-lock-syntactic-keywords
624   (let ((verbs (regexp-opt tex-verbatim-environments t)))
625     `((,(concat "^\\\\begin *{" verbs "}.*\\(\n\\)") 2 "|")
626       ;; Technically, we'd like to put the "|" property on the \n preceding
627       ;; the \end, but this would have 2 disadvantages:
628       ;; 1 - it's wrong if the verbatim env is empty (the same \n is used to
629       ;;     start and end the fenced-string).
630       ;; 2 - font-lock considers the preceding \n as being part of the
631       ;;     preceding line, so things gets screwed every time the previous
632       ;;     line is re-font-locked on its own.
633       ;; There's a hack in tex-font-lock-keywords-1 to remove the verbatim
634       ;; face from the \ but C-M-f still jumps to the wrong spot :-(  --Stef
635       (,(concat "^\\(\\\\\\)end *{" verbs "}\\(.?\\)") (1 "|") (3 "<"))
636       ;; ("^\\(\\\\\\)begin *{comment}" 1 "< b")
637       ;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b")
638       ("\\\\verb\\**\\([^a-z@*]\\)"
639        ;; Do it last, because it uses syntax-ppss which needs the
640        ;; syntax-table properties of previous entries.
641        1 (tex-font-lock-verb (match-end 1))))))
642
643 (defun tex-font-lock-unfontify-region (beg end)
644   (font-lock-default-unfontify-region beg end)
645   (while (< beg end)
646     (let ((next (next-single-property-change beg 'display nil end))
647           (prop (get-text-property beg 'display)))
648       (if (and (eq (car-safe prop) 'raise)
649                (member (car-safe (cdr prop)) '(-0.3 +0.3))
650                (null (cddr prop)))
651           (put-text-property beg next 'display nil))
652       (setq beg next))))
653
654 (defface superscript
655   '((t :height 0.8)) ;; :raise 0.3
656   "Face used for superscripts."
657   :group 'tex)
658 (defface subscript
659   '((t :height 0.8)) ;; :raise -0.3
660   "Face used for subscripts."
661   :group 'tex)
662
663 (defface tex-math
664   '((t :inherit font-lock-string-face))
665   "Face used to highlight TeX math expressions."
666   :group 'tex)
667 ;; backward-compatibility alias
668 (put 'tex-math-face 'face-alias 'tex-math)
669 (defvar tex-math-face 'tex-math)
670
671 (defface tex-verbatim
672   ;; '((t :inherit font-lock-string-face))
673   '((t :family "courier"))
674   "Face used to highlight TeX verbatim environments."
675   :group 'tex)
676 ;; backward-compatibility alias
677 (put 'tex-verbatim-face 'face-alias 'tex-verbatim)
678 (defvar tex-verbatim-face 'tex-verbatim)
679
680 (defun tex-font-lock-verb (end)
681   "Place syntax-table properties on the \verb construct.
682 END is the position of the first delimiter after \verb."
683   (unless (nth 8 (syntax-ppss end))
684     ;; Do nothing if the \verb construct is itself inside a comment or
685     ;; verbatim env.
686     (save-excursion
687       ;; Let's find the end and mark it.
688       ;; We used to do it inside tex-font-lock-syntactic-face-function, but
689       ;; this leads to funny effects when jumping to the end of the buffer,
690       ;; because font-lock applies font-lock-syntactic-keywords to the whole
691       ;; preceding text but font-lock-syntactic-face-function only to the
692       ;; actually displayed text.
693       (goto-char end)
694       (let ((char (char-before)))
695         (skip-chars-forward (string ?^ char)) ;; Use `end' ?
696         (when (eq (char-syntax (preceding-char)) ?/)
697           (put-text-property (1- (point)) (point) 'syntax-table '(1)))
698         (unless (eobp)
699           (put-text-property (point) (1+ (point)) 'syntax-table '(7))
700           ;; Cause the rest of the buffer to be re-fontified.
701           ;; (remove-text-properties (1+ (point)) (point-max) '(fontified))
702           )))
703     "\""))
704
705 ;; Use string syntax but math face for $...$.
706 (defun tex-font-lock-syntactic-face-function (state)
707   (let ((char (nth 3 state)))
708     (cond
709      ((not char) font-lock-comment-face)
710      ((eq char ?$) tex-math-face)
711      (t tex-verbatim-face))))
712
713
714 (defun tex-define-common-keys (keymap)
715   "Define the keys that we want defined both in TeX mode and in the TeX shell."
716   (define-key keymap "\C-c\C-k" 'tex-kill-job)
717   (define-key keymap "\C-c\C-l" 'tex-recenter-output-buffer)
718   (define-key keymap "\C-c\C-q" 'tex-show-print-queue)
719   (define-key keymap "\C-c\C-p" 'tex-print)
720   (define-key keymap "\C-c\C-v" 'tex-view)
721
722   (define-key keymap [menu-bar tex] (cons "TeX" (make-sparse-keymap "TeX")))
723
724   (define-key keymap [menu-bar tex tex-kill-job]
725     '(menu-item "Tex Kill" tex-kill-job :enable (tex-shell-running)))
726   (define-key keymap [menu-bar tex tex-recenter-output-buffer]
727     '(menu-item "Tex Recenter" tex-recenter-output-buffer
728                 :enable (get-buffer "*tex-shell*")))
729   (define-key keymap [menu-bar tex tex-show-print-queue]
730     '("Show Print Queue" . tex-show-print-queue))
731   (define-key keymap [menu-bar tex tex-alt-print]
732     '(menu-item "Tex Print (alt printer)" tex-alt-print
733                 :enable (stringp tex-print-file)))
734   (define-key keymap [menu-bar tex tex-print]
735     '(menu-item "Tex Print" tex-print :enable (stringp tex-print-file)))
736   (define-key keymap [menu-bar tex tex-view]
737     '(menu-item "Tex View" tex-view :enable (stringp tex-print-file))))
738
739 (defvar tex-mode-map
740   (let ((map (make-sparse-keymap)))
741     (set-keymap-parent map text-mode-map)
742     (tex-define-common-keys map)
743     (define-key map