作者:weishu
博客:http://www.jianshu.com/u/e347b97e2f0c
我们使用纯文本写代码,有了Markdown又可以使用纯文本写文档,那么对于更直观的信息表达方式——图片,能不能使用纯文本描述呢?
另外,你是否见到过这样的注释
![](https://i-blog.csdnimg.cn/blog_migrate/ce571d9e07a8687bceccf7eb2f3e83ad.jpeg)
ASCII art图像
没错,这种逼格极高的ASCII图片注释方式就是我们要讨论的话题。
使用纯ASCII文本表达图像的方式有什么好处呢?大致有下面几点:
装B;没啥好解释的。
可以在代码注释里面用图像充分表达信息;没图say个jb?一图胜千言。迄今为止好像没有什么IDE可以支持直接在代码编辑里面放图片的,在另外一些纯文本的场合也是如此。比如RFC的文档都是txt,里面很多图都是纯ASCII表达。
你以为仅仅是一个纯文本图片这么简单?它可以转换为普通的诸如png格式的真正的图片,还支持SVG矢量图!
好了,也许有人说markdown的一些拓展格式不也是支持流程图的吗?它使用的flowchart.js确实可以很好滴完成一些漂亮的流程图,还有 plantuml和图片DSL语言 dot及它的软件包graphviz等;没错,它们可以使用纯文本表达图像,但它们不是真正的图像;无法嵌入文本代码中,只有在经过渲染之后才能直观地看到图。
又有人说,我知道 asciiflow 这个网站,可以绘制这种流程图,完美解决我的需求。但是,你在手动绘制的时候,是不是要考虑图像的各种细节?大小,放置位置,对齐方式?我们关注的应该是图像本身,而不是如何绘制这个图。markdown为什么这么易用?就是因为我们不用关心文档的格式,不用考虑什么字体,几级标题等等繁琐的格式,可以专注于创作本身。
姑且你已经认同了这种使用ASCII表达图像方式的优点,但是...这种图难道要使用手一个个字符地敲出来吗??如果真的这么做,简直不要太麻烦!光在前面添加一个空格,后面的所有行都需要改;我们需要一个自动化工具。
Graph::Easy
Graph::Easy 就是今天要介绍的主角;它是 perl的一个软件包,可以使用perl代码直接描述图像;当然,我们肯定不会为了画个图专门去学习perl;
这个软件包的强大之处在于: 它定义了一套非常简单易用的专门用来描述图像的DSL(领域专用语言),我们可以像写代码一样表达我们需要描述的图像(放心,这个语法非常简单);不用关心图像里面如何布局;这种语言经过处理可以得到ASCII图像,直接放在代码注释中;如果需要还可以转换成png或者矢量图等格式。
先举个简单的例子,感受一下:
![](https://i-blog.csdnimg.cn/blog_migrate/c12a83065beb82c08d5aa58d44dd6cc9.png)
这种DSL经过渲染之后得到的ASCII图是这样的:
![](https://i-blog.csdnimg.cn/blog_migrate/239b63f4401b4f66baa509a5e951ec1d.png)
02
安装
首先需要安装 graphviz 软件包,可以在graphviz官网下载;mac用户可以 brew install graphviz;其他linux发行版参考官网(http://www.graphviz.org/)。
安装perl;mac和linux用户可以略过;一般系统自带,没有的话和windows一起去perl官网(http://www.perl.org/)查询如何安装; 据说windows下有傻瓜包activeperl;请自行搜索。
安装cpan; 这个是perl的软件包管理,类似npm, pip, apt-get; mac下直接在命令行输入cpan 命令,一路next即可。其他系统参考cpan官网(http://www.cpan.org/modules/INSTALL.html)
安装Graph::Easy ;这一步就很容易了;在命令行输入cpan进入cpan shell;然后输入install Graph::Easy即可。
03
使用
使用分为两步
使用Graph::Easy DSL的语法描述图像,存为文本文件,比如 simple.txt
使用 graph-easy 命令处理这个文件: graph-easy simple.txt
最简单的使用方式就是这样;当然,Graph::Easy 不仅仅支持自己的DSL语法,它还支持诸如dot 这种较为通用的图像描述语言;可以直接读取dot 格式的输入,产生其他的诸如 ascii,png,svg格式的图像。
04
语法
注释
注释用 # 表达;注意 # 之后,一定需要加空格;由于历史原因;Graph::Easy的颜色也使用了 # ,不加空格会解析失败。
![](https://i-blog.csdnimg.cn/blog_migrate/d3f2ae6589ffc853be6c7014e6c251e9.png)
空格
空格通常没有什么影响,多个空字符会合并成一个,换行的空字符会忽略;下面的表述是等价的。
![](https://i-blog.csdnimg.cn/blog_migrate/57f9e15a07d2fe44687a77bad31b8639.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6f94eeb04a713b62b2923a1a2960452b.png)
节点(Node)
用中括号括起来的就是节点,我们简单可以理解为一些形状;比如流程图里面的矩形,圆等;
![](https://i-blog.csdnimg.cn/blog_migrate/d2b4cb5368ecc44060ad3f85046ad412.png)
可以用逗号分割多个节点:
![](https://i-blog.csdnimg.cn/blog_migrate/d1ee26f055fcb47b7435ac9665d73a91.png)
上面的代码图像如下:
![](https://i-blog.csdnimg.cn/blog_migrate/4a9ee810269dcdc71f44de9fd8a4bf1a.png)
边(Edges)
将节点连接起来的就是边;Graph::Easy 的DSL支持这几种风格的边:
![](https://i-blog.csdnimg.cn/blog_migrate/7c4553ea0618b52ec44a2a6ebe297fe3.png)
可以给边加标签,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8024da3d155b12781c641eb8b67fecd3.png)
结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f72bd38f790e5f949d575dcf8c8a1ed8.png)
属性(Attributes)
可以给节点和边添加属性;比如标签,方向等;使用大括号 {}表示,里面的内容类似css,attribute: value。
![](https://i-blog.csdnimg.cn/blog_migrate/3b21f04fae900d8bdb393d844bc5072b.png)
上面的DSL输入如下:
![](https://i-blog.csdnimg.cn/blog_migrate/37d257a95d9cc343f0559de33989d3cb.png)
Graph::Easy提供了非常多的属性; 另外,Graph::Easy的文档(http://bloodgate.com/perl/graph/manual/index.html)非常详细,建议通读一遍;了解其中的原理和细节,对于绘图和布局有巨大帮助。有时间的话我就翻译一下。
05
实例
语法是不是非常简单?有了这些知识,我们就可以建立自己的流程图了;Have a try!来个MVP模式的示意图试试~
新建文件,vi mvp.txt; 输入以下代码:
![](https://i-blog.csdnimg.cn/blog_migrate/4f939fbd0992f28bdaa3731efe3a6ad0.png)
保存然后退出;命令行执行 graph-easy mvp.txt, 输入效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/0c03811bf24bceb76c7348c4c9f122f6.png)
两行代码就搞定了!自动对齐,调整位置,箭头,标签等等;我们完全不用管具体图形应该如何绘制,注意力集中在描述图像本身;还在等什么!赶紧试一试吧!!