branch: main commit d39d66abbd1eb79c8b995850614405e6468b943e Merge: 4b8d775f 66549552 Author: Tassilo Horn <t...@gnu.org> Commit: Tassilo Horn <t...@gnu.org>
Merge remote-tracking branch 'origin/master' into externals/auctex --- font-latex.el | 131 +++++++++++++++++++++++++++++++++++++++++++++++++--------- texmathp.el | 4 +- 2 files changed, 113 insertions(+), 22 deletions(-) diff --git a/font-latex.el b/font-latex.el index 91137bac..a7076162 100644 --- a/font-latex.el +++ b/font-latex.el @@ -833,7 +833,7 @@ Generated by `font-latex-make-user-keywords'."))) ;; Add the "fixed" matchers and highlighters. (dolist (item '(("\\(^\\|[^\\]\\)\\(&+\\)" 2 'font-latex-warning-face) - ("\\$\\$\\([^$]+\\)\\$\\$" 1 'font-latex-math-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)) @@ -1057,24 +1057,10 @@ have changed." ;;; Syntactic fontification -;; Copy and adaptation of `tex-font-lock-syntactic-face-function' in -;; `tex-mode.el' of CVS Emacs (March 2004) (defun font-latex-syntactic-face-function (state) - (let ((char (nth 3 state))) - (cond - ((not char) 'font-lock-comment-face) - ((eq char ?$) 'font-latex-math-face) - (t - (when (characterp char) - ;; This is a \verb?...? construct. Let's find the end and mark it. - (save-excursion - (skip-chars-forward (string ?^ char)) ;; Use `end' ? - (when (eq (char-syntax (preceding-char)) ?/) - (put-text-property (1- (point)) (point) 'syntax-table '(1))) - (unless (eobp) - (put-text-property (point) (1+ (point)) 'syntax-table '(7))))) - 'font-latex-verbatim-face)))) - + (if (nth 3 state) + 'font-latex-verbatim-face + 'font-lock-comment-face)) ;;; Faces @@ -1225,7 +1211,7 @@ have changed." (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")) + '((?\( . ".") (?\) . ".") (?@ . "w")) "List of specifiers for the syntax alist of `font-lock-defaults'.") (defun font-latex-add-to-syntax-alist (list) @@ -1277,7 +1263,8 @@ triggers Font Lock to recognize the change." font-latex-extend-region-backwards-command-in-braces font-latex-extend-region-backwards-quotation font-latex-extend-region-backwards-math-env - font-latex-extend-region-backwards-math-envII) + font-latex-extend-region-backwards-math-envII + font-latex-extend-region-backwards-dollar-math) (syntax-propertize-function . font-latex-syntax-propertize-function) (syntax-propertize-extend-region-functions @@ -1819,6 +1806,110 @@ The \\begin{equation} incl. arguments in the same line and (setq font-lock-beg (point)) (throw 'extend t)))))) +(defun font-latex-match-dollar-math (limit) + "Match inline math $...$ or display math $$...$$ before LIMIT." + (if (font-latex-find-dollar-math limit) + ;; Found "$" which starts $...$ or $$...$$. + (let ((beg (point)) + ;; Go inside the math expression. + (num (skip-chars-forward "$" limit))) + (if (< num 3) + (if ;; Let's find the same number of live dollar signs. + (font-latex-find-dollar-math limit num) + ;; Found. + (progn + (forward-char num) + (set-match-data (list beg (point))) + t) + ;; Not found. It means that there was opening "$" or + ;; "$$", but we can't find the corresponding close tag + ;; until LIMIT. Then it is either + ;; (1) The math expression continues to the next line, or + ;; (2) The buffer has unclosed "$" or "$$". + ;; Regard the former case as a positive match because + ;; experiments tends to imply that's more robust despite + ;; of frequent false positives produced during editing. + ;; N.B. It is ensured that LIMIT doesn't fall just + ;; inside single "$$" because + ;; `font-lock-extend-region-functions' takes care of it. + (unless (eobp) + (set-match-data (list beg (point))) + t)))))) + +(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." + (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? + ((nth 3 (syntax-ppss)) + (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)) + ;; (Quote from bug#19589, with a bit of adaptation) + ;; + ;; > When I use environment variables (such as $HOME) in a .tex + ;; > file, the $ triggers math mode syntax highlighting. The + ;; > result is that the rest of the buffer, until the next $, + ;; > is highlighted as if it were in math mode. Some examples: + ;; > \includegraphics{$HOME/path/to/graphic} + ;; > \bibliography{$HOME/path/to/bib} + ;; + ;; In order to spare work around of adding "%$" at the end of + ;; the lines for such cases, we stay away from the next syntax + ;; state check. + ;; ;; check 3: Else, is "$" in comments or verb-like construct? + ;; ((nth 8 (syntax-ppss)) + ;; (skip-chars-forward "$" limit)) + (t + ;; That "$" is live one. + (throw 'found t)))))) + +(require 'texmathp) +;; FIXME: Big overhead here. We can obviously unify +;; `font-latex-extend-region-backwards-math-env' and +;; `font-latex-extend-region-backwards-math-envII' into +;; this function. +(defun font-latex-extend-region-backwards-dollar-math () + "Extend region backwards for math inside $...$ or $$...$$." + ;; Use `texmathp' to identify whether the point is inside $...$ or + ;; $$...$$. Only heuristic, but it's very difficult to identify + ;; rigorously without syntactic support. + + ;; Check if `font-lock-beg' is inside "$...$" or "$$...$$". + (goto-char font-lock-beg) + + ;; Work around 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)) + + (when (and (texmathp) (< (cdr texmathp-why) font-lock-beg) + (member (car texmathp-why) '("$" "$$"))) + ;; 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) diff --git a/texmathp.el b/texmathp.el index 723623bc..3beac2e6 100644 --- a/texmathp.el +++ b/texmathp.el @@ -185,10 +185,10 @@ customize (customize calls it when setting the variable)." ((memq type '(sw-toggle)) 'togglers))) (set var (cons (car entry) (symbol-value var)))) (setq texmathp-onoff-regexp - (concat "\\(?:[^\\\\]\\|\\`\\)" + (concat "\\(?:[^\\]\\|\\`\\)" (regexp-opt switches t)) texmathp-toggle-regexp - (concat "\\([^\\\\\\$]\\|\\`\\)" + (concat "\\([^\\$]\\|\\`\\)" (regexp-opt togglers t))))) (defcustom texmathp-tex-commands nil