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 ;; Maintainer: auctex-devel@gnu.org @@ -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