Detectar delimitador

Detectar delimitador

É possível verificar se um token é um delimitador, ou seja (, , ), |, \vert, \langle, \rangle, etc sem verificar diretamente cada um deles em uma condição?

A estrutura do delimitador está bem descrita aqui:https://tex.stackexchange.com/a/296650/213149. Parece usar \delimitero comando

Portanto, minha pergunta é como posso detectar esse delimitador de maneira um tanto versátil usando TeX puro ou LaTeX3.

Por exemplo, quero personalizar a macro \isDelimiter{...}para imprimir trueou falseno documento se o argumento for um delimitador ou não, respectivamente.

Responder1

Não tenho certeza se isso pode ser útil para o seu \vecaproblema. De qualquer forma…

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

insira a descrição da imagem aqui

Como reconhecemos quando uma sequência de controle é um delimitador? Sua expansão de primeiro nível deve começar \delimiterou, se for um personagem, \delcodedeve ser positiva.

A verificação de um personagem é, portanto, óbvia. Para uma sequência de controle precisamos primeiro ver se ela é expansível ou não. Mas também precisamos cuidar \{e \}que são um tanto especiais, então esses casos se resolvem sozinhos.

Se a sequência de controle que estamos examinando não for expansível, ela não será um delimitador (talvez outras exceções como \{e \}devam ser adicionadas com alguns pacotes de fontes). Se for expansível, olhamos para a sua expansão de primeiro nível chamando

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

portanto, o otipo de argumento fará a expansão de um nível necessária. Isto se tornará

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

A definição de \__antshar_isdel_exp_aux:wé

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

então o primeiro token na expansão da sequência de controle que estamos examinando torna-se #1e o restante torna- \q_nilse #2. O resto, isto é, #3e #4é o texto verdadeiro e falso para \isDelimiterTF. O primeiro argumento é indelimitado, portanto, levará o primeiro token no fluxo de entrada como argumento; o segundo argumento termina quando o TeX encontra \q_stop.

O estranho \q_nilestá aí porque se você tentasse \isDelimiter{\empty}{T}{F}não haveria nada na expansão; neste caso \q_nilé considerado como #1e #2está vazio. Mas, como \q_nilnão é \delimiter, tudo passa.

informação relacionada