今までのブログの記事は、過去に作成したパッチとかを引っぱり出してきて、まとめ直しているものが主なのですが、今回は最近に気付いた話です。
文字コード ISO-2022-JP で書かれた昔のメールを emacs23 を使って加工していて UTF-8 でセーブしようとした時に、うまく変換できない文字があってセーブできないことに気付いたのが事の発端です。少し調べてみるとJIS C 6226-1978 (いわゆる旧JIS)の文字の中に Unicode に変換できない文字があるらしいことがわかりました。
何でこんなことになってるんだということで、さらに調べたとこと emacs23 では JIS と Unicode の変換表で旧JIS(JIS C 6226-1978)と新JIS(JIS X 0208-1983/1990)では異なるマッピングを使っていることが判明しました。旧JISと新JISでは、かなり文字の字形が変更されているため厳密に扱おうとすれば異なるマッピングが必要となるのはその通りなのですが、互換性の問題から大抵のアプリケーションやライブラリでは旧JISと新JISは同じ文字として扱い、特殊な対応を入れているもので第一水準と第二水準を入れ換えられた二十数文字への対応を行うくらいだったのですが。
Emacs-23 は真面目に字形対応してしまったらしい。何てことをしてくれたんだ...
いや、誉めるべきか、貶すべきか悩ましい。漢字の字形の Unicode的な扱いとしては正しいと思うのだけど、また独自の JIS ⇔ Unicode 変換表が増えたことになるわけで。
で、話を元に戻して旧JISからUnicodeに変換できない文字だが、source を調べたところ旧JISからUnicodeへの対応表は昔に京大の安岡先生が作成された表を元にしているみたいなのだが、Unicodeの基本統合漢字だけが対象になっていて、拡張漢字A,Bなどが対象になっていないせいか変換先が未定義なままになっている文字があることが原因みたい。
とりあえず、旧JISでは異なる変換表を使うという主旨を尊重して抜けている部分を補完するとしたら以下のような感じだろうか。あと JIS 1区32点のバックスラッシュ(全角扱い)が ASCII の 0x5C (半角扱い)に変換されるのは文字幅的に嬉しくないのでついでに変更をしておこう。
diff -urN emacs-23.3.orig/etc/charsets/JISC6226.map emacs-23.3/etc/charsets/JISC6226.map
--- emacs-23.3.orig/etc/charsets/JISC6226.map 2010-10-13 07:43:12.000000000 +0900
+++ emacs-23.3/etc/charsets/JISC6226.map 2011-06-14 10:09:40.212292788 +0900
@@ -31,7 +31,7 @@
0x213D 0x2014
0x213E 0x2010
0x213F 0xFF0F
-0x2140 0x005C
+0x2140 0xFF3C
0x2141 0x301C
0x2142 0x2016
0x2143 0xFF5C
@@ -862,6 +862,7 @@
0x343F 0x6B53
0x3440 0x6C57
0x3441 0x6F22
+0x3442 0x3D4E
0x3443 0x704C
0x3444 0x74B0
0x3445 0x7518
@@ -1155,6 +1156,7 @@
0x374B 0x6842
0x374C 0x6E13
0x374D 0x7566
+0x374E 0x25874
0x374F 0x7CFB
0x3750 0x7D4C
0x3751 0x7D99
@@ -1176,6 +1178,7 @@
0x3761 0x621F
0x3762 0x6483
0x3763 0x6FC0
+0x3764 0x28EF6
0x3765 0x6841
0x3766 0x5091
0x3767 0x6B20
@@ -3537,6 +3540,7 @@
0x513A 0x5140
0x513B 0x5152
0x513C 0x514C
+0x513D 0x5154
0x513E 0x5162
0x513F 0x7AF8
0x5140 0x5169
@@ -6458,6 +6462,7 @@
0x7042 0x970F
0x7043 0x9716
0x7044 0x9719
+0x7045 0x9724
0x7046 0x972A
0x7047 0x9730
0x7048 0x9739