Comportamento instável de \@ifnextchar,

Comportamento instável de \@ifnextchar,

Quando compilo o MWE abaixo, o primeiro \@ifnextchar,sempre é avaliado como falso, o que está claramente errado no último caso. No entanto, o segundo (dentro \punctuationcheck) funciona perfeitamente. Por que a mesma condicional seria avaliada como False e depois True?

\documentclass{article}

\makeatletter
\newcommand{\punctuationcheck}{%
\@ifnextchar){I see a parens\relax}{%
\@ifnextchar]{I see a square bracket\relax}{%
\@ifnextchar.{I see a period\relax}{%
\@ifnextchar,{I see a comma\relax}{I didn' t see anything\ }}}}%
}
\newcommand{\ie}{\textit{i.e.}\@ifnextchar,{I saw a comma\relax}{I didn't see a comma,}\punctuationcheck}
\makeatother

\begin{document}
\ie) test

\ie] test

\ie. test

\ie, test
\end{document}

O que isso produz quando eu compilo:

ou seja, não vi vírgula, vi parênteses) teste

ou seja, não vi vírgula, vi colchete] teste

ou seja, não vi vírgula, vi ponto final. teste

ou seja, não vi vírgula, vi vírgula, teste

Responder1

A sintaxe de \@ifnextcharé

\@ifnextchar<test-token>{<true>}{<false>}<token>

Se <test-token>for igual a <token>, então o <true>código será inserido, caso contrário, <false>será inserido e o fluxo de entrada se tornará

<true><token>

ou

<false><token>

Observe que <token>não é removido nesta fase. A maneira correta de usar isso é ter \@ifnextchar<test-token>{<true>}{<false>}como parte final do código da macro, de modo que <token>será o que segue a macro.

No seu código, em vez disso, <token>já está especificado e é \punctuationcheck, então o TeX está certo em sempre usar o <false>código.

Solução:

\newcommand{\ie}{%
  \textit{i.e.}%
  \@ifnextchar,%
    {I saw a comma}%
    {I didn't see a comma,\punctuationcheck}%
}

informação relacionada