dvipdfmx / xdvipdfmx のコマンドラインオプション
TeX をお使いの方にはおなじみの dvipdfmx / xdvipdfmx ですが、 コマンドラインオプションでは指定できるのに、 TeX 文書中では指定できない機能がいくつかありました。例えば、
$ dvipdfmx -z 0 foo.dvi
のように、コマンドラインオプション「-z 0
」を指定すると、
PDF の圧縮をしないようにすることができますが、これと同等のことを
TeX 文書中で指定することはできない
ようでした。
私のやりたいことは、圧縮を抑止する「-z 0
」よりは、
LilyPond の PDF ドキュメントで PDF 相互間のリンクが正常に機能するように、
PDF ラベル最適化を抑止する「-C 0x0010
」という
コマンドラインオプションと同等のことがしたい、というものでした。
これを special や primitive なりで指定できれば、 texinfo.tex 中で指定することにより、 LilyPond や、その他 Texinfo を使った PDF ドキュメント相互間で リンクが機能するようになります。
tex ソースファイル中から dvipdfmx / xdvipdfmx のコマンドラインオプションを指定する方法はないんでしょうかね。
— TrueRoad (@trueroad_jp) 2016年3月24日
具体的には (x)dvipdfmx に -C 0x0010 を渡したいんです。同じ効果のある special や primitive でもあればいいのですが。
— TrueRoad (@trueroad_jp) 2016年3月24日
xetex --output-driver='xdvipdfmx -C 0x0010' という方法は思い付きましたが .tex 中で指定できないかと。
— TrueRoad (@trueroad_jp) 2016年3月24日
このオプションを付けないと \special{pdf:dest ...} で指定した文字列が数字に置き換えられてしまいます。
— TrueRoad (@trueroad_jp) 2016年3月24日
すると、同じ PDF 内部で /GoTo のジャンプをする分には問題ありませんが、外部の PDF から /GoToR でジャンプしてこれないんです。
— TrueRoad (@trueroad_jp) 2016年3月24日
自分なりに調べてみたりしたのですが、 残念ながらそういう機能は無さそうだ、ということがわかりました。
無ければ作ってしまえ
もちろんほしい機能があれば要望してみるのもいいんですが、 以前、xdvipdfmx のバグ修正パッチを作ってみたことがありましたので、 ほしい機能が「無ければ作ってしまえ」というわけで、 挑戦してみることにしました。
以前のバグ修正
ここで一旦、以前のバグ修正 (TeX Live SVN r39834) について触れておきます。
TeX Live 2015 の dvipdfmx / xdvipdfmx は
\special{pdf:dest ...}
で指定する文字列(ラベル)が最終的に UTF-16 になる場合、
半角の 1 (U+0031) や ü (U+00FC) のような U+00FF 以下の文字があると、
その前までで切れてしまいリンクがまともに動作しない、という
問題がありました
。
これは特に XeTeX (xdvipdfmx) の場合、特に何もしなくても 非 US-ASCII 文字が含まれていた場合は UTF-8 から UTF-16 への変換が走るため、 致命的でした。 特に、Texinfo では node 名に US-ASCII の接頭語を連結したものを ラベルに使うようになっているため、node 名に日本語を使うと、 (日本語は非 US-ASCII なので UTF-16 変換が走り、 接頭語の US-ASCII は U+00FF 以下なので切れてしまうという……) 必ず踏んでしまうバグになってしまっていました。
ただし、普通に LaTeX で hyperref パッケージを使っている場合であれば、
ラベルは必ず US-ASCII 文字のみで構成されるようですので、特に問題ありません。
また、TeX Live 2013 以前は、この問題は無さそうです。
TeX Live 2014 と TeX Live 2015 にはこの問題がありますが、
実は本記事の主題である「-C 0x0010
」で回避できます。
また、これとは別の修正 (TeX Live SVN r39695, r39753, r39754) により、
UTF-16 への変換が行われなくなるため、とりあえず致命的ではなくなる、
ことにはなりました。
が、気持ち悪いので、試しにソースを眺めていたところ、 ちょっとしたパッチで直せそうだったのです。 そこで、ビルド環境を作って、パッチを作り、 取り込んで (TeX Live SVN r39834) いただきました。
新しい special を追加
話を戻します。
というわけで dvidpfmx / xdvipdfmx のビルド環境はあったので、
新しい special を追加するパッチを作ってみました。
最初は、いちばんやりたかった
「-C 0x0010
」相当のラベル最適化抑止ができる pdf special を追加する
パッチを作りました。そして、PDF に圧縮がかかっていると、
本当にラベル最適化が抑止できているか確認が難しいため、
デバッグ用に「-z
」相当の圧縮率を指定できる pdf special を追加する
パッチを作ってみました。
最終的には作者様からアドバイスをいただき、 dvipdfmx.cfg と同様のコマンドラインオプションが指定できるような、 dvipdfmx special を新設することとなりました。
使い方
TeX Live 2016 に間に合ったようですので、TeX Live 2016 であれば使えます。
従来、PDF 圧縮を抑止するには
$ dvipdfmx -z 0 foo.dvi
のようにコマンドラインオプション「-z 0
」を指定する必要がありました。
新 special で PDF 圧縮抑止するには、 TeX 文書中に、
\special{dvipdfmx:config z 0}
と書くことで実現できます。
同様に、PDF ラベル最適化抑止をしたければ、従来は、
$ dvipdfmx -C 0x0010 foo.dvi
のようにコマンドラインオプション「-C 0x0010
」を指定するなり、
XeTeX であれば、
$ xetex --output-driver='xdvipdfmx -C 0x0010' foo.tex
とか、Texinfo の場合は、
$ PDFTEX="xetex --output-driver='xdvipdfmx -C 0x0010'" texi2pdf foo.texi
等のように指定する必要がありました。
こちらも新 special を使うと、TeX 文書中に、
\special{dvipdfmx:config C 0x0010}
と書くことにより実現できます。
コマンドラインオプションのように - (ハイフン)を付けません。
書式は dvipdfmx.cfg と同じです。
注意
xdvipdfmx (XeTeX) の場合でも、special 名は dvipdfmx
です。
xdvipdfmx
ではありません。
この \special{dvipdfmx:config ...}
は、
最初に読み込まれるだけです。
ですので、文章中で動作を切り替えたりすることはできません。
オマケ
これでコマンドラインオプションは不要になる、のですが、 LilyPond の場合、ビルド環境を TeX Live 2016 に切り替えるには 時間がかかりそうですので、結局、
LilyPond 2.19.40 から PDF ドキュメント相互間のリンクが機能するようになりました。ドキュメント生成時に xetex --output-driver='xdvipdfmx -C 0x0010' するようにしたことによります。
— TrueRoad (@trueroad_jp) 2016年4月18日
LilyPond 2.19.36 までは pdfTeX で PDF ドキュメントを生成していましたが TeX Gyre フォントの問題を回避するため 2.19.37 から XeTeX に変わっています。
— TrueRoad (@trueroad_jp) 2016年4月18日
ただ texinfo.tex の XeTeX を使った PDF リンク生成機能が不十分だったこと、PDF 相互間リンクが機能するために (x)dvipdfmx コマンドラインオプションが必要なこと、から LilyPond 2.19.39 までリンクの多くが機能していませんでした。
— TrueRoad (@trueroad_jp) 2016年4月18日
texinfo.tex + XeTeX 向け PDF リンク生成機能を作り本家 texinfo へコミット、LilyPond 側はドキュメント生成に xdvipdfmx コマンドラインオプションを指定するようにコミット、してようやく 2.19.36 までと同等になったと思います。
— TrueRoad (@trueroad_jp) 2016年4月18日
というわけで、 結局コマンドラインオプションを付けるようにしてしまいました。。。