6

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?

4

You can use the following definition of \listparticipants:

enter image description here

\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.

5

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}.

4

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}

Output

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
3

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

enter image description here

\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}

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.