我想将“元组”列表/序列传递给宏,如下所示:
\foo {
(value11 value12 value13)
(value21 value22 value23)
(value31 value32 value33)
(value41 value42 value43)
(value51 value52 value53)
}
我该如何定义\foo
才能(valuex1 valuex2 valuex3)
逐个处理列表中的每个元组?知道如何处理“元组”长度可变的情况也很好,尽管这是一个侧重点,我很乐意接受没有这种情况的答案。
我想象我在这里寻找的是 xparse 和/或 expl3 答案,但我担心 xparse 对我来说本质上只是黑魔法。
答案1
和listofitems
:
\documentclass{article}
\usepackage{listofitems}
\ignoreemptyitems
\setsepchar{(||)}
\newcommand\foo[1]{%
\readlist*\z{#1}%
\foreachitem\zz\in\z[]{%
Processing tuple: \zz\par
}%
}
\begin{document}
\foo {
(value11 value12 value13)
(value21 value22 value23)
(value31 value32 value33 value34 value35)
(value41 value42 value43)
(value51 value52 value53)
}
\end{document}
如果需要一个二次循环来处理(五)元组中的项目,那么可以这样做:
\documentclass{article}
\usepackage{listofitems}
\ignoreemptyitems
\newcommand\foo[1]{%
\setsepchar{(||)}
\readlist*\z{#1}%
\foreachitem\zz\in\z[]{%
Processing tuple:
\setsepchar{ }
\readlist\zzz{\zz}
\foreachitem\zzzz\in\zzz[]{%
subitem: \zzzz\quad
}%
\par\medskip
}%
}
\begin{document}
\foo {
(value11 value12 value13)
(value21 value22 value23)
(value31 value32 value33 value34 value35)
(value41 value42 value43)
(value51 value52 value53)
}
\end{document}
答案2
如果项目用大括号括起来而不是用圆括号括起来,则更像 LaTeX。
\documentclass{article}
\ExplSyntaxOn
% no black magic, really
\NewDocumentCommand{\foo}{m}
{% #1 is a list of items in braces
\tl_map_function:nN { #1 } \noldorin_foo_process:n
}
% now an example of \noldorin_foo_process:n
\seq_new:N \l__noldorin_foo_process_seq
\cs_new_protected:Nn \noldorin_foo_process:n
{
% split the argument at spaces
\seq_set_split:Nnn \l__noldorin_foo_process_seq { ~ } { #1 }
% print each item surrounded by angle brackets and follow each by \par
\seq_map_inline:Nn \l__noldorin_foo_process_seq { $\langle$##1$\rangle$ \par }
% then vertical space between each tuple
\bigskip
}
\ExplSyntaxOff
\begin{document}
\foo {
{value11 value12 value13}
{value21 value22 value23}
{value31 value32 value33}
{value41 value42 value43}
{value51 value52 value53}
}
\end{document}
为什么\tl_map_function:nN
?因为这会将作为参数给出的标记列表拆分为“项目”,即单个标记或括号组。并依次将指定的函数应用于每个项目。
您现在必须决定实际上\noldorin_foo_process:n
应该做什么。