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?

Werner
  • 603,163
Egidio
  • 93

4 Answers4

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

egreg
  • 1,121,712
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.

Werner
  • 603,163
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. :)

Paulo Cereda
  • 44,220
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}
Peter Grill
  • 223,288