目录/图目录与表目录 (tocloft)

\tableofcontents\listoffigures\listoftables 会收集标题和题注信息,自动生成目录、图目录和表目录。本页介绍它们的机制(辅助文件与两次处理)、深度控制、手动把星号标题加入目录的方法,以及用 tocloft 调整缩进、字体和点线引导的步骤。标题本身的基础留给“结构、标题与目录”页面;这里专注于这些列表的生成与 定制

三种自动列表与辅助文件

目录只需放置 \tableofcontents 即可生成。同样,\listoffigures 会从 figure 环境的题注生成图目录,\listoftables 会从 table 环境的题注生成表目录。通常把它们放在前置部分,也就是标题之后。

三者机制相同。LaTeX 在处理文档时,会把每个标题或题注的编号、标题和页码写入 辅助文件:目录用 .toc,图目录用 .lof,表目录用 .lot,文件名都与主文档(根文件)相同。下一次处理时,它会读回这些辅助文件来排版列表。

这带来一个 重要结论。第一次处理时辅助文件尚不存在(或已过期),因此列表会是空的或不准确。要得到正确结果,至少需要编译两次。官方参考也说明,第一次用于存储信息,第二次用于取回信息。若页码发生变化,还可能需要更多次;latexmk 等构建工具会自动重复直到稳定。

这些列表的标题来自与语言相关的宏:目录标题是 \contentsname(默认 “Contents”),图目录是 \listfigurename,表目录是 \listtablename,都可用 \renewcommand 改写。在 bookreport 中,这些标题会排成 无编号章(内部为 \chapter*),在 article 中排成无编号节。由于没有编号,这些列表本身默认不会进入目录;下面会说明如何手动添加。

document.tex
\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 中可为 partchaptersectionsubsection 等(会使用对应格式和缩进);在 lof 中是 figure;在 lot 中是 table
  • text — 要列出的文字。前置 \protect\numberline{} 可与编号条目的缩进对齐;其中任何脆弱命令都需要加 \protect

位置很重要:\addcontentsline 会记录处理到该行时的当前页码,因此应放在标题命令 紧接之后。星号标题的标准写法如下。页码由 LaTeX 自动补入,不要写进 text

latex
\section*{はじめに}
\addcontentsline{toc}{section}{はじめに}

\chapter*{謝辞}
\addcontentsline{toc}{chapter}{謝辞}

另一个 \addtocontents{ext}{text} 插入的不是条目行,而是 素材,例如空白或格式命令。它有两个参数:目标扩展名 ext 和要写入的内容 text。例如,要在图目录中插入垂直空白,可以这样写。由于 .lof 会在下一次运行时读回,像 \vspace 这样的脆弱命令需要 \protect。简言之:带页码的条目行用 \addcontentsline,空白和装饰用 \addtocontents

latex
\addtocontents{lof}{\protect\vspace{2ex}}   % 図目次に縦の空きを差し込む
\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}  % ここ以降の目次の深さを変える

用 tocloft 深入定制列表

若想细致控制标准列表的外观,常用的是 tocloft 包(Peter Wilson 编写)。用 \usepackage{tocloft} 载入后,可以通过 \renewcommand 和专用命令分别设置各层级的 缩进、编号宽度、字体、点线引导。命令名很有规律:把表示列表层级的前缀(toc = \partchap = \chaptersec = \sectionsubsec = \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足够大、表示不打印点的值用于移除引导线

下面的例子把节标题设为粗体,并让点线引导稍微密一些。写在导言区。

latex
\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 本身 不提供 这种自动添加功能。

latex
\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