しおりとメタデータ

hyperref を読み込んだ LaTeX 文書を、まっさらな状態から 1 回だけコンパイルしてみてください。できあがった PDF には しおり(アウトライン)が 1 件もありません。2 回目でようやく全部そろいます。理由はしおりの作られ方にあって、hyperref は見出しを jobname.out という別ファイルに書き出し、それを次の実行の冒頭で読み直してから PDF に入れるからです。このページでは、その仕組みと、.out ファイルごと捨てて 1 回で済ませる bookmark パッケージ、\hypersetup で入れる PDF メタデータ、新しい \DocumentMetadata の入口、そして日本語のしおりが文字化けする問題とその解決を、pdfinfo の出力で裏を取りながら見ていきます。

しおりは hyperref が見出しから自動生成する

\usepackage{hyperref} と書くだけで、\chapter\section\subsection から PDF のアウトラインができます。設定は読み込み時のオプションか \hypersetup{} で行い、よく使うのは 4 つ——bookmarks(既定でオン)、bookmarksnumbered(節番号もしおりに入れる)、bookmarksopen(開いた状態で表示)、bookmarksopenlevel=N(どの深さまで開くか)。ここで生まれる中間ファイル jobname.out は、覗いてみると LaTeX のマクロ呼び出しの列になっています。しかも文字列は素の見出しではなく UTF-16BE で書かれていて、英語の見出しでさえ \376\377\000C\000o\000v\000e\000r のように 1 文字ごとに \000 が挟まります。先頭の \376\377 は UTF-16 の BOM で、PDF の文字列がそう定められているからです。

latex
\usepackage[bookmarksnumbered,bookmarksopen,bookmarksopenlevel=1]{hyperref}
% or set the same keys later
\hypersetup{bookmarksopenlevel=1}
log
% report.out after three passes — hyperref stores the outline here
\BOOKMARK [0][]{cover.0}{\376\377\000C\000o\000v\000e\000r}{}% 1
\BOOKMARK [0][]{chapter.1}{...1 Foundations...}{}% 2
\BOOKMARK [1][-]{section.1.1}{...1.1 First section...}{chapter.1}% 3
\BOOKMARK [2][-]{subsection.1.1.1}{...1.1.1 A subsection...}{section.1.1}% 4

深さの既定値は、しおり側ではなく 目次側 から来ます。report クラスの tocdepth は 2(subsection まで)なので、\subsubsection を書いてもしおりには現れません。これは意図した動作で、目次としおりの粒度を揃えるためです。しおりだけ深くしたいときは bookmarksdepth を使います——実測で bookmarksdepth=4 を足すと、目次には出ない \subsubsection がしおりにだけ現れました。逆に bookmarksdepth=1 にすれば、節までで畳めます。

オプション効果既定
bookmarksしおりを作るかどうかtrue
bookmarksnumberedしおりの文言に節番号を含めるfalse
bookmarksopen開いた状態で表示するfalse
bookmarksopenlevelどの深さまで開いた状態にするか最大
bookmarksdepthしおりに載せる最大の深さtocdepth に従う

見出しのない場所にしおりを足す——\pdfbookmark

表紙・目次・番号のない前書きのように、見出し命令を通らない場所には \pdfbookmark[レベル]{表示する文字}{アンカー名} を直接置きます。第 1 引数のレベルは \chapter が 0、\section が 1 という数値で、第 3 引数のアンカー名は文書内で一意でなければなりません(重複すると destination が衝突します)。現在のレベルにそのまま足すなら \currentpdfbookmark{文字}{アンカー}、1 段深く足すなら \belowpdfbookmark{文字}{アンカー} があります。実務でいちばん多いのは目次自身にしおりを付ける場面で、\tableofcontents の直前に 1 行置くだけです——これがないと、読者は目次にだけ戻れないという妙な PDF ができあがります。

latex
\begin{document}
\pdfbookmark[0]{Cover}{cover}      % level 0, same rank as \chapter
\maketitle
\clearpage
\pdfbookmark[1]{Contents}{toc}     % the classic missing bookmark
\tableofcontents
\chapter{Foundations}

bookmark パッケージ——.out ファイルを捨てて 1 回で決める

Heiko Oberdiek の bookmark パッケージ(TeX Live 2024 同梱版は v1.31、2023-12-10)を hyperref後に読み込むと、しおりの生成機構がまるごと置き換わります。効果は測ればすぐ分かります——素の hyperref では、まっさらな状態からの 1 回目に作られた PDF に /Outlines が存在せず、2 回目でようやく 7 項目が入りました。bookmark を足すと 1 回目からすでに 7 項目そろっています。仕掛けは単純で、bookmark.out ファイルを書きません(実際、ディレクトリに .out が生成されなくなります)。しおりの情報を .aux 経由で回すので、古くなった別ファイルを読み直す段が消えるのです。hyperref 側のしおりは自動で無効化されるため、衝突の心配もありません。

もう一つの利点が装飾です。\bookmarksetup{}numbered(節番号を含める)、openopenlevel、そして項目ごとの色と字面——color=bluebolditalic——を指定できます。生成された PDF を覗くと、しおりの各項目に /C [ … ] という色エントリが実際に書き込まれています。個別の項目だけ変えたいなら \bookmarksetupnext{color=red} を直前に置きます。長い報告書で付録や索引だけ色を変えておくと、サイドバーの見通しが一気に良くなります。

latex
\usepackage{hyperref}
\usepackage{bookmark}      % must come after hyperref
\bookmarksetup{numbered, open, openlevel=1, color=blue}

% one entry only
\bookmarksetupnext{color=red, bold}
\chapter{Appendix}

PDF メタデータ——\hypersetup でタイトルと著者を名乗る

ビューアの「文書のプロパティ」に出る情報は \hypersetup{} の 4 つのキーで決まります——pdftitlepdfauthorpdfsubjectpdfkeywords\title\author からは自動で写されないので、両方に書く必要があります(hyperref\maketitle より前に値を知る必要があるためです)。設定したかどうかは pdfinfo を叩けば一目で分かります。pdfcreatorpdfproducer は作成ソフトを示す欄で、通常は自動で埋まります——hyperref を読み込んだ pdfLaTeX の出力なら Creator: LaTeX with hyperrefProducer: pdfTeX-1.40.26 です。この 2 つは書き換えられますが、あとで「何で作られたか」を追う手がかりが消えるので、触らないほうが無難です。

latex
\usepackage{hyperref}
\hypersetup{
  pdftitle={Measured Bookmarks},
  pdfauthor={Ada Lovelace},
  pdfsubject={PDF navigation},
  pdfkeywords={LaTeX, hyperref, bookmarks}
}
terminal
$ pdfinfo report.pdf
Title:           Measured Bookmarks
Subject:         PDF navigation
Keywords:        LaTeX, hyperref, bookmarks
Author:          Ada Lovelace
Creator:         LaTeX with hyperref
Producer:        pdfTeX-1.40.26
Pages:           5
Page size:       595.276 x 841.89 pts (A4)
PDF version:     1.5

アクセント付きの文字も、いまはそのまま書けます。hyperref 7.01h(TeX Live 2024 同梱)は内部で \Hy@unicodetrue を既定にしており、pdftitle={Théorie des catégories — Übersicht} は pdfLaTeX でもそのまま pdfinfo に出ます。かつて必要だった unicode オプションを明示的に足す必要はありません。ただし \hypersetup の値は PDF の文字列としてそのまま書き込まれるので、マクロを入れないことが実務上の鉄則です——pdftitle={\LaTeX{} の使い方} のように書くと展開に失敗しやすく、素直に pdftitle={LaTeX の使い方} と書くほうが確実です。

\DocumentMetadata——メタデータとタグ付けの新しい入口

\DocumentMetadata{…}\documentclass より に置く、LaTeX カーネルの新しい宣言です。TeX Live 2024 では実際に使え、lang=en-GB(文書の言語)、pdfversion=2.0(PDF のバージョン)、pdfstandard=A-2B(PDF/A の水準。A-1B から A-4 まで)、uncompress(圧縮をすべて止める)といったキーを受け付けます。1 行足すだけでも効果は目に見えます——pdfinfoMetadata Streamno から yes に変わり、PDF に XMP のメタデータストリームが入ります。\hypersetuppdftitle などはそのまま併用でき、両方の値が正しく PDF に入ることを実測で確認できます。

その先にあるのがタグ付き PDF です。testphase={phase-III} を足して pdflatex を 2 回回すと、pdfinfoTaggedyes に変わります——LaTeX が段落や見出しの構造を PDF の構造ツリーとして書き出しはじめた、という意味です。名前のとおりまだ試験段階の機能なので、投稿用の最終版で無条件に有効にするものではありませんが、動く状態のものが標準の TeX Live に入っているという事実は知っておく価値があります。なお \DocumentMetadata には 用紙サイズに関する副作用 があるので、既存の文書に足すときは PDF の寸法を確認してください(詳しくは「PDF の生成と制御」を参照)。

latex
\DocumentMetadata{pdfversion=2.0, lang=en-GB, testphase={phase-III}}
\documentclass{article}
\usepackage{hyperref}
\hypersetup{pdftitle={Tagged Test}, pdfauthor={Ada Lovelace}}
% pdfinfo then reports: Tagged: yes / Metadata Stream: yes / PDF version: 2.0

日本語のしおりが文字化けする——pxjahyperdvipdfmx オプション

upLaTeX + dvipdfmx で日本語のしおりを正しく出すには、2 つの手当てが要ります。1 つめは hyperref のドライバ指定です。\usepackage{hyperref} とだけ書くと、ログには Package hyperref Info: Driver (default): hdvips. と出ます——DVI を作っているのに、hyperref は dvips 向けの \special を書いてしまうのです。その DVI を dvipdfmx に食わせると dvipdfmx:warning: Unknown token "SDict"Interpreting special command ps: (ps:) failed. が並び、しおりもリンクも丸ごと消えた PDF ができます。\usepackage[dvipdfmx]{hyperref} と書けばログは Driver: hdvipdfm. に変わり、警告はゼロになります。

2 つめが文字コードです。ドライバを直すとしおりは出るようになりますが、日本語の見出しは æ鞥æ鲬èꪞã膮èꚋå螺ã膗 のような文字列に化けます。.out ファイルを覗くと理由が見えます——本来 は UTF-16BE で \145\345 の 2 バイトになるべきなのに、UTF-8 の 3 バイトがそれぞれ別の文字として扱われ、\000\346\000\227\000\245 のように水増しされているのです。ここで \usepackage{pxjahyper}(八登崇之 氏作、TeX Live 2024 同梱版は v1.3)を足すと、.out\376\377\145\345\147\054\212\236… という正しい UTF-16BE になり、pdfinfoTitle日本語のタイトル と読めるようになります。しおりだけでなく pdftitlepdfauthor も同時に直る点が重要です。

latex
% upLaTeX -> dvipdfmx: both lines are needed
\documentclass{ujarticle}
\usepackage[dvipdfmx]{hyperref}   % without this: dvipdfmx warning, no outline
\usepackage{pxjahyper}            % without this: mojibake in the outline
\hypersetup{pdftitle={...}, pdfauthor={...}}

この 2 段構えが要るのは (u)pLaTeX の DVI 経路だけです。LuaLaTeX + LuaTeX-ja なら素の \usepackage{hyperref} で正解にたどり着きます——ログには Driver (autodetected): hluatex. と出て、.out は最初から正しい UTF-16BE です。XeLaTeX + xeCJK でも同じく、追加のパッケージなしにしおりが読めます。日本語文書でしおりの文字化けに何度もやられているなら、エンジンを乗り換えるのが最短の解決策になることがあります。なお hyperref はできるだけ後ろで読み込むのが定石ですが、cleveref は必ず hyperref の後でなければならず、順序を間違えると ! Package cleveref Error: cleveref must be loaded after hyperref!. で止まります。varioref も併用するなら、hyperrefvariorefcleveref の順です。