Определить переменную списка

Определить переменную списка

Я использую etoolboxдля обработки списков, в частности \forcsvlist.

При передаче списка, разделенного запятыми, напрямую в \forcsvlist, он может разобрать каждый элемент в списке. Однако, если я определяю переменную списка где-то еще, он \forcsvlistне может различать каждый элемент в списке и воспринимает его как один целый аргумент.

Например:

\newcommand\doforme[1]{#1 \\}
\forcsvlist\doforme{a,b,c}

Вышеуказанный код отлично работает, добавляя новую строку в конец каждого элемента. Но следующий код не работает

\newcommand\doforme[1]{#1 \\}
\def\@authors{a,b,c}
\forcsvlist\doforme{\@authors}

Это заставляет меня думать, что должен быть какой-то другой способ определения списка, который \forcsvlistможно интерпретировать.

решение1

Проблема использования переменной формы заключалась в ее более раннем расширении, которое затем принимало все a,b,cкак одну сущность. Под одной сущностью я подразумеваю единственный элемент в списке.

Чтобы решить эту проблему, прежде всего нам нужно использовать здесь двойные скобки. Так что {a,b,c}становится {{a,b,c}}, причина чего станет ясна к концу этого ответа.

\expandafterпримитив расширяет аргумент, данный ему после следующего. Например, если есть \def\foo{A}, \def\bar{B}и \expandafter\foo\bar, он сначала станет \foo B, а затем в конечном итоге станет AB.

Аналогично я могу решить вышеуказанную проблему в вопросе следующим образом:

noindent\expandafter\forcsvlist\expandafter\doforme\authors

Если мы посмотрим на рекурсивное выражение выше, то первое expandafter переходит к своему первому аргументу (\forcsvlist), пропускает его на некоторое время и пытается расширить аргумент рядом с ним, который в этом случае снова \expandafter. Итак, второе \expandafterснова пропускает \doformeна некоторое время, а затем расширяется \authors. \authorsis current {{a,b,c}}. После расширения оно становится {a,b,c}. Таким образом, окончательное выражение теперь становится

\noident\forcsvlist\doforme{a,b,c}

что эквивалентно передаче аргумента, как в первом случае в вопросе, и, следовательно, приводит к тем же результатам.

решение2

Пакет etoolboxопределяет специальную команду для обработки внутренних списков: \forlistloop. Эти списки используют специальный символ в качестве внутреннего разделителя списка. Поэтому вам придется использовать \listadd(или аналогичные команды - см.etoolboxдокументация) для добавления элемента в такой список.

\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand\doforme[1]{#1 \\}
\forcsvlist{\listadd\authors}{a,b,c}
\noindent\forlistloop\doforme{\authors}
\end{document}

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