在我目前正在處理的專案中,使用者可以在專案定義的環境中定義標籤列表,這些標籤列表內部儲存在巨集中(例如,\tags
)。此列表中的每一項都包含一個或多個單字以及多餘的空格和數字(例如,\tags
可能是{foo, bar, baz qux , quux2, Corge Grault}
)。
我想知道如何定義一個\mytest
命令來測試用戶提供的一個或多個單字是否屬於該\tags
列表,並根據測試結果執行程式碼。使用者應該能夠使用布林運算符(and、or、not),任何多餘的空格都應該被消除,並且可以有一個選項來確定搜尋是否應該考慮單字大小寫。
例如, if\tags={foo, bar, baz qux , quux2, Corge Grault}
和 if \userinput=(foo && BAR ) || garply
then\mytest{\userinput}{\tags}{true}{false}
將返回true
,而\mytest[1]{\userinput}{\tags}{true}{false}
將返回false
,假設[1]
提供的可選參數意味著搜尋區分大小寫。
我有一種感覺,LaTeX3 在解決這個問題上特別有用,但不幸的是我的能力不足以達到預期的結果。
任何幫助將是非常受歡迎的。
答案1
該命令\mytest
具有*
區分大小寫的選項。
它用於\str_map_inline:nn
循環第二個參數。
在此循環中的每個項目上\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}