2011年6月30日木曜日

emacs 23 (その7)

EUC-JP系の文字コードには、EUC-JP と EUC-JIS-2004/EUC-JISX0213 があり、これらは本質的に異った文字集合ですので互換性がありません。 ASCII および JIS 第一水準、第二水準の範囲ではほぼ同じになっていますが、補助漢字の部分、と第三、第四水準の部分には互換性がありません。

個人的に EUC-JP で書かれたファイルと、EUC-JIS-2004 で書かれたファイルの両方ともに、それなりの数を保有しているため、その区別が問題になっています。酷いものになる一つのファイルの中に EUC-JP と EUC-JIS-2004 の文字が混在してしまっています。(そももかな漢字変換用の辞書の .skk-jisyo からして混在になちゃってたりして。) JIS X 0213 が補助漢字(JIS X 0212)を包含してくてれいれば良かったんですけどね。

補助漢字にしか存在しない文字もあるため、規格的に言えば正しくないのでしょうが、EUC-JP と EUC-JIS-2004 を同時に扱う互換エンコーディングを定義することにしました。



;;
;; Japanese EUC-JP Compatible Table
;;
;; treat undefined JIS X 0208 character as JIS X 0213-1 character.
;; treat undefined JIS X 0213-2 character as JIS X 0212 character.
;; treat JIS C 6226 character as corresponding JIS X 0208/0213/0212 character.
;;
(let ((c1 #x21)
      (table (make-translation-table))
      (table2 (make-translation-table)))
  (while (<= c1 #x7e)
    (let ((c2 #x21))
      (while (<= c2 #x7e)
        (let* ((uchar (lambda (c) (and c (<= c #x10ffff))))
               (comb (get 'jisx0213-to-unicode 'translation-table))
               (cc (logior (lsh c1 8) c2))
               (j0208-78 (decode-char 'japanese-jisx0208-1978 cc))
               (j0208 (decode-char 'japanese-jisx0208 cc))
               (j0212 (decode-char 'japanese-jisx0212 cc))
               (j0213-1 (decode-char 'japanese-jisx0213.2004-1 cc))
               (j0213-2 (decode-char 'japanese-jisx0213-2 cc))
               (rev_j0208-78
                (and (funcall uchar j0208-78)
                     (or (encode-char j0208-78 'japanese-jisx0208)
                         (encode-char j0208-78 'japanese-jisx0213-1)
                         (encode-char j0208-78 'japanese-jisx0213.2004-1)
                         (encode-char j0208-78 'japanese-jisx0213-2)
                         (encode-char j0208-78 'japanese-jisx0212))))
               (rev_j0212
                (and (funcall uchar j0212)
                     (or (encode-char j0212 'japanese-jisx0213-1)
                         (encode-char j0212 'japanese-jisx0213.2004-1)
                         (encode-char j0212 'japanese-jisx0213-2)))))
          (when (and (not (funcall uchar j0208))
                     (or (funcall uchar j0213-1) (aref comb j0213-1)))
            (aset table j0208 j0213-1)
            (aset table2 j0213-1 j0208))
          (when (not rev_j0208-78)
            (aset table2 j0208-78 j0208))
          (when (and (not (funcall uchar j0213-2)) (funcall uchar j0212))
            (aset table j0213-2 j0212)
            (when (not rev_j0212)
              (aset table2 j0212 j0213-2))))
        (setq c2 (1+ c2))))
    (setq c1 (1+ c1)))
  (set-char-table-parent table2 (get 'ja-compatible-encode-map
                                     'translation-table))
  (define-translation-table 'ja-compatible-decode-eucjp-map table)
  (define-translation-table 'ja-compatible-encode-eucjp-map table2))

;;
;; coding system
;; euc-ja-compatible
;;
(define-coding-system 'euc-jp-compatible
  "ISO 2022 based EUC encoding for japanses for JIS X 0213 (and JIS X 0212)."
  :coding-type 'iso-2022
  :mnemonic ?E
  :designation [ascii japanese-jisx0208 katakana-jisx0201 japanese-jisx0213-2]
  :flags '(short ascii-at-eol ascii-at-cntl single-shift)
  :charset-list '(ascii
                  japanese-jisx0208
                  japanese-jisx0213-1
                  japanese-jisx0213.2004-1
                  japanese-jisx0213-2
                  japanese-jisx0212
                  latin-jisx0201
                  katakana-jisx0201
                  japanese-jisx0208-1978)
  :mime-charset 'euc-jis-2004
  :decode-translation-table (get 'ja-compatible-decode-eucjp-map
                                 'translation-table)
  :encode-translation-table (get 'ja-compatible-encode-eucjp-map
                                 'translation-table)
)

;(define-coding-system-alias 'japanese-iso-8bit       'euc-jp-compatible)
;(define-coding-system-alias 'euc-jis-2004            'euc-jp-compatible)
;(define-coding-system-alias 'euc-jisx0213            'euc-jp-compatible)
;(define-coding-system-alias 'euc-japan-1990          'euc-jp-compatible)
;(define-coding-system-alias 'euc-japan               'euc-jp-compatible)
;(define-coding-system-alias 'euc-jp                  'euc-jp-compatible)

この euc-jp-compatible という coding-system を使うことにより、EUC-JP と EUC-JIS-2004 の混在環境が利用ができるようになります。補助漢字と第三、第四水準の両方の文字が使える unicode 環境などで EUC-JP系と文字コードを扱う場合などに便利ではないかと思います。

この coding-system では、あえてファイルの文字集合の保存は行っていません。補助漢字(JIS X 0212)と、第三/第四水準(JIS X0213)の両方い重複している文字がある場合には 積極的に JIS X 0213 の文字コードの方で出力します。補助漢字にしか含まれていない文字のみ補助漢字で出力します。このため EUC-JP のファイルを読み込んでセーブしただけで内容が変更されてしまう場合があります。(Emacs-23 は内部 unicode なので、そもそも区別するのが面倒という理由もありますが...)

0 件のコメント:

コメントを投稿