\DeclareTextSymbol 和 \DeclareTextCommandDefault 与标准 \newcommand 等相比

\DeclareTextSymbol 和 \DeclareTextCommandDefault 与标准 \newcommand 等相比

答案 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\oldtextbornkpfonts\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肯定更安全。

相关内容