Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26461
  • 博文数量: 15
  • 博客积分: 721
  • 博客等级: 上士
  • 技术积分: 125
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-07 18:06
文章分类
文章存档

2011年(3)

2010年(12)

我的朋友

分类: WINDOWS

2010-11-25 12:08:07

Emacs 的编码系统这个话题太大了,得写一篇很长的文章才能说清楚。而且
对于用户来说,可能并不感兴趣,也不关心这个。

Emacs22 的编码原理是让多个国家的编码系统共存。buffer里的每一个字符
都用 1-4 个字节表示,比如 gb2312 的汉字就是用3个字节表示,这三个
字节中的第一个字节叫 leading byte, 说明了这个字符所属的字符集,后
面两个字节是这个字符的gb2312编码。chinese-gb2312 的 leading byte
是 0x91, big5 因为比较大,所以分成了两个 charset: chinese-big5-1
和 chinese-big5-2, leading byte 分别是 0x98 和 0x99。

所以对于 Emacs22 来说,只要查看一个字符的 leading byte,就可以知道
它属于哪个字符集,一看是 0x91 就知道它是 gb2312 字符,一看是 0x98
就知道它是 big5 字符。所以一个汉字可能会有好几种内部编码,比如“好”
字,gb2312, big5, 朝鲜文, 日文中都有这个字,那么它就有四种内部编码。

当 Emacs22 打开一个文件的时候,就需要判断出这个文件的编码系统,然
后给文件中的每个字符加上 leading byte,放到内存中,Emacs22把这个过
程叫做 decode。当emacs22保存文件时就需要根据每个字符的 leading
byte 把它转换成相应字符集的编码,再写到文件中,emacs22把这个过程叫
做 encode。

为了演示 Emacs decode/encode 的过程,我们可以做个小实验:

- 新建一个文件 ~/test.txt
- 输入“中文”两个字
- C-x f gb2312
- C-x C-s 保存文件
- 在 *scrach* buffer 里输入
(insert-file-contents-literally "~/test.txt")
C-j 一下可以看到 \326\320\316\304 ,这是八进制的“中文”两个字的编码。
- 现在打开 ~/test.txt,然后执行
M-x toggle-enable-multibyte-characters
我们可以看到 \221\326\320\221\316\304,Emacs在每个汉字的编码前都加
上了一个 \221,正是十六进制的 0x91——gb2312的 leading byte。

然而,leading byte 的数量是有限的,而世界上的字符集却越来越多,因
此当 gbk 和 gb18030 出现以后,就没有合适的 leading byte 分配给它们,
所以 Emacs22 不支持 gbk 和 gb18030。

苏勇和詹剑写的 mule-gbk,实际上是把全部的gbk字符分成了三部分,分别
占用了 chinese-cns-5, chinese-cns-6, chinese-cns-7 的 3 个
leading byte。mule-gbk 的主要代码就是把 gbk 中的字符加上这三个
leading byte 之一,放入内存,也就是 decode;或者反过来把内存中带有
这三个 leading byte 之一的字符转换成 gbk 编码,也就是 encode。
Emacs为了方便进行各种编码的转换,专门内嵌了一种称为 ccl 的语言,编
码转换部分的代码就是用 ccl 写成的。

Emacs23的编码原理是把所有的字符集都转换成 utf-8,内部字符都是
utf-8 编码。这样对于每个字符集都需要两张表,一个是 charset -->
utf-8,另一个是 utf-8 --> charset。Emacs23源码的 etc/charsets/ 目录
下有很多 *.map 文件,就是这种转换表。

当Emacs23打开一个文件时,先判断文件的编码,然后加载相应的表格,再
按照表格把文件中的字符一个一个转换成 utf-8 放入内存;保存文件时,
也是按照表格把内部的 utf-8 编码转换成相应的字符集编码。

unicode 的全部编码可以分成很多 block,在 可以查到。
由于中国参与 unicode 的制定比较晚,因此造成了gb2312/gbk/gb18030中
的字符被分配到了很多不同的 block 中,汉字还相对比较连续,标点符号
就特别分散,这个block中有几个,那个block中有几个。

Emacs 23 在进行 fill 时不整齐的原因,主要是那些标点符号的宽度属性
设置错误,本来应该是2,却设成了1,因此 fill 时计算行宽不准确,标点
符号越多,误差越大。我的那个patch主要是更改了这些标点符号的宽度属
性。
阅读(851) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~