超链接 (hyperref)

大多数 LaTeX 宏包都只管好自己的一亩三分地。hyperref 不是:为了把 \ref\cite、标题和目录变成 PDF 中可点击的链接,它从内部悄悄重新定义了相当多 LaTeX 自身的命令。这一个事实几乎解释了关于它的一切——手册为何反复叮嘱「最后加载」,为何唯独 cleveref 必须排在它之后,以及为何多数人第一件事就是关掉 每个链接周围那个红框。本页涵盖链接外观、\href\url、PDF 元数据与书签,以及标题里第一次出现数学公式时必定会遇到的那条警告。

只要在导言区写下 \usepackage{hyperref} 就够了:不做任何配置,文档中的每一个引用都会变成链接。\ref\pageref、用 \cite 做的文献引用、目录及图表目录中的每一项、脚注标记、索引条目——凡是能确定去向的都在其列。在 PDF 阅读器中点击即可跳到目标,URL 则在浏览器中打开。不过有时你并不想要链接。引用类命令都备有 带星号的形式\ref*{key}\pageref*{key}\autoref*{key} 只输出编号而不做成链接。

为什么 hyperref 要最后加载,以及唯一的例外

hyperref 应放在导言区的 几乎最后,理由就是开头说的:这个宏包的工作正是大量重新定义 LaTeX 命令。若在它之后再加载别的、也会改动同一批命令的宏包,那些重定义就会被覆盖,链接和书签会悄无声息地坏掉。hyperref 手册本身把这条建议写得很明白,并且加了一条脚注说明:削减重定义数量、从而降低对加载顺序依赖的工作已经开始。也就是说,这是当下的权宜之计,而非永恒的定律(宏包加载顺序本身在文档类与导言区那一页讲述)。

「最后」实际上只有一个例外:cleveref。它靠检测 hyperref 已定义的内容来构建自己的引用命令,所以顺序反过来根本行不通。这不会悄悄坏掉——TeX Live 2024 附带的 cleveref.sty 会在 \begin{document} 处检查顺序,并以 ! Package cleveref Error: cleveref must be loaded after hyperref! 中止。若还用到 varioref,顺序是 varioref → hyperref → cleveref。手册还明令禁止另一种写法:不要在 \AtBeginDocumentbegindocument 钩子内部加载 hyperref,因为 hyperrefnameref 自己也用这个钩子,执行时机会变得脆弱。若确需推迟加载,应使用 begindocument/before 钩子。

latex
\usepackage{graphicx}
\usepackage{amsmath}
% ... every other package ...
\usepackage{hyperref}   % almost last
\usepackage{cleveref}   % the exception: after hyperref

% With varioref in play, the prescribed order is:
%   varioref -> hyperref -> cleveref

默认情况下,hyperref 用一个 彩色方框 把链接框起来(colorlinks 默认为 false)。在屏幕上这确实醒目,但印到纸上就麻烦了:方框会被印出来,而链接功能在纸上根本不存在。读者只看到正文里散落着一些看不出用途的红色矩形——这正是「装了 hyperref 之后版面就毁了」这类感受的由来。配置方式有两种:加载时给选项,或事后用 \hypersetup{...} 以逗号分隔列出 key=value\hypersetup 写在导言区的任何位置都可以。

实践中大家第一个设的就是 colorlinks=true。它去掉方框,改为给 链接文字本身 上色,这样打印干净,屏幕上也好读。颜色按类型区分,默认 linkcolor 为红、citecolor 为绿、urlcolor 为洋红、filecolor 为青——这套配色是为了在显示器上便于分辨,直接用在投稿论文里则略显花哨。想收敛一些,用 allcolors 把它们统一成一个颜色最省事;若以打印为主,答案是 hidelinks:它既不上色也不加框,链接在外观上完全消失,但 仍然可以点击。最后这种搭配最适合常见情形——以 PDF 分发、同时也会被印在纸上阅读的文档。

选项效果默认
colorlinks去掉方框,改为给链接文字上色false
hidelinks无颜色无边框;仍可点击(适合打印)
linkcolor\ref 等内部链接的颜色red
citecolor\cite 文献引用的颜色green
urlcolor\url\href 中 URL 的颜色magenta
filecolor打开本地文件的链接颜色cyan
allcolors把上述所有链接颜色一次统一设为同一值
allbordercolors方框模式下一次性设定所有边框颜色
bookmarksnumbered在书签条目中包含章节编号false
bookmarksopen一开始就展开书签树false

\href\url — 通往外部世界的链接

外部 URL 的链接由两个命令生成。\href{URL}{display text} 把链接挂到任意文字上;\url{URL}把 URL 本身用等宽字体排出,同时做成链接。地址需要在正文中显示时用 \url,需要藏在其他文字后面时用 \href。它们真正的价值在于对参数的处理方式:URL 中常见的 LaTeX 特殊字符——%#~_——在 URL 部分可以直接照写,无需转义\url 的参数内仍有少量限制)。若只想要等宽外观而不需要链接,用 \nolinkurl{URL}

latex
See \href{https://www.ctan.org/pkg/hyperref}{the hyperref page on CTAN}.
% the words carry the link; the address is not shown

Download from \url{https://www.ctan.org/}.
% the address is typeset AND linked

\nolinkurl{https://example.com/a_b#c}
% monospaced, no link; underscore and hash need no escaping

Token not allowed in a PDF string\texorpdfstring

只要在标题里放进数学公式,hyperref 几乎必定给出这条警告。原因在于标题文字有 两个去处:一个是排版后正文中的标题,另一个是进入 PDF 书签的 纯字符串。按 PDF 规范,书签只是文本,所以 $^ 或像 \emph 这样的命令都进不去。hyperref 会把无法处理的记号逐个丢弃,并且每丢一个就报告一次。标题本身照样排得好好的,只有书签丢了内容——忽略这条警告,得到的正是这种悄无声息的退化。

log
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref)                removing `math shift' on input line 4.

Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref)                removing `superscript' on input line 4.

解决办法是 \texorpdfstring{给 TeX}{给 PDF 字符串}。第一个参数用于排版,第二个用于书签,于是标题拿到数学公式,书签拿到读法:\section{The value of \texorpdfstring{$x^2$}{x squared}}。有一处需留意:第二个参数同样会变成 PDF 字符串,所以在那里写 x^2 只是把警告转移到了 ^ 上。第二个参数里别留任何标记,只放 纯字符,比如 x squared 或 Unicode 的

PDF 元数据 — pdftitlepdfauthorpdfusetitle

hyperref 还会写入 PDF 的 文档信息——阅读器「文档属性」中显示的那些字段,文献管理软件导入的、许多搜索索引读取的也是它们。通过 \hypersetuppdftitle(标题)、pdfauthor(作者)、pdfsubject(主题)、pdfkeywords(关键词)来设定。若值中含有逗号或等号,会与键的分隔符冲突,因此 把值用花括号括起来 最稳妥:pdftitle={Foundations of Linear Algebra}

容易被忽略的是,这些字段与文档自身的 \title\author两回事。写了 \title 不会往元数据里放任何东西,反过来改了元数据也不会改变封面。若想让二者同步,就用 hyperref 的 pdfusetitle:它会从 \title\author 推导出 pdftitlepdfauthor,重复维护随之消失。但它必须作为宏包选项给出——写成 \usepackage[pdfusetitle]{hyperref}。若写成 \hypersetup{pdfusetitle},此时判定时点已过,于是 什么也不会发生,而且没有任何警告。若标题本身含有数学公式或 \\,那就又回到上一节的 \texorpdfstring 了。

书签 — 由标题自动生成的 PDF 大纲

书签(PDF 大纲)是阅读器在页面旁显示的可折叠标题列表。超过一百页的文档里,读者用它的次数远多于目录。hyperref 会从文档的章、节等标题 自动生成 书签(bookmarks=true 是默认值);想包含章节编号就加 bookmarksnumbered=true,想一开始就展开树形结构就加 bookmarksopen=true。书签要经过一个 .out 辅助文件,所以和目录一样,需要多次编译 才能稳定。

书签在复杂文档里乱掉——顺序错位、层级损坏、条目消失——标准做法是加载 bookmark 宏包,位置在 hyperref 之后。它替换 hyperref 较旧的书签代码,让 .out 的处理更稳定,还额外允许设置书签条目的 字重与颜色。细节调整通过 \bookmarksetup{...} 进行。它几乎没有额外开销,所以长文档里没有理由不从一开始就加上。

日文等非 ASCII 文字的书签乱码时

书签和元数据是 以字符串形式 写进 PDF 的,因此一旦其中含有日文、中文、西里尔字母等超出 ASCII 的内容,编码问题就会浮现。关键是 以 Unicode 输出。在 LuaLaTeX 与 XeLaTeX 中,unicode 默认启用,所以通常不加任何设置,中日文书签也能正确输出。若要显式声明,写 \usepackage[unicode]{hyperref}\hypersetup{unicode}

传统的 pLaTeX / upLaTeX + dvipdfmx 路线则是另一回事。标准做法是 \usepackage[dvipdfmx]{hyperref} 再加上 pxjahyper 宏包。pxjahyper 存在的目的正是在 (u)pLaTeX 下生成不乱码的日文书签,它随 TeX Live 一同提供。相关选项是 pdfencoding=auto,它会自动判断:字符串能落在 ASCII 内就保持原样,否则切换到 Unicode(主要面向 pdfTeX 系列;Unicode 引擎默认已是 Unicode,通常不需要)。一句话:LuaLaTeX 什么都不用做;(u)pLaTeX 加 pxjahyper

latex
% pLaTeX / upLaTeX + dvipdfmx
\usepackage[dvipdfmx]{hyperref}
\usepackage{pxjahyper}   % Japanese bookmarks without garbling

% LuaLaTeX / XeLaTeX: unicode is already the default
% \usepackage{hyperref}

hyperref 添加的引用命令 — \autoref\nameref

在做链接的同时,hyperref 还添了两种写引用的方式。\autoref{key} 用来代替 \ref,会按目标类型 自动前置对应词——小节得到 “section 3.4”,图得到 “Figure 3”——并把整体做成链接。前置词可通过重新定义 \figureautorefname\sectionautorefname 等来修改,本地化也是同一套办法。另一个 \nameref{key} 插入的不是编号,而是 标题文字本身:引用 \section{Introduction} 上的标签会得到 “Introduction”,正适合按题名而非编号引用的场合。若还需要多项引用和自动单复数,cleveref\cref\autoref 走得更远——完整对比在交叉引用那一页。

可以直接拿来用的 \hypersetup 配置

下面是实际文档最常落定的形态。colorlinks=true 去掉方框、给文字上色,颜色按类型分开,bookmarksnumbered 生成带编号的书签,pdfusetitle 让元数据与 \title\author 保持同步。若文档以打印为主,把从 colorlinksurlcolor 这四行换成一个 hidelinks 即可。 这样链接在页面上不再可见,而在 PDF 中阅读的人依然可以点击。

preamble
\title{Foundations of Linear Algebra}
\author{A. N. Author}

% pdfusetitle must be a PACKAGE option; inside \hypersetup it does nothing
\usepackage[pdfusetitle]{hyperref}   % almost last
\hypersetup{
  colorlinks=true,       % colour the text, not a box
  linkcolor=blue,        % \ref, \autoref, ToC entries
  citecolor=teal,        % \cite
  urlcolor=magenta,      % \url and \href
  bookmarksnumbered=true,
  pdfsubject={Lecture notes},
  pdfkeywords={LaTeX, linear algebra, vector spaces},
}
\usepackage{bookmark}    % after hyperref: sturdier bookmarks

% print-first alternative: replace the four colour lines with
%   hidelinks,