Buscar en una lista de palabras utilizando operadores booleanos

Buscar en una lista de palabras utilizando operadores booleanos

En el proyecto en el que estoy trabajando actualmente, el usuario puede definir, dentro de un entorno definido por el proyecto, una lista de etiquetas, almacenadas internamente en una macro (por ejemplo, \tags). Cada elemento de esta lista consta de una o más palabras y espacios y números superfluos (por ejemplo, \tagspodría ser {foo, bar, baz qux , quux2, Corge Grault}).

Me gustaría saber cómo definir un \mytestcomando que probaría si una o más palabras proporcionadas por el usuario pertenecen a la \tagslista y ejecutaría un código de acuerdo con el resultado de la prueba. El usuario debería poder utilizar operadores booleanos (y, o no), se deberían eliminar los espacios superfluos y podría haber una opción para determinar si la búsqueda debe tener en cuenta las mayúsculas y minúsculas.

Por ejemplo, if \tags={foo, bar, baz qux , quux2, Corge Grault} y if \userinput=(foo && BAR ) || garplythen \mytest{\userinput}{\tags}{true}{false}devolvería truewhile \mytest[1]{\userinput}{\tags}{true}{false} devolvería false, suponiendo que el parámetro opcional [1]proporcionado significa que la búsqueda distingue entre mayúsculas y minúsculas.

Tengo la sensación de que LaTeX3 podría resultar particularmente útil para resolver este problema, pero lamentablemente no soy lo suficientemente competente para lograr el resultado deseado.

Cualquier ayuda sería bienvenida.

Respuesta1

El comando \mytesttiene una opción *para distinguir entre mayúsculas y minúsculas.

Se utiliza \str_map_inline:nnpara recorrer el segundo argumento.

En cada elemento de este bucle \tl_set_rescan:Nnnse realiza. Luego se verifica si este elemento es |, &, (o ).

La función \__searching_if_in:comienza con \tl_trim_spaces:N. Se construye \l__searching_boolean_expression_tl. Al final, esto es interpretado por \bool_if:nTF.

ingrese la descripción de la imagen aquí

\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}

información relacionada