3

I need to store a csv list for later use in the end code part of an environment. Can somebody explain me what's going wrong in the following example?

\documentclass{article}
\usepackage{etoolbox}
\usepackage{ifthen}
\newcommand*\mycsv{1,2,3}
\newcommand*\printnumbers[1]{
  \ifthenelse{\equal{#1}{1}}{one, }{}
  \ifthenelse{\equal{#1}{2}}{two, }{}
  \ifthenelse{\equal{#1}{3}}{three, }{}
}
\newcommand*\doprint[1]{\forcsvlist\printnumbers{#1}}
\begin{document}
\doprint{1,2,3} % does work

\doprint{\mycsv} % does not work
\end{document}

If the list is stored in the macro, it seems to be no longer a list for \forcsvlist but a single token. Any other solution which solves my problem?

Josef
  • 7,432
  • 3
    Related/duplicate http://tex.stackexchange.com/questions/22393/forcsvlist-and-expansion – egreg Feb 05 '13 at 14:59
  • @egreg Yep '\newcommand*\doprint[1]{\expandafter\forcsvlist\expandafter\printnumbers\expandafter{#1}}' does the trick. Thank you! Oh, i hate TeX ;-) – Josef Feb 05 '13 at 15:11
  • You can hide that in a \xforcsvlist macro: \newcommand{\xforcsvlist}[2]{\expandafter\forcsvlist\expandafter#1\expandafter{#2}} and then \newcommand{\doprint}[1]{\xforcsvlist\printnumbers{#1}} – egreg Feb 05 '13 at 15:26

1 Answers1

2

Since #1 can't be all of 1, 2, 3 at the same time, there is an inefficiency in OP's \printnumbers. Here is an alternative solution.

\documentclass{article}
\usepackage{loops}
\newcommand*\comma{\ifforeachlastitem.\else, \fi}
\newcommand*\doprint[1]{%
  \newforeach [expand list once] \x in {#1} {%
    \skvifcase\skvxifstrcmpTF\x
      {1}{one\comma}
      {2}{two\comma}
      {3}{three\comma}
    \elsedo
      \@latex@error{\string\doprint: no match}\@ehd
    \endif
  }%
}
\begin{document}
\doprint{1,2,3}
\par
\doprint{} % empty list
\par
\newcommand*\mylist{1,2,3}
\doprint{\mylist}
\end{document} 

This solution can be generalized to other list types beyond {1,2,3}.

Ahmed Musa
  • 11,742