Search code examples
emacslatexauctex

How can I modify emacs' Search and Replace to perform a more complicated task?


total Emacs noob here. So right now I'm working on a fairly big LaTeX project in Emacs in which there are couple of places where I need to index some words, using the makeidx package. Because I also wanted indexed words to be bold, I created my own command \ind{} which would make the argument go bold and indexed. But right now I'm dissatisifed with this command so I'd like to change every instance of \ind{whatever} in my text by \textbf{whatever}\index{whatever by default}.

The thing is I know exactly what I want :

  1. Go through the text, look for any instance of \ind{ and replace by \textbf{ using search-and-replace
  2. Save the argument of \ind ("whatever" in this case) in memory
  3. Ask me the user what should the argument of \index be. By default (by striking enter), it should be the first argument, but I can also change my mind and enter something different ("whatever by default" in this case). If there's no input (only a space " " for example) stop the program.
  4. Write down \index{, the new argument and }.
  5. Go to next occurance in the text.

But, alas!, I know not how to achieve this, so I need someone's help. If it should take too much time to explain how to do such a thing, would you please send me some tutorial about writing my own functions?

I hope I'm being clear, and thanks for your patience!


Solution

  • This approach seems vaguely unorthodox to me, but it works and seems sufficient for a one-off job...

    In the replacement text for replace-regexp and query-replace-regexp (C-M-%), one newer escape sequence is \,(...), where ... can be any Lisp expression. There's a Lisp function read-from-minibuffer which reads arbitrary text typed by the user, with an optional default. Therefore:

    C-M-%: Start query-replace-regexp.

    \\ind{\([^}]+?\)}: The pattern to search for.

    \\textbf{\1}\\index{\,(read-from-minibuffer "index content? " \1)}: The replacement text. The user will be prompted for the text to put in the braces following the \index{} element, using the original text between the braces following the \ind{} element as a default.

    Note that when using query-replace-regexp, you'll have to confirm each choice by typing y after each. Use M-x replace-regexp if you want to avoid this step.