# Illegal parameter number with \docsvlist

I'm trying to define a macro that take as an input a CSV list and create an item list. etoolbox comes just handy for this and the macro I'm using is

\begin{itemize}
\renewcommand*{\do}[1]{\item[] #1}
\expandafter\docsvlist\expandafter{\participants}
\end{itemize}


where \participants is the CSV list of items to itemize.

My problem is that when I insert this macro as a newcommand definition like

\newcommand{\listparticipants}{
\begin{itemize}
\renewcommand*{\do}[1]{\item[] #1}
\expandafter\docsvlist\expandafter{\participants}
\end{itemize}
}


I get the following error message

! Illegal parameter number in definition of \listparticipants.
<to be read again>
1
l.29 }


What am I missing?

-
–  Marco Daniel May 30 '12 at 18:27

You can use the following definition of \listparticipants:

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\listparticipants}[1]{
\begin{itemize}
\renewcommand*{\do}[1]{\item[] ##1}
\docsvlist{#1}
\end{itemize}
}
\begin{document}
\listparticipants{Tom,Dick,Harry}
\end{document}


Note that you're redefining a command within another one. For the parameter text to be correctly referenced, you need to double the parameter text #s. So, #1 refers to the argument to \listparticipants, while ##1 refers to the argument to \do.

This convention would hold even if you didn't require \listparticipants to take an argument:

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\listparticipants}{
\begin{itemize}
\renewcommand*{\do}[1]{\item[] ##1}
\expandafter\docsvlist\expandafter{\participants}
\end{itemize}
}
\begin{document}
\def\participants{Tom,Dick,Harry}
\listparticipants
\end{document}


Note that the first MWE might be a better approach, since it allows you to format your list of participants (using, say, \textbf{Tom},\textit{Dick},\textsf{Harry}), while the second won't work properly with such definitions due to expansion.

-
Thanks a lot. This solved precisely my question! –  Egidio May 31 '12 at 9:45

Another way to process comma separated lists is to use PGF's \foreach macro:

\documentclass{article}
\usepackage{pgffor}

\newcommand{\listparticipants}[1]{
\begin{itemize}
\foreach \particpant in {#1} {%
\item \particpant
}
\end{itemize}
}

\begin{document}
\listparticipants{Tom,Dick,Harry}
\end{document}

-

You can avoid \docsvlist if you switch to xparse:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\listparticipants}{ >{\SplitList{,}}m}
{%
\begin{itemize}
\ProcessList{#1}\lpitem
\end{itemize}
}
\NewDocumentCommand{\lpitem}{m}{\item #1} % just to allow for further customization

\begin{document}
\listparticipants{Tom,Dick,Harry}
\end{document}


You can split the list given as argument at commas; then \ProcessList{#1}\lpitem will do in turn \lpitem{Tom}, \lpitem{Dick} and \lpitem{Harry}.

-

For the sake of completeness, you can use another handy macro from etoolbox, \DeclareListParser:

\documentclass{article}

\usepackage{etoolbox}

\DeclareListParser*{\iterateparticipants}{,}

\newcommand{\listparticipants}[1]{%
\begin{itemize}
\iterateparticipants{\item}{#1}
\end{itemize}
}

\begin{document}

\listparticipants{Tom,Dick,Harry}

\end{document}


There we go. :)

-
One has to watch out for trailing spaces in the values, because they aren't trimmed off. This isn't relevant in the present case, but might be in other situations. –  egreg May 30 '12 at 22:07
@egreg: Thanks, I fixed the code. :) –  Paulo Cereda May 30 '12 at 22:09