English page もどる

文字幅問題 (2002-03-31)


はじめに

コンピュータは、ヨーロッパやアメリカと同様、 中日韓においても昔から使われてきました。 中日韓の人々がコンピュータで漢字を使い始めた当初から、 漢字はターミナルベースの (GUI ではない) ソフトウェアやハードウェアにおいて 2 カラムを占有してきました。 従って、1 カラムの (日本語で「半角」) 文字と 2 カラムの (日本語で「全角」) 文字があります。(少なくとも日本では) 文字幅を決めた公的な規格は存在しませんが、半角・全角の概念は 中日韓の世界において非常に強いデファクトスタンダードとなっています。

中日韓のエンコーディング群においては、 ある文字が半角か全角かを判別するのは非常に簡単です。 ISO 646 (ASCII、JIS X 0201 ローマ字、などなど) と JIS X 0201 カナに属する文字 (つまり、1 バイト文字) は半角、それ以外は全角です。 中日韓の人々は何十年もこのデファクトスタンダードに従って 生活しているので、私の意見では、このデファクトスタンダードは 重大な欠陥を抱えていないことが実績によって証明されています。 したがって、Unicode とその変換表は、 私が以下で述べる問題に対処する責任があると思います。

Unicode Consortium は、 この中日韓のデファクトスタンダードに対応すべく、 Unicode Standard Annex #11 EAST ASIAN WIDTH (UAX#11、以前には UTR#11) を提供しています。この文書は、Unicode 文字をいくつかのカテゴリに 分類しています。「N」「A」「H」「W」「F」「Na」です。

訳注: 「Na」は narrow、「H」は half width で、半角です。 「W」は wide、「F」は full width で、全角です。 「N」は not asian で、中日韓の文字集合に現れない文字です。 「A」は ambiguous で、文脈依存の意味です。

中日韓のデファクトスタンダードを保持するためには、 ISO 646 (ASCII、JIS X 0201 ローマ字、などなど) と JIS X 0201 カナに属する文字は「Na」または「H」、中日韓エンコーディングに 現れるその他の文字は「W」「F」「A」のいずれかとなるべきです。 さらに、「N」の出現は UAX#11 のバグとみなすべきです。

訳注: なぜ「A」が許されるかというと、「A」はロシア文字やギリシャ文字のように、 JIS X 0208 に含まれるけれども本来は半角であるべき文字に適用されて いるからです。

私はスクリプトを用いて EastAsianWidth.txt を チェックしましたが、 それ以降、EastAsianWidth.txt は変更されているので、 新しいファイルを使ってチェックしなおしました。


調査に用いたファイルやソフトウェア

調査の対象としたファイルは、 ftp://ftp.unicode.org/Public/UNIDATA/EastAsianWidth.txt の、Unicode 3.2 用のものです。先頭行には

# EastAsianWidth-3.2.0.txt
と書かれています。

調査には、Unicode から CJK 各エンコーディングへの変換表が必要になります。 それは、ftp://ftp.unicode.org/Public/MAPPINGS 以下から入手しました。 使用したのは、

チェックに用いたスクリプトは以下の通りです。 中日韓のエンコーディング群における 1 バイト文字が Unicode において Na または H となっているか、 2 バイト文字が A または W または F となっているか、 ということを調べ、そうでない場合に報告します。 1 バイト文字が A になる、というのをなぜ報告させるか、 というと、A は、CJK コンテキストのときに全角、 そうでないときに半角、となるのが普通であり、 それに反するときには例外処理を必要とするためです。

#!/usr/bin/perl

open(FILE, "EastAsianWidth.txt") || die "Cannot open width file.";
while($a = <FILE>) {
	$a =~ /^([0-9A-F]+);([A-Za-z]+)/;
	$num = $1; $w = $2;
	if ($num eq "") {next;}
	$width{$num} = $w;
}
close(FILE);

sub checkfile($$$$) {
	my($file, $localcolumn, $ucscolumn, $commentcolumn)=@_;
	open(FILE, $file) || die "Cannot open $file";
	print "FILE $file------\n";
	while($a = <FILE>) {
	    if ($a =~ /^\#/) {next;}
	    chomp($a);
	    @list = split(/\t/, $a);
	    $loc = $list[$localcolumn];
	    $ucs = $list[$ucscolumn];
	    if ($ucs < 0x20 || ($ucs >= 0x7f && $ucs <= 0x9f)) {next;}
	    $ucs =~ s/0x//;
	    $width = $width{$ucs};
	    $com = $list[$commentcolumn];
	    if ($loc < 0x100 && 
		($width eq "W" || $width eq "F" || $width eq "A" || $width eq "N")) {
		print "$loc  U+$ucs  $width  $com\n";
	    } elsif ($loc > 0x100 && 
		($width eq "N" || $width eq "H" || $width eq "Na")) {
		print "$loc  U+$ucs  $width  $com\n";
	    }
	    
	}
}

&checkfile("JIS0208.TXT", 1, 2, 3);
&checkfile("JIS0212.TXT", 0, 1, 2);
&checkfile("SHIFTJIS.TXT", 0, 1, 2);
&checkfile("CP932.TXT", 0, 1, 2);
&checkfile("JAPANESE.TXT", 0, 1, 2);
&checkfile("GB2312.TXT", 0, 1, 2);
&checkfile("CHINSIMP.TXT", 0, 1, 2);
&checkfile("BIG5.TXT", 0, 1, 2);
&checkfile("CHINTRAD.TXT", 0, 1, 2);
&checkfile("KSX1001.TXT", 0, 1, 2);
&checkfile("KOREAN.TXT", 0, 1, 2);

調査結果

以下のような結果となりました。

FILE JIS0208.TXT------
0x2140  U+005C  Na  # REVERSE SOLIDUS
0x215D  U+2212  N  # MINUS SIGN
0x2171  U+00A2  Na  # CENT SIGN
0x2172  U+00A3  Na  # POUND SIGN
0x224C  U+00AC  Na  # NOT SIGN
FILE JIS0212.TXT------
0x2234  U+00AF  Na  # MACRON
0x2237  U+007E  Na  # TILDE
0x2238  U+0384  N  # GREEK TONOS
0x2239  U+0385  N  # GREEK DIALYTIKA TONOS
0x2243  U+00A6  Na  # BROKEN BAR
0x226D  U+00A9  N  # COPYRIGHT SIGN
0x2661  U+0386  N  # GREEK CAPITAL LETTER ALPHA WITH TONOS
0x2662  U+0388  N  # GREEK CAPITAL LETTER EPSILON WITH TONOS
0x2663  U+0389  N  # GREEK CAPITAL LETTER ETA WITH TONOS
0x2664  U+038A  N  # GREEK CAPITAL LETTER IOTA WITH TONOS
0x2665  U+03AA  N  # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0x2667  U+038C  N  # GREEK CAPITAL LETTER OMICRON WITH TONOS
0x2669  U+038E  N  # GREEK CAPITAL LETTER UPSILON WITH TONOS
0x266A  U+03AB  N  # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0x266C  U+038F  N  # GREEK CAPITAL LETTER OMEGA WITH TONOS
0x2671  U+03AC  N  # GREEK SMALL LETTER ALPHA WITH TONOS
0x2672  U+03AD  N  # GREEK SMALL LETTER EPSILON WITH TONOS
0x2673  U+03AE  N  # GREEK SMALL LETTER ETA WITH TONOS
0x2674  U+03AF  N  # GREEK SMALL LETTER IOTA WITH TONOS
0x2675  U+03CA  N  # GREEK SMALL LETTER IOTA WITH DIALYTIKA
0x2676  U+0390  N  # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0x2677  U+03CC  N  # GREEK SMALL LETTER OMICRON WITH TONOS
0x2678  U+03C2  N  # GREEK SMALL LETTER FINAL SIGMA
0x2679  U+03CD  N  # GREEK SMALL LETTER UPSILON WITH TONOS
0x267A  U+03CB  N  # GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0x267B  U+03B0  N  # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0x267C  U+03CE  N  # GREEK SMALL LETTER OMEGA WITH TONOS
0x2742  U+0402  N  # CYRILLIC CAPITAL LETTER DJE
0x2743  U+0403  N  # CYRILLIC CAPITAL LETTER GJE
0x2744  U+0404  N  # CYRILLIC CAPITAL LETTER UKRAINIAN IE
0x2745  U+0405  N  # CYRILLIC CAPITAL LETTER DZE
0x2746  U+0406  N  # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0x2747  U+0407  N  # CYRILLIC CAPITAL LETTER YI
0x2748  U+0408  N  # CYRILLIC CAPITAL LETTER JE
0x2749  U+0409  N  # CYRILLIC CAPITAL LETTER LJE
0x274A  U+040A  N  # CYRILLIC CAPITAL LETTER NJE
0x274B  U+040B  N  # CYRILLIC CAPITAL LETTER TSHE
0x274C  U+040C  N  # CYRILLIC CAPITAL LETTER KJE
0x274D  U+040E  N  # CYRILLIC CAPITAL LETTER SHORT U
0x274E  U+040F  N  # CYRILLIC CAPITAL LETTER DZHE
0x2772  U+0452  N  # CYRILLIC SMALL LETTER DJE
0x2773  U+0453  N  # CYRILLIC SMALL LETTER GJE
0x2774  U+0454  N  # CYRILLIC SMALL LETTER UKRAINIAN IE
0x2775  U+0455  N  # CYRILLIC SMALL LETTER DZE
0x2776  U+0456  N  # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0x2777  U+0457  N  # CYRILLIC SMALL LETTER YI
0x2778  U+0458  N  # CYRILLIC SMALL LETTER JE
0x2779  U+0459  N  # CYRILLIC SMALL LETTER LJE
0x277A  U+045A  N  # CYRILLIC SMALL LETTER NJE
0x277B  U+045B  N  # CYRILLIC SMALL LETTER TSHE
0x277C  U+045C  N  # CYRILLIC SMALL LETTER KJE
0x277D  U+045E  N  # CYRILLIC SMALL LETTER SHORT U
0x277E  U+045F  N  # CYRILLIC SMALL LETTER DZHE
0x2922  U+0110  N  # LATIN CAPITAL LETTER D WITH STROKE
0x2A21  U+00C1  N  # LATIN CAPITAL LETTER A WITH ACUTE
0x2A22  U+00C0  N  # LATIN CAPITAL LETTER A WITH GRAVE
0x2A23  U+00C4  N  # LATIN CAPITAL LETTER A WITH DIAERESIS
0x2A24  U+00C2  N  # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0x2A25  U+0102  N  # LATIN CAPITAL LETTER A WITH BREVE
0x2A26  U+01CD  N  # LATIN CAPITAL LETTER A WITH CARON
0x2A27  U+0100  N  # LATIN CAPITAL LETTER A WITH MACRON
0x2A28  U+0104  N  # LATIN CAPITAL LETTER A WITH OGONEK
0x2A29  U+00C5  N  # LATIN CAPITAL LETTER A WITH RING ABOVE
0x2A2A  U+00C3  N  # LATIN CAPITAL LETTER A WITH TILDE
0x2A2B  U+0106  N  # LATIN CAPITAL LETTER C WITH ACUTE
0x2A2C  U+0108  N  # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
0x2A2D  U+010C  N  # LATIN CAPITAL LETTER C WITH CARON
0x2A2E  U+00C7  N  # LATIN CAPITAL LETTER C WITH CEDILLA
0x2A2F  U+010A  N  # LATIN CAPITAL LETTER C WITH DOT ABOVE
0x2A30  U+010E  N  # LATIN CAPITAL LETTER D WITH CARON
0x2A31  U+00C9  N  # LATIN CAPITAL LETTER E WITH ACUTE
0x2A32  U+00C8  N  # LATIN CAPITAL LETTER E WITH GRAVE
0x2A33  U+00CB  N  # LATIN CAPITAL LETTER E WITH DIAERESIS
0x2A34  U+00CA  N  # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0x2A35  U+011A  N  # LATIN CAPITAL LETTER E WITH CARON
0x2A36  U+0116  N  # LATIN CAPITAL LETTER E WITH DOT ABOVE
0x2A37  U+0112  N  # LATIN CAPITAL LETTER E WITH MACRON
0x2A38  U+0118  N  # LATIN CAPITAL LETTER E WITH OGONEK
0x2A3A  U+011C  N  # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
0x2A3B  U+011E  N  # LATIN CAPITAL LETTER G WITH BREVE
0x2A3C  U+0122  N  # LATIN CAPITAL LETTER G WITH CEDILLA
0x2A3D  U+0120  N  # LATIN CAPITAL LETTER G WITH DOT ABOVE
0x2A3E  U+0124  N  # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0x2A3F  U+00CD  N  # LATIN CAPITAL LETTER I WITH ACUTE
0x2A40  U+00CC  N  # LATIN CAPITAL LETTER I WITH GRAVE
0x2A41  U+00CF  N  # LATIN CAPITAL LETTER I WITH DIAERESIS
0x2A42  U+00CE  N  # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0x2A43  U+01CF  N  # LATIN CAPITAL LETTER I WITH CARON
0x2A44  U+0130  N  # LATIN CAPITAL LETTER I WITH DOT ABOVE
0x2A45  U+012A  N  # LATIN CAPITAL LETTER I WITH MACRON
0x2A46  U+012E  N  # LATIN CAPITAL LETTER I WITH OGONEK
0x2A47  U+0128  N  # LATIN CAPITAL LETTER I WITH TILDE
0x2A48  U+0134  N  # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0x2A49  U+0136  N  # LATIN CAPITAL LETTER K WITH CEDILLA
0x2A4A  U+0139  N  # LATIN CAPITAL LETTER L WITH ACUTE
0x2A4B  U+013D  N  # LATIN CAPITAL LETTER L WITH CARON
0x2A4C  U+013B  N  # LATIN CAPITAL LETTER L WITH CEDILLA
0x2A4D  U+0143  N  # LATIN CAPITAL LETTER N WITH ACUTE
0x2A4E  U+0147  N  # LATIN CAPITAL LETTER N WITH CARON
0x2A4F  U+0145  N  # LATIN CAPITAL LETTER N WITH CEDILLA
0x2A50  U+00D1  N  # LATIN CAPITAL LETTER N WITH TILDE
0x2A51  U+00D3  N  # LATIN CAPITAL LETTER O WITH ACUTE
0x2A52  U+00D2  N  # LATIN CAPITAL LETTER O WITH GRAVE
0x2A53  U+00D6  N  # LATIN CAPITAL LETTER O WITH DIAERESIS
0x2A54  U+00D4  N  # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0x2A55  U+01D1  N  # LATIN CAPITAL LETTER O WITH CARON
0x2A56  U+0150  N  # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0x2A57  U+014C  N  # LATIN CAPITAL LETTER O WITH MACRON
0x2A58  U+00D5  N  # LATIN CAPITAL LETTER O WITH TILDE
0x2A59  U+0154  N  # LATIN CAPITAL LETTER R WITH ACUTE
0x2A5A  U+0158  N  # LATIN CAPITAL LETTER R WITH CARON
0x2A5B  U+0156  N  # LATIN CAPITAL LETTER R WITH CEDILLA
0x2A5C  U+015A  N  # LATIN CAPITAL LETTER S WITH ACUTE
0x2A5D  U+015C  N  # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
0x2A5E  U+0160  N  # LATIN CAPITAL LETTER S WITH CARON
0x2A5F  U+015E  N  # LATIN CAPITAL LETTER S WITH CEDILLA
0x2A60  U+0164  N  # LATIN CAPITAL LETTER T WITH CARON
0x2A61  U+0162  N  # LATIN CAPITAL LETTER T WITH CEDILLA
0x2A62  U+00DA  N  # LATIN CAPITAL LETTER U WITH ACUTE
0x2A63  U+00D9  N  # LATIN CAPITAL LETTER U WITH GRAVE
0x2A64  U+00DC  N  # LATIN CAPITAL LETTER U WITH DIAERESIS
0x2A65  U+00DB  N  # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0x2A66  U+016C  N  # LATIN CAPITAL LETTER U WITH BREVE
0x2A67  U+01D3  N  # LATIN CAPITAL LETTER U WITH CARON
0x2A68  U+0170  N  # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0x2A69  U+016A  N  # LATIN CAPITAL LETTER U WITH MACRON
0x2A6A  U+0172  N  # LATIN CAPITAL LETTER U WITH OGONEK
0x2A6B  U+016E  N  # LATIN CAPITAL LETTER U WITH RING ABOVE
0x2A6C  U+0168  N  # LATIN CAPITAL LETTER U WITH TILDE
0x2A6D  U+01D7  N  # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
0x2A6E  U+01DB  N  # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
0x2A6F  U+01D9  N  # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
0x2A70  U+01D5  N  # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
0x2A71  U+0174  N  # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
0x2A72  U+00DD  N  # LATIN CAPITAL LETTER Y WITH ACUTE
0x2A73  U+0178  N  # LATIN CAPITAL LETTER Y WITH DIAERESIS
0x2A74  U+0176  N  # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
0x2A75  U+0179  N  # LATIN CAPITAL LETTER Z WITH ACUTE
0x2A76  U+017D  N  # LATIN CAPITAL LETTER Z WITH CARON
0x2A77  U+017B  N  # LATIN CAPITAL LETTER Z WITH DOT ABOVE
0x2B23  U+00E4  N  # LATIN SMALL LETTER A WITH DIAERESIS
0x2B24  U+00E2  N  # LATIN SMALL LETTER A WITH CIRCUMFLEX
0x2B25  U+0103  N  # LATIN SMALL LETTER A WITH BREVE
0x2B28  U+0105  N  # LATIN SMALL LETTER A WITH OGONEK
0x2B29  U+00E5  N  # LATIN SMALL LETTER A WITH RING ABOVE
0x2B2A  U+00E3  N  # LATIN SMALL LETTER A WITH TILDE
0x2B2B  U+0107  N  # LATIN SMALL LETTER C WITH ACUTE
0x2B2C  U+0109  N  # LATIN SMALL LETTER C WITH CIRCUMFLEX
0x2B2D  U+010D  N  # LATIN SMALL LETTER C WITH CARON
0x2B2E  U+00E7  N  # LATIN SMALL LETTER C WITH CEDILLA
0x2B2F  U+010B  N  # LATIN SMALL LETTER C WITH DOT ABOVE
0x2B30  U+010F  N  # LATIN SMALL LETTER D WITH CARON
0x2B33  U+00EB  N  # LATIN SMALL LETTER E WITH DIAERESIS
0x2B36  U+0117  N  # LATIN SMALL LETTER E WITH DOT ABOVE
0x2B38  U+0119  N  # LATIN SMALL LETTER E WITH OGONEK
0x2B39  U+01F5  N  # LATIN SMALL LETTER G WITH ACUTE
0x2B3A  U+011D  N  # LATIN SMALL LETTER G WITH CIRCUMFLEX
0x2B3B  U+011F  N  # LATIN SMALL LETTER G WITH BREVE
0x2B3D  U+0121  N  # LATIN SMALL LETTER G WITH DOT ABOVE
0x2B3E  U+0125  N  # LATIN SMALL LETTER H WITH CIRCUMFLEX
0x2B41  U+00EF  N  # LATIN SMALL LETTER I WITH DIAERESIS
0x2B42  U+00EE  N  # LATIN SMALL LETTER I WITH CIRCUMFLEX
0x2B46  U+012F  N  # LATIN SMALL LETTER I WITH OGONEK
0x2B47  U+0129  N  # LATIN SMALL LETTER I WITH TILDE
0x2B48  U+0135  N  # LATIN SMALL LETTER J WITH CIRCUMFLEX
0x2B49  U+0137  N  # LATIN SMALL LETTER K WITH CEDILLA
0x2B4A  U+013A  N  # LATIN SMALL LETTER L WITH ACUTE
0x2B4B  U+013E  N  # LATIN SMALL LETTER L WITH CARON
0x2B4C  U+013C  N  # LATIN SMALL LETTER L WITH CEDILLA
0x2B4F  U+0146  N  # LATIN SMALL LETTER N WITH CEDILLA
0x2B50  U+00F1  N  # LATIN SMALL LETTER N WITH TILDE
0x2B53  U+00F6  N  # LATIN SMALL LETTER O WITH DIAERESIS
0x2B54  U+00F4  N  # LATIN SMALL LETTER O WITH CIRCUMFLEX
0x2B56  U+0151  N  # LATIN SMALL LETTER O WITH DOUBLE ACUTE
0x2B58  U+00F5  N  # LATIN SMALL LETTER O WITH TILDE
0x2B59  U+0155  N  # LATIN SMALL LETTER R WITH ACUTE
0x2B5A  U+0159  N  # LATIN SMALL LETTER R WITH CARON
0x2B5B  U+0157  N  # LATIN SMALL LETTER R WITH CEDILLA
0x2B5C  U+015B  N  # LATIN SMALL LETTER S WITH ACUTE
0x2B5D  U+015D  N  # LATIN SMALL LETTER S WITH CIRCUMFLEX
0x2B5E  U+0161  N  # LATIN SMALL LETTER S WITH CARON
0x2B5F  U+015F  N  # LATIN SMALL LETTER S WITH CEDILLA
0x2B60  U+0165  N  # LATIN SMALL LETTER T WITH CARON
0x2B61  U+0163  N  # LATIN SMALL LETTER T WITH CEDILLA
0x2B65  U+00FB  N  # LATIN SMALL LETTER U WITH CIRCUMFLEX
0x2B66  U+016D  N  # LATIN SMALL LETTER U WITH BREVE
0x2B68  U+0171  N  # LATIN SMALL LETTER U WITH DOUBLE ACUTE
0x2B6A  U+0173  N  # LATIN SMALL LETTER U WITH OGONEK
0x2B6B  U+016F  N  # LATIN SMALL LETTER U WITH RING ABOVE
0x2B6C  U+0169  N  # LATIN SMALL LETTER U WITH TILDE
0x2B71  U+0175  N  # LATIN SMALL LETTER W WITH CIRCUMFLEX
0x2B72  U+00FD  N  # LATIN SMALL LETTER Y WITH ACUTE
0x2B73  U+00FF  N  # LATIN SMALL LETTER Y WITH DIAERESIS
0x2B74  U+0177  N  # LATIN SMALL LETTER Y WITH CIRCUMFLEX
0x2B75  U+017A  N  # LATIN SMALL LETTER Z WITH ACUTE
0x2B76  U+017E  N  # LATIN SMALL LETTER Z WITH CARON
0x2B77  U+017C  N  # LATIN SMALL LETTER Z WITH DOT ABOVE
FILE SHIFTJIS.TXT------
0x7E  U+203E  A  # OVERLINE
0x815F  U+005C  Na  # REVERSE SOLIDUS
0x817C  U+2212  N  # MINUS SIGN
0x8191  U+00A2  Na  # CENT SIGN
0x8192  U+00A3  Na  # POUND SIGN
0x81CA  U+00AC  Na  # NOT SIGN
FILE CP932.TXT------
FILE JAPANESE.TXT------
FILE GB2312.TXT------
FILE CHINSIMP.TXT------
FILE BIG5.TXT------
0xA14E  U+FF64  H  # HALFWIDTH IDEOGRAPHIC COMMA
0xA1F2  U+2641  N  # EARTH
0xA244  U+00A5  Na  # YEN SIGN
0xA246  U+00A2  Na  # CENT SIGN
0xA247  U+00A3  Na  # POUND SIGN
FILE CHINTRAD.TXT------
FILE KSX1001.TXT------
FILE KOREAN.TXT------
注: Unicode Consortium によって提供されている変換表だけしか チェックできない、というこの研究の限界に注意してください。


註釈

この調査結果は、UAX#11 または変換表のバグだと考えられます。

この調査結果 (ただし、以前のもの) については、Unicode Consortium の 註釈があります。 これによると、調査結果の多くの文字 (私の調査結果によると、 全角にするべきなのに半角になっている、とされる) は、対応する FULLWIDTH 文字が Unicode (U+FFxx 領域) に存在するために、半角とするのが正しいとのことです。 そして、変換表のほうが修正されるべきである、とのこと。 たとえば、

(U+2212 MINUS SIGN の FULLWIDTH 版は存在するのでしょうか?) また、「対応する FULLWIDTH 文字が U+FFxx 領域に存在する」 という以外の理由で、変換表の誤りだとしている箇所もあります。 両者について、「Microsoft の変換表はそれぞれ U+FE51 SMALL IDEOGRAPHIC COMMA (EastAsianWidth = W) と U+2295 CIRCLED PLUS (EastAsianWidth = A) に割り当てている」 として、変換表のバグだとしています。

しかし、JIS X 0208、JIS X 0212、JIS X 0213 は、 文字の幅を全く規定していません。すなわち、JIS には全角・半角の区別はないのです。したがって、 JIS が制定する変換表は、全角・半角を考慮したものとは なりえません。たとえば U+00A2 CENT SIGN と U+FFE0 FULLWIDTH CENT SIGN とでは、U+00A2 CENT SIGN を採用するのが当然の帰結となります。

これは、Unicode と JIS、あるいは UAX#11 と変換表とのあいだで 責任のなすりあいをしているに過ぎません。(ただし、私は JIS に問い合わせたわけではありませんので、JIS が実際にはどんな立場かについては分かりません)。 が、重要なことは、ひとつの規格の中での整合性や完全性を 保つことより、ユーザの利便性を図ることではないでしょうか。 少なくともどちらか片方が、折れなければならないと思います。 そして、Unicode が普及しつつあるいまとなっては、 変換表に手を加えるのはもはや非常に困難で、 UAX#11 を変更するほうがずっと簡単だと思います。つまり、

と変更すると、JIS X 0212 を除く大部分が修正されます。 (ただし、変換表は変換表で問題があるので、いずれにせよ 修正されなければならないと思っています)。

残りのケースを見ていきましょう。

FILE JIS0208.TXT------
0x2140  U+005C  Na  # REVERSE SOLIDUS
JIS X 0208 は、EUC-JP では ASCII とともに組み合わせて使うので、 U+005C は ASCII 用に空けておく必要があります (EUC-JP 往復変換の互換性を参照してください)。 つまり、この変換には、文字幅以外にも問題があり、 そっちの問題のほうが致命的なので、変換表を変更しなければなりません。 もしその変更が行われれば、U+005C は Na でも構わないことになります。

次に、

FILE JIS0208.TXT------
0x215D  U+2212  N  # MINUS SIGN
ですが、これは、「対応する FULLWIDTH がある」との主張にもかかわらず、 それが存在していません。したがって、これは N から A へと変更するべきです。

次に、

FILE SHIFTJIS.TXT------
0x7E  U+203E  A  # OVERLINE
は、(これだけ見ると) EastAsianWidth.txt の Revision 9 における変更の結果、 かえって悪くなってしまった例です。 SHIFTJIS の 0x7e は半角でなければなりませんので、 Na が適切となります。しかし、U+203E は、 で使われているので、こちらでは全角でなければなりません。 従って、EastAsainWidth を、すべてを満足させるように決定することは できないので、変換表のほうを変えるしかありません。

次に、

FILE BIG5.TXT------
0xA244  U+00A5  Na  # YEN SIGN
ですが、これを全角にすると、こんどは SHIFTJIS でこれを半角で使いたいのと衝突してしまいます。 したがって、変換表を変えるしかありません。

次に、

FILE BIG5.TXT------
0xA14E  U+FF64  H  # HALFWIDTH IDEOGRAPHIC COMMA
ですが、HALFWIDTH な文字は EastAsianWidth = H でないといけないので、これは変換表のバグだと言えます。

次に、JIS X 0212 については、Unicode の註釈によると、 JIS X 0212 はほとんど普及していないし、JIS X 0213 の登場により、 ますます衰退していくことだろうから、サポートする必要がない、 とのことです。しかし、EastAsianWidth は東アジアにおける 文字幅の習慣との互換性を目的としているのに (そして実際、ロシア文字やギリシャ文字も「A」となっているのに) なぜこんな中途半端なことをするのか、理由が分かりません。

まとめると、EastAsianWidth は、

と変更するべきです。

JIS X 0213

JIS X 0213 の登場に伴い、より多くの文字が「A」に 変更しなければならないと思われます。 これについては、追って調査します。


Tomohiro KUBOTA <debian at tmail dot plala dot or dot jp>