
É 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 \delimiter
o 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 true
ou false
no documento se o argumento for um delimitador ou não, respectivamente.
Responder1
Não tenho certeza se isso pode ser útil para o seu \veca
problema. 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}
Como reconhecemos quando uma sequência de controle é um delimitador? Sua expansão de primeiro nível deve começar \delimiter
ou, se for um personagem, \delcode
deve 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 o
tipo 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 #1
e o restante torna- \q_nil
se #2
. O resto, isto é, #3
e #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_nil
está aí porque se você tentasse \isDelimiter{\empty}{T}{F}
não haveria nada na expansão; neste caso \q_nil
é considerado como #1
e #2
está vazio. Mas, como \q_nil
não é \delimiter
, tudo passa.