キーワード

プロフィール

深沢千尋

Author:深沢千尋
みなさんこんにちは、深沢千尋です。(公式ページ
文字コード【超】研究 改訂第2版NEW!」「すぐわかるPerl」「すぐわかる オブジェクト指向 Perl」の著者です。
ここでは、多くは技術的でないこと、ごくまれに技術的なことをなげやりに書いていきます。
メールは suguwakaruPerl@gmail.com まで。(アットマークは ASCII に)
Twitterはじめました。@query1000です。よろしく~

最新記事

最新コメント

最新トラックバック

月別アーカイブ

カテゴリ

検索フォーム

RSSリンクの表示

リンク

ブロとも申請フォーム

QRコード

QRコード

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

「まるごとEncode」解題(11)CPAN による文字コードのインストール

続き。
ここまでは、本の内容をそのまま Windows に写しているだけだったので、ちょっと書いていて後ろめたさもあった。
とくにここ数節はちょっとこっちも息切れしてその感が強かった。
しかし今日からは自分で言うのもなんだが結構面白いと思う。
弾さんも中級編だけにカナ~リ端折って書いているので、こうして解題する意味もあるだろう。

今日は CPAN を使った文字コードのインストールである。

Perl のインストール状態ですでに相当数の文字コード(変換テーブル)がインストールされており、その数はどんどん増えているが、追加の文字コードが CPAN にある場合もあって、それをこれからインストールする。

その前に、現状の文字コードは何だったか、貯めておく。
解題(9)の listEncodings.pl を実行する。

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>listEncodings.pl > defaultEncodeList.txt

この状態で defaultEncodeList.txt の中身はこうである。

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>type defaultEncodeList.txt
7bit-jis
AdobeStandardEncoding
AdobeSymbol
AdobeZdingbat
ascii
ascii-ctrl
big5-eten
big5-hkscs
cp1006
cp1026
cp1047
cp1250
cp1251
cp1252
cp1253
cp1254
cp1255
cp1256
cp1257
cp1258
cp37
cp424
cp437
cp500
cp737
cp775
cp850
cp852
cp855
cp856
cp857
cp858
cp860
cp861
cp862
cp863
cp864
cp865
cp866
cp869
cp874
cp875
cp932
cp936
cp949
cp950
dingbats
euc-cn
euc-jp
euc-kr
gb12345-raw
gb2312-raw
gsm0338
hp-roman8
hz
iso-2022-jp
iso-2022-jp-1
iso-2022-kr
iso-8859-1
iso-8859-10
iso-8859-11
iso-8859-13
iso-8859-14
iso-8859-15
iso-8859-16
iso-8859-2
iso-8859-3
iso-8859-4
iso-8859-5
iso-8859-6
iso-8859-7
iso-8859-8
iso-8859-9
iso-ir-165
jis0201-raw
jis0208-raw
jis0212-raw
johab
koi8-f
koi8-r
koi8-u
ksc5601-raw
MacArabic
MacCentralEurRoman
MacChineseSimp
MacChineseTrad
MacCroatian
MacCyrillic
MacDingbats
MacFarsi
MacGreek
MacHebrew
MacIcelandic
MacJapanese
MacKorean
MacRoman
MacRomanian
MacRumanian
MacSami
MacSymbol
MacThai
MacTurkish
MacUkrainian
MIME-B
MIME-Header
MIME-Header-ISO_2022_JP
MIME-Q
nextstep
null
posix-bc
shiftjis
symbol
UCS-2BE
UCS-2LE
UTF-16
UTF-16BE
UTF-16LE
UTF-32
UTF-32BE
UTF-32LE
UTF-7
utf-8-strict
utf8
viscii

前にもこの表出した。

では Encode::EUCJPMS というのを使ってみよう。

CP932 は Shift_JIS のベンダー独自互換であって、CP932 にあって Shift_JIS にない字というのがあるが、これを使ったコードを使って EUC-JP へのコード変換を行うとやっかいなことになる。

例としては、

test932.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
①って Windows では「まる1」で変換できるが、これは機種依存文字だそうだ~
学校の先生が使いたくてつかいたくてしょうがないらしいぞ。
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

というファイルがあったとして、これを(7)に出てきたdecodeEncodeopen.plで変換してみる。

#! perl
# decodeEncodeopen.pl -- ファイルの読み込み、置換、出力(openでdecode)

use strict;
use warnings;
use utf8;
use Encode;

for my $argv (@ARGV) {
open my $fh, "<:encoding(cp932)", $argv or die "cannot open $argv because $!";
while (<$fh>) {
s{ (?:深沢|ふかざわ|フカザワ)
[\s\x{3000}]* # \s + FULLWIDTH SPACE
(?:千尋|ちひろ|チヒロ)
} {Perl Describer}gmsx;
print encode("eucjp", $_);
}
}

__END__

では実行。

F:\Dropbox20091029\My Dropbox\Marugoto\test>decodeEncodeopen.pl test932.txt > e.txt

結果はこのようになる。

e.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
?って Windows では「まる1」で変換できるが、これは機種依存文字だそうだ?
学校の先生が使いたくてつかいたくてしょうがないらしいぞ。
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

ここで?は掛け値なしの ASCII のクエスチョンマーク(?、0x3F)であり、EUC-JP にない CP932 文字を Encode が置き換えているものである。

これは、前にも出てきたし、後にも出てくるが、encode 関数の第3引数というのを使うと何の字が化けているのか分かる。

具体的にいうと
print encode("eucjp", $_);

print encode("eucjp", $_, Encode::PERLQQ);
に変えてみる。

結果はこのようになる。

e.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
\x{2460}って Windows では「まる1」で変換できるが、これは機種依存文字だそうだ\x{ff5e}
学校の先生が使いたくてつかいたくてしょうがないらしいぞ。
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

①はコテコテの JIS X 0208 基本漢字にないやつだが、これが U+2460 に入っている。
Unihan Databaseを引いてみるとなるほど①だが、J-Sourceというのを見てみるとどこの表にも入っていない。
(JIS X 0213 では CP932(の原規格)を追認して同じ場所 1-13-1 に入ったと思うのだが・・・)

Macは(日)になっていたのだがもう直ったはず、と書こうと思っていたのだが、テキストエディットで見てみると相変わらず直ってなくてたまげた。

Cot editor で見てみると、
日本語(Windows)では①、
日本語(Mac OS)では(日)、
日本語(JIS X 0213)では①
になっている。
へぇ~。
このへんもそのうち追及せねばなるまい。

さて、~はおかしくないか。
これは JIS X 0208 に入っていたはずである。

具体的に言うと CP932 の 0x8160 であるが、これが Unicode の U+FF5E に登録されているという。
Unihan Database を見ると、確かにそうなっている。

これが世に言う波ダッシュ問題である。
JIS X 0208 の波ダッシュは JIS X 0208 の 01-33 であるが、これ本来~である。(ぼくは個人的に上がり下がりの波線と言っている)

ところが、これを、Unicodeの U+301C に登録した人が、縦書き用の波線を90度回転させた〜(下がり上がり)を登録してしまった。
で、Unicode における~は、U+FF5E に登録された。

ということで、まとめると、
 Windowsの ~ 0x8161 は
 本来 〜 WAVE DASH U+301C になるべきだが、
 Windows の変換テーブルでは ~ FULLSIZE TILDE U+FF5E になっている。

Perl はこの変換を尊重して、~をU+FF5Eに変換しているが、U+FF5Eは EUC-JP が参照する JIS X 0208 および JIS X 0212 のレパートリーにないので、? になってしまった。

この件は404 Blog Not Found:Encode - 規格のバグまでは直せませんに書いてある。

ということで、①同様~などというフツーの字までが Unicode に絡むと機種依存文字になってしまったわけだ。

ということで、ぼくは語尾を~で延ばすクセがこの年になって身についてしまったが、そんなことのためにこんな深みにはまってしまった~

閑話休題、ではこの機種依存文字を「MSっぽい EUC」で正しく変換しよう。
これを実現するのが Encode::EUCJPMS である。

原記事「まるごと Encode」によるとこうある。

「Encode では、公式の shiftjis と、その Microsoft による拡張である CP932 を別の文字コードとして区別しています。しかし、たいていの Windows 環境においては、CP932 は shiftjis と区別されずに使われており、そしてそれを EUC-JP に変換した際に、CP932にはあってもshiftjisには存在しない機種依存文字をそのまま送出しています。EncodeでEUC-JPを指定した場合、当然存在しない文字として扱われてしまうのですが、これをWindowsのように扱えるようにするのが本モジュールの機能です。
 詳しくは、上記の perldoc および森山氏のblog「コードページ932 http://msyk/at/webry.info」を参照してください。」

Encode::EUCJPMSのperldocは http://perldoc.net/Encode/EUCJPMS.pm である。
eucJP-ms、cp51932などが使えるようになるようだ。

森山氏のブログとしては、以下の記事が参考になる。
eucJP-ms と CP51932 の違い
「eucJP-ms と cp51932 は、両方とも、EUC-JP をWindows標準キャラクタセットの文字を扱えるようにしたもので、それぞれ次のような拡張が行われています。」

では Encode::EUCJPMS をインストールしよう。

「まるごとEncode」には以下のようにある。


Encodeは日常使う文字コードの多くがすでにサポートされていますが、iモード絵文字など、サポートされていない文字コードも存在します。
そういう時も、CPAN経由で文字コードをインストールすることができます。
通常のモジュールをインストールするときと同様、cpanシェルを起動してから、

cpan>install Encode::FooBar

とすれば OK です。
どんな文字コードが存在するかは、

http://search.cpan.org/search?query=Encode&mode=dist

から検索するとよいでしょう。


もちろんこれは Mac OS X も含む UNIX 環境でのことで、本稿の目的 Windows で実験するという用途で普通には使えない。
いや、使えないはずだった。
ところが最近状況が変わって、Strawberry Perl という便利なものが出来た。

Windows で Perl といえば老舗 ActivePerl であるが、大きな問題があって、新しいモジュールを自分で手軽にインストールできない。
基本的に ppm を使ってインストールするのだが、その場合どこかの誰かがモジュールを Windows 用にビルドして ppm リポジトリーというところにアップロードしてくれている必要がある。
この ppm というのがなかなか上がらないし、上がっていても古かったりする。
いやもちろん腕に覚えがあれば Visual C++ で tarball をビルドでき、ビルドした結果を ppm にして自力でアップロードすることだって出来るのであるが、これがカナーリ敷居が高かった。

しかし、Strawberry Perl、ぼくはストパーなどと呼んでいるが、これだと Windows 用の GNU C コンパイラである MinGW などが組み込まれていて、cpan コマンドで容易にビルドできる。
本ブログでも過去記事で、Text::Kakasi と PAR の pp を Perl 5.10 で使えるようにした。
これ、業務でよく使うのだが、ActivePerl では Perl 5.8 までしか対応していなくて、5.8 が捨てられなかったのだ。

じゃあ ActivePerl はもう捨てていいかというとそういうわけではなくて、やはり老舗の味というか、問題なく枯れていて、ふだんつかうモジュールはいっぱい PPM になっているので、Windows で業務を Perl 化したいということになると、まだまだ ActivePerl の方が信頼性安定性実績はあると思う。

じゃあストパーはどういうときに使うかと言うと、Windows 環境の Perl ミーハー勉強実験用というか、このブログやぼくの本とかを読んで Perl を UNIX 流に使って遊びたい、最新の cpan モジュールを自力でバンバンインストールしたい、だけど日常の環境を UNIX 化するのはちょっとカンベンというスタンスで使うのではないだろうか。

(ちなみに、これから入れる Encode::EUCJPMS も ppm 化しているから、cpan 使わなくても

いや、好きにすればいいと思うけど、ここではストパーを使って Encode::EUCJPMS を cpan でインストールしてみよう。

C:\Documents and Settings\you>cpan

cpan shell -- CPAN exploration and modules installation (v1.9452)
Enter 'h' for help.


cpan> install Encode::EUCJPMS
Fetching with LWP:
http://cpan.strawberryperl.com/authors/01mailrc.txt.gz
Fetching with LWP:
http://cpan.strawberryperl.com/modules/02packages.details.txt.gz
Fetching with LWP:
http://cpan.strawberryperl.com/modules/03modlist.data.gz
Creating database file ...

Gathering information from index files ...
Populating database tables ...
Done!
Running install for module 'Encode::EUCJPMS'
Running make for N/NA/NARUSE/Encode-EUCJPMS-0.07.tar.gz
Fetching with LWP:
http://cpan.strawberryperl.com/authors/id/N/NA/NARUSE/Encode-EUCJPMS-0.07.tar.gz

Fetching with LWP:
http://cpan.strawberryperl.com/authors/id/N/NA/NARUSE/CHECKSUMS
Checksum for C:\strawberry\cpan\sources\authors\id\N\NA\NARUSE\Encode-EUCJPMS-0.
07.tar.gz ok
Scanning cache C:\strawberry\cpan\build for sizes
DONE

CPAN.pm: Going to build N/NA/NARUSE/Encode-EUCJPMS-0.07.tar.gz

enc2xs is C:\strawberry\perl\bin\enc2xs
encode.h is at C:\strawberry\perl\lib\Encode
Checking if your kit is complete...
Looks good
Writing Makefile for Encode::EUCJPMS
cp EUCJPMS.pm blib\lib\Encode\EUCJPMS.pm
C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\bin\enc2xs -"Q" -o EUCJPMS_t
.c -f EUCJPMS_t.fnm
Reading cp51932 (cp51932)
Reading eucJP-ms (eucJP-ms)
Writing compiled form
78710 bytes in string tables
6301 bytes (7.41%) saved spotting duplicates
C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\lib\ExtUtils\xsubpp -nolinen
umbers -typemap C:\strawberry\perl\lib\ExtUtils\typemap EUCJPMS.xs > EUCJPMS.xs
c && C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "mv" -- EUCJPMS.xsc
EUCJPMS.c
gcc -c -IC:\strawberry\perl\lib\Encode -s -O2 -DWIN32 -DHAVE_DES_FCRYPT
-DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-ali
asing -DPERL_MSVCRT_READFIX -s -O2 -DVERSION=\"0.07\" -DXS_VERSION=\"0
.07\" "-IC:\strawberry\perl\lib\CORE" EUCJPMS.c
gcc -c -IC:\strawberry\perl\lib\Encode -s -O2 -DWIN32 -DHAVE_DES_FCRYPT
-DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-ali
asing -DPERL_MSVCRT_READFIX -s -O2 -DVERSION=\"0.07\" -DXS_VERSION=\"0
.07\" "-IC:\strawberry\perl\lib\CORE" EUCJPMS_t.c
Running Mkbootstrap for Encode::EUCJPMS ()
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 EUCJPMS.bs

C:\strawberry\perl\bin\perl.exe -MExtUtils::Mksymlists \
-e "Mksymlists('NAME'=>\"Encode::EUCJPMS\", 'DLBASE' => 'EUCJPMS', 'DL_FUNC
S' => { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);"
dlltool --def EUCJPMS.def --output-exp dll.exp
g++ -o blib\arch\auto\Encode\EUCJPMS\EUCJPMS.dll -Wl,--base-file -Wl,dll.base -m
dll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib" EUCJPMS.o
EUCJPMS_t.o -Wl,--image-base,0x15180000 C:\strawberry\perl\lib\CORE\libperl510.
a -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshel
l32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc
32 -lodbccp32 dll.exp
dlltool --def EUCJPMS.def --base-file dll.base --output-exp dll.exp
g++ -o blib\arch\auto\Encode\EUCJPMS\EUCJPMS.dll -mdll -s -L"C:\strawberry\perl\
lib\CORE" -L"C:\strawberry\c\lib" EUCJPMS.o EUCJPMS_t.o -Wl,--image-base,0x1
5180000 C:\strawberry\perl\lib\CORE\libperl510.a -lmoldname -lkernel32 -luser32
-lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi3
2 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 dll.exp
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 755 blib\arch\
auto\Encode\EUCJPMS\EUCJPMS.dll
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "cp" -- EUCJPMS.bs blib\a
rch\auto\Encode\EUCJPMS\EUCJPMS.bs
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 blib\arch\
auto\Encode\EUCJPMS\EUCJPMS.bs
NARUSE/Encode-EUCJPMS-0.07.tar.gz
C:\strawberry\c\bin\dmake.EXE -- OK
Running make test
C:\strawberry\perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0,
'blib\lib', 'blib\arch')" t/*.t
t/EUCJPMS.t .. ok
All tests successful.
Files=1, Tests=9, 1 wallclock secs ( 0.11 usr + 0.05 sys = 0.16 CPU)
Result: PASS
NARUSE/Encode-EUCJPMS-0.07.tar.gz
C:\strawberry\c\bin\dmake.EXE test -- OK
Running make install
Prepending C:\strawberry\cpan\build\Encode-EUCJPMS-0.07-U4rv6s/blib/arch C:\stra
wberry\cpan\build\Encode-EUCJPMS-0.07-U4rv6s/blib/lib to PERL5LIB for 'install'
Files found in blib\arch: installing files in blib\lib into architecture depende
nt library tree
Installing C:\strawberry\perl\site\lib\auto\Encode\EUCJPMS\EUCJPMS.bs
Installing C:\strawberry\perl\site\lib\auto\Encode\EUCJPMS\EUCJPMS.dll
Installing C:\strawberry\perl\site\lib\Encode\EUCJPMS.pm
Appending installation info to C:\strawberry\perl\lib/perllocal.pod
NARUSE/Encode-EUCJPMS-0.07.tar.gz
C:\strawberry\c\bin\dmake.EXE install UNINST=1 -- OK


cpan>

かっこいいわー。
gcc でコンパイルして、dmake というので make している。
これ、そのうち何らかのパッチを tarball に入れて手動ビルドするときも使うので、なんとなく覚えておくとよい。

さて、Encode モジュールがサポートしている文字セットを比較してみる。

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>listEncodings.pl > Encodelist.txt

として、defaultEncodeList.txt と Encodelist.txt を比較する。
これ UNIX では普通 diff というのを使うが、最近 Windows で fc(file compare)というのが使えると分かった。

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>fc defaultEncodeList.txt Encodelist.txt
ファイル defaultEncodeList.txt と ENCODELIST.TXT を比較しています
FC: 相違点は検出されませんでした

あれー違わないって。

それはそうである。

#! perl -l
# listEncodings.pl -- サポートしている文字コードの一覧表示

use Encode;
#use Encode::EUCJPMS;
#use Encode::JavaScript::UCS;
#use FukazawaSmile::FukazawaSmile;

print for (Encode->encodings(":all"))

__END__

ここではデフォルトの Encode モジュールがサポートしている文字コードの一覧表示を見たのだ。
この

#use Encode::EUCJPMS;

の注釈を取って、

use Encode::EUCJPMS;

としてみる。

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>listEncodings.pl > Encodelist.txt

F:\Dropbox20091029\My Dropbox\Marugoto\donePL>fc defaultEncodeList.txt Encodelist.txt
ファイル defaultEncodeList.txt と ENCODELIST.TXT を比較しています
***** defaultEncodeList.txt
cp500
cp737
***** ENCODELIST.TXT
cp500
cp50220
cp50221
cp51932
cp737
*****

***** defaultEncodeList.txt
euc-kr
gb12345-raw
***** ENCODELIST.TXT
euc-kr
eucJP-ms
gb12345-raw
*****

だそうである。

cp500
cp737



cp500
cp50220
cp50221
cp51932
cp737

に変わったということで、

cp50220
cp50221
cp51932

が新しく増えた。

同様に

eucJP-ms

が増えたのである。

では使ってみよう。

#! perl
# decodeEncodeopen.pl -- ファイルの読み込み、置換、出力(openでdecode)

use strict;
use warnings;
use utf8;
use Encode;
use Encode::EUCJPMS; #★相違点1

for my $argv (@ARGV) {
open my $fh, "<:encoding(cp932)", $argv or die "cannot open $argv because $!";
while (<$fh>) {
s{ (?:深沢|ふかざわ|フカザワ)
[\s\x{3000}]* # \s + FULLWIDTH SPACE
(?:千尋|ちひろ|チヒロ)
} {Perl Describer}gmsx;
print encode("eucJP-ms", $_); #相違点2
}
}

__END__

と言うふうに変えて実行する。

F:\Dropbox20091029\My Dropbox\Marugoto\test>decodeEncodeopen.pl test932.txt > e2.txt

e2.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
①って Windows では「まる1」で変換できるが、これは機種依存文字だそうだ~
学校の先生が使いたくてつかいたくてしょうがないらしいぞ。
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

うおーできた。
スポンサーサイト

<< 「まるごとEncode」解題(12)encode 関数の第3引数 | ホーム | 「まるごとEncode」解題(10)文字コードの本名を調べる >>


コメント

コメントの投稿


管理者にだけ表示を許可する

 ホーム 


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。