这个问题是对这个问题的回答的一种后续:如何迭代以逗号分隔的列表?
不同之处在于,我想迭代存储在宏中的 csv 列表\myTerms
。按照 MWE,中的列表\myTerms
似乎按字面意思理解,而不是解析为 CSV。我尝试用 来修复它\expanded{}
,但似乎不起作用。
梅威瑟:
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\myList}{mm}
{
\clist_set:Nn \l_tmpa_clist { #1 }
\clist_use:Nnnn \l_tmpa_clist { #2 } { #2 } { #2 }
}
\ExplSyntaxOff
\newcommand{\mySeparator}{\textbullet}
\newcommand{\makeMyList}[1]{
\begingroup
\scshape\myList{#1}{\mySeparator}
\endgroup
}
\newcommand{\myTerms}{test, another test}
\begin{document}
\makeMyList{\expanded{\myTerms}}
\end{document}
当我不使用宏myTerms
而只是将列表写出\makeMyList
参数时,就可以实现所需的输出,如下所示:
期望输出:
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\myList}{mm}
{
\clist_set:Nn \l_tmpa_clist { #1 }
\clist_use:Nnnn \l_tmpa_clist { #2 } { #2 } { #2 }
}
\ExplSyntaxOff
\newcommand{\mySeparator}{\textbullet}
\newcommand{\makeMyList}[1]{
\begingroup
\scshape\myList{#1}{\mySeparator}
\endgroup
}
\begin{document}
\makeMyList{test, another test}
\end{document}
这让我认为\expanded{}
需要扩展控制,但我似乎犯了另一个错误。我该如何解决这个问题?
答案1
当您使用时expl3
,只要您不进行低级编程,我建议坚持使用它提供的扩展方法。我的意思是:您不必费心将列表扩展为输入,我认为最好让它在级别上处理expl3
。
您的使用\expanded
不起作用,因为在\expanded
完成其工作之前,您的意志\makeMyList
会抓住它的参数并将其\expanded{\myTerms}
视为输入,没有找到逗号,因此将其用作单个术语。
该级别的扩展expl3
可以通过两种不同的方式进行:
- 有根据的猜测,如果只提供了一个参数,那么很可能这是一个存储值的宏
- 例如通过星号在 处提供一个“开关”
\makeMyList
,在这种情况下我们可以使用\exp_args:No
或类似的。
以下工具两个都,但使用\expandafter
第二种方法代替 -layer expl3
:
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\myList}{mm}
{
\tl_if_single:nTF {#1}
{
% if the single item is a group we don't expand it
\tl_trim_spaces_apply:nN {#1} \tl_if_head_is_group:nTF
{ \clist_set:Nn }
{
% if it's no group it must be N-type, and the test for group is
% faster
% there might be spaces around #1 but those will be removed by TeX's
% argument grabbing, so don't hurt
\token_if_expandable:NTF #1
\clist_set:NV
\clist_set:Nn
}
}
{ \clist_set:Nn }
\l_tmpa_clist {#1}
\clist_use:Nn \l_tmpa_clist {#2}
}
\ExplSyntaxOff
\newcommand{\mySeparator}{\textbullet}
\NewDocumentCommand \makeMyList { s m }
{
\begingroup
\scshape
\IfBooleanTF {#1}
{\expandafter\myList\expandafter{#2}\mySeparator}
{\myList{#2}\mySeparator}%
\endgroup
}
\newcommand{\myTerms}{test, another test}
\begin{document}
% expansion-guess at the expl3 level
\makeMyList{\myTerms}\par
\makeMyList{\myTerms,abc}
% expansion of first token in the list by the interface
\makeMyList*{\myTerms}\par
\makeMyList*{\myTerms,abc}
\end{document}
编辑:按照建议添加了更多测试@AndrewStacey。
答案2
您的建议的问题在于,\expanded
直到太晚才会被看到。根据您想要实现的具体目标,有几种方法可以做到这一点。一个简单的方法是将更改为\clist_set:Nn
。\clist_set:NV
这需要价值宏的作为要使用的列表。您还需要删除 周围的括号#1
。这将进行一次扩展,因此如果您的列表包含宏,则它们不会被扩展。
(我现在没有可以轻松测试这一点的设备,所以您可能需要进行一些其他调整。)