在我目前正在进行的项目中,用户可以在项目定义的环境中定义一个标签列表,这些标签列表内部存储在宏中(例如\tags
)。此列表中的每个项目都由一个或多个单词以及多余的空格和数字组成(例如,\tags
可以是{foo, bar, baz qux , quux2, Corge Grault}
)。
我想知道如何定义一个\mytest
命令来测试用户提供的一个或多个单词是否属于列表\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
循环第二个参数。
在此循环中,对每一项\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}