[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)