\tableofcontents、\listoffigures、\listoftables 会收集标题和题注信息,自动生成目录、图目录和表目录。本页介绍它们的机制(辅助文件与两次处理)、深度控制、手动把星号标题加入目录的方法,以及用 tocloft 调整缩进、字体和点线引导的步骤。标题本身的基础留给“结构、标题与目录”页面;这里专注于这些列表的生成与 定制。
三种自动列表与辅助文件
目录只需放置 \tableofcontents 即可生成。同样,\listoffigures 会从 figure 环境的题注生成图目录,\listoftables 会从 table 环境的题注生成表目录。通常把它们放在前置部分,也就是标题之后。
三者机制相同。LaTeX 在处理文档时,会把每个标题或题注的编号、标题和页码写入 辅助文件:目录用 .toc,图目录用 .lof,表目录用 .lot,文件名都与主文档(根文件)相同。下一次处理时,它会读回这些辅助文件来排版列表。
这带来一个 重要结论。第一次处理时辅助文件尚不存在(或已过期),因此列表会是空的或不准确。要得到正确结果,至少需要编译两次。官方参考也说明,第一次用于存储信息,第二次用于取回信息。若页码发生变化,还可能需要更多次;latexmk 等构建工具会自动重复直到稳定。
这些列表的标题来自与语言相关的宏:目录标题是 \contentsname(默认 “Contents”),图目录是 \listfigurename,表目录是 \listtablename,都可用 \renewcommand 改写。在 book 和 report 中,这些标题会排成 无编号章(内部为 \chapter*),在 article 中排成无编号节。由于没有编号,这些列表本身默认不会进入目录;下面会说明如何手动添加。
\documentclass{report}
\begin{document}
\tableofcontents % .toc を使う(2 回処理が必要)
\listoffigures % .lof
\listoftables % .lot
\chapter{序論}
\end{document}目录深度 — tocdepth
哪些级别的标题会进入目录由 tocdepth 计数器决定。它的值是标题的 level 值(\section 为 1,\subsection 为 2,book/report 中的 \chapter 为 0,……),表示要列出的最深层级。因此 \setcounter{tocdepth}{1} 只列到节并省略小节;\setcounter{tocdepth}{2} 则列到小节。默认值是 article 中 3,book/report 中 2。
不要把它与控制编号的 secnumdepth 混淆。secnumdepth 决定标题 编号到多深,tocdepth 决定 目录列到多深,二者可以独立设置。例如,可以让标题编号到小节,但目录只列到节。图目录和表目录只有一个层级(图、表),所以不受 tocdepth 影响。
手动添加条目 — addcontentsline 与 addtocontents
星号标题(\section* 或 \chapter*)没有编号,也没有自动的页码引用,因此不会自行进入目录。若要让“引言”“致谢”、参考文献或索引出现在目录中,请用 \addcontentsline{ext}{unit}{text} 手动写入一行。三个参数都必不可少。
ext— 目标辅助文件的扩展名。目录用toc,图目录用lof,表目录用lot。unit— 条目类型。在toc中可为part、chapter、section、subsection等(会使用对应格式和缩进);在lof中是figure;在lot中是table。text— 要列出的文字。前置\protect\numberline{}可与编号条目的缩进对齐;其中任何脆弱命令都需要加\protect。
位置很重要:\addcontentsline 会记录处理到该行时的当前页码,因此应放在标题命令 紧接之后。星号标题的标准写法如下。页码由 LaTeX 自动补入,不要写进 text。
\section*{はじめに}
\addcontentsline{toc}{section}{はじめに}
\chapter*{謝辞}
\addcontentsline{toc}{chapter}{謝辞}另一个 \addtocontents{ext}{text} 插入的不是条目行,而是 素材,例如空白或格式命令。它有两个参数:目标扩展名 ext 和要写入的内容 text。例如,要在图目录中插入垂直空白,可以这样写。由于 .lof 会在下一次运行时读回,像 \vspace 这样的脆弱命令需要 \protect。简言之:带页码的条目行用 \addcontentsline,空白和装饰用 \addtocontents。
\addtocontents{lof}{\protect\vspace{2ex}} % 図目次に縦の空きを差し込む
\addtocontents{toc}{\protect\setcounter{tocdepth}{1}} % ここ以降の目次の深さを変える用 tocloft 深入定制列表
若想细致控制标准列表的外观,常用的是 tocloft 包(Peter Wilson 编写)。用 \usepackage{tocloft} 载入后,可以通过 \renewcommand 和专用命令分别设置各层级的 缩进、编号宽度、字体、点线引导。命令名很有规律:把表示列表层级的前缀(toc = \part,chap = \chapter,sec = \section,subsec = \subsection,……,图为 fig,表为 tab)与作用组合起来。
缩进和编号宽度 可用 \cftsetindents{entry}{indent}{numwidth} 一次设置。第一个参数是对象(如 section),indent 是从左边界起的缩进,numwidth 是为编号保留的宽度。也可以用 \setlength 直接调整单独的长度寄存器 \cftsecindent 和 \cftsecnumwidth。当编号位数变多并与标题相撞时,就加宽 numwidth。
字体 可分别控制条目文字和页码。\renewcommand{\cftsecfont}{...} 决定节条目标题的字体,\cftsecpagefont 决定其页码字体(章则为 \cftchapfont、\cftchappagefont)。列表自身标题的字体可用图目录的 \cftloftitlefont 等命令修改。
点线引导(标题和页码之间的一串点)由 \cftsecleader 控制。点的密度由长度 \cftdotsep(默认 4.5)决定:值越小越密,越大越疏。若要完全去掉引导线,可用 \renewcommand{\cftsecleader}{\cftdotfill{\cftnodots}}(\cftnodots 是一个足够大的值,表示“不打印点”)。点字符本身由 \cftdot 设置(默认是句点)。
| 命令 | 控制内容 | |
|---|---|---|
\cftsetindents | 一次设置该层级的缩进和编号宽度 | {entry}{indent}{numwidth} |
\cftsecfont | 节条目标题的字体 | 用 \renewcommand 重定义 |
\cftsecpagefont | 节条目页码的字体 | 用 \renewcommand 重定义 |
\cftsecleader | 节条目的点线引导 | 如 \cftdotfill{\cftdotsep} |
\cftdotsep | 引导点的间距(默认 4.5;越小越密) | 长度(mu 单位) |
\cftnodots | 足够大、表示不打印点的值 | 用于移除引导线 |
下面的例子把节标题设为粗体,并让点线引导稍微密一些。写在导言区。
\usepackage{tocloft}
\renewcommand{\cftsecfont}{\bfseries} % 節の題を太字に
\renewcommand{\cftsecpagefont}{\bfseries} % ページ番号も太字に
\renewcommand{\cftsecleader}{\bfseries\cftdotfill{\cftdotsep}} % 太字の点線リーダー
\renewcommand{\cftdotsep}{2} % 点をやや密に
\cftsetindents{section}{1.5em}{2.5em} % 字下げと番号幅把图目录和表目录放入目录
如前所述,\listoffigures、\listoftables(以及参考文献、索引)的标题没有编号,因此默认不出现在目录中。要让它们出现有两种方法。简单方法是在每个列表命令 正前方 放一行 \addcontentsline。注意,tocloft 本身 不提供 这种自动添加功能。
\cleardoublepage
\addcontentsline{toc}{chapter}{\listfigurename} % 図目次を目次に載せる
\listoffigures
\cleardoublepage
\addcontentsline{toc}{chapter}{\listtablename} % 表目次を目次に載せる
\listoftables另一种方法是载入 tocbibind 包(同样由 Peter Wilson 编写)。使用 \usepackage{tocbibind} 后,它会把存在的目录、图目录、表目录、参考文献和索引 自动加入目录。若要单独关闭某些项目,可用选项切换:nottoc(排除目录本身)、notlot(排除表目录)、notlof(排除图目录)、notbib(排除参考文献)、notindex(排除索引)。特别是参考文献或索引跨多页时,这比手写 \addcontentsline 更安全,也省去了手工行。
更高级的控制 — titletoc 与 etoc
如果需要超出 tocloft 的定制能力,有两个突出选择。titletoc(Javier Bezos 编写,是 titlesec 相关套件的一部分)可以按层级细致定义目录每一行的格式,包括行前后的素材和分隔。它提供强大的钩子来独立塑造各行,尤其适合已经用 titlesec 统一标题样式的文档。
etoc(Jean-François Burnol 编写)自由度更高,可通过“行样式”和“整体样式”的框架完全重新设计目录。它的亮点是 \localtableofcontents:可从同一个 .toc 为每章排出局部目录,甚至能把目录渲染成树状或思维导图等复杂形式。推荐顺序是先从 tocloft 试起,只有当想重做结构本身时再转向 titletoc / etoc。