Ich habe eine Funktion \Foo
, die ich anhand dessen teste, was sie meiner Meinung nach für bestimmte Argumente erweitern sollte. Zwei Probleme: 1/ Ich kann die vollständig erweiterte Version von nicht „protokollieren“ \Foo{arg}
. 2/ Selbst wenn die Erweiterung beim Betrachten der PDF-Ausgabe richtig erscheint, schlagen die darauf basierenden Tests \str_if_eq:p
fehl.
Hier ist ein Auszug der Protokolldatei, die Hook 1 im Code entspricht:
\l_tmpa_tl=\Foo {A,B,C}.
Ich habe auf der rechten Seite =
eine erweiterte Version davon erwartet. Warum ist dies nicht der Fall und kann dies gemacht werden?
Hier ist die Ausgabe, die Hook 2 im Code entspricht:
FAIL ist das Ergebnis des Tests auf Gleichheit der Erweiterung \Foo {A,B,C}
, die links von der Mitte angezeigt wird +
, gegenüber der rechten. Woher kommt die Diskrepanz?
\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}
Antwort1
Sie können einen Zeichenfolgenvergleich nur für erweiterbares Material durchführen. Sie haben einen Dokumentbefehl, \Foo
, der geschützt ist, und verwenden auch \seq_gset_from_clist:Nn
, das nicht erweiterbar ist. (In interface3
ist jede Funktion, die nicht mit einem Sternchen gekennzeichnet ist, nicht erweiterbar; im Allgemeinen ist alles, was eine Zuweisung oder einen Satz durchführt, nicht erweiterbar.)
Das Umschreiben zur Verwendung einer erweiterbaren Zuordnung für die Kommaliste führt zu
\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}
Wie inegregs Antwort, Sie haben in Ihrem Code verschiedene Konstrukte, die nicht dem empfohlenen Muster entsprechen und die ich vermieden habe.
Antwort2
Sie verwenden eine nicht erweiterbare Funktion, obwohl für den Erfolg Erweiterbarkeit erforderlich ist.
\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}
Außerdem missbrauchen Sie \exp_args:...
und \exp_last_unbraced:...
; zum Beispiel
\exp_args:NNx \tl_set:Nn \l_tmpa_tl { #1 }
wird besser geschrieben als
\tl_set:Nx \l_tmpa_tl { #1 }
und beachten Sie auch \str_if_eq:eeTF
, um die vollständige Erweiterung zu erhalten.
Sie erhalten „PASS“ und in der Protokolldatei
> A, B and C.
aufgrund der erzwungenen Erweiterung mit \tl_log:e
.