0

I tried to use texmathp with iserch-filter-predicate to let query-replace function skipping maths in my LaTeX code.

I wrote this code:

(defun skip-math (beg end)
  "Return nil if some text BEG to END is a LaTeX maths environment or in in-line maths."
  (require 'texmathp)
  (catch 'skip-region
    (let ((pos  beg))
      (while (< pos end)
        (when (texmathp) (throw 'skip-region nil))
        (setq pos  (1+ pos))))
    t))

(defmacro with-query-replace-skip-math (&rest body)
  "Makes search-* and query-seplace* commands in BODY skip LaTeX maths strings."
  (declare (indent 1))
  `(let ((isearch-filter-predicate 'skip-math)) 
     ,@body))


(defun foo-to-bar ()
  (interactive)
  (with-query-replace-skip-math
      (query-replace-regexp "foo" 
                "bar" nil (point-min) (point-max))))

I tested on:

%% bar foo

foo

\begin{equation}
foo
\end{equation}

foo $ foo $

bar $$ foo $$ foo

\begin{displaymath}
foo
\end{displaymath}

%% foo

bar %% foo bar foo

It works but the query-replace match highlighting is broken:

enter image description here

How can I fix this?

  • You don't show skip-math-and-comments. You show only skip-math. – Drew Mar 5 at 18:13
  • texmathp doesn't seem to depend on a position (doesn't accept one as arg). What's the point of iterating from beg to end in that case? Do you perhaps need to move to pos? (But you say it works, other than the highlighting problem.) – Drew Mar 5 at 18:16
  • Do you see the same problem if you use a different predicate or is this somehow specific to using texmathp? – Drew Mar 5 at 18:18
  • @Drew, sorry is a typo. – Gabriele Nicolardi Mar 5 at 18:18
  • Googling for texmathp... Its doc string says "Determine if point is inside (La)TeX math mode." So it sounds like your filter predicate needs to move point to each position pos, to test that position. E.g., (goto-char (setq pos...)). – Drew Mar 5 at 18:21
0

I found that the texmathp function alters the match-data so I solved wrapping the while loop in my function (modified following Drew's suggestions) with the save-match-data macro:

(defun skip-math (beg end)
  "Return nil if some text BEG to END is a LaTeX maths environment or in in-line maths."
  (require 'texmathp)
  (catch 'skip-region
    (let ((pos  beg))      
      (save-excursion
        (save-match-data
          (goto-char pos)
          (while (< pos end)
            (when (texmathp) (throw 'skip-region nil))
            (goto-char (setq pos  (1+ pos)))))
        t))))

(defun foo-to-bar ()
  (interactive)
  (let ((isearch-filter-predicate 'skip-math))
    (query-replace-regexp "foo" 
                          "bar" nil (point-min) (point-max))))

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.