In dem Projekt, an dem ich gerade arbeite, kann der Benutzer innerhalb einer vom Projekt definierten Umgebung eine Liste von Tags definieren, die intern in einem Makro gespeichert werden (z. B. ). Jedes Element in dieser Liste besteht aus einem oder mehreren Wörtern sowie überflüssigen Leerzeichen und Zahlen ( könnte \tags
z. B. sein ).\tags
{foo, bar, baz qux , quux2, Corge Grault}
Ich möchte wissen, wie man einen \mytest
Befehl definiert, der prüft, ob ein oder mehrere vom Benutzer eingegebene Wörter zur \tags
Liste gehören oder nicht, und einen Code entsprechend dem Testergebnis ausführt. Der Benutzer sollte Boolesche Operatoren verwenden können (und, oder, nicht), alle überflüssigen Leerzeichen sollten entfernt werden und es könnte eine Option geben, um festzulegen, ob bei der Suche die Groß-/Kleinschreibung berücksichtigt werden soll oder nicht.
Beispielsweise würden „if“ \tags={foo, bar, baz qux , quux2, Corge Grault}
und „if \userinput=(foo && BAR ) || garply
then“ \mytest{\userinput}{\tags}{true}{false}
zurückgeben, true
während \mytest[1]{\userinput}{\tags}{true}{false}
„ zurückgeben“ würde false
, vorausgesetzt, dass der angegebene optionale Parameter [1]
bedeutet, dass bei der Suche die Groß-/Kleinschreibung beachtet wird.
Ich habe das Gefühl, dass LaTeX3 sich bei der Lösung dieses Problems als besonders hilfreich erweisen könnte, aber leider bin ich nicht kompetent genug, um das gewünschte Ergebnis zu erzielen.
Jede Hilfe ist herzlich willkommen.
Antwort1
Der Befehl \mytest
verfügt über eine Option *
zur Berücksichtigung der Groß- und Kleinschreibung.
Es führt \str_map_inline:nn
eine Schleife über das zweite Argument durch.
Für jedes Element in dieser Schleife \tl_set_rescan:Nnn
wird ausgeführt. Anschließend wird überprüft, ob dieses Element |
, &
, (
oder ist )
.
Die Funktion \__searching_if_in:
beginnt mit \tl_trim_spaces:N
. Sie konstruiert \l__searching_boolean_expression_tl
. Am Ende wird dies durch interpretiert \bool_if:nTF
.
\documentclass[border=6pt]{standalone}
\ExplSyntaxOn
\clist_new:N \l__searching_tags_clist
\tl_new:N \l__searching_accumulate_text_tl
\tl_new:N \l__searching_boolean_expression_tl
\tl_new:N \l__searching_text_item_tl
\cs_new:Npn \__searching_if_in:
{
\tl_trim_spaces:N \l__searching_accumulate_text_tl
\tl_if_empty:NF \l__searching_accumulate_text_tl
{
\clist_if_in:NVTF \l__searching_tags_clist \l__searching_accumulate_text_tl
{ \tl_put_right:Nn \l__searching_boolean_expression_tl { \c_true_bool } }
{ \tl_put_right:Nn \l__searching_boolean_expression_tl { \c_false_bool } }
}
\tl_clear:N \l__searching_accumulate_text_tl
}
\NewDocumentCommand { \mytest } { s m m m m }
{
\clist_set:NV \l__searching_tags_clist #3
\tl_clear:N \l__searching_accumulate_text_tl
\tl_clear:N \l__searching_boolean_expression_tl
\str_map_inline:nn {#2}
{
\tl_set_rescan:Nnn \l__searching_text_item_tl {} {##1}
\tl_if_in:nVTF { | & ( ) } \l__searching_text_item_tl
{
\__searching_if_in:
\tl_put_right:NV \l__searching_boolean_expression_tl \l__searching_text_item_tl
}
{
\IfBooleanTF {#1}
{ \tl_put_right:NV \l__searching_accumulate_text_tl \l__searching_text_item_tl }
{ \tl_put_right:Ne \l__searching_accumulate_text_tl { \text_lowercase:n { \l__searching_text_item_tl } } }
}
}
\__searching_if_in:
\bool_if:nTF { \l__searching_boolean_expression_tl } {#4} {#5}
}
\ExplSyntaxOff
\newcommand{\tags}{foo , bar , baz qux , quux2 , Corge Grault}
\begin{document}
\mytest{(foo && BAR ) || garply}{\tags}{true}{false}
\mytest*{(foo && BAR ) || garply}{\tags}{true}{false}
\mytest{ bAr & & foO }{\tags}{true}{false}
\mytest{ baz qux }{\tags}{true}{false}
\end{document}