Using \expandafter for macro redefinitions

Sometimes I want to redefine a macro of a class or package but want to use its original definition. Instead of copy&paste one could use the original macro directly:

  1. come up with a new macro, ensure that it’s not defined yet,
  2. save the definition of the original macro to the new macro,
  3. redefine the original macro using the new macro with the saved original code,

I will give a very simple example for a demonstration. Today a LaTeX Community member said that he’s using the quote environment but wants the enclosed text to have a smaller size. A straightforward solution is to use \renewenvironment copying the original code, let’s say from article.cls, and to make a small modification:

\renewenvironment{quote}
  {\list{}{\rightmargin\leftmargin}%
   \item\relax\small}
  {\endlist}

Just the \small was added. This solution needs the writer to examine the class source, that may also be changed later.

The second solution is the method I’ve described above:

\newcommand*\origquote{}
\let\origquote\quote
\renewcommand*\quote{\origquote\small}

The \newcommand line may be omitted, I’ve just used it to ensure that an error would be raised if a macro with that name was already defined by somehing else.
The last code works like the first solution, but respects the original class code and it will also respect further changes of the class, therefore I’m preferring it.

But the third solution is similar, shorter and doesn’t need the creation of another macro. It’s doing the same job but uses the original macro directly, avoiding a recursion problem by using \expandafter:

\expandafter\def\expandafter\quote\expandafter{\quote\small}

You can find the same method applied in my comment to a previous blog post.

If you want to know how expandafter works you will find explanations in TeX books and documentations. Further there’s an extensive tutorial by Stephan v. Bechtolsheim (TUGboat, Volume 9, 1988), old but still valid of course.

This topic was discussed in the LaTeX Community Forum and on Matheplanet.com.

26. October 2008 by stefan
Categories: Uncategorized | 4 comments

Comments (4)

  1. There’s another and “simpler” solution:

    g@addto@macroquotesmall

    which essentially does the same as the one liner with the three expandafter’s; of course it must be surrounded by makeatletter and makeatother, but the number of tokens is still smaller. :)

  2. Hi Enrico,

    thank you for informing about this useful macro. It can be used for the same purpose, but there’s still a difference: g@addto@macro works globally, the expandafter solution can be used locally. You could limit the scope of the that redefiniton by begingroup … endgroup or just by an environment. The macro would be the original one outside of the environment of the scope.

    Stefan

  3. Pingback: Removing Space Around Math Equations « LaTeXamples

  4. Pingback: Birkenstock 37

Leave a Reply

Required fields are marked *