Hi Keita,

Ikumi Keita <[email protected]> writes:

> It turned out that the following piece of code in font-latex-test.el is
> the culprit:
> (define-advice LaTeX-common-initialization (:after ())
>   (font-lock-ensure))
>
> Due to this advice, syntax propertization runs before
> `font-latex-syntactic-keywords-extra' is ready, so emacs thinks that
> "Syntax propertization is already done." and doesn't apply the updated
> contents of `font-latex-syntactic-keywords-extra'.

Thanks for looking at this.

> We can circumvent this situation by inserting
>       (syntax-ppss-flush-cache (point-min))
> between
>       (TeX-update-style t)
> and
>       (font-lock-ensure)
> in `font-latex-shortvrb-chars' in font-latex-test.el.

I played with `font-lock-flush' but `syntax-ppss-flush-cache' is the
correct one.

> (In a longer term perspective, we should factor out the syntax
> propertization facility out of font-latex.el and implement it as a major
> mode functionality in order to avoid these gotchas due to involvement of
> syntax propertization and font lock.)

IIRC this issue has popped up before, right?

> By the way, I think these syntax table codes in shortvrb.el are no
> longer necessary, aren't they?
>    ;; Syntax
>    (when LaTeX-shortvrb-chars
>      (let ((st (make-syntax-table (syntax-table))))
>        (dolist (c LaTeX-shortvrb-chars)
>          (modify-syntax-entry c "\"" st))
>        (set-syntax-table st)))

Yes, I removed that bit.  The current change is attached.  I will
install it in a day or two if there is no other comment.  Again, thanks
for your help.

Best, Arash
diff --git a/style/shortvrb.el b/style/shortvrb.el
index e6de0608..405ab6f2 100644
--- a/style/shortvrb.el
+++ b/style/shortvrb.el
@@ -1,6 +1,6 @@
 ;;; shortvrb.el --- AUCTeX style for `shortvrb.sty'  -*- lexical-binding: t; -*-
 
-;; Copyright (C) 2009--2022 Free Software Foundation, Inc.
+;; Copyright (C) 2009--2023 Free Software Foundation, Inc.
 
 ;; Author: Ralf Angeli <[email protected]>
 ;; Maintainer: [email protected]
@@ -45,12 +45,11 @@
 (require 'tex-style)
 
 ;; Silence the compiler:
-(declare-function font-latex-add-to-syntax-alist
-                  "font-latex"
-                  (list))
+(declare-function font-latex-set-syntactic-keywords
+                  "font-latex" ())
 (declare-function font-latex-add-keywords
-                  "font-latex"
-                  (keywords class))
+                  "font-latex" (keywords class))
+(defvar font-latex-syntactic-keywords-extra)
 
 (TeX-add-style-hook
  "shortvrb"
@@ -69,26 +68,28 @@
                   (cons str str)))
               LaTeX-shortvrb-chars)))
 
-   ;; Syntax
-   ;; N.B. This doesn't handle backslash just before the closing
-   ;; delimiter like |xyz\| correctly.  We hope we can live with that.
-   (when LaTeX-shortvrb-chars
-     (let ((st (make-syntax-table (syntax-table))))
-       (dolist (c LaTeX-shortvrb-chars)
-         (modify-syntax-entry c "\"" st))
-       (set-syntax-table st)))
-
    ;; Fontification
-   (when (and LaTeX-shortvrb-chars
-              (featurep 'font-latex)
+   (when (and (featurep 'font-latex)
               (eq TeX-install-font-lock 'font-latex-setup))
-     (font-latex-add-to-syntax-alist
-      (mapcar (lambda (char) (cons char "\""))
-              LaTeX-shortvrb-chars))
-
      (font-latex-add-keywords '(("MakeShortVerb"   "*{")
                                 ("DeleteShortVerb" "{"))
-                              'function)))
+                              'function)
+
+     ;; Use `font-latex-syntactic-keywords-extra' instead of
+     ;; `font-latex-add-to-syntax-alist' so we can catch a backslash
+     ;; within the shortvrb delimiters and make things like |xyz\|
+     ;; work correctly:
+     (when LaTeX-shortvrb-chars
+       (dolist (c LaTeX-shortvrb-chars)
+         (let ((s (char-to-string c)))
+           (add-to-list 'font-latex-syntactic-keywords-extra
+                        `(,(concat "\\(" s "\\)"
+                                   ".*?"
+                                   "\\(" (regexp-quote TeX-esc) "*\\)"
+                                   "\\(" s "\\)")
+                          (1 "\"") (2 ".") (3 "\"")))))
+       ;; Tell font-lock about the update
+       (font-latex-set-syntactic-keywords))))
  TeX-dialect)
 
 ;;; shortvrb.el ends here
diff --git a/tests/latex/font-latex-test.el b/tests/latex/font-latex-test.el
index 0c81392a..7ec3d6df 100644
--- a/tests/latex/font-latex-test.el
+++ b/tests/latex/font-latex-test.el
@@ -350,4 +350,59 @@ x
       (should (font-latex-faces-present-p 'font-lock-function-name-face
                                           (match-end 0)))  )))
 
+(ert-deftest font-latex-shortvrb-chars ()
+  "Test fontification within delimiters defined by `LaTeX-shortvrb-chars'."
+  (with-temp-buffer
+    (let ((TeX-install-font-lock #'font-latex-setup)
+          (LaTeX-shortvrb-chars '(?| ?\"))
+          (TeX-parse-self t))
+      (insert "\
+\\documentclass{article}
+\\usepackage{shortvrb}
+\\begin{document}
+foo |xyz\\| bar
+foo \"xyz\\\" bar
+\\end{document}")
+      (LaTeX-mode)
+      (TeX-update-style t)
+      ;; See https://lists.gnu.org/archive/html/auctex-devel/2023-04/msg00011.html
+      (syntax-ppss-flush-cache (point-min))
+      (font-lock-ensure)
+      (goto-char (point-min))
+      (re-search-forward "^f" nil t)
+      (should-not (get-text-property (point) 'face))
+      (search-forward "|" nil t)
+      ;; This is the `|' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (1- (point))))
+      ;; This is the `x' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face))
+      (search-forward "|" nil t)
+      ;; This is the `\' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (- (point) 2)))
+      ;; This is the `|' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (1- (point))))
+      (search-forward "ba" nil t)
+      (should-not (get-text-property (point) 'face))
+
+      (re-search-forward "^f" nil t)
+      (should-not (get-text-property (point) 'face))
+      (search-forward "\"" nil t)
+      ;; This is the `"' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (1- (point))))
+      ;; This is the `x' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face))
+      (search-forward "\"" nil t)
+      ;; This is the `\' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (- (point) 2)))
+      ;; This is the `"' char:
+      (should (font-latex-faces-present-p 'font-latex-verbatim-face
+                                          (1- (point))))
+      (search-forward "ba" nil t)
+      (should-not (get-text-property (point) 'face)))))
+
 ;;; font-latex-test.el ends here

Reply via email to