[LaTeX] 把不編號章節加進目錄和 PDF 書籤
本文已加入專欄文章目錄,歸入「進階使用」文章系列。
本文涉及的宏包
hyperref
bookmark
,生成 PDF 書籤,依賴hyperref
tocbibind
,為目錄、參考文獻和索引生成目錄項
默認情況
章節命令(以 section
為例)
section [<short title>]{<long title>}
section*[<short title>]{<long title>}
分別生成編號和不編號的章節標題。默認情況下,
- 編號的章節標題,產生目錄項,即在
ableofcontents
生成的目錄中有對應的條目。 - 不編號的章節標題,不產生目錄項。
如果使用 hyperref
/bookmark
宏包來生成 PDF 書籤,那麼
- 編號的章節標題,還產生 PDF 書籤。點擊標題對應的書籤和目錄項,將跳轉到正文中章節標題出現的位置。
- 不編號的章節標題,不產生 PDF 書籤。
不編號章節舉例
以書籍舉例,序言、前言、參考文獻和索引部分的標題,是常見的不編號章節標題。特別地,由 ableofcontents
產生的目錄部分的標題,也是不編號的章節標題。
這些不編號章節,按生成方式,又有兩類
- 手動生成的,例如
section*{前言}
- 自動生成的,例如命令
ableofcontents
和printindex
就會自動生成目錄和索引部分的標題。這些命令的內部,也使用了帶星號的章節命令,如section*{...}
。
把不編號章節同時加入目錄和 PDF 書籤
手動生成的
section*{前言}
addcontentsline{toc}{section}{前言}
addcontentsline
必須出現在章節標題命令之後。
自動生成的
- 理論上,需要用戶了解並修改
ableofcontents
命令的定義,往裡加入addcontentsline
或類似命令。 - 實際上,已有宏包替用戶做了這類事,例如
tocbibind
宏包就提供了把目錄(toc
)、參考文獻(bib
)和索引(ind
)的標題加入目錄的功能。載入宏包,功能即生效。宏包文檔介紹了一些可配置項,例如只把索引加入目錄,而另兩項不動。 - 注意,
tocbibind
宏包重定義了相關命令(如ableofcontents
),如有其他宏包和文檔類修改了相同命令,可能遇到兼容性問題。
注意,把不編號章節加入目錄時,對應的 PDF 書籤會自動添加。每一條目錄項都有對應的 PDF 書籤,這是合理的默認行為。
把不編號章節僅加入 PDF 書籤
手動生成的
% preamble
% usepackage{bookmark}
section*{title 2}
% see definition of Hy@MakeCurrentHref in hyperref.sty
ookmark[dest=HyperLocalCurrentHref, level=1]{title 2}
說明
- 類似地,
ookmark
需要在章節標題命令之後使用。 dest
選項接受一個由hyperref
定義的超鏈接目標(destination)- 帶星號的章節標題命令(如
section*
)會創建一個新的超鏈接目標,並將其儲存在一系列命令中,HyperLocalCurrentHref
是其中的一個。(暫不清楚HyperGlobalCurrentHref
、HyperLocalCurrentHref
和@currentHref
在應用上的差異。) level
選項接受一個整數,用於表示書籤的(絕對)層級。類似的還有接受相對層級的rellevel
選項,詳見bookmark
宏包文檔 1.2.5 節。
自動生成的
- 理論上,同樣需要用戶了解並修改相應命令的定義。
- 實際上,筆者還沒發現提供相關功能的宏包。
不推薦的用法
只用 hyperref
宏包實現「把手動生成的不編號章節僅加入 PDF 書籤」,生成的書籤跳轉目標「不準」,需要做額外的調整。見本專欄之前的文章《(舊文)[LaTeX] - 使手動添加的 PDF 章節書籤跳轉到準確位置》。使用bookmark
宏包則沒有這個問題。
在 hyperref
的用戶文檔中,針對 PDF 書籤的功能,也推薦用戶使用 bookmark
宏包(見 hyperref
文檔 4.1.1 節末尾)。
所以,涉及手動生成 PDF 書籤時,推薦 bookmark
宏包。
比較完整的例子
下面的例子,集中展示了前文提到的幾種用法。
documentclass{article}
usepackage{lipsum}
usepackage{tocbibind}
usepackage[bookmarksopen=true]{hyperref}
usepackage{bookmark}
egin{document}
ableofcontents
section{abc}
lipsum
section{bcd}
lipsum
section*{title}
addcontentsline{toc}{section}{title}
subsection*{sub title}
addcontentsline{toc}{subsection}{sub title}
subsection*{sub title 2}
addcontentsline{toc}{subsection}{sub title 2}
lipsum
section*{title 2}
% see definition of Hy@MakeCurrentHref in hyperref.sty
ookmark[dest=HyperLocalCurrentHref, level=1]{title 2}
lipsum
end{document}
附記
一條不帶有鏈接跳轉的目錄項,它所需的只有三項信息(詳見本專欄文章《探索 LaTeX2e 格式:目錄項(外一篇:怎麼改 numwidth)》),
- 層級
- 內容(包括編號和文本)
- 頁碼
所以,更一般的情況下,addcontentsline
只需和對應的無編號章節目錄出現在同一頁,保證兩者的頁碼相同即可。
一條帶有鏈接跳轉的目錄項,它需要額外獲取跳轉目標的信息。PDF 格式支持的跳轉目標,可以儲存三項內容,
- 目標所在頁面(以絕對頁碼的形式)
- 目標在那一頁的橫縱相對位置
- 跳轉後的顯示狀態(如適應寬度、適應高度等)
詳見 PDF Ref v1.7, Sec. 8.2.1。在 hyperref
里,跳轉目標儲存在 @currentHref
。 所以,更一般的情況下,只需保證在無編號章節目錄和 ookmark
命令之間,@currentHref
儲存的信息不被刷新即可。
@currentHref
這個宏的命名方式,和 LaTeX2e 中儲存標籤信息的內部宏 @currentlabel
(本專欄文章《探索 LaTeX2ε 格式:計數器》有所提及)有相似之處。
推薦閱讀: