En expl3, ¿cómo probar si algo, una vez completamente expandido, contiene algún carácter perteneciente a las clases 11 o 12?

En expl3, ¿cómo probar si algo, una vez completamente expandido, contiene algún carácter perteneciente a las clases 11 o 12?

Me pregunto sobre expl3la sintaxis (sin usar las adiciones más recientes, digamos adiciones posteriores a 2018 [nada especial sobre 2018, es solo una fecha arbitraria para decirno demasiado reciente]) cómo probar si algouna vez completamente expandidocontienecualquier personaje que pertenezca a las clases 11 o 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}

Si uso \tl_if_blank:nTF, no 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}

Respuesta1

Suponiendo que podemos tratar grupos de llaves solo en el nivel superior, y eso {E}es equivalente a E, entonces podemos hacer

\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

Es posible perfeccionar el manejo de los aparatos ortopédicos, pero la pregunta no define claramente las expectativas en estas áreas.

El problema se vuelve más complicado con algo como \qquadse expande a \hskip 2em\relax, y que luego contiene catcode-11 y 12 tokens. Si asumimos que tales casos pueden estar cubiertos por

\usepackage{etoolbox}
\robustify\qquad

luego podemos proceder a obtener los resultados deseados con el código sugerido.

información relacionada