Emacs中绘图 - ditaa篇
Fast,Cheap,Good: Choose any two.
--anonymous.
1 emacs中的图
emacs用途多多,编辑代码、文档、演示文稿,记日志等等。在这些应用中有一个共同点,也是广大emacser很可能需要的一点功能,画图,对于大多数使用emacs的都是死宅死宅技术男,主要的用途还就是流程图,框图之流。
一图胜千言 1 ,图能够用简单的方式表达出可能需要很复杂的语言才能描述清的想法。一个广泛的认识就是人更容易理解图片。人们喜欢玩界面华丽的游戏,而同样的游戏如果是文本的,就会让人失去兴趣。一篇博客如果内容较多,有那么几张图片,怎么也会比全部长篇的文字要容易阅读。
那么emacs如何来插入一个给力的图片呢?
使用Latex的graphicx包。Latex的排版与图片功能相当的强大,但是它的门槛更高,使用比较复杂,应用场合主要在科学论文。一般的应用,博客,日志啥的话,投入产出比太低了。
wiki-mode,Muse-mode和org-mode这样的写作工具2,使用[image]标签,插入本地图片,然后生成html、pdf;或者插入图片的url地址,也是一种使用较多的方式。
这种方式比较普遍,方便,但不快捷。画一张合适的、给力的图片需要什么??
一个软件,熟练的操作。
软件候选者:Photoshop,收费,咱学习之用,使用绿色版 。一个Photoshop的使用那就是N本书,想真正的学会使用Photoshop来绘制流程图,也并不满足方便,快捷两个条件。Microsoft Visio,同样,收费,咱学习之用,使用绿色版,学习Microsoft Visio同样是需要一定的周期滴,也同样不满足方便,快捷两个条件。而且这两个软件有大缺点,跨平台不好,使用过程繁琐。
所以,我最衷爱的,ASCII图3就闪亮登场了,当当当当~~~,大家鼓掌。
ASCII图可以在任何文本适用的地方存在,如Internet Relay Chat( IRC), E-mail, 论坛,BBS,非图形界面,同时可以在源代码中表示公司或产品的logo,或流程图。甚至有geeker将整个程序直接写成一坨ASCII图,看起来是相当的给力4。
介绍了什么是ASCII图,它的好处。那么下一步,就讨论下如何绘制ASCII图。我们肯定不会是一个字符一个字符的去敲,然后拼起来,将简单的事情复杂化,是我的专长,但是我却从不做愚蠢的事情。画ASCII图,我们有专门、专业的软件5。
但是既然我们是emaser,我们当然要看一下,emacs能不能做这件事情呢?答案肯定是YES。
emacs中有两个mode处理ASCII图,picture-mode和artist-mode。picture-mode请参考emacswiki,而前边我们介绍过artist-mode,没看过的童鞋请进时光穿梭机。
介绍完了背景知识,我们来一个真实的例子。
2 应用场景
我们有大批的cpp,h这样的源文件,每天和他们打交道。有一天我们想要给人演示对于源文件,我们都能做些什么。我们可以使用编辑器编辑它们,以使他们完成我们需要的功能;编译器编译他们,生成可执行文件;doxygen处理他们,生成源代码的文档…,其它用途还用很多,比如把程序写成下面的样子,成功的完成zhuangbility这样艰巨的任务:
#include <math.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
double L ,o ,P
,_=dt,T,Z,D=1,d,
s[999],E,h= 8,I,
J,K,w[999],M,m,O
,n[999],j=33e-3,i=
1E3,r,t, u,v ,W,S=
74.5,l=221,X=7.26,
a,B,A=32.2,c, F,H;
int N,q, C, y,p,U;
Window z; char f[52]
; GC k; main(){ Display*e=
XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
*D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
XEvent z; XNextEvent(e ,&z);
++*((N=XLookupKeysym
(&z.xkey,0))-IT?
N-LT? UP-N?& E:&
J:& u: &h); --*(
DN -N? N-DT ?N==
RT?&u: & W:&h:&J
); } m=15*F/l;
c+=(I=M/ l,l*H
+I*M+a*X)*_; H
=A*r+v*X-F*l+(
E=.1+X*4.9/l,t
=T*m/32-I*T/24
)/S; K=F*M+(
h* 1e4/l-(T+
E*5*T*E)/3e2
)/S-X*d-B*A;
a=2.63 /l*d;
X+=( d*l-T/S
*(.19*E +a
*.64+J/1e3
)-M* v +A*
Z)*_; l +=
K *_; W=d;
sprintf(f,
"%5d %3d"
"%7d",p =l
/1.7,(C=9E3+
O*57.3)%0550,(int)i); d+=T*(.45-14/l*
X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
*I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
179*v)/2312; select(p=0,0,0,0,&G); v-=(
W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
)/107e2)*_; D=cos(o); E=sin(o); } }
//程序在linux下使用以下命令编译: //cc banks.c -o banks -DIT=XK_Page_Up -DDT=XK_Page_Down \ // -DUP=XK_Up -DDN=XK_Down -DLT=XK_Left -DRT=XK_Right \ // -DCS=XK_Return -Ddt=0.02 -lm -lX11 -L/usr/X11R6/lib
但是本文中,我们只关注对cpp源文件的前三点应用:编辑,编译,生成文档。
3 ASCII图
好吧,我们的第一个演示版本。
+----------+ edit +----------+ input +----------+ compile +----------+
| refined |<-----+ h,cpp +-------->+ compiler,+-------->+Executable|
| h,cpp | | | | linker | | File |
+----------+ +----+-----+ +----------+ +----------+
| input
v
+----------+
| doxygen |
| |
+----+-----+
| process
v
+----------+
| Doxgen |
| Document |
+----------+
第一个版本,作为一种可嵌入文本的ASCII图,绘制简单,简单,大方,实用(情人眼里出西施?)……
但是,有童鞋说过(主要是我自己感觉)实用性不强,很多人是不接受ASCII图的,文章里夹了这么一个ASCII图,别人抵触情绪马上起来,这无关技术,只是习惯。
4 简单框图
那么,如果这是一幅图,看起来或许更爽….。这样可以吗?好吧,我们试一下,把上面的ASCII图变为图片。

OMG,这个如何做到的?:),我们使用的是如下代码,将ASCII图转化为png(org-mode中)。
#+BEGIN_DITAA asciiExample.png -o -r -S
+----------+ edit +----------+ input +----------+ compile +----------+
| refined |<-----+ h,cpp +-------->+ compiler,+-------->+Executable|
| h,cpp | | | | linker | | File |
+----------+ +----+-----+ +----------+ +----------+
| input
v
+----------+
| doxygen |
| |
+----+-----+
| process
v
+----------+
| Doxgen |
| Document |
+----------+
#+END_DITAA
这里使用的是ditaa,第一次听说ditaa这个玩意是在从punchagan的博客,即这里 6,当时我问了一个org-mode中怎样嵌入ASCII图的问题7,他就给了我这么大一个鱼杆!!
5 着色
好,言归正传。看起来,还不错。但是精益求精是我们的特点,嘿嘿。我们希望区分一下,源用红色表示,处理过程用绿色表示,结果呢,我们用黑色表示,这样看起来或许更美观一些,美观也就是用Photoshop或者Microsoft Visio画图追求的效果嘛。GO.

着色的代码如下:
#+BEGIN_DITAA asciiExampleWithColor.png -o -r -S
+----------+ edit +----------+ input +----------+ compile +----------+
| cPNK | | cRED | | cGRE | | cPNK |
| refined |<-----+ h,cpp +-------->+ compiler,+-------->+Executable|
| h,cpp | | | | linker | | File |
| | | | | | | |
+----------+ +----+-----+ +----------+ +----------+
| input
v
+----------+
| cGRE |
| doxygen |
| |
+----+-----+
| process
v
+----------+
| cPNK |
| Doxgen |
| Document |
| |
+----------+
#+END_DITAA
6 完整而优雅的图案
看起来,到现在,我们做的还不错。但是,作为一个喜欢把简单事情复杂化的geek,显然我们还不能不满足。这个图没有区分度,h,cpp是输入,Excutable file是磁盘文件,Doxygen Document是文档,但是图中,它们看起来没有区分开,我们需要在休息前,再来点小的修葺。

代码如下:
#+BEGIN_DITAA asciiExampleWithColorAndType.png -o -r -S
+----------+ edit +----------+ input +----------+ compile +----------+
| cPNK | | cRED | | cGRE | | cPNK |
| refined |<-----+ h,cpp +-------->+ compiler,+-------->+Executable|
| h,cpp | | | | linker | | File |
| {s} | | {io} | | | | {s} |
+----------+ +----+-----+ +----------+ +----------+
| input
v
+----------+
| cGRE |
| doxygen |
| |
+----+-----+
| process
v
+----------+
| cPNK |
| Doxgen |
| Document |
| {d} |
+----------+
#+END_DITAA
Done!该喝杯咖啡了。哦,不,对我来说,该去睡会觉了,Zzzzzz
7 中文
能使用中文也算是基本需求了,那么最后来一个试验用图。

#+BEGIN_DITAA asciiExampleWithColorAndTypeUtf8.png -e gb2312
+------------+ +------------+
| 中文 |---->| 中文 |
| | | |
+------------+ +------------+
#+END_DITAA
正确显示中文需要文章使用的编码和ditaa指定的编码一致。
但是在加入中文的时候,边框的对齐很难做到,不得不说是个让人很不爽的地方。
8 ditaa
9 不算小结的小结
org-mode+artist-mode+ditaa是一个emacs中使用图片的很好的办法,但不是万能的。实际上,主要画流程图,框图比较好用。下面我列举了两个可以在emacs中胜任绘图需求的方法:
- graphviz
- python + matlab lib
graphviz已然非常强大,而matlab绘制科学图形是更胜一筹,鉴于篇幅,本文不再展开。
更多……..敬请期待。
Footnotes:
1 可爱的wiki利用一则漫画解释一图胜千言:A:为什么一图胜千言 B:你打字多快 A:25/分钟 B:这就对了,当我画40分钟画好了我的图,………,你正好敲了1000个字。要看出处的漫画,猛击我。
2 Wiki-mode, Muse-mode, org-mode就是博客,日志,随笔这样的居家过日子必备之工具。
3 ASCII图 是一种图行设计技术,使用ascii 标准中128个可见字符组成的picture,可用在电脑上的演示。
4 http://en.wikipedia.org/wiki/International\_Obfuscated\_C\_Code\_Contest。
5 ascii 编辑软件 http://en.wikipedia.org/wiki/List\_of\_text\_editors#ASCII\_and\_ANSI\_art。
6 punchagan是org2blog的作者,同时推荐一个牛人sacha。
7 http://punchagan.wordpress.com/2010/07/20/org2blog-readme/#comment-710 .

loading...

没人讲讲 graphviz 么,感觉比这个好。。。
[回复]
fangzhzh 回复:
八月 4th, 2010 at 3:34 上午
@wd, 下一篇吧:)
[回复]
en, graphviz 好,不过跟 emacs 没什么关系了。。?
[回复]
fangzhzh 回复:
八月 4th, 2010 at 7:25 上午
@xwl, graphviz也是可以内嵌进我们万能的orgmode的,呵呵
[回复]
cool
[回复]
还有这么power的东东啊,真帅,可惜是java的,我拒绝在自己的电脑上安装java。
PS::”给力“是个什么词啊?是我又old了么?
[回复]
fangzhzh 回复:
八月 4th, 2010 at 5:48 上午
@Meteor Liu, 给力出自 日和漫画,http://www.douban.com/group/topic/11314779/,不过和emacs没有关系,挺搞的
[回复]
ahei 回复:
八月 4th, 2010 at 5:56 上午
@Meteor Liu, ….为啥拒绝装Java啊, 又不是微软的东西
[回复]
Meteor Liu 回复:
八月 4th, 2010 at 6:59 上午
@ahei, 洁癖吧
[回复]
ahei 回复:
八月 4th, 2010 at 7:02 上午
@Meteor Liu, 哈哈,Java哪不干净了
[回复]
Meteor Liu 回复:
八月 4th, 2010 at 7:16 上午
@ahei,
能少装一个软件就不多装一个,而且java又大又慢。
当然这都是次要原因,最主要是因为我不会java。
[回复]
ahei 回复:
八月 4th, 2010 at 7:22 上午
@Meteor Liu, 光装一个Java运行环境没多大的
[回复]
fangzhzh 回复:
八月 4th, 2010 at 7:22 上午
@Meteor Liu, 单就学习面向对象的话,java的类库是个很好的教材。java本身的设计也是OO的思想更加清晰
[回复]
Meteor Liu 回复:
八月 4th, 2010 at 7:25 上午
@fangzhzh,
相比java,我宁愿用python。
java的OO我觉得是一种过度OO。
[回复]
fangzhzh 回复:
八月 4th, 2010 at 8:06 上午
@Meteor Liu, 你说的是java语言本身过度OO,还是说java的类库实现上出现了很多的过度设计,导致类库看起来很做作,在理解上不自然?
[回复]
Meteor Liu 回复:
八月 4th, 2010 at 9:18 上午
@fangzhzh,
啊,不好。这个话题马上要变成语言之争了,还是停吧
[回复]
fangzhzh 回复:
八月 4th, 2010 at 9:26 上午
@Meteor Liu, c++程序员表示鸭梨不大^-^
[回复]
fangzhzh 回复:
八月 12th, 2010 at 6:37 上午
@Meteor Liu, 最近几天在做j2me的东西,看j2me的API文档和参考实现,有点小干物。我觉得java有一些很好的东西,比如接口编程、完善的类库和文档。带
来几个好处,一是使用方便,很容易上手;二类库+接口编程使后续的对类库的扩展很自然;三多琢磨琢磨这些sun的牛人写的代码,消化其之计理念,然后应用到后续的C++工作中,也会很有帮助,毕竟思想没有界限。拙见,欢迎批评指正
[回复]
看到第一个代码段,还以为我浏览器的排版出问题了~
细看一下,原来是“zhuangbility”!哈~
[回复]
fangzhzh 回复:
八月 17th, 2010 at 1:46 上午
@tsong87, 嘿嘿,将zhuangbi进行到底
[回复]
看不出 又有文章更新了。
这篇不错,不错~~
[回复]
fangzhzh 回复:
八月 17th, 2010 at 1:47 上午
@B.Qnyd, 用greader订阅啊,有更新的话就会实时收到了,可惜计划中的graphviz还处于计划中,希望这个周能出吧
[回复]
hi,~~看了下你的文章,ditaa看起来很不错哈
不过里面好像对如何安装使用的描述很少,所以想请教几个问题
1)如果让org mode把ditaa load进来?
2)文章里讲”想要使用diataa的话,你的电脑 必须 安装java,并且使java的bin目录在
emacs的path内” 这是啥意思啊?把java的bin目录链接到emacs目录下来?
[回复]
fangzhzh 回复:
八月 18th, 2010 at 8:47 上午
@blizz,(1) org-mode负责将#+BEGIN_DITAA #END_DITAA中的代码解释为diataa代码,(2)我没有说明白,java.exe可以在emacs中调用就行。在系统的path中设定,或者emacs中设定均可。
[回复]
一直用artist-mode画框图来着。
用文本还是方便啊。。
复杂的就不行了。
[回复]
fangzhzh 回复:
九月 10th, 2010 at 7:41 下午
@wgf4242, 是啊,简洁,实用才是artist-mode的初衷嘛~~~~~
[回复]
偷偷的告诉楼主
PlantUML+graphviz+org-mode,比ditta还要强大的多哦~~
NND.我三个月前给AHEI发送EMAIL,写了一片有关EMACS快捷键的文章.
其中就使用了PlantUML画流程图.源码文件都给他发过去了,都这么久了,
也没见给传上来.吐血.
[回复]
偷偷的告诉楼主
PlantUML+graphviz+org-mode,比ditta还要强大的多哦~~
NND.我三个月前给AHEI发送EMAIL,写了一片有关EMACS快捷键的文章.
其中就使用了PlantUML画流程图.源码文件都给他发过去了,都这么久了,
也没见给传上来.吐血.
[回复]
fangzhzh 回复:
十月 9th, 2011 at 8:43 上午
@zw963,我当时是想整一个系列的,ditaa, graphviz, asymptote,后面的那篇asym,写了一点点,但是不满意,就扔了。
你写一篇关于plantuml的吧。
你跟ahei联系下,问问为什么没有发吧,据说他最近很忙,百度加班严重
[回复]