4

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.

4

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 becomes AB.

Similarly, I can solve the above problem in the question like this :

noindent\expandafter\forcsvlist\expandafter\doforme\authors

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 becomes

\noident\forcsvlist\doforme{a,b,c}

which is equivalent to passing the argument like the first case in the question, and hence produce same results.

2

The package etoolbox defines a special command to handle internal lists: \forlistloop. These lists use a special character as internal list separator. So you have to use \listadd (or similar commands - see the etoolbox documentation) to add an item to such a list.

\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand\doforme[1]{#1 \\}
\forcsvlist{\listadd\authors}{a,b,c}
\noindent\forlistloop\doforme{\authors}
\end{document}

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.