hyperref パッケージは PDF の注釈機能を用いて実現されている
PDF(Portable Document Format)形式の文書を読んでいると、時折ハイパーリンクが埋め込まれた箇所を見掛けることがあります。これは PDF における注釈機能によって実現されているものです。
hyperref パッケージ
LaTeX における hyperref パッケージは、文書内へのハイパーリンクの埋め込みを実現するコマンドです。\url
や \href
コマンドを記述した文書をコンパイルすると図 1 の出力が得られ、色付きの矩形に囲われた領域をクリックすることで、指定された Web ページへとジャンプできます。
\documentclass{jarticle}
\usepackage[dvipdfmx]{hyperref}
\usepackage{pxjahyper}
\begin{document}
\url{https://example.com} のように URL を直接埋め込めるほか、
Markdown における \verb|[Example Domain](https://example.com)| に相当する
\href{https://example.com}{Example Domain} といった記述もサポートされている。
\end{document}
図 1:LaTeX における \url, \href コマンドの出力
さて PDF の仕様において、このハイパーリンクはどのように定義されているのでしょうか。ディスプレイ上では表示されるものの、印刷すると消失する謎の枠線も気になるところです。
注釈
PDF の仕様書としてお馴染み PDF References sixth edition を参照してみると、URL へのジャンプといったインタラクティブな行為はアクションとして定義され、アクションのトリガとして注釈・しおりが指定されています。hyperref のように文書中にリンクを設ける場合は注釈が用いられます。
注釈やしおりは、文書中のある場所への移動の代わりに、アプリケーションの起動、音声の再生、注釈の表示の変更といった、ビューアが実行するアクション(PDF 1.1)を指定できます。注釈・しおり項目の辞書内の
A
エントリ(任意、p. 606 8.15, p.585 8.4を参照)に、注釈・しおり項目が有効化したときに実行するアクションを指定します。
出典:Adobe Systems Incorporated: PDF References sixth edition - Adobe® Portable Document Format Version 1.7, p.647(筆者訳)
Annotation dictionaries
PDF ファイルは連鎖的な辞書構造を用いて構成されます。
今回使用する注釈を定義するには、Annotation dictionaries と呼ばれる辞書を定義します。定義した 1 つ以上の Annotation dictionaries を、Page Objects の Annots
エントリに配列として記述することで、ページに注釈が関連付けられます。
Annotation dictionaries は、以下のエントリを要求します(リンクの記述に必要なエントリのみを抜粋)。
エントリ名 | 型 | 必須 | 詳細 |
---|---|---|---|
Type | name | o | Annot |
Subtype | name | o | 注釈の種類を指定する。リンクの場合は Link
|
Rect | rectangle | o | 注釈の座標と大きさを指定する。left, bottom, right, top を要素とする数値型の配列 |
F | integer | - | 注釈の特徴を指定する。後述するビットフラグを使用 |
BS | dictionary | - | 枠線のスタイルを指定する(後述) |
Border | array | - | 枠線のスタイルを指定する(後述) |
枠線のスタイル
枠線のスタイルを指定するには、BS
エントリに以下の辞書を設定します。
BS
エントリに競合する存在として Border
エントリも存在しますが、PDF 1.2 で新たに定義された BS
エントリでは、より詳細なスタイル指定が可能となっています。PDF 1.2 以降であれば基本的に前者を使用して問題なさそうです。
エントリ名 | 型 | 必須 | 詳細 | デフォルト値 |
---|---|---|---|---|
Type | name | - | Border |
- |
W | number | - | 枠線の幅をポイント単位で指定する | 1 |
S | name | - | 枠線のスタイルを指定する。以下の値を選択。S : solid, D dashed, B : beveled, I : inset, U : underline |
S |
D | array | - |
S エントリに D を指定した場合に指定する。graphic state における line dash pattern を記述 |
[3] |
line dash pattern は数値型の配列です。[3 2]
と指定すると、長さ 3 の線が描画され、続いて長さ 2 の間隔が設けられます。
Anotation flags
F
エントリにはビットフラグを用いて、最下位から順に注釈の特徴を指定します。指定のないビットは 0 とします。印刷時における注釈の表示等はここで設定されていたんですね。
位置 | 名称 | バージョン | 有効な場合 |
---|---|---|---|
1 | Invisible | - | 注釈が標準的なタイプに属さず、ハンドラも利用できない場合に、注釈を非表示にする |
2 | Hidden | PDF 1.2 ― | 種類や注釈ハンドラによらず、画面上で注釈を非表示にする |
3 | PDF 1.2 ― | 印刷時に注釈を表示する。Acrobat 3.0 よりも前ではフラグの値によらず印刷時は非表示 | |
4 | NoZoom | PDF 1.3 ― | ページの倍率によらず、注釈を拡大しない |
5 | NoRotate | PDF 1.3 ― | ページの回転によらず、注釈を回転させない |
6 | NoView | PDF 1.3 ― | Hidden + ReadOnly |
7 | ReadOnly | PDF 1.3 ― | マウスクリックやマウスオーバーに反応しない |
8 | Locked | PDF 1.4 ― | 注釈の削除・編集を禁止する |
9 | ToggleNoView | PDF 1.5 ― | 特定のイベントに対して NoView のフラグを反転させる。マウスオーバー時等に使用する |
10 | LockedContents | PDF 1.7 ― | 注釈の内容の変更を禁止する |
以下のコードを用いてビットフラグを求めます。
public static int GetBitFlags(byte[] bits)
{
int no = 0;
for (int i = 0; i < bits.Length; i++)
{
no |= bits[i] << i;
}
return no;
}
注釈を描画してみる
これらを用いて、以下の矩形によって表される注釈を描画します。
- 座標:左下を原点として (10 pt, 10 pt)
- サイズ:幅 40 pt、高さ 10 pt
- 枠線:RGB(255, 0, 102)、幅 2pt、[4, 4] の破線
1 0 obj <<
/Type /Page
...
/Annots [ 1 0 R ]
>>
endobj
2 0 obj <<
/Type /Annot
/Rect [5 5 20 20]
/Subtype /Link
/BS 3 0 R
>>
endobj
3 0 obj <<
/Type /Border
/W 2.0000000
/S /D
/D [ 4.0000000 4.0000000 ]
>>
endobj
間接オブジェクト 2 0 obj
として Annotation Dictionaries を定義し、これを Page Objects 1 0 obj
から参照しています。これを Adobe Acrobat で開くと、図 2 の通りピンク色の矩形が出現しました。これが注釈です。
アクション
この注釈をクリックした際に Web サイトに遷移するように、URI Actions を追加します。URI Actions も例によって辞書として定義され、以下のエントリを持ちます。
エントリ名 | 型 | 必須 | 詳細 |
---|---|---|---|
S | name | o | URI |
URI | ASCII string | - | 7 ビット ASCII で URI を指定する |
IsMap | boolean | - |
true にした場合、URI が解決された時点でのマウス座標が URI のクエリパラメータとして追加される。初期値 false (例: https://example.com/?5,6 ) |
URI Actions の辞書を、先程用意した Annotation Dictionaries の A
エントリに追加します。
2 0 obj <<
...
/A <<
/S /URI
/URI (https://www.tsukuba.ac.jp)
/IsMap false
>>
>>
アクションを追記した PDF を開き、注釈の箇所をクリックすると、Web ブラウザが起動し、指定された URI(https://www.tsukuba.ac.jp)が開かれました。あとはこれにテキストを重畳すれば、hyperref パッケージが提供するコマンドと同等の機能が再現できます。
図 2:注釈をクリックすると Web ページへと遷移する
なお \ref
コマンドで実現されるような文書中の相互参照は、Action Types を Go-To Actions に変更することで実現されます。
参考文献
[1] Adobe Systems Incorporated: PDF References sixth edition - Adobe® Portable Document Format Version 1.7. (2006), https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf
Discussion