3

I wrote the following code

\documentclass{article}
\makeatletter
 \newtoks\a@toks
 \newtoks\b@toks
 \newcounter{a@counter}%
 \newcounter{b@counter}%
 \setcounter{a@counter}{0}%
 \setcounter{b@counter}{0}%
 \newcommand{\aAdd}[1]{%
  \ifnum\thea@counter>0\a@toks=\expandafter{\the\a@toks {#1}}%
  \else\a@toks=\expandafter{\the\a@toks {#1}}%
  \fi
  \stepcounter{a@counter}%
 }
 \newcommand{\reset}{%
  \setcounter{a@counter}{0}%
  \a@toks={}%
 }
 \newcommand{\bexp}{%
  \ifnum\theb@counter>0\b@toks=\expandafter{\the\b@toks, (\the\a@toks)}%
  \else\b@toks=\expandafter{\the\b@toks (\the\a@toks) }%
  \fi
  \stepcounter{b@counter}%
  \setcounter{a@counter}{0}%
  \a@toks=\noexpand{}%
 }
 \newcommand{\print}{%
  \the\b@toks%
 }
\makeatother
\begin{document}
 Hello World!\\[3cm]
 \aAdd{a}
 \aAdd{b}
 \bexp
 \aAdd{c}
 \print
\end{document}

What I'm trying to do is the following: with \aAdd I add some element to a list, specifically in this example after

\aAdd{a}
\aAdd{b}

I expect \a@toks to be equal to ab. Then I flush this into another token, so I expect \b@toks to be equal to ab. The problem is when the command

\a@toks={}

is executed, this resets even \b@toks that continues to follow \a@toks, so that, when I execute

\aAdd{c}

\b@toks has the value c.

I would like, once set \b@toks = \a@toks to set only the value of \b@toks, so that, when I redefine \a@toks, \b@toks continues to have the preceding value (in this case ab).

Can anyone help me?

7
  • the question is very hard to understand, after the first two \aAdd the register \a@toks is {a}{b} not ab do you not want the braces? and after \bexp the register \b@toks is (\the \a@toks ) but (I think?) you want the content of a@toks not a reference? May 4, 2016 at 19:30
  • The problem is not what is stored in \a@toks, but what is stored in\b@toks. I want that after I reset \a@toks={} in \b@toks continues to be {a}{b}. Have I explained it better?
    – MaPo
    May 4, 2016 at 19:33
  • beware doing \ifnum\theb@counter>0\b@toks which will try to expand \b@toks to terminate the number before doing the test, it works here as b@toks is not expandable but safer to leave a space after 0 or better use \z@ May 4, 2016 at 19:34
  • \b@toks=\expandafter{\the\a@toks} for the first assignment?
    – user31729
    May 4, 2016 at 19:35
  • but your description said a@toks contains ab which it does not, so the whole question is very confusing. b@toks is never set to {a}{b} in the above code. May 4, 2016 at 19:35

2 Answers 2

9

\expandafter doesn't expand everything after it, just the following token. Also, since it seems like b@counter measures the content added to \b@toks, I don't see the need for

\ifnum...
\else\b@toks=\expandafter{\the\b@toks (\the\a@toks) }
\fi

where you want to add (an empty) \b@toks to itself.

The following produces what you're after, I think (I've cleaned it up a bit):

enter image description here

\documentclass{article}

\makeatletter
\newtoks\a@toks
\newtoks\b@toks
\newcounter{b@counter}%
\newcounter{a@counter}[b@counter]%

\newcommand{\aAdd}[1]{%
  \ifnum\value{a@counter}>0 \a@toks=\expandafter{\the\a@toks {#1}}%
  \else\a@toks=\expandafter{\the\a@toks {#1}}%
  \fi
  \stepcounter{a@counter}%
}
\newcommand{\reset}{%
  \setcounter{a@counter}{0}%
  \a@toks={}%
}
\newcommand{\bexp}{%
  \ifnum\value{b@counter}>0
    \edef\x{\noexpand\b@toks={\the\b@toks, (\the\a@toks)}}%
  \else
    \edef\x{\noexpand\b@toks={(\the\a@toks)}}%
  \fi
  \x
  \stepcounter{b@counter}%
  \a@toks={}%
}
\newcommand{\print}{%
  \the\b@toks%
}
\makeatother

\begin{document}

Hello World!

\bigskip

\aAdd{a}% \a@toks = {a}
\aAdd{b}% \a@toks = {a}{b}
\bexp% \a@toks = {}, \b@toks = {a}{b}
\aAdd{c}% \a@toks = {c}
\print% \b@toks

\end{document}

One could use

\b@toks=\expandafter{\expandafter(\the\a@toks)}

to make sure \a@toks is expanded before inserting it into \b@toks. However, I've instead opted to make sure everything expands before adding it to \b@toks by using an \edef\x{...}\x approach.

If leaving behind an unwanted \x is a problem, you can use the following definition for \bexp:

\newcommand{\bexp}{%
  \begingroup
  \ifnum\value{b@counter}>0
    \edef\x{\endgroup\noexpand\b@toks={\the\b@toks, (\the\a@toks)}}%
  \else
    \edef\x{\endgroup\noexpand\b@toks={(\the\a@toks)}}%
  \fi
  \x
  \stepcounter{b@counter}%
  \a@toks={}%
}
11
  • \noexpand{ is harmless, but... May 4, 2016 at 19:40
  • @DavidCarlisle... sorry, missed that one.
    – Werner
    May 4, 2016 at 19:42
  • 1
    Just use e-TeX!
    – Joseph Wright
    May 4, 2016 at 19:47
  • It is almost I like to do, the last thing is that I was lookin for. I still do not understand why, if between the \aAdd{c} and the \print i write another \bexp I get (ab), () instead of (ab), (c),which I would like to obtain for my purposes...
    – MaPo
    May 4, 2016 at 19:50
  • Thanks for helping me understand a bit more about token registers and such. I've always been clueless on them. May 4, 2016 at 19:51
5

Werner's analysis is very good. Here's an alternative implementation with xparse and expl3. Note that you can define as optional argument to \print the separator between items (default is “comma-space”).

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\aAdd}{m}
 {
  \mapo_aadd:n { #1 }
 }
\NewDocumentCommand{\bexp}{}
 {
  \mapo_bexp:
 }
\NewDocumentCommand{\reset}{}
 {
  \mapo_reset:
 }
\NewDocumentCommand{\print}{O{,~}}
 {
  \mapo_print:n { #1 }
 }

\tl_new:N \l_mapo_a_tl
\seq_new:N \l_mapo_b_seq

\cs_new_protected:Nn \mapo_aadd:n
 {
  \tl_put_right:Nn \l_mapo_a_tl { #1 }
 }
\cs_new_protected:Nn \mapo_bexp:
 {
  \seq_put_right:Nx \l_mapo_b_seq { ( \exp_not:V \l_mapo_a_tl ) }
  \mapo_reset:
 }
\cs_new_protected:Nn \mapo_reset:
 {
  \tl_clear:N \l_mapo_a_tl
 }
\cs_new:Nn \mapo_print:n
 {
  \seq_use:Nn \l_mapo_b_seq { #1 }
 }
\ExplSyntaxOff

\begin{document}

\noindent
Hello World!\\
\aAdd{a}\aAdd{b}\bexp\aAdd{c}%
\print\\
\bexp
\print[---]

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .