Conditional

Last-modified: 2011-06-02 (木) 03:41:03

\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}
(Definition in latex.ltx ltdirchk.dtx)

\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}
(Definition in latex.ltx)

\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}
(Definition in latex.ltx)
  • 用法

    \@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}
(Definition in latex.ltx)
\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}
(Definition in latex.ltx)

\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}}}
(Definition in latex.ltx)
  • 用法

    \@ifstar{WithStarCase}{WithoutStarCase}KeyLetter

  • KeyLetter が * のとき,

    \@ifnextchar *{\@firstoftwo{WithStarCase}}{WithoutStarCase}*

    \@firstoftwo{WithStarCase}*

    WithStarCase

    となり, WithStarCase が処理される.
  • KeyLetter が * ではないとき,

    \@ifnextchar *{\@firstoftwo{WithStarCase}}{WithoutStarCase}KeyLetter

    WithoutStarCase KeyLetter

    となり, WithoutStarCase が処理される.

\@star@or@long

\def\@star@or@long#1{%
  \@ifstar
   {\let\l@ngrel@x\relax#1}%
   {\let\l@ngrel@x\long#1}}
(Definition in latex.ltx)
  • 引数をとる必要性が判らない.

    \def\@star@or@long{%

      \@ifstar

       {\let\l@ngrel@x\relax}%

       {\let\l@ngrel@x\long}}

    として, \l@ngrel@x を切替えれば充分なのではなかろうか.