阅读 koma 脚本源代码(更准确地说tocbasic.sty
),我发现从第 623 行开始有这样的代码:
\DefineFamily{KOMAarg}
\DefineFamilyMember[.toc]{KOMAarg}
\newcommand*{\DeclareNewTOC}[2][]{%
\newif\iftb@nt@float
% ...
\def\tb@nt@tocentrystyle{default}%
% ...
根据手册,该命令的语法为:\DeclareNewTOC[options]{extension}
。
如果我调用命令,那么@
(在这种情况下)的作用是什么?会扩展为什么?\tb@nt@
\DeclareNewTOC[float]{foo}
原因是我想更改我最后添加的命令(addtocentrystyle
)。
提前感谢任何帮助。
答案1
您听说过 LaTeX 中的类别代码的概念吗?
在标记化时,即从 .tex 文件读取输入并创建标记并将标记放入标记流时,LaTeX 仅将类别代码 11(字母)的字符作为多字母控制序列名称的组成部分。
通常字符a
...z
和A
...Z
属于类别代码11(字母)。
通常该角色@
的类别代码为 12(其他)。
因此通常在 .tex-input-files 中不能表示名称包含字符 的多字母控制序列@
。
@
因此,用于用户级的控制序列的名称中没有该字符 。
但是有控制序列\makeatletter
和\makeatother
。
\makeatletter
赋予字符@
类别代码 11(字母)。
\makeatother
赋予字符@
类别代码 12(其他)。
这意味着:
之后的\makeatletter
字符@
将在后续 .tex-input 的标记化过程中被视为类别代码为 11(字母)的任何字符;通常字符a
...z
和A
...Z
属于类别代码 11(字母)。
因此,\makeatletter
您可以在后续 .tex-input 中表示名称包含字符 的多字母控制序列@
。
(顺便说一句:您不需要在 .cls-files/documentclass-files 和 .sty-files/package-files 中使用\makeatletter
.. ,因为 LaTeX在处理此类文件时会自动给出类别代码 11(字母)。)\makeatother
@
通过\makeatletter
...\makeatother
机制,可以使用@
仅在控制序列名称中使用的字符不是旨在供用户直接调用。
概要:
@
控制序列名称中的字符如\iftb@nt@float
或\tb@nt@tocentrystyle
只是所讨论的控制序列名称的组成部分,如字符a
...z
和A
... Z
(通常)可以是控制序列名称的组成部分。
@
这些控制序列名称中包含的情况表明,代码的程序员/维护者希望它们不是供用户直接使用。
这也表明所讨论的控制序列标记的定义可能会在所讨论代码的未来版本中发生变化。
因此,当重新定义/修改由他人维护且包含@
控制序列名称的代码时,您不能依赖重新定义/修改来适合该代码的未来版本。
例如,在 LaTeX2e 内核的最新版本中,许多内部代码(包含@
控制序列的名称)发生了变化。此类变化可能会破坏内核宏的私有修改。;-)
答案2
在内部代码中,它很常用@
。这是通过分配@
字母的类别代码来实现的,这样它就可以像任何其他字母一样成为宏名称的一部分,为此,有宏\makeatletter
和反转其效果\makeatother
。这两个在包或类代码中不是必需的,因为 LaTeX 已经确保有@
一个字母。
因此,在您的代码片段中没有宏\tb@nt@
,但有一个名为的宏\tb@nt@tocentrystyle
,并且定义为扩展为default
,以及一个条件\iftb@nt@float
,它将扩展为\iftrue
或\iffalse
,此外,对于该条件,还有\tb@nt@floattrue
和\tb@nt@floatfalse
来切换条件(那些由创建\newif
)。