Convert from EUC-JP to UTF-8 problem? (ambiguous width characters)

Last modified: Mon, May 07 22:31:39 JST 2007
Shinichiro HIDA <shinichiro@stained-g.net>

2007年4月の事、Debian GNU/Linux Etch 上、LANG=ja_JP.UTF-8 とい う環境で、rxvt-unicode-ml + w3m 、および、Emacs 22.0.96.1 + Emacs-w3m (CVS) という組合せを利用した場合、一部の文字が化ける (正確にはこれだけでは化けないのだが)現象が見られた。

まだ調べ切れていないので、正確なところは理解できていないのだが、 http://lists.debian.or.jp/debian-devel/200703/msg00038.html あたりで指摘されている事と関係あったりするのだろうか?

このページは、上記の問題について emacs-w3m, および mule-ja のメー リングリストで皆様に 色々と教えて頂く過程で 書いたものである。

本当は自分でコード読んで解決しないといけないところなのだが、お 恥ずかしい限りで、私はいつまで立ってもレベルが低く滅多にそこま でたどり着けないのだ...

化ける文字の例

U+2026 Horizontal Ellipsis - Three Dot Leader
  1. by UTF-8 Entity (&#2026;)

  2. by RAW input (…)

  3. by HTML 4 Entity (by number &#8230;)

  4. by HTML 4.0 Entity (not standard - &#133;)

  5. by XHTML 1.1 Entity (by word &hellip;)

  6. by XHTML 1.1 Entity (by number &#x02026;)

Emacs-w3m でこのページを表示し、問題の文字にカーソルを当て、 M-x describe-char すると次のような結果が得られる。

  character: … (342438, #o1234646, #x539a6, U+2026)
    charset: mule-unicode-0100-24ff (Unicode characters of the range U+0100..U+24FF.)
 code point: #x73 #x26
     syntax: _  which means: symbol
buffer code: #x9C #xF4 #xF3 #xA6
  file code: not encodable by coding system euc-jp-unix
    display: by this font (glyph code)
     -Efont-Biwidth-Medium-R-Normal--14-140-75-75-P-70-ISO10646-1 (#x2026)

There are text properties here:
  rear-nonsticky       t
  w3m-name-anchor      ("description" "summary" "author")
	

しかし、本来なら、次のような結果となるべきだと思われる。

  character: … (53444, #o150304, #xd0c4, U+2026)
    charset: japanese-jisx0208 (JISX0208.1983/1990 Japanese Kanji: ISO-IR-87.)
 code point: #x21 #x44
     syntax: _  which means: symbol
   category: >:A character which can't be placed at beginning of line. j:Japanese
             |:While filling, we can break a line at this character.
buffer code: #x92 #xA1 #xC4
  file code: #xA1 #xC4 (encoded by coding system japanese-iso-8bit-unix)
    display: by this font (glyph code)
     -Shinonome-Mincho-Medium-R-Normal--14-130-75-75-C-140-JISX0208.1990-0 (#x2144)

There are text properties here:
  fontified            t
	

ちなみに、これは、ローカルで EUC-JP なバッファでこの HTML ファ イルを編集しながら M-x describe-char を行ない得た結果である。


解決方法

この問題は、Unicode において、文字幅が Ambiguous (不定)と指定 された文字を Halfwidth として判定し表示したため、JISX0208 範 囲にない文字となり ISO10646 な文字が利用されたことにより起こ る、という事のようだ。

この問題自体はすでに 2004-10 頃には mule-ja メーリングリスト で取り上げられており、新しいものではまったくなかった。(私が知 らなかっただけ、とも言う)

そもそも、今回私がいまさら気づいた問題の根っ子には、通常、い わゆる半角幅 (Halfwidth) を用いる欧米言語圏では、諸記号類につ いても同等の幅で表示するほうが自然である一方、いわゆる全角幅 (Fullwidth) を常用する CJK (Chinese Japanese Korean) 環境では Fullwidth が良い、というような事情から、Ambiguous とされた事 から、同じ文字が Halfwidth, Fullwidth 双方に存在し、そのどち らを利用するかは、利用環境に依存するという事情がある模様。

Emacs(22 以降) の場合、そのままで UTF 環境を利用可能(もちろん Mule-UCS を利用する事も可能)で、この問題を避けるために、 JISX0208 の範囲に存在し、かつ ISO10646 側で表示されるような文 字がある場合、任意に範囲を指定して JISX0208 側を呼び出す事が できるという事だ。

今回、emacs-w3m, mule-ja のメーリングリストで教えて頂いた範囲 では、 Carbon Emacs Package と、 Debian の language-env , Mule-UCS パッケージあたりには、すでに対策が入っており、これら を利用している場合には、とくに何もする事なく、問題は起きない と思われる。

ちなみに、 Carbon Emacs Package Debian の language-env では若干異なる部分があるのだが、Mac の場合は、コード変換が独 特なもののようで、このあたりも影響しているらしい。

他のものについては調べられていないため分からない。

ディストリビューションによる対策が提供されていないような場合 (自分で CVS からビルドしているとか)、具体的には、次のように設 定する。(これは Debian の language-env パッケージの 2007-04 時点での物)

(utf-translate-cjk-set-unicode-range
 '((#x00a2 . #x00a3) (#x00a7 . #x00a8) (#x00ac . #x00ac)
   (#x00b0 . #x00b1) (#x00b4 . #x00b4) (#x00b6 . #x00b6)
   (#x00d7 . #x00d7) (#x00f7 . #x00f7) (#x0370 . #x03ff)
   (#x0400 . #x04ff) (#x2000 . #x206f) (#x2100 . #x214f)
   (#x2103 . #x2103) (#x212b . #x212b) (#x2190 . #x21ff)
   (#x2200 . #x22ff) (#x2300 . #x23ff) (#x2500 . #x257f)
   (#x25a0 . #x25ff) (#x2600 . #x26ff) (#x2e80 . #xd7a3)
   (#xff00 . #xffef)))
	

さらなる問題(?)が..

ここしばらく ja_JP.UTF-8 locale 上の Emacs22 で、上記のように utf-translate-cjk-set-unicode-range を設定して利用していたの だが、wl-en メーリングリストに流れた UTF-8 なメール(中身はほ ぼ ASCII)で、シングルクォート U+0027 ['] が FullWidth な U+2019 [’] 状態で表示される事に気づいた。

with utf-translate-cjk-set-unicode-range
(図 1): Emacs22 + wl で、上記 utf-translate-cjk-set-unicode-range を 有効 にして、UTF-8 のメールを表示した場合。
without utf-translate-cjk-set-unicode-range
(図 2): Emacs22 + wl で、上記 utf-translate-cjk-set-unicode-range を 無効 にして、UTF-8 のメールを表示した場合。

これ、実は、文書を作成する段階で、シングルクォートとアポスト ロフィが区別して入力されており、アポストロフィ['] が FullWidth の Right Quotation Mark [’] として表示された 結果だと思われる。

普段、何気なく 「英語配列のキーボードの"L"キーの2個 右」を入力して、これを一口に "シングルクォート" と いっているのだが、実は似たような字形の物があるので難しい。

  1. Apostrophe
    U+0027, [']
  2. Modifier Letter Apostrophe
    U+02BC, [ʼ]
  3. Right Single Quotation Mark
    U+2019, [’]
  4. Heavy Single Comma Quotation Mark Ornament
    U+275C, [❜]
  5. Full Width Apostrophe
    U+FF07, [']

ちなみに、 unicode.org の code chart の Apostrophe の項目には、次のような記述がある。

0027 ' APOSTROPHE
       =apostrophe-quote(1.0)
       =APL quote
       ・neutral (vertical) glyph with mixed usage
       ・2019 ’ is preferred for apostrophe
       ・preferred characters in English for paired
         quotation marks are 2018 ‘ & 2019 ’
        →02B9 ʹ modifier letter prime
        →02BC ʼ modifier letter apostrophe
        →02C8 ˈ modifier letter vertical line
        →0301 ́  combining acute accent
        →2032 ′ prime
	

普段、何気なく利用している "シングルクォート" とい う言葉なのだが、どうやら私のイメージと Unicode の code chart を突き合わせると、それは Unicode においては Apostrophe (アポ ストロフィ) が該当するようだ。

今回の場合、"can't " などの省略された文字を表すもの としては、字面から読みとるに、Modifier Letter Apostrophe U+02BC [ʼ] あるいは Modifier Letter Prime(?) を当てるの が妥当なようにも思えるのだが、 2019 ’ is preferred for apostrophe という事なので、良く分からない... なんでこれが FullWidth にな るんだ?

本当にこれで正しいのか、根本的にはどうすべきなのか、という点 については勉強不足のためまったく理解できていないのが悲しい所 なのだが、とりあえずは、上記 utf-translate-cjk-set-unicode-range の設定から、2018 と 2019 あたりを除外してやると utf-translate-cjk-set-unicode-range を 有効にしつつ、設定していないのと同様に (自然な感じに) 表示す る事が可能。

具体的には、(#x2000 . #x206f) の範囲が一括指定されているので、 ここから 2018 と 2019 を除外するとすると、(#x2000 . #x2017) (#x201A . #x206f) となる。

xterm (uxterm) -cjk_width と emacs -nw の組合せでの問題

上記のように utf-translate-cjk-set-unicode-range から 2018 と 2019 を除外した場合、xterm に -cjk_width オプションをつけて起動し、その中で emacs -nw した場合に、カー ソルの動きがおかしくなるという問題がある。

具体的には問題の [’] の 1文字の上でカーソルが 2カウン トしてしまう、というものだ。

一方で、xterm (uxterm) に -cjk_width オプションを つけない 場合には、今度は逆に 2018 と 2019 を除外しておかないと、 "’" の次の文字 (ここでは "]") に カーソルを移動する事が出来なくなる、という不具合が起こる。

もっとも、今回の問題は cjk 環境の問題であるので、-cjk_width オプションが ついている場合 について考えるべき (-cjk_width なしの場合はあまり考慮せずとも 構わない(?)) だろうと思うのだが、emacs -nw 上の emacs-w3m ば かりでなく、素の w3m で確認した場合にも[’] の上で 2カ ウントしていまうという問題があるので、おそらく根本的には xterm 側での対処が必要(?) なのではないだろうか。


Valid CSS Valid XHTML 1.1