Использование forcsvlist с макросами, принимающими более одного аргумента

Использование forcsvlist с макросами, принимающими более одного аргумента

Я хотел бы сжать этот пример кода с помощью \forcsvlist(предоставленногоetoolboxупаковка).

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

Я бы хотел просто переместить \iftoggles в \mycmdи определить пары аргументов в 'списке'. Однако я не знаю, возможно ли передать более одного аргумента за раз в forcvslist.


После замечательных ответов @Andrew и @Werner я написал эту команду как многоаргументную версию \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}

Если я не ошибаюсь, он создает вспомогательную команду, если она не определена ранее. Я сделал это для того, чтобы использовать ее forcsvlistargsнесколько раз в одном документе, не объявляя функцию явно.

Полагаю, это \csname \detokenize{#1}\endcsname##1\relaxможно изменить на что-то подобное #1##1\relax, но я что-то упускаю.

решение1

Возможно, есть более эффективный способ, но вы всегда можете сделать что-то вроде этого:

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

Когда вы латексируете это, файл журнала содержит

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

что показывает, что \MyCmdон правильно получает пары аргументов и затем передает их в \mycmdn ожидаемым образом.

(Я убрал ваши команды переключения, так как они, похоже, отвечают на какой-то другой код, который вы не включили.)

решение2

Если вы правильно укажете «отдельные» элементы в списке CSV, вы сможете разбить их на столько аргументов, сколько захотите:

введите описание изображения здесь

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

После захвата элементов списка они передаются другому макросу с необходимыми аргументами.

Связанный контент