Question

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!

Was it helpful?

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.

OTHER TIPS

Vlad give you the LaTeX answer to your problem. An Emacs solution is the key-macro: start with

C-x (

to define a new macro, then do one step of your change, say:

C-s \ind{
<left>ex

Then copy and paste the argument in the \textbf macro... You have to be careful to move in a way that will be repeatable. Once the standard modification is done, you let the cursor after the whatever by default and end the definition by

C-x )

now C-x e will call the macro you just define, letting your cursor at the correct place to change the part you want to change You can also repeat the e to call the macro several time at once.

Why not just redefine the \ind so that it can get an optional argument?

For example:

\newcommand{\ind}[2][]{%
  \def\first{#1}%
  \ifx\first\empty
     \textbf{#2}\index{#2}%
  \else
     \textbf{#2}\index{#1}%
  \fi
}

This way you can use \ind{whatever} or \ind[whatever-else]{whatever}.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top