100
|
1 ;;; font-latex.el --- LaTeX fontification for Font Lock mode.
|
|
2
|
|
3 ;; Copyright (C) 1996 Peter S. Galbraith
|
|
4
|
|
5 ;; Authors: Peter S. Galbraith <galbraith@mixing.qc.dfo.ca>
|
|
6 ;; Simon Marshall <Simon.Marshall@esrin.esa.it>
|
|
7 ;; Maintainer: Peter S. Galbraith <galbraith@mixing.qc.dfo.ca>
|
|
8 ;; Created: 06 July 1996
|
|
9 ;; Version: 0.403 *Beta* (19 Nov 96)
|
|
10 ;; Keywords: LaTeX faces
|
|
11
|
|
12 ;; RCS $Id: font-latex.el,v 1.1 1997/02/20 02:17:35 steve Exp $
|
|
13 ;; Note: RCS version number does not correspond to release number.
|
|
14
|
|
15 ;; LCD Archive Entry: (Not yet submitted!)
|
|
16 ;; font-latex|Peter Galbraith|galbraith@mixing.qc.dfo.ca|
|
|
17 ;; LaTeX fontification for font-lock|
|
|
18 ;; 06-Jul-1996|0.01|~/modes/font-latex.el|
|
|
19
|
|
20 ;; The archive is archive.cis.ohio-state.edu in /pub/gnu/emacs/elisp-archive.
|
|
21
|
|
22 ;;; This file is not part of GNU Emacs.
|
|
23
|
|
24 ;; This package is free software; you can redistribute it and/or modify
|
|
25 ;; it under the terms of the GNU General Public License as published by
|
|
26 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
27 ;; any later version.
|
|
28
|
|
29 ;; This package is distributed in the hope that it will be useful,
|
|
30 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
31 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
32 ;; GNU General Public License for more details.
|
|
33
|
|
34 ;; You should have received a copy of the GNU General Public License
|
|
35 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
36 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
37 ;; Boston, MA 02111-1307, USA.
|
|
38
|
|
39 ;;; Commentary:
|
|
40
|
|
41 ;; New versions of this package (if they exist) may be found at:
|
|
42 ;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/font-latex.el
|
|
43
|
|
44 ;; Description:
|
|
45 ;; This package enhances font-lock fontification patterns for LaTeX.
|
|
46 ;; font-lock mode is a minor mode that causes your comments to be
|
|
47 ;; displayed in one face, strings in another, reserved words in another,
|
|
48 ;; and so on.
|
|
49 ;;
|
|
50 ;; Please see the accompanying file font-latex.tex for a demo of what
|
|
51 ;; font-latex is supposed to do at different fontification levels.
|
|
52
|
|
53 ;; Installation instructions:
|
|
54 ;;
|
|
55 ;; Put this file in your emacs load-path, and byte-compile it:
|
|
56 ;; M-x byte-compile-file
|
|
57 ;; ** It runs faster when you byte-compile it! **
|
|
58 ;;
|
|
59 ;; Then all you need to do is add this form to your .emacs file:
|
|
60 ;;
|
|
61 ;; (if window-system
|
|
62 ;; (require 'font-latex))
|
|
63 ;;
|
|
64 ;; There are two levels of fontification, selected by the value of the
|
|
65 ;; font-lock variable font-lock-maximum-decoration. font-latex uses two
|
|
66 ;; levels. There are ways documented in font-latex.el to set this
|
|
67 ;; differently for each mode that uses font-lock, but if you are unsure and
|
|
68 ;; are running on a fast enough machine, try putting this in your ~/.emacs
|
|
69 ;; file:
|
|
70 ;; (setq font-lock-maximum-decoration t)
|
|
71 ;; It probably best to put it before the (require 'font-latex) statement.
|
|
72 ;;
|
|
73 ;; Lazy-lock users:
|
|
74 ;;
|
|
75 ;; lazy-lock and font-lock don't work too well together (up to Emacs 19.33
|
|
76 ;; and XEmacs 19.14 anyway). font-latex uses functions to find text to
|
|
77 ;; fontify that may span more than one line, and this doesn't suit
|
|
78 ;; lazy-lock's search limits too well.
|
|
79 ;;
|
|
80 ;; Old hilit19 (and hilit-LaTeX) users:
|
|
81 ;;
|
|
82 ;; If you are upgrading from using hilit-LaTeX.el or were using hilit19,
|
|
83 ;; you must disable hilit19 (at least for latex mode) in order to use
|
|
84 ;; font-latex.el. Here's how:
|
|
85 ;;
|
|
86 ;; - If you don't care to use hilit19 at all, don't `load' or `require' it
|
|
87 ;; in your ~/.emacs file by removing the "(require 'hilit-LaTeX)" line.
|
|
88 ;; - If you wish to use hilit19 everywhere but in latex mode, add the
|
|
89 ;; following before your `load' or `require' hilit19:
|
|
90 ;;
|
|
91 ;; (setq hilit-mode-enable-list '(not latex-mode))
|
|
92 ;;
|
|
93 ;; You can tell you using font-latex instead of hilit-LaTeX because:
|
|
94 ;;
|
|
95 ;; - colours will be different
|
|
96 ;; - You'll see a message like `Fontifying font-latex.tex...done'
|
|
97 ;; instead of `highlighting 1: \(^\|[^\\]\)\(\\[a-zA-Z\\]+\)'
|
|
98 ;; ----------------------------------------------------------------------------
|
|
99 ;;; Change log:
|
|
100 ;; V0.403 19Nov96 (RCS V1.37)
|
|
101 ;; - Christoph Wedler <wedler@fmi.uni-passau.de>
|
|
102 ;; XEmacs patch for local math-font
|
|
103 ;; - Changed scheme for fontification of \section*{...}
|
|
104 ;; V0.402 13Nov96 PSG (RCS V1.35)
|
|
105 ;; - Embeded comments handled.
|
|
106 ;; - Better XEmacs initilisation.
|
|
107 ;; V0.401 12Nov96 PSG (RCS V1.34) - Nothing fontified when commented-out.
|
|
108 ;; V0.400 11Nov96 PSG (RCS V1.33)
|
|
109 ;; - Stab at on-the-fly multiline.
|
|
110 ;; - mono support: <Johannes.Weinert@Informatik.Uni-Oldenburg.DE>
|
|
111 ;; V0.314 16Oct96 PSG - Support for dark background removed for XEmacs.
|
|
112 ;; V0.313 07Oct96 PSG (RCS V1.31) - Support for dark background.
|
|
113 ;; V0.312 26Aug96 PSG (RCS V1.30) - Added font-latex-commented-outp.
|
|
114 ;; V0.311 22Aug96 PSG (RCS V1.29) - fixed for XEmacs.
|
|
115 ;; V0.310 22Aug96 simon (RCS V1.27)
|
|
116 ;; - make font-latex-setup run font-lock-make-faces before variable trickery.
|
|
117 ;; - set font-latex-string-face to the global value of font-lock-string-face.
|
|
118 ;; V0.309 21Aug96 PSG (RCS V1.26)
|
|
119 ;; - new font-latex-math-face done by string syntax. User may modify it.
|
|
120 ;; - new font-latex-string-face.
|
|
121 ;; V0.308 15Aug96 PSG (RCS V1.25)
|
|
122 ;; - $$...$$ gets font-latex-math-face
|
|
123 ;; - font-latex-match-math-envII fixed.
|
|
124 ;; V0.307 14Aug96 PSG (RCS V1.23) - setup okay if loaded in a latex-mode-hook
|
|
125 ;; V0.306 14Aug96 PSG (RCS V1.22) - added "item" to font-latex-match-function
|
|
126 ;; V0.305 14Aug96 PSG (RCS V1.20) - use keep in font-latex-match-math-envII
|
|
127 ;; V0.304 14Aug96 PSG (RCS V1.18) - minor comment edits.
|
|
128 ;; V0.303 14Aug96 simon (RCS V1.17)
|
|
129 ;; - rewrote font-latex-match-math-envII like font-latex-match-quotation
|
|
130 ;; V0.302 12Aug96 PSG (RCS V1.16)
|
|
131 ;; - (goto-char end) in condition-case error to avoid infinite loops.
|
|
132 ;; V0.301 08Aug96 PSG (RCS V1.14)
|
|
133 ;; - Better faces in XEmacs.
|
|
134 ;; V0.300 07Aug96 PSG (RCS V1.12)
|
|
135 ;; - Changed font-latex-match-font-inside-braces again for stranded \bf
|
|
136 ;; - "[a-z]+box" changed
|
|
137 ;; - font-latex-match-math-env checks preceding-char for \\[
|
|
138 ;; - use eval-after-compile in font-latex-match-math-envII
|
|
139 ;; V0.201 05Aug96 PSG added \\(display\\)?math to Simon's changes
|
|
140 ;; V0.200 05Aug96 simon: (RCS V1.10)
|
|
141 ;; - fixed font-latex-match-command-outside-arguments
|
|
142 ;; - rewrote font-latex-match-font-outside-braces like above
|
|
143 ;; - rewrote font-latex-match-font-inside-braces like above
|
|
144 ;; V0.101 01Aug96 PSG added \\(display\\)?math
|
|
145 ;; V0.100 01Aug96 PSG - massive new test version
|
|
146 ;; V0.061 23Jul96 PSG
|
|
147 ;; - Removed trailing "\\>" in warning-face regexp (fails with \\ \- \\*)
|
|
148 ;; V0.06 23Jul96 PSG
|
|
149 ;; - fixed dobib in font-latex-labels.
|
|
150 ;; - shorter font regexp in levels 3+4.
|
|
151 ;; - removed \item and & from type
|
|
152 ;; - fixed font-latex-math-envII regexp
|
|
153 ;; V0.05 22Jul96 PSG
|
|
154 ;; - changed \ref etc to reference-face.
|
|
155 ;; - \\b added in buggy \item[option] regexp (not really fixed).
|
|
156 ;; - font-latex-labels regexp bug
|
|
157 ;; V0.041 simon:
|
|
158 ;; - added font-latex-match-command-outside-arguments
|
|
159 ;; - rewrote font-latex-match-quotation and font-latex-bib-highlight-mouse
|
|
160 ;; - rewrote then removed bib-cite functionality.
|
|
161 ;; - general top-level cleanup
|
|
162 ;; V0.04 11Jul96 PSG
|
|
163 ;; - added font-lock-comment-start-regexp defined in 19.32
|
|
164 ;; - encoded 8-bit characters to 7-bit.
|
|
165 ;; V0.03 10Jul96 PSG
|
|
166 ;; - font-latex-bib-cite-mouse-highlight-p can change after font-lock-defaults
|
|
167 ;; is constructed.
|
|
168 ;; V0.02 09Jul96 PSG
|
|
169 ;; - added font-latex-bib-cite-mouse-highlight-p
|
|
170 ;; - Fixed `overwrite' flags
|
|
171 ;; V0.01 06Jul96 Peter S Galbraith - Created
|
|
172 ;; ----------------------------------------------------------------------------
|
|
173 ;;; Code:
|
|
174 (require 'font-lock)
|
|
175
|
|
176 (defvar font-latex-warning-face 'font-latex-warning-face
|
|
177 "Face to use for LaTeX major keywords.")
|
|
178 (defvar font-latex-sedate-face 'font-latex-sedate-face
|
|
179 "Face to use for LaTeX minor keywords.")
|
|
180 (defvar font-latex-italic-face 'font-latex-italic-face
|
|
181 "Face to use for LaTeX italics.")
|
|
182 (defvar font-latex-bold-face 'font-latex-bold-face
|
|
183 "Face to use for LaTeX bolds.")
|
|
184 (defvar font-latex-math-face 'font-latex-math-face
|
|
185 "Face to use for LaTeX math environments.")
|
|
186
|
|
187 ;; End-User can stop reading here.
|
|
188
|
|
189 ;; Make sure font-latex.el is supported. I don't claim to have tested this...
|
|
190 (if (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version)))
|
|
191 (and (= emacs-major-version 19) (< emacs-minor-version 14))
|
|
192 (and (= emacs-major-version 19) (< emacs-minor-version 29)))
|
|
193 (error "`font-latex' was written for Emacs 19.29/XEmacs 19.14 or later"))
|
|
194
|
|
195 (defvar font-latex-is-XEmacs
|
|
196 (not (null (save-match-data (string-match "XEmacs\\|Lucid" emacs-version)))))
|
|
197
|
|
198 (defvar font-latex-string-face nil
|
|
199 "Face to use for strings. This is set by Font LaTeX.")
|
|
200
|
|
201 (defvar font-lock-comment-start-regexp nil
|
|
202 "Regexp to match the start of a comment.")
|
|
203
|
|
204 (eval-when-compile
|
|
205 (require 'cl))
|
|
206
|
|
207 (cond
|
|
208 ((not font-latex-is-XEmacs)
|
|
209 ;;; emacs:
|
|
210 ;; Otherwise I overwrite fock-lock-face-attributes.
|
|
211 ;; font-lock.el needs a better way to add these faces!
|
|
212 (if (not font-lock-face-attributes)
|
|
213 (font-lock-make-faces))
|
|
214 (unless (assq 'font-latex-sedate-face font-lock-face-attributes)
|
|
215 (cond
|
|
216 ;; FIXME: Add better conditions for grayscale.
|
|
217 ((memq font-lock-display-type '(mono monochrome grayscale greyscale
|
|
218 grayshade greyshade))
|
|
219 (setq font-lock-face-attributes
|
|
220 (append
|
|
221 font-lock-face-attributes
|
|
222 (list '(font-latex-bold-face nil nil t nil nil)
|
|
223 '(font-latex-italic-face nil nil nil t nil)
|
|
224 '(font-latex-math-face nil nil nil nil t)
|
|
225 '(font-latex-sedate-face nil nil nil t nil)
|
|
226 (list
|
|
227 'font-latex-warning-face
|
|
228 (cdr (assq 'background-color (frame-parameters)))
|
|
229 (cdr (assq 'foreground-color (frame-parameters)))
|
|
230 nil nil nil)))))
|
|
231 ((eq font-lock-background-mode 'light) ; light colour background
|
|
232 (setq font-lock-face-attributes
|
|
233 (append
|
|
234 font-lock-face-attributes
|
|
235 ;;;FIXME: These won't follow font-lock-type-face's changes.
|
|
236 ;;; Should I change to a (copy-face) scheme?
|
|
237 '((font-latex-bold-face "DarkOliveGreen" nil t nil nil)
|
|
238 (font-latex-italic-face "DarkOliveGreen" nil nil t nil)
|
|
239 (font-latex-math-face "green4")
|
|
240 (font-latex-sedate-face "grey50")
|
|
241 (font-latex-warning-face "red" nil t nil nil)))))
|
|
242 (t ; dark colour background
|
|
243 (setq font-lock-face-attributes
|
|
244 (append
|
|
245 font-lock-face-attributes
|
|
246 '((font-latex-bold-face "OliveGreen" nil t nil nil)
|
|
247 (font-latex-italic-face "OliveGreen" nil nil t nil)
|
|
248 (font-latex-math-face "LightSeaGreen")
|
|
249 ;; good are > LightSeaGreen, LightCoral, coral, orchid, orange
|
|
250 (font-latex-sedate-face "grey60")
|
|
251 (font-latex-warning-face "red" nil t nil nil))))))))
|
|
252 (t
|
|
253 ;;; XEmacs:
|
|
254 (make-face 'font-latex-string-face "Face to use for LaTeX string.")
|
|
255 (copy-face 'font-lock-string-face 'font-latex-string-face)
|
|
256
|
|
257 (make-face 'font-latex-bold-face "Face to use for LaTeX bolds.")
|
|
258 (copy-face 'font-lock-type-face 'font-latex-bold-face)
|
|
259 (make-face-bold 'font-latex-bold-face)
|
|
260
|
|
261 (make-face 'font-latex-italic-face "Face to use for LaTeX italics.")
|
|
262 (copy-face 'font-lock-type-face 'font-latex-italic-face)
|
|
263 (make-face-italic 'font-latex-italic-face)
|
|
264
|
|
265 (make-face 'font-latex-math-face "Face to use for LaTeX math.")
|
|
266 (make-face 'font-latex-sedate-face "Face to use for LaTeX minor keywords.")
|
|
267 (make-face 'font-latex-warning-face "Face to use for LaTeX major keywords.")
|
|
268 (make-face-bold 'font-latex-warning-face)
|
|
269 ;; XEmacs uses a tag-list thingy to determine if we are using color
|
|
270 ;; or mono (and I assume a dark background).
|
|
271 (set-face-foreground 'font-latex-math-face "green4" 'global nil 'append)
|
|
272 (set-face-foreground 'font-latex-sedate-face "grey50" 'global nil 'append)
|
|
273 (set-face-foreground 'font-latex-warning-face "red" 'global nil 'append)))
|
|
274
|
|
275 (defun font-latex-setup ()
|
|
276 "Setup this buffer for LaTeX font-lock. Usually called from a hook."
|
|
277 ;; Trickery to make $$ fontification be in `font-latex-math-face' while
|
|
278 ;; strings get whatever `font-lock-string-face' has been set to.
|
|
279 (if font-latex-is-XEmacs
|
|
280 ;; Cool patch from Christoph Wedler...
|
|
281 (let (instance)
|
|
282 (mapcar (function
|
|
283 (lambda (property)
|
|
284 (setq instance
|
|
285 (face-property-instance 'font-latex-math-face property
|
|
286 nil 0 t))
|
|
287 (if (numberp instance)
|
|
288 (setq instance
|
|
289 (face-property-instance 'default property nil 0)))
|
|
290 (or (numberp instance)
|
|
291 (set-face-property 'font-lock-string-face property
|
|
292 instance (current-buffer)))))
|
|
293 (built-in-face-specifiers)))
|
|
294 (font-lock-make-faces)
|
|
295 (make-local-variable 'font-lock-string-face)
|
|
296 (setq font-lock-string-face font-latex-math-face
|
|
297 font-latex-string-face (default-value 'font-lock-string-face))
|
|
298 ;; Tell Font Lock about the support.
|
|
299 (make-local-variable 'font-lock-defaults)
|
|
300 ;; Parentheses () are disabled because they should not delimit fontification
|
|
301 ;; in LaTeX text.
|
|
302 (setq font-lock-defaults
|
|
303 '((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
|
|
304 nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
|
|
305 (font-lock-comment-start-regexp . "%")
|
|
306 (font-lock-mark-block-function . mark-paragraph)))))
|
|
307
|
|
308 (when font-latex-is-XEmacs
|
|
309 (put 'latex-mode 'font-lock-defaults
|
|
310 '((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
|
|
311 nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
|
|
312 (font-lock-comment-start-regexp . "%")
|
|
313 (font-lock-mark-block-function . mark-paragraph)))
|
|
314 (put 'latex-tex-mode 'font-lock-defaults 'latex-mode)
|
|
315 (put 'LaTex-tex-mode 'font-lock-defaults 'latex-mode)
|
|
316 (put 'LaTeX-mode 'font-lock-defaults 'latex-mode)
|
|
317 (put 'japanese-LaTeX-mode 'font-lock-defaults 'latex-mode)
|
|
318 (put 'LATeX-MoDe 'font-lock-defaults 'latex-mode)
|
|
319 (put 'lATEx-mODe 'font-lock-defaults 'latex-mode))
|
|
320
|
|
321 (defconst font-latex-keywords-1
|
|
322 (list
|
|
323 ;; FIXME: Maybe I should put this in a function, use override but let
|
|
324 ;; the function determine if commented-out.
|
|
325 (list (concat "\\\\\\(\\(no\\)?pagebreak\\|\\(new\\|clear\\(double\\)?\\)"
|
|
326 "page\\|enlargethispage\\|\\(no\\)?linebreak\\|newline\\|"
|
|
327 "-\\|\\\\\\(\*\\)?\\|displaybreak\\|allowdisplaybreaks\\)")
|
|
328 '(0 font-latex-warning-face))
|
|
329 '("\\$\\$\\([^$]+\\)\\$\\$" 1 font-latex-math-face) ;;; $$...$$
|
|
330 '(font-latex-match-quotation . font-latex-string-face) ;;; ``...''
|
|
331 '(font-latex-match-font-outside-braces ;;;\textit{text}
|
|
332 (0 font-lock-keyword-face
|
|
333 append ;Override? [t 'keep 'prepend 'append]
|
|
334 ;; Can't use prepend because that overwrites syntax fontification
|
|
335 ;; e.g. comments.
|
|
336 t) ;Laxmatch? if t, do not signal error
|
|
337 (1 font-latex-italic-face append t)
|
|
338 (2 font-latex-bold-face append t)
|
|
339 (3 font-lock-type-face append t))
|
|
340 '(font-latex-match-font-inside-braces ;;;{\it text}
|
|
341 (0 font-lock-keyword-face append t)
|
|
342 (1 font-latex-italic-face append t)
|
|
343 (2 font-latex-bold-face append t)
|
|
344 (3 font-lock-type-face append t)))
|
|
345 "Subdued level highlighting for LaTeX modes.")
|
|
346
|
|
347 (defconst font-latex-keywords-2
|
|
348 (append font-latex-keywords-1
|
|
349 '((font-latex-match-reference ;;;\cite
|
|
350 (0 font-lock-keyword-face append t)
|
|
351 (1 font-lock-variable-name-face append t) ;;; [opt]
|
|
352 (2 font-lock-reference-face append t)) ;;; {key}
|
|
353 (font-latex-match-function ;;;\section
|
|
354 (0 font-lock-keyword-face append t)
|
|
355 (1 font-lock-variable-name-face append t) ;;; [opt]
|
|
356 (2 font-lock-function-name-face append t)) ;;; {text}
|
|
357 (font-latex-match-variable
|
|
358 (0 font-lock-keyword-face nil t)
|
|
359 (1 font-lock-variable-name-face nil t)
|
|
360 (2 font-lock-variable-name-face nil t))
|
|
361 (font-latex-match-math-env
|
|
362 (0 font-latex-math-face append t)) ;;;\(...\)
|
|
363 (font-latex-match-math-envII ;;;Math environ.
|
|
364 (0 font-latex-math-face append t))
|
|
365 ("\\\\[@A-Za-z]+" ;;;Other commands
|
|
366 (0 font-latex-sedate-face append))))
|
|
367 "High level highlighting for LaTeX modes.")
|
|
368
|
|
369 (defvar font-latex-keywords font-latex-keywords-1
|
|
370 "Default expressions to highlight in TeX mode.")
|
|
371
|
|
372
|
|
373 (defun font-latex-match-reference (limit)
|
|
374 (font-latex-match-command-outside-arguments
|
|
375 (eval-when-compile
|
|
376 (concat "\\\\" "\\("
|
|
377 (mapconcat 'identity
|
|
378 '("[A-Za-z]*cite[A-Za-z]*" "label" "\\(page\\|v\\|eq\\)?ref"
|
|
379 "index" "glossary" "\\(footnote\\(mark\\|text\\)?\\)")
|
|
380 "\\|")
|
|
381 "\\)\\>"))
|
|
382 limit nil nil))
|
|
383
|
|
384 (defun font-latex-match-function (limit)
|
|
385 "Fontify things like \\section{text}"
|
|
386 (font-latex-match-command-outside-arguments
|
|
387 (eval-when-compile
|
|
388 (concat "\\\\" "\\("
|
|
389 (mapconcat 'identity
|
|
390 ;; \\*? doesn't work with \\> at the end of the regexp.
|
|
391 ;; Instead, allow `*' for all commands (!)
|
|
392 '("item" ;;;FIXME: does not have an {arg} so should treated elsewhere.
|
|
393 "include" "input" "bibliography"
|
|
394 "part" "chapter" "\\(sub\\)*section" "\\(sub\\)*paragraph"
|
|
395 "begin" "end"
|
|
396 "title" "author" "date" "thanks" "address"
|
|
397 "pagenumbering"
|
|
398 "\\(this\\)?pagestyle"
|
|
399 "nofiles" "includeonly"
|
|
400 "bibliographystyle" "\\(document\\(style\\|class\\)\\)"
|
|
401 "\\(re\\)?new\\(environment\\|command\\|length\\|theorem\\|counter\\)"
|
|
402 "usepackage" "caption" "\\(f\\|m\\|s\\)box" "\\(v\\|h\\)space")
|
|
403 "\\|")
|
|
404 "\\)\\>"))
|
|
405 limit nil t))
|
|
406
|
|
407 (defun font-latex-match-variable (limit)
|
|
408 "Fontify things like \\newcommand{stuff}"
|
|
409 (font-latex-match-command-outside-arguments
|
|
410 (eval-when-compile
|
|
411 (concat "\\\\" "\\("
|
|
412 "set\\(length\\|towidth\\|counter\\)\\|"
|
|
413 "addto\\(length\\|counter\\)"
|
|
414 "\\)\\>"))
|
|
415 limit t nil))
|
|
416
|
|
417
|
|
418 ;; FIXME: --About font-latex-commented-outp--
|
|
419 ;; Fontification is *slower* for affected functions (in particular
|
|
420 ;; font-latex-match-function), so it will be worth it to increase
|
|
421 ;; performance in the algorithm.
|
|
422 ;; - don't return (store-match-data (list nil nil)) in
|
|
423 ;; font-latex-match-command-outside-arguments, instead skip over
|
|
424 ;; commented-out parts internally.
|
|
425 ;; - Perhaps handling outlined code is excessive and slows down the
|
|
426 ;; search too much?
|
|
427 ;; - Is save-match-data expensive? The calling function could store
|
|
428 ;; the match-data before it calls (font-latex-commented-outp) knowing
|
|
429 ;; that is would trash the list.
|
|
430 (defun font-latex-commented-outp ()
|
|
431 "Return t is comment character is found between bol and point."
|
|
432 (save-excursion
|
|
433 (let ((limit (point)))
|
|
434 (save-match-data
|
|
435 ;; Handle outlined code
|
|
436 (re-search-backward "^\\|\C-m" (point-min) t)
|
|
437 (if (re-search-forward "^%\\|[^\\]%" limit t)
|
|
438 t
|
|
439 nil)))))
|
|
440
|
|
441 (defvar font-latex-match-command-cache-state nil
|
|
442 "Cache state of unterminated match to fontify")
|
|
443 (defvar font-latex-match-command-cache-start nil
|
|
444 "Cache start of unterminated match to fontify")
|
|
445 (defvar font-latex-match-command-cache-limit nil
|
|
446 "Cache end of unterminated match to fontify")
|
|
447 (defvar font-latex-match-command-cache-keywords nil
|
|
448 "Cache keywords of unterminated match to fontify")
|
|
449 (make-variable-buffer-local 'font-latex-match-command-cache-state)
|
|
450 (make-variable-buffer-local 'font-latex-match-command-cache-start)
|
|
451 (make-variable-buffer-local 'font-latex-match-command-cache-limit)
|
|
452 (make-variable-buffer-local 'font-latex-match-command-cache-keywords)
|
|
453
|
|
454 ;; FIXME - Note to myself
|
|
455 ;; In call to font-latex-match-command-outside-arguments, I could arrange
|
|
456 ;; such that keywords which cannot use [options] have this set to nil.
|
|
457 ;; LaTeX code woulldn't fontify if options are used illegally in commands,
|
|
458 ;; cuing users in that they are doing something wrong. (See RCS V1.11 for
|
|
459 ;; useopt option)
|
|
460 ;;
|
|
461 ;; NOTE - Without an override flag, font-lock does not re-fontify the
|
|
462 ;; option `opt' when the `t' is typed-in in "\cite[opt". The first `o'
|
|
463 ;; was fontified and now has a face, which font-lock-apply-highlight
|
|
464 ;; won't override. The `p' and `t' get a face as they are typed by
|
|
465 ;; inheriting from left-stickyness on the `o'.
|
|
466 ;; THEREFORE, I cannot rely on font-lock-apply-highlight to continue
|
|
467 ;; multi-line incomplete patterns, because the first character of the
|
|
468 ;; pattern on the first line has a face. I must use `prepend'.
|
|
469 (defun font-latex-match-command-outside-arguments (keywords limit twoargs
|
|
470 asterix)
|
|
471 "Search for regexp command KEYWORDS[opt]{arg} before LIMIT.
|
|
472 If TWOARG is t, allow two arguments {arg1}{arg2}
|
|
473 If ASTERIX is t, fontify trailing asterix in command.
|
|
474 Sets `match-data' so that:
|
|
475 subexpression 0 is the keyword,
|
|
476 subexpression 1 is the contents of any following [...] forms
|
|
477 subexpression 2 is the contents of any following {...} forms.
|
|
478 Returns nil if none of KEYWORDS is found."
|
|
479 ;; Prior incomplete match?
|
|
480 (if font-latex-match-command-cache-state
|
|
481 (setq font-latex-match-command-cache-state nil) ;Stop now!
|
|
482 (when (and font-latex-match-command-cache-keywords
|
|
483 (equal font-latex-match-command-cache-keywords keywords)
|
|
484 (>= font-latex-match-command-cache-limit (point))
|
|
485 (< font-latex-match-command-cache-start (point)))
|
|
486 (goto-char font-latex-match-command-cache-start)
|
|
487 (setq font-latex-match-command-cache-state 'stop)) ;Can only do once
|
|
488 (when (re-search-forward keywords limit t)
|
|
489 (let ((this-start (match-beginning 0)))
|
|
490 (cond
|
|
491 ((font-latex-commented-outp)
|
|
492 ;; Return a nul match such that we skip over this pattern.
|
|
493 ;; (Would be better to skip over internally to this function)
|
|
494 (store-match-data (list nil nil))
|
|
495 t)
|
|
496 (t
|
|
497 (let ((kbeg (match-beginning 0))
|
|
498 (kend (+ (match-end 0)
|
|
499 (if (and asterix (eq (following-char) ?\*)) 1 0)))
|
|
500 sbeg send cbeg cend)
|
|
501 (goto-char kend) ;May be moved by asterix
|
|
502 (while (eq (following-char) ?\[)
|
|
503 (save-restriction
|
|
504 ;; Restrict to LIMIT.
|
|
505 (narrow-to-region (point-min) limit)
|
|
506 (setq sbeg (1+ kend))
|
|
507 (if (condition-case nil
|
|
508 (goto-char (or (scan-sexps (point) 1) (point-max)))
|
|
509 (error))
|
|
510 (setq send (1- (point)))
|
|
511 (setq send (point-max))
|
|
512 (goto-char send)
|
|
513 (setq font-latex-match-command-cache-state 'stop))))
|
|
514 (when (eq (following-char) ?\{)
|
|
515 (save-restriction
|
|
516 ;; Restrict to LIMIT.
|
|
517 (narrow-to-region (point-min) limit)
|
|
518 (setq cbeg (1+ (point)))
|
|
519 (if (condition-case nil
|
|
520 (goto-char (or (scan-sexps (point) 1) (point-max)))
|
|
521 (error))
|
|
522 (setq cend (1- (point)))
|
|
523 (setq cend (point-max))
|
|
524 (goto-char cend)
|
|
525 (setq font-latex-match-command-cache-state 'stop))))
|
|
526 (when (and twoargs (eq (following-char) ?\{))
|
|
527 (save-restriction
|
|
528 ;; Restrict to LIMIT.
|
|
529 (narrow-to-region (point-min) limit)
|
|
530 (if (condition-case nil
|
|
531 (goto-char (or (scan-sexps (point) 1) (point-max)))
|
|
532 (error))
|
|
533 (setq cend (1- (point)))
|
|
534 (setq cend (point-max))
|
|
535 (goto-char cend)
|
|
536 (setq font-latex-match-command-cache-state 'stop))))
|
|
537 (store-match-data (list kbeg kend sbeg send cbeg cend))
|
|
538 (when font-latex-match-command-cache-state
|
|
539 (setq font-latex-match-command-cache-start this-start)
|
|
540 (setq font-latex-match-command-cache-limit (point))
|
|
541 (setq font-latex-match-command-cache-keywords keywords))
|
|
542 t)))))))
|
|
543
|
|
544 (defvar font-latex-match-font-cache-state nil
|
|
545 "Cache state of unterminated match to fontify")
|
|
546 (defvar font-latex-match-font-cache-start nil
|
|
547 "Cache start of unterminated match to fontify")
|
|
548 (defvar font-latex-match-font-cache-limit nil
|
|
549 "Cache end of unterminated match to fontify")
|
|
550 (defvar font-latex-match-font-cache-keywords nil
|
|
551 "Cache keywords of unterminated match to fontify")
|
|
552 (make-variable-buffer-local 'font-latex-match-font-cache-state)
|
|
553 (make-variable-buffer-local 'font-latex-match-font-cache-start)
|
|
554 (make-variable-buffer-local 'font-latex-match-font-cache-limit)
|
|
555 (make-variable-buffer-local 'font-latex-match-font-cache-keywords)
|
|
556
|
|
557 (defun font-latex-match-font-outside-braces (limit)
|
|
558 "Search for font-changing command like \textbf{fubar} before LIMIT.
|
|
559 Sets `match-data' so that:
|
|
560 subexpression 0 is the keyword,
|
|
561 subexpression 1 is the content to fontify in italic.
|
|
562 subexpression 2 is the content to fontify in bold.
|
|
563 subexpression 3 is the content to fontify in type-face.
|
|
564 Returns nil if no font-changing command is found."
|
|
565 (if font-latex-match-font-cache-state
|
|
566 (setq font-latex-match-font-cache-state nil) ;Stop now!
|
|
567 (when (and font-latex-match-font-cache-keywords
|
|
568 (equal font-latex-match-font-cache-keywords keywords)
|
|
569 (>= font-latex-match-font-cache-limit (point))
|
|
570 (< font-latex-match-font-cache-start (point)))
|
|
571 (goto-char font-latex-match-font-cache-start)
|
|
572 (setq font-latex-match-font-cache-state 'stop)) ;Can only do once
|
|
573 (when (re-search-forward
|
|
574 (eval-when-compile
|
|
575 (concat "\\\\" "\\("
|
|
576 "\\(emph\\)\\|" ;;; 2 - italic
|
|
577 "\\(text\\("
|
|
578 "\\(it\\|sl\\)\\|" ;;; 5 - italic
|
|
579 "\\(md\\|rm\\|sf\\|tt\\)\\|" ;;; 6 - type
|
|
580 "\\(bf\\|sc\\|up\\)" ;;; 7 - bold
|
|
581 "\\)\\)\\|"
|
|
582 "\\(boldsymbol\\|pmb\\)" ;;; 8 - bold
|
|
583 "\\)" "{"))
|
|
584 limit t)
|
|
585 (cond
|
|
586 ((font-latex-commented-outp)
|
|
587 ;; Return a nul match such that we skip over this pattern.
|
|
588 ;; (Would be better to skip over internally to this function)
|
|
589 ;; Using `prepend' won't help here, because the problem is that
|
|
590 ;; scan-sexp *fails* to find a commented-out matching bracket!
|
|
591 (store-match-data (list nil nil))
|
|
592 t)
|
|
593 (t
|
|
594 (let ((kbeg (match-beginning 0)) (kend (match-end 1))
|
|
595 (beg (match-end 0)) end itbeg itend bfbeg bfend ttbeg ttend)
|
|
596 (goto-char kend)
|
|
597 (save-restriction
|
|
598 ;; Restrict to LIMIT.
|
|
599 (narrow-to-region (point-min) limit)
|
|
600 (if (condition-case nil
|
|
601 (goto-char (or (scan-sexps (point) 1) (point-max)))
|
|
602 (error))
|
|
603 (setq end (1- (point)))
|
|
604 (setq end (point-max))
|
|
605 (goto-char end)
|
|
606 (setq font-latex-match-font-cache-state 'stop)))
|
|
607 (cond ((or (match-beginning 2) (match-beginning 5))
|
|
608 (setq itbeg beg
|
|
609 itend end))
|
|
610 ((match-beginning 6)
|
|
611 (setq ttbeg beg
|
|
612 ttend end))
|
|
613 (t
|
|
614 (setq bfbeg beg
|
|
615 bfend end)))
|
|
616 (store-match-data
|
|
617 (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
|
|
618 (when font-latex-match-font-cache-state
|
|
619 (setq font-latex-match-font-cache-start kbeg)
|
|
620 (setq font-latex-match-font-cache-limit (point))
|
|
621 (setq font-latex-match-font-cache-keywords keywords))
|
|
622 ;; Start the subsequent search immediately after this keyword.
|
|
623 (goto-char kend)
|
|
624 t))))))
|
|
625
|
|
626 (defvar font-latex-match-infont-cache-state nil
|
|
627 "Cache state of unterminated match to fontify")
|
|
628 (defvar font-latex-match-infont-cache-start nil
|
|
629 "Cache start of unterminated match to fontify")
|
|
630 (defvar font-latex-match-infont-cache-limit nil
|
|
631 "Cache end of unterminated match to fontify")
|
|
632 (defvar font-latex-match-infont-cache-keywords nil
|
|
633 "Cache keywords of unterminated match to fontify")
|
|
634 (make-variable-buffer-local 'font-latex-match-infont-cache-state)
|
|
635 (make-variable-buffer-local 'font-latex-match-infont-cache-start)
|
|
636 (make-variable-buffer-local 'font-latex-match-infont-cache-limit)
|
|
637 (make-variable-buffer-local 'font-latex-match-infont-cache-keywords)
|
|
638
|
|
639 (defun font-latex-match-font-inside-braces (limit)
|
|
640 "Search for font-changing command like {\bf fubar} before LIMIT.
|
|
641 Sets `match-data' so that:
|
|
642 subexpression 0 is the keyword.
|
|
643 subexpression 1 is the content to fontify in italic.
|
|
644 subexpression 2 is the content to fontify in bold.
|
|
645 subexpression 3 is the content to fontify in type-face.
|
|
646 Returns nil if no font-changing command is found."
|
|
647 (if font-latex-match-infont-cache-state
|
|
648 (setq font-latex-match-infont-cache-state nil) ;Stop now!
|
|
649 (when (and font-latex-match-infont-cache-keywords
|
|
650 (equal font-latex-match-infont-cache-keywords keywords)
|
|
651 (>= font-latex-match-infont-cache-limit (point))
|
|
652 (< font-latex-match-infont-cache-start (point)))
|
|
653 (goto-char font-latex-match-infont-cache-start)
|
|
654 (setq font-latex-match-infont-cache-state 'stop)) ;Can only do once
|
|
655 (when (re-search-forward
|
|
656 (eval-when-compile
|
|
657 (concat "\\\\" "\\("
|
|
658 ;;; 2 - italic
|
|
659 "\\(em\\|it\\(shape\\)?\\|sl\\(shape\\)?\\)\\|"
|
|
660 ;;; 5 - bold
|
|
661 "\\(bf\\(series\\)?\\|upshape\\|sc\\(shape\\)?\\)\\|"
|
|
662 "mdseries\\|tt\\(family\\)?\\|"
|
|
663 "sf\\(family\\)?\\|rm\\(family\\)?\\|"
|
|
664 "tiny\\|scriptsize\\|footnotesize\\|"
|
|
665 "small\\|normalsize\\|large\\|Large\\|LARGE\\|huge\\|Huge"
|
|
666 "\\)\\>[ \t]*"))
|
|
667 limit t)
|
|
668 (cond
|
|
669 ((font-latex-commented-outp)
|
|
670 ;; Return a nul match such that we skip over this pattern.
|
|
671 ;; (Would be better to skip over internally to this function)
|
|
672 ;; Using `prepend' won't help here, because the problem is that
|
|
673 ;; scan-sexp *fails* to find a commented-out matching bracket!
|
|
674 (store-match-data (list nil nil))
|
|
675 t)
|
|
676 (t
|
|
677 (let ((kbeg (match-beginning 0)) (kend (match-end 1))
|
|
678 (beg (match-end 0)) end itbeg itend bfbeg bfend ttbeg ttend)
|
|
679 (goto-char (match-beginning 0))
|
|
680 (cond
|
|
681 ((not (eq (preceding-char) ?\{))
|
|
682 ;; Fontify only the keyword as bf/it/type (no argument found).
|
|
683 (cond ((match-beginning 2) (setq itbeg kbeg itend kend))
|
|
684 ((match-beginning 5) (setq bfbeg kbeg bfend kend))
|
|
685 (t (setq ttbeg kbeg ttend kend)))
|
|
686 (goto-char (match-end 0))
|
|
687 (store-match-data
|
|
688 (list nil nil itbeg itend bfbeg bfend ttbeg ttend))
|
|
689 t)
|
|
690 (t
|
|
691 (condition-case nil
|
|
692 (forward-char -1)
|
|
693 (error))
|
|
694 (save-restriction
|
|
695 ;; Restrict to LIMIT.
|
|
696 (narrow-to-region (point-min) limit)
|
|
697 (if (condition-case nil
|
|
698 (goto-char (or (scan-sexps (point) 1) (point-max)))
|
|
699 (error))
|
|
700 (setq end (1- (point)))
|
|
701 (setq end (point-max))
|
|
702 (goto-char end)
|
|
703 (setq font-latex-match-infont-cache-state 'stop)))
|
|
704 (cond ((match-beginning 2) (setq itbeg beg itend end))
|
|
705 ((match-beginning 5) (setq bfbeg beg bfend end))
|
|
706 (t (setq ttbeg beg ttend end)))
|
|
707 (store-match-data
|
|
708 (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
|
|
709 (when font-latex-match-infont-cache-state
|
|
710 (setq font-latex-match-infont-cache-start kbeg)
|
|
711 (setq font-latex-match-infont-cache-limit (point))
|
|
712 (setq font-latex-match-infont-cache-keywords keywords))
|
|
713 ;; Start the subsequent search immediately after this keyword.
|
|
714 (goto-char kend)))))))))
|
|
715
|
|
716 ;;; FIXME: Add caches for math-env, math-envII and quotations.
|
|
717 (defun font-latex-match-math-env (limit)
|
|
718 "Used for patterns like:
|
|
719 \\( F = ma \\)
|
|
720 \\ [ F = ma \\] but not \\\\ [len]"
|
|
721 (when (re-search-forward "\\(\\\\(\\)\\|\\(\\\\\\[\\)" limit t)
|
|
722 (goto-char (match-beginning 0))
|
|
723 (if (eq (preceding-char) ?\\) ; \\[ is not a math environment
|
|
724 (progn
|
|
725 (goto-char (match-end 0))
|
|
726 (store-match-data (list nil nil))
|
|
727 t)
|
|
728 (let ((b1start (point)))
|
|
729 (search-forward (cond ((match-beginning 1) "\\)")
|
|
730 (t "\\]"))
|
|
731 limit 'move)
|
|
732 (let ((b2end (or (match-end 0) (point))))
|
|
733 (store-match-data (list b1start b2end))
|
|
734 t)))))
|
|
735
|
|
736 (defun font-latex-match-math-envII (limit)
|
|
737 "Used for patterns like:
|
|
738 \\begin{equation}
|
|
739 fontified stuff
|
|
740 \\end{equation}
|
|
741 The \\begin{equation} and \\end{equation are not fontified here."
|
|
742 (when (re-search-forward
|
|
743 (eval-when-compile
|
|
744 (concat "\\\\begin{\\(\\(display\\)?math\\|equation\\|eqnarray"
|
|
745 "\\|gather\\|multline\\|align\\|x*alignat"
|
|
746 "\\)\\*?}"))
|
|
747 limit t)
|
|
748 (let ((beg (match-end 0)) end)
|
|
749 (if (search-forward (concat "\\end{" (buffer-substring
|
|
750 (match-beginning 1)(match-end 0)))
|
|
751 limit 'move)
|
|
752 (setq end (match-beginning 0))
|
|
753 (setq end (point)))
|
|
754 (store-match-data (list beg end))
|
|
755 t)))
|
|
756
|
|
757 (defun font-latex-match-quotation (limit)
|
|
758 "Used for patterns like:
|
|
759 ``this is a normal quote'' and these are multilingual quoted strings:
|
|
760 \"< french \"> and \"`german\"' quotes, << french >> and 8-bit french."
|
|
761 (when (re-search-forward
|
|
762 (eval-when-compile
|
|
763 (concat "\\(``\\)\\|\\(\"<\\)\\|\\(\"`\\)\\|\\(<<\\)\\|"
|
|
764 "\\(" (char-to-string 171) "\\)")) ; An 8-bit "<<"
|
|
765 limit t)
|
|
766 (let ((beg (match-beginning 0)))
|
|
767 (search-forward
|
|
768 (cond ((match-beginning 1) "''")
|
|
769 ((match-beginning 2) "\">")
|
|
770 ((match-beginning 3) "\"'")
|
|
771 ((match-beginning 4) ">>")
|
|
772 ((match-beginning 5) (eval-when-compile (char-to-string 187))))
|
|
773 limit 'move)
|
|
774 (store-match-data (list beg (point)))
|
|
775 t)))
|
|
776
|
|
777 ;; Install ourselves
|
|
778
|
|
779 (add-hook 'LaTeX-mode-hook 'font-latex-setup)
|
|
780 (add-hook 'latex-mode-hook 'font-latex-setup)
|
|
781 ;; If font-latex is loaded using a latex-mode-hook, then the add-hook above
|
|
782 ;; won't be called this time around. Check for this now:
|
|
783 (if (eq major-mode 'latex-mode)
|
|
784 (font-latex-setup))
|
|
785
|
|
786 ;; Provide ourselves:
|
|
787
|
|
788 (provide 'font-latex)
|
|
789
|
|
790 ;;; font-latex.el ends here
|