1;;; font-latex.el --- LaTeX fontification for Font Lock mode. 2 3;; Copyright (C) 1996-2019 Free Software Foundation, Inc. 4 5;; Authors: Peter S. Galbraith <psg@debian.org> 6;; Simon Marshall <Simon.Marshall@esrin.esa.it> 7;; Maintainer: auctex-devel@gnu.org 8;; Created: 06 July 1996 9;; Keywords: tex, wp, faces 10 11;;; This file is not part of GNU Emacs. 12 13;; This package is free software; you can redistribute it and/or modify 14;; it under the terms of the GNU General Public License as published by 15;; the Free Software Foundation; either version 3, or (at your option) 16;; any later version. 17 18;; This package is distributed in the hope that it will be useful, 19;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21;; GNU General Public License for more details. 22 23;; You should have received a copy of the GNU General Public License 24;; along with GNU Emacs; see the file COPYING. If not, write to the 25;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 26;; Boston, MA 02110-1301, USA. 27 28;;; Commentary: 29;; 30;; This package enhances font-lock fontification patterns for LaTeX. 31;; font-lock mode is a minor mode that causes your comments to be 32;; displayed in one face, strings in another, reserved words in 33;; another, and so on. 34;; 35;; ** Infinite loops !? ** 36;; If you get an infinite loop, send a bug report! 37;; Then set the following in your ~/.emacs file to keep on working: 38;; (setq font-latex-do-multi-line nil) 39 40;;; Code: 41 42(require 'font-lock) 43(require 'tex) 44 45(eval-when-compile 46 (require 'cl-lib)) 47 48(defgroup font-latex nil 49 "Font-latex text highlighting package." 50 :prefix "font-latex-" 51 :group 'faces 52 :group 'tex 53 :group 'AUCTeX) 54 55(defgroup font-latex-keywords nil 56 "Keywords for highlighting text in font-latex." 57 :prefix "font-latex-" 58 :group 'font-latex) 59 60(defgroup font-latex-highlighting-faces nil 61 "Faces for highlighting text in font-latex." 62 :prefix "font-latex-" 63 :group 'font-latex) 64 65(defvar font-latex-multiline-boundary 5000 66 "Size of region to search for the start or end of a multiline construct.") 67 68(defvar font-latex-quote-regexp-beg nil 69 "Regexp used to find quotes.") 70(make-variable-buffer-local 'font-latex-quote-regexp-beg) 71 72(defvar font-latex-quote-list '(("``" "''") ("<<" ">>" french) ("«" "»" french)) 73 "List of quote specifiers for quotation fontification. 74 75Each element of the list is either a list consisting of two 76strings to be used as opening and closing quotation marks 77independently of the value of `font-latex-quotes' or a list with 78three elements where the first and second element are strings for 79opening and closing quotation marks and the third element being 80either the symbol 'german or 'french describing the order of 81quotes. 82 83If `font-latex-quotes' specifies a different state, order of the 84added quotes will be reversed for fontification. For example if 85'(\"\\\"<\" \"\\\">\" french) is given but `font-latex-quotes' 86specifies 'german, quotes will be used like \">foo\"< for 87fontification.") 88 89(defvar font-latex-quotes-control nil 90 "Internal variable for keeping track if `font-latex-quotes' changed.") 91(make-variable-buffer-local 'font-latex-quotes-control) 92 93(defvar font-latex-quotes-internal nil 94 "Internal variable for tracking outcome of automatic detection. 95If automatic detection is not enabled, it is assigned the value 96of `font-latex-quotes'.") 97(make-variable-buffer-local 'font-latex-quotes-internal) 98 99(defvar font-latex-quotes-fallback 'french 100 "Fallback value for `font-latex-quotes' if automatic detection fails.") 101 102(defvar font-latex-quote-style-list-french 103 '("french" "frenchb" "frenchle" "frenchpro" "francais" "canadien" 104 "acadian" "italian") 105 "List of styles for which French-style quote matching should be activated.") 106 107(defvar font-latex-quote-style-list-german 108 '("austrian" "german" "germanb" "naustrian" "ngerman") 109 "List of styles for which German-style quote matching should be activated.") 110 111(defcustom font-latex-quotes 'auto 112 "Whether to fontify << French quotes >> or >>German quotes<<. 113Also selects \"<quote\"> versus \">quote\"<. 114 115If value `auto' is chosen, an attempt is being made in deriving 116the type of quotation mark matching from document settings like 117the language option supplied to the babel package. 118 119If nil, quoted content will not be fontified." 120 :type '(choice (const auto) (const french) (const german) (const nil)) 121 :group 'font-latex) 122(put 'font-latex-quotes 'safe-local-variable 123 '(lambda (x) (memq x '(auto french german nil)))) 124 125(defun font-latex-add-quotes (quotes) 126 "Add QUOTES to `font-latex-quote-list'. 127QUOTES has to be a list adhering to the format of an element of 128`font-latex-quote-list'." 129 (setq font-latex-quotes-control nil) 130 (add-to-list (make-local-variable 'font-latex-quote-list) quotes)) 131 132(defun font-latex-quotes-set-internal () 133 "Set `font-latex-quotes-internal' according to `font-latex-quotes'. 134If `font-latex-quotes' is set to `auto', try to derive the 135correct value from document properties." 136 (setq font-latex-quotes-internal 137 (if (eq font-latex-quotes 'auto) 138 (or (when (TeX-elt-of-list-member 139 font-latex-quote-style-list-french TeX-active-styles) 140 'french) 141 (when (TeX-elt-of-list-member 142 font-latex-quote-style-list-german TeX-active-styles) 143 'german) 144 font-latex-quotes-fallback) 145 font-latex-quotes))) 146;; Update the value of `font-latex-quotes-internal' when the list of 147;; styles changes. 148(add-hook 'TeX-update-style-hook 'font-latex-quotes-set-internal) 149 150;; The definitions of the title faces were originally taken from 151;; info.el (Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 97, 98, 99, 152;; 2000, 2001 Free Software Foundation, Inc.) and adapted to the needs 153;; of font-latex.el. 154 155(defconst font-latex-sectioning-max 5 156 "Highest number for font-latex-sectioning-N-face") 157(defface font-latex-sectioning-5-face 158 '((((type tty pc) (class color) (background light)) 159 (:foreground "blue4" :weight bold)) 160 (((type tty pc) (class color) (background dark)) 161 (:foreground "yellow" :weight bold)) 162 (((class color) (background light)) 163 (:weight bold :inherit variable-pitch :foreground "blue4")) 164 (((class color) (background dark)) 165 (:weight bold :inherit variable-pitch :foreground "yellow")) 166 (t (:weight bold :inherit variable-pitch))) 167 "Face for sectioning commands at level 5." 168 :group 'font-latex-highlighting-faces) 169 170(defun font-latex-update-sectioning-faces (&optional max height-scale) 171 "Update sectioning commands faces." 172 (unless height-scale 173 (setq height-scale (if (numberp font-latex-fontify-sectioning) 174 ;; Make sure `height-scale' is a floating point 175 ;; number because `set-face-attribute' treats 176 ;; integers differently from floating points. 177 (float font-latex-fontify-sectioning) 178 1.1))) 179 (unless max 180 (setq max font-latex-sectioning-max)) 181 (dotimes (num max) 182 (let* (;; reverse for XEmacs: 183 (num (- max (1+ num))) 184 (face-name (intern (format "font-latex-sectioning-%s-face" num)))) 185 (unless (get face-name 'saved-face) ; Do not touch customized faces. 186 (set-face-attribute face-name nil :height height-scale))))) 187 188(defcustom font-latex-fontify-sectioning 1.1 189 "Whether to fontify sectioning macros with varying height or a color face. 190 191If it is a number, use varying height faces. The number is used 192for scaling starting from `font-latex-sectioning-5-face'. Typically 193values from 1.05 to 1.3 give best results, depending on your font 194setup. If it is the symbol `color', use `font-lock-type-face'. 195 196Caveats: Customizing the scaling factor applies to all sectioning 197faces unless those face have been saved by customize. Setting 198this variable directly does not take effect unless you call 199`font-latex-update-sectioning-faces' or restart Emacs. 200 201Switching from `color' to a number or vice versa does not take 202effect unless you call \\[font-lock-fontify-buffer] or restart 203Emacs." 204 :type '(choice (number :tag "Scale factor") 205 (const color)) 206 :initialize 'custom-initialize-default 207 :set (lambda (symbol value) 208 (set-default symbol value) 209 (unless (eq value 'color) 210 (font-latex-update-sectioning-faces font-latex-sectioning-max value))) 211 :group 'font-latex) 212 213(defun font-latex-make-sectioning-faces (max &optional height-scale) 214 "Build the faces used to fontify sectioning commands." 215 (unless max (setq max font-latex-sectioning-max)) 216 (unless height-scale 217 (setq height-scale (if (numberp font-latex-fontify-sectioning) 218 ;; Make sure `height-scale' is a floating point 219 ;; number because the integer type is treated 220 ;; differently. 221 (float font-latex-fontify-sectioning) 222 1.1))) 223 (dotimes (num max) 224 (let* ((num (- max (1+ num))) 225 (face-name (intern (format "font-latex-sectioning-%s-face" num))) 226 (f-inherit (intern (format "font-latex-sectioning-%s-face" (1+ num))))) 227 (eval 228 `(defface ,face-name 229 '((t (:height ,height-scale :inherit ,f-inherit))) 230 (format "Face for sectioning commands at level %s. 231 232Probably you don't want to customize this face directly. Better 233change the base face `font-latex-sectioning-5-face' or customize the 234variable `font-latex-fontify-sectioning'." ',num) 235 :group 'font-latex-highlighting-faces))))) 236 237(font-latex-make-sectioning-faces font-latex-sectioning-max) 238 239 240;;; Keywords 241 242(defvar font-latex-keywords-1 nil 243 "Subdued level highlighting for LaTeX modes.") 244 245(defvar font-latex-keywords-2 nil 246 "High level highlighting for LaTeX modes.") 247 248(defvar font-latex-built-in-keyword-classes 249 '(("warning" 250 ("nopagebreak" "pagebreak" "newpage" "clearpage" "cleardoublepage" 251 "enlargethispage" "nolinebreak" "linebreak" "newline" "-" "\\" "\\*" 252 "appendix" "displaybreak" "allowdisplaybreaks" "include") 253 font-latex-warning-face 1 noarg) 254 ("variable" 255 (("setlength" "|{\\{") ("settowidth" "|{\\{") ("settoheight" "{{") 256 ("settodepth" "{{") ("setcounter" "{|{\\") 257 ("addtolength" "|{\\{") ("addtocounter" "{|{\\") 258 ("stepcounter" "{") ("refstepcounter" "{") 259 ("arabic" "{") ("roman" "{") ("Roman" "{") ("alph" "{") ("Alph" "{") 260 ("fnsymbol" "{")) 261 font-lock-variable-name-face 2 command) 262 ("biblatexnoarg" 263 ("newrefsegment" "mancite" "pno" "ppno" "nopp" "psq" "psqq") 264 font-lock-variable-name-face 2 noarg) 265 ("biblatex" 266 (;; 3.2.2 Setting Package Options 267 ("ExecuteBibliographyOptions" "[{") 268 ;; 3.7.1 Resources 269 ("addbibresource" "[{") ("addglobalbib" "[{") ("addsectionbib" "[{") 270 ;; 3.7.2 The Bibliography 271 ("printbibliography" "[") ("bibbysection" "[") ("bibbysegment" "[") 272 ("bibbycategory" "[") ("printbibheading" "[") 273 ;; 3.7.3 Bibliography Lists 274 ("printbiblist" "[{") ("printshorthands" "[") 275 ;; 3.7.4 Bibliography Sections 276 ("newrefsection" "[") 277 ;; 3.7.6 Bibliography Categories 278 ("DeclareBibliographyCategory" "{") ("addtocategory" "{{") 279 ;; 3.7.7 Bibliography Headings and Environments 280 ("defbibenvironment" "{{{{") ("defbibheading" "{[{") 281 ;; 3.7.8 Bibliography Notes 282 ("defbibnote" "{{") 283 ;; 3.7.9 Bibliography Filters and Checks 284 ("defbibfilter" "{{") ("defbibcheck" "{{") 285 ;; 3.7.10 Reference Contexts 286 ("DeclareRefcontext" "{{") ("newrefcontext" "[{") 287 ("assignrefcontextkeyws" "*[{") ("assignrefcontextcats" "*[{") 288 ("assignrefcontextentries" "*[{") 289 ;; 3.7.11 Dynamic Entry Sets 290 ("defbibentryset" "{{") 291 ;; 3.8.1 Standard Commands 292 ("Cite" "[[{") 293 ("parencite" "*[[{") ("Parencite" "[[{") 294 ("footcite" "[[{") ("footcitetext" "[[{") 295 ;; 3.8.2 Style-specific Commands 296 ("textcite" "[[{") ("Textcite" "[[{") 297 ("smartcite" "[[{") ("Smartcite" "[[{") 298 ("supercite" "{") 299 ;; 3.8.3 Qualified Citation Lists 300 ;; For qualified lists, fontify at least 2 mandatory arguments 301 ("cites" "(([[{[[{") ("Cites" "(([[{[[{") 302 ("parencites" "(([[{[[{") ("Parencites" "(([[{[[{") 303 ("footcites" "(([[{[[{") ("footcitetexts" "(([[{[[{") 304 ("smartcites" "(([[{[[{") ("Smartcites" "(([[{[[{") 305 ("textcites" "(([[{[[{") ("Textcites" "(([[{[[{") 306 ("supercites" "(([[{[[{") 307 ;; 3.8.4 Style-independent Commands 308 ("autocite" "*[[{") ("Autocite" "*[[{") 309 ("autocites" "(([[{[[{") ("Autocites" "(([[{[[{") 310 ;; 3.8.5 Text Commands 311 ("citeauthor" "*[[{") ("Citeauthor" "*[[{") ("citetitle" "*[[{") 312 ("citeyear" "*[[{") ("citedate" "*[[{") 313 ("citeurl" "[[{") ("parentext" "{") 314 ("brackettext" "{") 315 ;; 3.8.6 Special Commands 316 ("fullcite" "[[{") ("footfullcite" "[[{") 317 ("volcite" "[{[{") ("Volcite" "[{[{") 318 ("volcites" "(([{[{[{[{") ("Volcites" "(([{[{[{[{") 319 ("pvolcite" "[{[{") ("Pvolcite" "[{[{") 320 ("pvolcites" "(([{[{[{[{") ("Pvolcites" "(([{[{[{[{") 321 ("fvolcite" "[{[{") ("ftvolcite" "[{[{") 322 ("fvolcites" "(([{[{[{[{") ("Fvolcites" "(([{[{[{[{") 323 ("svolcite" "[{[{") ("Svolcite" "[{[{") 324 ("svolcites" "(([{[{[{[{") ("Svolcites" "(([{[{[{[{") 325 ("tvolcite" "[{[{") ("Tvolcite" "[{[{") 326 ("tvolcites" "(([{[{[{[{") ("Tvolcites" "(([{[{[{[{") 327 ("avolcite" "[{[{") ("Avolcite" "[{[{") 328 ("avolcites" "(([{[{[{[{") ("Avolcites" "(([{[{[{[{") 329 ("notecite" "[[{") ("Notecite" "[[{") 330 ("pnotecite" "[[{") ("Pnotecite" "[[{") 331 ("fnotecite" "[[{") 332 ;; 3.8.7 Low-level Commands 333 ("citename" "[[{[{") ("citelist" "[[{[{") ("citefield" "[[{[{") 334 ;; 3.8.8 Miscellaneous Commands 335 ("citereset" "*") ("RN" "{") ("Rn" "{") 336 ;; 3.9 Localization Commands 337 ("DefineBibliographyStrings" "{{") ("DefineBibliographyExtras" "{{") 338 ("UndefineBibliographyExtras" "{{") ("DefineHyphenationExceptions" "{{") 339 ("NewBibliographyString" "{")) 340 font-lock-constant-face 2 command) 341 ("reference" 342 (("nocite" "*{") ("cite" "*[[{") ("label" "{") ("pageref" "{") 343 ("vref" "*{") ("eqref" "{") ("ref" "{") ("Ref" "{") ("include" "{") 344 ("input" "{") ("bibliography" "{") ("index" "{") ("glossary" "{") 345 ("footnote" "[{") ("footnotemark" "[") ("footnotetext" "[{") 346 ("marginpar" "[{")) 347 font-lock-constant-face 2 command) 348 ("function" 349 (("begin" "{") ("end" "{") ("pagenumbering" "{") 350 ("thispagestyle" "{") ("pagestyle" "{") ("nofiles" "") 351 ("includeonly" "{") ("bibliographystyle" "{") ("documentstyle" "[{") 352 ("documentclass" "[{[") ("newenvironment" "*{[[{{") 353 ("newcommand" "*|{\\[[{") ("newlength" "|{\\") 354 ("newtheorem" "{[{[") 355 ("providecommand" "*|{\\[[{") 356 ("newcounter" "{[") ("renewenvironment" "*{[[{{") 357 ("renewcommand" "*|{\\[[{") ("renewtheorem" "{[{[") 358 ("usepackage" "[{[") ("fbox" "{") ("mbox" "{") ("rule" "[{{") 359 ("addvspace" "{") ("vspace" "*{") ("hspace" "*{") 360 ("thinspace" "") ("negthinspace" "") 361 ("labelformat" "{{") 362 ;; XXX: Should macros without arguments rather be listed in a 363 ;; separate category with 'noarg instead of 'command handling? 364 ("enspace" "") ("enskip" "") ("quad" "") ("qquad" "") ("nonumber" "") 365 ("centering" "") ("raggedright" "") ("raggedleft" "") 366 ("TeX" "") ("LaTeX" "") ("LaTeXe" "")) 367 font-lock-function-name-face 2 command) 368 ("sectioning-0" 369 (("part" "*[{")) 370 (if (eq font-latex-fontify-sectioning 'color) 371 'font-lock-type-face 372 'font-latex-sectioning-0-face) 373 2 command) 374 ("sectioning-1" 375 (("chapter" "*[{")) 376 (if (eq font-latex-fontify-sectioning 'color) 377 'font-lock-type-face 378 'font-latex-sectioning-1-face) 379 2 command) 380 ("sectioning-2" 381 (("section" "*[{")) 382 (if (eq font-latex-fontify-sectioning 'color) 383 'font-lock-type-face 384 'font-latex-sectioning-2-face) 385 2 command) 386 ("sectioning-3" 387 (("subsection" "*[{")) 388 (if (eq font-latex-fontify-sectioning 'color) 389 'font-lock-type-face 390 'font-latex-sectioning-3-face) 391 2 command) 392 ("sectioning-4" 393 (("subsubsection" "*[{")) 394 (if (eq font-latex-fontify-sectioning 'color) 395 'font-lock-type-face 396 'font-latex-sectioning-4-face) 397 2 command) 398 ("sectioning-5" 399 (("paragraph" "*[{") ("subparagraph" "*[{") 400 ("subsubparagraph" "*[{")) 401 (if (eq font-latex-fontify-sectioning 'color) 402 'font-lock-type-face 403 'font-latex-sectioning-5-face) 404 2 command) 405 ("slide-title" () font-latex-slide-title-face 2 command) 406 ("textual" 407 (("item" "[") ("bibitem" "[{") ("title" "{") ("author" "{") ("date" "{") 408 ("thanks" "{") ("address" "{") ("caption" "[{") 409 ("textsuperscript" "{") ("textsubscript" "{") ("verb" "*")) 410 font-lock-type-face 2 command) 411 ("bold-command" 412 (("textbf" "{") ("textsc" "{") ("textup" "{") ("boldsymbol" "{") 413 ("pmb" "{")) 414 font-latex-bold-face 1 command) 415 ("italic-command" 416 (("emph" "{") ("textit" "{") ("textsl" "{")) 417 font-latex-italic-face 1 command) 418 ("math-command" 419 (("ensuremath" "|{\\")) 420 font-latex-math-face 1 command) 421 ("type-command" 422 (("texttt" "{") ("textsf" "{") ("textrm" "{") ("textmd" "{") ("oldstylenums" "{")) 423 font-lock-type-face 1 command) 424 ("bold-declaration" 425 ("bf" "bfseries" "sc" "scshape" "upshape") 426 font-latex-bold-face 1 declaration) 427 ("italic-declaration" 428 ("em" "it" "itshape" "sl" "slshape") 429 font-latex-italic-face 1 declaration) 430 ("type-declaration" 431 ("tt" "ttfamily" "sf" "sffamily" "rm" "rmfamily" "mdseries" 432 "tiny" "scriptsize" "footnotesize" "small" "normalsize" 433 "large" "Large" "LARGE" "huge" "Huge") 434 font-lock-type-face 1 declaration)) 435 "Built-in keywords and specifications for font locking. 436 437The first element of each item is the name of the keyword class. 438 439The second element is a list of keywords (macros without an 440escape character) to highlight or, if the fifth element is the 441symbol 'command, a list of lists where the first element of each 442item is a keyword and the second a string specifying the macro 443syntax. It can contain \"*\" if the macro has a starred variant, 444\"[\" for an optional argument, \"{\" for a mandatory argument, 445and \"\\\" for a macro. A \"|\" means the following two tokens 446should be regarded as alternatives. 447 448The third element is the symbol of a face to be used or a Lisp 449form returning a face symbol. 450 451The fourth element is the fontification level. 452 453The fifth element is the type of construct to be matched. It can 454be one of 'noarg which will match simple macros without 455arguments (like \"\\foo\"), 'declaration which will match macros 456inside a TeX group (like \"{\\bfseries foo}\"), or 'command which 457will match macros of the form \"\\foo[bar]{baz}\".") 458 459(defcustom font-latex-deactivated-keyword-classes nil 460 "List of strings for built-in keyword classes to be deactivated. 461 462Valid entries are \"warning\", \"variable\", \"biblatexnoarg\", 463\"biblatex\", \"reference\", \"function\" , \"sectioning-0\", 464\"sectioning-1\", \"sectioning-2\", \"sectioning-3\", 465\"sectioning-4\", \"sectioning-5\", \"slide-title\", \"textual\", 466\"bold-command\", \"italic-command\", \"math-command\", 467\"type-command\", \"bold-declaration\", \"italic-declaration\", 468\"type-declaration\". 469 470You have to restart Emacs for a change of this variable to take effect." 471 :group 'font-latex-keywords 472 :type `(set ,@(mapcar 473 (lambda (spec) 474 `(const :tag ,(concat 475 ;; Name of the keyword class 476 (let ((name (split-string (car spec) "-"))) 477 (setcar name (capitalize (car name))) 478 (mapconcat 'identity name " ")) 479 " keywords in `" 480 ;; Name of the face 481 (symbol-name 482 (let ((face (nth 2 spec))) 483 (if (symbolp face) face (eval face)))) 484 "'.\n" 485 ;; List of keywords 486 (with-temp-buffer 487 (insert " Keywords: " 488 (mapconcat (lambda (x) 489 (if (listp x) 490 (car x) 491 x)) 492 (nth 1 spec) ", ")) 493 (fill-paragraph nil) 494 (buffer-string))) 495 ,(car spec))) 496 font-latex-built-in-keyword-classes))) 497 498(defun font-latex-make-match-defun (prefix name face type) 499 "Return a function definition for keyword matching. 500The variable holding the keywords to match are determined by the 501strings PREFIX and NAME. The type of matcher is determined by 502the symbol TYPE. 503 504This is a helper function for `font-latex-make-built-in-keywords' 505and `font-latex-make-user-keywords' and not intended for general 506use." 507 ;; Note: The functions are byte-compiled at the end of font-latex.el. 508 ;; FIXME: Is the cond-clause possible inside of the defun? 509 510 ;; In an earlier version of font-latex the type could be a list like 511 ;; (command 1). This indicated a macro with one argument. Provide 512 ;; a match function in this case but don't actually support it. 513 (cond ((or (eq type 'command) (listp type)) 514 (eval `(defun ,(intern (concat prefix name)) (limit) 515 ,(concat "Fontify `" prefix name "' up to LIMIT. 516 517Generated by `font-latex-make-match-defun'.") 518 (when ,(intern (concat prefix name)) 519 (font-latex-match-command-with-arguments 520 ,(intern (concat prefix name)) 521 (append 522 (when (boundp ',(intern (concat prefix name 523 "-keywords-local"))) 524 ,(intern (concat prefix name "-keywords-local"))) 525 ,(intern (concat prefix name "-keywords"))) 526 ;; `face' can be a face symbol, a form returning 527 ;; a face symbol, or a list of face attributes. 528 ,(if (and (listp face) (fboundp (car face))) 529 face 530 `',face) 531 limit))))) 532 ((eq type 'declaration) 533 (eval `(defun ,(intern (concat prefix name)) (limit) 534 ,(concat "Fontify `" prefix name "' up to LIMIT. 535 536Generated by `font-latex-make-match-defun'.") 537 (when ,(intern (concat prefix name)) 538 (font-latex-match-command-in-braces 539 ,(intern (concat prefix name)) limit))))) 540 ((eq type 'noarg) 541 (eval `(defun ,(intern (concat prefix name)) (limit) 542 ,(concat "Fontify `" prefix name "' up to LIMIT. 543 544Generated by `font-latex-make-match-defun'.") 545 (when ,(intern (concat prefix name)) 546 (re-search-forward 547 ,(intern (concat prefix name)) limit t))))))) 548 549(defun font-latex-keyword-matcher (prefix name face type) 550 "Return a matcher and highlighter as required by `font-lock-keywords'. 551PREFIX and NAME are strings which are concatenated to form the 552respective match function. FACE is a face name or a list of face 553attributes that will be applied to the respective part of the 554match returned by the match function. A lisp form returning a 555face name or a list of face attributes is also valid for FACE. 556TYPE is the type of construct to be highlighted. Currently the 557symbols 'command, 'declaration and 'noarg are valid. 558 559This is a helper function for `font-latex-make-built-in-keywords' 560and `font-latex-make-user-keywords' and not intended for general 561use." 562 ;; Quote a list of face attributes and a face symbol 563 ;; but do not quote a form returning such value. 564 (unless (and (listp face) (fboundp (car face))) 565 (setq face `',face)) 566 567 ;; In an earlier version of font-latex the type could be a list like 568 ;; (command 1). This indicated a macro with one argument. Provide 569 ;; a matcher in this case but don't actually support it. 570 (cond ((or (eq type 'command) (listp type)) 571 `(,(intern (concat prefix name)) 572 (0 (font-latex-matched-face 0) append t) 573 (1 (font-latex-matched-face 1) append t) 574 (2 (font-latex-matched-face 2) append t) 575 (3 (font-latex-matched-face 3) append t) 576 (4 (font-latex-matched-face 4) append t) 577 (5 (font-latex-matched-face 5) append t) 578 (6 (font-latex-matched-face 6) append t) 579 (7 (font-latex-matched-face 7) append t) 580 (8 (font-latex-matched-face 8) append t) 581 (9 (font-latex-matched-face 9) append t) 582 (10 (font-latex-matched-face 10) append t) 583 (11 (font-latex-matched-face 11) append t))) 584 ((eq type 'noarg) 585 `(,(intern (concat prefix name)) 586 (0 ,face))) 587 ((eq type 'declaration) 588 `(,(intern (concat prefix name)) 589 (0 'font-latex-warning-face t t) 590 (1 'font-lock-keyword-face append t) 591 (2 ,face append t))))) 592 593(defun font-latex-make-built-in-keywords () 594 "Build defuns, defvars and defcustoms for built-in keyword fontification." 595 (dolist (item font-latex-built-in-keyword-classes) 596 (let ((prefix "font-latex-match-") 597 (name (nth 0 item)) 598 (keywords (nth 1 item)) 599 (face (nth 2 item)) 600 (level (nth 3 item)) 601 (type (nth 4 item))) 602 603 ;; defvar font-latex-match-*-keywords-local 604 (eval `(defvar ,(intern (concat prefix name "-keywords-local")) 605 ',keywords 606 ,(concat "Buffer-local keywords to add to `" 607 prefix name "-keywords'.\n\n" 608 (if (eq type 'command) 609 "\ 610This must be a list where each element is a list consisting of a 611keyword string \(not a regular expression\) omitting the leading 612backslash and a format specifier as described in the doc string of 613`font-latex-user-keyword-classes'." 614 "\ 615This must be a list where each element is a keyword string \(not a 616regular expression\) omitting the leading backslash.") 617 618 "\n\n\ 619This is an internal variable which should not be set directly. 620Use `font-latex-add-keywords' instead. 621 622Generated by `font-latex-make-built-in-keywords'."))) 623 (make-variable-buffer-local 624 (intern (concat prefix name "-keywords-local"))) 625 626 ;; defun font-latex-match-*-make 627 ;; Note: The functions are byte-compiled at the end of font-latex.el. 628 (eval `(defun ,(intern (concat prefix name "-make")) () 629 ,(concat "Make or remake the variable `" prefix name "'. 630 631Generated by `font-latex-make-built-in-keywords'.") 632 (let ((keywords 633 (append 634 (unless (member ,name 635 font-latex-deactivated-keyword-classes) 636 ,(intern (concat prefix name "-keywords-local"))) 637 ,(intern (concat prefix name "-keywords")))) 638 multi-char-macros single-char-macros) 639 (dolist (elt keywords) 640 (let ((keyword (if (listp elt) (car elt) elt))) 641 (if (string-match "^[A-Za-z]" keyword) 642 (push keyword multi-char-macros) 643 (push keyword single-char-macros)))) 644 (when (or multi-char-macros single-char-macros) 645 (setq ,(intern (concat prefix name)) 646 (concat 647 "\\\\\\(" 648 (when multi-char-macros 649 (concat 650 "\\(?:" (regexp-opt multi-char-macros) "\\)\\>")) 651 (when single-char-macros 652 (concat 653 (when multi-char-macros "\\|") 654 "\\(?:" (regexp-opt single-char-macros) "\\)")) 655 "\\)")))))) 656 657 ;; defcustom font-latex-match-*-keywords 658 (eval `(defcustom ,(intern (concat prefix name "-keywords")) nil 659 ,(concat "List of keywords " 660 (when (eq type 'command) "and formats ") 661 "for " name " face.\n" 662 (if (eq type 'command) 663 "\ 664Each element has to be a list consisting of the name of a macro 665omitting the leading backslash and a format specifier as 666described in the doc string of `font-latex-user-keyword-classes'." 667 "\ 668Each element has to be the name of a macro as a string, omitting 669the leading backslash.") 670 "\n\n\ 671Setting this variable directly does not take effect; restart 672Emacs. 673 674Generated by `font-latex-make-built-in-keywords'.") 675 :type '(repeat ,(if (eq type 'command) 676 '(list (string :tag "Keyword") 677 (string :tag "Format")) 678 '(string :tag "Keyword"))) 679 :set (lambda (symbol value) 680 (set-default symbol value) 681 (funcall ',(intern (concat prefix name "-make")))) 682 :group 'font-latex-keywords)) 683 684 ;; defvar font-latex-match-* 685 (eval `(defvar ,(intern (concat prefix name)) nil 686 ,(concat "Regular expression to match " name 687 " keywords. 688 689Generated by `font-latex-make-built-in-keywords'"))) 690 (make-variable-buffer-local (intern (concat prefix name))) 691 692 ;; defun font-latex-match-* 693 (font-latex-make-match-defun prefix name face type) 694 695 ;; Add matchers and highlighters to `font-latex-keywords-{1,2}'. 696 (let ((keywords-entry (font-latex-keyword-matcher 697 prefix name face type))) 698 (add-to-list (intern (concat "font-latex-keywords-" 699 (number-to-string level))) 700 keywords-entry t) 701 (when (= level 1) 702 (add-to-list 'font-latex-keywords-2 703 keywords-entry t)))))) 704(font-latex-make-built-in-keywords) 705 706(defcustom font-latex-user-keyword-classes nil 707 "List of user-defined keyword classes for font locking. 708 709Every keyword class consists of four parts, a name, a list of 710keywords, a face and a specifier for the type of macro to be 711highlighted. 712 713When adding new entries, you have to use unique values for the 714class names, i.e. they must not clash with names of the built-in 715keyword classes or other names given by you. Additionally the 716names must not contain spaces. 717 718The list of keywords defines which commands and declarations 719should be covered by the keyword class. A keyword can either be 720a simple command name omitting the leading backslash or a list 721consisting of the command name and a string specifying the syntax 722of the command. The latter is useful if you want to match LaTeX 723macros with arguments (see below). You can specify the occurence 724and order of optional (\"[\") and mandatory (\"{\") arguments for 725each keyword. For example for \"documentclass\" you'd use \"[{\" 726because the macro has one optional followed by one mandatory 727argument. Optionally starred macros can be indicated with \"*\". 728In case an argument is an unbraced macro, use \"\\\". You can 729also specify two alternative arguments by prefixing them with 730\"|\". As an example, the specifier for \\newcommand is 731\"*|{\\=\\[[{\". 732 733The face argument can either be an existing face or a face 734attribute. 735 736There are three alternatives for the class type: 737 738A value of `command' indicates commands with arguments 739\(\"\\foo[bar]{baz}\"). The mandatory arguments in curly braces 740will get the face you specified. 741 742A value of `declaration' indicates declarations inside of TeX 743groups (\"{\\foo bar}\"). The content inside the braces, 744excluding the command, will get the face you specified. In case 745the braces are missing, the face will be applied to the command 746itself. 747 748A value of `noarg' indicates commands without arguments 749\(\"\\foo\"). The command itself will get the face you 750specified. 751 752Setting this variable directly does not take effect; 753restart Emacs." 754 :group 'font-latex-keywords 755 :type `(repeat (list (string :tag "Name") 756 (choice (repeat :tag "Keywords" (string :tag "Keyword")) 757 (repeat 758 :tag "Keywords with specs" 759 (group (string :tag "Keyword") 760 (string :tag "Format specifier")))) 761 ,'(choice (face :tag "Face name") 762 (custom-face-edit :tag "Face attributes")) 763 (choice :tag "Type" 764 ;; Maps to 765 ;;`font-latex-match-command-with-arguments' 766 (const :tag "Command with arguments" 767 command) 768 ;; Maps to 769 ;;`font-latex-match-command-in-braces' 770 (const :tag "Declaration inside TeX group" 771 declaration) 772 ;; Maps to `re-search-forward' 773 (const :tag "Command without arguments" 774 noarg)))) 775 :set (lambda (symbol value) 776 (dolist (item value) 777 (when (string-match " " (car item)) 778 (error "No spaces allowed in name"))) 779 (let (names names-uniq) 780 (dolist (item (append font-latex-built-in-keyword-classes value)) 781 (setq names (append names (list (car item))))) 782 (setq names (TeX-sort-strings names)) 783 (setq names-uniq (TeX-delete-duplicate-strings names)) 784 (dotimes (i (safe-length names-uniq)) 785 (unless (string= (nth i names) (nth i names-uniq)) 786 (error "Name %S already exists" (nth i names))))) 787 (set-default symbol value) 788 (let ((prefix "font-latex-match-")) 789 (dolist (elt value) 790 (unless (boundp (intern (concat prefix (car elt)))) 791 ;; defvar font-latex-match-* 792 (eval `(defvar ,(intern (concat prefix (car elt))) nil 793 ,(concat "Regular expression to match " (car elt) 794 " keywords. 795 796Generated by `font-latex-user-keyword-classes'")))) 797 (let ((keywords (nth 1 elt)) 798 single-char-macro-flag) 799 (setq keywords (if (listp (car keywords)) 800 (mapcar 'car keywords) 801 keywords)) 802 (catch 'single-char 803 (dolist (keyword keywords) 804 (unless (string-match "^[A-Za-z]" keyword) 805 (setq single-char-macro-flag t) 806 (throw 'single-char nil)))) 807 (set (intern (concat prefix (car elt))) 808 (when (> (safe-length keywords) 0) 809 (concat "\\\\" (let ((max-specpdl-size 1000)) 810 (regexp-opt keywords t)) 811 (unless single-char-macro-flag "\\>"))))))))) 812 813(defun font-latex-make-user-keywords () 814 "Build defuns and defvars for user keyword fontification." 815 (let ((keyword-specs font-latex-user-keyword-classes)) 816 (dolist (item keyword-specs) 817 (let ((prefix "font-latex-match-") 818 (name (nth 0 item)) 819 (keywords (nth 1 item)) 820 (face (nth 2 item)) 821 (type (nth 3 item))) 822 823 ;; defvar font-latex-match-*-keywords 824 (eval `(defvar ,(intern (concat prefix name "-keywords")) ',keywords 825 ,(concat "Font-latex keywords for " name " face. 826 827Generated by `font-latex-make-user-keywords'."))) 828 829 ;; defun font-latex-match-* 830 (font-latex-make-match-defun prefix name face type) 831 832 ;; Add the matcher to `font-latex-keywords-2'. 833 (add-to-list 'font-latex-keywords-2 834 (font-latex-keyword-matcher prefix name face type) t)))) 835 836 ;; Add the "fixed" matchers and highlighters. 837 (dolist (item 838 '(("\\(^\\|[^\\]\\)\\(&+\\)" 2 'font-latex-warning-face) 839 ("\\$\\$\\([^$]+\\)\\$\\$" 1 'font-latex-math-face) 840 (font-latex-match-quotation 841 (0 'font-latex-string-face append) 842 (1 'font-latex-warning-face)) 843 ;; Hack to remove the verbatim face from the \ in 844 ;; \end{verbatim} and similar. The same hack is used in 845 ;; tex-mode.el. 846 ("\\(\\\\\\)end" 847 (1 (get-text-property (match-end 1) 'face) t)))) 848 (add-to-list 'font-latex-keywords-1 item) 849 (add-to-list 'font-latex-keywords-2 item)) 850 (dolist (item 851 '((font-latex-match-math-env 852 (0 'font-latex-warning-face t t) 853 (1 'font-latex-math-face append t)) 854 (font-latex-match-math-envII 855 (0 'font-latex-math-face append t)) 856 (font-latex-match-simple-command 857 (0 'font-latex-sedate-face append)) 858 (font-latex-match-script 859 (1 (font-latex-script (match-beginning 0)) append)) 860 (font-latex-match-script-chars 861 (1 (font-latex-script-char (match-beginning 1)) prepend)))) 862 (add-to-list 'font-latex-keywords-2 item t))) 863(font-latex-make-user-keywords) 864 865(defun font-latex-add-keywords (keywords class) 866 "Add KEYWORDS to CLASS. 867KEYWORDS is a list of keywords or keywords with syntax specs. 868CLASS corresponds to a keyword class and can be one of the 869symbols 'warning, 'variable, 'reference, 'biblatexnoarg, 870'biblatex, 'function, 'sectioning-0, 'sectioning-1, 871'sectioning-2, 'sectioning-3, 'sectioning-4, 'sectioning-5, 872'slide-title, 'textual, 'bold-command, 'italic-command, 873'math-command, 'type-command, 'bold-declaration, 874'italic-declaration or 'type-declaration. 875 876The keywords will be added to the buffer-local list of keywords 877of the respective keyword class and necessary updates of the font 878locking machinery will be triggered." 879 (let* ((class (symbol-name class)) 880 (list (intern (format "font-latex-match-%s-keywords-local" class)))) 881 (dolist (elt keywords) 882 (add-to-list list elt)) 883 (funcall (intern (format "font-latex-match-%s-make" class))) 884 (font-latex-update-font-lock))) 885 886(defvar font-latex-keywords font-latex-keywords-1 887 "Default expressions to highlight in TeX mode.") 888 889 890;;; Subscript and superscript 891 892(defcustom font-latex-fontify-script t 893 "If non-nil, fontify subscript and superscript strings. 894 895By default, super/subscripts are raised/lowered if this variable 896is non-nil. This fontification only affects one level of 897scripts, e.g., in x^{y^z}, the y and the z have the same size and 898are equally raised over x. 899 900If this variable is set to the symbol `multi-level', then y is 901raised above x, and z is raised above y. With many script 902levels, the text might become too small to be readable, thus 903there is the option `font-latex-fontify-script-max-level'. (The 904factors for text shrinking are defined in the faces 905`font-latex-superscript-face' and `font-latex-subscript-face' and 906the raise/lower factor in `font-latex-script-display'.) 907 908If this variable is set to the symbol `invisible', then the 909effect is essentially like `multi-level' but additionally the 910script operators ^ and _ are not displayed." 911 :type '(choice (boolean :tag "Enabled") 912 (const :tag "Multiple levels" multi-level) 913 (const :tag "Hide ^ and _" invisible)) 914 :group 'font-latex) 915(put 'font-latex-fontify-script 'safe-local-variable 916 (lambda (val) 917 (or (booleanp val) 918 (memq val '(multi-level invisible))))) 919 920(defcustom font-latex-fontify-script-max-level 3 921 "Maximum scriptification level for which script faces are applied. 922The faces `font-latex-superscript-face' and 923`font-latex-subscript-face' define custom :height values < 1.0. 924Therefore, scripts are displayed with a slightly smaller font 925than normal math text. If `font-latex-fontify-script' is 926`multi-level' or `invisible', the font size becomes too small to 927be readable after a few levels. This option allows to specify 928the maximum level after which the size of the script text won't 929be shrunken anymore. 930 931For example, see this expression: 932 933 \\( x^{y^{z^a_b}} \\) 934 935x has scriptification level 0, y has level 1, z has level 2, and 936both a and b have scriptification level 3. 937 938If `font-latex-fontify-script-max-level' was 2, then z, a, and b 939would have the same font size. If it was 3 or more, then a and b 940were smaller than z just in the same way as z is smaller than y 941and y is smaller than x." 942 :group 'font-latex 943 :type 'integer) 944 945(defcustom font-latex-script-display '((raise -0.5) . (raise 0.5)) 946 "Display specification for subscript and superscript content. 947The car is used for subscript, the cdr is used for superscripts." 948 :group 'font-latex 949 :type '(cons (choice (sexp :tag "Subscript form") 950 (const :tag "No lowering" nil)) 951 (choice (sexp :tag "Superscript form") 952 (const :tag "No raising" nil)))) 953 954 955;;; Syntactic keywords 956 957(defvar font-latex-syntactic-keywords nil 958 "Syntactic keywords used by `font-latex'.") 959(make-variable-buffer-local 'font-latex-syntactic-keywords) 960 961(defvar font-latex-syntactic-keywords-extra nil 962 "List of syntactic keywords to add to `font-latex-syntactic-keywords'. 963The form should be the same as in `font-lock-syntactic-keywords'.") 964(make-variable-buffer-local 'font-latex-syntactic-keywords-extra) 965 966;; Set and updated in `font-latex-set-syntactic-keywords'. 967(defvar font-latex-doctex-syntactic-keywords nil) 968 969(defun font-latex-set-syntactic-keywords () 970 "Set the variable `font-latex-syntactic-keywords'. 971This function can be used to refresh the variable in case other 972variables influencing its value, like `LaTeX-verbatim-environments', 973have changed." 974 ;; Checks for non-emptiness of lists added in order to cater for 975 ;; installations where `(regexp-opt-group nil)' would enter a loop. 976 (let ((verb-envs (and (fboundp 'LaTeX-verbatim-environments) 977 (LaTeX-verbatim-environments))) 978 (verb-macros-with-delims 979 (and (fboundp 'LaTeX-verbatim-macros-with-delims) 980 (LaTeX-verbatim-macros-with-delims))) 981 (verb-macros-with-braces 982 (and (fboundp 'LaTeX-verbatim-macros-with-braces) 983 (LaTeX-verbatim-macros-with-braces)))) 984 (setq verb-envs (and verb-envs (regexp-opt verb-envs)) 985 verb-macros-with-delims (and verb-macros-with-delims 986 (regexp-opt verb-macros-with-delims)) 987 verb-macros-with-braces (and verb-macros-with-braces 988 (regexp-opt verb-macros-with-braces)) 989 font-latex-syntactic-keywords nil) 990 (unless (= (length verb-envs) 0) 991 (add-to-list 'font-latex-syntactic-keywords 992 `(,(concat 993 "^[ \t]*\\\\begin *{\\(?:" verb-envs "\\)}" 994 ;; Some environments accept an optional and/or mandatory 995 ;; argument that can span over more lines. Between 996 ;; "\begin{<envname>}" and the optional argument there 997 ;; can be whitespaces and the newline can be commented 998 ;; by a "%" character. 999 "[ \t]*\\(?:%.*\n[ \t]*\\)?" 1000 ;; The following line of the regexp matches the optional 1001 ;; argument and allows for up to one level of brackets 1002 ;; inside the argument (e.g., the dialect of a language 1003 ;; in the `lstlisting' environment by the `listings' 1004 ;; package). 1005 "\\(?:\\[[^\]\[]*\\(?:\\[[^\]\[]*\\][^\]\[]*\\)*\\]\\)?" 1006 ;; After the optional argument, there may also be 1007 ;; another mandatory argument(s) (e.g. with VerbatimOut or 1008 ;; the minted envs or defined with `lstnewenvironment'). 1009 "\\(?:{[^}]*}\\)*" 1010 ;; Now match the final newline. The "." alternative 1011 ;; catches the case where verbatim content is written 1012 ;; immediately after the \begin{verbatim}. 1013 "\\(\n\\|.\\)") 1014 (1 "|" t))) 1015 (add-to-list 'font-latex-syntactic-keywords 1016 ;; Using the newline character for the syntax 1017 ;; property often resulted in fontification 1018 ;; problems when text was inserted at the end of 1019 ;; the verbatim environment. That's why we now use 1020 ;; the starting backslash of \end. There is a hack 1021 ;; in `font-latex-make-user-keywords' to remove the 1022 ;; spurious fontification of the backslash. 1023 `(,(concat "\\(\\\\\\)end *{\\(?:" verb-envs "\\)}") 1024 (1 "|" t)))) 1025 (unless (= (length verb-macros-with-delims) 0) 1026 (add-to-list 'font-latex-syntactic-keywords 1027 `(,(concat "\\\\\\(?:" verb-macros-with-delims "\\)" 1028 ;; Some macros take an optional 1029 ;; argument. This is the same line as 1030 ;; above for environments. 1031 "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" 1032 ;; An opening curly brace as delimiter 1033 ;; is valid, but allowing it might screw 1034 ;; up fontification of stuff like 1035 ;; "\url{...} foo \textbf{<--!...}". 1036 "\\([^a-z@*\n\f{]\\).*?" 1037 ;; Give an escape char at the end of the 1038 ;; verbatim construct punctuation syntax. 1039 ;; Prevents wrong fontification of stuff 1040 ;; like "\verb|foo\|". 1041 "\\(" (regexp-quote TeX-esc) "*\\)\\(\\1\\)") 1042 (1 "\"") (2 ".") (3 "\"")))) 1043 (unless (= (length verb-macros-with-braces) 0) 1044 (add-to-list 'font-latex-syntactic-keywords 1045 `(,(concat "\\\\\\(?:" verb-macros-with-braces "\\)" 1046 ;; Some macros take an optional 1047 ;; argument. This is the same line as 1048 ;; above for environments. 1049 "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" 1050 "\\({\\).*?[^\\]\\(?:\\\\\\\\\\)*\\(}\\)") 1051 (1 "|") (2 "|"))))) 1052 (when font-latex-syntactic-keywords-extra 1053 (nconc font-latex-syntactic-keywords font-latex-syntactic-keywords-extra)) 1054 ;; Cater for docTeX mode. 1055 (setq font-latex-doctex-syntactic-keywords 1056 (append font-latex-syntactic-keywords 1057 ;; For docTeX comment-in-doc. 1058 `(("\\(\\^\\)\\^A" (1 (font-latex-doctex-^^A))))))) 1059 1060 1061;;; Syntactic fontification 1062 1063;; Copy and adaptation of `tex-font-lock-syntactic-face-function' in 1064;; `tex-mode.el' of CVS Emacs (March 2004) 1065(defun font-latex-syntactic-face-function (state) 1066 (let ((char (nth 3 state))) 1067 (cond 1068 ((not char) 'font-lock-comment-face) 1069 ((eq char ?$) 'font-latex-math-face) 1070 (t 1071 (when (characterp char) 1072 ;; This is a \verb?...? construct. Let's find the end and mark it. 1073 (save-excursion 1074 (skip-chars-forward (string ?^ char)) ;; Use `end' ? 1075 (when (eq (char-syntax (preceding-char)) ?/) 1076 (put-text-property (1- (point)) (point) 'syntax-table '(1))) 1077 (unless (eobp) 1078 (put-text-property (point) (1+ (point)) 'syntax-table '(7))))) 1079 'font-latex-verbatim-face)))) 1080 1081 1082;;; Faces 1083 1084(defface font-latex-bold-face 1085 (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit bold)) 1086 ((assq :weight custom-face-attributes) '(:weight bold)) 1087 (t '(:bold t))))) 1088 `((((class grayscale) (background light)) 1089 (:foreground "DimGray" ,@font)) 1090 (((class grayscale) (background dark)) 1091 (:foreground "LightGray" ,@font)) 1092 (((class color) (background light)) 1093 (:foreground "DarkOliveGreen" ,@font)) 1094 (((class color) (background dark)) 1095 (:foreground "OliveDrab" ,@font)) 1096 (t (,@font)))) 1097 "Face used to highlight text to be typeset in bold." 1098 :group 'font-latex-highlighting-faces) 1099 1100(defface font-latex-italic-face 1101 (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit italic)) 1102 ((assq :slant custom-face-attributes) '(:slant italic)) 1103 (t '(:italic t))))) 1104 `((((class grayscale) (background light)) 1105 (:foreground "DimGray" ,@font)) 1106 (((class grayscale) (background dark)) 1107 (:foreground "LightGray" ,@font)) 1108 (((class color) (background light)) 1109 (:foreground "DarkOliveGreen" ,@font)) 1110 (((class color) (background dark)) 1111 (:foreground "OliveDrab" ,@font)) 1112 (t (,@font)))) 1113 "Face used to highlight text to be typeset in italic." 1114 :group 'font-latex-highlighting-faces) 1115 1116(defface font-latex-math-face 1117 (let ((font (cond ((assq :inherit custom-face-attributes) 1118 '(:inherit underline)) 1119 (t '(:underline t))))) 1120 `((((class grayscale) (background light)) 1121 (:foreground "DimGray" ,@font)) 1122 (((class grayscale) (background dark)) 1123 (:foreground "LightGray" ,@font)) 1124 (((class color) (background light)) 1125 (:foreground "SaddleBrown")) 1126 (((class color) (background dark)) 1127 (:foreground "burlywood")) 1128 (t (,@font)))) 1129 "Face used to highlight math." 1130 :group 'font-latex-highlighting-faces) 1131 1132(defface font-latex-sedate-face 1133 '((((class grayscale) (background light)) (:foreground "DimGray")) 1134 (((class grayscale) (background dark)) (:foreground "LightGray")) 1135 (((class color) (background light)) (:foreground "DimGray")) 1136 (((class color) (background dark)) (:foreground "LightGray")) 1137 ;;;(t (:underline t)) 1138 ) 1139 "Face used to highlight sedate stuff." 1140 :group 'font-latex-highlighting-faces) 1141 1142(defface font-latex-string-face 1143 (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit italic)) 1144 ((assq :slant custom-face-attributes) '(:slant italic)) 1145 (t '(:italic t))))) 1146 `((((type tty) (class color)) 1147 (:foreground "green")) 1148 (((class grayscale) (background light)) 1149 (:foreground "DimGray" ,@font)) 1150 (((class grayscale) (background dark)) 1151 (:foreground "LightGray" ,@font)) 1152 (((class color) (background light)) 1153 (:foreground "RosyBrown")) 1154 (((class color) (background dark)) 1155 (:foreground "LightSalmon")) 1156 (t (,@font)))) 1157 "Face used to highlight strings." 1158 :group 'font-latex-highlighting-faces) 1159 1160(defface font-latex-warning-face 1161 (let ((font (cond ((assq :inherit custom-face-attributes) '(:inherit bold)) 1162 ((assq :weight custom-face-attributes) '(:weight bold)) 1163 (t '(:bold t))))) 1164 `((((class grayscale)(background light)) 1165 (:foreground "DimGray" ,@font)) 1166 (((class grayscale)(background dark)) 1167 (:foreground "LightGray" ,@font)) 1168 (((class color)(background light)) 1169 (:foreground "red" ,@font)) 1170 (((class color)(background dark)) 1171 (:foreground "red" ,@font)) 1172 (t (,@font)))) 1173 "Face for important keywords." 1174 :group 'font-latex-highlighting-faces) 1175 1176(defface font-latex-verbatim-face 1177 (let ((font (if (and (assq :inherit custom-face-attributes) 1178 (facep 'fixed-pitch)) 1179 '(:inherit fixed-pitch) 1180 '(:family "courier")))) 1181 `((((class grayscale) (background light)) 1182 (:foreground "DimGray" ,@font)) 1183 (((class grayscale) (background dark)) 1184 (:foreground "LightGray" ,@font)) 1185 (((class color) (background light)) 1186 (:foreground "SaddleBrown" ,@font)) 1187 (((class color) (background dark)) 1188 (:foreground "burlywood" ,@font)) 1189 (t (,@font)))) 1190 "Face used to highlight TeX verbatim environments." 1191 :group 'font-latex-highlighting-faces) 1192 1193(defface font-latex-superscript-face 1194 '((t (:height 0.85))) 1195 "Face used for superscripts." 1196 :group 'font-latex-highlighting-faces) 1197 1198(defface font-latex-subscript-face 1199 '((t (:height 0.85))) 1200 "Face used for subscripts." 1201 :group 'font-latex-highlighting-faces) 1202 1203(defface font-latex-script-char-face 1204 (let ((font (cond ((assq :inherit custom-face-attributes) 1205 '(:inherit underline)) 1206 (t '(:underline t))))) 1207 `((((class grayscale) (background light)) 1208 (:foreground "DarkGray" ,@font)) 1209 (((class grayscale) (background dark)) 1210 (:foreground "gray" ,@font)) 1211 (((class color) (background light)) 1212 (:foreground "salmon")) 1213 (((class color) (background dark)) 1214 (:foreground "DarkRed")) 1215 (t (,@font)))) 1216 "Face used for the script chars ^ and _." 1217 :group 'font-latex-highlighting-faces) 1218 1219(defface font-latex-slide-title-face 1220 (let* ((scale 1.2)) 1221 `((t (:inherit (variable-pitch font-lock-type-face) 1222 :weight bold :height ,scale)))) 1223 "Face for slide titles." 1224 :group 'font-latex-highlighting-faces) 1225 1226;;; Setup 1227 1228(defvar font-lock-comment-start-regexp nil 1229 "Regexp to match the start of a comment.") 1230 1231(defvar font-latex-extend-region-functions nil 1232 "List of functions extending the region for multiline constructs. 1233 1234Each function should accept two arguments, the begin and end of 1235the region to be fontified, and return the new region start. If 1236no extension is necessary, the original region start should be 1237returned. 1238 1239All specified functions will be called and the region extended 1240backwards to the minimum over their return values.") 1241 1242(defvar font-latex-syntax-alist 1243 ;; Use word syntax for @ because we use \> for matching macros and 1244 ;; we don't want \foo@bar to be found if we search for \foo. 1245 '((?\( . ".") (?\) . ".") (?$ . "\"") (?@ . "w")) 1246 "List of specifiers for the syntax alist of `font-lock-defaults'.") 1247 1248(defun font-latex-add-to-syntax-alist (list) 1249 "Activate syntactic font locking for the entries in LIST. 1250The entries are added to `font-latex-syntax-alist' and eventually 1251end up in `font-lock-defaults'. Each entry in LIST should be a 1252cons pair as expected by `font-lock-defaults'. The function also 1253triggers Font Lock to recognize the change." 1254 (set (make-local-variable 'font-latex-syntax-alist) 1255 (append font-latex-syntax-alist list)) 1256 ;; Tell font-lock about the update. 1257 (setq font-lock-set-defaults nil) 1258 (font-latex-setup)) 1259 1260;;;###autoload 1261(defun font-latex-setup () 1262 "Setup this buffer for LaTeX font-lock. Usually called from a hook." 1263 (font-latex-set-syntactic-keywords) 1264 ;; Trickery to make $$ fontification be in `font-latex-math-face' while 1265 ;; strings get whatever `font-lock-string-face' has been set to. 1266 (when (fboundp 'built-in-face-specifiers) 1267 ;; Cool patch from Christoph Wedler... 1268 (let (instance) 1269 (mapc (lambda (property) 1270 (setq instance 1271 (face-property-instance 'font-latex-math-face property 1272 nil 0 t)) 1273 (if (numberp instance) 1274 (setq instance 1275 (face-property-instance 'default property nil 0))) 1276 (or (numberp instance) 1277 (set-face-property 'font-lock-string-face property 1278 instance (current-buffer)))) 1279 (built-in-face-specifiers)))) 1280 1281 ;; Activate multi-line fontification facilities if available. 1282 (when (boundp 'font-lock-multiline) 1283 (set (make-local-variable 'font-lock-multiline) t)) 1284 1285 ;; Functions for extending the region. 1286 (dolist (elt '(font-latex-extend-region-backwards-command-with-args 1287 font-latex-extend-region-backwards-command-in-braces 1288 font-latex-extend-region-backwards-quotation 1289 font-latex-extend-region-backwards-math-env 1290 font-latex-extend-region-backwards-math-envII)) 1291 (add-to-list 'font-latex-extend-region-functions elt)) 1292 1293 ;; Tell Font Lock about the support. 1294 (make-local-variable 'font-lock-defaults) 1295 ;; The test for `major-mode' currently only works with docTeX mode 1296 ;; because `TeX-install-font-lock' is called explicitely in 1297 ;; `doctex-mode'. In case other modes have to be distinguished as 1298 ;; well, remove the call to `TeX-install-font-lock' from 1299 ;; `VirTeX-common-initialization' and place it in the different 1300 ;; `xxx-mode' calls instead, but _after_ `major-mode' is set. 1301 (let ((defaults 1302 `((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2) 1303 nil nil ,font-latex-syntax-alist nil)) 1304 (variables 1305 '((font-lock-comment-start-regexp . "%") 1306 (font-lock-mark-block-function . mark-paragraph) 1307 (font-lock-fontify-region-function 1308 . font-latex-fontify-region) 1309 (font-lock-unfontify-region-function 1310 . font-latex-unfontify-region)))) 1311 ;; Add the mode-dependent stuff to the basic variables defined above. 1312 (if (eq major-mode 'doctex-mode) 1313 (progn 1314 (setcar defaults (append (car defaults) 1315 '(font-latex-doctex-keywords))) 1316 (setq variables 1317 (append variables 1318 '((font-lock-syntactic-face-function 1319 . font-latex-doctex-syntactic-face-function) 1320 (font-lock-syntactic-keywords 1321 . font-latex-doctex-syntactic-keywords))))) 1322 (setq variables 1323 (append variables 1324 '((font-lock-syntactic-face-function 1325 . font-latex-syntactic-face-function) 1326 (font-lock-syntactic-keywords 1327 . font-latex-syntactic-keywords))))) 1328 ;; Set the defaults. 1329 (setq font-lock-defaults (append defaults variables))) 1330 1331 ;; Make sure fontification will be refreshed if a user sets variables 1332 ;; influencing fontification in her file-local variables section. 1333 (add-hook 'hack-local-variables-hook #'font-latex-after-hacking-local-variables t t)) 1334 1335(defun font-latex-update-font-lock (&optional syntactic-kws) 1336 "Tell font-lock about updates of fontification rules. 1337If SYNTACTIC-KWS is non-nil, also update 1338`font-latex-syntactic-keywords'." 1339 ;; Update syntactic keywords. 1340 (when syntactic-kws 1341 (font-latex-set-syntactic-keywords)) 1342 1343 ;; Let font-lock recompute its fontification rules. 1344 (setq font-lock-set-defaults nil) 1345 (font-lock-set-defaults) 1346 1347 ;; Re-initialize prettification if needed. 1348 (when (and (boundp 'prettify-symbols-mode) 1349 (boundp 'prettify-symbols--keywords) 1350 prettify-symbols-mode 1351 prettify-symbols--keywords) 1352 (font-lock-add-keywords nil prettify-symbols--keywords))) 1353 1354(defun font-latex-jit-lock-force-redisplay (buf start end) 1355 "Compatibility for Emacsen not offering `jit-lock-force-redisplay'." 1356 ;; The following block is an expansion of `jit-lock-force-redisplay' 1357 ;; and involved macros taken from CVS Emacs on 2007-04-28. 1358 (with-current-buffer buf 1359 (let ((modified (buffer-modified-p))) 1360 (unwind-protect 1361 (let ((buffer-undo-list t) 1362 (inhibit-read-only t) 1363 (inhibit-point-motion-hooks t) 1364 (inhibit-modification-hooks t) 1365 deactivate-mark 1366 buffer-file-name 1367 buffer-file-truename) 1368 (put-text-property start end 'fontified t)) 1369 (unless modified 1370 (restore-buffer-modified-p nil)))))) 1371 1372(defun font-latex-fontify-region (beg end &optional loudly) 1373 "Fontify region from BEG to END. 1374If optional argument is non-nil, print status messages." 1375 (let ((extend-list (delq nil (mapcar (lambda (fun) (funcall fun beg end)) 1376 font-latex-extend-region-functions)))) 1377 (when extend-list 1378 (let ((orig-beg beg)) 1379 (setq beg (apply 'min extend-list)) 1380 (when (featurep 'jit-lock) 1381 ;; Stolen from `jit-lock-fontify-now' (2007-04-27) and 1382 ;; adapted. Without this stanza only the line in which a 1383 ;; change happened will refontified. The rest will only be 1384 ;; refontified upon redisplay. 1385 (run-with-timer 0 nil 'font-latex-jit-lock-force-redisplay 1386 (current-buffer) beg orig-beg)))) 1387 (font-lock-default-fontify-region beg end loudly))) 1388 1389;; Copy and adaption of `tex-font-lock-unfontify-region' from 1390;; tex-mode.el in GNU Emacs on 2004-08-04. 1391;; (XEmacs passes a third argument to the function.) 1392(defun font-latex-unfontify-region (beg end &rest ignored) 1393 "Unfontify region from BEG to END." 1394 (font-lock-default-unfontify-region beg end) 1395 ;; XEmacs does not provide `font-lock-extra-managed-props', so 1396 ;; remove the `font-latex-multiline' property manually. (The 1397 ;; property is only added if `font-lock-multiline' is bound.) 1398 (unless (boundp 'font-lock-multiline) 1399 (remove-text-properties beg end '(font-latex-multiline))) 1400 (remove-text-properties beg end '(script-level)) 1401 (let ((start beg)) 1402 (while (< beg end) 1403 (let ((next (next-single-property-change beg 'display nil end)) 1404 (prop (get-text-property beg 'display))) 1405 (if (and (eq (car-safe prop) 'raise) 1406 (null (cddr prop))) 1407 (put-text-property beg next 'display nil)) 1408 (setq beg next))) 1409 (remove-text-properties start end '(invisible)))) 1410 1411(defadvice font-lock-after-change-function (before font-latex-after-change 1412 activate) 1413 "Extend region for fontification of multiline constructs. 1414This is only necessary if the editor does not provide multiline 1415fontification facilities like `font-lock-multiline' itself." 1416 (unless (boundp 'font-lock-multiline) 1417 (let ((ad-beg (ad-get-arg 0)) 1418 (ad-end (ad-get-arg 1))) 1419 (save-excursion 1420 (goto-char ad-beg) 1421 (beginning-of-line) 1422 (when (get-text-property (point) 'font-latex-multiline) 1423 (setq ad-beg (previous-single-property-change (point) 1424 'font-latex-multiline)) 1425 (when (numberp ad-beg) 1426 (ad-set-arg 0 ad-beg))) 1427 (goto-char ad-end) 1428 (end-of-line) 1429 (when (get-text-property (point) 'font-latex-multiline) 1430 (setq ad-end (next-single-property-change (point) 1431 'font-latex-multiline)) 1432 (when (numberp ad-end) 1433 (ad-set-arg 1 ad-end))))))) 1434 1435(defun font-latex-after-hacking-local-variables () 1436 "Refresh fontification if required by updates of file-local variables. 1437This function is added to `hack-local-variables-hook' and 1438recomputes fontification if variables affecting fontification are 1439modified. Such variables include 1440`LaTeX-verbatim-environments-local', 1441`LaTeX-verbatim-macros-with-braces-local', 1442`LaTeX-verbatim-macros-with-delims-local'." 1443 (when 1444 ;; In Emacs we know if the value came from file or directory 1445 ;; locals. Note to self: directory-local variables are also added 1446 ;; to file-local-variables-alist. 1447 (let ((hacked-local-vars (mapcar #'car file-local-variables-alist))) 1448 (or (memq 'LaTeX-verbatim-environments-local hacked-local-vars) 1449 (memq 'LaTeX-verbatim-macros-with-braces-local hacked-local-vars) 1450 (memq 'LaTeX-verbatim-macros-with-delims-local hacked-local-vars))) 1451 ;; Ok, we need to refresh fontification. 1452 (font-latex-update-font-lock t))) 1453 1454;;; Utility functions 1455 1456(defun font-latex-find-matching-close (openchar closechar) 1457 "Skip over matching pairs of OPENCHAR and CLOSECHAR. 1458OPENCHAR is the opening character and CLOSECHAR is the closing 1459character. Character pairs are usually { } or [ ]. Comments are 1460ignored during the search." 1461 (let ((parse-sexp-ignore-comments 1462 (not (eq major-mode 'doctex-mode))) ; scan-sexps ignores comments 1463 (init-point (point)) 1464 (mycount 1) 1465 (esc-char (or (and (boundp 'TeX-esc) TeX-esc) "\\")) 1466 ;; XXX: Do not look up syntax-table properties since they may 1467 ;; be misleading, e.g. in the case of "{foo}^^A" where the 1468 ;; closing brace gets a comment end syntax. 1469 (parse-sexp-lookup-properties nil)) 1470 (or 1471 (condition-case nil 1472 (progn 1473 (goto-char (with-syntax-table 1474 (TeX-search-syntax-table openchar closechar) 1475 (scan-sexps (point) 1))) 1476 ;; No error code. See if closechar is unquoted 1477 (save-excursion 1478 (backward-char 1) 1479 (zerop (mod (skip-chars-backward (regexp-quote esc-char)) 2)))) 1480 (error nil)) 1481 (save-match-data 1482 (goto-char (1+ init-point)) 1483 (while (and (> mycount 0) 1484 (re-search-forward 1485 (string ?\[ 1486 ;; closechar might be ] 1487 ;; and therefor must be first in regexp 1488 closechar openchar 1489 ?\]) 1490 nil t)) 1491 (cond 1492 ((font-latex-commented-outp) 1493 (forward-line 1)) 1494 ((save-excursion 1495 (backward-char 1) 1496 (zerop (mod (skip-chars-backward (regexp-quote esc-char)) 1497 2))) 1498 (setq mycount (+ mycount 1499 (if (= (preceding-char) openchar) 1 -1))))))) 1500 (if (= mycount 0) 1501 t 1502 (goto-char init-point) 1503 nil)))) 1504 1505(defun font-latex-commented-outp () 1506 "Return t if comment character is found between bol and point." 1507 (save-excursion 1508 (let ((limit (point)) 1509 (esc-char (if (and (boundp 'TeX-esc) TeX-esc) TeX-esc "\\"))) 1510 (forward-line 0) 1511 (if (and (eq (char-after) ?\%) 1512 (not (font-latex-faces-present-p 'font-latex-verbatim-face))) 1513 (not (eq major-mode 'doctex-mode)) 1514 (catch 'found 1515 (while (progn (skip-chars-forward "^%" limit) 1516 (< (point) limit)) 1517 (when (and (save-excursion 1518 (zerop (mod (skip-chars-backward 1519 (regexp-quote esc-char)) 2))) 1520 (not (font-latex-faces-present-p 1521 'font-latex-verbatim-face))) 1522 (throw 'found t)) 1523 (forward-char))))))) 1524 1525(defun font-latex-faces-present-p (faces &optional pos) 1526 "Return t if FACES are present at position POS. 1527FACES may be a single face or a list of faces. 1528If POS is omitted, the current position of point is used." 1529 (let* ((faces (if (listp faces) faces (list faces))) 1530 (pos (or pos (point))) 1531 (prop (get-text-property pos 'face)) 1532 (prop-list (if (listp prop) prop (list prop)))) 1533 (catch 'member 1534 (dolist (item prop-list) 1535 (when (memq item faces) 1536 (throw 'member t)))))) 1537 1538(defun font-latex-forward-comment () 1539 "Like `forward-comment' but with special provisions for docTeX mode. 1540In docTeX mode \"%\" at the start of a line will be treated as whitespace." 1541 (if (eq major-mode 'doctex-mode) 1542 ;; XXX: We should probably cater for ^^A as well. 1543 (progn 1544 (while (progn (if (bolp) (skip-chars-forward "%")) 1545 (> (skip-chars-forward " \t\n") 0))) 1546 (when (eq (char-after) ?%) 1547 (beginning-of-line 2) 1548 t)) 1549 (forward-comment 1))) 1550 1551(defun font-latex-put-multiline-property-maybe (beg end) 1552 "Add a multiline property if no equivalent is provided by the editor. 1553The text property is used to find the start or end of a multiline 1554construct when unfontifying a region. Emacs adds such a text 1555property automatically if `font-lock-multiline' is set to t and 1556extends the region to be unfontified automatically as well." 1557 (unless (boundp 'font-lock-multiline) 1558 (put-text-property beg end 'font-latex-multiline t))) 1559 1560 1561;;; Match functions 1562 1563(defvar font-latex-matched-faces nil 1564 "List of faces corresponding to matches in match data.") 1565 1566(defun font-latex-matched-face (pos) 1567 "Return face at position POS in `font-latex-matched-faces'." 1568 (nth pos font-latex-matched-faces)) 1569 1570(defvar font-latex-command-with-args-default-spec nil ; "*[{" 1571 "Default specifier for keywords without syntax description. 1572Set this to nil if verification of command syntax is unwanted.") 1573 1574(defvar font-latex-command-with-args-opt-arg-delims 1575 '((?\[ . ?\]) (?< . ?>) (?\( . ?\))) 1576 "List character pairs used as delimiters for optional arguments.") 1577 1578(defvar font-latex-syntax-error-modes '(latex-mode) 1579 "List of modes where syntax errors in macros should be indicated.") 1580 1581(defun font-latex-match-command-with-arguments (regexp keywords face limit) 1582 "Search for regexp command KEYWORDS[opt]{arg} before LIMIT. 1583Returns nil if none of KEYWORDS is found." 1584 (setq font-latex-matched-faces nil) 1585 (catch 'match 1586 (while (re-search-forward regexp limit t) 1587 (unless (font-latex-faces-present-p '(font-lock-comment-face 1588 font-latex-verbatim-face) 1589 (match-beginning 0)) 1590 (let* ((beg (match-beginning 0)) 1591 end ; Used for multiline text property. 1592 (match-data (list beg)) 1593 match-beg syntax-error alternative spec 1594 error-indicator-pos 1595 (spec-list (string-to-list 1596 (or (cadr (assoc (match-string 1) keywords)) 1597 font-latex-command-with-args-default-spec))) 1598 (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments 1599 (goto-char (match-end 0)) 1600 ;; Check for starred macro if first spec is an asterisk or a 1601 ;; plus sign in case of \defaultfontfeatures+ provided by 1602 ;; fontspec.sty 1603 (when (or (eq (car spec-list) ?*) 1604 (eq (car spec-list) ?+)) 1605 (setq spec-list (cdr spec-list)) 1606 (skip-chars-forward "*+" (1+ (point)))) 1607 ;; Add current point to match data and use keyword face for 1608 ;; region from start to point. 1609 (nconc match-data (list (point))) 1610 (add-to-list 'font-latex-matched-faces 'font-lock-keyword-face) 1611 (setq end (point)) 1612 (catch 'break 1613 ;; Walk the list of specs. 1614 (while spec-list 1615 (setq spec (pop spec-list) 1616 error-indicator-pos beg) 1617 (while (and (not (eobp)) (font-latex-forward-comment))) 1618 ;; Alternative 1619 (when (eq spec ?|) 1620 (setq alternative t) 1621 (setq spec (pop spec-list))) 1622 (cond 1623 ;; Macros: \foo 1624 ((eq spec ?\\) 1625 (if (eq (char-after) spec) 1626 (progn 1627 (nconc match-data 1628 (list (point) 1629 (progn 1630 (forward-char) 1631 (if (zerop (skip-syntax-forward "_w")) 1632 (forward-char) ; Single-char macro. 1633 (skip-chars-forward "*+")) 1634 (point)))) 1635 (nconc font-latex-matched-faces (list face)) 1636 (setq end (max end (point))) 1637 (when alternative (pop spec-list))) 1638 (setq syntax-error t) 1639 (throw 'break nil))) 1640 ;; Mandatory arguments: {...} 1641 ((eq spec ?{) 1642 (if (and (eq (char-after) spec) 1643 (setq match-beg (point)) 1644 (font-latex-find-matching-close ?{ ?})) 1645 (progn 1646 (nconc match-data (list (1+ match-beg) (1- (point)))) 1647 (nconc font-latex-matched-faces (list face)) 1648 (setq end (max end (1- (point)))) 1649 (when alternative (pop spec-list))) 1650 (unless alternative 1651 (setq syntax-error t) 1652 (when (and match-beg (= match-beg (point))) 1653 (setq error-indicator-pos match-beg)) 1654 (throw 'break nil)))) 1655 ;; Optional arguments: [...] and others 1656 ((eq (char-after) spec) 1657 (setq match-beg (point)) 1658 (if (font-latex-find-matching-close 1659 spec (cdr (assq 1660 spec 1661 font-latex-command-with-args-opt-arg-delims))) 1662 (progn 1663 (nconc match-data (list (1+ match-beg) (1- (point)))) 1664 (nconc font-latex-matched-faces 1665 (list 'font-lock-variable-name-face)) 1666 (setq end (max end (1- (point))))) 1667 (setq syntax-error t 1668 error-indicator-pos match-beg) 1669 (throw 'break nil)))) 1670 (setq alternative nil))) 1671 (when (and syntax-error (memq major-mode 1672 font-latex-syntax-error-modes)) 1673 ;; Add the warning face at the front of the list because 1674 ;; the matcher uses 'append and the face would otherwise 1675 ;; be overridden by the keyword face. 1676 (setq match-data (append (list error-indicator-pos 1677 (1+ error-indicator-pos)) 1678 match-data)) 1679 (push 'font-latex-warning-face font-latex-matched-faces)) 1680 (font-latex-put-multiline-property-maybe beg end) 1681 (store-match-data match-data) 1682 (throw 'match t)))))) 1683 1684(defun font-latex-extend-region-backwards-command-with-args (beg end) 1685 "Return position to extend region backwards for commands with args. 1686Return nil if region does not have to be extended for a multiline 1687macro to fit in. The region between the positions BEG and END 1688marks boundaries for searching for macro ends." 1689 (save-excursion 1690 (goto-char end) 1691 (catch 'extend 1692 (while (TeX-search-backward-unescaped "}" beg t) 1693 (let ((macro-start (TeX-find-macro-start 1694 (max (point-min) 1695 (- beg font-latex-multiline-boundary))))) 1696 (when (and macro-start 1697 (< macro-start beg)) 1698 (throw 'extend macro-start)))) 1699 nil))) 1700 1701(defun font-latex-match-command-in-braces (keywords limit) 1702 "Search for command like {\\bfseries fubar} before LIMIT. 1703Sets `match-data' so that: 1704 subexpression 0 is a warning indicator, 1705 subexpression 1 is the keyword, and 1706 subexpression 2 is the rest in the TeX group. 1707Returns nil if no command is found." 1708 (catch 'match 1709 (while (re-search-forward keywords limit t) 1710 (unless (font-latex-faces-present-p '(font-lock-comment-face 1711 font-latex-verbatim-face) 1712 (match-beginning 0)) 1713 (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 1714 (beg (match-end 0)) 1715 cbeg cend 1716 (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments 1717 (goto-char kbeg) 1718 (if (not (eq (preceding-char) ?\{)) 1719 ;; Fontify only the keyword (no argument found). 1720 (progn 1721 (setq cbeg kbeg cend kend) 1722 (goto-char (match-end 0)) 1723 (store-match-data (list (point) (point) 1724 (point) (point) 1725 cbeg cend)) 1726 (throw 'match t)) 1727 ;; There's an opening bracket 1728 (save-restriction 1729 ;; Restrict to LIMIT. 1730 (narrow-to-region (point-min) limit) 1731 (forward-char -1) ; Move on the opening bracket 1732 (if (font-latex-find-matching-close ?\{ ?\}) 1733 (progn 1734 (font-latex-put-multiline-property-maybe beg (1- (point))) 1735 (store-match-data (list kbeg kbeg 1736 kbeg kend 1737 beg (1- (point))))) 1738 (goto-char kend) 1739 (store-match-data (list (1- kbeg) kbeg 1740 kbeg kend 1741 kend kend))) 1742 (throw 'match t)))))))) 1743 1744(defun font-latex-extend-region-backwards-command-in-braces (beg end) 1745 "Return position to extend region backwards for commands in braces. 1746Return nil if region does not have to be extended for a multiline 1747group to fit in. The region between the positions BEG and END 1748marks boundaries for searching for group ends." 1749 (save-excursion 1750 (goto-char end) 1751 (catch 'extend 1752 (while (TeX-search-backward-unescaped "}" beg t) 1753 (let ((group-start (TeX-find-opening-brace 1754 nil (max (point-min) 1755 (- beg font-latex-multiline-boundary))))) 1756 (when group-start 1757 ;; XXX: Actually we'd have to check if any of the 1758 ;; declaration-type macros can be found right after the 1759 ;; brace. If we don't do this (like now) large regions 1760 ;; may be refontified for no good reason. For checking 1761 ;; the built-in `font-latex-match-*' variables for 1762 ;; declaration-type macros as well as the respective 1763 ;; user-defined variables could be concatenated. 1764 (goto-char group-start) 1765 (when (< group-start beg) 1766 (throw 'extend group-start))))) 1767 nil))) 1768 1769(defvar font-latex-match-simple-exclude-list 1770 '("-" "," "/" "&" "#" "_" "`" "'" "^" "~" "=" "." "\"") 1771 "List of characters directly after \"\\\" excluded from fontification. 1772Each character is a string.") 1773 1774(defvar font-latex-match-simple-include-list '("@") 1775 "List of characters allowed in a macro for fontification. 1776Each character is a string. This variable is initialized to 1777\"@\" since internal LaTeX commands are very often redefined in a 1778.tex file and the fontification should work correctly in those 1779cases.") 1780(make-variable-buffer-local 'font-latex-match-simple-include-list) 1781 1782(defun font-latex-match-simple-command (limit) 1783 "Search for command like \\foo before LIMIT." 1784 ;; \s_ matches chars with symbol syntax, \sw chars with word syntax, 1785 ;; \s. chars with punctuation syntax. We must exclude matches where 1786 ;; the first character after the \ is a reserved character and 1787 ;; should not be fontified (e.g. \, in foo\,bar or \- in foo\-bar). 1788 ;; These characters are stored in 1789 ;; `font-latex-match-simple-exclude-list'. In docTeX mode, we 1790 ;; remove "_" from this list to get correct fontification for macros 1791 ;; like `\__module_foo:nnn' 1792 (let* ((search (lambda () 1793 (TeX-re-search-forward-unescaped 1794 (concat 1795 ;; Chars directly after backslash 1796 "\\\\\\(\\s_\\|\\sw\\|\\s.\\)" 1797 ;; Start group of the following chars 1798 "\\(?:[" 1799 ;; a-zA-Z are always allowed: 1800 "a-zA-Z" 1801 ;; Additional characters added by AUCTeX styles 1802 (mapconcat #'identity 1803 font-latex-match-simple-include-list 1804 "") 1805 ;; End group 1806 "]\\)*") 1807 limit t))) 1808 (pos (funcall search))) 1809 (while (and pos 1810 (member (match-string 1) 1811 (if (eq major-mode 'doctex-mode) 1812 (remove "_" font-latex-match-simple-exclude-list) 1813 font-latex-match-simple-exclude-list))) 1814 (setq pos (funcall search))) 1815 pos)) 1816 1817(defun font-latex-match-math-env (limit) 1818 "Match math pattern up to LIMIT. 1819Used for patterns like: 1820\\( F = ma \\) 1821\\=\\[ F = ma \\] but not \\\\=\\[len]" 1822 (catch 'match 1823 (while (re-search-forward "\\(\\\\(\\)\\|\\(\\\\\\[\\)" limit t) 1824 (unless (save-excursion 1825 (goto-char (match-beginning 0)) 1826 ;; \\[ does not start a math environment 1827 (/= (mod (skip-chars-backward "\\\\") 2) 0)) 1828 (let ((beg (match-beginning 0)) 1829 (open-tag (if (match-beginning 1) "\\(" "\\[")) 1830 (close-tag (if (match-beginning 1) "\\)" "\\]"))) 1831 ;; Search for both opening and closing tags in order to be 1832 ;; able to avoid erroneously matching stuff like "\(foo \(bar\)". 1833 (if (and (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*\\(" 1834 (regexp-quote open-tag) "\\|" 1835 (regexp-quote close-tag) "\\)") 1836 limit 'move) 1837 (string= (match-string 1) close-tag)) 1838 ;; Found closing tag. 1839 (progn 1840 (font-latex-put-multiline-property-maybe beg (point)) 1841 (store-match-data (list beg beg beg (point)))) 1842 ;; Did not find closing tag. 1843 (goto-char (+ beg 2)) 1844 (store-match-data (list beg (point) (point) (point)))) 1845 (throw 'match t)))))) 1846 1847(defun font-latex-extend-region-backwards-math-env (beg end) 1848 "Return position to extend region backwards for math environments. 1849Return nil if region does not have to be extended for a multiline 1850environment to fit in. The region between the positions BEG and 1851END marks boundaries for searching for environment ends." 1852 (save-excursion 1853 (goto-char end) 1854 (catch 'extend 1855 (while (re-search-backward "\\(\\\\)\\)\\|\\(\\\\]\\)" beg t) 1856 (when (and (zerop (mod (skip-chars-backward "\\\\") 2)) 1857 (re-search-backward 1858 (concat "[^\\]\\(?:\\\\\\\\\\)*\\(" 1859 (regexp-quote (if (match-beginning 1) "\\(" "\\[")) 1860 "\\)") 1861 (- beg font-latex-multiline-boundary) t) 1862 (goto-char (match-beginning 1)) 1863 (< (point) beg)) 1864 (throw 'extend (point)))) 1865 nil))) 1866 1867(defcustom font-latex-math-environments 1868 '("display" "displaymath" "equation" "eqnarray" "gather" "math" "multline" 1869 "align" "alignat" "xalignat" "xxalignat" "flalign") 1870 "List of math environment names for font locking." 1871 :type '(repeat string) 1872 :group 'font-latex) 1873 1874(defun font-latex-match-math-envII (limit) 1875 "Match math patterns up to LIMIT. 1876Used for patterns like: 1877\\begin{equation} 1878 fontified stuff 1879\\end{equation} or 1880\\begin{empheq}[X=Y\\Rightarrow]{alignat=3} 1881 fontified stuff 1882\\end{empheq} 1883The \\begin{equation} incl. arguments in the same line and 1884\\end{equation} are not fontified here." 1885 (when (re-search-forward (concat "\\\\begin[ \t]*{" 1886 (regexp-opt font-latex-math-environments t) 1887 ;; Subexpression 2 is used to build 1888 ;; the \end{<env>} construct below 1889 "\\(\\*?}\\)" 1890 ;; Match an optional and possible 1891 ;; mandatory argument(s) as long as 1892 ;; they are on the same line with 1893 ;; no spaces in-between 1894 "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" 1895 "\\(?:{[^}]*}\\)*") 1896 limit t) 1897 (let ((beg (match-end 0)) end) 1898 (if (re-search-forward (concat "\\\\end[ \t]*{" 1899 (regexp-quote 1900 (buffer-substring-no-properties 1901 (match-beginning 1) 1902 (match-end 2)))) 1903 ;; XXX: Should this rather be done by 1904 ;; extending the region to be fontified? 1905 (+ limit font-latex-multiline-boundary) 'move) 1906 (setq end (match-beginning 0)) 1907 (goto-char beg) 1908 (setq end beg)) 1909 (font-latex-put-multiline-property-maybe beg end) 1910 (store-match-data (list beg end)) 1911 t))) 1912 1913(defun font-latex-extend-region-backwards-math-envII (beg end) 1914 "Return position to extend region backwards for math environments. 1915Return nil if region does not have to be extended for a multiline 1916environment to fit in. The region between the positions BEG and 1917END marks boundaries for searching for environment ends." 1918 (save-excursion 1919 (goto-char end) 1920 (catch 'extend 1921 (while (re-search-backward 1922 (concat "\\\\end[ \t]*{" 1923 (regexp-opt font-latex-math-environments t) 1924 "\\*?}") beg t) 1925 (when (and (re-search-backward 1926 (concat "\\\\begin[ \t]*{" 1927 (buffer-substring-no-properties 1928 (match-beginning 1) 1929 (match-end 0)) 1930 ;; Match an optional and possible 1931 ;; mandatory argument(s) 1932 "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" 1933 "\\(?:{[^}]*}\\)*") 1934 (- beg font-latex-multiline-boundary) t) 1935 (< (point) beg)) 1936 (throw 'extend (point)))) 1937 nil))) 1938 1939(defun font-latex-update-quote-list () 1940 "Update quote list and regexp if value of `font-latex-quotes' changed." 1941 (unless (eq font-latex-quotes-control font-latex-quotes) 1942 (setq font-latex-quotes-control font-latex-quotes) 1943 (font-latex-quotes-set-internal) 1944 ;; Set order of each entry in `font-latex-quote-list' according to 1945 ;; setting of `font-latex-quotes-internal'. 1946 (let ((tail font-latex-quote-list) 1947 elt) 1948 (while tail 1949 (setq elt (car tail)) 1950 (when (and (> (safe-length elt) 2) 1951 (not (eq (nth 2 elt) font-latex-quotes-internal))) 1952 (setcar tail (list (nth 1 elt) (nth 0 elt) 1953 font-latex-quotes-internal))) 1954 (setq tail (cdr tail)))) 1955 (setq font-latex-quote-regexp-beg 1956 (regexp-opt (mapcar 'car font-latex-quote-list) t)))) 1957 1958(defun font-latex-match-quotation (limit) 1959 "Match quote patterns up to LIMIT. 1960Used for patterns like: 1961``this is a normal quote'' and these are multilingual quoted strings: 1962\"< french \"> and \"`german\"' quotes. 1963The quotes << french >> and 8-bit french are used if `font-latex-quotes' is 1964set to french, and >>german<< (and 8-bit) are used if set to german." 1965 (when font-latex-quotes 1966 (font-latex-update-quote-list) 1967 ;; Search for matches. 1968 (catch 'match 1969 (while (TeX-re-search-forward-unescaped 1970 font-latex-quote-regexp-beg limit t) 1971 (unless (font-latex-faces-present-p '(font-lock-comment-face 1972 font-latex-verbatim-face 1973 font-latex-math-face) 1974 (match-beginning 0)) 1975 (let* ((beg (match-beginning 0)) 1976 (after-beg (match-end 0)) 1977 (opening-quote (match-string 0)) 1978 (closing-quote 1979 (nth 1 (assoc (if (fboundp 'string-make-multibyte) 1980 (string-make-multibyte (match-string 0)) 1981 (match-string 0)) 1982 font-latex-quote-list))) 1983 (nest-count 0) 1984 (point-of-surrender (+ beg font-latex-multiline-boundary))) 1985 ;; Find closing quote taking nested quotes into account. 1986 (while (progn 1987 (re-search-forward 1988 (concat opening-quote "\\|" closing-quote) 1989 point-of-surrender 'move) 1990 (when (and (< (point) point-of-surrender) (not (eobp))) 1991 (if (string= (match-string 0) opening-quote) 1992 (setq nest-count (1+ nest-count)) 1993 (when (/= nest-count 0) 1994 (setq nest-count (1- nest-count))))))) 1995 ;; If no closing quote was found, set the second match which 1996 ;; will be marked with warning color, if one was found, set 1997 ;; the first match which will be marked with string color. 1998 (if (or (= (point) point-of-surrender) (eobp)) 1999 (progn 2000 (goto-char after-beg) 2001 (store-match-data (list after-beg after-beg beg after-beg))) 2002 (font-latex-put-multiline-property-maybe beg (point)) 2003 (store-match-data (list beg (point) (point) (point)))) 2004 (throw 'match t))))))) 2005 2006(defun font-latex-extend-region-backwards-quotation (beg end) 2007 "Return position to extend region backwards for quotations. 2008Return nil if region does not have to be extended for a multiline 2009quotation to fit in. The region between the positions BEG and 2010END marks boundaries for searching for quotation ends." 2011 (if font-latex-quotes 2012 (progn 2013 (font-latex-update-quote-list) 2014 (let ((regexp-end (regexp-opt (mapcar 'cadr font-latex-quote-list) t))) 2015 (save-excursion 2016 (goto-char end) 2017 (catch 'extend 2018 (while (re-search-backward regexp-end beg t) 2019 (let ((closing-quote (match-string 0)) 2020 (nest-count 0) 2021 (point-of-surrender (- beg font-latex-multiline-boundary)) 2022 opening-quote) 2023 (catch 'found 2024 (dolist (elt font-latex-quote-list) 2025 (when (string= (cadr elt) closing-quote) 2026 (setq opening-quote (car elt)) 2027 (throw 'found nil)))) 2028 ;; Find opening quote taking nested quotes into account. 2029 (while (progn 2030 (re-search-backward (concat opening-quote "\\|" 2031 closing-quote) 2032 point-of-surrender 'move) 2033 (when (and (> (point) point-of-surrender) 2034 (not (bobp))) 2035 (if (string= (match-string 0) closing-quote) 2036 (setq nest-count (1+ nest-count)) 2037 (when (/= nest-count 0) 2038 (setq nest-count (1- nest-count))))))) 2039 (when (< (point) beg) 2040 (throw 'extend (point))))) 2041 nil)))) 2042 nil)) 2043 2044(defun font-latex-match-script (limit) 2045 "Match subscript and superscript patterns up to LIMIT." 2046 (when (and font-latex-fontify-script 2047 (re-search-forward "[_^] *\\([^\n\\{}]\\|\ 2048\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t)) 2049 (if (and (not (memq font-latex-fontify-script '(multi-level invisible))) 2050 (font-latex-faces-present-p '(font-latex-subscript-face 2051 font-latex-superscript-face))) 2052 ;; Apply subscript and superscript highlighting only once (in case 2053 ;; font-latex-fontify-script is not 'multi-level) in order to prevent 2054 ;; the font size becoming too small. We set an empty match to do that. 2055 (let ((point (point))) 2056 (store-match-data (list point point point point))) 2057 (when (match-end 3) 2058 (let ((beg (match-beginning 3)) 2059 (end (TeX-find-closing-brace 2060 ;; Don't match groups spanning more than one line 2061 ;; in order to avoid visually wrong indentation in 2062 ;; subsequent lines. 2063 nil (line-end-position)))) 2064 (store-match-data (if end 2065 (list (match-beginning 0) end beg end) 2066 (list beg beg beg beg)))))) 2067 t)) 2068 2069(defun font-latex-match-script-chars (limit) 2070 "Match subscript and superscript chars up to LIMIT." 2071 (and (re-search-forward "[^_^]\\([_^]\\)" limit t) 2072 (let ((pos (match-beginning 1))) 2073 (and (font-latex-faces-present-p 'font-latex-math-face pos) 2074 (not (font-latex-faces-present-p '(font-lock-constant-face 2075 font-lock-builtin-face 2076 font-lock-comment-face 2077 font-latex-verbatim-face) pos)) 2078 ;; Check for backslash quoting 2079 (not (let ((odd nil) 2080 (pos pos)) 2081 (while (eq (char-before pos) ?\\) 2082 (setq pos (1- pos) odd (not odd))) 2083 odd)))))) 2084 2085(defun font-latex--get-script-props (pos script-type) 2086 (let* ((old-raise (or (plist-get (get-text-property pos 'display) 'raise) 0.0)) 2087 (new-level (1+ (or (get-text-property pos 'script-level) 0))) 2088 (disp-props (copy-sequence (cl-case script-type 2089 (:super (cdr font-latex-script-display)) 2090 (:sub (car font-latex-script-display))))) 2091 (new-disp-props (let ((raise (plist-get disp-props 'raise)) 2092 (nl new-level)) 2093 (if raise 2094 ;; This polynom approximates that the factor 2095 ;; which is multiplied with raise is 1 for nl=1, 2096 ;; 0.8 for nl=2, 0.64 for nl=3, etc. (so always 2097 ;; about 80% of the previous value). 2098 (plist-put disp-props 'raise 2099 (+ old-raise 2100 (* raise 2101 (+ 1.1965254857142873 2102 (* nl -0.21841226666666758) 2103 (* nl nl 0.012018514285714385))))) 2104 disp-props)))) 2105 `(face ,(if (<= new-level font-latex-fontify-script-max-level) 2106 (cl-case script-type 2107 (:super 'font-latex-superscript-face) 2108 (:sub 'font-latex-subscript-face)) 2109 nil) 2110 script-level ,new-level 2111 display ,new-disp-props))) 2112 2113;; Copy and adaption of `tex-font-lock-suscript' from tex-mode.el in 2114;; GNU Emacs on 2004-07-07. 2115(defun font-latex-script (pos) 2116 "Return face and display spec for subscript and superscript content." 2117 (when (and (font-latex-faces-present-p 'font-latex-math-face pos) 2118 (not (font-latex-faces-present-p '(font-lock-constant-face 2119 font-lock-builtin-face 2120 font-lock-comment-face 2121 font-latex-verbatim-face) pos)) 2122 ;; Check for backslash quoting 2123 (not (let ((odd nil) 2124 (pos pos)) 2125 (while (eq (char-before pos) ?\\) 2126 (setq pos (1- pos) odd (not odd))) 2127 odd))) 2128 ;; Adding other text properties than `face' is supported by 2129 ;; `font-lock-apply-highlight' in CVS Emacsen since 2001-10-28. 2130 ;; With the introduction of this feature the variable 2131 ;; `font-lock-extra-managed-props' was introduced and serves here 2132 ;; for feature checking. 2133 (let ((extra-props-flag (boundp 'font-lock-extra-managed-props))) 2134 (if (eq (char-after pos) ?_) 2135 (if extra-props-flag 2136 (font-latex--get-script-props pos :sub) 2137 'font-latex-subscript-face) 2138 (if extra-props-flag 2139 (font-latex--get-script-props pos :super) 2140 'font-latex-superscript-face))))) 2141 2142(defun font-latex-script-char (pos) 2143 "Return face and display spec for subscript and superscript character at POS." 2144 (if (boundp 'font-lock-extra-managed-props) 2145 `(face font-latex-script-char-face 2146 ,@(when (eq font-latex-fontify-script 'invisible) 2147 '(invisible t))) 2148 'font-latex-script-char-face)) 2149 2150;;; docTeX 2151 2152(defvar font-latex-doctex-preprocessor-face 2153 'font-latex-doctex-preprocessor-face 2154 "Face used to highlight preprocessor directives in docTeX mode.") 2155 2156(defface font-latex-doctex-preprocessor-face 2157 '((t (:inherit (font-latex-doctex-documentation-face 2158 font-lock-builtin-face ; Emacs 21 does not provide 2159 ; the preprocessor face. 2160 font-lock-preprocessor-face)))) 2161 "Face used to highlight preprocessor directives in docTeX mode." 2162 :group 'font-latex-highlighting-faces) 2163 2164(defvar font-latex-doctex-documentation-face 2165 'font-latex-doctex-documentation-face 2166 "Face used to highlight the documentation in docTeX mode.") 2167 2168(defface font-latex-doctex-documentation-face 2169 '((((class mono)) (:inverse-video t)) 2170 (((class grayscale) (background dark)) (:background "#333")) 2171 (((class color) (background dark)) (:background "#333")) 2172 (t (:background "#eeeeee"))) 2173 "Face used to highlight the documentation parts in docTeX mode." 2174 :group 'font-latex-highlighting-faces) 2175 2176(defvar font-latex-doctex-keywords 2177 (append font-latex-keywords-2 2178 '(("^%<[^>]*>" (0 font-latex-doctex-preprocessor-face t))))) 2179 2180;; Copy and adaptation of `doctex-font-lock-^^A' in `tex-mode.el' of 2181;; CVS Emacs (March 2004) 2182(defun font-latex-doctex-^^A () 2183 (if (eq (char-after (line-beginning-position)) ?\%) 2184 (progn 2185 (put-text-property 2186 (1- (match-beginning 1)) (match-beginning 1) 'syntax-table 2187 (if (= (1+ (line-beginning-position)) (match-beginning 1)) 2188 ;; The `%' is a single-char comment, which Emacs 2189 ;; syntax-table can't deal with. We could turn it 2190 ;; into a non-comment, or use `\n%' or `%^' as the comment. 2191 ;; Instead, we include it in the ^^A comment. 2192 (eval-when-compile (string-to-syntax "< b")) 2193 (eval-when-compile (string-to-syntax ">")))) 2194 (let ((end (line-end-position))) 2195 (if (< end (point-max)) 2196 (put-text-property end (1+ end) 'syntax-table 2197 (eval-when-compile 2198 (string-to-syntax "> b"))))) 2199 (eval-when-compile (string-to-syntax "< b"))))) 2200 2201;; Copy and adaptation of `doctex-font-lock-syntactic-face-function' 2202;; in `tex-mode.el' of CVS Emacs (March 2004) 2203(defun font-latex-doctex-syntactic-face-function (state) 2204 ;; Mark docTeX documentation, which is parsed as a style A comment 2205 ;; starting in column 0. 2206 (if (or (nth 3 state) (nth 7 state) 2207 (not (memq (char-before (nth 8 state)) 2208 '(?\n nil)))) 2209 ;; Anything else is just as for LaTeX. 2210 (font-latex-syntactic-face-function state) 2211 font-latex-doctex-documentation-face)) 2212 2213 2214;;; Installation in non-AUCTeX LaTeX mode 2215 2216;; Here used to be some code which tried to magically make things work and 2217;; thereby broke other stuff. If you want to use font-latex with stock 2218;; latex-mode, then please just add `font-latex-setup' to `latex-mode-hook' 2219;; yourself. 2220 2221;;; Byte-compilation of generated functions 2222 2223(when (byte-code-function-p 2224 (symbol-function 'font-latex-make-built-in-keywords)) 2225 (dolist (elt font-latex-built-in-keyword-classes) 2226 (let ((name (nth 0 elt))) 2227 (byte-compile (intern (concat "font-latex-match-" name))) 2228 (byte-compile (intern (concat "font-latex-match-" name "-make")))))) 2229 2230 2231;; Provide ourselves: 2232(provide 'font-latex) 2233 2234;; Local Variables: 2235;; coding: utf-8 2236;; End: 2237 2238;;; font-latex.el ends here 2239