Gnus 中的编码设定


所属类别:linux

摘要内容: (详细内容)

特别推荐:免费发布信息 承包关键词~~抢爆了!HOT!


用了一段时间 Gnus,对 Gnus 中的各种编码设定有了些了解,写出来与大家分享。广告结束闲话结束Gnus 是构建在 Emacs 之上的,自然也就利用了 Emacs 超强的多国语言编码支持。所以如果你有一封乱码的邮件,如果 Gnus 看不了的话,那么估计卖糕的也不会有办法了。为了处理各种编码的邮件,gnus 提供了很多可以设置的变量。不过变量多了也会带来麻烦,如果你设置不好的话,就有可能开枪打中自己的脚。** 先谈谈邮件编码邮件可以分为两个部分: header 和 body。比较文明的邮件会在 header 的`Content-Type' 这一行中用 MIME 说明邮件采用了什么编码。而不文明的邮件则缺少这种说明,对于只有英文的邮件,这样做不会有问题,而对于包含中文的邮件,就有可能这是导致乱码,小比尔的 Outlook Express 就喜欢发出这种邮件,一些webmail 也经常干这种事。另外,在邮件头中,还可以指定邮件的传输编码。如果邮件的内容都是7位的us-ascii字符,就不会出现什么传输编码的问题,但是因为汉字的编码一般都是8位的,而有些邮件网关只能传输7bit字符,最高位作其它用途了,所以就出现了base64, quoted-printable 等把8位字符转换成7位编码进行传输的编码方案。邮件的传输编码可以在邮件头中用 `Content-Transfer-Encoding' 指出来。我们可以让 Gnus 把 `Content-Type' 和 `Content-Transfer-Encoding' 字段显示出来:(add-hook 'gnus-startup-hook'(lambda ()(setq gnus-visible-headers(concat "^User-Agent:\\^Content-Type:\\""Content-Transfer-Encoding:\\""^X-mailer:\\^X-Newsreader:\\^X-Sender:\\"gnus-visible-headers))))这样我们就可以看到邮件采用了什么编码(顺便还可以看到对方用的是什么客户端软件),如果邮件指定了编码,你就会在邮件头部看到这一行:Content-Type: text/plain; charset=GB18030如果邮件指定了传输编码,就可以看到这样一行:Content-Transfer-Encoding: base64** Gnus 中与编码有关的变量需要说明的是,大多数情况下,邮件都是比较文明的,在 Content-Type 字段已经说明了邮件采用的编码,那么 Gnus 将自动按指定的编码显示邮件。除非 Emacs 本身就不支持这种编码,否则是不会出现乱码的。一个常见情况就是使用 Emacs21 或 Emacs22,而不安装 mule-gbk,要知道Emacs21/22 本身就不支持 GBK 和GB18030,这样对于 charset=gbk, 或charset=gb18030 的邮件出现乱码就不奇怪了。所以,如果你使用的是 Emacs21 或Emacs22, 赶紧去下载 mule-gbk 装上吧。注意,对于 Emacs22,mule-gbk 的设置中一定要加上这一句:(utf-translate-cjk-load-tables)否则 Emacs22 无法进行 gbk <--> utf-8 的转换,而 gnus 是先用 utf-8 编写邮件,再转换成指定的编码发出去,如果不加上这句设置,就会出现只能发 utf-8的邮件,不能发 gbk 邮件的怪现象。下面讨论的设置适用于 Emacs22+mule-gbk 和 Emacs23。如果邮件中已经用 Content-Type 和 Content-Transfer-Encoding 指定了编码,那么 gnus 将忠实地采用这些编码处理邮件,这时是不应该出现乱码的。所以,我们所做的设置基本上都是为了对付那些捣乱的,不指明编码的邮件。现在我们来看看 gnus 中与编码设置有关的变量。这些变量可以分为两种类型,一种是与邮件内容有关的,另一种是与组名(group name)有关的。** 与邮件内容有关的变量*** gnus-default-charset这个变量指定查看邮件所用编码的默认值(对于未指定编码的邮件)。但是这个变量的会被下一个变量(gnus-group-charset-alist)覆盖。如果不设置这个变量,它的值将由 `current-language-environment' 确定。例如:(setq gnus-default-charset 'gbk)*** gnus-group-charset-alist这个变量根据组名确定本组的默认编码。设置这个变量时我们要给出一个(regexp charset) 对,其中 regexp 时匹配组名的正则表达式,charset 是制定的编码。在这个变量的默认设置中,我们可以查到如下内容:("\\(^\\:\\)hk\\>\\\\(^\\:\\)tw\\>\\\\" cn-big5)("\\(^\\:\\)cn\\>\\\\" cn-gb-2312)可以看出,对于以 hk 或 tw 开头(或者组名中包含 :hk 或 :tw)的组,采用big5编码。而对于以 cn 开头或组名中包含 :cn 的组采用 cn-gb-2312 的编码。因为现在 gbk 比 gb2312 应用更广泛,所以我们需要更改这个变量的设置:(add-to-list 'gnus-group-charset-alist'("\\(^\\:\\)cn\\>\\\\" gbk))这个变量也可以在 group parameter 中以 (charset . gbk) 的方式指定。*** gnus-summary-show-article-charset-alist有时候,默认的编码还不能解决问题,例如,有人把 big5 编码的邮件投递到了 cn 开头的组里,而且邮件头中又没有编码设定(插一句,这些邮件一般都是垃圾邮件),这时就需要手工指定编码。(setq gnus-summary-show-article-charset-alist'((1 . utf-8)(2 . big5)(3 . gbk)(4 . utf-7)))进行了这种设定以后,我们看到乱码邮件时就可以用 `1 g' 指定采用 utf-8,`2 g' 指定big5等等,不过能不能正确解码就要看你自己猜的对不对了。** 与组名有关的变量我们订阅新闻组时,可以看到有些服务器上的组名都是英文的,比如在`news.cn99.com' 这个服务器中组名都是这样的:gnu.emacs.helpcn.comp.os.linuxtw.bbs.os.linux而有些服务器的组名却是包含中文的,比如新帆`news.newsfan.net'的组名:计算机.软件.操作系统.FreeBSD计算机.软件.操作系统.linux休闲娱乐.游戏天地.Diablo下面两个变量是为了让gnus能正确地处理非ascii组名的。*** gnus-group-name-charset-group-alist这个变量根据组名确定组名采用的编码,默认值是`((".*" utf-8))',也就是默认用 utf-8 处理所有组名。我们可以这样这样设置:(setq gnus-group-name-charset-group-alist'(("\\.com\\.cn:" . gbk)("news\\.newsfan\\.net" . gbk)))这样所有组名中含有 .com.cn 或 news.newsfan.net 的组,其名称都采用 gbk解码。不过如果我们把 news.newsfan.net 设置为 native method, 那么组名中就不会出现 news.newsfan.net,那么这个变量就发挥不了作用,怎么办呢?可以采用下面这个变量。*** gnus-group-name-charset-method-alist还记得吗?我们选择新闻服务器时是怎么设定的?对了,我们是通过设置method 来选择服务器的,比如:(setq gnus-select-method '(nntp "news.newsfan.net"))(setq gnus-secondary-select-methods '((nnml "")))这个变量可以根据我们选择的 method,为来自这个 method 的组设置组名的编码。(setq gnus-group-name-charset-method-alist'(((nntp "news.newsfan.net") . gbk)))这样,所有来自新帆服务器的组名都采用gbk来解码。** 设置发出邮件的编码: mm-coding-system-priorities当我们向外发送邮件时,也可以指定编码,比如我们希望发出的邮件采用gb2312编码,就可以这样设置:(setq mm-coding-system-priorities '(iso-8859-1 gb2312 utf-8))这样,gnus将先试这采用 iso-8859-1 编码邮件,如果不行就采用 gb2312,实在不行再采用 utf-8 编码。这样如果你写了一封纯英文的信件,将会采用 iso-8859-1 发出;如果你写了一封中文信件,但其中的汉字都在 gb2312 的范围内,则采用gb2312发出;如果你的信件中含有gb2312以外的字符,则会被以utf-8编码发出。那么如果想对不同的组采用不同的编码发信,有办法实现吗?可以,通过设置posting-style 就可以实现。(setq gnus-posting-styles'((".*"(name "Brep")(address "brep@bogus.com")(eval (setq mm-coding-system-priorities'(iso-8859-1 utf-8))))("^cn\\.comp"(name "Brep")(address "brep@smth.org")(eval (setq mm-coding-system-priorities'(iso-8859-1 gb2312 utf-8))))("^tw\\.comp"(name "Brep")(address "brep@ptt.cc")(eval (setq mm-coding-system-priorities'(iso-8859-1 big5 utf-8))))))这样对于 cn.comp 开头的组,gnus会先尝试采用gb2312发送邮件,不行再用utf-8,而对于 tw.comp 开头的组,会先尝试采用big5发送邮件,不行再用utf-8。** 处理有问题的邮件: gnus-newsgroup-ignored-charsets有些客户端发出的邮件没有指定正确的MIME类型,例如本来这封邮件是用 gbk 编码的,但是 MIME 类型却设置成了 x-gbk:Content-Type: text/plain; charset=x-gbk这时gnus解码时会遇到困难,我们可以把这种 MIME 类型加入到gnus-newsgroup-ignored-charsets 列表中,让 gnus 采用默认的编码处理它。再比如,有些邮件的 MIME 类型是 charset=gb18030, 对于 emacs23,这是没问题的,因为 Emacs23 支持 gb18030 编码。但是 emacs22+mule-gbk 根本就不支持gb18030,那么该怎么办呢?同样我们可以把 gb18030 加入gnus-newsgroup-ignored-charsets 列表中:(setq gnus-newsgroup-ignored-charsets'(unknown-8bit x-unknown x-gbk gb18030))ignored-charsets 也可以在 group parameters 中这样指定:(ignored-charsets x-unknown iso-8859-1)** 指定传输编码:gnus-group-posting-charset-alist这个变量可以用来设置邮件头中的 Content-Transfer-Encoding 字段,为邮件指定传输编码。这个变量的默认值已经设置的很好了,我从来没有遇到需要设置这个变量的情况。** 不要让自己发出乱码的邮件(指定附件文件名和subject的编码方式)gnus 默认采用 RFC2231 对附件文件名进行编码,有些 MUA 无法识别这种编码。现在比较流行的方式是采用 RFC2047 对附件文件名进行编码。可以采用如下设定,让gnus 也采用这种方式对文件名进行编码:(defalias 'mail-header-encode-parameter 'rfc2047-encode-parameter)有很多差劲的邮件客户端无法解码 quoted-printable 编码(看到过 subject 中有很多 `=' 号的乱码邮件吗?就是由于这个原因产生的。)为了保证我们发出的邮件subject 采用 base64 编码,而不是采用quoted-printable 编码,最好加上这两句:(add-to-list 'rfc2047-charset-encoding-alist '(gbk . B))(add-to-list 'rfc2047-charset-encoding-alist '(gb18030 . B))** 参考设置最后给出一个参考设置吧,适用于 Emacs22+mule-gbk 或者 Emacs23:(setq gnus-default-charset 'gbk)(add-to-list 'gnus-group-charset-alist'("\\(^\\:\\)cn\\>\\\\" gbk))(setq gnus-summary-show-article-charset-alist'((1 . utf-8)(2 . big5)(3 . gbk)(4 . utf-7)))(setq gnus-group-name-charset-group-alist'(("\\.com\\.cn:" . gbk)("news\\.newsfan\\.net" . gbk)))(setq gnus-group-name-charset-method-alist'(((nntp "news.newsfan.net") . gbk)))(setq gnus-newsgroup-ignored-charsets'(unknown-8bit x-unknown x-gbk gb18030))(defalias 'mail-header-encode-parameter 'rfc2047-encode-parameter)(add-to-list 'rfc2047-charset-encoding-alist '(gbk . B))(add-to-list 'rfc2047-charset-encoding-alist '(gb18030 . B))(setq gnus-posting-styles'((".*"(name "Brep")(address "brep@bogus.com")(eval (setq mm-coding-system-priorities'(iso-8859-1 utf-8))))("^cn\\.comp"(name "Brep")(address "brep@smth.org")(eval (setq mm-coding-system-priorities'(iso-8859-1 gb2312 utf-8))))("^tw\\.comp"(name "Brep")(address "brep@ptt.cc")(eval (setq mm-coding-system-priorities'(iso-8859-1 big5 utf-8))))))(add-hook 'gnus-startup-hook'(lambda ()(setq gnus-visible-headers(concat "^User-Agent:\\^Content-Type:\\""Content-Transfer-Encoding:\\""^X-mailer:\\^X-Newsreader:\\^X-Sender:\\"gnus-visible-headers))))** 不要让自己发出乱码的邮件(指定附件文件名和subject的编码方式)gnus 默认采用 RFC2231 对附件文件名进行编码,有些 MUA 无法识别这种编码。现在比较流行的方式是采用 RFC2047 对附件文件名进行编码。可以采用如下设定,让gnus 也采用这种方式对文件名进行编码:(defalias 'mail-header-encode-parameter 'rfc2047-encode-parameter)有很多差劲的邮件客户端无法解码 quoted-printable 编码(看到过 subject 中有很多 `=' 号的乱码邮件吗?就是由于这个原因产生的。)为了保证我们发出的邮件subject 采用 base64 编码,而不是采用quoted-printable 编码,最好加上这两句:(add-to-list 'rfc2047-charset-encoding-alist '(gbk . B))(add-to-list 'rfc2047-charset-encoding-alist '(gb18030 . B))因为这篇文章主要是讨论Gnus的编码问题,所以这里列出的仅仅是与编码有关的设置。# Local Variables:# mode: org# coding: utf-8# End:

相关信息

· linux 时时浏览查看工具---iftop

· WIN32 汇编写的加密解密软件

· 通过动态编译获取字符串表达的值

·  IT新人如何走好自己的路








....

115139 68463