在 12pt 的文档里,LaTeX 的 \Huge 与 \huge 是 同一条命令。不是大小相近——size12.clo 第 86 行写着 \let\Huge=\huge,二者字面上就是一个东西。之所以如此,是因为从 \tiny 到 \Huge 这十条尺寸命令表示的是相对于正文的 相对档位 而非绝对尺寸,所以同一个 \large 在 10pt 文档里是 12pt,在 12pt 文档里则是 14.4pt。而且这一档档的刻度并非 LaTeX 的发明:这些数字正是 Knuth 写进 plain TeX 的 \magstep 取值。本页给出十条命令在 10pt / 11pt / 12pt 下的实测数值表,讲清写了 {\Large ...} 却只有字变大、行距没变的著名陷阱,以及 \fontsize 悄无声息地什么也不做时究竟发生了什么。
从 \tiny 到 \Huge — 十条声明
尺寸命令不带参数。它们不是 \textbf{...} 那样的命令,而是从落笔处起切换其后一切的声明,因此作用范围要靠你自己用分组或环境来划定。 从小到大共十条:\tiny、\scriptsize、\footnotesize、\small、\normalsize、\large、\Large、\LARGE、\huge、\Huge。区分档位的只有首字母大小写和全大写的 LARGE,所以要留意拼写而非外观。写 \Large{文本} 并不会把它当参数:那只是声明了 \Large,随后放下一个内含 {文本} 的分组,离开该分组时尺寸并不会恢复。要限定范围,就写 {\Large 文本}——把声明放进花括号里面。\normalsize 是正文尺寸,与 \documentclass 的尺寸选项一致(默认 10pt)。
% right: the declaration is inside the braces
Ordinary text. {\Large only this part is large.} Ordinary again.
% wrong: nothing is passed as an argument, and the size never comes back
Ordinary text. \Large{this is large} and so is everything after it.实际磅值随基准尺寸而变(10pt / 11pt / 12pt)
同一条命令,结果的磅值会随你传给 \documentclass 的是 10pt、11pt 还是 12pt 而变。 \large 在 10pt 与 11pt 类中都是 12pt,在 12pt 类中则是 14.4pt。下表是在标准文档类(article / report / book)中把十条命令逐一实际排出、并输出 \f@size 与 \baselineskip 得到的数值。每格按 字号 / 行距(相邻行基线之间的距离)的顺序排列。之所以连行距一并列出,是因为这样一眼就能看出:尺寸命令挪动的不只是字,行间也跟着一起动。
| 命令 | 10pt 文档类 | 11pt 文档类 | 12pt 文档类 |
|---|---|---|---|
\tiny | 5pt / 6pt | 6pt / 7pt | 6pt / 7pt |
\scriptsize | 7pt / 8pt | 8pt / 9.5pt | 8pt / 9.5pt |
\footnotesize | 8pt / 9.5pt | 9pt / 11pt | 10pt / 12pt |
\small | 9pt / 11pt | 10pt / 12pt | 10.95pt / 13.6pt |
\normalsize | 10pt / 12pt | 10.95pt / 13.6pt | 12pt / 14.5pt |
\large | 12pt / 14pt | 12pt / 14pt | 14.4pt / 18pt |
\Large | 14.4pt / 18pt | 14.4pt / 18pt | 17.28pt / 22pt |
\LARGE | 17.28pt / 22pt | 17.28pt / 22pt | 20.74pt / 25pt |
\huge | 20.74pt / 25pt | 20.74pt / 25pt | 24.88pt / 30pt |
\Huge | 24.88pt / 30pt | 24.88pt / 30pt | 24.88pt / 30pt(与 \huge 相同) |
顺着刻度看下去——12、14.4、17.28、20.74、24.88——每一档大约是上一档的 1.2 倍。这并非巧合。plain TeX 第 391 行写着 \def\magstep#1{\ifcase#1 \@m\or 1200\or 1440\or 1728\or 2074\or 2488\fi\relax}:Knuth 定下的放大倍率是 1200、1440、1728、2074、2488,也就是以千分率表示的 1.2 的一次方到五次方。LaTeX 较大的那五档原样沿用了这些数字。看着别扭的 10.95pt 同样来自紧上一行的 \def\magstephalf{1095 }——1.2 的平方根约 1.0954,取整而来。再往下看 latex.ltx 第 8915 行起的宏名,会发现名为「十四点」的 \@xivpt 定义为 14.4,名为「二十五点」的 \@xxvpt 定义为 24.88。名字是给人看的简称,数值才是那道放大倍率的阶梯。
这道阶梯停在 24.88pt,是因为那正是 Computer Modern 所提供的最大设计尺寸。 字体定义文件 ot1cmr.fd 里列出的尺寸是 <5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88> 共十二级——与尺寸命令所攀的那道梯子完全一致。所以在 12pt 文档类里,\huge 已经顶到 24.88pt 的天花板,size12.clo 第 86 行索性写 \let\Huge=\huge,把二者变成同一条命令。在 11pt 文档类里两者是不同的:\huge 为 20.74pt,\Huge 为 24.88pt。 若遇到「换成 \Huge 也不见变大」的症状,请先检查类选项是不是 12pt。以上数值全部针对标准文档类;jsarticle 等日文文档类、extsizes 以及 KOMA-Script 各有自己的刻度与上限,请勿照搬此表。
{\Large ...} 字变大了,行距却没变
因为段落的结束标记——空行或 \par——落在了右花括号外面。把它挪进分组里。 TeX 确定行距的时刻,不是排字符的时候,而是 把段落切分成行的时候。若段落的结尾在分组之外,到那一刻 \baselineskip 早已退回正文的值,于是大号字就按正文行距排了出来。在 10pt 文档类中对一个两行的 \Large(14.4pt)段落实测:\par 放在分组外时行距为 12pt,放在分组内时为 18pt。每行相差 6pt。
% right -- \par is inside the group, so the leading is 18pt
{\Large
A long paragraph that will wrap onto a second line and keep its leading.
\par}
% wrong -- the paragraph ends after the group, so the leading falls back to 12pt
{\Large A long paragraph that will wrap onto a second line and lose its leading.}
The next paragraph.这 6pt 在纸面上表现为行与行的相撞。\Large 的字形自基线向上伸出 9.99998pt,向下伸出 2.79999pt(用 \sbox 测得)。上下相加为 12.79997pt,比错误的 12pt 行距多出 0.8pt。也就是说,只要某一行有向下伸的字母(g、y、p),下一行又有向上伸的字母(h、k、l),这两者在纸上必然重叠。行数少时不易察觉,往往要等到把投稿用 PDF 打印出来才会显形。
两点补充。其一,加上 \selectfont 也无济于事:试排 {\Large\selectfont ...},实测仍是 12pt。问题不在字体选择,而在于段落排完那一刻 \baselineskip 的取值,所以除了挪动 \par 的位置别无他法。其二,这个症状 在 \centering 下会出现,在 center 环境下不会。写 {\centering \Large ... } 而把空行留在外面会得到 12pt,而 \begin{center} \Large ... \end{center} 实测为正确的 18pt——因为 \end{center} 会在关闭分组之前先结束段落。若居中的大标题行距不对劲,先怀疑是不是把 \centering 放进了一个裸的分组里。
任意尺寸 — \fontsize 与 \selectfont
若十个档位里没有你要的尺寸,可以用 \fontsize{尺寸}{行距}\selectfont 直接指定磅值。第一个参数是字号,第二个是行距。 海报标题,或表格里想单独压紧的一行,都是合理的「跳出阶梯」场合。这里的关键是:\fontsize 只是把数值记下来,什么也不选。实测显示,\fontsize{20}{24}x 中那个 x 宽 5.2778pt,与 \normalsize 下的 x 分毫不差。补上 \selectfont 后变为 10.05351pt,20pt 的字才真正出现。而且忘记写 \selectfont 既不报错也不警告。 「明明设了尺寸却没变」的报告,多半就是这个原因。
% \fontsize alone changes nothing and says nothing
{\fontsize{20}{24}Still 10pt.}
% \selectfont is what commits the change
{\fontsize{20}{24}\selectfont 20pt type on 24pt leading.}第二个参数不可省略,因此按惯例取字号的约 1.2 倍即可(20pt 大致配 24pt)。回看上面的表,标准文档类的比例大体也在这个范围内,比如 10pt / 12pt、14.4pt / 18pt。\tiny 之类的声明型命令会替你自动调整行距,而 \fontsize 则把这件事 交给你自己——这才是实务上最要紧的区别。设得太小,行就会因上一节所述的同一道理而重叠。若想加宽整篇文档的行距(比如 1.5 倍行距),那根本不是尺寸命令的活儿,请参阅讲行距的那一页。
尺寸命令在公式里不起作用
在数学模式里写尺寸命令,LaTeX 会忽略它,并在日志里留下一行。 排 $ \large x $ 会得到 LaTeX Font Warning: Command \large invalid in math mode on input line 9.。这是警告而非错误,编译继续进行,x 仍以普通大小输出。公式内部的大小属于另一套体系——由外围文字尺寸与数学样式(\displaystyle / \textstyle / \scriptstyle / \scriptscriptstyle)共同决定——不能与正文尺寸命令混用。若只是想把分数或求和号排大,用 \displaystyle。要放大整条公式,就在公式 外面 声明尺寸——{\Large $ ... $} 是有效的。
LaTeX Font Warning: Command \large invalid in math mode on input line 9.决定尺寸的顺序
字号要自上而下地决定,而不是一边写正文一边就地打补丁,这样才不会崩。 首先确定全文的基准尺寸,如 \documentclass[11pt]{...}。其次,凡是 反复出现 的东西——标题、图注、脚注、表注——都在文档类或宏包的配置里定尺寸,而不是每次在正文里手动指定。最后剩下的、真正「一次性」的场合——海报标题、表格中的补充说明——才用 {\small ...} 就地指定。守住这个顺序,日后把基准尺寸从 11pt 改成 12pt,整篇文档都会按比例跟着走。反之,若把局部指定撒进正文,改动基准尺寸的那一刻,恰恰是这些地方被落下。对于正文级数本就不同的海报或幻灯片,别用局部命令硬撑,一开始就选为该用途制作的文档类。
- 基准尺寸用类选项来定。 把整个正文裹进
{\small ...}容易破坏与脚注、标题、行距的协调,而且投稿规定写着「正文 11pt」时,这也算不得数。 - 别在正文里把章节标题放大。
\section的外观要通过文档类配置或titlesec之类的宏包来改。用正文里的\Large伪造标题,既不会进目录,也无法交叉引用。 - 重复出现的元素在定义处改。 若希望所有表注都小一号,就定义一个表注宏或环境,别在正文里逐个手动处理。
- 局部尺寸要在段落边界收口。 长而小的段落,请把
\par留在分组内部,让行距也按同一尺寸敲定。 - 缩小表格之前先怀疑结构。 在把整张表硬塞进
\scriptsize之前,先考虑删减列、横排,或拆成两张表。 - 按最终页面尺寸检查 PDF。 屏幕上读得清的,打印在 A4 的评审 PDF 上可能太小。要按实际尺寸看,而不是放大看。