Wie behandelt TeX \else und \fi in Bedingungssätzen?

Wie behandelt TeX \else und \fi in Bedingungssätzen?

Ich habe Pakete gesehen, die

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

was TeX anscheinend gerne akzeptiert. Aber erwartet TeX beim ersten Zweig nicht \elseanstelle von \fi? Das heißt, ist das Folgende nicht die richtige Syntax für den ersten Zweig? Auch dies wird von TeX akzeptiert.

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

BEARBEITEN

Danke an Egreg. \ifDie Verfolgung zeigt, was passiert.

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

Hier ist ein Fall, den ich interessant finde:

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

Antwort1

Verwenden wir \iftrueund \iffalseum zu testen, was passiert, unter der Annahme der Definition

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

\iftrue

\iftrue\afterelse T\else F\fi

wird

\afterelse T\else F\fi

und die nächste Erweiterung gibt

\fi T

\iffalse

\iffalse\afterelse T\else F\fi

wird

F\fi

und die Erweiterung von \fiist leer.


Wichtig ist, dass beim Wählen des "true"-Zweiges nur der Test entfernt wird, während \elsebeim Wählen des "false"-Zweiges alles bis einschließlich entfernt wird. Dies kann man in der folgenden interaktiven Sitzung sehen:

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

Der Code

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

ist nicht korrekt, wie die folgende interaktive Sitzung zeigt

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

verwandte Informationen