Проверка расширения функции по строке

Проверка расширения функции по строке

У меня есть функция \Foo, которую я тестирую относительно того, во что, по моему мнению, она должна расширяться для заданных аргументов. Две проблемы: 1/ Я не могу «зарегистрировать» полностью расширенную версию \Foo{arg}. 2/ Даже когда расширение кажется правильным, судя по выводу pdf, тесты, основанные на , \str_if_eq:pтерпят неудачу.

Вот фрагмент файла журнала, соответствующего хуку 1 в коде:

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

Я ожидал на RHS =расширенной версии. Почему ее нет, и можно ли это сделать?

Вот вывод, соответствующий хуку 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, которая защищена, а также используйте \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.

Связанный контент