The Gold Old Tools: Pic and Chem

我本来只想写一下 pic 这个小工具,因为很少有中文资料介绍其用法。但是写下来没想到一个小软件联系到那么多典故,更让我对当年的贝尔实验室高山仰止。The gold old days never come again.

目录
1. Pic 的作者
2. 一个 Pic 的简单例子
3. 一个复杂的例子
4. 关于 chem 的典故
5. 在 LaTeX 中使用 pic

1. Pic 的作者

Pic,我敢打赌大部分读者没有听说过这个软件(或者说语言),但是我也敢打赌大部分读者听说过它的作者。

所以我只好从它的作者 Brian W. Kernighan 开始介绍了。不过也许用不着我介绍,假如你学过 C 语言,并且碰巧读过那本经典的 The C Programming Language(K&R);假如你使用 Linux,并且碰巧用过 AWK;或者你不小心学了一门编程语言,并且碰巧你学会写的第一个程序叫做“Hello, world”,那么你都应该感谢 Kernighan。没错, K&R 和 AWK 中的 K 都是代表 Kernighan,而且 Kernighan 是第一个使用 “Hello, world” 的人

2. 一个 Pic 的简单例子

Pic,是 Kernighan 写的一个图像排版软件,它主要用来作为 troff 中图片的预处理工具。简单点儿来说,pic 就是用来画特定一类图的工具,比如流程图、状态图、Petri~网、化学分子式等等。就像可以用写代码的方式写文档一样(TeX),我们也可以用写代码的方式画图,pic 就是这样一种语言。我们来看一个简单的例子(来自 More Programming Pearls):

.PS
ellipse "Source" "Code"
arrow
box "Compiler"
arrow
ellipse "Object" "Code"
.PE

将上面代码保存成一个 compiler.pic 文件,然后执行下面命令:

$ pic compiler.pic | groff | ps2eps > compiler.eps

我们就能得到名为 compiler.eps 的图像,下面这张图是使用 convert 命令从 compiler.eps 转换成的 png 图像:

Compiler(无法看到此图,可能因为您无法连接国外网站)

其实 Linux 下的 pic 是 GNU 版本的 gpic,groff 也是 GNU 版本的 troff,它们是都是被 GNU 重写了的自由软件版本的 pic 和 troff。

上面编译的步骤是,先用 gpic 将 compiler.pic 预处理为 troff 文档,然后用 groff 生成 ps 文件,然后用 ps2eps 将 ps 文件转化为 eps 图片。由于它们都是从标准输出打印文件,所以我们就用管道将这三个命令连接了起来,并且最后将标准输出重定向到 eps 文件。

3. 一个复杂的例子

看到这些,可能有人就怀疑说,这图很简单嘛,用 Photoshop 或者 GIMP 也花费不了多长时间,我干吗要再去学一门语言呢!那么,你尝试用 Photoshop 画一下下面这张图片。

Chemical Structure(无法看到此图,可能因为您无法连接国外网站)

画这张图的代码如下:

.cstart
    R:  benzene pointing right
        bond left from R.V4 ; HO
        bond -150 from R.V3 ; CH3O
        bond right from R.V1 ; C
        double bond up from C ; O
        bond right from C ; N
        bond 45 ; C2H5
        bond 135 from N ; C2H5
.cend

看到这,可能有人感叹说,哇,pic 真厉害!错(or 半错?),上面这段代码不是 pic 语言,而是 chem 语言。pic 是 troff 的预处理器,而 chem 又是 pic 的预处理器。所以上面这段代码的编译命令是:

$ chem.pl chem.chem | pic | groff | ps2eps > chem.eps

chem.pl 先把上面代码转换成 pic 语言,然后再用 pic 进行处理。

4. 关于 chem 的典故

关于 chem,还有一段典故:

话说当年(别问我,我不知道是哪一年)一个星期一的下午,Kernighan、 Jon Bentley 和一个同在贝尔实验室的化学家 Lynn Jelinski 闲扯了一会儿,Lynn 就向他俩抱怨在文档中插入化学结构式实在太麻烦了。正好 Kernighan 刚写了 pic,就想,咦,这不可以用 pic 画吗?于是那天晚上 K&B 就写了一个简单的前端。Lynn 一看,哎,不错!他们仨花了一个星期时间完成了 chem 语言,还在 Computers & Chemistry 杂志上发了篇 paper,名字叫做:Chem - a program for phototypesetting chemical structure diagrams。

别着急,还没完。话说当年(1990) GNU 要搞自由软件版本的 troff,开始重写 troff,把前端中的 pic, tbl, soelim 和 eqn 都重写了,就剩下画数学公式的 ideal 和 chem 没有重写。到现在你看你自己 Linux 中的 info groff,在 Introduction->Preprocessor 的最后还能找到:“There are other preprocessors in existence, but, unfortunately, no free implementations are available. Among them are preprocessors for drawing mathematical pictures (`ideal') and chemical structures (`chem').“

时间慢慢到了 2006 年 10 月 19 号,一个叫 Bernd Warken 的小子在 groff 的邮件列表中吼了一嗓子:哈哈,我用 Perl 重写了 chem!然后维护者 Werner LEMBERG 大叔就说:Great! 才有了我上文中的 chem.pl,原始的 chem 是用 AWK 语言写的。但是 chem.pl 到现在还没有到 groff 的正式发行版中,原因很囧,groff 在 2006 年 10 月 16 号以后还没有 release 新版本。所以如果你想使用 chem.pl,只能到 groff 的 cvs 仓库下载:http://cvs.savannah.gnu.org/viewvc/groff/contrib/chem/?root=groff

5. 在 LaTeX 中使用 pic

上面只是简单介绍了一下用 pic 做 eps 图片的过程,但是 pic 还可以用到 LaTeX 中,这样简单的图片就直接在 TeX 里写了。比如我们的第一个图片,就可以这样在 TeX 中使用:

\documentstyle{article}
\begin{document}
  \newenvironment{centergpic}{}{\begin{center}~\box\graph~\end{center}}
     \begin{centergpic}
.PS
ellipse "Source" "Code"
arrow
box "Compiler"
arrow
ellipse "Object" "Code"
.PE
     \end{centergpic}
\end{document}

.PS 和 .PE 一定要在行首。将上面文件保存成 compiler.tex,用 pic 预处理一下,再用 latex 编译:

$ pic -t compiler.tex > compiler1.tex
$ latex compiler1.tex
$ dvipdfmx compiler1.dvi

就能生成含有该图的 pdf 文件。

PS:若有人对 Pic 感兴趣,请阅读 Eric S. Raymond 大叔写的 “Making Pictures With GNU PIC”。你没看错,就是写《大教堂和集市》和《Unix 编程艺术》那个 Raymond 大叔。你也不用下载它,到 /usr/share/doc/groff/ 下面找一找吧,那个叫做 pic.ps.gz 的。

《The Gold Old Tools: Pic and Chem》上有6条评论

  1. K, one of my idols.
    It was said that all books made with troff were worth reading...

    $ evince /usr/share/doc/groff/pic.ps.gz
    so many pages, pass...

  2. dot / Graphviz
    http://liyanrui.is-programmer.com/posts/6261.html
    http://www.graphviz.org/Download..php

    之前复习 数据结构,正愁没有软件画图(我发觉1/3时间画图,1/2时间理解思考,1/6时间写代码似乎比较有效率)
    正想是不是要用 py + gtk 写个,这时却在 reader 上看到有人用 [ dot ] ……

    很久很久以前,写数字图书馆(shuge)时我想过怎么让 php 自动生成“学习路线图”

    都是 Bell Lab 的东西,不知道它们是不是各有秋千?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注