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行目付近
 1  CharRefRx = /&(?:#(\d{2,6})|(#{CharEntityTable.keys * '|'}));/
 2  TextDecorationTable = { 'underline' => :underline, 'line-through' => :strikethrough }
 3### ここから追加
 4  # see. https://en.wikipedia.org/wiki/Web_colors#HTML_color_names
 5  ColorTable = {
 6    'white' => 'ffffff',
 7    'silver' => 'c0c0c0',
 8    'gray' => '808080',
 9    'black' => '000000',
10    'red' => 'ff0000',
11    'maroon' => '800000',
12    'yellow' => 'ffff00',
13    'olive' => '808000',
14    'lime' => '00ff00',
15    'green' => '008000',
16    'aqua' => '00ffff',
17    'teal' => '008080',
18    'blue' => '0000ff',
19    'navy' => '000080',
20    'fucsia' => 'ff00ff',
21    'purple' => '800080',
22  }
23### ここまで追加
24  #DummyText = %(\u0000)
<gemルートパス>/asciidoctor-pdf-1.5.0.alpha.16/lib/asciidoctor-pdf/formatted_text/transform.rbの235行目付近
 1    attrs[:class].split.each do |class_name|
 2      case class_name
 3      when 'underline'
 4        styles << :underline
 5      when 'line-through'
 6        styles << :strikethrough
 7      end
 8### ここから追加
 9      unless class_name.nil?
10        cvalue = class_name.downcase
11        fragment[:color] = ColorTable[cvalue] if ColorTable.key?(cvalue)
12      end
13### ここまで追加
14    end if attrs.key?(:class)

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

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

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