Asciidoctor PDFと日本語禁則処理
Asciidoctor PDFを使っていて一番困っているのは日本語禁則処理です。標準だとまともに禁則処理されないんですよね。
このように、行頭に平然と禁則文字がきてしまいます。理由は簡単、Asciidoctor PDFは日本語の禁則処理を実装していないから、です。
もうちょっと掘り下げると、AsciiDoctor PDFのPDF生成ロジックはPrawnというRuby製のPDF生成ライブラリに大きく依存しています。このPrawnの改行ロジックが日本語(というかCJK全般)を考慮していないので、結果として禁則されない、ということのようです。
改行のロジックは https://github.com/prawnpdf/prawn/blob/master/lib/prawn/text/formatted/line_wrap.rb です。行を正規表現でchunkに分割し、chunkごとに処理をしている様子。 分割の区切り文字はwhitespace, hyphen, soft hyphen, zero-width spaceでしょうか。大抵の言語はこれでうまくいくんですよね...
でも、日本語は全然上手くいかないので、対策を考える必要があります。
案1: Asciidoctor PDF CJKを使う
Asciidoctor PDF CJKという、Asciidoctor PDF用のextensionがあります。 CJKでの改行処理を改善するための拡張で、これを入れるとある程度いい感じになります。
ただ、extensionの解説に書いてある通り、
Insert zero-width space(ZWSP) before CJ characters to fix line wrap
という力業なんですよね。ZWSPというのは幅ゼロのスペースです。これを日本語文字の間に挿入するとPrawnの改行ロジックが1文字1chunkと認識するので改行がうまくいく、という算段。
結果、ZWSPが大量に挿入されるのでPDFファイルサイズが膨らみます。あと、感覚的にちょっと気持ち悪い...
とは言え、Asciidoctor PDFを使うなら現時点では実用可能な唯一の選択肢です。
(2018/3/17追記)
PrawnはZWSPを取り除いてPDFを生成しているようです。なのでファイルサイズが膨らむというのは誤りですね。すいません。
案2: asciidoctor-fopubに乗り換える
Asciidoctor PDFを諦めるアプローチもあります。
Apache FOPというXSL formatting objects (XSL-FO)をPDFに変換できるJava製ツールがあります。これをAsciiDoctorと連携してくれるのがasciidoctor-fopubです。
Apache FOPには日本語の禁則処理が実装されているのでうまくいくはず。と思ったのですが、手元では環境構築がうまくいかず。実際には試せていません。Asciidoctor PDFと比べると手軽さにかなり難がある印象。
案3: いっそLaTeXに変換する
さらに割り切って何らかのコンバーターを噛ませてLaTeXにしてしまう案。
LaTeXはApache FOPよりも環境構築のハードルが高い気がするので試してません。 asciidoctor/asciidoctor-latexあたりが使えるのかな?
まあ、LaTeXにするならAsciiDocじゃなくてもいいよね、という気もします。
そんなわけで、禁則処理の問題が解決しないとAsciidoctor PDFの実戦投入はちょっとシンドイ。Asciidoctor PDF CJKでお茶を濁しつつ、よりよいアプローチを模索するのが現実解ですかね...
関連(するかもしれない)記事
おススメ