写给《程序员》杂志社:那些你们早该知道的东西

缘起

最近我写了一篇文章投给《程序员》杂志社,“开源”专题。我写的是关于Jscex的内容,自然十分用心,再加上看了不少之前编辑让我提些意见建议的文章,因此我对于这期的内容还是很有信心的。我是一个对文章阅读体验有极高要求的人,无论是作为文章的读者还是文章的作者,也经常对各种样式混乱的博客表示不满。我也算是《程序员》的长期读者,知道它在代码展示方面有很多不足之处,之前也时常向相关人等(例如刘江总编)提出不少建议。这次既然涉及到我的文章,我自然会加倍小心,千叮咛万嘱咐,也主动配合编辑的工作。我反复的询问编辑对于代码提交方式的需求,对方说要提供代码的截图,最好需要着色。于是我为每一幅代码都提供了高清的截图。有多高清?在Retina屏幕的帮助下,图片像素高达3360x2100,当时我还在微博上笑谈到“这次总不会模糊了吧”。保险起见,我还为每一段代码增加了PDF矢量格式。

令人遗憾的是,在编辑发给我的PDF中这段代码是这样的:

我顿时就愤怒了。清晰度先姑且不谈,编辑说是因为这是压缩后的PDF,实际印刷出来会很清晰。但是,代码为什么会变成这样?我的高清截图哪儿去了?即使由于种种原因这种截图无法使用,那么矢量的PDF呢?我并不是心疼我花在准备代码上的时间,我心疼的是整篇文章的阅读体验。假如我看到一篇这样的文章,我基本就会随手丢在一旁,糟糕的阅读体验会让我没有心情关注内容。在我看来,我的文章就这么被毁了。

即便编辑对此表示歉意,但于事无补。同时我发现《程序员》杂志社从编辑到排版人员,居然会不了解一些已经被广为接受的知识,甚至可以说是“常识”。为了让今后的文章可以“免遭毒手”,我当时立刻表示要为《程序员》杂志社单独写一篇文章补补课。编辑和排版人员不能因为“不写代码”而忽视这些基础内容,因为这对你们来说就是所谓的“行业”或者说“领域”知识。就好比我现在是金融行业的程序员,就不能因为我“只是个写代码的”而对基础金融常识视而不见。

没有这么多理由。

代码样式

上面这段代码犯了一个最最基本的错误:使用了“非等宽字体”。例如,您能看出上面这段代码使用了几个作为缩进?有人说是4.5格,这估计是看着第一个缩进数出来的,您不妨再数下if (compare(与上一行代码相差了几个字符。这就是因为在非等宽字体里,不同的字符是不同的宽度,空格就显得特别窄,而小写l和大写W的宽度会差好几倍。但是在等宽字体中,无论是什么字符都是相同宽度,例如World的五个字符。代码排版一定要使用“等宽字体”,也就是每个字符都是相同的宽度,这样代码才能显得优雅整洁,对齐良好。

例如我博客上的代码都优先使用Windows自带的Consolas字体:

或是Mac自带的Monaco字体:

不过等宽字体只是必要条件,还不够充分,例如Courier New是一种等宽字体,但并不适合用于编写代码。请看这个表达式:

假如您的答案是1234,则说明您落入了Courier New的陷阱。这里第二个数字并非11111,而是一个长整型的1111,因为它最后一个字母是小写字母L,而不是数字1。但是换作是Consolas就会一清二楚:

Monaco也有明显区别:

同样需要区分的还有数字0和大写字母O等等,这点对于非等宽字体来说反而不是问题,但在选择等宽字体时就需要注意区分度,让人可以一眼看清究竟是什么样的代码。适合用于编写程序的字体有很多,而且几乎都是现成的,我们完全不需要自行挖掘。

代码样式虽然简单,但往往就是是否专业的分水岭。不管你是多么优秀的程序员,一旦使用了非等宽字体编写代码,我就会认为你至少在这个方面显得不专业。当然,你可以说是你的个人习惯,我也会尊重你的选择,因为这只会影响你一个人。但是,作为一个出版社,一个媒体,是要将一段代码展现给千万大众阅读的,如果还使用非等宽字体就是一种罪过了。其实《程序员》杂志之前的代码也至少会使用等宽字体,不知道为什么这次就这么堕落了,还堕落在我这个极其重视阅读体验的人头上。

文档格式

我不知道《程序员》内部使用什么格式提交文本,就我感觉来说他们十分喜欢Word,我拿到的所有的文档都是Word格式的。我这次提交了Markdown格式及其导出的HTML文件,编辑的反馈居然是“排版人员不知道如何使用”,最后的文章也完全丢失了所有的内嵌代码格式。好吧,那么我们就一点点来说。

对于一篇文章来说,Word其实很不利于排版。因为Word自带大量样式,这些显然不能直接使用。而且,并非所有人都会使用Word进行排版,因此我们经常能看到一些格式混乱的Word文档。有经验的同学会使用Word的“大纲视图”来编写代码,最终设定各个节点的格式,一篇文章的布局就搞定了,完全不需要手动设置每一行每一段。

从这个方面来说,其实HTML是个很好的格式,排版人员应该很容易使用才对。HTML文档本身其实不包括任何样式,样式都是由CSS决定的。HTML节点都有各自的“语义”,例如用<h1></h1><h6></h6>来表示标题,<p></p>来表示自然段落,<code></code>来表示代码,<ol></ol><ul></ul>来表示有序或无需的列表,一篇使用HTML提交的文章,其文档的结构已经一清二楚,剩下的只是如何表示每个元素的问题。

但是“HTML标签”终究不太适合直接用来编写文档,因为人们需要花额外的精力来表达文档结构,而并非全身心投入到文档内容里。如果使用一些所见即所得的工具来编写HTML,又容易出现样式混乱的情况。我目前见过的最好的,最干净,最不容易产生混乱代码的HTML所见即所得编辑器便是Windows Live Writer,这这可能是因为它的目标是为了编写博客这样的文章内容,因此只提供了相当有限的样式设置功能,并能自动清理混乱的HTML代码。这其实也是我们写技术文章的要求:结构清楚,不需要复杂的样式。所以,我其实很推荐各位使用Windows Live Writer来编写文章——假如不那么“技术”的话。

对于技术人员来说,或者文章中涉及大量代码,可能更好的选择是Markdown格式。Markdown是专为程序员打造的文档格式,它的特点是容易编写,容易阅读。使用Markdown我们可以很轻易地表达出文档的各种结构,例如段落,列表,甚至代码:

# 一级标题

## 二级标题

段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一段落一。

段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二段落二。

    // 缩进四格即是代码    
    var compareAsync = function (x, y, callback) {
        setTimeout(function () {
            callback(x - y);
        }, 50)
    }

还可以引用:

> 引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一引用一
>
> 引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二引用二

以及列表:

1. 有序列表项1
2. 有序列表项2
3. 缩进四格还可以嵌套
    * 无序列表项1
    * 无序列表项2

使用Markdown格式一般是为了生成HTML(它还支持内嵌HTML代码),因此例如上面的内容会自动生成<h1></h1><h2></h2><p></p><pre><code></code></pre><blockquote></blockquote><ol></o><ul></ul>等元素,但是从编写上来说Markdown格式无疑更为方便。同时,Markdown格式可以使用普通的文本编辑器打开,并直接阅读,基本没有障碍。正因为这些好处,Markdown格式已经在编程领域运用地越来越广泛,例如StackOverflow的回复,自然也有我的博客回复等等。我建议,假如您认为自己是一个专业程序员,就尽快掌握Markdown格式吧。

值得一提地是,Markdown还支持在段落内方便地嵌入代码:

Step类库提供了一个`Step`函数。

它生成的HTML代码会自动为第二个Step用上<code></code>标签,因此样式也会有所不同,例如在我的博客上:

还记得代码的基本规则吗?没错,便是“等宽字体”。文章的内嵌代码也是代码,也要使用等宽字体。遗憾地是,尽管我不断向编辑强调这一点,尽管我提供的Markdown格式和HTML里面都体现了普通文本和内嵌代码的区别,最终《程序员》杂志还是不加分辨地进行排版。

总结

虽然这篇文章是因《程序员》而起,也是特地写给《程序员》的编辑和排版人员的,但是这种业余的排版风格并非他们一家的专利。例如“电子工业出版社”的《HTML 5实验室:Canvas世界》一书,其中所有的代码排版也是混乱不堪,此外我也不提这不知道是“太太乐鸡精”还是“香飘飘奶茶”风格的封面了。尽管书中写了不少Jscex的内容,我还是实在不好意思向别人推荐这本书,因为看上去实在是太山寨了。

说实话我很难想象,国内的出版媒体会堕落到这种地步,经历了那么多年,连一些基本的要求都做不好。其实这并不仅仅是出版社的问题,读者和作者也有一定的责任,为什么那么多年来就没人指出?为什么作者不讲究点“品味”不爱惜自己的辛勤成果?到底怎样才能让我们的媒体变得专业?我不知道,但至少从现在开始,我会努力盯住我所看得到的地方。《程序员》杂志自然是一个,希望你们不会让我失望。

不对,是“继续”失望。

文章来源:

Author:jeffz@live.com (老赵)
link:http://blog.zhaojie.me/2012/07/to-programmer-magazine-something-you-should-have-known-for-a-long-tim