浏览某些内容的列表的最佳方法是什么?

浏览某些内容的列表的最佳方法是什么?

定义新命令时需要的一个常见操作似乎是扫描参数列表(例如用逗号分隔,但也可能用其他东西分隔)并对列表中的每个参数执行某些操作,找到最后一个参数,或者其他操作。

例如,编写类似于\Command{a,b,c}或 的命令\Command{c.d.e},并使用 、 和 执行某些操作abc参阅定义运算符列表忽略偶数输入

那里已经发布了一些解决方案,但是执行此类操作的最佳习惯用法是什么?LaTeX\@for看起来很不错,但是是否可以使用它来扫描除逗号分隔列表之外的任何内容?

答案1

我自己还没有达到处理列表的水平,但我一直在使用etoolboxPhilipp Lehman 进行一些其他 TeX 编程任务。我相信3.7 列表处理应该能给你一个很好的解决方案。

例如(在的最新版本上etoolbox),你可以写:

\DeclareListParser*{\myfor}{;}
\myfor{\fbox}{item1; item2; item3}

答案2

我希望有人能发布更好/更好的解决方案,但到目前为止,这似乎是我见过的最好的解决方案。

\def\do@scan#1:{%
  \ifx#1\relax
    \let\next\relax
  \else
    \DoSomethingWith{#1}\let\next\do@scan
  \fi\next
}
\newcommand{\scanlist}[1]{\do@scan#1:\relax:}

当然,:你也可以使用,或任何其他合理的分隔符。

答案3

由于 Morbusg 的回答将这个问题推到了首位,所以我要添加一个 LaTeX3 答案。这个想法是将列表转换为称为序列的内部结构,然后映射到该序列上\l_MyMap_seq

\documentclass{article}
\usepackage{expl3, xparse}
\ExplSyntaxOn
\seq_new:N \l_MyMap_seq
\NewDocumentCommand{\MyMap}{O{,}mm}
  {
    \seq_set_split:Nnn \l_MyMap_seq {#1} {#2}
    \seq_map_inline:Nn \l_MyMap_seq {#3}
  }
\ExplSyntaxOff
\begin{document}
  \MyMap{a,b,c}{\fbox{#1} }
  \begin{tabular}{c}
    \MyMap[:]{a:b:c}{#1\\}
  \end{tabular}
\end{document}

第一个(可选)参数是分隔符,默认为逗号。第二个参数是列表,第三个参数是一个函数,将列表中的每个项目作为#1

xparse软件包还提供了\SplitList,可以用作

\NewDocumentCommand {\foo} { >{\SplitList{.}} m m } { \tl_map_inline:nn {#1}{#2} }

在 的定义中对 的分隔符进行硬编码\foo

答案4

在上下文中,列表处理使用 完成\processcommalist。假设您想要将宏\doCommand应用于传递给 的每个列表元素\Command。以下 的定义\Command执行此操作:

\def\Command#1{\processcommalist[#1]\doCommand}

如果列表可能包含宏,例如

\def\Arguments{a,b,c}
\Command{\Arguments,d,e,f}

然后你可以使用\processcommacommand,例如

\def\Command#1{\processcommalistcommand[#1]\doCommand}

有一些更快的替代方案,\rawprocesscommalist\rawprocesscommacommand它们有一定的局限性。请参阅 ConTeXt wiki请参阅列表处理以了解详细信息。

要处理带有任意分隔符的列表,\processlist可以使用。\processlist需要 5 个参数:列表开头标记、列表结尾标记、元素分隔符、应用于每个元素的命令和列表。例如,\Command[a:b:c]使用冒号作为分隔符的命令可以定义为

\def\Command{\processlist[]:}

相关内容