“参见图 3”“由公式 (2)”“见第 2 页”——如果手写这些编号和页码,只要移动一个图、表或小节,所有引用都会错位。LaTeX 的做法是给对象贴上名称,让机器计数。本页从核心的 \label 与 \ref/\pageref 开始,经过 amsmath 的 \eqref、hyperref 的 \autoref 和 \nameref,再到 varioref 与 cleveref,依次介绍能让引用自动保持正确的工具。
核心机制 — \label 与 \ref
整个相互引用系统只建立在两个命令上。\label{key} 会把名称 key 绑定到该位置最近一次递增的计数器的值。\ref{key} 则把这个名称指向的编号插入正文。编号由 LaTeX 计数,所以你完全不需要自己输入数字。key 是你自选的任意字符串,也就是源码中指代图、公式或小节的“昵称”。
关键在于“最近一次递增”的说法:\label 捕获什么,取决于它放在哪里。图或表应放在 \caption 之后(递增计数器的是 \caption;若放在 \begin{figure} 之后,可能会捕获章号等);公式应放在 equation 环境内部;标题应放在 \section 等命令之后。经验法则是:把 \label 紧跟在产生编号的命令后面。
\section{はじめに}
\label{sec:intro}
\begin{equation}
\label{eq:euler}
e^{i\pi} + 1 = 0
\end{equation}
\begin{figure}
\centering
\includegraphics{leaf}
\caption{葉脈の構造}
\label{fig:leaf}
\end{figure}
第\ref{sec:intro}節で述べたように、式~\ref{eq:euler}と図~\ref{fig:leaf}を参照する。\ref 只返回编号,因此“图”“公式”“节”等词需要自己写。惯例是用不可断空格 ~(tie)把词和编号连接起来,而不是普通空格,这样换行时词不会和编号分离(例如 Figure~\ref{fig:leaf})。后面介绍的 \autoref 和 \cref 正是用来消除这种手写词语的麻烦以及写错类型的风险。
为什么要编译两次
相互引用无法在一次编译中确定。LaTeX 每遇到一个 \label,都会把对应编号和页码写入 .aux 文件(与正文同名的辅助文件)。\ref 能使用的是上一次运行写入 .aux 的信息。因此第一次处理时目标编号还未知,输出中会出现粗体 ??,日志中也会给出下面的警告。
LaTeX Warning: Label(s) may have changed. Rerun to get cross references right.再编译一次后,.aux 中的值会被读回,?? 会变成正确编号。如果编号发生前后移动导致引用值改变,警告会再次出现,因此需要重复到警告消失为止(实际工作中通常两次足够)。latexmk 等构建工具会自动执行这个循环;Overleaf 也会在后台多次处理,所以你很少在那里看到 ??。
页码引用与命名
如果想引用的不是编号而是页码,使用 \pageref{key}。它接受与 \ref 相同的名称,并返回该 \label 所在页面的页码。这样就能同时写出编号和页码,例如“see Figure 3 on page 12”(Figure~\ref{fig:leaf} on page~\pageref{fig:leaf})。
key 可以是任何字符串,但广泛使用的做法是给它加上表示类型的前缀:sec:(节)、fig:(图)、tab:(表)、eq:(公式)、ch:(章)、lst:(代码清单)。这样有两个好处。像 fig:leaf 这样按含义命名,即使调整图片顺序也不必改标签名。并且一看 \ref{fig:...} 就知道目标类型,也能避免 caption 和代码清单的名称冲突。
| 前缀 | 用于 |
|---|---|
ch: | 章 |
sec: | 节和小节 |
fig: | 图 |
tab: | 表 |
eq: | 公式 |
lst: | 代码清单 |
公式引用 — \eqref(amsmath)
公式编号按惯例写成带括号的形式(“由公式 (3)”)。普通 \ref 只返回 3,需要手动补括号;加载 amsmath 后可用的 \eqref{key} 会自动补上括号,返回 (3)。更好的是,括号会不受周围字体影响始终以直立体排版,即使在斜体文本中也不会倾斜。引用公式时,\eqref 比 \ref 更方便。
\usepackage{amsmath}
% ...
式~\eqref{eq:euler}はオイラーの等式である。
% 出力: 式 (1) はオイラーの等式である。hyperref 扩展 — \autoref 与 \nameref
加载 hyperref 后,每个引用都会在 PDF 中变成可点击链接,并增加两个方便的引用命令。\autoref{key} 会根据目标类型自动在前面加上对应词,如 “Figure”“section”等(小节会得到 “section 3.4”,图会得到 “Figure 3”),并把整体做成超链接。这样就不必在 Figure~\ref{...} 中手写 “Figure”,也避免写错类型。前置词可通过重定义 \figureautorefname、\sectionautorefname 等来改变,这也是本地化的方法。
另一个命令 \nameref{key} 插入的不是编号,而是目标的标题文字本身。如果对 \section{Introduction} 上的标签使用 \nameref,就会得到 “Introduction” 这个标题文本。当你想按标题而不是编号引用时使用它,例如“as discussed in ‘Introduction.’”。
\usepackage{hyperref}
% ...
\autoref{fig:leaf}を参照。 % 出力: Figure 3 を参照。(リンク付き)
\nameref{sec:intro}で述べた。 % 出力: はじめに で述べた。感知页码的引用 — varioref
在装订文档中,与其机械地写“第 N 页的图”,若距离很近,说“下一页的图”,若在同一跨页,说“对页的图”,读起来更自然。varioref 的 \vref{key} 会像 \ref 一样输出编号,同时检查目标是否在另一页,并自动添加与页位置相关的文字,如 “on the next page”“on the facing page”“on page 5”。如果目标在同一页,则不添加任何内容。
如果只想给出页码提示,使用 \vpageref{key}(不输出编号,只输出“on the next page”等)。\vpageref 有两个可选参数:第一个指定目标在同一页时使用的文字,第二个指定目标不在同一页时的引导语。当引用和目标很近、可能会也可能不会被分页隔开时,这很有用。由于输出会随页面位置动态变化,varioref 通常可能需要额外一次编译才能稳定。
\usepackage{varioref}
% ...
See~\vref{fig:leaf}.
% 同ページ: See figure 3.
% 別ページ: See figure 3 on the next page. / ... on page 12.智能引用 — cleveref(\cref / \Cref)
cleveref 把引用提升了一个层级。\cref{key} 和 \autoref 一样会自动前置类型词(默认如 “fig. 1”,使用 noabbrev 选项则为 “figure 1”),但它真正的强项是多个引用和范围引用。像 \cref{a,b,c} 这样用逗号分隔且不加空格传入标签时,它会自动排序并压缩编号,输出 “figures 1, 2 and 3” 或 “equations~(2) and~(4)” 等,甚至会正确处理类型词的单复数。连续范围可用 \crefrange{first}{last} 缩成 “figures 1 to 3”。
句首需要类型词大写时,使用 \Cref{key}(首字母大写),用于 “Figure 3 shows …” 这样的开头;句中则用小写的 \cref。如果希望全文始终大写,可用 capitalise 选项加载。前置词可用 \crefname{type}{singular}{plural} 定义或修改(首字母大写版本是 \Crefname),这也是本地化到日语等语言的方法,例如 \crefname{figure}{図}{図}。如果只想像普通 \ref 一样输出编号,使用 \labelcref{key}。
加载顺序至关重要:cleveref 必须最后加载,并且在 hyperref 之后。如果也使用 varioref,顺序应为 varioref → hyperref → cleveref。顺序弄错时,引用可能在日志没有任何警告的情况下指向完全错误的对象。
\usepackage{varioref}
\usepackage{hyperref}
\usepackage{cleveref} % 必ず最後に / always last
% ...
\cref{fig:a,fig:b,fig:c} % figures 1 to 3
\cref{eq:euler,eq:max} % equations (1) and (4)
\Cref{sec:intro} discusses % Section 1 discusses ...如果不确定该用哪个,建议在整个文档中统一使用 cleveref。它会自动处理类型词、单复数、多个引用和范围,因此用 Figure~\ref{...} 方式可能出现的错误,例如想写 Figure 却写成 Table,就不会发生。
| 命令 | 输出内容 |
|---|---|
\label{key} | 给最近的计数器加标签(无输出) |
\ref{key} | 仅编号(如 3) |
\pageref{key} | 该标签所在页码 |
\eqref{key} | 带括号的公式编号(如 (3))/ amsmath |
\autoref{key} | 类型词 + 编号 + 链接(如 Figure 3)/ hyperref |
\nameref{key} | 目标标题文本 / hyperref |
\vref{key} | 编号 + 页码提示(下一页等)/ varioref |
\cref{key} | 类型词 + 编号;自动处理列表/范围 / cleveref |
\Cref{key} | 首字母大写的 \cref,用于句首 / cleveref |
\crefrange{a}{b} | 连续范围引用(如 figures 1 to 3)/ cleveref |