在文章类中出现以下与字体选择相关的代码:
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal}
\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal}
代码中的命令到底起什么作用?
答案1
宣言
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
做
\DeclareRobustCommand\rm{\@fontswitch{\normalfont\rmfamily}{\mathrm}}
让我们看看当 LaTeX$\rm a$
在以下最小文档中找到时会发生什么:
\documentclass{article}
\begin{document}
$\rm a$
\end{document}
开始吧:
\rm ->\protect \rm
\rm
是一个强大的命令,因此这是它的正常扩展。现在,由于\protect
是\relax
,因此\rm
展开为:
\rm ->\@fontswitch {\normalfont \rmfamily }{\mathrm }
接下来\@fontswitch
展开:
\@fontswitch #1#2->\ifmmode \let \math@bgroup \relax
\def \math@egroup {\let \math@bgroup \@@math@bgroup
\let \math@egroup \@@math@egroup }#2\relax \else #1\fi
#1<-\normalfont \rmfamily
#2<-\mathrm
我们看到了参数。由于我们处于数学模式,因此遵循“真”分支,因此执行\math@bgroup
和的重新定义\math@egroup
并\mathrm
展开:
\mathrm ->\protect \mathrm
\mathrm ->\relax \ifmmode \else \non@alpherr \mathrm \fi
\use@mathgroup \M@OT1 \symoperators
\use@mathgroup #1#2->\relax \ifmmode \math@bgroup \expandafter
\ifx \csname M@\f@encoding \endcsname #1\else #1\fi \mathgroup #2\relax
\expandafter \math@egroup \fi
#1<-\M@OT1
#2<-\symoperators
再次,我们处于数学模式(\mathrm
有一些代码禁止在其外部使用);测试是使用扩展为的事实进行\f@encoding
的
\f@encoding ->OT1
现在还有待扩展\math@egroup
:
\math@egroup ->\let \math@bgroup \@@math@bgroup
\let \math@egroup \@@math@egroup
事情就结束了。本质上,这被转化为
${\mathrm{a}}$
如果{\rm a}
在文本模式下发现,那么它基本上就变成了
{\normalfont\rmfamily a}
也就是说,\rm
模拟命令的旧行为。
这就是为什么{\sf\sl a}
不使用倾斜的无衬线字体,而是使用倾斜的衬线字体:它相当于
{\normalfont\sffamily\normalfont\slshape a}
道德:绝不使用旧字体命令。你不会得到任何好处,而且会失去新命令的灵活性。好吧,18 年后它们不再真的新的。
答案2
深入研究source2e
得到以下信息:
[
\DeclareOldFontCommand
] 是用于创建声明性字体更改命令的函数,也可用于在数学模式下更改字母。
基本上,您引用的行只是使\rm
等\normalfont\rmfamily
在文本模式下等同于 在数学模式下等同于\mathrm
。这样做是为了让使用这些弃用字体命令的文档仍能与 LaTeX2e 正确配合使用。(请注意,使用声明性字体开关的正确方法是\rmfamily
等。)
脆弱和稳健的命令是 LaTeX 命令中最棘手的问题之一。在排版文档时,LaTeX 会使用 TeX 的许多功能,例如算术、定义宏和设置变量。但是,这些命令至少在三种不同情况下不安全。这些命令被 LaTeX 称为“移动参数”,包括:
- 将信息写入文件,例如索引或目录。
- 将信息写入屏幕。
- 在
\edef
、\message
、\mark
或其他命令中,它会充分评估其参数。LaTeX 用来使脆弱的命令变得健壮的方法是在它们前面加上
\protect
。[...]
[
\DeclareRobustCommand
] 是一个包编写器命令,其语法与 相同\newcommand
,但声明了一个受保护的命令。
本质上,使用\DeclareRobustCommand
保证当(例如)将带有的章节标题\cal
写入.aux
文件时不会发生任何奇怪的事情。
\DeclareOldFontCommand
\DeclareRobustCommand
内部使用。