TeX는 조건문에서 \else와 \fi를 어떻게 처리하나요?

TeX는 조건문에서 \else와 \fi를 어떻게 처리하나요?

나는 다음을 사용하는 패키지를 보았습니다.

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

TeX는 기꺼이 받아들이는 것 같습니다. 그러나 첫 번째 분기를 수행할 때 TeX는 \else대신에 를 기대하지 않습니까 \fi? 즉, 다음은 첫 번째 포크에 대한 올바른 구문이 아닌가요? 이것 역시 TeX에서 허용됩니다.

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

편집하다

에그레그에게 감사드립니다. 추적 \if은 무슨 일이 일어나고 있는지 보여줍니다.

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

제가 흥미롭게 생각하는 사례는 다음과 같습니다.

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

답변1

정의를 가정하고 무슨 일이 일어나는지 테스트하기 위해 \iftrue및 를 사용합시다 .\iffalse

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

\iftrue

\iftrue\afterelse T\else F\fi

된다

\afterelse T\else F\fi

그리고 다음 확장은

\fi T

\iffalse

\iffalse\afterelse T\else F\fi

된다

F\fi

확장은 \fi비어 있습니다.


중요한 점은 "true" 분기를 선택하면 테스트만 제거되고, \else"false" 분기를 선택하면 테스트를 포함한 모든 항목이 제거된다는 것입니다. 이는 다음 대화식 세션에서 볼 수 있습니다.

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

코드

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

다음 대화식 세션에서 볼 수 있듯이 올바르지 않습니다.

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

관련 정보