Поиск в списке слов с использованием булевых операторов

Поиск в списке слов с использованием булевых операторов

В проекте, над которым я сейчас работаю, пользователь может определить в среде, определенной проектом, список тегов, хранящихся внутри макроса (например, \tags). Каждый элемент в этом списке состоит из одного или нескольких слов и лишних пробелов и цифр (например, \tagsможет быть {foo, bar, baz qux , quux2, Corge Grault}).

Я хотел бы знать, как определить \mytestкоманду, которая будет проверять, принадлежат ли одно или несколько слов, предоставленных пользователем, списку \tags, и выполнять код в соответствии с результатом теста. Пользователь должен иметь возможность использовать булевы операторы (и, или, не), все лишние пробелы должны быть удалены, и может быть возможность определить, следует ли при поиске учитывать регистр слов.

Например, если \tags={foo, bar, baz qux , quux2, Corge Grault} и если \userinput=(foo && BAR ) || garplythen \mytest{\userinput}{\tags}{true}{false}вернут truewhile \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}

Связанный контент