在Web页面里渲染Dot图形(Make Apache A GraphiViz Server)

在工作中,我们用 wiki 或者 html 页面维护我们的设计文档。文档中会嵌入一些流程图、数据流图之类的 graphs。如果用 GraphiViz 的 dot 格式来描述,会很方便,因为 dot 格式是一种描述性语言,其源码和 wiki/html 源码都可以用SVN 管理,而 SVN 可以协调大家对同一个文档(或者其中某个插图)的修改,这就成了一个 geek 版本的 Google Docs。

那怎样才能让文档(html文件)中的插图(dot文件)在浏览时被渲染成图像(比如png或者gif文件)呢? 一个叫 Stephen North 的哥们儿用 Perl 语言写了一个 叫做 webdot.pl 的 CGI 程序来做这事儿。具体的说,当 Apache(或者其他) Web 服务器得到一个渲染请求,比如:

http://myhost.mycompany.com/webdot.pl/a.dot.neato.png

它就会调用 webdot.pl,来渲染http://myhost.mycompany.com/a.dot这个dot文件--用 GraphViz的neato引擎,渲染成 png 格式,并且返回浏览器。

这样一来,我们的文档(比如叫做http://myhost.mycompany.com/design_doc.html)中,就可以嵌入这样一个html tag:

来显示由 a.dot 渲染出来的 png 图像了。

webdot.pl 很聪明--如果一个 dot 文件已经被渲染过了,则其结果会放在一个缓存目录里,下一次请求就不用重新渲染了,而是直接返回缓存的渲染结果。这就需要指定一个缓存用的目录,这个目录是被 Apache(或者其他) Web 服务器启动的 webdot.pl 的 CGI进程可以访问的(有读写权限的)。

周末在我的 iMac 上试了试上面的想法,把工作过程记录如下:

  1. 安装 Apache。在 Mac OS X 上,Apache 是标准组建,不需要安装;在各种
    Linux上,也都很容易安装。
  2. 安装 GraphViz。在 Mac OS X 上,可以通过 Homebrew来安装:
    brew install graphviz

    在 Linux 下都可以用对应的 package manager 来安装。

  3. 因为 webdot.pl 是用 Perl 写的,所以需要安装 Perl。在 Mac OS X 上,Perl 是随着 XCode 安装的;在 Linux 上,可以用对应的 package manager 安装。
  4. 修改 Apache 的配置文件,使其可以执行 CGI 脚本。
    sudo emacs /etc/apache2/httpd.conf

    确保有下面这行(没有被注释)

    AddHandler cgi-script .cgi .pl
  5. 修改用户属性权限文件。比如我的用户名是wangyi,所以我要修改
    /etc/apache2/users/wangyi.conf,确保有以下两行

    Options Indexes MultiViews SymLinksIfOwnerMatch Includes ExecCGI
    DirectoryIndex index.html index.cgi
  6. 重启 Apache,让上面两步修改生效。在 Mac OS X 上,在 System Preference > Sharing 对话框里,勾掉 Web Sharing,等一会儿,再勾上 Web Sharing。在 Linux 上,应该是通过执行以下命令:
    sudo /etc/init.d/httpd restart
  7. 为了确认上面两步正确,我们让 Apache 来执行一个简单的 CGI 脚本程序。在用户目录下(我的是/Users/wangyi/Site),写一个简单的 perl CGI 程序,比如取名叫first.pl:
    #!/usr/bin/perl -wT
    print "Content-type: text/html\n\n";
    print "<h2>Hello, World!</h2>\n";
    

    使这个文件有可执行权限:

    chmod a+x first.pl

    然后在浏览器里试试:

    http://localhost/~wangyi/first.pl

    如果一切正常,应该看到浏览器里显示了大字”Hello, World!”。如果没有,则检
    查一下log文件:/var/log/apache2/error_log

  8. 下载和安装 webdot.pl。从这里下载,放到上一步放 first.pl 的那个目录(/Users/wangyi/Site)。需要编辑webdot.pl,以确定其中三个变量, Tdir, $SigCommand, GraphvizBinDir,的值是有效的。
  9. 写一个简单的 dot 文件(比如叫做/Users/wangyi/Site/a.dot):

    graph G {
    a — b — c — d
    b — e — d
    }

  10. 在本地测试 webdot.pl。执行以下命令:
    cd /Users/wangyi/Site
    ./webdot.pl http://localhost/~wangyi/a.dot.neato.ps
    

    webdot.pl应该能通过 HTTP 访问到 a.dot,并且将其渲染成 Postscript 格式,结果打印在屏幕上。

  11. 在浏览器里测试 webdot.pl。在浏览器里输入
    http://localhost/~wangyi/webdot.pl/http://localhost/~wangyi/a.dot.dot.gif

    正常情况下应该能看到输出;否则应该检查log。

  12. 在文档中嵌入插图(graph)。试着编译一个 html 文件(比如叫做/Users/wangyi/Site/a.html:
    <html>
    <body>
    Hello
    <img src="http://localhost/~wangyi/webdot.pl/http://localhost/~wangyi/a.dot.dot.png"/>
    </body>
    </html>
    

    然后在浏览器中访问之:http://localhost/~wangyi/a.html,效果应该如下图