無向グラフのDOTにgvprでrank付きサブグラフを加える #3
とりあえず前回のコードでうまくrankの設定がなされたサブグラフが加えられた。
しかし、insert_rank.gが出力するDOTを見ると、
graph { subgraph 3 { graph [rank=same]; "2,3"; "1,3"; "0,3"; } subgraph 2 { graph [rank=same]; ...snip
のように、subgraphキーワードやサブグラフの名前などが明示されていて、
...snip { rank = same; "0,3"; "1,3"; "2,3"; } ...snip
のようなシンプルさに欠けている感じがする。
次のようなテストをしてみる。
$ cat << foo | > graph { > { rank = same; "0,3"; "1,3"; "2,3"; } > { rank = same; "0,2"; "1,2"; "2,2"; } > { rank = same; "0,1"; "1,1"; "2,1"; } > { rank = same; "0,0"; "1,0"; "2,0"; } > } > foo > gvpr " > BEG_G { > graph_t g; > for (g = fstsubg($); g != NULL; g = nxtsubg(g)) { > print(g); > node_t n; > for (n = fstnode(g); n != NULL; n = nxtnode_sg(g, n)) print(' ', n); > } > } > " %3 0,3 1,3 2,3 %5 0,2 1,2 2,2 %7 0,1 1,1 2,1 %9 0,0 1,0 2,0
以上の結果からこの無名(に見える)サブグラフは名前の先頭に%が付いていることが分かる。
そこでinsert_rank.gで作成するサブグラフ名を単なるy値から%付きに変更した。
insert_rank.g
BEG_G { int y = -1; node_t n; for (n = fstnode($); n != NULL; n = nxtnode(n)) y = MAX(y, yOf(n.name)); for (; y >= 0; y--) { graph_t g = subg($, sprintf('%%%d', y)); g.rank = 'same'; } } N { subnode(subg($G, sprintf('%%%d', yOf(name))), $); }
これを使うと、
$ gvpr -f gen_mesh.g -a 3,4 | gvpr -cf insert_rank.g graph { { graph [rank=same]; "2,3"; "1,3"; "0,3"; } { graph [rank=same]; "2,2"; "1,2"; "0,2"; } { graph [rank=same]; "1,1"; "2,1"; "0,1"; } { graph [rank=same]; "0,0"; "1,0"; "2,0"; } "0,0" -- "1,0"; ...snip
これですっきりした。
rank=same;
がgraph [rank=same];
になるのはgvprの出力の仕様なので多分仕方がないと思う。
何もしないgvprフィルタに通しても、
$ echo "graph{{ rank = same; \"0,3\"; \"1,3\"; \"2,3\"; }}" | gvpr -c "BEG_G{}" graph { { graph [rank=same]; "0,3"; "1,3"; "2,3"; } }
のような形式での出力になる。