
私は現在、マクロ(かなり新しい)をいじっていますが、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
取得するために を使用します。を使用すると、入力がカウンターである場合など、入力が評価される前に変更されるリスクがあります。Yes
No
\car
\def