1

I want to search and replace a block of text with a "query-like" approach all at once.

For example, if I have

\emph{``Foo $\bar$ baz''}

to be replaced by

\emph{Foo $\bar$ baz}

using a "query-like" approach all at once, how could I do?

I have tried something like this:

(defun foo ()
  (interactive)

  ;; \emph{``Foo''} --> \emph{Foo}
  (goto-char (point-min))
  (while (re-search-forward "\\\\emph{``" nil t)
    (save-excursion
      (let* ((pos1 (copy-marker (match-beginning 0)))
             (pos2 (copy-marker (progn
                                  (goto-char (- (match-end 0) 3))
                                  (forward-pexp)
                                  (point))))
             (text (buffer-substring-no-properties (+ pos1 8) (- pos2 3))))

        (query-replace-regexp (concat "\\\\emph{``"
                                      text
                                      "''}")
                              (concat "\\\\emph{"
                                      (regexp-quote text)
                                      "}")
                              nil pos1 pos2)))))

but it does not work if there are chars to be escaped (text could be everything, even chars to be escaped, like \ in LaTeX macro or [ ] or $...$ or other).

It works if there are no chars to be escaped.

I have just found a solution for this example with a "query-like" approach, i.e.

(query-replace-regexp "\\\\emph{``"
                      "\\\\emph{" nil pos1 pos2)

(query-replace-regexp "''}"
                      "}" nil (- pos2 3) pos2)

but it is not all at once. I would like to have only one call to query-replace-regexp.

Note

In this answer I have found a solution to be used for solving this question.

4
  • 2
    Running query-replace-regexp interactively with arguments \\emph{``\(.+\)''} → \\emph{\1} seems to do the job. – Juancho Nov 23 '20 at 15:20
  • If you're not using regexps, don't call regexp functions? query-replace vs query-replace-regexp. If you need regexps, use regexp-quote to escape special characters in the search pattern. You've actually used it in your code, but you used it on the replacement text, which almost certainly isn't what you intended. – phils Nov 24 '20 at 21:48
  • If each 'query' is for a single known region, then you could using perform-replace instead of a query-replace* function. – phils Nov 24 '20 at 21:50
  • @phils I have gone by trial and error because, unfortunately, I do not always know how to use the tools that elisp makes available. If I do not need that emacs queries me about replacements to be done, I generally use perform-replace with query-flag set to nil, otherwise I use query-replace-regexp. In this way it is easier for me to debug my scripts, each of them has thousands of lines of code: when I call a script and something breaks, I simply set query-flag from nil to t and so it is easier to find where something is wrong. – Onner Irotsab Nov 25 '20 at 13:19

Your Answer

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

Browse other questions tagged or ask your own question.