有人可以解释一下 xparse 的 \SplitList 中的分支吗?

有人可以解释一下 xparse 的 \SplitList 中的分支吗?

我一直在深入研究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#2of\__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 格式,我们可能会有一个“已知”的活动字符列表,并且极其强烈不鼓励改变这一点。因此,在这种情况下可能不需要这种方法。

相关内容