Archive for July 2005

A MySQL 4.1 Story

下面要写的是一篇非常无聊的东西,充斥了大量各式各样的编码、转换、客户端、服务器端、连接……呃,我自己都不愿意去看它,但想一想,写下来还是有点意义的,原因有四:

  1. MySQL 4.1 对多语言的支持有了很大变化 (这导致了问题的出现);
  2. 尽管大部分的地方 (包括个人使用和主机提供商),MySQL 3 仍然占主导地位;但 MySQL 4.1 是 MySQL 官方推荐的数据库,已经有主机提供商开始提供并将会越来越多;
  3. 许多 PHP 程序以 MySQL 作为默认的数据库管理软件,但它们一般不区分 MySQL 4.1 与 4.1 以下版本的区别,笼统地称“MySQL 3.xx.xx 以上版本”就满足安装需求了;
  4. 因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题;

简单的说,MySQL 自身的变化和使用 MySQL 的 PHP 程序对此忽略,导致了问题的出现和复杂化,而由于大部分用户使用的是英文,使这种问题不被重视。这里提到的 PHP 程序,主要就 WordPress 而言。 Continue reading ‘A MySQL 4.1 Story’ »

IE 7 Beta 1

订阅了 MSDN 的用户已经可以下载 IE 7 的 Beta 1。同样一个 IE7,有人关心的是 CSS 的支持,有人关心的是对 Firefox 的影响,还有人关心的是 Google 和 Yahoo 的 Toolbar…

中文版 Windows XP 的用户需要修改注册表才能运行安装程序,详情请看这里

Planet 的一个 patch

Planet 是一个比较常用的 feed 聚合器,GNOME、Debian、Perl 等社群都使用这个收集他们相关的新闻,采用的是 Mark Pilgrim 的 Universal Feed Parser (现在这个 feed parser 已经不由 mark 维护,而是放在 sourceforge.net 由几个人共同维护),原来的设置里没法正常处理中文,前几天试用这个东西的时候,顺手做了点修改。这里是 diff 文件,应用在 planetlib.py 上 (我的修改根据的是前几天的一个 nightly 版本)。

但请注意,这仅仅是一个面向简体中文用户的修改,如果你希望支持其他的编码 (比如 ISO-8859-1、Big-5 等),可以参考我的改动变化一下,并不复杂。

因为面对的仅仅是简体中文用户,所以只需要保证不同的来源编码 (gb2312、gbk、gb18030 和 utf-8) 都能够正确转换成目标编码 utf-8 即可。现在使用的策略是这样的,不根据 xml encoding= 中的内容来判断编码,首先尝试以 gbk (即 cp936) 解码,不行则用 gb18030 解码,再不行则直接返回 (认为此时是 utf-8)。

这种策略是考虑到简体中文的 blog 一般只有可能使用上述三种编码。(本来没用 gb18030,但在测试的时候遇到一个 blog 的 RSS 有个地方 gb2312 无法解析,换用 gb18030 就 OK 了,说明 xml encoding 有的时候也是骗人的…)

说到 Planet,类似的程序还有一个基于 Wordpress 和 Magpie Feed parser 的插件,feedwordpress,试用了一下没发现什么问题,能够根据源编码自动判断并转换成 utf-8。但要小心不能正常处理 UTF-8 的 MySQL 服务器。

好吧……我承认就在我自己的机器上遇到了这个问题,从插件怀疑到 wordpress,再怀疑到 php,最后终于发现原来是 MySQL 这小子坏事,网上好像也见到类似的情况。

Win32 下开发 Apache2 Module 起步

Apache 的模块是很有意思的东西,原来 O’Reilly 有本 Writing Apache Modules in Perl and C,算是这方面的终极宝典,可惜此书名不副实,Perl 的内容占了绝大部分,C 的内容几乎是一笔带过 (也难怪,作者就是 mod_perl 的作者嘛),而且这本书是 1999 年写的,也是按照 Apache 1.3 的内容来写的,和现在 Apache2 的情况已经有了不少差别。

而且网上有的教程都是讲 Linux 下的配置过程,问题在于我自己在测试开发的时候是要用 Win32 下的 Apache 的,所以只好自己搞定。

我在网上 google 了一下,没找到什么详细的资料,考虑可能有朋友需要这种上手的教程,把今天的步骤写下来。

安装 Apache 2.

这里 找到一份最简单的 Apache2 module 源代码,这里有这份代码的详细说明,不过讨论是 Unix/Linux 下的情况。

如果你没有安装 Visual C++ 6.0 或者 Visual Studio .Net 的话,可以安装 Visual C++ 2003 Toolkit,这是免费的 M$ 的 C++ 编译器。

在 mod_tut1.c 的开头加一句:

#ifndef WIN32
#define WIN32
#endif

把 Apache2 的头文件和库文件目录加入 INCLUDE 和 LIB 环境变量中。可以参考下面这个 batch file:

set LIB=%LIB%;E:\Progra~1\Apache~1\Apache2\lib
set INCLUDE=%INCLUDE%;E:\Progra~1\Apache~1\Apache2\include

cl /c mod_tut1.c 编译,生成 mod_tut1.obj

link /DLL mod_tut1.obj libhttpd.lib 链接起来,生成 mod_tut1.dll

mod_tut1.dll 改名为 mod_tut1.so,复制到 Apache2 安装目录的 modules 子目录下。

在 httpd.conf 中加一句:

LoadModule tut1_module modules/mod_tut1.so

重新启动 Apache,访问 http://localhost/ 一次,然后打开 access.log,看看里面有没有新增“A request was made”的内容,有的话,说明搞定了。:)

当然,上面的内容也不是开发的实际过程,具体的开发过程,前面提到的那本书和 Apache 的文档里描述得更详细,这些,无论是 Unix/Linux 还是 Win32 都是共通的,所以也就无需我饶舌了。

说说 O’Reilly 的图书

毫无疑问,O’Reilly 是我最喜欢的出版商,现在连我父母都知道我喜欢挑“封面有小动物”的书买,说来看了这几年 O’Reilly 出的书,架上堆了十来本,硬盘上更是塞了近百本电子版的,对这些书,还是有点感想的,这里便挑基本说说。

Programming Internet Email (Internet Email 编程)

这书算是最早看的一本了,绝对是关于 Email 编程的集大成者,特点是并不多花时间讲繁复的协议,而是侧重于代码,从 SMTP、POP 到加密、邮箱的编写等等都有详细的讲解,大部分的代码实用 Perl 写的,不过都很直接,可以轻松转换为其他的语言,只有涉及本地邮件存储的一些代码采用 Java 实现,不大容易移植到其他语言中。另外美中不足的是,没有涉及邮件服务器的编写,大概如果谈到这个,短短 400 余页的篇幅根本不够吧。

C Pocket Reference

我是个懒人,连天天要用的 C 库函数也往往记不好,每到这时,往往临时抱佛脚,赶紧点开电子版的 C Pocket Reference。C 语言的参考手册当然不少,K&R 后边附的一般够用,GNU LibC 的手册也不错,但这本书好就好在简明,找起来特别快。不过现在用 vim 写程序,装了个叫 cref 的插件,找起来更方便了,这本书也就渐渐不怎么打开了。

lex & yacc

有个朋友曾给我描述这么个场景:到麦当劳要杯可乐,然后翻开一本 lex & yacc,坐在里面看到午夜,算是程序员很惬意的生活了。我看书一向缺乏耐性,这本书也就刚刚把 lex 的部分看完,估计也看不到午夜,不过印象最深还是它的侧重实用,程序员们看大部头的编译原理,被种种概念闹得一肚子火的时候,这书就实在太及时了,精当而不多余的例子,每个都值得细细咀嚼。唯一的遗憾是中文版翻译得太差。

Learning XML

我学 XML 算是半路出家,打开一个 XML 文件觉得好玩,就自己瞎编开了,也不知道什么 DTD,就写了数千行的 XML 和 XSL,也仅仅是觉得好玩而已。后来看到这本书,不禁可惜自己开头没看到它,不然系统的学一学,也不至于像现在脑袋装的那么不牢靠,可现在手头有了这本书,却又没有心境从头看起了。和 Learning 系列的其它书一样,这本书也挺薄,大概也就 300 页上下,唯一可惜的是贵了点,中文版要卖 30 多元。如果你刚刚才开始学 XML,强烈推荐。

sed & awk

这本书符合 O’Reilly 图书的一切特征,简明扼要,绝少废话,例子也很实用,所以不必我多说什么了,只要你发现 sed 或者 awk 很对你的胃口,相信买本 sed & awk 是没错的。唯一的遗憾是内容的组织稍微松了一些,不耐心的读者会觉得重要的特性总在后边。

Learning Perl

这是技术书籍中幽默的典范,有的时候太幽默了以至于我无法集中精力去学习 Perl。

Learning the Vi Editor

如果你用的是 vim,而且希望尽量发挥 vim 的强大功能,这本书不会有很大帮助,因为太多篇幅被消耗在 vi 的其他 clone 版本上了。事实上 vim 本身的手册已经够好,真的不需要什么其他的书了。

SQL in a Nutshell

差点忘了这本书,也是看得很早的一本,in a Nutshell 系列毫无疑问也是适合家中收藏的,能够在相对较短的篇幅内浓缩大量参考手册般的资料,同时又不失可读性,这就很能展现 O’Reilly 作者们的功力了,这个系列的书我认真读的虽然只有这一本,但 Java in a Nutshell、Linux in a Nutshell 等都很不错。单就此书而言,侧重的是标准的 SQL 和各个厂商实现之间的差别和比较,能不止于商业的数据库,而同时涉及 MySQL、PostgreSQL 这些 Open Source 的产品,这一点就令我很满意。

UNIX Power Tools

每天睡前看一则 Unix Power Tools,此乃提升功力的一大秘诀,切切。

好书当然还有很多,不是我这里能够列举得完的,不过现在网络时代,好书往往得来的太容易,读者也就不知道珍惜,古人云书非借不能读,读书贵在专心,贪多务得,诚金玉良言,诫之莫忘。

FrameMaker Tips

FrameMaker 是 TeX 以外我最喜欢的排版软件了,虽然界面有点寒碜,但简单直接,不像 InDesign 那么麻烦 (况且 InDesign CS2 实在是太慢了…),中文支持也不错,除了 OpenType 的支持有点限制,实在是很方便的。这里写点我使用中记下来的小技巧。

  1. FrameMaker 7.0 以上才有比较好的中文支持,所以建议使用 7.0 或者 7.1 版本。不需要是多语言的版本。
  2. 中文字体和英文字体一般是不能混合选择的,如果你希望一段话中,汉字使用黑体,英文使用 Myriad,就得自己创建 combined font,FrameMaker 默认已经创建了两个,FMSongti 和 FMHeiti,在菜单中选择 Format->Document->Combined Fonts…,就可以 Add 自由选择 Asian Font 和 Western Font 的字体了,此后在 Paragraph Designer 的 Default Font 中选择你新建的这个字体即可。
  3. 默认的配置是,只有某些特殊的情况下才压缩汉字的标点符号,例如句号和引号的距离,但可以在 Paragraph Designer 的 Asian->Asian Punctuation 中选择 Always Squeeze 解决这个问题。
  4. 必须先创建一个颜色,然后才能使用它,你可以在 View->Color->Definitions 里选择,当然,你可以自己设置 RGB 值,不过最简单的是在 Color Libraries 中选择。此外,基于某个已有的颜色创建 Print As: Tint 类型的颜色也是很方便的,你可以调整百分比,创建采用相同基色,但更淡的颜色。

Web 与排版学上的字体问题

关于字体的讨论,其实无论是国外还是国内,都已经有不少,可是我发现绝大部分的内容或者有失偏颇,或者不够全面,下面我试图将自己一段时间内的观点总结一下,以求提出一个比较容易接受的 CSS 字体选择的建议。

事关大小

字体的大小总是一个困扰人的问题,用绝对单位还是用相对单位?或者具体来说,用什么单位?ex? em? pt? px? 百分比? 让我们看看 CSS 2.1 Spec 中的说明:

  1. 相对大小包括:em, ex, px
  2. 绝对大小包括:in, cm, mm, pt, pc
  3. em 就是相对 font-size 制定的大小而言的,例如 margin: 1.2em 就是指设置 1.2 个字符宽度的 margin,当 em 本身用于 font-size 时,指的是它所继承元素的相对大小。
  4. 百分比也是相对 font-size 而言的。

因此我认为,em 和百分比都不适合设置字体的大小,因为相互变动的因素太多了,修改一个地方就有可能影响很多其他的地方。ex 是根据拉丁字母的 x 的高度而言的,这不适合汉字的大小,所以也否决了。px 是根据当前显示设备的解析度而言的,同一个 px 对应不同的设备——比如屏幕或纸张——实际的大小会有一定差异。

所以我认为,如果网页中应该存在作为绝对参照系的长度,那么 pt 和 px 应该是首选,其他的长度根据这个绝对参照系,按照百分比或者 em 来变动。

下面谈谈网页和印刷中大小造成的差异。99% 的网页是用来在屏幕上阅读的,而问题在于,屏幕的解析度要比纸张低得多,所以如果直接把字体按照纸张上印刷的那个大小显示,肯定是看不清的,仅就英文字体而言,许多细微的点划、衬线都没法在那么低的解析度下表现出来,所以我们只能用专门设计给屏幕显示的字体。

这些字体的优劣是很难评述的,有一种看法认为,尽管纸张印刷中都倾向于有衬线 (serif) 的字体比无衬线 (sans-serif) 的要易读,但屏幕上无衬线的字体反而要好一些。所以微软把 Verdana 吹捧为了最适合网页使用的字体。我通常也偏向于使用 Verdana、Arial 多于 Times、Georgia。

对于中文字体的情况有所不同,中文字体在屏幕上的清晰显示依赖的是点阵字体,或者简单的说,就是微软随 Windows 提供的宋体和新宋体 (simsun & nsimsun),这套字体是华康公司 (Dynalab) 设计的,对 9pt 到 12pt 左右的字体都设计了对应的点阵字体。其中使用得最广泛的是 9pt, 10.5pt 和 12pt 的字体:

常用的中文字体

那么比这个大小要大的汉字呢?就要依赖操作系统的字体圆整 (anti-alias,以下简称 aa) 技术了,一般大家认为,Mac OS X 和 Linux 下的 AA 要比 Windows 的 ClearType 好很多。然而不管怎么说,用太大的汉字是比较危险的。 Continue reading ‘Web 与排版学上的字体问题’ »

什么是坏的系统设计

什么是好的系统设计?我不知道,但依我看,LaTeX 是坏的系统设计的一个典型,MFC 也如此,而坏的系统最重要的一个特点是,使用者不能把它作为一个黑匣子看待,而必须了解其内部构造才能有效使用它。

凡系统构造的时候,总希望隐藏内部的复杂性于简洁的接口背后,这样,用户只需要知道如何调用接口、这个接口实现了哪个功能就可以了,而不必了解其实现的细节。尽管 LaTeX 也是如此宣称的,可事实上并非如此,不了解实现细节,终究只能用到一些皮毛,稍微复杂一点的问题便解决不了。

举个例子,前些日子我希望实现这么一个功能,把每个章节标题的序号单独放在一列中,而正文与章节标题的文字对齐。如下:

  1  Hello world..
     A quick brown fox jumps over
     a lazy dog. 

按照默认的情况则是:

1 Hello world 

A quick brown fox jumps over
a lazy dog. 

可是,就算是实现书籍排版上这么常见的一个功能,LaTeX 也没有提供任何接口做到,不仅标准的文档类里面没有,连附加的宏包也没有实现这一功能的。所幸辗转所得一段代码能解决这个问题:

\makeatletter
\def\@seccntformat#1{\protect\makebox[0pt][r]{\csname
the#1\endcsname\quad}}
\makeatother

然而这段代码,根本是重新定义了 article 文档类中所用到标题数字格式,用到的纯属 TeX 的方法,和 LaTeX 简直毫无关系,试问若不看 article 的代码,怎能写出这段重定义的代码来,而这样一来,LaTeX 又怎么能算提供了一个黑匣子?

为什么说 LaTeX 对开发者来说也是糟糕的呢?是因为要写出这段代码来解决问题,首先你得对 LaTeX 的编程有所了解,否则 \makeatletter\makeatother 是什么意思无从得知,第二得对纯 TeX 有了解,不然 \def 是什么意思也肯定不大了然,第三,你还得对别人写好的 article 文档类分析透彻,否则 \csname 是什么?\@seccntformat 又该放在哪里,有几个参数,从何得知?

这是 LaTeX 这种以编程的形式来排版的坏处,当然,也不能全归咎于形式,从 Knuth 始,大量的 LaTeX 开发人员,以及宏包的作者,都有一种把简单问题复杂化的倾向,好像不说得那么复杂无以显得自己水平多么高。明明一个参数就能解决问题的函数,非搞得七八个参数,看似灵活性高了,实则让人学起来、用起来头痛,没事谁愿意记你这个参数是干什么的?

最重要的是,这种方式不像 WYSWYG 的形式那么容易让人举一反三:同样一个功能,Adobe FrameMaker 中也没提供具体实现它的选项,但 FrameMaker 提供了几个很直观的功能:

首先,标题可以自动编号,你可以定制标题编号的格式 第二,可以创建一个在正文左侧的 column,成为 side-head,这一列保持空白,但标题可以跨越到这一列中 第三,标题编号的格式可以包含制表符

因此我自己就发现了可以用下述方法实现上边提到的功能: 首先,创建两个制表符:

     *    *

然后,把正文放在 side-head 右边的 column 里,标题则跨越到 side-head 中,但标题编号设置为 \t<n +>\t (</n><n +> 表示阿拉伯数字的编号,\t 表示一个制表符的宽度)。 接下来,只需要保证第二个制表符的位置,和 side-head 的右边界相同便可以实现我需要的功能了。

这让我想起 Web 标准推行中表格与 CSS 之争,表格该不该用于排版,现在倒是没什么好争的了,但大家却甚少考虑,为什么表格用于排版会会这么流行?W3C 可从来么鼓励过大家这么做,但为何只需要一人介绍,便应者云集?其实正是因为表格比 CSS 直观得多,表格一画,哪边居左,多少留右,上边高度多少,底部留多长,一目了然,设计者容易构思,而不像 CSS,还要考虑什么绝对宽度、相对宽度、固定位置,甚至还要用浮动之类的方法来扭扭捏捏的实现……

好的技术首先应该是易学的,否则纵然再好,也必然为公众所抛弃。

  • 前面提到 MFC,这里权且补充两句,君不见《深入浅出 MFC》,《MFC Internals》之类的书卖得一直很好,倘若耍耍 AppWizard 便能精通 MFC,大家还用得着费那么大的劲,通过看 MFC 的代码来理解其深刻含义么?