\if
\ifeof
\IfFileExists
\def\IfFileExists#1#2#3{%
\openin\@inputcheck#1 %
\ifeof\@inputcheck
#3\relax
\else
\read\@inputcheck to \reserved@a
\ifx\reserved@a\today
\typeout{#1 found}#2\relax
\else
\typeout{BAD: old file \reserved@a (should be \today)}%
#3\relax
\fi
\fi
\closein\@inputcheck}
\long\def \IfFileExists#1#2#3{%
\openin\@inputcheck#1 %
\ifeof\@inputcheck
\ifx\input@path\@undefined
\def\reserved@a{#3}%
\else
\def\reserved@a{\@iffileonpath{#1}{#2}{#3}}%
\fi
\else
\closein\@inputcheck
\edef\@filef@und{#1 }%
\def\reserved@a{#2}%
\fi
\reserved@a}
\long\def\@iffileonpath#1{%
\let\reserved@a\@secondoftwo
\expandafter\@tfor\expandafter\reserved@b\expandafter
:\expandafter=\input@path\do{%
\openin\@inputcheck\reserved@b#1 %
\ifeof\@inputcheck\else
\edef\@filef@und{\reserved@b#1 }%
\let\reserved@a\@firstoftwo%
\closein\@inputcheck
\@break@tfor
\fi}%
\reserved@a}
\newif
\@ifundefined
\def\@ifundefined#1{%
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
用法
\@ifundefined{ControlSequenceName}{UndefinedCase}{DefinedCase}
↓\expandafter\ifx\csnameControlSequenceName\endcsname\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{UndefinedCase}{DefinedCase}
↓\ifx\ControlSequenceName\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{UndefinedCase}{DefinedCase}
\ControlSequenceName が未定義または \relax のとき
\@firstoftwo{UndefinedCase}{DefinedCase}
↓UndefinedCase
\ControlSequenceName が \relax 以外のものとして定義されているとき
\@secondoftwo{UndefinedCase}{DefinedCase}
↓DefinedCase
- \expandafter は \ifx \else \fi の処理を先に終了するためのもの.
- ControlSequenceName は展開可能な macro でも可.
例えば,
\makeatletter
\@ifundefined{somecs}
{\texttt{\@backslashchar somecs} is undefined.}
{\texttt{\string\somecs} is defined as \texttt{\meaning\somecs}.}
という処理を考えてみる. \somecs が未定義の場合, \somecs が \let または \def により \relax と定義されている場合で, 出力は以下のようになる.
%% when \somecs is undefined.
\somecs is undefined.
\let\somecs\relax
\somecs is undefined.
\def\somecs{\relax}
\somecs is defined as macro:->\relax .
\@ifundefined の引数は, \somecs の \ を取り除いた somecs になることに注意.
\@ifnextchar
\def\@ifnextchar#1#2#3{%
\let\reserved@d=#1%
\def\reserved@a{#2}\def\reserved@b{#3}%
\futurelet\@let@token\@ifnch}
\def\@ifnch{%
\ifx\@let@token\@sptoken
\let\reserved@c\@xifnch
\else
\ifx\@let@token\reserved@d
\let\reserved@c\reserved@a
\else
\let\reserved@c\reserved@b
\fi
\fi
\reserved@c}
\def\:{\let\@sptoken= } \: % this makes \@sptoken a space token
\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
\@testopt
\def\@testopt#1#2{%
\@ifnextchar[{#1}{#1[#2]}}
\@ifstar
\def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
用法
\@ifstar{WithStarCase}{WithoutStarCase}KeyLetter
- KeyLetter が * のとき,
\@ifnextchar *{\@firstoftwo{WithStarCase}}{WithoutStarCase}*
↓\@firstoftwo{WithStarCase}*
↓
となり, WithStarCase が処理される.WithStarCase
- KeyLetter が * ではないとき,
\@ifnextchar *{\@firstoftwo{WithStarCase}}{WithoutStarCase}KeyLetter
↓
となり, WithoutStarCase が処理される.WithoutStarCase KeyLetter
\@star@or@long
\def\@star@or@long#1{%
\@ifstar
{\let\l@ngrel@x\relax#1}%
{\let\l@ngrel@x\long#1}}
引数をとる必要性が判らない.
として, \l@ngrel@x を切替えれば充分なのではなかろうか.\def\@star@or@long{%
\@ifstar
{\let\l@ngrel@x\relax}%
{\let\l@ngrel@x\long}}