« 如何让 lua 做尽量正确的热更新 | 返回首页 | 用分布式压缩贴图加快 Unity3D 的打包过程 »

用 Ascii 画关系图

写备注总有时候光靠文字描述不是很清楚,这个时候特别想在文档中附个关系图。用 graphviz 的 DOT 来描述图固然不错,但是它需要额外工具来生成才能直观的查看。如果我们想在纯文本环境附上插图,使用 ascii art 是最佳选择。

我搜了一下,perl 的 Graph::Easy 是唯一能找到的支持 ascii 输出的关系图绘制软件。

但是这个东西有个问题,就是对中文支持不行,虽然文档中说完全支持 Unicode ,但显然作者并没有把汉字用在 Ascii 输出上过。

问题是这样产生的:UTF8 中,汉字是 3 字节,而对于显示来说,等宽字体的汉字是 2 倍普通字母宽。这样在排版时,你必须知道一个字符串在视觉上是多宽,才可能用 ascii 字符拼接出正确的方框和连线。

比如,这个帖子就讨论了类似的问题

一开始,我希望找到 Graph::Easy 库中取 label 宽度的函数,让它正确返回 label 的视觉宽度。修改后,发现还是不行。这是因为,这个东西在 ascii 输出时,是用一个 2D 的字符数组模拟了虚拟画布(framebuffer)。它认为,framebuffer 上的一个矩形区域,就应该是 w * h 个字符构成的区域。如果想进一步的让它在 framebuffer 上定位正确,还需要修改它计算坐标的地方。可是,写 framebuffer 是一个随机过程,你向左边写一个一个字符,如果是汉字的话,会改变右边的 x 坐标。也就是把右侧所有的字符都挤了一个位置。如果再重排右侧的所有数据代价就太大了,而且它的内部模块也并没有抽象出这样的定位函数。

后来我想到一个取巧的做法,再读取任何 label 串时,都把这个串处理一下,把其中的汉字全部追加一个不可能在正常文本中存在的字符 U+FFFF ,让每个汉字都真的占据两个字符位。这样的字符串处理函数原本就在模块内存在(因为它本身就要去做类似 \n 的转义),这样就可以让整个排版过程正常了。

接下来要改的是最终把 framebuffer 序列化回字符串的过程,把里面所有的 U+FFFF 都删掉,就可以正确的输出了。

ps. 本来想提个 PR ,但是 github 上的那个仓库似乎不是原作者在维护的, CPAN 上的版本也不知道怎么提 issue ,所以还是自己玩玩就行了吧。


2017 年 5 月 2 日补充:

有同学找我要 patch ,我附在这里:基于 Graph-Easy 0.76 版。

diff --git a/lib/Graph/Easy.pm b/lib/Graph/Easy.pm
index 0ae40fd..b67bacc 100644
--- a/lib/Graph/Easy.pm
+++ b/lib/Graph/Easy.pm
@@ -1570,7 +1570,9 @@ sub as_ascii
   # select 'ascii' characters
   $self->{_ascii_style} = 0;

-  $self->_as_ascii(@_);
+  my $asc = $self->_as_ascii(@_);
+  $asc =~ s/(\x{FFFF})//g;
+  $asc;
   }

 sub _as_ascii
diff --git a/lib/Graph/Easy/Node.pm b/lib/Graph/Easy/Node.pm
index b58f538..6d7d7c7 100644
--- a/lib/Graph/Easy/Node.pm
+++ b/lib/Graph/Easy/Node.pm
@@ -1503,6 +1503,9 @@ sub label

   $label = $self->_un_escape($label) if !$_[0] && $label =~ /\\[EGHNT]/;

+  # placeholder for han chars
+  $label =~ s/([\x{4E00}-\x{9FFF}])/$1\x{FFFF}/g;
+
   $label;
   }
 

Comments

你好,我想问下按照你的代码修改后如何重新编译Graph-Easy,我是用cpan安装的,对perl还不太熟悉

测试

http://asciiflow.com/ 不错啊

Emacs有个artist-mode很符合你的要求,能在文本文件中绘制ascii

CPAN的ISSUE系统在这里:https://rt.cpan.org/Dist/Display.html?Name=Graph-Easy

这个可以哦

你需要 jave.de

asciiflow.com也不支持中文,类似的工具就没见过支持中文的,包括monodraw.app

哈哈还是1楼的那个好

我是用别人的网页工具 windows程序员 orz
http://asciiflow.com/

Post a comment

非这个主题相关的留言请到:留言本