パワーポイントなどで図を描こうとすると、レイアウトやサイズなどがなかなか決められず、サクッと描くことができない性分です。
設定を変更できるから迷うのであって、いっその事、ガチガチに制約があった方が割り切れていいんじゃないかと、よくある、テキストで描かれた図を作成するツールを検討してみました。

そのようなツールはいくつかあるのですが、一番シンプルで分かりやすかった「Graph::Easy」を使ってみることにしました。
Graph::Easyの使い方はそれほど難しくないのですが、CUIツールなので使っていないとすぐに忘れてしまうため、個人用備忘録としてここにまとめました。
インストール
Graph::EasyはPerlのモジュールなのでcpanを使ってインストール
cpan Graph::Easy
cpanが入っていない場合は下記でcpanをインストール
sudo apt-get install build-essential
使い方
ファイルを介した方が後々楽なのでその方法を記す。結果は標準出力に出力されるので、必要ならばリダイレクトでファイルに出力する
graph-easy <インプットファイルパス>
書き方
基本:ノードに線を引く
- 線の向きは「直線」「矢印」「双方向矢印」
- 線の種類は「-」「.」「=」
- 他にもあるが、テキストなので違いはほとんど分からず、これで十分
■入力■ [A]--[B]->[C]<->[D] [E]..[F].>[G]<.>[H] [I]==[J]=>[K]<=>[L] ■出力■ +---+ +---+ +---+ +---+ | A | --- | B | --> | C | <--> | D | +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ | E | ... | F | ..> | G | <..> | H | +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ | I | === | J | ==> | K | <==> | L | +---+ +---+ +---+ +---+
ノードの並びは、アウトプットが左でインプットが右に決まっている。右から左、つまり「[B]<-[C]」という書き方はできない。そういう場合は「[C]->[B]」の行を追加する。
■入力■ [A]->[B] [C]->[B] ■出力■ +---+ +---+ +---+ | A | --> | B | <-- | C | +---+ +---+ +---+
線に名前をつける。ノードの表示名を変える
■入力■
[A]--{label:line}[B]
[C]{label:node}--[D]
■出力■
+------+ line +---+
| A | ------- | B |
+------+ +---+
+------+ +---+
| node | ------- | D |
+------+ +---+
線に名前をつける方法は他に「[A]- line ->[B]」」というやり方もあるが、これは向きの無い線(「--」など)には使えないので、「label」を使ったやり方に統一しておいた方が覚えることが少なくて済む。
分岐・合流
■入力■
[A]->[B]->[C]
[D]->[B]
[B]->[E]
■出力■
+---+
| E |
+---+
^
|
|
+---+ +---+ +---+
| A | --> | B | --> | C |
+---+ +---+ +---+
^
|
|
+---+
| D |
+---+
各線のつながりを1つ1つ分けて書いていけば、Graph::Easyがよしなにつないでくれる。
1点からの分岐・1点への合流
■入力■
[A]->{start:front,0}[B]
[A]->{start:front,0}[C]
■出力■
+---+ +---+
| A | -+-----> | B |
+---+ | +---+
| +---+
+-----> | C |
+---+
■入力■
[A]->{end:back,0}[C]
[B]->{end:back,0}[C]
■出力■
+---+ +---+
| A | ------+-> | C |
+---+ | +---+
|
|
|
+---+ |
| B | ------+
+---+
線の途中の分岐・合流
■入力■
[L1]{shape:edge}
[L2]{shape:edge;label:""}
[A]--[L1]->[B]--[L2]->[C]
[L1]->[D]
[E]->[L2]
■出力■
+---+ L1 +---+ +---+
| A | -------------> | B | ------------> | C |
+---+ +---+ +---+
| ^
| |
v |
+----+ +---+
| D | | E |
+----+ +---+
「{shape:edge}」でノードを線の途中のポイントとすることができる。ポイント名をlabelで無名にすると、名前が表示されなくなる。
グループ化
■入力■
(GroupA [A]->[B])
[B]->[C]
[A]->[D]
■出力■
+ - - - - - - - - - -+
' GroupA '
' '
' +------+ +---+ ' +---+
' | A | --> | B | ' --> | C |
' +------+ +---+ ' +---+
' '
+ - - - - - - - - - -+
|
|
v
+------+
| D |
+------+
「()」で囲むとグループになる。ただ、イマイチ使い勝手が良くないので、あまり凝ったことはせず、アクセント程度に用いるのがよさげ。
全体の向きの変更
■入力■
graph{flow:south}
[A]->[B]
■出力■
+---+
| A |
+---+
|
|
v
+---+
| B |
+---+
何も設定しないと図は左から右に描かれるが、「graph{flow:[north|south|east|west]}」で全体の向きを指定できる。
線が出ていく面と、入っていく面の指定
■入力■
[A]->{start:north; end:south}[B]
■出力■
+----+
| |
+---+ | +---+
| A | | | B |
+---+ | +---+
| ^
+----+
どうしても、この面から線が出て、この面へ入っていくのを決めたい時は、指定することが可能。どちらか一方だけの指定も可能。
同じ面から複数の線を並行に出す
■入力■
[A]->{start:east}[B]
[A]->{start:east}[C]
[A]->{start:east}[D]
■出力■
+---+ +---+
| | --> | B |
| | +---+
| | +---+
| A | --> | C |
| | +---+
| | +---+
| | --> | D |
+---+ +---+
同じ面から複数線を定義すると、複数の線が並行に並ぶ。
ノードの枠線を変える
■入力■
[A]->[B]{border:dotted}
■出力■
+---+ .....
| A | --> : B :
+---+ :...:
他にもあるが、テキストなので違いはほとんど分からず、これで十分
テキスト折り返し
■入力
[A\nB]->[C]{label:C\nD}
■出力■
+---+ +---+
| A | | C |
| B | --> | D |
+---+ +---+
「\n」で改行を入れられる。
画像出力
dot形式で出力して画像化する場合

「dot」を使って画像を作成しているのでdotが必要。dotは「Graphviz」をインストールすると付いてくる。
sudo apt-get install graphviz
「-png」オプションでpng出力
graph-easy <入力ファイル名> -png
画像サイズを指定する場合は、一旦「dot」形式で出力して、それを「dot」に渡してオプションで指定する。
graph-easy <入力ファイル名> -as_dot | dot -Tpng -Gsize=1 -Gdpi=500 -o <出力ファイル名>
上記は500pxの出力例。縦横のどちらか大きい方の最大値が指定値になる。(縦のみ、横のみのサイズ指定は無理そう)
テキストを画像化する場合

「Imagemagick」を使ってテキストを画像化する。Imagemagickが入っていない場合はインストール。
sudo apt-get install imagemagick
色、サイズを指定して出力
graph-easy <入力ファイル名> | \ head -c -1 | \ convert -background "#ffffff" -fill "#000000" -font "FreeMono" -size 100x100 \ label:@- <出力ファイル名>
最後に改行が入るので「head -c -1」で取り除いている。
幅を指定して縦をよしなにする場合は、「-size 100x」と縦を指定しない。ただし、その時の出力画像の縦サイズは、1フォント分の縦になるので、テキストの縦行数から実際の縦幅を計算して、「-size 100x<計算後の縦サイズ>」で再度出力し直す。
縦を指定して横をよしなにする場合は、「-size x100」と幅を指定しない。