我目前正在研究宏(相当新),但我似乎缺少一些关于 LaTeX / TeX 宏的基本知识:
\def\car{Yes}
\def\iszero#1{
\ifnum#1=0{
\let \car = Yes
}
\else{
\let \car = No
}
\car
}
\iszero{1}
返回是。
我想知道为什么会发生这种情况,以及如何防止 LaTeX 过早地\car
用其当前值替换。
答案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 原始条件,因此两个分支是不是括号中的位置:相反,它们由条件的结尾、和\else
来分隔\fi
。\let
原语只能用于将一个标记分配给第二个标记的值:您不能使用它来定义宏,因为宏需要\def
。
答案2
TeX 条件的语法不使用括号来表示真和假分支。
也\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