Markdown 的一点翻译

Markdown 是 John Gruber 精心设计的一套文本标记系统,由 Michel Fortin 转换到 PHP 并提供了 WordPress 的插件。这两天抽空翻译了一下 [Markdown][1] 的[基本功能][2]以备学习。感谢 [hlb][3] 的指点,我想下面要做的大概是翻译完整的 [syntax][4] 文件和 PHP Markdown 的[扩展][5]功能。此外,[MultiMarkdown][6] 也是个有趣的东西。

[1]: http://daringfireball.net/projects/markdown/ “Markdown”
[2]: http://daringfireball.net/projects/markdown/basics “Markdown Basics”
[3]: http://hlb.yichi.org/blog “布丁长辈的 blog”
[4]: http://daringfireball.net/projects/markdown/syntax “Markdown Syntax”
[5]: http://www.michelf.com/projects/php-markdown/extra/ “PHP Markdown Extra”
[6]: http://fletcher.freeshell.org/wiki/MultiMarkdown “MultiMarkdown”

噢对了,翻译后的文件在[这儿](http://opencjk.org/~jjgod/document/markdown/basics.php)。

Wrong Encoding? Whose Fault

早在 2004 年,Tim Bray, Nick BradburyMark Pilgrim 这几位大牛就有过一场著名的口水战,围绕着客户端是否应该接受不 valid 的 XML (XHTML) 而展开,这场口水战以 Mark Pilgrim 的一篇堪称经典的 Thought Experiment 而告结束。Mark 举的一个例子就是页面本来是完全 valid 的,但别人发来了一个 trackback,其中包含了非法的字符,导致整个页面都无法通过校验。

时至今日,一年半过去了,乱码的 trackback 仍然随处可见,我们的 blog 工具版本号一升再升,难道就是解决不了这个问题?

### 为什么要解决这个问题?

有人会问,为什么要解决这种问题呢?人人都用 UTF-8 不就好了么?没错,在一个理想的世界里,UTF-8 解决了一切问题。问题在于,在一个理想的世界里,M$ 不是坏蛋,IE 还支持 CSS 3 呢!所以我们不能依靠这种白日梦。踏实一点来看,我们现在生活的世界情况是这样的:Apache 占据了大部分的市场,PHP 和 Perl 是两种主要的 Web 脚本语言——尤其对 Blog 而言,MySQL 是大部分开源 Web 程序使用的数据库,可是主机服务上还往往不如人意,大部分的用户不能自如的指定自己 Blog 使用的字符编码,转换 MySQL 存储数据的编码也不是天天没事就能转来转去玩儿的。

这个环境,说明我们应该对他人的页面使用的编码宽容一些。

### 这个问题理应如何解决

Trackback 不是一个标准,更没有标准化组织进行维护,它只是 MovableType 中发明的一种格式,最权威的说明,就是这篇 TrackBack Technical Specification。而这个规范中对编码唯一的说明是:

The client SHOULD include the character encoding of the content being sent (title, excerpt, and weblog name) in the charset attribute of the Content-Type header.

例如:

POST http://www.example.com/trackback/5
Content-Type: application/x-www-form-urlencoded; charset=utf-8

但接收这个 trackback 的那一方如何获取这个 charset 的值呢?如果在 PHP 中,唯一的方法是用 `getallheaders()` 函数,但这是在“PHP 作为 Apache 模块安装时才可使用”——事实上许多主机提供商是以 CGI 方式安装 PHP 的。

所以此路不通,我们应该对 Trackback 的协议进行扩展,在 POST 的数据中添加关于字符编码的一项,WordPress 就是以这种方式来实现的,让我们先打开 wp-trackback.php,这是接收 trackback 用的:

$charset = $_POST[‘charset’];

if ($charset)
$charset = strtoupper( trim($charset) );
else
$charset = ‘ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS’;

if ( function_exists(‘mb_convert_encoding’) ) {
$title = mb_convert_encoding($title,
get_settings(‘blog_charset’), $charset);

上面的代码说明,WP 会从 POST 数据的 `charset` 一列中取得 trackback 发送者使用的字符编码,如果找不到就使用一套预设的编码 (从这个预设的编码我们可以肯定,90% 的可能是有个日本人给 WordPress 官方报告了 trackback 错误的问题,所以它们头痛医头,只加上了三个日文编码),然后使用 mb_convert_encoding 函数把这个编码转换为 blog 当前使用的编码。

让我们注意三点:

1. 每个 PHP 安装不一定都启用了 mbstring 模块,也就是说,不一定能进行这个转换,例如,我自己的电脑上安装的 PHP 5,默认就没有打开这个模块。
2. 当给出一列来源编码时,转换函数以一种猜测的方式来尝试转换 (我在 Planet 的 patch 中描述了这种转换的原理),但这种猜测未必是对的,例如,Big-5 的编码和 GB2312 的编码有部分是重合的,此时无论把 Big-5 列在前还是 GB2312 列在前,都无法同时正确解码这两种编码的文档。
3. 我们有理由相信这是 WP 私自作出的扩展,MT 不知道这一点 (我手头没有 MT 的代码,使用 MT 的朋友若有兴趣,请帮忙查查)。

### WP 糟糕在哪里和我们如何改进

WP 的问题是,它使用 POST 数据中的 charset 一栏来分辨编码,但它自己发送的 trackback 中,不包含这一栏 (`trackback()` 函数在 `wp-includes/functions.php` 中),我必须承认我搞不懂这是为什么。

有了上面的解释,我们很容易提出下列的改进:

1. 提出更改 Trackback 的规范,增加 charset 这一项。
2. 建议 WP 和 MT 都在发送 Trackback 时,包含这一项。
3. 建议 WP 和 MT 在发送 Trackback 时,先转换成 UTF-8 再发送。

Vanilla 的本地化

这个东东本来已经快写完了,结果 Firefox 居然崩溃了,前边写的全丢失,打倒 Firefox!

Vanilla 是个新出的论坛系统,里边有不少新概念,比如 AJAX 的运用,Atom 1.0,OO 的 PHP 开发方式,CSS 中对手持设备的支持,等等。可惜作者的水平显然还不算老练,本地化特别不方便,而是性能特别差,三是 bug 还很多,作者改 bug 又很慢。所以注定是个玩具了。建议认真想开论坛的现在别用。

昨天看了 Jedi 的 Vanilla 的中文化,便手痒找来玩玩,有几个小 bug,原来详细写了,刚才丢了数据,也懒得重新写,简单说说吧。

1. 配置文件不支持中文,解决方法看这里
2. MySQL 4.1,论坛内容不支持中文,解决方法看这里
3. PHP 5,扩展列表有错,解决方法看这里
4. 中文化中遇到的问题,过几天整理一下再细写。