キーワード

プロフィール

深沢千尋

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

最新記事

最新コメント

最新トラックバック

月別アーカイブ

カテゴリ

検索フォーム

RSSリンクの表示

リンク

ブロとも申請フォーム

QRコード

QRコード

スポンサーサイト

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

パソコン新調

2009年もここまで押し詰まってパソコンを新調した。
ここまで来るのに紆余曲折があった。

旧著の改定版を著すためにWindows7のスクリーンショットを取る必要があった。
ここで次の3つの選択肢がある。
1) MacBook+VMWareFusion3
2) 旧XP機をつぶしてインストール
3) 新W7機を購入

まず、ワークマシンとしてバリバリ活躍しているので 2) はないなと思っていた。
で、ここはやっぱ 1) がカッコイイと思って、VMWF3と、あと用もないメモリを買ってDSP版の W7 を買って入れたのである。

いろいろあったのだが、やはり画面が13インチだと狭い。
ぼくは結構図版に凝る方らしくてきついのである。
では iiyama の HD 画面のと2画面にすればいいのではないかと思うのだが、今度は入力デバイスが問題になる。
いちおう Apple の外付けキーボードは買ったのだがマジックマウスは抵抗があって本体のトラックパッドを使うことにした。
スワイプ(なでる)動作が変わるのに違和感があったし、その場タップができないのがいやだった。

でも、Apple の外付けキーボードがちょっと予想外に打ちにくい。
MacBookの入力デバイスはやはり本体が最高である。
ここ20年来の疑問なのだが、ノートパソコンのリッド(液晶部分、蓋)って外付けモニタを使うときはバキッと外せるようにならないものか。
Windowsのキーボードとの非互換、あと VMWF3 が意外に不安定(やはり 64bit CPU の 8GB メモリにすべきか)だったこともあって、こっちがだんだん苦痛になってきた。

ということで、W7 のスクリーンショット用と割り切ってパソコンをもう1台買うことにしたのである。
それが 2009-12-25、金曜日のことだ。

機種はエプソンダイレクトにした。
雨が降っても槍が降っても長野で組み立てて2日以内に届けてくれるという噂を確かめたかったのだ。
結果はそんなはずはなくて、2009-12-29、火曜日着。
まあ十分だよ!

機種はAT971にした。

最初は MacMini なみに小さいST125Eにする気マンマンだったのだが、3万円ほども違うので見送った。
プロセッサは Core Duo の 2.96GHz、160GB-HDD、2GB-RAM という超地味な構成である。
ま、スクリーンショット撮り用だから最小限でいいやと思っていた。
(今は後悔している~

これが今朝、朝イチの9時に日通で来た。
こういうの、運もあるだろうけど気持ちいい。
箱を持ってそのあまりの軽さに3歩歩めず、と思った。
軽い!
小さい!
まあ昔Windows NT 3.51のころ会社にあったコンパックのマシンにこんなのあったね。

開梱すると、思ったよりもフロントパネルが小さくてそのぶん奥行きが長い感じ。
足元縦置きで使うので、この方が安定感があるし、美しく見える。
上面(縦置きで使うと左面)にデカイ丸いメッシュの通気孔があって、スピーカーでかいな~と思ったけどそんなことはなくて廃熱だ。
薄いので、裏に孔があって3センチぐらいのファンがあったら、小さいファンが高速回転すると耳障りな音がするところだが、そうではないので交換がもてる。
ただ、縦置きにするときは一番左のパソコンにしないと孔を塞いでしまう。

で、さっそく起動。
折悪しく大掃除でいらないイーサのケーブルとかぜんぜんないのよ~

コレガのWiFiの子機があまり使っていないノートにささっていたのでこれを転用することにする。
1メートルWiFiだ。
XP機でドライバーとマニュアルPDFをダウンロードしてUSBメモリに入れる。

切替機も用意していないので入力デバイスをどうしようか悩むが、結局一時しのぎでXP機のものをすべて利用する。

自分でも忘れていたのだが、キーボード、マウス、Webカメラなど、すべてエレコムのUSBハブに挿していた。

キーボードは2000年に買ったUNICOMPのSpaceSaverで、当然PS/2だが、これもエレコムのPS/2<=>USB変換を介してつないでいた。

USBハブは以前使っていて懲りていたのだが、使っていない10年間に長足の技術の進歩を遂げたらしく、ぜんぜん問題がない。
ということで、使っていることを忘れていた。
とくにこのエレコムは、ACアダプタから給電するのでバスパワーが補え、裏に磁石がついているのでデスクの向こう側にペタンと貼っておける。
道理で最近足元がキレイだと思ったよ。

この USB ハブをまるごと差し替え。
乱暴だが、結果は良好である。

モニタはMacに刺さっていた DVI 接続を持ってきた。
XP 機はVGA機にする。
これで、USBの切り替えスイッチを1個だけ導入すれば切り替えは割とスムーズである。

で、いよいよEPSON機を起動。
起動が早い!
まあ、Atom+1GB+Vistaあたりを見慣れていたのでこれぐらい当たり前か。

最初初心者ウィザード的なものをいろいろ聞かれる。
モニタがあっさり1920x1080で認識したのはビックリ。

そのあと、JWordとgooの何かをインストールするか聞かれる。
これで EPSON の清潔なイメージが一気に吹っ飛んだ。
JWord はどこにでも出てくるな~。
いや、JWord も JWord なりに付き合いをやめた数年の間に改心したのかもしれないが、初心者ウィザードでこっそり入れようとするあたり、やはり油断できない。
外す。

で、起動する。
最初キーボード配列が 106JP になっていて、101US にするのにちょっと手間取った。
ココの情報で助かった。

まとめると、
・デバイスマネージャーでキーボードがHIDキーボードデバイスであることを確認
・REGEDIT
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
・LayerDriver JPNの値を kbd101.dll に変更
・OverrideKeyboardIdentifierの値を PCAT_101KEY に変更
・再起動

PS/2 だとまたちょっと違うよう。
再起動も高速!

どのタイミングでやったか忘れてしまったが、Wifiもあっさりつながった。

再起動すると Logicool の Web カメラのドライバが更新を求めてきて、更新すると独自のビデオチャットへの加入を勧められる。

ビデオチャットの詳細を表示をクリックすると、Flash が必要だとなって、Flash をインストールすると、Adobe にマカフィーのウィルススキャンも一緒にどうですかと勧められる。
(それはもうエプソンが入れてくれている)

Flash をインストールして、ビデオチャットの使用を確認すると、試用期間が澄むと有料になるそうなので遠慮する。

これで Web カメラの更新が終わったわけだが、アレー、ぼく何やってたっけ。

最近常時接続環境でパソコンを使っているとこの問題がある。
ネットワーク上は乞食の群れなのである。
「これはどうですか」
「いりません」
「これも一緒にどうですか」
「それはなんですか」
「こういうものです」
「いりません」
「メールアドレスを教えてくれますか」
「結構です」
そんなことを言っていると、何をやっていたか忘れてしまうのである。
まあ役に立つ乞食もいるわけだろうが・・・。

で、使っているわけだが、これが快適!
何が快適かと言って、音が静かである。
普通小さなパソコンはうるさいものであるが、これは本当に静かである。
速度も全然問題ない。
正直 Atom+Vista で苦労し過ぎたので、当たり前のことで感動しているだけかもしれない。
あとまあ何も入れていないので、今は快適というだけかもしれないが、正直感動しまくり。


こっちをメインにしたい。
しかしメモリは3GBまでしか増設できないというのはちょっとどうか。

テキスト処理中心で、ちょっとパソコンを使いたい、小さなデスクトップを探している人はおすすめである。
本当に2(営業)日で届くよ。
スポンサーサイト

テーマ : 雑記 - ジャンル : その他

「まるごとEncode」解題(14)オレ文字コードの自作/enc2xs を使う編

続き。
いよいよひとまずの最終回である。
Encodeモジュールを使うと自分専用の文字コードを定義することができるの続き。

2つ目は enc2xs というプログラムを使う方法。
これは、ucm ファイルという変換テーブルを入力として、新しい文字コードを生成するものである。
詳細は例によってperldocに当たれということだが、簡単には以下のように行う。

まず、ネタ元の ucm ファイルを用意する
ここでは、「まるごとEncode」解題(11)CPAN による文字コードのインストールでインストールした Encode::EUCJPMS の ucm が C:\strawberry\cpan\build\Encode-EUCJPMS-0.07-U4rv6s\ucm の下にできるので(cp51932.ucm と、cp51932.ucm の2つ)それを参考に作ってみた。
と言っても、テスト用で、ゴミみたいなファイルである。

fukazawaSmile.ucm - - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
#
# fukazawaSmile

"fukazawaSmile"
1
5
\x3F

CHARMAP
\x28\x5E\x5F\x5E\x29 |0 # SMILE
END CHARMAP
- - - - - - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

全部類推で書いたのだが、 は名前、 はマルチバイトの最小長、 は最大長である。
はencodeの第3引数を省略したときの代替文字で、ここでは ? を指定した。
以下CHARMAPからEND CHARMAPまでが変換テーブルである。

ここでは U+263A(例の ☺)が来たら日本式の顔文字に変換してみた。
|0 というのは Unicode とこの文字コード系のラウンドトリップコンバージョンを保証するという意味だそうだ。
# 以降は注釈である。

さて、ごちゃごちゃにならないようにこのファイル1つをフォルダに入れたら、そのフォルダで以下のコマンドを実行する。

C:\Documents and Settings\you\デスクトップ\test>enc2xs -M fukazawaSmile fukazawaSmile.ucm
Generating Makefile.PL...
Generating fukazawaSmile.pm...
Generating t/fukazawaSmile.t...
Generating README...
Generating Changes...

ちゃんとファイルが出来たか確認する。

C:\Documents and Settings\you\デスクトップ\test>tree /a /f
フォルダ パスの一覧
ボリューム シリアル番号は CC49-9896 です
C:.
| Changes
| fukazawaSmile.pm
| fukazawaSmile.ucm
| Makefile.PL
| README
|
\---t
fukazawaSmile.t

できている。

では make する。
まず makefile を作るための Perl スクリプト Makefile.PL を実行する。

C:\Documents and Settings\you\デスクトップ\test>perl Makefile.PL
enc2xs is C:\strawberry\perl\bin\enc2xs
encode.h is at C:\strawberry\perl\lib\Encode
Writing Makefile for Encode::fukazawaSmile

次に、UNIX 環境であれば % make test とするところであるが、Windows 上の Strawberry Perl 環境では dmake とすればいいだけである。
このへんがラクだね>ストパー

C:\Documents and Settings\you\デスクトップ\test>dmake test
cp fukazawaSmile.pm blib\lib\Encode\fukazawaSmile.pm
C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\bin\enc2xs -"Q" -o fukazawaSmile_t.c -f fukazawaSmile_t.fnm
Reading fukazawaSmile (fukazawaSmile)
Writing compiled form
Use of uninitialized value in substr at C:\strawberry\perl\bin\enc2xs line 767,
line 11.
8 bytes in string tables
C:\strawberry\perl\bin\perl.exe C:\strawberry\perl\lib\ExtUtils\xsubpp -nolinen
umbers -typemap C:\strawberry\perl\lib\ExtUtils\typemap fukazawaSmile.xs > fukazawaSmile.xsc && C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "mv" --fukazawaSmile.xsc fukazawaSmile.c
gcc -c -IC:\strawberry\perl\lib\Encode -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -DPERL_MSVCRT_READFIX -s -O2 -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" "-IC:\strawberry\perl\lib\CORE" fukazawaSmile.c
gcc -c -IC:\strawberry\perl\lib\Encode -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -DPERL_MSVCRT_READFIX -s -O2 -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" "-IC:\strawberry\perl\lib\CORE" fukazawaSmile_t.c
Running Mkbootstrap for Encode::fukazawaSmile ()
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 fukazawaSmile.bs
C:\strawberry\perl\bin\perl.exe -MExtUtils::Mksymlists \
-e "Mksymlists('NAME'=>\"Encode::fukazawaSmile\", 'DLBASE' => 'fukazawaSmile', 'DL_FUNCS' => { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);"
dlltool --def fukazawaSmile.def --output-exp dll.exp
g++ -o blib\arch\auto\Encode\fukazawaSmile\fukazawaSmile.dll -Wl,--base-file -Wl,dll.base -mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib" fukazawaSmile.o fukazawaSmile_t.o -Wl,--image-base,0x1c140000 C:\strawberry\perl\lib\CORE\libperl510.a -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 dll.exp
dlltool --def fukazawaSmile.def --base-file dll.base --output-exp dll.exp
g++ -o blib\arch\auto\Encode\fukazawaSmile\fukazawaSmile.dll -mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib" fukazawaSmile.o fukazawaSmile_t.o -Wl,--image-base,0x1c140000 C:\strawberry\perl\lib\CORE\libperl510.a -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -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\fukazawaSmile\fukazawaSmile.dll
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "cp" -- fukazawaSmile.bsblib\arch\auto\Encode\fukazawaSmile\fukazawaSmile.bs
C:\strawberry\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 blib\arch\auto\Encode\fukazawaSmile\fukazawaSmile.bs
C:\strawberry\perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0,'blib\lib', 'blib\arch')" t/*.t
t/fukazawaSmile.t .. ok
All tests successful.
Files=1, Tests=2, 1 wallclock secs ( 0.14 usr + 0.05 sys = 0.19 CPU)
Result: PASS

C:\Documents and Settings\you\デスクトップ\test>

うまくいったっぽい。
ここで「念のため各ファイルを手直しした方がよいでしょう」とあるが、ここはもうインストールしてしまう。

C:\Documents and Settings\you\デスクトップ\test>dmake install
Files found in blib\arch: installing files in blib\lib into architecture dependent library tree
Installing C:\strawberry\perl\site\lib\auto\Encode\fukazawaSmile\fukazawaSmile.bs
Installing C:\strawberry\perl\site\lib\auto\Encode\fukazawaSmile\fukazawaSmile.dll
Installing C:\strawberry\perl\site\lib\Encode\fukazawaSmile.pm
Appending installation info to C:\strawberry\perl\lib/perllocal.pod

できました。

では使ってみよう。

#! perl
# expFukazawa.pl

use utf8;
use Encode;
use FukazawaSmile::FukazawaSmile;

my $smile = chr 0x263A;
print encode('fukazawaSmile', "Let's go じゅんで~す$smile");

__END__

とでも実行してみようか。

F:\Dropbox20091029\My Dropbox\Marugoto>expFukazawa.pl > u.txt

結果を見てみよう。

u.txt - - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
???????????????(^_^)
- - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

うん、スマイルマークしか定義していないのでほとんど ? になってしまった。

ではプログラムをこう直す。

#! perl
# expFukazawa.pl

use utf8;
use Encode;
use FukazawaSmile::FukazawaSmile;

my $smile = chr 0x263A;
print "", encode('fukazawaSmile', "Let's go じゅんで~す$smile", Encode::XMLCREF), " ";

__END__

実行はこうだ。

F:\Dropbox20091029\My Dropbox\Marugoto>expFukazawa.pl > u.html

u.html ができるのでブラウズしてみる。

20091214_html.png

あははできている。

念のためソースはこうである。

20091214_htmlsrc.png

スマイルマーク以外の字が文字参照になっているわけだ。

「まるごとEncode」解題(12)encode 関数の第3引数

続き。
これまで何回か出てきたが、encode関数には第3引数が渡せる。
以下のプログラムを参照。

#! perl
# encodeSmile.pl -- EUC-JPに該当する文字がない場合(UTF-8で保存)。

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

my $smile = chr 0x263A;
print encode('eucjp', "じゅんで~す$smile\n");
print encode('eucjp', "じゅんで~す$smile\n", Encode::XMLCREF);
print encode('eucjp', "じゅんで~す$smile\n", Encode::PERLQQ);
print encode('ascii', "じゅんで~す$smile\n", Encode::XMLCREF);

__END__

ここでは 0x263A と言う字を含む文字列を encode で EUC-JP に変換している。

U+263AというUnicodeはUnihan Databaseを見れば分かるが☺である。
ちなみに上の文字は「&#x263A;」と文字参照を使って書いた。
当然 EUC-JP の文字レパートリーにはないので、失敗する。

ちなみに、ちょっとヘンな感じがする。
UTF-8 なのだから 0xE298BA なのでは?
違う。
これはperlfuc の chrの項を見れば分かるが、Unicode スカラー値を 16 進数で渡せばいいのである。
だから

my $smile = \x{263A};

と一緒である。

では実行。

F:\Dropbox20091029\My Dropbox\Marugoto>encodeSmile.pl > e.txt

ーe.txtー コ コ カ ラ ー ー ー ー ー ー>8
じゅんで?す?
じゅんで&#xff5e;す☺
じゅんで\x{ff5e}す\x{263a}
じゅんで~す☺
ー ー ー コ コ マ デ ー ー ー ー ー ー>8

(※便宜上アンパサンドを全角にしています)

そう、~も失敗しているのである。
これは想定内だ。
Encode::EUCJPMSも追加する。

#! perl
# encodeSmile.pl -- EUC-JPに該当する文字がない場合(UTF-8で保存)。

use strict;
use warnings;
use Encode;
use Encode::EUCJPMS; # ★変更点
use utf8;

my $smile = chr 0x263A;
print encode('eucJP-ms', "じゅんで~す$smile\n"); # ★変更点
print encode('eucJP-ms', "じゅんで~す$smile\n", Encode::XMLCREF); # ★変更点
print encode('eucJP-ms', "じゅんで~す$smile\n", Encode::PERLQQ); # ★変更点
print encode('ascii', "じゅんで~す$smile\n", Encode::XMLCREF);

__END__

再実行。

F:\Dropbox20091029\My Dropbox\Marugoto>encodeSmile.pl > e.txt

ーe.txtー コ コ カ ラ ー ー ー ー ー ー>8
じゅんで~す[Z]
じゅんで~す&#x263a;
じゅんで~す\x{263a}
&#x3058;&#x3085;&#x3093;&#x3067;&#xff5e;&#x3059;&#x263a;
ー ー ー コ コ マ デ ー ー ー ー ー ー>8

(※便宜上アンパサンドを全角にしています)

では1行1行検証してみよう。

print encode('eucJP-ms', "じゅんで~す$smile\n"); # ★変更点



じゅんで~す[Z]

になっている。
これ、実際には Windows のエディタ上では黒い四角に白抜きで Z といういかつい字で、0x1A だ。
さっきまでは変換できない文字は ? (0x3F) だった。
これは、この連載の(14)に出てくるが、eucJP-ms のモトになっている ucm という変換テーブルファイルの先頭で指定されている。
ウチの環境では
C:\strawberry\cpan\build\Encode-EUCJPMS-0.07-U4rv6s\ucm\eucJP-ms.ucm
というファイルであるが、

\x1A

という業で指定されているようだ。

続き。

print encode('eucJP-ms', "じゅんで~す$smile\n", Encode::XMLCREF); # ★変更点



じゅんで~す&#x263a;

になっている。

これは、U+263A を16進数文字参照&#x263a;になっているのだ。

print encode('eucJP-ms', "じゅんで~す$smile\n", Encode::PERLQQ); # ★変更点



じゅんで~す\x{263a}

になっている。これは Perl の16進表記になっている。
詳しくはperldoc Handling Malformed Data (奇形データの取り扱い)に書かれている。

print encode('ascii', "じゅんで~す$smile\n", Encode::XMLCREF);

が面白くて

&#x3058;&#x3085;&#x3093;&#x3067;&#xff5e;&#x3059;&#x263a;

になっている。
ここで U+3058は「じ」、U+3085は「ゅ」、U+3093は「ん」だから、ひらがなが全部文字参照化されている。
これは、第1引数が ascii になっているからで、ASCII 以外の文字は全部文字参照化される。
究極の文字化け対策である。
こういうサイトたまにありますな。

「まるごと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」解題(10)文字コードの本名を調べる

続き。
Shift_JIS のことを Encode モジュールに指定するとき、名前として shiftjis と渡しても、sjis と渡してもよい。
これは Encode モジュールに登録するときいくつも名前を付けられるからである。
この「本名」を知るには、以下のプログラムを使う。

#! perl
# encodeRealName.pl -- 文字コードの本名を調べる

use Encode;
print "$_ is ", find_encoding($_)->name, "\n" for @ARGV;

__END__

実行してみる。
引数に試したい名前を指定して使う。
複数指定可。

F:\Dropbox20091029\My Dropbox\Marugoto>encodeRealName.pl sjis Shift_JIS Shift-JIS eucjp
sjis is shiftjis
Shift_JIS is shiftjis
Shift-JIS is shiftjis
eucjp is euc-jp

Encode モジュールについて登録されている名前としては、Shift_JIS は shiftjis で、EUC-JP は euc-jp であることがわかる。

ちなみにこれも、元の本ではワンライナー実行していた。

perl -MEncode -le 'print "$_ is ", find_encoding($_)->name, for @ARGV' jis eucjp sjis

ではやってみよう。
さっきの伝で DOS 窓で使うときは外側のクォートを ""、内側を '' にする。

perl -MEncode -le "print '$_ is ', find_encoding($_)->name, for @ARGV" jis eucjp sjis

では実行してみる。

F:\Dropbox20091029\My Dropbox\Marugoto>perl -MEncode -le "print '$_ is ', find_encoding($_)->name, for @ARGV" jis eucjp sjis
$_ is 7bit-jis
$_ is euc-jp
$_ is shiftjis

あっダメだ。
'' は "" と違って変数を値で展開してくれないのである。
こうだ。

perl -MEncode -le "print $_, ' is ', find_encoding($_)->name, for @ARGV" jis eucjp sjis

F:\Dropbox20091029\My Dropbox\Marugoto>perl -MEncode -le "print $_, ' is ', find_encoding($_)->name, for @ARGV" jis eucjp sjis
jis is 7bit-jis
eucjp is euc-jp
sjis is shiftjis

意外とあっさりできたな。

「まるごとEncode」解題(9)Encode がサポートしている文字コードの一覧表示

続き。
Encode がサポートしている文字コードの一覧を表示するには、以下のようなプログラムを実行する。

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

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

print "$_\n" for (Encode->encodings(":all"))

__END__

実行結果。

F:\Dropbox20091029\My Dropbox\Marugoto>listEncodings.pl
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

元原稿ではワンライナーだった。
ぼくはめったにワンライナーを使わないが挑戦してみよう~

F:\>perl -MEncode -le 'print for (Encode->encodings(":all"))'
Can't find string terminator "'" anywhere before EOF at -e line 1.

ダメじゃな。

F:\>perl -MEncode -le "print for (Encode->encodings(':all'))"
7bit-jis
AdobeStandardEncoding
AdobeSymbol
AdobeZdingbat
ascii
ascii-ctrl
...

これだとうまく行った。

DOS 窓はクォートとして "" しか使えないようだ。
ちなみに、DOS 窓に対してワンライナーを渡すためのクォートとして "" を使っているので、その中の encodings に引数を渡すクォートは '' にしている。
もとの原稿は逆にしている。

ちなみに Mac の bash は外が '' で中が "" でも、逆でもうまくいった。

一応元プログラムを解説すると

for (Encode->encodings(':all')) {
print "$_\n";
}

でも同じこと。

for $encoding (Encode->encodings(':all')) {
print $encoding, "\n";
}

でも同じだ。

では、なぜワンライナーでは \n を挟まないのに改行をしてくれたかというと、perl コマンドに -l オプションを渡していたから。
これを渡すと勝手に行処理をする(読み込みは chomp してくれ、書き込みは \n を付与する)

プログラム版で

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

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

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

__END__

と、シュバング行 #! に -l を渡しても同じだ。

Windows でシュバング行を書いても意味がないような気がするが、実際にはこうやってコマンドラインオプションを渡せて便利なのである。

ちなみに #! は英語で shebang だが外人が言っているのを聞くとシュベイングに聞こえる。
ぼくはシュバングと書いているが日本語の表記としてはシェバングが一般的なようだ。
「シュバング UNIX」が Google で 700 ぐらい、「シェバング UNIX」だと 1400 ぐらい。
she の e はシュワ(schwa、あいまい母音、http://www.bbc.co.uk/worldservice/learningenglish/grammar/pron/sounds/vowel_short_5.shtml)だ。

「まるごとEncode」解題(8)ファイル処理(2)

さて、前回は

(1)外界から読み込んだオクテットストリームを decode して Perl 文字列にする
(2)Perl 文字列を処理する
(3)Perl 文字列を encode してオクテットストリームに変えて外界に書き出す

という基礎に則って以下のようなファイル処理のプログラムを書いた。

#! perl
# decodeEncodeFile.pl -- ファイルの読み込み、置換、出力

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

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

この decode、encode を消すことができる。

まず、decode であるが、open 関数の第2引数に「encoding ディシプリン」(discipline、規範)あるいは「encoding レイヤー」(layer 層)というものを追加することによって省略できる。
プログラムはこうだ。

#! 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__

変更箇所としては

open my $fh, "<", $argv or die "cannot open $argv because $!";

my $utf8 = decode("shiftjis", $_);



open my $fh, "<:encoding(cp932)", $argv or die "cannot open $argv because $!";

となった。

また、decode 関数が不要になったので中間関数 $utf8 を使わず、直接 $_ を s/// 演算子および encode 関数に渡している。

なお、encode 関数を消すこともできる。

この場合、標準出力 STDOUT はすでに open されているので、:encoding レイヤーを追加することはできない。
この場合は、本稿の場合既出だが、binmode 関数を使う。
こうだ。

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

use strict;
use warnings;
use utf8;

binmode STDOUT, ":encoding(eucjp)";

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;
}
}

__END__

変更箇所は

use Encode;

print encode("eucjp", $_);



binmode STDOUT, ":encoding(eucjp)";

print;

となった。
encode を使わないので、$_ を渡す必要がなくなったから、$_ の姿が完全に消えてしまった。
で、encode も decode も使わなくなったので use Encode がいらなくなった。

ということで、encode も decode も Encode も姿を消しているが、外界から読んできたオクテットストリームを decode して Perl 文字列にして処理し、Perl 文字列をオクテットストリームに encode して外界に書き込むという原則は変わらない。

「まるごとEncode」解題(7)ファイル処理

17日の沈黙を経て続き。
沈黙中に実のあるコメントとトラックバックをいただいているが、それもおいおい研究します。

以下は、これまで学んだ基礎を踏襲して、ファイル処理を行う。
基礎は以下の通り。

(1)外界から読み込んだオクテットストリームを decode して Perl 文字列にする
(2)Perl 文字列を処理する
(3)Perl 文字列を encode してオクテットストリームに変えて外界に書き出す

では以下のプログラムを実行してみよう。

#! perl
# decodeEncodeFile.pl -- ファイルの読み込み、置換、出力

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

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

実行する前にプログラムを解説する。

@ARGV はプログラムの引数を受け取る配列だ。
この1個1個を $argv に入れながら for ループを回している。
$argv を入力ファイル名として開き、ファイルハンドル $fh に関連付けている。
open が失敗したら or 以降が実行され「ファイル $argv は理由 $! によって開けません」と言って die している。
open に成功したらファイルハンドル $fh を逐次読み込みしている。

入力した各行 $_ を Shift_JIS 文字コードで解釈して decode し、得られた Perl 文字列を $utf8 に入れている★ここがミソ1

次に、$utf8 を s/// で置換している。
ここでは
 深沢千尋
 ふかざわ(全角空白2個)チヒロ
 フカザワ(半角空白2個とタブ3個)ちひろ
などの「深沢千尋っぽい文字列」を「Perl Describer」という文字列に置換している。

・s{from}{to} 形式でカッコを使って分かりやすく文字列を指定していること。
・(?:aaa|bbb|ccc)はaaaまたはbbbまたはccc、(?:~)は文字列を捕獲しないグルーピング
・\x{XXXX}(XXXXは16進数)で Unicode スカラー値 U+3000 の文字(全角空白)をあらわしていること★ここがミソ2
・s/// 演算子の x 修飾子によって正規表現内の空白、改行、注釈を有効化する(perlre によると「Use extended regular expressions.」だそう。http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators)

などに注目したい。

さて、最後に $utf8 の中身を、EUC-JP 文字コードで解釈して encode し、得られたオクテットストリームを print 出力している★ここがミソ3

print は標準出力に関連付けられているので、標準出力に処理された全行がズラズラ~と連続表示される。

★ミソ1:decode

my $utf8 = decode("shiftjis", $_);
入力した各行 $_ を Shift_JIS 文字コードで解釈して decode し、得られた Perl 文字列を $utf8 に入れている★ここがミソ1

これはいいだろう。
Shift_JIS のことを shiftjis と書いているが、これは「だいたい」合っていれば使える。
このことは後で出てくるので後続記事を「だいたい」で検索のこと。

★ミソ2:\x{XXXX}

[\s\x{3000}]* # \s + FULLWIDTH SPACE
・\x{XXXX}(XXXXは16進数)で Unicode スカラー値 U+3000 の文字(全角空白)をあらわしていること★ここがミソ2

\x{XXXX} は Unicode 文字1文字を表す。
(perluniintro で解説されている http://perldoc.jp/docs/perl/5.8.1/perluniintro.pod)

ちょっと気になることがあるので試してみる。

#! perl
# naniwanoJoe.pl -- 辰吉丈一郎の名前を正しく書いてみる

use strict;
use warnings;
use utf8;
binmode STDOUT, ':encoding(cp932)'; # 出力はCP932に変更

print "辰吉丈一郎のジョウは正しくは\x{2000B}だというが、さて、出せるか?\n";

__END__

テスト。

F:\Dropbox20091029\My Dropbox\Marugoto\test>naniwanoJoe.pl
"\x{2000b}" does not map to cp932 at F:\Dropbox20091029\My Dropbox\Marugoto\test\naniwanoJoe.pl line 9.
辰吉丈一郎のジョウは正しくは\x{2000b}だというが、さて、出せるか?

\x{2000b}が cp932 にないから出せない、ということだ。
じゃあ UTF-8 だったら出せるとでも?(戸田奈津子調?)

#! perl
# naniwanoJoe.pl -- 辰吉丈一郎の名前を正しく書いてみる

use strict;
use warnings;
use utf8;
#binmode STDOUT, ':encoding(cp932)'; # 出力はCP932に変更

print "辰吉丈一郎のジョウは正しくは\x{2000B}だというが、さて、出せるか?\n";

__END__

テスト。

F:\Dropbox20091029\My Dropbox\Marugoto\test>naniwanoJoe.pl > k.txt
Wide character in print at F:\Dropbox20091029\My Dropbox\Marugoto\test\naniwanoJoe.pl line 9.

F:\Dropbox20091029\My Dropbox\Marugoto\test>

怒られたな。
こうするか。

#! perl
# naniwanoJoe.pl -- 辰吉丈一郎の名前を正しく書いてみる

use strict;
use warnings;
use utf8;
binmode STDOUT, ':encoding(utf8)'; # 出力はUTF-8に変更

print "辰吉丈一郎のジョウは正しくは\x{2000B}だというが、さて、出せるか?\n";

__END__

テスト。

F:\Dropbox20091029\My Dropbox\Marugoto\test>naniwanoJoe.pl > k.txt

F:\Dropbox20091029\My Dropbox\Marugoto\test>

怒られなくなった。
では k.txt を見てみるか。

20091205joeWin.png

ダメだぁ。

では最近購入した Mac でこれを見てみる。

拡張子 .txt のファイルを何も考えないでダブルクリックするとテキストエディットというアプリで開こうとするが、これだとダメ。

20091205macTxtOpenError.png

だけど、CotEditorというので開いてみると、見事に開いて見え、正しいジョウの字が見られた。

20091205cotEditorJoe.png

U+2000B というのは、16進数5ケタであることからも分かるとおり、サロゲートペアである。
この時は Windows XP 上の MS ゴシックだとフォントがないようだ。
でも UTF-8 文字としては正しいコード(0xF0 A0 80 8B)が生成され、Mac 上ではフォントがあったのでちゃんと見られた。
では同じ Windows でも Vista だとどうだとか、XP でも Meiryo(メイリオ)を入れたらどうだとか、特に方針を決めずに書いているとドンドン話が逸れる。
とりあえずこの辺にしておこう。
\x{XXXX} の XXXX は Unicode スカラー値が入る。

★ミソ3:encode

print encode("eucjp", $utf8);
さて、最後に $utf8 の中身を、EUC-JP 文字コードで解釈して encode し、得られたオクテットストリームを print 出力している★ここがミソ3

ここではミソ1の逆で、$utf8 を EUC-JP でエンコードして出力。
ここでもいい加減な名前 eucjp を使っている。

ちなみに、この名前は IANA というところに登録しているのだが、正しい名前は Shift_JIS(Shift と JIS の間はアンダーバー)、EUC-JP(EUC と JP の間はハイフンマイナス)が正しいそうだ。

ではテストしてみる。
2個ファイルを Shift_JIS で用意。

love.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
あなたはフカザワチヒロだ
お前こそが、ふかざわ   ちひろだね
キミハ深沢 千尋ダネ!
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

kiss.txt- - - - - - ココカラ - - - - - - - - - - - - - - - - ->8
フカザワチヒロサンコンニチハ
ふかざわ   ちひろ さん こんにちは
深沢 千尋 様 今日は
- - - - - - - - - - ココマデ - - - - - - - - - - - - - - - - ->8

では実行。

F:\Dropbox20091029\My Dropbox\Marugoto\test>decodeEncodeFile.pl love.txt kiss.txt > e.txt

F:\Dropbox20091029\My Dropbox\Marugoto\test>

出力は euc なのでリダイレクトしてみた。
e.txt の中を見てみる。

20091205euc.png

出来てるっぽい。
ちなみに秀丸のステータスバーの日本語表示だが、
 日本語 (Shift-JIS)
 日本語(EUC)
と微妙にキモチワルイ。
「秀丸で SHift-JIS と書いているのは正しくは Shift_JIS のことだ」
とか教養にならない知識(これを非教養知識と呼ぼう)を増やしていかないといけないのだ。
ちなみに Microsoft のメモ帳がもっとすごくて「ANSI」なのである。

今回は横道が多かった。

| ホーム |


 ホーム 


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