
Cuando compilo el MWE siguiente, el primero \@ifnextchar,
siempre se evalúa como falso, lo que es claramente incorrecto en el último caso. Sin embargo, el segundo (dentro de \punctuationcheck
) funciona bien. ¿Por qué el mismo condicional se evaluaría como Falso y luego como Verdadero?
\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}
Lo que esto produce cuando lo compilo:
es decir, no vi una coma, veo una prueba de paréntesis
es decir, no vi una coma, veo un corchete] prueba
es decir, no vi una coma, veo un punto. prueba
es decir, no vi una coma, veo una coma, prueba
Respuesta1
La sintaxis de \@ifnextchar
es
\@ifnextchar<test-token>{<true>}{<false>}<token>
Si <test-token>
es igual a <token>
, entonces <true>
se inserta el código; de lo contrario, <false>
se inserta y el flujo de entrada se convertirá en
<true><token>
o
<false><token>
Tenga en cuenta que <token>
no se elimina en esta etapa. La forma correcta de usar esto es tenerlo \@ifnextchar<test-token>{<true>}{<false>}
como parte final del código de la macro, por lo que <token>
será lo que siga a la macro.
En su código, en cambio, <token>
ya está especificado y lo es \punctuationcheck
, por lo que TeX tiene razón en usar siempre el <false>
código.
Solución:
\newcommand{\ie}{%
\textit{i.e.}%
\@ifnextchar,%
{I saw a comma}%
{I didn't see a comma,\punctuationcheck}%
}