これは「TeX/LaTeX Advent Caleandar 2020」の11日目の記事です。
(10日目は CareleSmith9 さん、12日目は abenori さんです。)
「アドベントカレンダーが埋まらない」という緊急事態発生につき、急遽、拙作のチョットスゴイ(かもしれない)パッケージである**bxpdfverパッケージ**についての50分で書き殴った解説記事を放出します
bxpdfverパッケージのここがスゴイ!
LaTeXでPDFファイルを出力するには次の2通りの方法1があります。
- DVI出力のエンジン(LaTeX、pLaTeX、upLaTeX)とdvipdfmxを組み合わせる
- PDF出力のエンジン(pdfLaTeX、XeLaTeX、LuaLaTeX)を使う
最近のTeX Liveにおいては、どちらの工程を用いた場合も出力されるPDFのバージョンは1.5となります。
しかし、出力PDFのバージョンを変えたい場合があります。例えば次のような場合です。
- 後の工程でPDFを加工する必要があり、そのためのソフトウェアがPDF-1.4にしか対応していないため、出力PDFバージョンを1.4にする必要がある。
- 文書中でPDF-1.6の画像を挿入しているため、出力PDFバージョンを1.6(以上)にする必要がある2。
dvipdfmxを用いる場合は、起動時のオプションで出力PDFバージョンを指定できます。
# 出力PDFバージョンを1.4にする
dvipdfmx -V 4 report.dvi
また、TeX言語レベルの機能を使えば文書中で出力PDFバージョンを指定することもできます。PDF出力エンジンの場合は、当然3文書中で指定することになるのですが、エンジンごとに指定の方法が異なっていてイロイロ厄介です
この**「出力PDFバージョンの**(文書内での)指定」をLaTeXレベルで行うためのパッケージがbxpdfverです。
PDFバージョン指定の他にも「PDFストリームの圧縮を行うか」などの様々な**「出力PDFの性質」を指定する**機能ももっています。
使ってみる
bxpdfverパッケージは以下のエンジン/DVIウェアに対応しています。
- DVI出力エンジンとdvipdfmxの組み合わせ。
- pdfLaTeX/XeLaTeX/LuaLaTeX。
※dvipsには非対応です4。
パッケージ読込
dvipdfmxを使う場合には、ドライバ指定(\documentclass
に5dvipdfmx
オプションを付ける)が必要です。
% 例えばupLaTeX+dvipdfmxの場合
% ↓dvipdfmxオプションをつける
\documentclass[uplatex,dvipdfmx,a4paper]{jsarticle}
\usepackage{bxpdfver}
PDF出力エンジンの場合はドライバ指定は不要です。
% 例えばLuaLaTeXの場合
\documentclass[a4paper]{ltjsarticle}
\usepackage{bxpdfver}
出力PDFバージョンを指定する
\setpdfversion
命令で指定します。引数はバージョン値で、有効な値6は1.4
・1.5
・1.6
・1.7
・2.0
です。
% 出力PDFバージョンを1.7にする
\setpdfversion{1.7}
あるいは、パッケージ読込時にオプションでも指定できます。
% 出力PDFバージョンを1.7にする
\usepackage[1.7]{bxpdfver}
出力PDFバージョンを挿入画像と同じにする
\setpdfversion
命令の引数にPDFファイル名を指定すると、そのファイルのPDFバージョンが出力バージョンに指定されます。
% 出力PDFバージョンをimage.pdfと同じにする
\setpdfversion{image.pdf}
※パッケージオプションではファイルでのパージョン指定はできません。
ストリームの圧縮を抑止する
\suppresspdfcompression
命令を実行するとPDF内部のストリームデータの圧縮が抑止されます。「PDFチョットデキル」ような人が「LaTeXの出力したPDFの中のコードを調査したい」という場合に有用です。
% ストリームの圧縮を抑止する
\suppresspdfcompression
パッケージオプション(nocompress
)でも指定できます。
% ストリームの圧縮を抑止する
\usepackage[nocompress]{bxpdfver}
※dvipdfmxのコマンド行オプションの-z 0
の指定と等価です。
オブジェクトストリームの使用を抑止する
\suppresspdfobjcompression
命令7を実行すると「出力コード中でオブジェクトストリームが使われなくなり、全般的8にPDF-1.4以前の古い書式が使われる」ようになります。「PDF自信ニキ」のための機能です。
% オブジェクトストリームを抑止する
\suppresspdfobjcompression
パッケージオプション(noobjcompress
)でも指定できます。
% オブジェクトストリームを抑止する
\usepackage[noobjcompress]{bxpdfver}
PDF中の数値データの精度を指定する
使う機会はほぼないと思いますが、これで不具合が回避できる場合があったらしいです。
% 数値データを小数第4位まで出力する
\setpdfdecimaldigits{4}
※dvipdfmxのコマンド行オプションの-d <整数>
の指定と等価です。
PDF内部のアンカー名を保持する
hyperrefパッケージを使うとPDF文書内にリンクを配置できます。この際に、文書の内部のリンクについては、HTMLと同様にその遷移先を“アンカー”(正式な用語では“destination name”という)で識別しています。ほとんどの場合、この“アンカー”の名は外部からは参照されず内部のリンクとアンカーの間で一貫していれば十分であるため、dvipdfmx(とXeLaTeX)では「アンカー名を連番の数字で付けなおす」という処理を行っています。しかし時には「2つのPDF文書の間でリンクを張りたい」なんて場合もあり、この際にdvipdfmxの既定の処理が行われると、リンクが正常に機能しなくなってしまいます。
\preservepdfdestinations
命令はdvipdfmxの「アンカー名の付けなおし」の処理を抑止し、hyperref(等)によって生成されたアンカー名が保持されるようにします。
% アンカー名を保持する
\preservepdfdestinations
まとめ
人生はもっと計画的に生きましょう(えっ)
-
ん、dvips? なにそれ? ↩
-
LaTeXの工程における「PDF画像の挿入」は単に対象のPDFのコードをそのまま埋め込むだけ(再レンダリングはしない)なので、PDF-1.6の機能を含む画像を埋め込んだときにそれが正しく処理されるためには、大本のPDFのバージョンをそれ以上にする必要があります。 ↩
-
エンジンが直接PDFを出力しているので、設定を書き込む場所はTeX文書内しかありえません。 ↩
-
実際のところ、dvipsを使ってDVI→PS→PDFと変換する工程の場合、出力PDFバージョン等は「PS→PDFの変換を行うソフトウェア」の設定に委ねることになり、それはLaTeX文書中では指定できないはずです。 ↩
-
\usepackage[dvipdfmx]{bxpdfver}
のようにパッケージにドライバオプションを指定することも可能ですが、イマドキのLaTeXではドライバオプションはグローバルに指定するお約束になっています。 ↩ -
PDFの実在のバージョンで1.4以降のものはこれが全てです。 ↩
-
objcompression
という名称はpdfTeXのプリミティブの\pdfobjcompresslevel
に由来します。実際は「オブジェクトストリーム」はそれ自体は圧縮とは関係ありません(圧縮の効率を高めるための機構ではありますが)。 ↩ -
もちろん
\suppresspdfobjcompression
は「PDFのバージョン」自体には影響しません。バージョンが1.5以上のPDFでも古い書式は使えます。なお、バージョンが1.4の場合は無条件に古い書式が使われます。 ↩