Detectar delimitador

Detectar delimitador

¿Es posible comprobar si un token es un delimitador, es decir (, ), |, , \vert, \langle, \rangleetc. sin comprobar directamente cada uno de ellos en una condición?

La estructura del delimitador se describe bien aquí:https://tex.stackexchange.com/a/296650/213149. Parece usar \delimitercomando

Entonces mi pregunta es cómo puedo detectar dicho delimitador de una manera algo versátil usando TeX puro o LaTeX3.

Por ejemplo, quiero una macro personalizada \isDelimiter{...}para imprimir trueo falseen el documento si su argumento es un delimitador o no, respectivamente.

Respuesta1

No estoy seguro de que esto pueda ser útil para tu \vecaproblema. De todos modos…

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\isDelimiterTF}{mmm}
 {
  \antshar_isdel:Nnn #1 { #2 } { #3 }
 }

% first check whether #1 is a control sequence
\cs_new:Nn \antshar_isdel:Nnn
 {
  \token_if_cs:NTF #1
   {
    \__antshar_isdel_cs:Nnn #1 { #2 } { #3 }
   }
   {
    \__antshar_isdel_char:Nnn #1 { #2 } { #3 }
   }
 }

% it is a control sequence; first check the two exceptional cases \{ and \}
% which return true; otherwise go on: if the token is not expandable return false
\cs_new:Nn \__antshar_isdel_cs:Nnn
 {
  \str_case:nnF { #1 }
   {
    {\{}{#2}
    {\}}{#2}
   }
   {
    \token_if_expandable:NTF #1
     {
      \__antshar_isdel_csexp:Nnn #1 { #2 } { #3 }
     }
     {
      #3
     }
  }
 }

% the token is expandable, access its expansion
\cs_new:Nn \__antshar_isdel_csexp:Nnn
 {
  \__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
 }

% if the expansion begins with \delimiter return true, otherwise false
\cs_new:Nn \__antshar_isdel_exp:nnn
 {
  \__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
 }
\cs_generate_variant:Nn \__antshar_isdel_exp:nnn { o }

\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
 {
  \token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
 }

% when the token is a character, look at its \delcode;
% if positive return true, otherwise false
\cs_new:Nn \__antshar_isdel_char:Nnn
 {
  \int_compare:nTF { \delcode`#1 > 0 } { #2 } { #3 }
 }

\ExplSyntaxOff

\begin{document}

\verb|a|: \isDelimiterTF{a}{T}{F}

\verb|(|: \isDelimiterTF{(}{T}{F}

\verb|]|: \isDelimiterTF{]}{T}{F}

\verb|\langle|: \isDelimiterTF{\langle}{T}{F}

\verb-\|-: \isDelimiterTF{\|}{T}{F}

\verb|\{|: \isDelimiterTF{\{}{T}{F}

\verb|\lbrace|: \isDelimiterTF{\lbrace}{T}{F}

\verb|\mbox|: \isDelimiterTF{\mbox}{T}{F}

\end{document}

ingrese la descripción de la imagen aquí

¿Cómo reconocemos cuando una secuencia de control es un delimitador? Su expansión de primer nivel debe comenzar con \delimitero, si es un personaje, debe \delcodeser positivo.

Por tanto, la comprobación de un personaje es obvia. Para una secuencia de control primero necesitamos ver si es expandible o no. Pero también hay que cuidarlos \{y \}que son algo especiales, por eso estos casos se solucionan solos.

Si la secuencia de control que estamos examinando no es expandible, no es un delimitador (tal vez se deban agregar otras excepciones como \{y con algunos paquetes de fuentes). \}Si es expandible, miramos su expansión de primer nivel llamando

\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }

entonces el otipo de argumento hará la expansión de un nivel requerida. esto se convertirá

\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }

La definición de \__antshar_isdel_exp_aux:wes

\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
 {
  \token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
 }

entonces el primer token en la expansión de la secuencia de control que estamos examinando se convierte en #1y el resto \q_nilse convierte en #2. El resto, es decir, #3y #4son el texto verdadero y falso de \isDelimiterTF. El primer argumento no está delimitado, por lo que tomará el primer token del flujo de entrada como argumento; el segundo argumento termina cuando TeX encuentra \q_stop.

Lo extraño \q_nilestá ahí porque si lo intentas \isDelimiter{\empty}{T}{F}no habría nada en la expansión; en este caso \q_nilse toma como #1y #2está vacío. Pero como \q_nilno es así \delimiter, todo pasa.

información relacionada