Org Mode

Org Mode 本来是 Emacs 中的一个管理 todo 的工具,有很多人用它来做 gtd 管理,但是实际上它的排版功能也非常强大,比目前风靡全国的 markdown 更加优秀。语法形式上两者有所交集,但是本质上 Org Mode 更加统一和方便;此外由于号称支持 markdown 的编辑器太多,并且各家都有一些不同的标准在,导致很多不爽的东西,例如代码高亮,再例如插入图片的方式等,直接的 latex 公示预览等。相比之下,Org Mode 目前还只是作为 Emacs 的插件来提供的,支持比较完整和统一。输出功能也是 orgmode 的优势,可以配合各种后端输出程 html,latex,pdf,markdown,slide 等等等等。markdown 的输出需要配置 pandoc,依赖比较繁琐。配合 org-babel 之后,能够完成很多令人惊奇的事情。可以毫不夸张的说,org-babel 的出现,极大的扩展了 org-mode 作为排版工具的用途。

org-babel 是什么

历史渊源

据《圣经·创世记》第 11 章记载,很早时候,人类说话的口音都是一样的,当时人类联合起来兴建希望塔顶通天能传扬己名的高塔,该塔叫做 Babel,通常叫巴别塔或通天塔。为了阻止人类的计划,上帝让人类说不同的语言,使人类相互之间不能沟通,计划因此失败,人类自此各散东西。

实际上搬到今天的程序语言届也一样,每隔一段时间总有人出来争论,那种语言更好用。org-babel 是 org 里面的 babal,其目的是使的各种语言都能够以一个统一的格式表现在文档中,更好的进行排版。也就是说,这个 org 文档,它既懂得 c 语言,又懂得 python,java,还有各种各样的其他语言,这些语言能够统一的表现在一个文档中。从这个意义上讲,org-babel 更加类似于《银河系漫游指南》中的 babel fish。

“体型很小,黄色,外形像水蛭,很可能是宇宙中最奇异的事物。它靠接收脑电波的能量为生,并且不是从其携带者身上接收,而是从周围的人身上。它从这些脑电波能量中吸收所有未被人察觉的精神频率,转化成营养。然后它向携带者的思想中排泄一种由被察觉到的精神频率和大脑语言中枢提供的神经信号混合而成的心灵感应矩阵。所有这些过程的实际效果就是,如果你把一条巴别鱼塞进耳朵,你就能立刻理解以任何形式的语言对你说的任何事情。你所听到的解码信号就是巴别鱼向你的思想提供的脑电波矩阵。

从一个统一的角度来说,实际上所有的编程语言只做一种事情,那就是对于给定的输入,给出一个给定的输出。换句话说,即使程序语言内部不知道,不过几乎所有的语言,输入和输出其实都差不多。所以在这个框架下,其实它们是统一的。org-babel 即可以将它们统一到 org 文档中。

文学编程

正经的说,org-babel 可以将其他语言都嵌入到 org 中,并且可以运行,还可以将结果也保存在 org 文档中,类比的讲,可以想一下 ipython-notebook,但是 notebook 只针对 python 语言,而 org-babel 几乎可以针对所有语言!

在程序设计语言中,有一类程序语言设计方式叫做“文学编程”,即 Literate programming,是由高德纳老爷子提出的编程方法,维基百科上这么解释的:

正如高德纳所构想的那样,文学编程范型不同于传统的由计算机强加的编写程序的方式和顺序,而代之以让程序员用他们自己思维内在的逻辑和流程所要求的顺序开发程序。文学编程自由地表达逻辑,而且它用人类日常使用的语言写出来,就好像一篇文章一样,文章里包括用来隐藏抽象的宏和传统的源代码。文学编程工具用来从文学源文件中获得两种表达方式,一种用于计算机进一步的编译和执行,称作“绕出”(tangled)的代码,一种用于格式化文档,称作从文学源代码中“织出”(woven)。虽然第一代文学编程工具特定于计算机语言,但后来的工具可以不依赖具体语言,并且存在于比编程语言更高的层次中。

配置了 org-babel 的 org 恰恰也是文学编程的利器。可以吧整个程序组织成一个 org 文件,注释和代码一起,注释详细解释了代码的逻辑和思想。不过这个方式用起来不多,倒在教学或演示中用得很多,例如 ipython notebook。作为一个可以跟着学习的交互式文档,或一个小的代码演示平台。也特别适合学一种语言的一个笔记记录,演示和学习心得都统一在一体。

ob-ipython

ipython-notebook 之所以好,是因为 ipython 在后台使用了一个 kernel,前台的文件需要与后台的 kernel 通信来解析和执行,并且可以同步的将执行结果显示在前台界面。通过将代码或文字组织成 block cell 的方式,将两者进行了统一。但是在每次增加 cell 的时候需要指定 cell 的类型,即是 markdown 文字 cell 还是代码。由于将代码直接写在网页上,缺少了代码高亮,补全等一系列的写代码必备的功能,这些使得 ipython-notebook 不适合写很多代码,只能做一些小的演示。

ob-ipython 相比之下就没有这些问题,基于 org 的 source block,可以随时将代码块 narrow 到一个专门的编辑区域编辑,这个编辑区域和原生编辑代码的一致,代码补全,实时纠错和在编辑器写代码体验一样,而在编辑器中写代码也恰好是 emacs 擅长的。此外通过对代码块加头尾标识的方式,更加适合协作的整个流程。不需要考虑下面一个块是代码还是文字,比较统一。

综上,ob-ipython 可以算是 orgmode 中的一个非常特色的 org-babel 模块,几乎可以完全的替换 ipython-notebook,还具有一些更好的功能。下图正好是使用 ob-ipython 的一个简单截图。

tangle

tangle 比较有意思,可以讲文档中所有的代码抽取出来,形成一个文档。例如写一个类似 ipython notebook 的文档,可以一个命令将所有的代码抽取出来形成一个 py 文件,这个文件可以作为软件的代码发布。这在配置文件中很有用。例如 emacs 自身的配置,很多配置为什么这么写是有其根据或渊源的,这些当然可以通过注释的方式写出来,不过更好的方式是保留 org 格式的整个文档,在载入时自动抽取。