asciidoctor-pdf で文字色が変わらない

1. 背景

こんな風に書くと

[red]#Obvious# and [big red yellow-background]*very obvious*.
[underline]#Underline text#, [overline]#overline text# and
[blue line-through]*bold blue and line-through*
5a647245
図 1. hemlへの変換例

こんな感じに文字色が変わるはずなのですが、 asciidoctor-pdf で作った PDF では次のように色が付きません。

9a32e579
図 2. PDFへの変換例
yellow-background とか overline も適用されてませんが、今回は無視します

Add support for quoted text attributes (prefixed in square brackets) by Hextremist · Pull Request #350 · asciidoctor/asciidoctor-pdf · GitHub にプルリクも出されていてこれがマージされれば文字色以外の不具合も修正されそうなのですが、マージされる気配がありません。

2. 対策

2.1. adoc 側で対応する

現状のasciidoctor-pdfが期待する通りのspanを作ってやれば取り敢えず色変わりました。

pass:[<span style="color:#ff0000">あああ</span>]

2.2. asciidoctor-pdf のソースを修正する

Add support for quoted text attributes (prefixed in square brackets) by Hextremist · Pull Request #350 · asciidoctor/asciidoctor-pdf · GitHub のプルリクを適用してみようかとも思いましたが、文字色以外の修正も入っていて対象ファイルも複数で、確認がめんどくさいのでやめました。

で、簡易的に文字色だけ反映されればと思って以下の修正を加えてみました。

修正ファイルは asciidoctor-pdf-1.5.0.alpha.16/lib/asciidoctor-pdf/formatted_text/transform.rb

<gemルートパス>/asciidoctor-pdf-1.5.0.alpha.16/lib/asciidoctor-pdf/formatted_text/transform.rbの13行目付近
13  CharRefRx = /&(?:#(\d{2,6})|(#{CharEntityTable.keys * '|'}));/
14  TextDecorationTable = { 'underline' => :underline, 'line-through' => :strikethrough }
15### ここから追加
16  # see. https://en.wikipedia.org/wiki/Web_colors#HTML_color_names
17  ColorTable = {
18    'white' => 'ffffff',
19    'silver' => 'c0c0c0',
20    'gray' => '808080',
21    'black' => '000000',
22    'red' => 'ff0000',
23    'maroon' => '800000',
24    'yellow' => 'ffff00',
25    'olive' => '808000',
26    'lime' => '00ff00',
27    'green' => '008000',
28    'aqua' => '00ffff',
29    'teal' => '008080',
30    'blue' => '0000ff',
31    'navy' => '000080',
32    'fucsia' => 'ff00ff',
33    'purple' => '800080',
34  }
35### ここまで追加
36  #DummyText = %(\u0000)
<gemルートパス>/asciidoctor-pdf-1.5.0.alpha.16/lib/asciidoctor-pdf/formatted_text/transform.rbの235行目付近
235    attrs[:class].split.each do |class_name|
236      case class_name
237      when 'underline'
238        styles << :underline
239      when 'line-through'
240        styles << :strikethrough
241      end
242### ここから追加
243      unless class_name.nil?
244        cvalue = class_name.downcase
245        fragment[:color] = ColorTable[cvalue] if ColorTable.key?(cvalue)
246      end
247### ここまで追加
248    end if attrs.key?(:class)

修正後に作成した PDF はこんな感じで文字色が変わりました。

5d6eeee8
図 3. transform.rb 修正後のPDF

当然ですが、 asciidoctor-pdf のバージョンが上がる度に修正を加える必要があります。