Subject: bug#78587: [PATCH] TeX-find-macro-end

From: Arash Esbati <[email-masked]>
Date: Wed, 28 May 2025 23:53:00 +0200

Hi Paul,

"Paul D. Nelson" <[email-masked]> writes:

> Thanks, that suggestion is helpful, and seems to take care of the issue
> you noted.

Great, glad it helped.

> Please find attached an updated patch, to which I also added a test.

Thanks, I have 2 minor question below.

> From 65906577241bda8d7321d0ef33f0808944d06bed Mon Sep 17 00:00:00 2001
> From: Paul Nelson <[email-masked]>
> Date: Sun, 25 May 2025 17:11:49 +0200
> Subject: [PATCH] Fix TeX macro end detection in some edge cases
>
> * tex.el (TeX-find-macro-end-helper): Use
> TeX-search-syntax-table with square brackets when calling
> forward-sexp.  This fixes parsing of optional arguments
> containing other unmatched delimiters, such as
> \begin{enumerate}[a)], where the search would stop at ')'
> instead of ']'.  We take further care to treat examples like
> \begin{enumerate}[a{]}].
>
> * tests/latex/latex-test.el
> (TeX-find-macro-end-with-complicated-optional-args): New test
> concerning the above issue.
> ---
>  tests/latex/latex-test.el | 13 +++++++++++++
>  tex.el                    | 16 +++++++++++++---
>  2 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/tests/latex/latex-test.el b/tests/latex/latex-test.el
> index b68ea3b8..92b7c530 100644
> --- a/tests/latex/latex-test.el
> +++ b/tests/latex/latex-test.el
> @@ -761,4 +761,17 @@ check the indentation for optional argument of \\usepackage."
>                 (buffer-string)
>                 "sab\n")))))
>  
> +(ert-deftest TeX-find-macro-end-with-complicated-optional-args ()
> +  "Check that end of macro is determined correctly."
> +  ;; (bug#78587)
> +  (dolist (str '("\begin{enumerate}[a]"
> +                 "\begin{enumerate}[(a)]"
> +                 "\begin{enumerate}[a)]"
> +                 "\begin{enumerate}[a{]}]"))
> +    (with-temp-buffer
> +      (insert str)
> +      (LaTeX-mode)
> +      (should (equal (point-max)
> +                     (TeX-find-macro-end-helper (point-min)))))))
> +
>  ;;; latex-test.el ends here
> diff --git a/tex.el b/tex.el
> index e90252d8..62fc217b 100644
> --- a/tex.el
> +++ b/tex.el
> @@ -5866,9 +5866,19 @@ those will be considered part of it."
>                         (forward-line 1)
>                         (looking-at "[ \t]*\\(\\[\\)"))))
>              (goto-char (match-beginning 1))
> -            (condition-case nil
> -                (forward-sexp)
> -              (scan-error (throw 'found (point)))))
> +            (goto-char (match-beginning 1))
> +            ;; Imitate `font-latex-find-matching-close', motivated by
> +            ;; examples like \begin{enumerate}[a{]}].
> +            (let* ((syntax (TeX-search-syntax-table ?\[ ?\]))

Why do you need `let*' here?  `let' seems to do the job, or am I missing
something?

> +                   (parse-sexp-ignore-comments
> +                    (not (eq major-mode 'docTeX-mode))))

Can we do (not (derived-mode-p 'docTeX-mode))?

Let me know what you think about the above, I can add them when I
install the patch.

Best, Arash