我们已经看到这次精彩的讨论\def
关于和之间的区别\newcommand
。从答案来看,使用
\newcommand
优于的优点\def
是显而易见的。
为什么有些 LaTeX 宏使用 来定义\def
?
让我们逐一考虑这些情况。
最高级别(内核), latex.ltx
\def\newcommand{\@star@or@long\new@command}
以上很明显。LaTeX 基于 TeX,并且\newcommand
是 LaTeX 覆盖。
\newcommand
需要先使用 TeX 原语进行定义。如果没有这个,我们就无法继续前进引导。
但在此之后,仍然有那么多\def
s。(恐怕我的例子是随机挑选的,因此不代表某个类别。)
\def\@ifnch
\def\makeatletter
\def\makeatother
- 现在我们进入下一个级别,即文档类。
在文章.cls,每种举一个例子。
\newcommand\@ptsize{}
\def\ps@headings
在书籍目录,同样,每种类型随机取一个示例。
\newcommand\@chapapp
\def\@maketitle
在回忆录.cls,\def
里面\newcommand
(我并不一定声称上述情况不存在。)
\newcommand{\nametest}[2]{%
\samenamefalse
\begingroup
\def\@memtempa{#1} \def\@memtempb{#2}
\ifx \@memtempa\@memtempb
\endgroup
\samenametrue
\else
\endgroup
\fi}
我们再往前走一步,挑选包裹。fancyhdr.sty随机。我们发现
\def
和\newcommand
。\newcommand{\fancyhead} \def\@fancyerrmsg
我的问题是,为什么 LaTeX 同时使用
\def
和\newcommand
?
它是否像开发人员当时想使用的一样简单?
(作为 TeX 使用者,我仍然使用\def
,可能比 还多
\newcommand
。没有什么特别的原因。我只是出于习惯这样做。)
或者有更深层次的技术原因?
答案1
使用的一个主要原因\def
是,无论它是否已经存在,它本身都会定义某些东西。例如,使用 TeX,你可以定义
\def\mymacro{<stuff>}
并且不用担心\mymacro
这次调用之后会存在什么。相比之下,使用纯 LaTeX,人们必须(大致)
\makeatletter
\@ifundefined{mymacro}
{\newcommand{\mymacro}{<stuff>}}
{\renewcommand{\mymacro}{<stuff>}}
\makeatother
虽然有些 LaTeX 结构(在latex.ltx
)使用上述定义前检查,通常只是一个方便的选择\def
(\edef
,\gdef
或\xdef
)。
此外,TeX\def
允许指定非常强大的参数文本,并且无法使用纯 LaTeX 轻松复制(有关这方面的一些讨论,请参阅从 更改\def
为\newcommand*
)。
答案2
核心 latex 格式和文章等类别的大部分样式可以追溯到最初的 latex 2.x 及更早版本。请注意,它曾经采用分钟加载 article.sty(当时是这样)删除注释的整个过程(如今正式称为 dtx/doc 系统)是因为加载未注释的文件明显比加载注释的文件要快。在这种情况下,定义一个带有错误检查的高级命令系统供用户使用,但使用较低级别的宏定义几乎所有的核心功能绝对有意义。
LaTeX2e 对其进行了一点改动,但改动不大。我们当时做的一件事是在所有用户可访问的长度(例如或列\setlength
的宽度参数)中使用 latex 而不是原始长度设置,这样如果 加载了包,它们就会受到重新定义的影响。但大多数 def 仍保持为 def:-)minipage
p
\setlength
calc
尽管如此,考虑到 latex2e 的功能,在内部代码中使用这两种形式仍然有意义。以最后一个例子为例
\newcommand{\fancyhead}
这是顶级命令,如果已经定义,您可能会产生错误,因为发生了一些不好的事情,周围还有一些其他冲突的代码。
\def\@fancyerrmsg
但是一旦您决定要加载包,您可能只定义需要定义的内容而不检查所有内容,这样更快(现在不太重要,但这个包比 latex2e 旧 :-) 但您也不想在每个内部定义上都生成错误,理想情况下,您希望出现一个错误表明包发生冲突,或者如果一切正常则没有错误。
答案3
遗憾的是,这真的是开发人员的感受。有时是因为它曾经是 TEX,有时是因为“开发人员就是这么用的”。LaTeX 经过了几次修订,并且呈指数级增长,远远超出了预期,因此如此规模的代码库中存在“一些”怪癖是很自然的。
LaTeX3 应该有一个更清晰的界面来定义命令,你可以在这里阅读相关内容:LaTeX3