在这答案 egreg 使用了宏\DeclareTextSymbol
,\DeclareTextCommandDefault
而\UndeclareTextCommand
我之前(但没有成功)尝试过简单的\newcommand
或\let
。
有人可以详细说明这些命令的正确用法以及与标准的区别等\newcommand
吗?
答案1
一些命令能够根据当前输出编码选择其操作。
最简单的例子就是重音符号。\"
当输出编码(即可用字形与字体中它们的位置之间的对应关系)为 OT1 或 T1 时,人们希望重音符号的行为有所不同。
在第一种情况下,\"u
将由重音符号和字符组成输出,而使用 T1 它将直接排版预组合字符(考虑连字符时,这种差异非常重要)。
\DeclareTextSymbol
因此,可以使用或类似的功能来定义命令,而不是维护在切换编码时更改定义的命令列表。
让我们看看\textborn
。它在基本 LaTeX 中未定义,但textcomp
提供了它的定义:
% textcomp.sty, line 225
\DeclareTextCommandDefault{\textborn}{\tc@check@symbol2\textborn}
知道替换文本应该做什么并不重要,但这定义\textborn
为
\?-cmd \textborn \?\textborn
(三个标记,最后一个是单个标记,其扩展是上述替换文本\tc@check@symbol2\textborn
,可以通过执行来访问\csname ?\string\textborn\endcsname
)。
稍后,当ts1enc.def
加载时,由于textcomp.sty
隐式调用\usepackage[TS1]{inputenc}
),LaTeX 会发现
\DeclareTextSymbol{\textborn}{TS1}{98}
这将起到与之前类似的作用,定义\textborn
为
\TS1-cmd \textborn \TS1\textborn
(再次是三个标记)。这是最重要的部分。这样的命令如何工作?
在 的扩展中\textborn
,如果 LaTeX 位于需要排版字符的位置,则将根据 TS1 检查当前输出编码。如果是,则只使用当前字体的字形编号 98;否则将打开一个组,将编码切换到 TS1,排版字符 98 并关闭该组。
这样的命令总是健壮的,这意味着如果在移动参数中找到它,它将产生自身,而不是在涉及写操作时扩展。
这应该可以解释你做以下事情时的困惑
\let\oldtextborn\textborn
在加载之前,和kpfonts
产生的输出之间没有任何区别。该包不会重新定义,而是根据所选的字体系列名称将新字体与 TS1 编码关联起来。因此和仍然相同。\textborn
\oldtextborn
kpfonts
\textborn
\oldtextborn
\textborn
对于定义\textborn
使用cmr
家庭,必须小心,因为像
\let\oldtextborn\textborn
\renewcommand\textborn{{\fontfamily{cmr}\selectfont\oldtextborn}}
不保证安全。例如,如果\textborn
出现在移动参数中,比如在章节标题或标题中,则文件.aux
将包含
\@writefile{toc}{\contentsline {section}{\numberline {1}{\fontfamily {cmr}\selectfont {\fontfamily {cmr}\selectfont \textborn }}}{1}}
其中命令似乎被扩展了几次。在其他情况下,这甚至可能导致无限循环。
涉及的策略\UndeclareTextCommand
肯定更安全。