4

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.

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

  • That's awesome! I tried also with (fancy|empty) instead of {(fancy|empty)} and it works also! Thank you. – U.Martinez-Corral Sep 28 '14 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.

  • 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? – U.Martinez-Corral Sep 28 '14 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 Sep 28 '14 at 3:21

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.