我在几个项目中使用相同的前言。已定义的命令集在不同的环境中有所不同。在一个项目中,\eps
已定义,而在另一个项目中则未定义。我希望定义\eps
为\varepsilon
。
如果您尝试定义一个命令,而该名称已被使用,那么您将得到类似 的结果
<error>
。如果您尝试重新定义一个命令,而该名称尚未被使用,那么您将得到类似 的结果<different error>
。
因此,在我的情况中,两者都不能使用。我可以像这样解决这个问题:
\ifdefined\eps
\renewcommand{\eps}{\varepsilon}
\else
\newcommand{\eps}{\varepsilon}
\fi
但这很笨拙。我不明白\renewcommand
如果命令不存在,为什么要抱怨。无论如何,我们都在提供我们想要的命令定义。
答案1
“为什么”的问题很难回答。在这种情况下,答案是“因为 Leslie Lamport 在 20 世纪 80 年代初选择了这个定义”。
但是如果\renewcommand
按照你的建议去做,那么它就相当于\newcommand
根本不检查所定义的命令。这将否定\newcommand
这样做的大部分原因,即保护用户免于意外重新定义 latex 内部结构并破坏系统。
正如 Steven 在您的问题下评论的那样,这种行为就像 TeX 原语一样\def
,它总是定义(或重新定义)提供的命令。即使现在,您也经常看到用户\def
在 latex 文档中使用并覆盖内部命令。
这个想法是,\newcommand
如果某些事情即将出错,你就会使用它并得到警告,然后只有当你知道可以这样做时,才使用它\renewcommand
进行重新定义。
您可以更简单地定义您的命令
\def\zzcommand#1{\let#1\undefined\newcommand#1}
它首先取消命令的定义,以便\newcommand
始终成功,然后尝试
\zzcommand\box{\fbox{X}}
例如。
答案2
如果其中一个环境\eps
已经定义为给出 epsilon 的形式之一,则只需执行
\providecommand{\eps}{\varepsilon}
\renewcommand{\epsilon}{\varepsilon}
并且将在两种环境中\eps
产生使用。\varepsilon
如果\eps
定义为做其他事情,那么你就完了。
为什么\renewcommand
如果输入了未定义的命令,就会犹豫不决?因为\renewcommand
应该小心使用,并且知道自己在做什么。
答案3
这是 Leo Liu 的回答中的一个简单例子这里。
\providecommand
\foo
仅当此命令先前未定义时才重新定义该命令。
如果\newcommand
定义了\foo
,那么\providecommand
将会保持沉默。
有了\providecommand
,就永远存在一个\foo
成为meh
的\renewcommand
。
我不确定这是否是最优雅的答案,但它非常简单明了。
\documentclass{article}
% (un)comment to change \providecommand behavior
\newcommand{\foo}{foo}
% if {\foo} not defined, then {\foo} is ``bla''
\providecommand{\foo}{bla}
% {\foo} will always become ``meh''
\renewcommand{\foo}{meh}
\begin{document}
{\foo}
\end{document}