我一直在深入研究xparse.sty
以更好地了解\SplitList
其工作原理,但对那里发生的一些分支感到困惑。
\SplitList
本质上是用来\__xparse_split_list:nn
检查拆分时要使用的标记。
\cs_new_protected:Npn \__xparse_split_list:nn #1#2
{
\bool_if:nTF
{
\tl_if_single_p:n {#1} &&
! ( \token_if_cs_p:N #1 )
}
{ \__xparse_split_list_single:Nn #1 {#2} }
{ \__xparse_split_list_multi:nn {#1} {#2} }
}
如果使用单个标记进行拆分,则\__xparse_split_list_single:Nn
调用。此控制序列是在@
已更改的 catcaode 的组中定义的。
\group_begin:
\char_set_catcode_active:N \@
\cs_new_protected:Npn \__xparse_split_list_single:Nn #1#2
{
\tl_set:Nn \l__xparse_split_list_tl {#2}
\group_begin:
\char_set_lccode:nn { `\@ } { `#1 }
\tl_to_lowercase:n
{
\group_end:
\tl_replace_all:Nnn \l__xparse_split_list_tl { @ } {#1}
}
\__xparse_split_list_multi:nV {#1} \l__xparse_split_list_tl
}
\group_end:
我觉得这完全没有必要。这个命令序列到底在做什么,不能通过直接将#1
和#2
of\__xparse_split_list:nn
传递给 来处理吗\__xparse_split_list_multi:nn
?
最后一个宏定义如下:
\cs_set_protected:Npn \__xparse_split_list_multi:nn #1#2
{
\seq_set_split:Nnn \l__xparse_split_list_seq {#1} {#2}
\tl_clear:N \ProcessedArgument
\seq_map_inline:Nn \l__xparse_split_list_seq
{ \tl_put_right:Nn \ProcessedArgument { {##1} } }
}
这是我测试的 MWE(看看我是否能找出我遗漏的内容)。我基本上跳过了测试单个标记是否已传递的步骤,直接拆分参数。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \myProcessedArgument
\seq_new:N \l__my_split_list_seq
\cs_new_protected:Npn \__my_split_list:nn #1#2
{
\typeout{----------------------------------------}%%
\typeout{==>delimiter ~ is ~ "\detokenize{#1}"}
\seq_set_split:Nnn \l__my_split_list_seq {#1}{#2}
%%\seq_show:N \l__my_split_list_seq
\tl_clear:N \myProcessedArgument
\seq_map_inline:Nn \l__my_split_list_seq
{
\typeout{==>\detokenize{##1}}
}
}
\cs_new_eq:NN \mySplitList \__my_split_list:nn
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
Trial: \mySplitList{.:}{a.b.:{c}.sdf.:ewrewr}
Trial: \mySplitList{.}{a.b.:{c}.sdf.:ewrewr}
\end{document}
但是无论我使用哪种类型的标记字符串(单个或多个)来拆分标记列表,此 MWE 似乎都能正常工作。
答案1
此处的代码是防御性的,反映了 LaTeX2e 没有“固定”的活动字符列表这一事实。因此,字符在创建文档命令时可能为(例如)“其他”,但在使用时为“活动”。一个经典示例是babel
,但基本思想如下:
\documentclass{article}
\usepackage{xparse}
\DeclareDocumentCommand{\foo}{>{\SplitList{.}}m}{%
\fooaux#1{oops!}%
}
\def\fooaux#1#2{\detokenize{"#1"}, \detokenize{"#2"}}
\begin{document}
\foo{ab.cd}
\catcode`\.=\active
\foo{ab.cd}
\ExplSyntaxOn
\cs_set_eq:NN \SplitList \__xparse_split_list_multi:nn
\ExplSyntaxOff
\foo{ab.cd}
\end{document}
当然,任何类别代码的变化都可能在这里产生问题,但活跃角色是“现实生活中”最有可能出现的问题。
注意:虽然还没有最终确定,但目前的想法是,对于独立的 LaTeX3 格式,我们可能会有一个“已知”的活动字符列表,并且极其强烈不鼓励改变这一点。因此,在这种情况下可能不需要这种方法。