emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/auctex 6654955 2/3: Use search-based fontification for


From: Tassilo Horn
Subject: [elpa] externals/auctex 6654955 2/3: Use search-based fontification for $...$ (bug#33139)
Date: Tue, 2 Jun 2020 13:56:41 -0400 (EDT)

branch: externals/auctex
commit 6654955216a42936b87f76dc346aad829b1d52fb
Author: Ikumi Keita <ikumi@ikumi.que.jp>
Commit: Ikumi Keita <ikumi@ikumi.que.jp>

    Use search-based fontification for $...$ (bug#33139)
    
    It turned out that using "text quotes" syntax for "$" in
    `font-lock-syntax-table' sometimes leads to scrambled fontification
    about in-line math $...$ (bug#33139). That's because conflicting
    results of `syntax-ppss' are compiled into syntax-ppss cache as
    explained in:
    https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg02725.html
    We, Keita, Tassilo and Arash discussed this issue and decided to use
    search-based fontification for $...$ since syntactic fontification for
    $...$ doesn't seem prospective with regard to this bug.
    
    * font-latex.el (font-latex-match-dollar-math):
    
(font-latex-find-dollar-math,font-latex-extend-region-backwards-dollar-math):
    New functions to do search-based fontification for $...$.
    Fontification facility for $$...$$ is merged into them.
    (font-latex-make-user-keywords,font-latex-setup): Use new functions.
    (font-latex-syntax-alist): Don't change syntax of "$" during font lock.
    (font-latex-syntactic-face-function): Simplify.
---
 font-latex.el | 131 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 111 insertions(+), 20 deletions(-)

diff --git a/font-latex.el b/font-latex.el
index 91137ba..a707616 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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]