[Tex/LaTex] Emacs and latex math delimiters

auctexemacsmath-mode

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.

Best 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.

Related Question