Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'd like to "add to" an existing command by writing something like

\renewcommand{\somecommand}{\begin{something}\somecommand\end{something}}

but (not surprisingly) I get errors about being "too deeply nested".

Is there a way to take an existing command, add to it (by appending or prepending additional commands or text), and then have that "augmented" command replace the existing command?

share|improve this question
6  
You may also want to look at the etoolbox package. –  mbork Mar 9 '12 at 6:55
add comment

3 Answers

up vote 22 down vote accepted

You can use \let to save a command under another name, and then use that new name in the \renewcommand.

\documentclass{article}

\let\oldemph\emph
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}

\begin{document}
\oldemph{Old emph}
\emph{New emph}
\end{document}

(Edit: the TeX FAQ has much more information about "patching" commands. Edit2: egreg's answer below describes some of the gotchas of \let)

share|improve this answer
add comment

While something such as

\let\oldemph\emph
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}

seems to work, it really doesn't, because \emph is defined with \DeclareRobustCommand. Where doesn't it work? suppose you write that code and then use \emph in a caption:

\caption{This is \emph{emphasized}}

what is written in the .aux file is

\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces This is \textbf  {\emph  {emphasized}}}}{1}}

This is because the original expansion of \emph is

\protect\emph§

(where with § I'm denoting a space in the name). So the \emph{emphasized} in the caption gets expanded successively into

\textbf{\oldemph{emphasized}}
\protect\textbf§{\protect\emph§{emphasized}}
\textbf§{\emph§{emphasized}

and written as

\textbf  {\emph  {emphasized}}

(because TeX adds a space after a command name when writing). In this case, when reading the file for building the List of Figures or Tables, TeX will find

\textbf{\textbf{\oldemph{emphasized}}}

which is innocuous. But it's not very difficult to imagine situations where this can lead to infinite loops.

The package letltxmacro prevents this problem:

\usepackage{letltxmacro}
\LetLtxMacro{\oldemph}{\emph}
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}

would be a safer way to proceed.

Never use \let on commands defined with \DeclareRobustCommand or commands defined with \newcommand and having an optional argument.

The former can be recognized by the fact that \show\command returns

> \command=macro:
->\protect \command  .

The latter are distinguished by the fact that \show\command returns

> \command=macro:
->\@protected@testopt \command \\command {...}.

(where ... is actually the default for the optional argument).

share|improve this answer
    
Haha, I picked a perfect bad example! (Thanks for explaining the mistake!) –  dbaupp Mar 9 '12 at 10:34
add comment

Yes, this is possible using \g@addto@macro or some expanded definition (using \expandafter). Here are some examples:

enter image description here

\documentclass{article}
\setlength{\parindent}{0pt}% Just for this example
\begin{document}
\newcommand{\somecmd}{some \textbf{text}}
\somecmd \par
\makeatletter
\g@addto@macro\somecmd{ and some \textit{more} text}
\makeatother
\somecmd

\renewcommand{\somecmd}{some \textbf{text}}
\somecmd \par
\makeatletter
\expandafter\def\expandafter\somecmd\expandafter{\somecmd{} and some \textit{more} text}
\makeatother
\somecmd
\end{document}

The latter example, just like the former, appends contents to a macro. The placement of \somecmd in the latter could be used to prepend something.

However, nothing prevents you from making a new command that includes the old command as part of its expansion, since memory problems tend to be a thing of the past.

You run into problems when the contents of the newly-defined macro does not expand properly. Using your case as an example: although \somecommand may expand as expected, the center environment does not.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.