\section 或 \chapter 使用什么字体、编号方式以及前后空白,通常由文档类决定。titlesec 宏包(Javier Bezos 编写)让你可以在自己的导言区方便地重新设计这些外观。核心是两个命令:定义标题样式的 \titleformat,以及定义标题前后间距的 \titlespacing。文档结构本身在“结构、标题与目录”中介绍;这里专注于标题的*外观*。
先看快速设置
进入细致定义之前,titlesec 还提供了 仅通过宏包选项改变外观 的简易设置。例如用 \usepackage[sf,bf]{titlesec} 加载,会让所有标题变成无衬线加粗。选项分为三组,每组都有默认值,因此只需指定想改变的部分。
| 组 | 可选值 | 默认值 |
|---|---|---|
font / shape | rm sf tt md bf up it sl sc(字体族 / 粗细 / 字形) | bf |
size | big medium small tiny(标题大小) | big(与标准类相同) |
align | raggedleft center raggedright(对齐方式) | (取决于类) |
独立于这些设置,compact 选项可以压缩标题上下的空白。若要改变*编号*本身的输出方式,使用 \titlelabel:\thetitle 表示该标题的编号,标准类默认是 \titlelabel{\thetitle\quad}。如果只是想在编号后加一个句点,可以这样写。
\usepackage[sf,bf]{titlesec} % 見出しをサンセリフ+ボールドに
\titlelabel{\thetitle.\quad} % 「1.」のように番号のあとにピリオド如果“编号和间距保持不变,只改变字体”,星号形式 \titleformat* 是最短路径。第一个参数传入标题命令,第二个参数传入想应用的字体即可;标题的 *shape* 仍由类决定,只改变字面外观。
\titleformat*{\section}{\large\bfseries\sffamily} % \section の書体だけ差し替え用 \titleformat 定义外观
真正重新设计标题外观时使用(无星号的)\titleformat。它的参数很多,看起来吓人,但逐个看都很直观。整体形式如下。
\titleformat{⟨command⟩}[⟨shape⟩]{⟨format⟩}{⟨label⟩}{⟨sep⟩}{⟨before-code⟩}[⟨after-code⟩]⟨command⟩— 要重新设计的标题命令本身:\part、\chapter、\section、\subsection、\subsubsection、\paragraph、\subparagraph之一。[⟨shape⟩](可省略)— 标题的“形状”:hang、block、display、runin、leftmargin、frame等。默认是hang。{⟨format⟩}— 同时作用于编号和正文的格式。在这里统一指定字体、字号、对齐方式,例如\normalfont\Large\bfseries。{⟨label⟩}— 编号(标签)的输出方式,放入\thesection等。无编号层级可留空,但目录中也不会显示编号。{⟨sep⟩}— 标签与标题正文之间的间隔。必须写成长度,不能留空(在hang/block中为水平间隔,在display中为垂直间隔,在frame中为文字到边框的距离)。{⟨before-code⟩}— 在标题正文 之前 执行的代码。最后一个命令可以带一个参数,该参数会成为标题文字。[⟨after-code⟩](可省略)— 在标题正文 之后 执行的代码(hang/block/display中为垂直模式,runin/leftmargin中为水平模式)。
⟨shape⟩ 决定标题的基本布局。常用项如下。
| shape | 效果 |
|---|---|
hang | 默认值。编号悬挂,正文与其对齐(类似标准 \section) |
block | 把编号和正文作为一个块(段落)排版;适合居中标题和 picture 等特殊格式 |
display | 把标签放在正文上方的独立行(段落)中(类似标准 \chapter) |
runin | 行内标题:标题后不换行,正文在同一行继续(类似标准 \paragraph) |
leftmargin | 把标题放入左边距(rightmargin 是右边距版本) |
frame | 类似 display,但给标题加边框 |
用 \titlespacing 定义前后间距
与标题外观成对使用的是 \titlespacing,它设置标题周围的空白。通常使用带星号的 \titlespacing*。
\titlespacing*{⟨command⟩}{⟨left⟩}{⟨before-sep⟩}{⟨after-sep⟩}[⟨right⟩]⟨left⟩— 增加左边距的量(在leftmargin系形状中表示标题宽度;在runin中表示标题前的缩进)。⟨before-sep⟩— 标题 上方 的竖直空白。⟨after-sep⟩— 标题与正文之间的间隔(hang/block/display中为竖直,runin/leftmargin中为水平)。[⟨right⟩](可省略)— 在hang/block/display中增加右边距的量。
这里星号的含义很关键:带星号的 \titlespacing* 会抑制标题后第一个段落的缩进。LaTeX 有“标题后段落不缩进”的习惯,星号就是选择这种行为的标记(在 drop、wrap、runin 形状中,缩进抑制没有意义,因此星号无效)。所有参数都必须是 长度(dimension);包含 \stretch 等命令的值会报错。如果完整写 skip 值太麻烦,可以用 *4 这种 * 加数字的缩写,此时 \beforetitleunit 和 \aftertitleunit 作为单位。
组合示例
\titleformat 和 \titlespacing 通常成对编写。下面的导言区示例把 \section 改成这样的样式:左侧有一条细线,右侧用较大的无衬线粗体排列编号和标题。
\documentclass{article}
\usepackage{titlesec}
\titleformat{\section} % 対象は \section
[hang] % 形:番号をぶら下げる
{\sffamily\Large\bfseries} % 番号・本文に効く書式
{\thesection} % ラベル(番号)
{1em} % ラベルと本文の間隔
{} % 本文直前のコード(ここでは無し)
\titlespacing*{\section}
{0pt} % 左余白の追加なし
{3.5ex plus 1ex minus .2ex} % 見出しの上の空き
{2.3ex plus .2ex} % 見出しと本文の間の空き
\begin{document}
\section{はじめに}
本文がここから続きます。
\end{document}在这个 \titleformat 中,[hang] 选择悬挂编号的形状,{\sffamily\Large\bfseries} 同时作用于编号和标题。{\thesection} 输出 “1”“2” 等编号,{1em} 是编号与标题之间的空白。最后的 {} 是标题正文前的代码,这里不做任何事。后面的 \titlespacing* 不增加左边距(0pt),在标题上方留约 3.5ex,在标题与正文之间留约 2.3ex。plus/minus 是允许伸缩的量,用来帮助 LaTeX 平衡页面。由于带星号,\section 后的段落不会缩进。若要加横线,惯用做法是在 {⟨before-code⟩} 中放入 titlesec 的 \titlerule,并切换到 [display] 形状。
默认情况下,标题文字会隐式跟在 {⟨before-code⟩} 后面;但加上 explicit 选项后行为会改变,你必须用 #1 显式 放置标题文字(例如 \titleformat{\section}{..}{\thesection}{..}{#1.})。当你想在标题前后添加装饰时很有用。
用 titletoc 匹配目录及注意点
重新设计标题后,通常也会希望目录外观保持一致。为此,titlesec 带有姊妹宏包 titletoc(也可以单独使用)。核心命令是完整定义目录项的 \titlecontents,以及一次性创建带点线引导的常用样式 \dottedcontents。注意开头的 ⟨section⟩ 参数是 不带反斜杠的名称(如 section、chapter、figure 等)。
\usepackage{titletoc}
% 節の目次項目:点線リーダー付き(左寄せ 1.5em、ラベル幅 2.3em、リーダー幅 1pc)
\dottedcontents{section}[1.5em]{}{2.3em}{1pc}最后是两个常见陷阱。第一,\titlespacing 对 \chapter 和 \part 不会生效,除非同时用 \titleformat(或简易设置)改变其格式。\part 原本就是非标准实现,简易设置不会影响它;要改变它应使用 \titleformat。第二,titlesec 与 KOMA-Script 系列类(如 scrartcl)兼容性不好。KOMA-Script 会警告不推荐同时使用,并且会破坏多个功能,包括 headings 选项和章节命令的扩展可选参数。若使用 KOMA-Script,请不要用 titlesec,而应使用 KOMA 自身的机制,如 \setkomafont 或 \RedeclareSectionCommand。