大多数 LaTeX 宏包都只管好自己的一亩三分地。hyperref 不是:为了把 \ref、\cite、标题和目录变成 PDF 中可点击的链接,它从内部悄悄重新定义了相当多 LaTeX 自身的命令。这一个事实几乎解释了关于它的一切——手册为何反复叮嘱「最后加载」,为何唯独 cleveref 必须排在它之后,以及为何多数人第一件事就是关掉 每个链接周围那个红框。本页涵盖链接外观、\href 与 \url、PDF 元数据与书签,以及标题里第一次出现数学公式时必定会遇到的那条警告。
一行 \usepackage{hyperref} 会把什么变成链接
只要在导言区写下 \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。手册还明令禁止另一种写法:不要在 \AtBeginDocument 或 begindocument 钩子内部加载 hyperref,因为 hyperref 和 nameref 自己也用这个钩子,执行时机会变得脆弱。若确需推迟加载,应使用 begindocument/before 钩子。
\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 -> cleverefcolorlinks 与 hidelinks — 去掉那个没人想要的红框
默认情况下,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}。
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 escapingToken not allowed in a PDF string 与 \texorpdfstring
只要在标题里放进数学公式,hyperref 几乎必定给出这条警告。原因在于标题文字有 两个去处:一个是排版后正文中的标题,另一个是进入 PDF 书签的 纯字符串。按 PDF 规范,书签只是文本,所以 $、^ 或像 \emph 这样的命令都进不去。hyperref 会把无法处理的记号逐个丢弃,并且每丢一个就报告一次。标题本身照样排得好好的,只有书签丢了内容——忽略这条警告,得到的正是这种悄无声息的退化。
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 的 x²。
PDF 元数据 — pdftitle、pdfauthor 与 pdfusetitle
hyperref 还会写入 PDF 的 文档信息——阅读器「文档属性」中显示的那些字段,文献管理软件导入的、许多搜索索引读取的也是它们。通过 \hypersetup 用 pdftitle(标题)、pdfauthor(作者)、pdfsubject(主题)、pdfkeywords(关键词)来设定。若值中含有逗号或等号,会与键的分隔符冲突,因此 把值用花括号括起来 最稳妥:pdftitle={Foundations of Linear Algebra}。
容易被忽略的是,这些字段与文档自身的 \title、\author 是 两回事。写了 \title 不会往元数据里放任何东西,反过来改了元数据也不会改变封面。若想让二者同步,就用 hyperref 的 pdfusetitle:它会从 \title 与 \author 推导出 pdftitle 与 pdfauthor,重复维护随之消失。但它必须作为宏包选项给出——写成 \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。
% 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 保持同步。若文档以打印为主,把从 colorlinks 到 urlcolor 这四行换成一个 hidelinks 即可。 这样链接在页面上不再可见,而在 PDF 中阅读的人依然可以点击。
\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,