LaTeX 内核提供了“scratch”宏\@tempa
,ETC。, 和\reserved@a
,ETC。这些用途多种多样。一般用户/程序员应该将哪个用作临时空间?
答案1
LaTeX2.09 使用\@tempa
, ... 作为临时宏,但到设计 LaTeX2e 时,许多样式文件(包)都使用相同的“临时”宏,它们不再真正“安全”,因此我们\reserved@a
在格式代码中使用 ,...,并记录为其他包不能使用。因此\@tempa
和朋友现在没有特殊地位,尽管它们被广泛使用,因为许多常见包的历史可以追溯到 latex2.09(即 1994 年之前)。
但实际上,对于现在编写的任何包,根本不需要使用这些通用的临时宏。如果您的包名为wibble.sty
use \wibble@a
,\wibble@b
,... 等。
1994 年,在运行 emtex 的 640K PC 上,加载 latex2e+amsmath 后只剩下大约 50 个命令名,因此尽可能多地重复使用相同的命令名是有意义的。在现代 texlive 或 miktex 安装中,字符串池中通常有数十万个命令名可用,通过重复使用一些通用命令名来混淆代码并冒着与其他软件包发生冲突的风险,这可能是一种风险,没有实际的潜在收益。
答案2
宏\reserved@...
是仅供 LaTeX 团队使用:它们不应被其他人使用。另一方面,宏\@temp...
可供一般临时使用。
这是因为内核的低级部分需要有可靠的存储以供内部使用。该\reserved@...
系列提供了这一点,使用它们可能会导致看似不相关的代码出现意外问题。该系列不存在这种依赖\@temp...
。
如果你是修补内核宏并使用保留名称正如内核所做的那样,你当然可能需要使用一个。然而,这是一个极其有限的环境条件。
答案3
当从头编写可能被我以外的人使用的代码时,我倾向于在自己的命名空间内编写所有内容,其中每个宏名称都有自己的前缀,由项目/包的名称组成,后面跟着一个@
缩写,表示编写该代码的人。例如,对于我不使用\@tempa
但使用的项目 foobar \foobar@UD@tempa
。如果我可以轻松地在控制序列的名称中使用数字,那么在许多地方,我也会在命名空间前缀中包含版本号/提交日期。
例外:用户级宏的宏名。
除此之外,我倾向于仅在本地范围内重新定义任何不是我引入的“临时”宏,在完成生成任何框时,这些本地范围已经再次关闭,以便我的临时重新定义不会在输出例程运行时干扰。(人们可以在\globaldefs
可能具有正值的情况下获得乐趣。;-))
另一个问题是钩子喜欢\everypar
或被\everyeof
修改的宏。修改其他人的宏(例如内核中的临时宏)可能会影响由这些钩子触发的事情的完成方式。这反过来可能会导致问题。
例如,最近有一个帖子宏 - 指向自定义定理的不准确超链接\@labels
甚至在用户没有意识到的情况下,内核的寄存器框也发生了改变:
定理类环境的文本标签将嵌套在另一个类似 itemize 的环境中。首先,将用于排版定理类环境的标签和放置超链接锚点的材料放入 box-register 中\@labels
。定理类环境依赖于\everypar
排版该 box-register 的内容。但是在\everypar
执行 -hook 之前,由于 itemize-like-environment,该 box-register 的内容已被替换。这次使用的材料没有放置超链接锚点。因此 hyperref 功能被破坏。
因此,甚至在用户不知情/无意的情况下,改变内核内容的问题也可能发生。