0

I want to replace a macro with its argument, that's to say, if I have

\newcommand{\foo}{FOO}

I want to replace every occurence of \foo with its argument FOO in a specified region.

I am trying to write a function in order to do this becasue I have to replace more than 100 macros:

(defun affil-name ()
  (interactive)

  (setq P0 (make-marker))
  (goto-char (point-min))
  (set-marker P0 (point))

  (setq P1 (make-marker))
  (goto-char (point-min))
  (search-forward "\\abstract" nil t)
  (previous-line)
  (set-marker P1 (point))

  (save-excursion
    (save-restriction
      (narrow-to-region P0 P1)

      (goto-char (point-min))

      (while (search-forward "\\newcommand" nil t)
        (setq pos1 (point-marker))
        (set-marker-insertion-type pos1 t)
        (forward-list)
        (setq pos2 (point-marker))
        (set-marker-insertion-type pos2 t)
        (forward-list)
        (setq pos3 (point-marker))
        (set-marker-insertion-type pos3 t)

        (setq cmd-name (car (extract-rectangle (+ 2 pos1) (- pos2 1))))
        (setq cmd-arg (car (extract-rectangle (+ pos2 1) (- pos3 1))))

        (perform-replace "\"cmd-name\""
                         "\"cmd-arg\"" t t nil 1 nil (point-min) (point-max))

        ))))

At the end of the loop, value of cmd-name and of cmd-arg are that of first occurence of \newcommand and there are no replacements.

  • If elisp is not compulsory here, the programme de-macro (in the texlive distribution) is yr friend. – Fran Burstall Feb 11 at 18:01
  • Do not use perform-replace. Heed what its doc string says: Don’t use this in your own program unless you want to query and set the mark just as ‘query-replace’ does. Instead, write a simple loop like this: (while (re-search-forward "foo[ \t]+bar" nil t) (replace-match "foobar" nil nil)) which will run faster and probably do exactly what you want. – NickD Feb 11 at 23:04
  • @FranBurstall de-macro works fine! – Onner Irotsab Feb 12 at 9:00
  • @NickD I generally use perform-replace becasuse I am inexpert and so I often use it with query-flag not-nil, so it asks me what to do about each replacement. replace-match does not ask anything and it does all replacements all at once (better: I do not know how to set replace-match in order to ask me what to do). – Onner Irotsab Feb 12 at 9:10

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.