根据字符串检查函数的展开

根据字符串检查函数的展开

我有一个函数\Foo,我用它来测试它对于给定参数应该扩展成什么样子。有两个问题:1/ 我无法“记录”完全扩展的版本\Foo{arg}。2/ 即使通过查看 pdf 输出发现扩展似乎正确,测试仍会\str_if_eq:p失败。

以下是代码中Hook 1对应的日志文件的摘录:

\l_tmpa_tl=\Foo {A,B,C}。

我期望 RHS 上有=其扩展版本。为什么没有,可以实现吗?

以下是代码中 Hook 2 对应的输出:

在此处输入图片描述

\Foo {A,B,C}FAIL 是测试中间的 LHS 上显示的扩展+与 RHS相等的结果。不一致的原因是什么?

\documentclass{l3doc}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \foo_str_compare:nn
{
  \exp_args:NNx \tl_set:Nn \l_tmpa_tl {#1}
  \tl_log:N \l_tmpa_tl % Hook 1
  \exp_last_unbraced:Nf % Hook 2
  \str_if_eq:nnTF
  {
    {\l_tmpa_tl}
    {#2}
    {PASS}
    {FAIL+#1+#2+}
  }
}

\NewDocumentCommand{\Foo}
{m}
{
  \seq_gset_from_clist:Nn \foo_seq {#1}
  \seq_use:Nnnn \foo_seq{,~}{,~}{~and~}
}

\NewDocumentCommand{\Test}{}
{
  \foo_str_compare:nn{\Foo{A,B,C}}{A,~B~and~C}
}

\ExplSyntaxOff

\begin{document}

\Test

\end{document}

答案1

您只能对可扩展材料进行字符串比较。您有一个\Foo受保护的文档命令,并且还使用\seq_gset_from_clist:Nn不可扩展的。(在中interface3,任何未标有星号的函数都是不可扩展的;广义上,任何执行分配或排版的函数都不可扩展。)

重写以使用逗号列表的可扩展映射会导致

\documentclass{l3doc}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new:Npn \foo_str_compare:nn #1#2
  {
    \str_if_eq:eeTF {#1} {#2}
      { PASS }
      { FAIL+#1+#2+}
  }

\NewExpandableDocumentCommand{\Foo}
{m}
{
  \int_case:nnF { \clist_count:n {#1} }
    {
      { 0 } { }
      { 1 } {#1}
      { 2 } { \__foo_two:w #1 \s_stop }
    }
    { \__foo_list:w #1 \s_stop }
}
\cs_new:Npn \__foo_two:w #1 , #2 \s_stop { #1 ~ and ~ #2 }
\cs_new:Npn \__foo_list:w #1 , #2 \s_stop
  {
    #1 , ~
    \int_compare:nNnTF { \clist_count:n {#2} } > 2
      { \__foo_list:w #2 \s_stop }
      { \__foo_two:w #2 \s_stop }
  }

\NewDocumentCommand{\Test}{}
{
  \foo_str_compare:nn{\Foo{A,B,C}}{A,~B~and~C}
}

\ExplSyntaxOff

\begin{document}

\Test

\end{document}

正如所指出的egreg 的回答,您的代码中存在各种不符合推荐模式的构造,而我已经避免使用这些构造。

答案2

您正在使用不可扩展的函数,但要想成功则必须具有可扩展性。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \foo_str_compare:nn
 {
  \tl_log:e { #1 }
  \str_if_eq:eeTF {#1} {#2}
   {PASS}
   {FAIL+#1+#2+}
 }
\cs_generate_variant:Nn \tl_log:n { e }

\NewDocumentCommand{\Test}{m}
 {
  \seq_gset_from_clist:Nn \l_tmpa_seq {#1}
  \foo_str_compare:nn{\seq_use:Nnnn \l_tmpa_seq{,~}{,~}{~and~}}{A,~B~and~C}
 }

\ExplSyntaxOff

\begin{document}

\Test{A,B,C}

\end{document}

此外,你还滥用\exp_args:...\exp_last_unbraced:...;例如,

\exp_args:NNx \tl_set:Nn \l_tmpa_tl { #1 }

更好的写法是

\tl_set:Nx \l_tmpa_tl { #1 }

并注意\str_if_eq:eeTF,以获得充分扩展。

您将获得“PASS”,并且在日志文件中,

> A, B and C.

由于强制扩张而造成的\tl_log:e

相关内容