« ^ »

ditaaの図の中に日本語を含めても図が崩れないようにする

所要時間: 約 4分

TL;DR

  • ditaaはASCIIアートの図を画像に変換できる。ただし日本語を含んでいると図が崩れる。
  • 図が崩れる理由は、全角文字の文字幅を考慮せず半角文字と同様に扱っているから。この問題を回避するためのJditaaというツールがある。
  • Jditaa(日本語対応版)の処理をditaaに取り込み、図の中に日本語を含められるようにした。またHomebrewでインストールできるようにした。

ditaaとは

ditaaはASCIIアートで描かれた図を整形して画像として出力する。 以下のようなASCIIアートで描かれた図を見ることもあるだろう。 コードに埋め込まれていたり、古いドキュメントにはこの手法で図解されているものも多い。

+---+     +---+
| A +---->| B |
+---+     +---+

ditaaのシンプルな例(simple.ditaa)

ditaaはこのような図を整形して画像に変換する。

ditaa simple.ditaa
simple.ditaaをditaaを用いて画像に変換する

simple.ditaa は次のように変換される。

https://res.cloudinary.com/symdon/image/upload/v1641715058/blog.symdon.info/simple_ywfld9.png
simple.ditaaの変換結果

ditaaは日本語を含んでいると結果が崩れる

日本語などの全角文字がASCIIアートに含まれていると 現行のditaa1では 生成される図が全般的に崩れる。

日本語Testing

+-------------+
|             |
| あ い う    |<---
|             |
+-*--+-----|--+
  |  |  |  |
           |
  |  |  |  |
+=*==+=====|==+
:             :     |
: あいう      :<----|->
:             :     |
+=============+

+-------------+
|             |     |
| AあBいCう   |<----*->
|             |
+-------------+

+=============+
:             :     |
: あ い う    :<====+=>
:             :
+=============+

   |   |
<==+===*==>

   |   |
<--+---*-->

^      ^
:      |
+--    +--
|      |
*--    *--
:      |
V      v

日本語が混ざる例(testing.ditaa)

https://res.cloudinary.com/symdon/image/upload/v1641714996/blog.symdon.info/testing-original_xznpij.png
日本語が混ざると結果が崩れる

なぜ日本語を含んでいると図が崩れるのか?

ditaaは 1A も文字数1として認識し、 1文字の表示幅は常に一定であるという前提で実装されている。 しかし日本語や中国語、韓国語、ベトナム語などは全角があり、 通常それは半角の2文字分として表示される2。 ditaaではこれを考慮せず描画を行うため、 先程のように図が崩れる結果となる。

日本語対応のJditaa

本来は文字幅の概念を取り入れることが正しいが、 そのためにはditaaをそこそこ修正する必要がある。 これに対するワークアラウンドを考えだした人がいる。 全角(半角2文字分)を半角1文字と同じように扱っていることに着目し、 全角文字の後ろに半角空白を1文字挿入する。 それをJditaaとして公開されていた3。 Jditaaはその内部でditaaのclassをimportして継承しており、解析の前に先程の処理を行う。 Jditaaはditaaを拡張した別のコマンドとして実装されていた。

Jditaaの処理をditaaに取り込む

ditaa自体はJavaで実装されている4。 Jditaaの処理は本来はditaaの内部にあるべき機能だが、 実装の内容が 帳尻を合わせるために半角スペースを追加する というワークアラウンド的な内容であったため、 本家が取り込むには微妙と考えそうしているのだろう。

ただ、そうであってもJditaaを探して整備することが大変であった5。 そのためditaa内部にJditaaを取り込むことにした。 ロジックはJditaaをほぼそのまま流用した6

以下はJditaaを取り込んだditaaで出力した結果である。

https://res.cloudinary.com/symdon/image/upload/v1641715095/blog.symdon.info/testing-support-cjk_vmsrqb.png

日本語対応ditaaをHomebrewでインストールできるようにした

Jditaaの機能を取り込んだditaaをインストールできるようにするために個人で管理しているHomebrew TapにFormulaを追加した7。 直接指定することで日本語対応のditaaをインストールできる。

brew install  TakesxiSximada/homebrew-tap/ditaa

変換時の課題

常に全角1文字のあとに半角スペースを1文字追加する。 そのため2文字の全角文字の場合はそれぞれの全角文字の後ろに半角スペースが付く。

例えば 日本語 という文字列に対しては 日<space>本<space>語<space> といった文字列になる。ditaaでは 日<space>本<space>語<space>日本語<space><space><space> では微妙に出力結果が異なる。このあたりは今回修正できなかった。今後の課題とする。

参考

https://gist.github.com/bpj/5454765371a4e3c1a8354fedced1cc6b/

脚注


1

v0.11.0

2

Unicodeについてはそれらに関する取り決めがあり標準化されている。 http://www.unicode.org/reports/tr11/tr11-15.html#Definitions

4

Clojureで実装しなおす旨の記述がREADMEにある。ただし進んではいないようだ。

5

Jditaaをダウンロードするためのリンクが切れていることがしばしばあった。