부울 연산자를 사용하여 단어 목록 검색

부울 연산자를 사용하여 단어 목록 검색

현재 작업 중인 프로젝트에서 사용자는 프로젝트에서 정의한 환경 내에서 내부적으로 매크로(예: )에 저장된 태그 목록을 정의할 수 있습니다 \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 ) || garplythen \mytest{\userinput}{\tags}{true}{false}would return truewhile \mytest[1]{\userinput}{\tags}{true}{false} would return 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}

관련 정보