diff options
Diffstat (limited to 'elpa/auctex-13.1.3/font-latex.el')
-rw-r--r-- | elpa/auctex-13.1.3/font-latex.el | 2314 |
1 files changed, 0 insertions, 2314 deletions
diff --git a/elpa/auctex-13.1.3/font-latex.el b/elpa/auctex-13.1.3/font-latex.el deleted file mode 100644 index c49a698..0000000 --- a/elpa/auctex-13.1.3/font-latex.el +++ /dev/null @@ -1,2314 +0,0 @@ -;;; font-latex.el --- LaTeX fontification for Font Lock mode. -*- lexical-binding: t; -*- - -;; Copyright (C) 1996-2022 Free Software Foundation, Inc. - -;; Authors: Peter S. Galbraith <psg@debian.org> -;; Simon Marshall <Simon.Marshall@esrin.esa.it> -;; Maintainer: auctex-devel@gnu.org -;; Created: 06 July 1996 -;; Keywords: tex, wp, faces - -;;; This file is not part of GNU Emacs. - -;; This package is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This package is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: -;; -;; This package enhances font-lock fontification patterns for LaTeX. -;; font-lock mode is a minor mode that causes your comments to be -;; displayed in one face, strings in another, reserved words in -;; another, and so on. - -;;; Code: - -(require 'font-lock) -(require 'tex) - -(eval-when-compile - (require 'cl-lib)) - -(defgroup font-latex nil - "Font-latex text highlighting package." - :prefix "font-latex-" - :group 'faces - :group 'tex - :group 'AUCTeX) - -(defgroup font-latex-keywords nil - "Keywords for highlighting text in font-latex." - :prefix "font-latex-" - :group 'font-latex) - -(defgroup font-latex-highlighting-faces nil - "Faces for highlighting text in font-latex." - :prefix "font-latex-" - :group 'font-latex) - -(defvar font-latex-multiline-boundary 5000 - "Size of region to search for the start or end of a multiline construct.") - -(defvar font-latex-quote-regexp-beg nil - "Regexp used to find quotes.") -(make-variable-buffer-local 'font-latex-quote-regexp-beg) - -(defvar font-latex-quote-list '(("``" "''") ("<<" ">>" french) ("«" "»" french)) - "List of quote specifiers for quotation fontification. - -Each element of the list is either a list consisting of two -strings to be used as opening and closing quotation marks -independently of the value of `font-latex-quotes' or a list with -three elements where the first and second element are strings for -opening and closing quotation marks and the third element being -either the symbol `german' or `french' describing the order of -quotes. - -If `font-latex-quotes' specifies a different state, order of the -added quotes will be reversed for fontification. For example if -'(\"\\\"<\" \"\\\">\" french) is given but `font-latex-quotes' -specifies `german', quotes will be used like \">foo\"< for -fontification.") - -(defvar font-latex-quotes-control nil - "Internal variable for keeping track if `font-latex-quotes' changed.") -(make-variable-buffer-local 'font-latex-quotes-control) - -(defvar font-latex-quotes-internal nil - "Internal variable for tracking outcome of automatic detection. -If automatic detection is not enabled, it is assigned the value -of `font-latex-quotes'.") -(make-variable-buffer-local 'font-latex-quotes-internal) - -(defvar font-latex-quotes-fallback 'french - "Fallback value for `font-latex-quotes' if automatic detection fails.") - -(defvar font-latex-quote-style-list-french - '("french" "frenchb" "frenchle" "frenchpro" "francais" "canadien" - "acadian" "italian") - "List of styles for which French-style quote matching should be activated.") - -(defvar font-latex-quote-style-list-german - '("austrian" "german" "germanb" "naustrian" "ngerman") - "List of styles for which German-style quote matching should be activated.") - -(defcustom font-latex-quotes 'auto - "Whether to fontify << French quotes >> or >>German quotes<<. -Also selects \"<quote\"> versus \">quote\"<. - -If value `auto' is chosen, an attempt is being made in deriving -the type of quotation mark matching from document settings like -the language option supplied to the babel package. - -If nil, quoted content will not be fontified." - :type '(choice (const auto) (const french) (const german) (const nil)) - :group 'font-latex) -(put 'font-latex-quotes 'safe-local-variable - (lambda (x) (memq x '(auto french german nil)))) - -(defun font-latex-add-quotes (quotes) - "Add QUOTES to `font-latex-quote-list'. -QUOTES has to be a list adhering to the format of an element of -`font-latex-quote-list'." - (setq font-latex-quotes-control nil) - (add-to-list (make-local-variable 'font-latex-quote-list) quotes)) - -(defun font-latex-quotes-set-internal () - "Set `font-latex-quotes-internal' according to `font-latex-quotes'. -If `font-latex-quotes' is set to `auto', try to derive the -correct value from document properties." - (setq font-latex-quotes-internal - (if (eq font-latex-quotes 'auto) - (or (when (TeX-elt-of-list-member - font-latex-quote-style-list-french TeX-active-styles) - 'french) - (when (TeX-elt-of-list-member - font-latex-quote-style-list-german TeX-active-styles) - 'german) - font-latex-quotes-fallback) - font-latex-quotes))) -;; Update the value of `font-latex-quotes-internal' when the list of -;; styles changes. -(add-hook 'TeX-update-style-hook #'font-latex-quotes-set-internal) - -;; The definitions of the title faces were originally taken from -;; info.el (Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 97, 98, 99, -;; 2000, 2001 Free Software Foundation, Inc.) and adapted to the needs -;; of font-latex.el. - -(defconst font-latex-sectioning-max 5 - "Highest number for font-latex-sectioning-N-face") -(defface font-latex-sectioning-5-face - '((((type tty pc) (class color) (background light)) - (:foreground "blue4" :weight bold)) - (((type tty pc) (class color) (background dark)) - (:foreground "yellow" :weight bold)) - (((class color) (background light)) - (:weight bold :inherit variable-pitch :foreground "blue4")) - (((class color) (background dark)) - (:weight bold :inherit variable-pitch :foreground "yellow")) - (t (:weight bold :inherit variable-pitch))) - "Face for sectioning commands at level 5." - :group 'font-latex-highlighting-faces) - -(defcustom font-latex-fontify-sectioning 1.1 - "Whether to fontify sectioning macros with varying height or a color face. - -If it is a number, use varying height faces. The number is used -for scaling starting from `font-latex-sectioning-5-face'. Typically -values from 1.05 to 1.3 give best results, depending on your font -setup. If it is the symbol `color', use `font-lock-type-face'. - -Caveats: Customizing the scaling factor applies to all sectioning -faces unless those face have been saved by customize. Setting -this variable directly does not take effect unless you call -`font-latex-update-sectioning-faces' or restart Emacs. - -Switching from `color' to a number or vice versa does not take -effect unless you call \\[font-lock-fontify-buffer] or restart -Emacs." - :type '(choice (number :tag "Scale factor") - (const color)) - :initialize #'custom-initialize-default - :set (lambda (symbol value) - (set-default symbol value) - (unless (eq value 'color) - (font-latex-update-sectioning-faces font-latex-sectioning-max value))) - :group 'font-latex) - -(defun font-latex-update-sectioning-faces (&optional max height-scale) - "Update sectioning commands faces." - (unless height-scale - (setq height-scale (if (numberp font-latex-fontify-sectioning) - ;; Make sure `height-scale' is a floating point - ;; number because `set-face-attribute' treats - ;; integers differently from floating points. - (float font-latex-fontify-sectioning) - 1.1))) - (unless max - (setq max font-latex-sectioning-max)) - (dotimes (num max) - (let* (;; reverse for XEmacs: - (num (- max (1+ num))) - (face-name (intern (format "font-latex-sectioning-%s-face" num)))) - (unless (get face-name 'saved-face) ; Do not touch customized faces. - (set-face-attribute face-name nil :height height-scale))))) - -(defun font-latex-make-sectioning-faces (max &optional height-scale) - "Build the faces used to fontify sectioning commands." - (unless max (setq max font-latex-sectioning-max)) - (unless height-scale - (setq height-scale (if (numberp font-latex-fontify-sectioning) - ;; Make sure `height-scale' is a floating point - ;; number because the integer type is treated - ;; differently. - (float font-latex-fontify-sectioning) - 1.1))) - (dotimes (num max) - (let* ((num (- max (1+ num))) - (face-name (intern (format "font-latex-sectioning-%s-face" num))) - (f-inherit (intern (format "font-latex-sectioning-%s-face" (1+ num))))) - (eval - `(defface ,face-name - '((t (:height ,height-scale :inherit ,f-inherit))) - (format "Face for sectioning commands at level %s. - -Probably you don't want to customize this face directly. Better -change the base face `font-latex-sectioning-5-face' or customize the -variable `font-latex-fontify-sectioning'." ',num) - :group 'font-latex-highlighting-faces) - t)))) - -(font-latex-make-sectioning-faces font-latex-sectioning-max) - - -;;; Keywords - -(eval-and-compile -(defconst font-latex-built-in-keyword-classes - '(("warning" - ("nopagebreak" "pagebreak" "newpage" "clearpage" "cleardoublepage" - "enlargethispage" "nolinebreak" "linebreak" "newline" "-" "\\" "\\*" - "appendix" "displaybreak" "allowdisplaybreaks" "tabularnewline" "include" - "backmatter" "frontmatter" "mainmatter" - "makeatletter" "makeatother" "newblock" "suppressfloats" "endinput") - font-latex-warning-face 1 noarg) - ("variable" - (("setlength" "|{\\{") ("settowidth" "|{\\{") ("settoheight" "{{") - ("settodepth" "{{") ("setcounter" "{|{\\") - ("addtolength" "|{\\{") ("addtocounter" "{|{\\") - ("stepcounter" "{") ("refstepcounter" "{") - ("counterwithin" "*[{{") ("counterwithout" "*[{{") - ("arabic" "{") ("roman" "{") ("Roman" "{") ("alph" "{") ("Alph" "{") - ("fnsymbol" "{")) - font-lock-variable-name-face 2 command) - ("biblatexnoarg" - ("newrefsegment" "mancite" "pno" "ppno" "nopp" "psq" "psqq") - font-lock-variable-name-face 2 noarg) - ("biblatex" - (;; 3.2.2 Setting Package Options - ("ExecuteBibliographyOptions" "[{") - ;; 3.7.1 Resources - ("addbibresource" "[{") ("addglobalbib" "[{") ("addsectionbib" "[{") - ;; 3.7.2 The Bibliography - ("printbibliography" "[") ("bibbysection" "[") ("bibbysegment" "[") - ("bibbycategory" "[") ("printbibheading" "[") - ;; 3.7.3 Bibliography Lists - ("printbiblist" "[{") ("printshorthands" "[") - ;; 3.7.4 Bibliography Sections - ("newrefsection" "[") - ;; 3.7.6 Bibliography Categories - ("DeclareBibliographyCategory" "{") ("addtocategory" "{{") - ;; 3.7.7 Bibliography Headings and Environments - ("defbibenvironment" "{{{{") ("defbibheading" "{[{") - ;; 3.7.8 Bibliography Notes - ("defbibnote" "{{") - ;; 3.7.9 Bibliography Filters and Checks - ("defbibfilter" "{{") ("defbibcheck" "{{") - ;; 3.7.10 Reference Contexts - ("DeclareRefcontext" "{{") ("newrefcontext" "[{") - ("assignrefcontextkeyws" "*[{") ("assignrefcontextcats" "*[{") - ("assignrefcontextentries" "*[{") - ;; 3.7.11 Dynamic Entry Sets - ("defbibentryset" "{{") - ;; 3.8.1 Standard Commands - ("Cite" "[[{") - ("parencite" "*[[{") ("Parencite" "[[{") - ("footcite" "[[{") ("footcitetext" "[[{") - ;; 3.8.2 Style-specific Commands - ("textcite" "[[{") ("Textcite" "[[{") - ("smartcite" "[[{") ("Smartcite" "[[{") - ("supercite" "{") - ;; 3.8.3 Qualified Citation Lists - ;; For qualified lists, fontify at least 2 mandatory arguments - ("cites" "(([[{[[{") ("Cites" "(([[{[[{") - ("parencites" "(([[{[[{") ("Parencites" "(([[{[[{") - ("footcites" "(([[{[[{") ("footcitetexts" "(([[{[[{") - ("smartcites" "(([[{[[{") ("Smartcites" "(([[{[[{") - ("textcites" "(([[{[[{") ("Textcites" "(([[{[[{") - ("supercites" "(([[{[[{") - ;; 3.8.4 Style-independent Commands - ("autocite" "*[[{") ("Autocite" "*[[{") - ("autocites" "(([[{[[{") ("Autocites" "(([[{[[{") - ;; 3.8.5 Text Commands - ("citeauthor" "*[[{") ("Citeauthor" "*[[{") ("citetitle" "*[[{") - ("citeyear" "*[[{") ("citedate" "*[[{") - ("citeurl" "[[{") ("parentext" "{") - ("brackettext" "{") - ;; 3.8.6 Special Commands - ("fullcite" "[[{") ("footfullcite" "[[{") - ("volcite" "[{[{") ("Volcite" "[{[{") - ("volcites" "(([{[{[{[{") ("Volcites" "(([{[{[{[{") - ("pvolcite" "[{[{") ("Pvolcite" "[{[{") - ("pvolcites" "(([{[{[{[{") ("Pvolcites" "(([{[{[{[{") - ("fvolcite" "[{[{") ("ftvolcite" "[{[{") - ("fvolcites" "(([{[{[{[{") ("Fvolcites" "(([{[{[{[{") - ("svolcite" "[{[{") ("Svolcite" "[{[{") - ("svolcites" "(([{[{[{[{") ("Svolcites" "(([{[{[{[{") - ("tvolcite" "[{[{") ("Tvolcite" "[{[{") - ("tvolcites" "(([{[{[{[{") ("Tvolcites" "(([{[{[{[{") - ("avolcite" "[{[{") ("Avolcite" "[{[{") - ("avolcites" "(([{[{[{[{") ("Avolcites" "(([{[{[{[{") - ("notecite" "[[{") ("Notecite" "[[{") - ("pnotecite" "[[{") ("Pnotecite" "[[{") - ("fnotecite" "[[{") - ;; 3.8.7 Low-level Commands - ("citename" "[[{[{") ("citelist" "[[{[{") ("citefield" "[[{[{") - ;; 3.8.8 Miscellaneous Commands - ("citereset" "*") ("RN" "{") ("Rn" "{") - ;; 3.9 Localization Commands - ("DefineBibliographyStrings" "{{") ("DefineBibliographyExtras" "{{") - ("UndefineBibliographyExtras" "{{") ("DefineHyphenationExceptions" "{{") - ("NewBibliographyString" "{")) - font-lock-constant-face 2 command) - ("reference" - (("nocite" "*{") ("cite" "*[[{") ("label" "{") ("pageref" "{") - ("vref" "*{") ("eqref" "{") ("ref" "{") ("Ref" "{") - ("footref" "{") ("include" "{") ("input" "{") - ("bibliography" "{") ("index" "{") ("glossary" "{") - ("footnote" "[{") ("footnotemark" "[") ("footnotetext" "[{") - ("marginpar" "[{") ("chaptermark" "{") ("sectionmark" "{") - ("subsectionmark" "{") ("subsubsectionmark" "{") - ("paragraphmark" "{") ("subparagraphmark" "{")) - font-lock-constant-face 2 command) - ("function" - (("begin" "{") ("end" "{") ("pagenumbering" "{") - ("thispagestyle" "{") ("pagestyle" "{") ("nofiles" "") - ("includeonly" "{") ("bibliographystyle" "{") ("documentstyle" "[{") - ("documentclass" "[{[") ("newenvironment" "*{[[{{") - ("newcommand" "*|{\\[[{") ("newlength" "|{\\") - ("newtheorem" "{[{[") - ("providecommand" "*|{\\[[{") - ("newcounter" "{[") ("renewenvironment" "*{[[{{") - ("renewcommand" "*|{\\[[{") ("renewtheorem" "{[{[") - ("usepackage" "[{[") ("RequirePackage" "[{[") - ("fbox" "{") ("mbox" "{") ("rule" "[{{") - ("framebox" "|[([{") ("makebox" "|[([{") ("newsavebox" "|{\\") - ("parbox" "[[[{{") ("savebox" "|{\\|[([{") ("sbox" "|{\\{") - ("usebox" "|{\\") - ("cline" "{") ("extracolsep" "{") ("multicolumn" "{{{") - ("linethickness" "{") ("multiput" "(({{") ("put" "({") - ("qbezier" "[(((") ("raisebox" "{[[{") - ("addvspace" "{") ("vspace" "*{") ("hspace" "*{") - ("addcontentsline" "{{{") ("addtocontents" "{{") - ("labelformat" "{{") - ("AddToHook" "{[{") ("RemoveFromHook" "{[") ("AddToHookNext" "{{") - ("ProvidesClass" "{[") ("ProvidesPackage" "{[") ("ProvidesFile" "{[") - ;; XXX: Should macros without arguments rather be listed in a - ;; separate category with 'noarg instead of 'command handling? - ("enspace" "") ("enskip" "") ("quad" "") ("qquad" "") ("nonumber" "") - ("bigskip" "") ("medskip" "") ("smallskip" "") - ("thinspace" "") ("negthinspace" "") - ("thicklines" "") ("thinlines" "") - ("noindent" "") ("hline" "") ("ldots" "") - ("centering" "") ("raggedright" "") ("raggedleft" "") - ("TeX" "") ("LaTeX" "") ("LaTeXe" "") - ("normalfont" "") ("normalshape" "") - ("tableofcontents" "") ("listoffigures" "") ("listoftables" "")) - font-lock-function-name-face 2 command) - ("sectioning-0" - (("part" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-0-face) - 2 command) - ("sectioning-1" - (("chapter" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-1-face) - 2 command) - ("sectioning-2" - (("section" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-2-face) - 2 command) - ("sectioning-3" - (("subsection" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-3-face) - 2 command) - ("sectioning-4" - (("subsubsection" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-4-face) - 2 command) - ("sectioning-5" - (("paragraph" "*[{") ("subparagraph" "*[{") - ("subsubparagraph" "*[{")) - (if (eq font-latex-fontify-sectioning 'color) - 'font-lock-type-face - 'font-latex-sectioning-5-face) - 2 command) - ("slide-title" () font-latex-slide-title-face 2 command) - ("textual" - (("item" "[") ("bibitem" "[{") ("title" "{") ("author" "{") ("date" "{") - ("thanks" "{") ("address" "{") ("caption" "[{") - ("textsuperscript" "{") ("textsubscript" "{") ("verb" "*")) - font-lock-type-face 2 command) - ("bold-command" - (("textbf" "{") ("textsc" "{") ("textssc" "{") ("textulc" "{") - ("textup" "{") ("textsw" "{") ("boldsymbol" "{") ("pmb" "{") - ("mathbf" "{")) - font-latex-bold-face 1 command) - ("italic-command" - (("emph" "{") ("textit" "{") ("textsl" "{") ("mathit" "{")) - font-latex-italic-face 1 command) - ("math-command" - (("ensuremath" "|{\\")) - font-latex-math-face 1 command) - ("type-command" - (("texttt" "{") ("textsf" "{") ("textrm" "{") ("textmd" "{") - ("textnormal" "{") ("oldstylenums" "{") ("legacyoldstylenums" "{") - ("mathrm" "{") ("mathsf" "{") ("mathtt" "{")) - font-lock-type-face 1 command) - ("bold-declaration" - ("bf" "bfseries" "sc" "scshape" "sscshape" "ulcshape" "upshape" "swshape") - font-latex-bold-face 1 declaration) - ("italic-declaration" - ("em" "it" "itshape" "sl" "slshape") - font-latex-italic-face 1 declaration) - ("type-declaration" - ("tt" "ttfamily" "sf" "sffamily" "rm" "rmfamily" "mdseries" - "tiny" "scriptsize" "footnotesize" "small" "normalsize" - "large" "Large" "LARGE" "huge" "Huge") - font-lock-type-face 1 declaration)) - "Built-in keywords and specifications for font locking. - -The first element of each item is the name of the keyword class. - -The second element is a list of keywords (macros without an -escape character) to highlight or, if the fifth element is the -symbol `command', a list of lists where the first element of each -item is a keyword and the second a string specifying the macro -syntax. It can contain \"*\" if the macro has a starred variant, -\"[\" for an optional argument, \"{\" for a mandatory argument, -and \"\\\" for a macro. A \"|\" means the following two tokens -should be regarded as alternatives. - -The third element is the symbol of a face to be used or a Lisp -form returning a face symbol. - -The fourth element is the fontification level. - -The fifth element is the type of construct to be matched. It can -be one of `noarg' which will match simple macros without -arguments (like \"\\foo\"), `declaration' which will match macros -inside a TeX group (like \"{\\bfseries foo}\"), or `command' which -will match macros of the form \"\\foo[bar]{baz}\".")) - -(defcustom font-latex-deactivated-keyword-classes nil - "List of strings for built-in keyword classes to be deactivated. - -Valid entries are \"warning\", \"variable\", \"biblatexnoarg\", -\"biblatex\", \"reference\", \"function\" , \"sectioning-0\", -\"sectioning-1\", \"sectioning-2\", \"sectioning-3\", -\"sectioning-4\", \"sectioning-5\", \"slide-title\", \"textual\", -\"bold-command\", \"italic-command\", \"math-command\", -\"type-command\", \"bold-declaration\", \"italic-declaration\", -\"type-declaration\". - -You have to restart Emacs for a change of this variable to take effect." - :group 'font-latex-keywords - :type `(set ,@(mapcar - (lambda (spec) - `(const :tag ,(concat - ;; Name of the keyword class - (let ((name (split-string (car spec) "-"))) - (setcar name (capitalize (car name))) - (mapconcat #'identity name " ")) - " keywords in `" - ;; Name of the face - (symbol-name - (let ((face (nth 2 spec))) - (if (symbolp face) face (eval face t)))) - "'.\n" - ;; List of keywords - (with-temp-buffer - (insert " Keywords: " - (mapconcat (lambda (x) - (if (listp x) - (car x) - x)) - (nth 1 spec) ", ")) - (fill-paragraph nil) - (buffer-string))) - ,(car spec))) - font-latex-built-in-keyword-classes))) - -(eval-and-compile -(defun font-latex--make-match-defun (prefix name face type) - "Return a function definition for keyword matching. -The variable holding the keywords to match are determined by the -strings PREFIX and NAME. The type of matcher is determined by -the symbol TYPE. - -This is a helper function for `font-latex-make-built-in-keywords' -and `font-latex-make-user-keywords' and not intended for general -use." - ;; FIXME: Is the cond-clause possible inside of the defun? - - ;; In an earlier version of font-latex the type could be a list like - ;; (command 1). This indicated a macro with one argument. Provide - ;; a match function in this case but don't actually support it. - (cond ((or (eq type 'command) (listp type)) - `(defun ,(intern (concat prefix name)) (limit) - ,(concat "Fontify `" prefix name "' up to LIMIT. - -Generated by `font-latex--make-match-defun'.") - (when ,(intern (concat prefix name)) - (font-latex-match-command-with-arguments - ,(intern (concat prefix name)) - (append - (when (boundp ',(intern (concat prefix name - "-keywords-local"))) - ,(intern (concat prefix name "-keywords-local"))) - ,(intern (concat prefix name "-keywords"))) - ;; `face' can be a face symbol, a form returning - ;; a face symbol, or a list of face attributes. - ,(if (and (listp face) (fboundp (car face))) - face - `',face) - limit)))) - ((eq type 'declaration) - `(defun ,(intern (concat prefix name)) (limit) - ,(concat "Fontify `" prefix name "' up to LIMIT. - -Generated by `font-latex--make-match-defun'.") - (when ,(intern (concat prefix name)) - (font-latex-match-command-in-braces - ,(intern (concat prefix name)) limit)))) - ((eq type 'noarg) - `(defun ,(intern (concat prefix name)) (limit) - ,(concat "Fontify `" prefix name "' up to LIMIT. - -Generated by `font-latex--make-match-defun'.") - (when ,(intern (concat prefix name)) - (re-search-forward - ,(intern (concat prefix name)) limit t)))))) - -(defun font-latex-keyword-matcher (prefix name face type) - "Return a matcher and highlighter as required by `font-lock-keywords'. -PREFIX and NAME are strings which are concatenated to form the -respective match function. FACE is a face name or a list of face -attributes that will be applied to the respective part of the -match returned by the match function. A lisp form returning a -face name or a list of face attributes is also valid for FACE. -TYPE is the type of construct to be highlighted. Currently the -symbols `command', `declaration' and `noarg' are valid. - -This is a helper function for `font-latex-make-built-in-keywords' -and `font-latex-make-user-keywords' and not intended for general -use." - ;; Quote a list of face attributes and a face symbol - ;; but do not quote a form returning such value. - (unless (and (listp face) (fboundp (car face))) - (setq face `',face)) - - ;; In an earlier version of font-latex the type could be a list like - ;; (command 1). This indicated a macro with one argument. Provide - ;; a matcher in this case but don't actually support it. - (cond ((or (eq type 'command) (listp type)) - `(,(intern (concat prefix name)) - (0 (font-latex-matched-face 0) append t) - (1 (font-latex-matched-face 1) append t) - (2 (font-latex-matched-face 2) append t) - (3 (font-latex-matched-face 3) append t) - (4 (font-latex-matched-face 4) append t) - (5 (font-latex-matched-face 5) append t) - (6 (font-latex-matched-face 6) append t) - (7 (font-latex-matched-face 7) append t) - (8 (font-latex-matched-face 8) append t) - (9 (font-latex-matched-face 9) append t) - (10 (font-latex-matched-face 10) append t) - (11 (font-latex-matched-face 11) append t))) - ((eq type 'noarg) - `(,(intern (concat prefix name)) - (0 ,face))) - ((eq type 'declaration) - `(,(intern (concat prefix name)) - (0 'font-latex-warning-face t t) - (1 'font-lock-keyword-face append t) - (2 ,face append t)))))) - -(defmacro font-latex-make-built-in-keywords () - "Build defuns, defvars and defcustoms for built-in keyword fontification." - (let ((flks '()) - (defs '())) - (dolist (item font-latex-built-in-keyword-classes) - (let ((prefix "font-latex-match-") - (name (nth 0 item)) - (keywords (nth 1 item)) - (face (nth 2 item)) - (level (nth 3 item)) - (type (nth 4 item))) - - ;; defvar font-latex-match-*-keywords-local - (push `(defvar-local ,(intern (concat prefix name "-keywords-local")) - ',keywords - ,(concat "Buffer-local keywords to add to `" - prefix name "-keywords'.\n\n" - (if (eq type 'command) - "\ -This must be a list where each element is a list consisting of a -keyword string \(not a regular expression\) omitting the leading -backslash and a format specifier as described in the doc string of -`font-latex-user-keyword-classes'." - "\ -This must be a list where each element is a keyword string \(not a -regular expression\) omitting the leading backslash.") - - "\n\n\ -This is an internal variable which should not be set directly. -Use `font-latex-add-keywords' instead. - -Generated by `font-latex-make-built-in-keywords'.")) - defs) - - ;; defvar font-latex-match-* - ;; We make this variable buffer local later, but don't use - ;; `defvar-local' here because it shouldn't have nil as its - ;; default value. Its true default value is set by - ;; through font-latex-match-*-make in :set specification of - ;; defcustom of font-latex-match-*-keywords below. It's - ;; only after that this variable can be buffer local. - (push `(defvar ,(intern (concat prefix name)) nil - ,(concat "Regular expression to match " name - " keywords. - -Generated by `font-latex-make-built-in-keywords'")) - defs) - - ;; This defvar (without value) is here just to suppress compiler - ;; warnings. Its true definition is done by defcustom following - ;; the next defun because its :set function depends on the - ;; function defined by that defun. - (push `(defvar ,(intern (concat prefix name "-keywords"))) - defs) - - ;; defun font-latex-match-*-make - (push `(defun ,(intern (concat prefix name "-make")) () - ,(concat "Make or remake the variable `" prefix name "'. - -Generated by `font-latex-make-built-in-keywords'.") - (let ((keywords - (append - (unless (member ,name - font-latex-deactivated-keyword-classes) - ,(intern (concat prefix name "-keywords-local"))) - ,(intern (concat prefix name "-keywords")))) - multi-char-macros single-char-macros) - (dolist (elt keywords) - (let ((keyword (if (listp elt) (car elt) elt))) - (if (string-match "^[A-Za-z]" keyword) - (push keyword multi-char-macros) - (push keyword single-char-macros)))) - (when (or multi-char-macros single-char-macros) - (setq ,(intern (concat prefix name)) - (concat - "\\\\\\(" - (when multi-char-macros - (concat - "\\(?:" (regexp-opt multi-char-macros) "\\)\\>")) - (when single-char-macros - (concat - (when multi-char-macros "\\|") - "\\(?:" (regexp-opt single-char-macros) "\\)")) - "\\)"))))) - defs) - - ;; defcustom font-latex-match-*-keywords - (push `(defcustom ,(intern (concat prefix name "-keywords")) nil - ,(concat "List of keywords " - (when (eq type 'command) "and formats ") - "for " name " face.\n" - (if (eq type 'command) - "\ -Each element has to be a list consisting of the name of a macro -omitting the leading backslash and a format specifier as -described in the doc string of `font-latex-user-keyword-classes'." - "\ -Each element has to be the name of a macro as a string, omitting -the leading backslash.") - "\n\n\ -Setting this variable directly does not take effect; restart -Emacs. - -Generated by `font-latex-make-built-in-keywords'.") - :type '(repeat ,(if (eq type 'command) - '(list (string :tag "Keyword") - (string :tag "Format")) - '(string :tag "Keyword"))) - :set (lambda (symbol value) - (set-default symbol value) - (funcall ',(intern (concat prefix name "-make")))) - :group 'font-latex-keywords) - defs) - - ;; Now that font-latex-match-* has attained proper default - ;; value, make it buffer local. - (push `(make-variable-buffer-local ',(intern (concat prefix name))) - defs) - - ;; defun font-latex-match-* - (push (font-latex--make-match-defun prefix name face type) defs) - - ;; Add matchers and highlighters to `font-latex-keywords-{1,2}'. - (let ((keywords-entry (font-latex-keyword-matcher - prefix name face type))) - (push (cons level keywords-entry) flks)))) - `(progn - ,@(nreverse defs) - (defvar font-latex-keywords-1 - ',(nreverse (delq nil (mapcar (lambda (x) (if (eq 1 (car x)) (cdr x))) - flks))) - "Subdued level highlighting for LaTeX modes.") - (defvar font-latex-keywords-2 - ',(nreverse (mapcar #'cdr flks)) - "High level highlighting for LaTeX modes.")))) - -(font-latex-make-built-in-keywords) - -(defcustom font-latex-user-keyword-classes nil - "List of user-defined keyword classes for font locking. - -Every keyword class consists of four parts, a name, a list of -keywords, a face and a specifier for the type of macro to be -highlighted. - -When adding new entries, you have to use unique values for the -class names, that is, they must not clash with names of the -built-in keyword classes or other names given by you. -Additionally the names must not contain spaces. - -The list of keywords defines which commands and declarations -should be covered by the keyword class. A keyword can either be -a simple command name omitting the leading backslash or a list -consisting of the command name and a string specifying the syntax -of the command. The latter is useful if you want to match LaTeX -macros with arguments (see below). You can specify the occurence -and order of optional (\"[\") and mandatory (\"{\") arguments for -each keyword. For example for \"documentclass\" you'd use \"[{\" -because the macro has one optional followed by one mandatory -argument. Optionally starred macros can be indicated with \"*\". -In case an argument is an unbraced macro, use \"\\\". You can -also specify two alternative arguments by prefixing them with -\"|\". As an example, the specifier for \\newcommand is -\"*|{\\=\\[[{\". - -The face argument can either be an existing face or a face -attribute. - -There are three alternatives for the class type: - -A value of `command' indicates commands with arguments -\(\"\\foo[bar]{baz}\"). The mandatory arguments in curly braces -will get the face you specified. - -A value of `declaration' indicates declarations inside of TeX -groups (\"{\\foo bar}\"). The content inside the braces, -excluding the command, will get the face you specified. In case -the braces are missing, the face will be applied to the command -itself. - -A value of `noarg' indicates commands without arguments -\(\"\\foo\"). The command itself will get the face you -specified. - -Setting this variable directly does not take effect; -restart Emacs." - :group 'font-latex-keywords - :type '(repeat (list (string :tag "Name") - (choice (repeat :tag "Keywords" (string :tag "Keyword")) - (repeat - :tag "Keywords with specs" - (group (string :tag "Keyword") - (string :tag "Format specifier")))) - (choice (face :tag "Face name") - (custom-face-edit :tag "Face attributes")) - (choice :tag "Type" - ;; Maps to - ;;`font-latex-match-command-with-arguments' - (const :tag "Command with arguments" - command) - ;; Maps to - ;;`font-latex-match-command-in-braces' - (const :tag "Declaration inside TeX group" - declaration) - ;; Maps to `re-search-forward' - (const :tag "Command without arguments" - noarg)))) - :set (lambda (symbol value) - (dolist (item value) - (when (string-match " " (car item)) - (error "No spaces allowed in name"))) - (let (names names-uniq) - (dolist (item (append font-latex-built-in-keyword-classes value)) - (setq names (append names (list (car item))))) - (setq names (TeX-sort-strings names)) - (setq names-uniq (TeX-delete-duplicate-strings names)) - (dotimes (i (safe-length names-uniq)) - (unless (string= (nth i names) (nth i names-uniq)) - (error "Name %S already exists" (nth i names))))) - (set-default symbol value) - (let ((prefix "font-latex-match-")) - (dolist (elt value) - (unless (boundp (intern (concat prefix (car elt)))) - ;; defvar font-latex-match-* - (eval `(defvar ,(intern (concat prefix (car elt))) nil - ,(concat "Regular expression to match " (car elt) - " keywords. - -Generated by `font-latex-user-keyword-classes'")))) - (let ((keywords (nth 1 elt)) - single-char-macro-flag) - (setq keywords (if (listp (car keywords)) - (mapcar #'car keywords) - keywords)) - (catch 'single-char - (dolist (keyword keywords) - (unless (string-match "^[A-Za-z]" keyword) - (setq single-char-macro-flag t) - (throw 'single-char nil)))) - (set (intern (concat prefix (car elt))) - (when (> (safe-length keywords) 0) - (concat "\\\\" (let ((max-specpdl-size 1000)) - (regexp-opt keywords t)) - (unless single-char-macro-flag "\\>"))))))))) - -(defun font-latex-make-user-keywords () - "Build defuns and defvars for user keyword fontification." - (let ((keyword-specs font-latex-user-keyword-classes)) - (dolist (item keyword-specs) - (let ((prefix "font-latex-match-") - (name (nth 0 item)) - (keywords (nth 1 item)) - (face (nth 2 item)) - (type (nth 3 item))) - - ;; defvar font-latex-match-*-keywords - (eval `(defvar ,(intern (concat prefix name "-keywords")) ',keywords - ,(concat "Font-latex keywords for " name " face. - -Generated by `font-latex-make-user-keywords'."))) - - ;; defun font-latex-match-* - (eval (font-latex--make-match-defun prefix name face type) t) - - ;; Add the matcher to `font-latex-keywords-2'. - (add-to-list 'font-latex-keywords-2 - (font-latex-keyword-matcher prefix name face type) t)))) - - ;; Add the "fixed" matchers and highlighters. - (dolist (item - '(("\\(^\\|[^\\]\\)\\(&+\\)" 2 'font-latex-warning-face) - (font-latex-match-dollar-math 0 'font-latex-math-face keep) - (font-latex-match-quotation - (0 'font-latex-string-face append) - (1 'font-latex-warning-face)) - ;; Hack to remove the verbatim face from the \ in - ;; \end{verbatim} and similar. The same hack is used in - ;; tex-mode.el. - ("\\(\\\\\\)end" - (1 (get-text-property (match-end 1) 'face) t)))) - (add-to-list 'font-latex-keywords-1 item) - (add-to-list 'font-latex-keywords-2 item)) - (dolist (item - '((font-latex-match-math-env - (0 'font-latex-warning-face t t) - (1 'font-latex-math-face append t)) - (font-latex-match-math-envII - (1 'font-latex-math-face append t)) - (font-latex-match-simple-command - (0 'font-latex-sedate-face append)) - (font-latex-match-script - (1 (font-latex-script (match-beginning 0)) append)) - (font-latex-match-script-chars - (1 (font-latex-script-char (match-beginning 1)) prepend)))) - (add-to-list 'font-latex-keywords-2 item t))) -(font-latex-make-user-keywords) - -(defun font-latex-add-keywords (keywords class) - "Add KEYWORDS to CLASS. -KEYWORDS is a list of keywords or keywords with syntax specs. -CLASS corresponds to a keyword class and can be one of the -symbols `warning', `variable', `reference', `biblatexnoarg', -`biblatex', `function', `sectioning-0', `sectioning-1', -`sectioning-2', `sectioning-3', `sectioning-4', `sectioning-5', -`slide-title', `textual', `bold-command', `italic-command', -`math-command', `type-command', `bold-declaration', -`italic-declaration' or `type-declaration'. - -The keywords will be added to the buffer-local list of keywords -of the respective keyword class and necessary updates of the font -locking machinery will be triggered." - (let* ((class (symbol-name class)) - (list (intern (format "font-latex-match-%s-keywords-local" class)))) - (dolist (elt keywords) - (add-to-list list elt)) - (funcall (intern (format "font-latex-match-%s-make" class))) - ;; Trigger refontification. - (when (fboundp 'font-lock-flush) - (font-lock-flush)))) - -(defvar font-latex-keywords font-latex-keywords-1 - "Default expressions to highlight in TeX mode.") - - -;;; Subscript and superscript - -(defcustom font-latex-fontify-script t - "If non-nil, fontify subscript and superscript strings. - -By default, super/subscripts are raised/lowered if this variable -is non-nil. This fontification only affects one level of -scripts, for example in x^{y^z}, the y and the z have the same -size and are equally raised over x. - -If this variable is set to the symbol `multi-level', then y is -raised above x, and z is raised above y. With many script -levels, the text might become too small to be readable, thus -there is the option `font-latex-fontify-script-max-level'. (The -factors for text shrinking are defined in the faces -`font-latex-superscript-face' and `font-latex-subscript-face' and -the raise/lower factor in `font-latex-script-display'.) - -If this variable is set to the symbol `invisible', then the -effect is essentially like `multi-level' but additionally the -script operators ^ and _ are not displayed." - :type '(choice (boolean :tag "Enabled") - (const :tag "Multiple levels" multi-level) - (const :tag "Hide ^ and _" invisible)) - :group 'font-latex) -(put 'font-latex-fontify-script 'safe-local-variable - (lambda (val) - (or (booleanp val) - (memq val '(multi-level invisible))))) - -(defcustom font-latex-fontify-script-max-level 3 - "Maximum scriptification level for which script faces are applied. -The faces `font-latex-superscript-face' and -`font-latex-subscript-face' define custom :height values < 1.0. -Therefore, scripts are displayed with a slightly smaller font -than normal math text. If `font-latex-fontify-script' is -`multi-level' or `invisible', the font size becomes too small to -be readable after a few levels. This option allows to specify -the maximum level after which the size of the script text won't -be shrunken anymore. - -For example, see this expression: - - \\( x^{y^{z^a_b}} \\) - -x has scriptification level 0, y has level 1, z has level 2, and -both a and b have scriptification level 3. - -If `font-latex-fontify-script-max-level' was 2, then z, a, and b -would have the same font size. If it was 3 or more, then a and b -were smaller than z just in the same way as z is smaller than y -and y is smaller than x." - :group 'font-latex - :type 'integer) - -(defcustom font-latex-script-display '((raise -0.5) . (raise 0.5)) - "Display specification for subscript and superscript content. -The car is used for subscript, the cdr is used for superscripts." - :group 'font-latex - :type '(cons (choice (sexp :tag "Subscript form") - (const :tag "No lowering" nil)) - (choice (sexp :tag "Superscript form") - (const :tag "No raising" nil)))) - - -;;; Syntactic keywords - -(defvar font-latex-syntactic-keywords nil - "Syntactic keywords used by `font-latex'.") -(make-variable-buffer-local 'font-latex-syntactic-keywords) - -(defvar font-latex-syntactic-keywords-extra nil - "List of syntactic keywords to add to `font-latex-syntactic-keywords'. -The form should be the same as in `font-lock-syntactic-keywords'.") -(make-variable-buffer-local 'font-latex-syntactic-keywords-extra) - -;; Set and updated in `font-latex-set-syntactic-keywords'. -(defvar font-latex-doctex-syntactic-keywords nil) - -(defun font-latex-set-syntactic-keywords () - "Set the variable `font-latex-syntactic-keywords'. -This function can be used to refresh the variable in case other -variables influencing its value, like `LaTeX-verbatim-environments', -have changed." - ;; Checks for non-emptiness of lists added in order to cater for - ;; installations where `(regexp-opt-group nil)' would enter a loop. - (let ((verb-envs (and (fboundp 'LaTeX-verbatim-environments) - (LaTeX-verbatim-environments))) - (verb-macros-with-delims - (and (fboundp 'LaTeX-verbatim-macros-with-delims) - (LaTeX-verbatim-macros-with-delims))) - (verb-macros-with-braces - (and (fboundp 'LaTeX-verbatim-macros-with-braces) - (LaTeX-verbatim-macros-with-braces)))) - (setq verb-envs (and verb-envs (regexp-opt verb-envs)) - verb-macros-with-delims (and verb-macros-with-delims - (regexp-opt verb-macros-with-delims)) - verb-macros-with-braces (and verb-macros-with-braces - (regexp-opt verb-macros-with-braces)) - font-latex-syntactic-keywords nil) - (unless (= (length verb-envs) 0) - (add-to-list - 'font-latex-syntactic-keywords - `(,(concat - "^[ \t]*\\\\begin *{\\(?:" verb-envs "\\)}" - ;; Some environments accept an optional and/or mandatory - ;; argument that can span over more lines. Between - ;; "\begin{<envname>}" and the optional argument there can - ;; be whitespaces and the newline can be commented by a "%" - ;; character. - "[ \t]*\\(?:%.*\n[ \t]*\\)?" - ;; The following line of the regexp matches the optional - ;; argument and allows for up to one level of brackets - ;; inside the argument (e.g., the dialect of a language in - ;; the `lstlisting' environment by the `listings' package). - "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" - ;; After the optional argument, there may also be another - ;; mandatory argument(s) (e.g. with VerbatimOut or the - ;; minted envs or defined with `lstnewenvironment'). Use - ;; the same trick as above in order to allow one level of - ;; braces in the argument. - "\\(?:{[^{}]*\\(?:{[^{}]*}[^{}]*\\)*}\\)*" - ;; Now match the final newline. The "." alternative - ;; catches the case where verbatim content is written - ;; immediately after the \begin{verbatim}. - "\\(\n\\|.\\)") - (1 "|" t))) - (add-to-list - 'font-latex-syntactic-keywords - ;; Using the newline character for the syntax property often - ;; resulted in fontification problems when text was inserted at - ;; the end of the verbatim environment. That's why we now use - ;; the starting backslash of \end. There is a hack in - ;; `font-latex-make-user-keywords' to remove the spurious - ;; fontification of the backslash. - `(,(concat "\\(\\\\\\)end *{\\(?:" verb-envs "\\)}") - (1 "|" t)))) - (unless (= (length verb-macros-with-delims) 0) - (add-to-list - 'font-latex-syntactic-keywords - `(,(concat "\\\\\\(?:" verb-macros-with-delims "\\)" - ;; Some macros take an optional argument. This is - ;; the same line as above for environments. - "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" - ;; An opening curly brace as delimiter is valid, but - ;; allowing it might screw up fontification of stuff - ;; like "\url{...} foo \textbf{<--!...}". - "\\([^a-z@*\n\f{]\\).*?" - ;; Give an escape char at the end of the verbatim - ;; construct punctuation syntax. Prevents wrong - ;; fontification of stuff like "\verb|foo\|". - "\\(" (regexp-quote TeX-esc) "*\\)\\(\\1\\)") - (1 "\"") (2 ".") (3 "\"")))) - (unless (= (length verb-macros-with-braces) 0) - (add-to-list - 'font-latex-syntactic-keywords - `(,(concat "\\\\\\(?:" verb-macros-with-braces "\\)" - ;; Some macros take an optional argument. This is - ;; the same line as above for environments. - "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" - "\\({\\).*?[^\\]\\(?:\\\\\\\\\\)*\\(}\\)") - (1 "|") (2 "|"))))) - (when font-latex-syntactic-keywords-extra - (nconc font-latex-syntactic-keywords font-latex-syntactic-keywords-extra)) - ;; ;; Cater for docTeX mode. - ;; (setq font-latex-doctex-syntactic-keywords - ;; (append font-latex-syntactic-keywords - ;; ;; For docTeX comment-in-doc. - ;; '(("\\(\\^\\)\\^A" (1 (font-latex-doctex-^^A)))))) - ;; Finally, compute our `syntax-propertize-function' anew. - (setq-local syntax-propertize-function - (font-latex--make-syntax-propertize-function))) - - -;;; Syntactic fontification - -(defun font-latex-syntactic-face-function (state) - (if (nth 3 state) - 'font-latex-verbatim-face - 'font-lock-comment-face)) - -;;; Faces - -(defface font-latex-bold-face - (let ((font '(:inherit bold))) - `((((class grayscale) (background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "LightGray" ,@font)) - (((class color) (background light)) - (:foreground "DarkOliveGreen" ,@font)) - (((class color) (background dark)) - (:foreground "OliveDrab" ,@font)) - (t (,@font)))) - "Face used to highlight text to be typeset in bold." - :group 'font-latex-highlighting-faces) - -(defface font-latex-italic-face - (let ((font '(:inherit italic))) - `((((class grayscale) (background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "LightGray" ,@font)) - (((class color) (background light)) - (:foreground "DarkOliveGreen" ,@font)) - (((class color) (background dark)) - (:foreground "OliveDrab" ,@font)) - (t (,@font)))) - "Face used to highlight text to be typeset in italic." - :group 'font-latex-highlighting-faces) - -(defface font-latex-math-face - (let ((font '(:inherit underline))) - `((((class grayscale) (background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "LightGray" ,@font)) - (((class color) (background light)) - (:foreground "SaddleBrown")) - (((class color) (background dark)) - (:foreground "burlywood")) - (t (,@font)))) - "Face used to highlight math." - :group 'font-latex-highlighting-faces) - -(defface font-latex-sedate-face - '((((class grayscale) (background light)) (:foreground "DimGray")) - (((class grayscale) (background dark)) (:foreground "LightGray")) - (((class color) (background light)) (:foreground "DimGray")) - (((class color) (background dark)) (:foreground "LightGray")) - ;;;(t (:underline t)) - ) - "Face used to highlight sedate stuff." - :group 'font-latex-highlighting-faces) - -(defface font-latex-string-face - (let ((font '(:inherit italic))) - `((((type tty) (class color)) - (:foreground "green")) - (((class grayscale) (background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "LightGray" ,@font)) - (((class color) (background light)) - (:foreground "RosyBrown")) - (((class color) (background dark)) - (:foreground "LightSalmon")) - (t (,@font)))) - "Face used to highlight strings." - :group 'font-latex-highlighting-faces) - -(defface font-latex-warning-face - (let ((font '(:inherit bold))) - `((((class grayscale)(background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale)(background dark)) - (:foreground "LightGray" ,@font)) - (((class color)(background light)) - (:foreground "red" ,@font)) - (((class color)(background dark)) - (:foreground "red" ,@font)) - (t (,@font)))) - "Face for important keywords." - :group 'font-latex-highlighting-faces) - -(defface font-latex-verbatim-face - (let ((font '(:inherit fixed-pitch))) - `((((class grayscale) (background light)) - (:foreground "DimGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "LightGray" ,@font)) - (((class color) (background light)) - (:foreground "SaddleBrown" ,@font)) - (((class color) (background dark)) - (:foreground "burlywood" ,@font)) - (t (,@font)))) - "Face used to highlight TeX verbatim environments." - :group 'font-latex-highlighting-faces) - -(defface font-latex-superscript-face - '((t (:height 0.85))) - "Face used for superscripts." - :group 'font-latex-highlighting-faces) - -(defface font-latex-subscript-face - '((t (:height 0.85))) - "Face used for subscripts." - :group 'font-latex-highlighting-faces) - -(defface font-latex-script-char-face - (let ((font '(:inherit underline))) - `((((class grayscale) (background light)) - (:foreground "DarkGray" ,@font)) - (((class grayscale) (background dark)) - (:foreground "gray" ,@font)) - (((class color) (background light)) - (:foreground "salmon")) - (((class color) (background dark)) - (:foreground "DarkRed")) - (t (,@font)))) - "Face used for the script chars ^ and _." - :group 'font-latex-highlighting-faces) - -(defface font-latex-slide-title-face - '((t (:inherit (variable-pitch font-lock-type-face) - :weight bold :height 1.2))) - "Face for slide titles." - :group 'font-latex-highlighting-faces) - -;;; Setup - -(defvar font-latex-syntax-alist - ;; Use word syntax for @ because we use \> for matching macros and - ;; we don't want \foo@bar to be found if we search for \foo. - '((?\( . ".") (?\) . ".") (?@ . "w")) - "List of specifiers for the syntax alist of `font-lock-defaults'.") - -(defun font-latex-add-to-syntax-alist (list) - "Activate syntactic font locking for the entries in LIST. -The entries are added to `font-latex-syntax-alist' and eventually -end up in `font-lock-defaults'. Each entry in LIST should be a -cons pair as expected by `font-lock-defaults'. The function also -triggers Font Lock to recognize the change." - (set (make-local-variable 'font-latex-syntax-alist) - (append font-latex-syntax-alist list)) - ;; We modify the `font-lock-syntax-table' directly but also call - ;; `font-latex-setup' in order to have `font-lock-defaults' be in sync. - (font-latex-setup) - (dolist (elt list) - (modify-syntax-entry (car elt) (cdr elt) font-lock-syntax-table)) - ;; Trigger refontification. - (when (fboundp 'font-lock-flush) - (font-lock-flush))) - -(defun font-latex--make-syntax-propertize-function () - "Return a `syntax-propertize-function' for (La|Doc)TeX documents." - (let ((kws ;; (if (derived-mode-p 'doctex-mode) - ;; font-latex-doctex-syntactic-keywords - font-latex-syntactic-keywords)) ;; ) - (syntax-propertize-via-font-lock kws))) - -;;;###autoload -(defun font-latex-setup () - "Setup this buffer for LaTeX font-lock. Usually called from a hook." - (font-latex-set-syntactic-keywords) - - ;; Activate multi-line fontification facilities. - (set (make-local-variable 'font-lock-multiline) t) - - ;; The test for `major-mode' currently only works with docTeX mode - ;; because `TeX-install-font-lock' is called explicitly in - ;; `doctex-mode'. In case other modes have to be distinguished as - ;; well, remove the call to `TeX-install-font-lock' from - ;; `VirTeX-common-initialization' and place it in the different - ;; `xxx-mode' calls instead, but _after_ `major-mode' is set. - (let ((defaults - `((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2) - nil nil ,font-latex-syntax-alist nil)) - (variables - '((font-lock-mark-block-function . mark-paragraph) - (font-lock-fontify-region-function - . font-latex-fontify-region) - (font-lock-unfontify-region-function - . font-latex-unfontify-region) - (font-lock-extend-region-functions - font-lock-extend-region-wholelines - font-lock-extend-region-multiline - font-latex-extend-region-backwards-command-with-args - font-latex-extend-region-backwards-command-in-braces - font-latex-extend-region-backwards-quotation - font-latex-extend-region-backwards-math) - (syntax-propertize-extend-region-functions - syntax-propertize-wholelines - font-latex-sp-extend-region-backwards-verb-env)))) - ;; Add the mode-dependent stuff to the basic variables defined above. - (if (eq major-mode 'doctex-mode) - (progn - (setcar defaults (append (car defaults) - '(font-latex-doctex-keywords))) - (setq variables - (append variables - '((font-lock-syntactic-face-function - . font-latex-doctex-syntactic-face-function))))) - (setq variables - (append variables - '((font-lock-syntactic-face-function - . font-latex-syntactic-face-function))))) - ;; Set the defaults. - (setq font-lock-defaults (append defaults variables))) - - ;; Make sure fontification will be refreshed if a user sets variables - ;; influencing fontification in her file-local variables section. - (add-hook 'hack-local-variables-hook #'font-latex-after-hacking-local-variables t t)) - -(defun font-latex-update-font-lock (&optional _syntactic-kws) - "Tell font-lock about updates of fontification rules. -If SYNTACTIC-KWS is non-nil, also update -`font-latex-syntactic-keywords'." - (display-warning - 'auctex - (concat "`font-latex-update-font-lock' should not be called. -It is obsolete and going to be removed. -If you have called `font-latex-add-keywords' and want to refresh fontification, -call `font-lock-flush' instead. -If you changed syntactic fontification, for example, one of the variables -- `LaTeX-verbatim-macros-with-delims' -- `LaTeX-verbatim-macros-with-delims-local' -- `LaTeX-verbatim-macros-with-braces' -- `LaTeX-verbatim-macros-with-braces-local' -- `LaTeX-verbatim-environments' -- `LaTeX-verbatim-environments-local' -- `font-latex-syntactic-keywords-extra' -then call `font-latex-set-syntactic-keywords'."))) - -(make-obsolete 'font-latex-update-font-lock nil "12.2.4") - -(defvar font-latex--updated-region-end nil -;; During font lock operation, matched range sometimes exceeds the -;; given end limit. So record the actual end in this variable to -;; notify the font lock machinery. -;; Match functions should do the following two if the end of the -;; actual match goes beyond the limit: -;; 1. If the value of this variable is smaller than limit, set this -;; variable to that limit. -;; 2. When the end of the actual match exceeds this variable, -;; - apply `font-lock-unfontify-region' between the value of this -;; variable and the end of the actual match -;; - update this variable to the end of the actual match -;; See implementation of `font-latex-match-math-env' for actual usage. - "Record the end of fontification.") -(defun font-latex-fontify-region (beg end &optional verbose) - "Fontify region from BEG to END. -Take care when the actually fonfified region was extended beyond END." - (setq font-latex--updated-region-end end) - (let ((res (font-lock-default-fontify-region beg end verbose))) - ;; COMPATIBILITY for older emacsen. Return value for jit-lock - ;; is meaningful for only newer emacsen. - (if (eq (car-safe res) 'jit-lock-bounds) - `(jit-lock-bounds ,(cadr res) . - ,(max (cddr res) font-latex--updated-region-end))))) - -;; Copy and adaption of `tex-font-lock-unfontify-region' from -;; tex-mode.el in GNU Emacs on 2004-08-04. -;; (XEmacs passes a third argument to the function.) -(defun font-latex-unfontify-region (beg end &rest _ignored) - "Unfontify region from BEG to END." - (font-lock-default-unfontify-region beg end) - (remove-list-of-text-properties beg end '(script-level invisible)) - (while (< beg end) - (let ((next (next-single-property-change beg 'display nil end)) - (prop (get-text-property beg 'display))) - (if (and (eq (car-safe prop) 'raise) - (null (cddr prop))) - (put-text-property beg next 'display nil)) - (setq beg next)))) - -(defun font-latex-after-hacking-local-variables () - "Refresh fontification if required by updates of file-local variables. -This function is added to `hack-local-variables-hook' and -recomputes fontification if variables affecting fontification are -modified. Such variables include -`LaTeX-verbatim-environments-local', -`LaTeX-verbatim-macros-with-braces-local', -`LaTeX-verbatim-macros-with-delims-local'." - (when - ;; In Emacs we know if the value came from file or directory - ;; locals. Note to self: directory-local variables are also added - ;; to file-local-variables-alist. - (let ((hacked-local-vars (mapcar #'car file-local-variables-alist))) - (or (memq 'LaTeX-verbatim-environments-local hacked-local-vars) - (memq 'LaTeX-verbatim-macros-with-braces-local hacked-local-vars) - (memq 'LaTeX-verbatim-macros-with-delims-local hacked-local-vars))) - ;; Ok, we need to refresh syntactic fontification. - (font-latex-set-syntactic-keywords))) - -;;; Utility functions - -(defun font-latex-find-matching-close (openchar closechar) - "Skip over matching pairs of OPENCHAR and CLOSECHAR. -OPENCHAR is the opening character and CLOSECHAR is the closing -character. Character pairs are usually { } or [ ]. Comments are -ignored during the search." - (let ((parse-sexp-ignore-comments - (not (eq major-mode 'doctex-mode))) ; scan-sexps ignores comments - (init-point (point)) - (mycount 1) - (esc-char (or (and (boundp 'TeX-esc) TeX-esc) "\\")) - ;; XXX: Do not look up syntax-table properties since they may - ;; be misleading, e.g. in the case of "{foo}^^A" where the - ;; closing brace gets a comment end syntax. - (parse-sexp-lookup-properties nil)) - (or - (condition-case nil - (progn - (goto-char (with-syntax-table - (TeX-search-syntax-table openchar closechar) - (scan-sexps (point) 1))) - ;; No error code. See if closechar is unquoted - (save-excursion - (backward-char 1) - (zerop (mod (skip-chars-backward (regexp-quote esc-char)) 2)))) - (error nil)) - (save-match-data - (goto-char (1+ init-point)) - (while (and (> mycount 0) - (re-search-forward - (string ?\[ - ;; closechar might be ] - ;; and therefor must be first in regexp - closechar openchar - ?\]) - nil t)) - (cond - ((font-latex-commented-outp) - (forward-line 1)) - ((save-excursion - (backward-char 1) - (zerop (mod (skip-chars-backward (regexp-quote esc-char)) - 2))) - (setq mycount (+ mycount - (if (= (preceding-char) openchar) 1 -1))))))) - (if (= mycount 0) - t - (goto-char init-point) - nil)))) - -(defun font-latex-commented-outp () - "Return t if comment character is found between bol and point." - (save-excursion - (let ((limit (point)) - (esc-char (if (and (boundp 'TeX-esc) TeX-esc) TeX-esc "\\"))) - (forward-line 0) - (if (and (eq (char-after) ?\%) - (not (font-latex-faces-present-p 'font-latex-verbatim-face))) - (not (eq major-mode 'doctex-mode)) - (catch 'found - (while (progn (skip-chars-forward "^%" limit) - (< (point) limit)) - (when (and (save-excursion - (zerop (mod (skip-chars-backward - (regexp-quote esc-char)) 2))) - (not (font-latex-faces-present-p - 'font-latex-verbatim-face))) - (throw 'found t)) - (forward-char))))))) - -(defun font-latex-faces-present-p (faces &optional pos) - "Return t if FACES are present at position POS. -FACES may be a single face or a list of faces. -If POS is omitted, the current position of point is used." - (let* ((faces (if (listp faces) faces (list faces))) - (pos (or pos (point))) - (prop (get-text-property pos 'face)) - (prop-list (if (listp prop) prop (list prop)))) - (catch 'member - (dolist (item prop-list) - (when (memq item faces) - (throw 'member t)))))) - -(defun font-latex-forward-comment () - "Like `forward-comment' but with special provisions for docTeX mode. -In docTeX mode \"%\" at the start of a line will be treated as whitespace." - (if (eq major-mode 'doctex-mode) - ;; XXX: We should probably cater for ^^A as well. - (progn - (while (progn (if (bolp) (skip-chars-forward "%")) - (> (skip-chars-forward " \t\n") 0))) - (when (eq (char-after) ?%) - (beginning-of-line 2) - t)) - (forward-comment 1))) - -;;; Match functions - -(defvar font-latex-matched-faces nil - "List of faces corresponding to matches in match data.") - -(defun font-latex-matched-face (pos) - "Return face at position POS in `font-latex-matched-faces'." - (nth pos font-latex-matched-faces)) - -(defvar font-latex-command-with-args-default-spec nil ; "*[{" - "Default specifier for keywords without syntax description. -Set this to nil if verification of command syntax is unwanted.") - -(defvar font-latex-command-with-args-opt-arg-delims - '((?\[ . ?\]) (?< . ?>) (?\( . ?\))) - "List character pairs used as delimiters for optional arguments.") - -(defvar font-latex-syntax-error-modes '(latex-mode) - "List of modes where syntax errors in macros should be indicated.") - -(defun font-latex-match-command-with-arguments (regexp keywords face limit) - "Search for regexp command KEYWORDS[opt]{arg} before LIMIT. -Returns nil if none of KEYWORDS is found." - (setq font-latex-matched-faces nil) - (catch 'match - (while (re-search-forward regexp limit t) - (unless (font-latex-faces-present-p '(font-lock-comment-face - font-latex-verbatim-face) - (match-beginning 0)) - (let* ((beg (match-beginning 0)) - end ; Used for multiline text property. - (match-data (list beg)) - match-beg syntax-error alternative spec - error-indicator-pos - (spec-list (string-to-list - (or (cadr (assoc (match-string 1) keywords)) - font-latex-command-with-args-default-spec))) - (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments - (goto-char (match-end 0)) - ;; Check for starred macro if first spec is an asterisk or a - ;; plus sign in case of \defaultfontfeatures+ provided by - ;; fontspec.sty - (when (or (eq (car spec-list) ?*) - (eq (car spec-list) ?+)) - (setq spec-list (cdr spec-list)) - (skip-chars-forward "*+" (1+ (point)))) - ;; Add current point to match data and use keyword face for - ;; region from start to point. - (nconc match-data (list (point))) - (add-to-list 'font-latex-matched-faces 'font-lock-keyword-face) - (setq end (point)) - (catch 'break - ;; Walk the list of specs. - (while spec-list - (setq spec (pop spec-list) - error-indicator-pos beg) - (while (and (not (eobp)) (font-latex-forward-comment))) - ;; Alternative - (when (eq spec ?|) - (setq alternative t) - (setq spec (pop spec-list))) - (cond - ;; Macros: \foo - ((eq spec ?\\) - (if (eq (char-after) spec) - (progn - (nconc match-data - (list (point) - (progn - (forward-char) - (if (zerop (skip-syntax-forward "_w")) - (forward-char) ; Single-char macro. - (skip-chars-forward "*+")) - (point)))) - (nconc font-latex-matched-faces (list face)) - (setq end (max end (point))) - (when alternative (pop spec-list))) - (setq syntax-error t) - (throw 'break nil))) - ;; Mandatory arguments: {...} - ((eq spec ?{) - (if (and (eq (char-after) spec) - (setq match-beg (point)) - (font-latex-find-matching-close ?{ ?})) - (progn - (nconc match-data (list (1+ match-beg) (1- (point)))) - (nconc font-latex-matched-faces (list face)) - (setq end (max end (1- (point)))) - (when alternative (pop spec-list))) - (unless alternative - (setq syntax-error t) - (when (and match-beg (= match-beg (point))) - (setq error-indicator-pos match-beg)) - (throw 'break nil)))) - ;; Optional arguments: [...] and others - ((eq (char-after) spec) - (setq match-beg (point)) - (if (font-latex-find-matching-close - spec (cdr (assq - spec - font-latex-command-with-args-opt-arg-delims))) - (progn - (nconc match-data (list (1+ match-beg) (1- (point)))) - (nconc font-latex-matched-faces - (list 'font-lock-variable-name-face)) - (setq end (max end (1- (point))))) - (setq syntax-error t - error-indicator-pos match-beg) - (throw 'break nil)))) - (setq alternative nil))) - (when (and syntax-error (memq major-mode - font-latex-syntax-error-modes)) - ;; Add the warning face at the front of the list because - ;; the matcher uses 'append and the face would otherwise - ;; be overridden by the keyword face. - (setq match-data (append (list error-indicator-pos - (1+ error-indicator-pos)) - match-data)) - (push 'font-latex-warning-face font-latex-matched-faces)) - (store-match-data match-data) - (throw 'match t)))))) - -;; Those are dynamically bound by font-lock. -(defvar font-lock-beg) -(defvar font-lock-end) - -(defun font-latex-extend-region-backwards-command-with-args () - "Extend region backwards for commands with args." - (save-excursion - (goto-char font-lock-end) - (catch 'extend - (while (TeX-search-backward-unescaped "}" font-lock-beg t) - (let ((macro-start - (TeX-find-macro-start - (max (point-min) - (- font-lock-beg font-latex-multiline-boundary))))) - (when (and macro-start - (< macro-start font-lock-beg)) - (setq font-lock-beg macro-start) - (throw 'extend t))))))) - -(defun font-latex-match-command-in-braces (keywords limit) - "Search for command like {\\bfseries fubar} before LIMIT. -Sets `match-data' so that: - subexpression 0 is a warning indicator, - subexpression 1 is the keyword, and - subexpression 2 is the rest in the TeX group. -Return nil if no command is found." - (catch 'match - (while (re-search-forward keywords limit t) - (unless (font-latex-faces-present-p '(font-lock-comment-face - font-latex-verbatim-face) - (match-beginning 0)) - (let ((kbeg (match-beginning 0)) (kend (match-end 1)) - (beg (match-end 0)) - cbeg cend - (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments - (goto-char kbeg) - (if (not (eq (preceding-char) ?\{)) - ;; Fontify only the keyword (no argument found). - (progn - (setq cbeg kbeg cend kend) - (goto-char (match-end 0)) - (store-match-data (list (point) (point) - (point) (point) - cbeg cend)) - (throw 'match t)) - ;; There's an opening bracket - (save-restriction - ;; Restrict to LIMIT. - (narrow-to-region (point-min) limit) - (forward-char -1) ; Move on the opening bracket - (if (font-latex-find-matching-close ?\{ ?\}) - (store-match-data (list kbeg kbeg - kbeg kend - beg (1- (point)))) - (goto-char kend) - (store-match-data (list (1- kbeg) kbeg - kbeg kend - kend kend))) - (throw 'match t)))))))) - -(defun font-latex-extend-region-backwards-command-in-braces () - "Extend region backwards for commands in braces." - (save-excursion - (goto-char font-lock-end) - (catch 'extend - (while (TeX-search-backward-unescaped "}" font-lock-beg t) - (let ((group-start - (TeX-find-opening-brace - nil (max (point-min) - (- font-lock-beg font-latex-multiline-boundary))))) - (when group-start - ;; XXX: Actually we'd have to check if any of the - ;; declaration-type macros can be found right after the - ;; brace. If we don't do this (like now) large regions - ;; may be refontified for no good reason. For checking - ;; the built-in `font-latex-match-*' variables for - ;; declaration-type macros as well as the respective - ;; user-defined variables could be concatenated. - (goto-char group-start) - (when (< group-start font-lock-beg) - (setq font-lock-beg group-start) - (throw 'extend t)))))))) - -(defvar font-latex-match-simple-exclude-list - '("-" "," "/" "&" "#" "_" "`" "'" "^" "~" "=" "." "\"") - "List of characters directly after \"\\\" excluded from fontification. -Each character is a string.") - -(defvar font-latex-match-simple-include-list '("@") - "List of characters allowed in a macro for fontification. -Each character is a string. This variable is initialized to -\"@\" since internal LaTeX commands are very often redefined in a -.tex file and the fontification should work correctly in those -cases.") -(make-variable-buffer-local 'font-latex-match-simple-include-list) - -(defun font-latex-match-simple-command (limit) - "Search for command like \\foo before LIMIT." - ;; \s_ matches chars with symbol syntax, \sw chars with word syntax, - ;; \s. chars with punctuation syntax. We must exclude matches where - ;; the first character after the \ is a reserved character and - ;; should not be fontified (e.g. \, in foo\,bar or \- in foo\-bar). - ;; These characters are stored in - ;; `font-latex-match-simple-exclude-list'. In docTeX mode, we - ;; remove "_" from this list to get correct fontification for macros - ;; like `\__module_foo:nnn' - (let* ((search (lambda () - (TeX-re-search-forward-unescaped - (concat - ;; Chars directly after backslash - "\\\\\\(\\s_\\|\\sw\\|\\s.\\)" - ;; Start group of the following chars - "\\(?:[" - ;; a-zA-Z are always allowed: - "a-zA-Z" - ;; Additional characters added by AUCTeX styles - (mapconcat #'identity - font-latex-match-simple-include-list - "") - ;; End group - "]\\)*") - limit t))) - (pos (funcall search))) - (while (and pos - (member (match-string 1) - (if (eq major-mode 'doctex-mode) - (remove "_" font-latex-match-simple-exclude-list) - font-latex-match-simple-exclude-list))) - (setq pos (funcall search))) - pos)) - -(defun font-latex-match-math-env (limit) - "Match math pattern up to LIMIT. -Used for patterns like: -\\( F = ma \\) -\\=\\[ F = ma \\] but not \\\\=\\[len]" - (catch 'match - (while (re-search-forward "\\(\\\\(\\)\\|\\(\\\\\\[\\)" limit t) - (unless (save-excursion - (goto-char (match-beginning 0)) - ;; \\[ does not start a math environment - (/= (mod (skip-chars-backward "\\\\") 2) 0)) - (let ((beg (match-beginning 0)) - (open-tag (if (match-beginning 1) "\\(" "\\[")) - (close-tag (if (match-beginning 1) "\\)" "\\]"))) - ;; Search for both opening and closing tags in order to be - ;; able to avoid erroneously matching stuff like "\(foo \(bar\)". - (if (and (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*\\(" - (regexp-quote open-tag) "\\|" - (regexp-quote close-tag) "\\)") - (+ limit font-latex-multiline-boundary) - 'move) - (string= (match-string 1) close-tag)) - ;; Found closing tag. - (let ((p (point))) - (if (< font-latex--updated-region-end limit) - ;; *-extend-region-functions have extended the - ;; limit already. - (setq font-latex--updated-region-end limit)) - ;; If the closing tag is beyond the current end of - ;; region, take care of it. - (when (< font-latex--updated-region-end p) - (font-lock-unfontify-region font-latex--updated-region-end p) - (setq font-latex--updated-region-end p)) - (store-match-data (list beg beg beg p))) - ;; Did not find closing tag. - (goto-char (+ beg 2)) - (store-match-data (list beg (point) (point) (point)))) - (throw 'match t)))))) - -(require 'texmathp) -(defcustom font-latex-math-environments nil - "List of math environment names for font locking. -It is no longer recommended to customize this option. You should -customize `texmathp-tex-commands' instead because it is important -for stable operation of font lock that this option is coherent -with that option in addition to `texmathp-tex-commands-default'. -See info node `(auctex)Fontification of math' to convert your -customization into `texmathp-tex-commands'." - ;; This option is now used only through - ;; `font-latex--match-math-envII-regexp'. - :type '(repeat string) - :group 'font-latex) - -(defvar font-latex--match-math-envII-regexp nil - "Regular expression to match math environments. -Set by `font-latex--update-math-env' and used in -`font-latex-match-math-envII'.") - -(defun font-latex-update-math-env () - "Update regexp to search for math environments. -Extract environments marked as `env-on' in -`texmathp-tex-commands1' except starred variants. Then build -`font-latex--match-math-envII-regexp' from them, appending the -environments in `font-latex-math-environments'." - ;; Make sure `texmathp-tex-commands1' is up to date. - (texmathp-compile) - (let (envs) - (dolist (entry texmathp-tex-commands1) - (if (and (eq 'env-on (cadr entry)) - (not (string= "*" (substring (car entry) -1)))) - (cl-pushnew (car entry) envs :test #'equal))) - (setq font-latex--match-math-envII-regexp - (concat "\\\\begin[ \t]*{" - ;; Take user additions also into account. - (regexp-opt (append font-latex-math-environments envs) t) - ;; Subexpression 2 is used to build the \end{<env>} - ;; construct later. - "\\(\\*?}\\)" - ;; Match an optional and possible mandatory - ;; argument(s) as long as they are on the same line - ;; with no spaces in-between. The content of optional - ;; argument can span multiple lines. - "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" - "\\(?:{[^}]*}\\)*")))) - -;; Initialize. -(font-latex-update-math-env) - -(defun font-latex-match-math-envII (limit) - "Match math patterns up to LIMIT. -Used for patterns like: -\\begin{equation} - fontified stuff -\\end{equation} or -\\begin{empheq}[X=Y\\Rightarrow]{alignat=3} - fontified stuff -\\end{empheq} -The \\begin{equation} incl. arguments in the same line and -\\end{equation} are not fontified here." - (when (re-search-forward font-latex--match-math-envII-regexp limit t) - (let ((beg (match-end 0)) end - (beg-of-begin (match-beginning 0))) - (if (re-search-forward (concat "\\\\end[ \t]*{" - (regexp-quote - (buffer-substring-no-properties - (match-beginning 1) - (match-end 2)))) - (+ limit font-latex-multiline-boundary) 'move) - (progn - (setq end (match-beginning 0)) - (if (< font-latex--updated-region-end limit) - (setq font-latex--updated-region-end limit)) - (when (< font-latex--updated-region-end end) - (font-lock-unfontify-region font-latex--updated-region-end end) - (setq font-latex--updated-region-end end))) - (goto-char beg) - (setq end beg - beg-of-begin beg)) - ;; Store the position of "\begin{foo}" as (match-beginnig 0) so - ;; that `font-lock-multiline' text property covers it. This keeps - ;; editing inside multi-line optional argument sane. - (store-match-data (list beg-of-begin end beg end)) - t))) - -(defun font-latex-match-dollar-math (limit) - "Match inline math $...$ or display math $$...$$ before LIMIT." - (catch 'match - (let (beg num) - (while (font-latex-find-dollar-math limit) - ;; Found "$" which starts $...$ or $$...$$. - (setq beg (point) - ;; Go inside the math expression. - num (skip-chars-forward "$" limit)) - ;; If those are three or more consecutive $, ignore them and - ;; search again. - (if (< num 3) - (if ;; Let's find the same number of live dollar signs. - (font-latex-find-dollar-math - ;; Hope that limit+font-latex-multiline-boundary - ;; doesn't fall just inside single "$$". - (min (point-max) (+ limit font-latex-multiline-boundary)) - num) - ;; Found. - (progn - (forward-char num) - (let ((p (point))) - (if (< font-latex--updated-region-end limit) - (setq font-latex--updated-region-end limit)) - (when (< font-latex--updated-region-end p) - (font-lock-unfontify-region - font-latex--updated-region-end p) - (setq font-latex--updated-region-end p)) - (set-match-data (list beg p))) - (throw 'match t)) - ;; Not found. - ;; That $ or $$ is probably unclosed in the buffer. - (throw 'match nil))))))) - -(defun font-latex-find-dollar-math (limit &optional num) - "Find dollar sign(s) before LIMIT. -Set point just before the found $. Ignore escaped $ (\"\\$\"). -Optional argument NUM, if non-nil, specifies the number of dollar -signs to follow the point and must be 1 or 2. -LIMIT must not exceed the end of buffer." - (catch 'found - (while (progn - (skip-chars-forward "^$" limit) - (< (point) limit)) - ;; Found "$". - ;; If that "$" is not our target, skip over it and search - ;; again. - (cond - ;; check 1: Are we in a verbatim construct or comment? - ((let ((ppss (syntax-ppss))) - (or (nth 3 ppss) - ;; Ignore $ in comments... - (and (nth 4 ppss) - ;; ... except if we're looking for the end of the - ;; inline math. We need to consider this %$ - ;; comments because they are the workaround for - ;; falsely triggered math mode due to valid, - ;; non-math occurrences of $. (bug#48365) - (not num)))) - (skip-chars-forward "$" limit)) - ;; check 2: Else, is "$" escaped? - ((TeX-escaped-p) - (forward-char 1)) - ;; check 3: Else, is the number of the following "$" wrong? - ;; This check cannot precede check 2 because "$1+2\$$" is - ;; legal. - ((and (eq num 2) (not (eq (char-after (1+ (point))) ?$))) - ;; If double dollars ($$) are followed by $, skip over that $. - ;; We need not care the case that single dollar ($) is - ;; followed by $$ because expressions like "$1+1$$2+2$" and - ;; "$1+2$$$3+3$$" are legal. - (forward-char 1)) - (t - ;; That "$" is live one. - (throw 'found t)))))) - -(defun font-latex-extend-region-backwards-math () - "Extend region backwards for math environmets. -Take into account $...$, $$...$$, \\(...\\) and \\=\\[...\\], too." - ;; Use `texmathp' to identify whether the point is inside math mode. - ;; Only heuristic, but it's very difficult to identify rigorously - ;; without syntactic support. - - ;; Check if `font-lock-beg' is inside math mode. - (goto-char font-lock-beg) - - ;; Workaround bug#41522. Ensure `syntax-table' property is given to - ;; all verbatim-like constructs up to the position before running - ;; `texmathp' in order to prevent wrong fontification of verbatim - ;; face. This is necessary because `texmathp' calls `up-list' inside - ;; narrowing. - (syntax-propertize (point)) - - ;; XXX: Should we make the `texmathp' search honor - ;; `font-latex-multiline-boundary'? - (when (and (texmathp) (< (cdr texmathp-why) font-lock-beg)) - ;; Make its beginning a new start of font lock region. - (setq font-lock-beg (cdr texmathp-why)) - t)) - -(defun font-latex-sp-extend-region-backwards-verb-env (beg end) - "Extend region backwards for verbatim environments." - (let ((envs (and (fboundp 'LaTeX-verbatim-environments) - (LaTeX-verbatim-environments)))) - (when envs - (save-excursion - (goto-char end) - (catch 'extend - (while (re-search-backward - (concat "\\\\end[ \t]*{" (regexp-opt envs t) "\\*?}") beg t) - (when (and (re-search-backward - (concat "\\\\begin[ \t]*{" - (buffer-substring-no-properties - (match-beginning 1) - (match-end 0)) - ;; Match an optional and possible - ;; mandatory argument(s) - "\\(?:\\[[^][]*\\(?:\\[[^][]*\\][^][]*\\)*\\]\\)?" - "\\(?:{[^}]*}\\)*") - (- beg font-latex-multiline-boundary) t) - (< (point) beg)) - (throw 'extend (cons (point) end))))))))) - -(defun font-latex-update-quote-list () - "Update quote list and regexp if value of `font-latex-quotes' changed." - (unless (eq font-latex-quotes-control font-latex-quotes) - (setq font-latex-quotes-control font-latex-quotes) - (font-latex-quotes-set-internal) - ;; Set order of each entry in `font-latex-quote-list' according to - ;; setting of `font-latex-quotes-internal'. - (let ((tail font-latex-quote-list) - elt) - (while tail - (setq elt (car tail)) - (when (and (> (safe-length elt) 2) - (not (eq (nth 2 elt) font-latex-quotes-internal))) - (setcar tail (list (nth 1 elt) (nth 0 elt) - font-latex-quotes-internal))) - (setq tail (cdr tail)))) - (setq font-latex-quote-regexp-beg - (regexp-opt (mapcar #'car font-latex-quote-list) t)))) - -(defun font-latex-match-quotation (limit) - "Match quote patterns up to LIMIT. -Used for patterns like: -``this is a normal quote'' and these are multilingual quoted strings: -\"< french \"> and \"`german\"' quotes. -The quotes << french >> and 8-bit french are used if `font-latex-quotes' is -set to `french', and >>german<< (and 8-bit) are used if set to `german'." - (when font-latex-quotes - (font-latex-update-quote-list) - ;; Search for matches. - (catch 'match - (while (TeX-re-search-forward-unescaped - font-latex-quote-regexp-beg limit t) - (unless (font-latex-faces-present-p '(font-lock-comment-face - font-latex-verbatim-face - font-latex-math-face) - (match-beginning 0)) - (let* ((beg (match-beginning 0)) - (after-beg (match-end 0)) - (opening-quote (match-string-no-properties 0)) - (closing-quote - (nth 1 (assoc opening-quote font-latex-quote-list))) - (nest-count 0) - (point-of-surrender (+ beg font-latex-multiline-boundary))) - ;; Find closing quote taking nested quotes into account. - (while (progn - (re-search-forward - (concat opening-quote "\\|" closing-quote) - point-of-surrender 'move) - (when (and (< (point) point-of-surrender) (not (eobp))) - (if (string= (match-string-no-properties 0) - opening-quote) - (setq nest-count (1+ nest-count)) - (when (/= nest-count 0) - (setq nest-count (1- nest-count))))))) - ;; If no closing quote was found, set the second match which - ;; will be marked with warning color, if one was found, set - ;; the first match which will be marked with string color. - (if (or (= (point) point-of-surrender) (eobp)) - (progn - (goto-char after-beg) - (store-match-data (list after-beg after-beg beg after-beg))) - (let ((p (point))) - (if (< font-latex--updated-region-end limit) - (setq font-latex--updated-region-end limit)) - (when (< font-latex--updated-region-end p) - (font-lock-unfontify-region - font-latex--updated-region-end p) - (setq font-latex--updated-region-end p)) - (store-match-data (list beg p p p)))) - (throw 'match t))))))) - -(defun font-latex-extend-region-backwards-quotation () - "Extend region backwards for quotations." - (when font-latex-quotes - (font-latex-update-quote-list) - (let ((regexp-end (regexp-opt (mapcar #'cadr font-latex-quote-list) t))) - (save-excursion - (goto-char font-lock-end) - (catch 'extend - (while (re-search-backward regexp-end font-lock-beg t) - (let ((found-end (match-beginning 0)) - (closing-quote (match-string-no-properties 0)) - (nest-count 0) - (point-of-surrender (- font-lock-beg - font-latex-multiline-boundary)) - opening-quote) - (catch 'found - (dolist (elt font-latex-quote-list) - (when (string= (cadr elt) closing-quote) - (setq opening-quote (car elt)) - (throw 'found nil)))) - ;; Find opening quote taking nested quotes into account. - (while (if (re-search-backward (concat opening-quote "\\|" - closing-quote) - point-of-surrender 'move) - ;; Found quotes before point-of-surrender. - (cond ((string= (match-string-no-properties 0) - closing-quote) - ;; Encountered another closing quote. - ;; Increase nest-count and continue - ;; the inner loop. - (setq nest-count (1+ nest-count))) - ;; Found an opening quote. - ((/= nest-count 0) - ;; If in nest, decrease nest-count - ;; and continue the inner loop. - (setq nest-count (1- nest-count))) - ;; Else we arrived at the opening quote - ;; matching with the closing quote found - ;; in the outer loop. - ((< (point) font-lock-beg) - ;; If that opening quote locates - ;; before `font-lock-beg', break the - ;; outer loop and extend the region. - (setq font-lock-beg (point)) - (throw 'extend t)) - (t - ;; Else terminate the inner loop and - ;; continue the outer loop. - nil)) - ;; Didn't find quotes before - ;; point-of-surrender. - ;; Go back just before the closing quote, - ;; terminate the inner loop and - ;; continue the outer loop. - (goto-char found-end) - nil))))))))) - -(defun font-latex-match-script (limit) - "Match subscript and superscript patterns up to LIMIT." - (when (and font-latex-fontify-script - (re-search-forward "[_^] *\\([^\n\\{}]\\|\ -\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t)) - (if (and (not (memq font-latex-fontify-script '(multi-level invisible))) - (font-latex-faces-present-p '(font-latex-subscript-face - font-latex-superscript-face))) - ;; Apply subscript and superscript highlighting only once (in case - ;; font-latex-fontify-script is not 'multi-level) in order to prevent - ;; the font size becoming too small. We set an empty match to do that. - (let ((point (point))) - (store-match-data (list point point point point))) - (when (match-end 3) - (let ((beg (match-beginning 3)) - (end (TeX-find-closing-brace - ;; Don't match groups spanning more than one line - ;; in order to avoid visually wrong indentation in - ;; subsequent lines. - nil (line-end-position)))) - (store-match-data (if end - (list (match-beginning 0) end beg end) - (list beg beg beg beg)))))) - t)) - -(defun font-latex-match-script-chars (limit) - "Match subscript and superscript chars up to LIMIT." - (catch 'found - (while (re-search-forward "[^_^]\\([_^]\\)" limit t) - (let ((pos (match-beginning 1))) - (when (and (font-latex-faces-present-p 'font-latex-math-face pos) - (not (font-latex-faces-present-p '(font-lock-constant-face - font-lock-builtin-face - font-lock-comment-face - font-latex-verbatim-face) pos)) - ;; Check for backslash quoting - (not (let ((odd nil) - (pos pos)) - (while (eq (char-before pos) ?\\) - (setq pos (1- pos) odd (not odd))) - odd))) - (throw 'found t)))))) - -(defun font-latex--get-script-props (pos script-type) - (let* ((old-raise (or (plist-get (get-text-property pos 'display) 'raise) 0.0)) - (new-level (1+ (or (get-text-property pos 'script-level) 0))) - (disp-props (copy-sequence (cl-case script-type - (:super (cdr font-latex-script-display)) - (:sub (car font-latex-script-display))))) - (new-disp-props (let ((raise (plist-get disp-props 'raise)) - (nl new-level)) - (if raise - ;; This polynom approximates that the factor - ;; which is multiplied with raise is 1 for nl=1, - ;; 0.8 for nl=2, 0.64 for nl=3, etc. (so always - ;; about 80% of the previous value). - (plist-put disp-props 'raise - (+ old-raise - (* raise - (+ 1.1965254857142873 - (* nl -0.21841226666666758) - (* nl nl 0.012018514285714385))))) - disp-props)))) - `(face ,(if (<= new-level font-latex-fontify-script-max-level) - (cl-case script-type - (:super 'font-latex-superscript-face) - (:sub 'font-latex-subscript-face)) - nil) - script-level ,new-level - display ,new-disp-props))) - -;; Copy and adaption of `tex-font-lock-suscript' from tex-mode.el in -;; GNU Emacs on 2004-07-07. -(defun font-latex-script (pos) - "Return face and display spec for subscript and superscript content." - (when (and (font-latex-faces-present-p 'font-latex-math-face pos) - (not (font-latex-faces-present-p '(font-lock-constant-face - font-lock-builtin-face - font-lock-comment-face - font-latex-verbatim-face) pos)) - ;; Check for backslash quoting - (not (let ((odd nil) - (pos pos)) - (while (eq (char-before pos) ?\\) - (setq pos (1- pos) odd (not odd))) - odd))) - (if (eq (char-after pos) ?_) - (font-latex--get-script-props pos :sub) - (font-latex--get-script-props pos :super)))) - -(defun font-latex-script-char (_pos) - "Return face and display spec for subscript and superscript character at POS." - `(face font-latex-script-char-face - ,@(when (eq font-latex-fontify-script 'invisible) - '(invisible t)))) - -;;; docTeX - -(defvar font-latex-doctex-preprocessor-face - 'font-latex-doctex-preprocessor-face - "Face used to highlight preprocessor directives in docTeX mode.") - -(defface font-latex-doctex-preprocessor-face - '((t (:inherit (font-latex-doctex-documentation-face - font-lock-builtin-face ; Emacs 21 does not provide - ; the preprocessor face. - font-lock-preprocessor-face)))) - "Face used to highlight preprocessor directives in docTeX mode." - :group 'font-latex-highlighting-faces) - -(defvar font-latex-doctex-documentation-face - 'font-latex-doctex-documentation-face - "Face used to highlight the documentation in docTeX mode.") - -(defface font-latex-doctex-documentation-face - '((((class mono)) (:inverse-video t)) - (((class grayscale) (background dark)) (:background "#333")) - (((class color) (background dark)) (:background "#333")) - (t (:background "#eeeeee"))) - "Face used to highlight the documentation parts in docTeX mode." - :group 'font-latex-highlighting-faces) - -(defvar font-latex-doctex-keywords - (append '((font-latex-doctex-match-^^A 0 font-lock-comment-face t)) - font-latex-keywords-2 - '(("^%<[^>]*>" (0 font-latex-doctex-preprocessor-face t))))) - -(defun font-latex-doctex-match-^^A (limit) - "In docTeX mode, match comment started by ^^A and ^^X before LIMIT." - (catch 'found - (while (TeX-re-search-forward-unescaped "\\^\\^[AX]" limit t) - (when (eq (char-after (line-beginning-position)) ?\%) - (forward-line 1) - ;; Adjust `font-latex--updated-region-end' if necessary. - (let ((p (point))) - (if (< font-latex--updated-region-end limit) - (setq font-latex--updated-region-end limit)) - (when (< font-latex--updated-region-end p) - (font-lock-unfontify-region - font-latex--updated-region-end p) - (setq font-latex--updated-region-end p)) - ;; We assume that the above adjustment preserves match data. - (set-match-data (list (match-beginning 0) p))) - (throw 'found t))))) - -;; Copy and adaptation of `doctex-font-lock-syntactic-face-function' -;; in `tex-mode.el' of CVS Emacs (March 2004) -(defun font-latex-doctex-syntactic-face-function (state) - ;; Mark docTeX documentation, which is parsed as a style A comment - ;; starting in column 0. - (if (or (nth 3 state) (nth 7 state) - (not (memq (char-before (nth 8 state)) - '(?\n nil)))) - ;; Anything else is just as for LaTeX. - (font-latex-syntactic-face-function state) - font-latex-doctex-documentation-face)) - - -;;; Installation in non-AUCTeX LaTeX mode - -;; Here used to be some code which tried to magically make things work and -;; thereby broke other stuff. If you want to use font-latex with stock -;; latex-mode, then please just add `font-latex-setup' to `latex-mode-hook' -;; yourself. - -;;; Byte-compilation of generated functions -;; Not needed now that we generate the code via a macro. -;; (when (byte-code-function-p -;; (symbol-function 'font-latex-make-built-in-keywords)) -;; (dolist (elt font-latex-built-in-keyword-classes) -;; (let ((name (nth 0 elt))) -;; (byte-compile (intern (concat "font-latex-match-" name))) -;; (byte-compile (intern (concat "font-latex-match-" name "-make")))))) - - -;; Provide ourselves: -(provide 'font-latex) - -;; Local Variables: -;; coding: utf-8 -;; End: - -;;; font-latex.el ends here |