¿Cómo maneja TeX \else y \fi en condicionales?

¿Cómo maneja TeX \else y \fi en condicionales?

He visto paquetes usando

\def\afterelse#1\else#2\fi{\fi#1}

que TeX parece feliz de aceptar. Pero al tomar la primera rama, ¿no espera TeX \elseen lugar de \fi? Es decir, ¿no es la siguiente sintaxis correcta para la primera bifurcación? Esto también lo acepta TeX.

\def\afterelse#1\else#2\fi{\else#1}

EDITAR

Gracias a Egreg. El rastreo \ifmuestra lo que está sucediendo.

\def\loggingallstuff{%
  \tracinggroups\@ne\tracingifs\@ne\loggingall\tracingassigns\@ne
}

\def\afterelse#1\else#2\fi{\fi#1}

{\loggingallstuff
  %\edef\x{\iftrue\afterelse T\else F\fi}
  \edef\x{\iftrue T\else F\fi}
%  \edef\x{\iffalse T\else F\fi}
}

% \iftrue
{\edef}
{\iftrue: (level 1) entered on line 23}
{true}
{\else: \iftrue (level 1) entered on line 23}
{\fi: \iftrue (level 1) entered on line 23}
{changing \x=undefined}
{into \x=macro:->T}

% \iffalse:
{\edef}
{\iffalse: (level 1) entered on line 24}
{false}
{\else: \iffalse (level 1) entered on line 24}
{\fi: \iffalse (level 1) entered on line 24}
{changing \x=undefined}
{into \x=macro:->F}

He aquí un caso que me parece interesante:

\documentclass{article}
\usepackage{pgfkeys}
\makeatletter

\def\pgfkeysafterfi#1\fi{\fi#1}
%\def\pgfkeysafterelsei#1\else#2\fi{\fi#1}
\def\pgfkeysafterelsei#1\else#2\fi{\else#1} % wrong but gives no error.

\def\pgfkeysifkeydef#1#2#3{%
  \ifcsname pgfk@#1/.@cmd\endcsname
    \pgfkeysafterelsei{#2}\else\pgfkeysafterfi{#3}\fi
}
\pgfkeys{%
  /handlers/.if definable/.code 2 args={
    \pgfkeysifkeydef{\pgfkeyscurrentpath}{%
      \@latexerr{Oops, key '\pgfkeyscurrentpath' already exists}
        {You aren't in trouble here!}%
    }{%
      \pgfkeys{\pgfkeyscurrentpath/.default=#1,\pgfkeyscurrentpath/.code=#2}%
    }%
  }%
}
\pgfkeys{
  /fam/.is family,/fam/.cd,
  keya/.if definable=\relax\@empty,
  keya/.if definable=\@empty{\def\x##1{##1*#1}},
}
\makeatother
\begin{document}
x
\end{document}

Respuesta1

Usemos \iftruey \iffalsepara probar lo que sucede, asumiendo la definición

\def\afterelse#1\else#2\fi{\fi#1}

\iftrue

\iftrue\afterelse T\else F\fi

se convierte

\afterelse T\else F\fi

y la próxima expansión da

\fi T

\iffalse

\iffalse\afterelse T\else F\fi

se convierte

F\fi

y la expansión de \fiestá vacía.


Lo importante es que cuando se toma la rama "verdadera", solo se elimina la prueba, mientras que todo hasta e inclusive \elsese elimina cuando se toma la rama "falsa". Esto se puede ver en la siguiente sesión interactiva:

This is TeX, Version 3.1415926 (TeX Live 2011)
**\relax

*\toks0=\expandafter{\iftrue T\else F\fi}         

*\showthe\toks0
> T\else F\fi .
<*> \showthe\toks0

? 

*\toks0=\expandafter{\iffalse T\else F\fi}

*\showthe\toks0
> F\fi .
<*> \showthe\toks0

El código

\def\afterelse#1\else#2\fi{\else#1}

no es correcto, como se muestra en la siguiente sesión interactiva

This is TeX, Version 3.1415926 (TeX Live 2011)
**\relax

*\def\afterelse#1\else#2\fi{\else#1}

*\iftrue\afterelse T\else F\fi

*
(Please type a command or say `\end')
*\bye
! Incomplete \iftrue; all text was ignored after line 0.
<inserted text> 
                \fi 
<to be read again> 
                   \bye 
<*> \bye

información relacionada