代码改变世界

浅谈代码着色(上):客户端着色

2009-12-14 19:53 by Jeffrey Zhao, ... 阅读, ... 评论, 收藏, 编辑

作为程序员,写文章时总免不了插入代码,而对代码进行着色几乎已经成为一个基础,一个事实标准。代码着色的确可以大大加强代码的可读性,因此即便是再不待见IDE的朋友,代码着色永远是必不可少的。不过在网页中进行代码着色的方式有很多,现在我们就来对比一下。记得之前也有朋友写过,但我总觉得不够完整,于是还是自己写一下吧。

这样过瘾。

现在先来谈“客户端着色”。这种着色方式的基本做法,在于在HTML中显示(几乎)完全普通的文本,而在页面加载过程中在浏览器里进行着色(通常是使用JavaScript)。由于HTML是服务器端输出的,但它不负责着色,因此我把这个做法叫作是“客户端着色”。例如,著名的问答网站Stack Overflow便使用的是客户端着色——可惜,我不知道它使用了何种着色方式。

如果我们要使用客户端着色,那么可以使用Syntax Highlighter这个JavaScript组件。这个组件现在非常流行。博客园便提供了内置的Syntax Hilighter支持。例如,它最基本的使用方式如下:

<pre class="brush:csharp">
static void Main(string[] args)
{ 
    // comment
    var i = 1;
    var s
}
</pre>

便可生成如下的效果:

static void Main(string[] args)
{ 
    // comment
    var i = 1;
    var s
}

然而,Syntax Highlighter的强大之处,在于它的可配置性。例如您可以如此来折叠代码,并高亮其第1和第3行:

<pre class="brush:csharp;collapse:true;highlight:[1,3]">
static void Main(string[] args)
{ 
    // comment
    var i = 1;
    var s
}
</pre>

效果如下(不过博客园的样式似乎不太好看):

static void Main(string[] args)
{ 
    // comment
    var i = 1;
    var s
}

其他更多配置还所有“轻量模式(没有右上角的浮动)”,“起始行号”等等——至少我看了之后就直接震精了。

客户端着色的最大优势,便是在于良好的分离。话说我们为什么要提倡XHTML + CSS的网页编写方式呢?其关键也就是“分离”:“数据”和“样式”的分离。客户端着色的方式,由服务器提供最纯粹的数据,没有任何修饰的数据,而在客户端通过JavaScript来进行“改写”——就好比用CSS来在客户端把平淡的XHTML变得丰富多彩一样。

既然分离,灵活性就高了。例如Syntax Highlighter也提供了一些“代码着色”以外的部分。因为可以使用JavaScript来操作页面,于是我们可以在页面上放置任意灵活的DOM结构。此外,如Syntax Highlighter是将HTML着色成带有不同class(如keyword或comment)的<code>标记。于是,我们可以通过不同的CSS定义来表示不同的着色方式。这样即便需要有所改变(如博客版式变化),那么好,我们重新提供一套着色样式即可。

不过客户端着色也有缺点。首先,您可能已经观察到了,如果使用Syntax Highlighter进行着色,在内容显示的时候是非常平淡的,这一切直到页面加载完毕后才改变,这是因为Syntax Highlighter在windows的load事件中才能进行着色。如果页面加载比较慢(如我的博客),可能就会等待较长时间才能看到着色效果。还有一个缺点可能不太被人关注:如果有人通过RSS等方式订阅了您的文章,那么它便无法获得着色效果了。

如果您只是一个普通用户,那么对于这两个缺点只能选择默默承受。不过,如果您是这个系统的开发人员,那么理论上还有的救,毕竟事在人为么。例如对于第一个缺点,我们可以在每个代码块下方插入一段用于“立即着色”的脚本,这样便可以避免着色的延迟。而第二个缺点,也可以在RSS内容输出之时,为文章里的代码块在服务器端进行着色。

于是这又带来了新的考量:如果系统使用wiki标记或BBCode等方式来保存文章内容,那么便要修改其转化逻辑。如果系统直接保存的是HTML代码,那么我们必须制定一个规则,让服务器端逻辑可以从文章的内容中识别出代码块,这样才能插入“立即着色”的代码,或是将其在服务器端进行着色。那么,您是每次输出时进行着色,还是在系统中直接保存修改好的内容?还有……

可见,“精益求精”也是有代价的。投入产出比是否值得,只有您自己可以作出判断了。

使用Live Messenger联系我