为什么 LaTeX 内部命令中带有 @?

为什么 LaTeX 内部命令中带有 @?

@ 有什么具体含义吗?例如,它是否被替换了?它是否将命令拆分为多个部分,例如\s@foo在内部可能表示“类型为 s 的 foo”?@ 的目的是否只是为了在类定义或包之外使用时使内部命令中断?如果是这样,那怎么会是一件好事呢?

答案1

其他人提到了防止用户定义/重新定义的保护。另一个方面是命令名称(例如)\foo可能仅包含字母,因此\mymacro是有效命令,\my!macro不是。因此,普通用户无法重新定义这些命令,因为\newcommand{\my!macro}{....}会引发错误。您可以重新定义类别代码,!例如将其用作字母,以便将其\my!macro视为有效命令名称(TeX 语言中的控制字)。这就是\makeatletter的作用@\makeatother将 改@回符号(类别代码“其他”)。

答案2

当 Knuth 最初发布该语言时,他使用 来@标记用户通常不应使用的命令。这是为了避免通过重新定义来覆盖内核命令。请记住,使用 定义的宏\def将覆盖具有相同名称的早期命令。几年后,Lamport 和无数其他软件包编写者也效仿了 LaTeX。@只有在使用 时,才能在文档中的命令中使用 ,\makeatletter以便它可以更改其\catcode

\make@page@wider对我来说它还有另一个用途,作为分割长命令的标记,例如它比更易读\makepagewider

答案3

不,它没有任何具体含义;它只是用于“命名”不应出现在常规文档中的代码。您可以使用几乎任何您喜欢的非字母符号;ConTeXt 还允许?!,而 LaTeX3/expl3 则使用_:

虽然在 LaTeX 包代码中很少有关于如何使用的约定@,但对于 expl3,我们建议使用以下语法

\<module>_<function name>:<argument spec>

\<l/g/c>_<module>_<variable name>_<datatype>

分别用于函数(接受参数的宏)和变量。对于变量,前缀分别l为“本地”、g“全局”和c“常量”。

答案4

当您重新定义以 at 符号字符 命名的 LaTeX 命令时,请使用此对@\makeatletter声明使 at 符号字符具有字母的类别代码,即代码 11。声明 \makeatother将 at 符号的类别代码设置为代码 12,即其默认值。

当 TeX 读取字符时,它会为每个字符分配一个类别代码或 catcode。例如,它为反斜杠字符分配\catcode 0。命令名称由一个 0 类字符(通常为反斜杠)后跟字母、11 类字符组成(但命令名称也可以由一个 0 类字符后跟一个非字母符号组成)。

LaTeX 源代码有一个惯例,即某些命令的名称中使用 @。这些命令主要供包或类编写者使用。该惯例可防止仅使用包或类的作者意外地用自己的命令替换此类命令,因为默认情况下 at 符号的 catcode 为 12。

\makeatletter和组合\makeatother会更改默认代码,然后将其改回。在 .tex 文件中,在前言部分,当您定义或重新定义以 命名的命令时@,请将它们放在定义周围。不要在 .sty 或 .cls 文件中使用这些组合,因为\usepackage\documentclass命令已经安排好 at 符号具有字母的字符代码,即 catcode 11。

在此示例中,类文件包含用户想要更改的命令\thesis@universityname 。这三行应放在序言中,在 之前\begin{document}

\makeatletter
\renewcommand{\thesis@universityname}{Saint Michael's College}
\makeatother

我认为理解/makeatletter有助于理解@正在发生的事情。至少在我读完这个帖子后,它对我有帮助。以下是页面解释从何而来。

相关内容