Eu tenho uma função \Foo
que testo em relação ao que acho que deveria ser expandida para determinados argumentos. Dois problemas: 1/Não consigo 'registrar' a versão totalmente expandida do \Foo{arg}
. 2/mesmo quando a expansão parece correta olhando para a saída do pdf, os testes baseados em \str_if_eq:p
falham.
Aqui está um trecho do arquivo de log correspondente ao Gancho 1 no código:
\l_tmpa_tl=\Foo {A,B,C}.
Eu esperava no RHS =
uma versão expandida dele. Por que não é e pode ser feito?
Aqui está a saída correspondente ao Gancho 2 no código:
FAIL é o resultado do teste de igualdade da expansão \Foo {A,B,C}
, mostrada no LHS do meio +
, em relação ao RHS. De onde vem o desacordo?
\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}
Responder1
Você só pode realizar uma comparação de strings para material expansível. Você tem um comando de documento, \Foo
que é protegido, e também usa \seq_gset_from_clist:Nn
, que não é expansível. (Em interface3
, qualquer função não marcada com um asterisco não é expansível; em geral, qualquer coisa que execute uma atribuição ou composição tipográfica não será expansível.)
Reescrever para usar um mapeamento expansível para a lista de vírgulas leva a
\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}
Como observado emresposta da egrégia, você tem várias construções em seu código que não são o padrão recomendado e que evitei.
Responder2
Você está usando uma função não expansível onde a capacidade de expansão é necessária para ter sucesso.
\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}
Além disso, você está abusando \exp_args:...
e \exp_last_unbraced:...
; por exemplo,
\exp_args:NNx \tl_set:Nn \l_tmpa_tl { #1 }
é melhor escrito como
\tl_set:Nx \l_tmpa_tl { #1 }
e observe também \str_if_eq:eeTF
, para obter expansão total.
Você receberá “PASS” e, no arquivo de log,
> A, B and C.
devido à expansão forçada com \tl_log:e
.