LaTeX が変数を置き換えないようにする

LaTeX が変数を置き換えないようにする

私は現在、マクロ(かなり新しい)をいじっていますが、LaTeX/TeX マクロに関するかなり基本的なことを見逃しているようです。

\def\car{Yes}
    \def\iszero#1{
    \ifnum#1=0{
        \let \car = Yes
    }
    \else{
        \let \car = No
    }
    \car
}
\iszero{1}

Yes を返します。

\carなぜこのようなことが起こるのか、また LaTeX が現在の値に早まって置き換えられるのを防ぐにはどうすればよいのか疑問に思っていました。

答え1

あなたが望む

\def\car{Yes}
\def\iszero#1{%
  \ifnum#1=0 % Terminate number with a space
    \def\car{Yes}%
  \else
    \def\car{No}%
  \fi
}
\iszero{1}

TeXのプリミティブ条件文を使用しているので、2つの分岐はないを中括弧で囲みます。代わりに、は条件の末尾、および で区切られます\else\fiプリミティブ\letは、1 つのトークンを 2 番目のトークンの値に割り当てるためにのみ使用できます。 を必要とするマクロの定義には使用できません\def

答え2

TeX 条件文の構文では、true および false の分岐に中括弧は使用されません。

また、\letあなたが考えているのとは違った動作をします。は(ほぼ) と同等に\let\foo=<token>なります。\foo<token>

\let\car = Yes

トークンYは に割り当てられ\car、 がes印刷されます (スキップされないブランチの場合)。 についても同様です\let\car = No

代わりにを使用する必要があります\def。ただし、 を必要としないより良い方法があります\car

プレーンTeXを前提とすると、

\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}

\def\iszero#1{%
  \ifnum#1=0
    \expandafter\firstoftwo
  \else
    \expandafter\secondoftwo
  \fi
  {Yes}{No}%
}

は機能します。この\expandafterトリックにより、条件付きテキストの残りが削除され、入力ストリームにまたは\firstoftwo{Yes}{No}が残ります。\secondoftwo{Yes}{No}

これは一般化できる

\def\IfIsZeroTF#1{%
  \ifnum#1=0
    \expandafter\firstoftwo
  \else
    \expandafter\secondoftwo
  \fi
}

呼ばれる

\IfIsZeroTF{1}{Yes}{No}

答え3

あるいは、比較を の定義内に配置します\car

%\def\car{Yes}%% Not needed for this example
\def\iszero#1{%
  \edef\car{%
    \ifnum#1=0
      Yes%
    \else
      No%
    \fi
  }}

False: \iszero{1}\car

True: \iszero{0}\car

またはのみを\edef取得するために を使用します。を使用すると、入力がカウンターである場合など、入力が評価される前に変更されるリスクがあります。YesNo\car\def

関連情報