I am using etoolbox
for list processing, specifically \forcsvlist
.
When passing the comma-separated list directly to \forcsvlist
, it is able to parse each item in the list. However, if I define the list variable somewhere else, \forcsvlist
is not able to distinguish between each item in the list, and takes it as one whole argument.
Eg:
\newcommand\doforme[1]{#1 \\}
\forcsvlist\doforme{a,b,c}
Above code works perfectly adding newline to end of each item.
But following code doesn't work
\newcommand\doforme[1]{#1 \\}
\def\@authors{a,b,c}
\forcsvlist\doforme{\@authors}
This makes me think that there must be some other way to define the list that \forcsvlist
can interpret.
Best Answer
The problem in using the variable form was its earlier expansion which would then take the whole
a,b,c
as one entity. By one entity, I mean the only single element in the list.To solve this problem, first of all we need to use double brackets here. So
{a,b,c}
becomes{{a,b,c}}
, the reason of which will become clear by the end of this answer.\expandafter
primitive expands the argument given to it after the next one. For example, if there are\def\foo{A}, \def\bar{B}
and\expandafter\foo\bar
, it will first become\foo B
, and then eventually becomesAB
.Similarly, I can solve the above problem in the question like this :
If we take a look at above recursive expression, the first expandafter goes to its first argument (\forcsvlist), skips it for a while, and try expanding argument next to it which in this case is again
\expandafter
. So, the second\expandafter
again skips\doforme
for a while and then expands\authors.
\authors
is currently{{a,b,c}}
. After expansion it becomes{a,b,c}
. So the final expression now becomeswhich is equivalent to passing the argument like the first case in the question, and hence produce same results.