3

Here is a minimal non-working example:

\documentclass{article}
\begin{document}

\let\@var\@empty

\newcommand{\append}[1]{ \xdef\@var{\@var #1} }

\append{1}
\append{2}
\append{3}

\@var

\end{document}

I was expecting \@var to contain the string 1 2 3, but instead I get the following error:

! TeX capacity exceeded, sorry [input stack size=5000].
\@var->\@var

How can I achieve what I was expecting to achieve?

Ceilican
  • 133

2 Answers2

3

You're missing \makeatletter...\makeatother pairs -- those are necessary due to \@ as macro (starter) name.

If the 'string' macro should not be indicated as internal (\@.... are internally 'hidden) choose another name, like \mystringvar, this will remove the issue with \makeatletter...\makeatother

\documentclass{article}
\begin{document}


\makeatletter
\let\@var\@empty
\newcommand{\append}[1]{\xdef\@var{\@var #1} }
% Another variant with kernel \g@addto@macro
\newcommand{\appendother}[1]{\g@addto@macro{\@var}{#1}}

\makeatother
\newcommand{\foo}{789}

\append{1}
\append{2}
\append{3}
\appendother{456\foo}
\makeatletter
\@var
\makeatother

\end{document}

enter image description here

  • Thanks! Could you explain why, using your definitions of \append and \appendother, writing \appendother{\textbf{3}} gives the expected result, but \append{\textbf{3}} throws the error ! Argument of \reserved@a has an extra }. ? – Ceilican Feb 02 '16 at 23:10
  • @Ceilican: \xdef can't be applied to a protected macro like \textbf –  Feb 03 '16 at 13:44
2

Christian has shown what you could do instead but to explain the error

@ is not a letter in the main document so

\let\@var\@empty

does

 \let\@=v

then typesets ar\@empty producing the paragraph text arvempty (which you don't see as later errors prevent a pdf being made.

Then

\newcommand{\append}[1]{ \xdef\@var{\@var #1} }

defines \append to typeset a space (why?) and then redefine \@ then typeset another space.

\append{1}

is therefore a space (ignored as we are in vertical mode) then

\xdef\@var{\@var 1}

this is defining the macro \@ to be followed by the tokens var to be the expansion of \@var 1 now at this point \@ is non-expandable as it is \let to v so now \@ has to be followed by var and expands to \@var 1

Then another ignored space is output and

\append{2}

this outputs another space then

\xdef\@var{\@var 2}

which again is redefining \@ to be a macro that must be followed by var but the definition is obtained by expanding \@var 1 but as noted above the expansion of \@var is at this point \@var 1 so the first expansion produces

\@var 1 2

Then \@ expands again producing

\@var 1 1 2

and so on until you run out of input stack. (because the 1's are all being pushed ahead of you)

wipet
  • 74,238
David Carlisle
  • 757,742