5

I'd like to compact this code sample with \forcsvlist (provided by the etoolbox package).

\newcommand\mycmd[2]{
  \pagestyle{#2}
  \csname tit#1\endcsname
  \cleardoublepage
}

\def\DOtitlepages{
 \iftoggle{togfancy}{ \mycmd{fancy}{empty} }{}
 \iftoggle{togplain}{ \mycmd{plain}{empty} }{}
 \iftoggle{toguser}{ \mycmd{user}{plain} }{}
}

I'd like just to move the \iftoggles to \mycmd and define the pairs of arguments in a 'list'. However I don't know if it is possible to pass more than one argument at a time to forcvslist.


After the great answers by @Andrew and @Werner, I've written this command as multiargument version of \forcsvlist:

\documentclass{article}
\usepackage{etoolbox}

\newcommand\mycmd[2]{#1 \par#2 \par}

\newcommand\forcsvlistargs[2]{
  \expandafter\providecommand\csname \detokenize{#1}aux\endcsname[1]{\csname \detokenize{#1}\endcsname##1\relax}
   \forcsvlist{\expandafter\csname \detokenize{#1}aux\endcsname}{#2}
}

\begin{document}

\forcsvlistargs{mycmd}{{{fancy}{empty}},{{plain}{empty}},{{user}{plain}}}

\end{document}

If I'm not wrong, it creates the auxiliary command if not previously defined. I did so in order to use forcsvlistargs several times in the same document, not having to explicitly declare de function first.

I suppose that \csname \detokenize{#1}\endcsname##1\relax can be change to something like that #1##1\relax, but I'm missing something.

2 Answers 2

4

Perhaps there is a more efficient way but you can always do something like this:

\documentclass{article}
\usepackage{etoolbox}
\newcommand\MyCmd[1]{\typeout{Mycmd: #1}\mycmd#1}
\def\mycmd(#1|#2){
\typeout{mycmd:  1: #1. 2: #2.}
}

\begin{document}
    \forcsvlist\MyCmd{{(fancy|empty)}, {(plain|plain)}, {(user|plain)}}
\end{document}

When you latex this the log file contains

Mycmd: (fancy|empty)
mycmd: 1: fancy. 2: empty.
Mycmd: (plain|plain)
mycmd: 1: plain. 2: plain.
Mycmd: (user|plain)
mycmd: 1: user. 2: plain.

which shows that \MyCmd is receiving the argument pairs correctly and then passing them onto \mycmd n the expected way.

(I took out your toggle commands as they seem to reply on some other code tat you didnt include.)

1
  • That's awesome! I tried also with (fancy|empty) instead of {(fancy|empty)} and it works also! Thank you.
    – umarcor
    Commented Sep 28, 2014 at 3:05
5

If you specify the "individual" items in the CSV list properly, you can break them up into as many arguments as you want to:

enter image description here

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand{\MyCmd@aux}[2]{\iftoggle{tog#1}{#2, }{no #1, }}
\newcommand{\MyCmd}[1]{\MyCmd@aux#1}
\makeatother
\begin{document}

\newtoggle{togfancy}
\newtoggle{togplain}
\newtoggle{toguser}

\toggletrue{togplain}% togplain is TRUE
\forcsvlist{\MyCmd}{%
  {{fancy}{empty}},
  {{plain}{plain}},
  {{user}{plain}}}


\toggletrue{togfancy}% togfancy is TRUE
\forcsvlist{\MyCmd}{%
  {{fancy}{empty}},
  {{plain}{plain}},
  {{user}{plain}}}

\toggletrue{toguser}% toguser is TRUE
\forcsvlist{\MyCmd}{%
  {{fancy}{empty}},
  {{plain}{plain}},
  {{user}{plain}}}
\end{document}

After capturing the list items, they're passed to another macro with the required arguments.

2
  • Thanks you. I suppose that this and Andrew's answer are nearly the same, but you specify the item properly to be used in a newcommand, while he sets it up to be used in a def. Is it correct?
    – umarcor
    Commented Sep 28, 2014 at 3:13
  • @U.Martinez-Corral: Yes; with \def you can specify that argument text in whichever way you want to. With \newcommand your arguments have to specified as a group {..}.
    – Werner
    Commented Sep 28, 2014 at 3:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .