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?

  • All 'works for me' (if I add the \makeatletter required): did you run exactly this file? – Joseph Wright Feb 2 '16 at 12:15
  • By the way -- you won't get 1 2 3 but 123. If you want to have the space in between you have to use \@var\ #1 – user31729 Feb 2 '16 at 12:23
  • @ChristianHupfer Not “backslash-space”, but \space. – egreg Feb 2 '16 at 13:32
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

|improve this answer|||||
  • 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 2 '16 at 23:10
  • @Ceilican: \xdef can't be applied to a protected macro like \textbf – user31729 Feb 3 '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)

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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