1

I need to perform this kind of (query-)substitutions in LaTeX code:

"fig" --> "figure"

But I don't want to match text inside commands e.g. \label{fig:1} or \includegraphics[width=2cm]{fig/D.pdf}.

I figured out to use face properties to select the strings to be replaced and I wrote this piece of code

(goto-char (point-min)
(while (search-forward-regexp "\\<\\([Ff]ig\\)\\(s?\\)\\>\\.?" nil t)
  (save-excursion
    (let ((b (make-marker))
      (e (make-marker)))
      (set-marker b (match-beginning 0))
      (set-marker e (point))
      (goto-char b)
      (font-lock-fontify-buffer)
      (let* ((face 'query-replace)
         (bg (face-background face)))
    (set-face-background face "OliveDrab3")
    (unwind-protect
        (unless (or (string= (face-at-point) "font-lock-constant-face")
            (string= (face-at-point) "font-lock-builtin-face"))

          (perform-replace "\\<\\([Ff]ig\\)\\(s?\\)\\>\\.?"
                   "\\1ure\\2" t t nil 1 nil b e))
      (set-face-background face bg)))
)))

It works quite well but fails if I run it at the file opening. It seems that emacs needs to scan the buffer in some way I don't understand.

I tried to put (font-lock-fontify-buffer) at the beginning of the script but it doesn't work.

1 - How can I force emacs to fontify the whole buffer before running my code?

2 - Any (tested) idea to achieve the same result with some other technique?

1

I want to answer my own question because I've just found that the redisplay command seems to solve my problem. I want to share my solution:

(goto-char (point-min)
(while (search-forward-regexp "\\<\\([Ff]ig\\)\\(s?\\)\\>\\.?" nil t)
  (save-excursion
    (let ((b (make-marker))
      (e (make-marker)))
      (set-marker b (match-beginning 0))
      (set-marker e (point))
      (goto-char b)
      (redisplay t)
      (let* ((face 'query-replace)
         (bg (face-background face)))
    (set-face-background face "OliveDrab3")
    (unwind-protect
        (unless (or (string= (face-at-point) "font-lock-constant-face")
            (string= (face-at-point) "font-lock-builtin-face"))

          (perform-replace "\\<\\([Ff]ig\\)\\(s?\\)\\>\\.?"
                   "\\1ure\\2" t t nil 1 nil b e))
      (set-face-background face bg)))
)))

Any comment about it? Is it a bad idea?

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.