No expl3, como testar se algo, uma vez totalmente expandido, contém algum caractere pertencente às classes 11 ou 12?

No expl3, como testar se algo, uma vez totalmente expandido, contém algum caractere pertencente às classes 11 ou 12?

Estou pensando na expl3sintaxe (não usando as adições mais recentes, digamos adições posteriores a 2018 [nada de especial sobre 2018, é apenas uma data arbitrária para dizernão muito recente]) como testar se algouma vez totalmente expandidocontémqualquer personagem que pertença às classes 11 ou 12?

\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xparse}

\NewExpandableDocumentCommand{\mytest}{m m m}{
    % CODE HERE
}

\newcommand{\myempty}{}
\newcommand{\mywhitespace}{ }
\newcommand{\myquad}{\qquad}
\newcommand{\myrelax}{\relax}
\newcommand{\mystring}{ x }

\begin{document}
\begin{tabular}{c}
\mytest{\myempty}{true}{false} \\        % false
\mytest{\mywhitespace}{true}{false} \\   % false
\mytest{\myquad}{true}{false} \\         % false
\mytest{\myrelax}{true}{false} \\        % false
\mytest{\mystring}{true}{false} \\       % true
\end{tabular}
\end{document}

Se eu usar \tl_if_blank:nTF, não funciona:

\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xparse}

\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_blank:nTF{eTF}
\NewExpandableDocumentCommand{\mytest}{m m m}{\tl_if_blank:eTF{#1}{#3}{#2}}
\ExplSyntaxOff

\newcommand{\myempty}{}
\newcommand{\mywhitespace}{ }
\newcommand{\myquad}{\qquad}
\newcommand{\myrelax}{\relax}
\newcommand{\mystring}{ x }

\begin{document}
\begin{tabular}{c}
\mytest{\myempty}{true}{false} \\      % false: OK
\mytest{\mywhitespace}{true}{false} \\ % false: OK
\mytest{\myquad}{true}{false} \\       % true: PROBLEM
\mytest{\myrelax}{true}{false} \\      % true: PROBLEM
\mytest{\mystring}{true}{false} \\     % true: OK
\end{tabular}
\end{document}

Responder1

Supondo que possamos tratar grupos de chaves apenas no nível superior, e que {E}seja equivalente a E, então podemos fazer

\ExplSyntaxOn
\prg_new_conditional:Npnn \vincent_if_blank:n #1 { p , T , F , TF }
  { \exp_args:Ne \__vincent_if_blank:n {#1} }
\cs_new:Npn \__vincent_if_blank:n #1
  {
    \tl_if_blank:nTF {#1}
      { \prg_return_true: }
      {
        \tl_map_function:nN {#1} \__vincent_if_blank_aux:n
        \prg_return_true:    
      }
  }
\cs_new:Npn \__vincent_if_blank_aux:n #1
  {
    \tl_if_single_token:nTF {#1}
      {
        \bool_lazy_or:nnT
          { \token_if_letter_p:N #1 }
          { \token_if_other_p:N #1 }
          { \tl_map_break:n { \use_i:nn \prg_return_false: } }
      }
      { \tl_map_break:n { \use_i:nn \prg_return_false: } }
      
  }
\NewExpandableDocumentCommand{\mytest}{m m m}{\vincent_if_blank:nTF{#1}{#3}{#2}}
\ExplSyntaxOff

O refinamento do manuseio das cintas é possível, mas a questão não define claramente as expectativas nestas áreas.

O problema se torna mais complicado, algo como \qquadse expande para \hskip 2em\relaxe contém os tokens catcode-11 e 12. Se assumirmos que tais casos podem ser abrangidos por

\usepackage{etoolbox}
\robustify\qquad

então podemos prosseguir para obter as saídas desejadas com o código sugerido.

informação relacionada