19

The following code works:

\def \robble {robble}
\def \robbles {\robble\robble}

But the following but doesn't:

\def \robbles {robble}
\def \robbles {\robbles robble}

The overall goal is to get robbles to be robblerobble. I need something like the second example, where I am appending on to the current value of a variable. The way it is written right now causes a stack overflow. Is there a way to append to variables in LaTeX?

lockstep
  • 250,273
knpwrs
  • 1,485

3 Answers3

22

You need to expand the \robbles macro in your second macro definition, otherwise you'll get a circular reference (\robbles calls \robbles which in turn calls \robbles). You can do that by saying

\def\robbles{robble}
\edef\robbles{\robbles robble}

where the \edef stands for expanded definition. This will expand the macros in the definition completely, until there's only unexpandable tokens left. That's fine in this case, because the contents of \robbles were only unexpandable tokens to begin with.

But if you initially defined \robbles to contain a macro, you would only want to expand \robbles once in the new definition. To do that, you can use \unexpanded\expandafter{\robbles} in the macro definition:

Compare:

\documentclass{article}

\begin{document}

\def\robble{robble}
\def\robbles{\robble} % \robbles contains the macro \robble
\edef\robbles{\robbles robble}

\robbles    % Will print "robblerobble"

\def\robble{ROBBLE} % We're redefining the macro used in the original definition

\robbles % Will still print "robblerobble", because we completely expanded \robble in the definition of \robbles

% Let's try again

\def\robble{robble}
\def\robbles{\robble} % \robbles contains the macro \robble
\edef\robbles{\unexpanded\expandafter{\robbles}robble}

\robbles    % Will print "robblerobble"

\def\robble{ROBBLES} % We're redefining the macro used in the original definition

\robbles % Will print "ROBBLErobble", because we only expanded \robbles once in the definition of \robbles
\end{document}
Jake
  • 232,450
  • 2
    Better use \unexpanded\expandafter{\rubble} than \expandafter\noexpand\rubble if eTeX is available (always). This covers the case where \rubble expands to more than just one macro. – Bruno Le Floch Dec 14 '11 at 07:01
  • @BrunoLeFloch: Thanks, I've changed the answer accordingly. – Jake Dec 14 '11 at 10:25
9

If it doesn't has to be local, you could use \g@addto@macro for appending to a macro:

\g@addto@macro\robbles{robble}

If necessary, use \makeatletter and \makeatother because of the @ in the name.

Alternatively, you can append to a macro if you change the expansion order, it also works locally if grouped:

\expandafter\def\expandafter\robbles\expandafter{\robbles robble}

\expandafter can reverse the expansion of two tokens. By using multiple \expandafter you can achieve here, that the second \robbles is expanded at first. Further explanation is given in A tutorial on expandafter by Stephan v. Bechtolsheim in TUGboat 9-1.

Stefan Kottwitz
  • 231,401
0

If we wish to expand completely the macro, then \edef\mymacro{\mymacro,3} works great as mentionned above.

But if you only want to expand once your macro, then I like \expanded{…} more and more (intuitively, it expands its parameter, except for tokens prefixed with \noexpand, and then it expands the resulting string). Since we want to postpone the evaluation of \def and \mymacro, we can simply prepend \noexpand in front of them:

\documentclass{article}

\begin{document}

\def\mymacro{1,2}

My macro is \mymacro

\expanded{\noexpand\def\noexpand\mymacro{\unexpanded\expandafter{\mymacro},3}}

My macro is \mymacro

\end{document}

Note that \unexpanded\expandafter{…} can be replaced with \expandonce{…} if we load etoolbox, since it actually expands only once the macro. enter image description here

tobiasBora
  • 8,684