私が現在取り組んでいるプロジェクトでは、プロジェクトで定義された環境内で、マクロ内に内部的に保存されるタグのリストをユーザーが定義できます (例: ) \tags
。このリストの各項目は、1 つ以上の単語と余分なスペースおよび数字で構成されます (例: )。\tags
{foo, bar, baz qux , quux2, Corge Grault}
\mytest
ユーザーが入力した 1 つ以上の単語がリストに属しているかどうかをテストし、テスト結果に応じてコードを実行するコマンドを定義する方法を知りたいです\tags
。ユーザーはブール演算子 (and、or、not) を使用でき、余分なスペースは削除され、検索で単語の大文字と小文字を区別するかどうかを決定するオプションがあるはずです。
たとえば、指定されたオプションのパラメータによって検索で大文字と小文字が区別されることを前提とすると、\tags={foo, bar, baz qux , quux2, Corge Grault}
および\userinput=(foo && BAR ) || garply
は\mytest{\userinput}{\tags}{true}{false}
を返し、 は を返しますtrue
。\mytest[1]{\userinput}{\tags}{true}{false}
false
[1]
この問題を解決するには LaTeX3 が特に役立つのではないかという気がしますが、残念ながら私には望む結果を達成できるほどの能力がありません。
どのような助けでも大歓迎です。
答え1
このコマンドには、大文字と小文字を区別するための\mytest
オプションがあります*
。
\str_map_inline:nn
2 番目の引数をループするために使用します。
このループ内の各項目に対して、が実行されます。次に、この要素が、、または で\tl_set_rescan:Nnn
あるかどうかが検証されます。|
&
(
)
関数\__searching_if_in:
は で始まります\tl_trim_spaces:N
。 を構築します\l__searching_boolean_expression_tl
。 最後に、 によって解釈されます\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}