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 Answer 1

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?

1
  • There is font-lock-ensure too.
    – Tom
    Commented Sep 26, 2021 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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