根據字串檢查函數的擴展

根據字串檢查函數的擴展

我有一個函數\Foo,我根據我認為的給定參數應該擴展到的函數進行測試。兩個問題: 1/我無法「記錄」完全擴展的\Foo{arg}. 2/即使透過查看 pdf 輸出,擴展看起來是正確的,測試也失敗\str_if_eq:p

以下是代碼中與 Hook 1 對應的日誌檔案的摘錄:

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

我期待 RHS 的=擴展版本。為什麼不可以,可以嗎?

以下是程式碼中與 Hook 2 對應的輸出:

在此輸入影像描述

FAIL 是測試展開式 的相等性的結果\Foo {A,B,C},顯示在中間的 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它是受保護的,並且還有 use \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}

如中所述艾格格的回答,您的程式碼中有各種不是推薦模式的構造,我已經避免了這些構造。

答案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

相關內容