Asciidoctor PDFと日本語禁則処理

2018/03/07

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でお茶を濁しつつ、よりよいアプローチを模索するのが現実解ですかね...




関連(するかもしれない)記事


おススメ