浅谈代码着色(上):客户端着色
2009-12-14 19:53 Jeffrey Zhao 阅读(7891) 评论(26) 编辑 收藏 举报作为程序员,写文章时总免不了插入代码,而对代码进行着色几乎已经成为一个基础,一个事实标准。代码着色的确可以大大加强代码的可读性,因此即便是再不待见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代码,那么我们必须制定一个规则,让服务器端逻辑可以从文章的内容中识别出代码块,这样才能插入“立即着色”的代码,或是将其在服务器端进行着色。那么,您是每次输出时进行着色,还是在系统中直接保存修改好的内容?还有……
可见,“精益求精”也是有代价的。投入产出比是否值得,只有您自己可以作出判断了。