The forward-sexp
command in EMACS can be used to find the $
that closes an inline equation: if the point is before the $
that opens the equation, then forward-sexp
moves the point after the closing $
. This does the correct thing with nested equations: e.g., if the point is before $a + \text{b $c$}$
, then forward-sexp
moves the point past the entire equation. Is there a way to find the \)
or \]
that closes a \(
and \[
with auctex, perhaps with texmathp
or font-latex-match-math-env
? This seems to be a bit tricky in EMACS as there is no way to store multi-char delimiters in a syntax table.
1 Answer
I have put together a function that might do what you want. It searches for the next LaTeX math delimiter – \(
, \)
, \[
or \]
– while ignoring comments and if is an opening delimiter it tries to find its matching delimiter.
(defun forward-latex-math ()
"Move forward across the next LaTeX equation. It is meant work like `forward-sexp' but for LaTeX math delimiters."
(interactive)
(let ((count 1))
;; Search for either of the following \( \) \[ \]
(re-search-forward-ignore-TeX-comments "\\\\(\\|\\\\)\\|\\\\\\[\\|\\\\]")
(cond
;; If the search hits \(
((looking-back "\\\\(" (- (point) 2))
(while (< 0 count)
;; Search for delimiters inside the equation
(re-search-forward-ignore-TeX-comments "\\\\(\\|\\\\)")
(if (looking-back "\\\\(" (- (point) 2))
(setq count (1+ count)) ; If start of a nested level
(setq count (1- count)))) ; If end of a nested level
;; Find the matching \)
(re-search-forward "\\\\)" (eobp) t count))
;; If the search hits \[
((looking-back "\\\\\\[" (- (point) 2))
(while (< 0 count)
;; Search for delimiters inside the equation
(re-search-forward-ignore-TeX-comments "\\\\\\[\\|\\\\]")
(if (looking-back "\\\\\\[" (- (point) 2))
(setq count (1+ count)) ; If start of a nested level
(setq count (1- count)))) ; If end of a nested level
;; Find the matching \]
(re-search-forward "\\\\]" (eobp) t count)))))
(defun re-search-forward-ignore-TeX-comments (regexp)
"Search for REGEXP and ignore TeX comments. Used by `forward-latex-math'."
(re-search-forward regexp (eobp) t)
;; If in comment search to after it
(while (TeX-in-comment)
(forward-line)
(re-search-forward regexp (eobp) t)))
To use it place it in your .emacs and run it by M-xforward-latex-math
. If you want to use it often you might want to bind it to key.
Since I have just started to learn Lisp I am sure this code can improved in many ways. Please comment if you have any suggestions.
-
This doesn't deal with commented-out delimiters correctly. It's not clear to me that these delimiters can be properly matched without reimplementing LaTeX. May 13, 2012 at 17:52
-
-
This code matches
\( % \)
as a single unit, but it shouldn't; it should continue searching on the next line to find the closing\)
. May 13, 2012 at 18:12 -
@SamuelIsaacson I have updated the function to ignore comments. Let me know if it does not work as you want.– N.N.May 15, 2012 at 15:44
$
...$
, as opposed to\(
...\)
, is reliably robust in macro arguments and when written to files (i.e., table of contents), and\begin{equation*}
...\end{equation*}
(using amsmath package) is quite better visible.\(
and\)
preferable to$
?\(
\)
\[
\]
. The theoretic gain of matched delimiters is not worth the price in editing support and loss of robustness in LaTeX.fixltx2e
which redefines them as robust.$
in LaTeX. I have some macros to quickly switch equations between inline and displayed that make critical use offorward-sexp
.