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 :
- Go through the text, look for any instance of
\ind{
and replace by\textbf{
usingsearch-and-replace
- Save the argument of
\ind
("whatever" in this case) in memory - 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. - Write down
\开发者_C百科index{
, the new argument and}
. - 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!
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.
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}
.
精彩评论