May 01, 2011
日本語テキスト音声合成システム Open JTalk
今までぽちたてを作ってみたりしてテキスト縦書きビューワーにばかり関心を持っていましたけども、最近は音声合成での日本語テキスト読み上げにも興味が出て来ました。Linux で使えて日本語で音声合成が出来るものには、
があるようです。
AquesTalk や AquesTalk2 は、その音声ライブラリが、ゆっくり声の SofTalk の内部で使われているので有名なのですが、プロプライエタリなものなので無償利用可能な評価版には「ナ行、マ行」の音韻がすべて「ヌ」になる制限があるから使えません。一方、オープンソースな Galatea Talk は、最新リリース情報を見ると開発が二年以上停滞しているようです。そこで同じオープンソースなもので、比較的活発に開発され、MMDAgent などにも組み込まれている Open JTalk を試してみる事にしました。
の記事を参考に、無事に debian squeeze でもビルド出来ました。あまり期待していなかったせいか、予想よりも良い感じに日本語テキストを読み上げてくれます。配布されている作成済みのボイスデータは男声だけですけども、女声のボイスデータが必要なら、同じ Open JTalk を使っている MMDAgent の Sample Script に含まれている、メイのボイスデータが流用出来ます。
2011年 5月 3日追記:ぽち*ぷ〜ちの Open JTalk で音声合成して日本語テキスト読み上げに debian squeeze で Open JTalk を導入する方法を書きました。
2011年 5月 4日追記:
Apr 28, 2011
SDL Perl をいじってみた (3)
今回はスコア表示を変更してゲームオーバー条件を付け、ゲームオーバー状態から RETURNキーを押すと最初から再スタート出来るようにしてみました。←→キーで左右の移動、qキーまたは ESCキーで終了するのは前のままです。
ライブラリは前回同様、SDL に加えて png画像の読み込みに SDL_image、truetypeフォントの読み込みに SDL_ttf を利用しています。また、Perl で使っている SDL Perl のバージョンは 2.532 です。2.2.6以前のバージョンでは動きません。残念な事に debian や ubuntu の SDL Perlパッケージ、libsdl-perl のバージョンは現時点では一番新しくても 2.2.5 なので、CPAN からインストールするしかありません。

ゲームオーバーの条件を付けた事で、だらだらとなんとなくソウルジェムを受け止めるだけの何かが、また少しだけゲームに近付いた気がします。
madoka.png と soul_gem.png


ソウルジェム以外のアイテム、例えばティーカップやきゅぅべえとかもランダムなタイミングでいくつも降らせてみたり、何かの条件を付けてまどかに矢を射させたりしてみたいのですけども、そもそもゲームの作り方を良く知らないぽちなので、実現するにはまだまだ知識が必要なようです。
教えて、ゲームのすごいひと!
#!/usr/local/bin/perl
use strict;
use warnings;
use SDL;
use SDL::Events;
use SDLx::App;
use SDLx::Rect;
use SDLx::Sprite;
use SDLx::Text;
my $error_limit = 10; # ゲームオーバーになるエラー数
# ウィンドウ全体の準備
my $app = SDLx::App->new(
width => 512,
height => 384,
title => 'Catch the Soul Gem!',
dt => 0.02,
exit_on_quit => 1,
);
# 自キャラの準備
my $player = {
rect => SDLx::Rect->new( $app->w / 2 - 16, $app->h / 5 * 4, 32, 32 ),
v_x => 0,
catch => 0,
error => 0,
};
# 自キャラ画像を入れる
my $player_character = SDLx::Sprite->new(
image => 'madoka.png', # 画像置き場へのパス
rect => $player->{rect},
);
# アイテムの準備
my $item = {
rect => SDLx::Rect->new( int( rand( $app->w ) ) - 16, 0, 32, 32 ),
v_y => 4,
};
# アイテム画像を入れる
my $item_character = SDLx::Sprite->new(
image => 'soul_gem.png', # 画像置き場のパス
rect => $item->{rect},
);
# キャッチスコアの準備
my $catch = SDLx::Text->new(
font => 'VL-Gothic-Regular.ttf', # この行削除ならシステムデフォルト
h_align => 'left',
);
# エラースコアの準備
my $error = SDLx::Text->new(
font => 'VL-Gothic-Regular.ttf', # この行削除ならシステムデフォルト
h_align => 'right',
);
# 表示
$app->add_show_handler(
sub {
$app->draw_rect( [ 0, 0, $app->w, $app->h - 45 ], 0x007bbbff ); # 空
$app->draw_rect( [ 0, $app->h - 45, $app->w, 45 ], 0xc3d825ff ); # 地面
$player_character->draw( $app ); # 自キャラ
$item_character->draw( $app ); # アイテム
$catch->write_to( $app, '昇天:' . $player->{catch} ); # キャッチスコア
$error->write_to( $app, '絶望:' . $player->{error} ); # エラースコア
if ( $player->{error} >= $error_limit ) { # ゲームオーバーだったら表示
$catch->write_xy( $app, 140, 170,
'救った魔法少女:' . $player->{catch} . '人' );
}
# CPU使用率が 100% に振り切れるようならディレイを挟んでも良いかも?
#$app->delay( 10 );
$app->update;
}
);
# 自キャラの動き
$app->add_move_handler(
sub {
my ( $step, $app ) = @_;
my $v_x = $player->{v_x};
unless ( $player->{error} >= $error_limit ) {
# 自キャラ座標の変化
$player->{rect}->x( $player->{rect}->x + ( $v_x * $step ) );
# 左の移動限度
if ( $player->{rect}->left <= 0 ) {
$player->{rect}->left( 0 );
}
# 右の移動限度
elsif ( $player->{rect}->right >= $app->w ) {
$player->{rect}->right( $app->w );
}
}
}
);
# アイテムの動き
$app->add_move_handler(
sub {
my ( $step, $app ) = @_;
my $v_y = $item->{v_y};
unless ( $player->{error} >= $error_limit ) {
# アイテム座標の変化
$item->{rect}->y( $item->{rect}->y + ( $v_y * $step ) );
# 衝突した?
if ( &check_collision( $item->{rect}, $player->{rect} ) ) {
$player->{catch}++;
&reset_item;
}
# 下端まで行き着いた?
elsif ( $item->{rect}->top >= $app->h ) {
$player->{error}++;
&reset_item;
}
}
}
);
# 自キャラの操作
$app->add_event_handler(
sub {
my ( $event, $app ) = @_;
# キーを押し込んだ場合
if ( $event->type == SDL_KEYDOWN ) {
# ←キーを押し込んで左へ
if ( $event->key_sym == SDLK_LEFT ) {
$player->{v_x} = -2;
}
# →キーを押し込んで右へ
elsif ( $event->key_sym == SDLK_RIGHT ) {
$player->{v_x} = 2.4;
}
# RETURNキーを押し込んで再スタート
elsif ( $event->key_sym == SDLK_RETURN ) {
$player->{catch} = 0;
$player->{error} = 0;
}
# qキーまたは ESCキーを押して終了
elsif (
$event->key_sym == SDLK_q
or $event->key_sym == SDLK_ESCAPE
) {
$app->stop();
}
}
# キーを離した場合
elsif ( $event->type == SDL_KEYUP ) {
# ←キーや→キーを離したら自キャラが止まる
if (
$event->key_sym == SDLK_LEFT
or $event->key_sym == SDLK_RIGHT
) {
$player->{v_x} = 0;
}
}
}
);
# ループ開始
$app->run;
# 衝突判定
sub check_collision {
my ($A, $B) = @_;
return if ( $A->bottom < $B->top + 16 ); # 自キャラ上半分の衝突判定を削る
return if ( $A->right < $B->left );
return if ( $A->left > $B->right );
# 衝突
return 1;
}
# アイテムをリセット
sub reset_item {
$item->{rect}->y( 0 ); # 上端の
$item->{rect}->x( int( rand( $app->w) ) - 16 ); # ランダムな水平位置
$item->{v_y} = int( rand( 3 ) ) + 3; # ランダムな速度で再出現
}
Apr 26, 2011
SDL Perl をいじってみた (2)
懲りずにまだまだ SDL Perl をいじっています。今回はアイテムと、アイテムと自キャラの衝突判定、スコア表示を追加してみました。少しはゲームに近づいたのではないでしょうか?
SDL に加えて png画像の読み込みに SDL_image、truetypeフォントの読み込みに SDL_ttf を利用しています。

ご覧のように、魔法少女まどか☆マギカのまどかが漆黒に染まったソウルジェムを拾うゲーム(まだゲームとは言えない出来ですけども)になってしまったのは、まどかマギカの第11話・第12話を観たばっかりだったのと、前回投稿した動画、SDL Perl でゲームっぽい何かを書いてみたのコメントのキャラをまどかのドット絵にしたら?という書き込みに乗っかってみたからです。そんでもってまたもや動画を投稿してみました。
madoka.png と soul_gem.png


コードを追加するよりドット絵を手打ちする方に遥かに多くの時間が掛かってしまいました。さらりと描ける方々が本当に羨ましいです。
#!/usr/local/bin/perl
use strict;
use warnings;
use SDL;
use SDL::Events;
use SDLx::App;
use SDLx::Rect;
use SDLx::Sprite;
use SDLx::Text;
# ウィンドウ全体の準備
my $app = SDLx::App->new(
width => 512,
height => 384,
title => 'Catch the Soul Gem!',
dt => 0.02,
exit_on_quit => 1,
);
# 自キャラの準備
my $player = {
rect => SDLx::Rect->new( $app->w / 2 - 16, $app->h / 5 * 4, 32, 32 ),
v_x => 0,
score => 0,
};
# 自キャラ画像を入れる
my $player_character = SDLx::Sprite->new(
image => 'madoka.png', # 画像置き場へのパス
rect => $player->{rect},
);
# アイテムの準備
my $item = {
rect => SDLx::Rect->new( int( rand( $app->w ) ) - 16, 0, 32, 32 ),
v_y => 4,
};
# アイテム画像を入れる
my $item_character = SDLx::Sprite->new(
image => 'soul_gem.png', # 画像置き場のパス
rect => $item->{rect},
);
# スコアの準備
my $score = SDLx::Text->new(
font => 'VL-Gothic-Regular.ttf', # truetypeフォント置き場へのパス
h_align => 'right',
);
# 表示
$app->add_show_handler(
sub {
$app->draw_rect( [ 0, 0, $app->w, $app->h - 45 ], 0x007bbbff ); # 空
$app->draw_rect( [ 0, $app->h - 45, $app->w, 45 ], 0xc3d825ff ); # 地面
$player_character->draw( $app ); # 自キャラ
$item_character->draw( $app ); # アイテム
$score->write_to( $app, 'SCORE:' . $player->{score} ); # スコア
# CPU使用率が 100% に振り切れるようならディレイを挟んでも良いかも?
#$app->delay( 10 );
$app->update;
}
);
# 自キャラの動き
$app->add_move_handler(
sub {
my ( $step, $app ) = @_;
my $v_x = $player->{v_x};
$player->{rect}->x( $player->{rect}->x + ( $v_x * $step ) );
# 左の移動限度
if ( $player->{rect}->left <= 0 ) {
$player->{rect}->left( 0 );
}
# 右の移動限度
elsif ( $player->{rect}->right >= $app->w ) {
$player->{rect}->right( $app->w );
}
}
);
# アイテムの動き
$app->add_move_handler(
sub {
my ( $step, $app ) = @_;
my $v_y = $item->{v_y};
$item->{rect}->y( $item->{rect}->y + ( $v_y * $step ) );
# 衝突した?
if ( &check_collision( $item->{rect}, $player->{rect} ) ) {
$player->{score}++;
&reset_item;
}
# 下端まで行き着いた?
elsif ( $item->{rect}->top >= $app->h ) {
&reset_item;
}
}
);
# 自キャラの操作
$app->add_event_handler(
sub {
my ( $event, $app ) = @_;
# キーを押し込んだ場合
if ( $event->type == SDL_KEYDOWN ) {
# ←キーを押し込んで左へ
if ( $event->key_sym == SDLK_LEFT ) {
$player->{v_x} = -2;
}
# →キーを押し込んで右へ
elsif ( $event->key_sym == SDLK_RIGHT ) {
$player->{v_x} = 2;
}
# qキーまたは ESCキーを押して終了
elsif (
$event->key_sym == SDLK_q
or $event->key_sym == SDLK_ESCAPE
) {
$app->stop();
}
}
# キーを離した場合
elsif ( $event->type == SDL_KEYUP ) {
# ←キーや→キーを離したら自キャラが止まる
if (
$event->key_sym == SDLK_LEFT
or $event->key_sym == SDLK_RIGHT
) {
$player->{v_x} = 0;
}
}
}
);
# ループ開始
$app->run;
# 衝突判定
sub check_collision {
my ($A, $B) = @_;
return if ( $A->bottom < $B->top + 16 ); # 自キャラ上半分の衝突判定を削る
return if ( $A->right < $B->left );
return if ( $A->left > $B->right );
# 衝突
return 1;
}
# アイテムをリセット
sub reset_item {
$item->{rect}->y( 0 ); # 上端の
$item->{rect}->x( int( rand( $app->w) ) - 16 ); # ランダムな水平位置
$item->{v_y} = int( rand( 3 ) ) + 3; # ランダムな速度で再出現
}
Apr 22, 2011
SDL Perl をいじった挙句、ニコニコ動画へ投稿
少しでも SDL Perl の知名度が上がらないかと思ってニコニコ動画へ動画を投稿してみました。
Perl でゲームを書いてみようなんて物好きで酔狂な人が、一人でも増えると心強いんだけど。
Apr 21, 2011
SDL Perl をいじってみた
まったりと SDL::Manual を読みながら、新しくなった SDL Perl をいじってみました。

chr_01.png

とりあえず、ムーヴハンドラやイベントハンドラを仕込んで自キャラを動かしてみるところまで。敵キャラやアイテムや衝突判定は次回へ持ち越しです。
#!/usr/local/bin/perl
use strict;
use warnings;
use SDL;
use SDL::Events;
use SDLx::App;
use SDLx::Rect;
use SDLx::Sprite;
# ウィンドウ全体の準備
my $app = SDLx::App->new(
width => 512,
height => 384,
title => 'test',
dt => 0.02,
exit_on_quit => 1,
);
# キャラクタを入れる器の準備
my $rect = {
chr => SDLx::Rect->new( $app->w / 2 - 16, $app->h / 5 * 4, 32, 32 ),
v_x => 0,
};
# キャラクタを入れる
my $chr = SDLx::Sprite->new(
image => 'chr_01.png', # 画像置き場へのパス
rect => $rect->{chr},
);
# 表示
$app->add_show_handler(
sub {
$app->draw_rect( [ 0, 0, $app->w, $app->h - 45 ], 0x007bbbff ); # 空
$app->draw_rect( [ 0, $app->h - 45, $app->w, 45 ], 0xc3d825ff ); # 地面
$chr->draw( $app ); # キャラ
# CPU使用率が 100% に振りきれるようならディレイを挟んでも良いかも?
#$app->delay( 10 );
$app->update;
}
);
# 動き
$app->add_move_handler(
sub {
my ( $step, $app ) = @_;
my $v_x = $rect->{v_x};
$rect->{chr}->x( $rect->{chr}->x + ( $v_x * $step ) );
# 左の移動限度
if ( $rect->{chr}->left <= 0 ) {
$rect->{chr}->left( 0 );
}
# 右の移動限度
elsif ( $rect->{chr}->right >= $app->w ) {
$rect->{chr}->right( $app->w );
}
}
);
# 操作
$app->add_event_handler(
sub {
my ( $event, $app ) = @_;
# キーを押し込んだ場合
if ( $event->type == SDL_KEYDOWN ) {
# ←キーを押し込んで左へ
if ( $event->key_sym == SDLK_LEFT ) {
$rect->{v_x} = -2;
}
# →キーを押し込んで右へ
elsif ( $event->key_sym == SDLK_RIGHT ) {
$rect->{v_x} = 2;
}
# qキーまたは ESCキーを押して終了
elsif (
$event->key_sym == SDLK_q
or $event->key_sym == SDLK_ESCAPE
) {
$app->stop();
}
}
# キーを離した場合
elsif ( $event->type == SDL_KEYUP ) {
# ←キーや→キーを離したら自キャラが止まる
if (
$event->key_sym == SDLK_LEFT
or $event->key_sym == SDLK_RIGHT
) {
$rect->{v_x} = 0;
}
}
}
);
# ループ開始
$app->run;
CPU の使用率が 100% に振り切れるのは、古い PC だから仕方ないとして、むむむ、自キャラの左右の移動速度があからさまに違うのは何故!?左右の移動速度に差が出るようには書いてない筈なんだけど…。
まだまだ問題山積みです。
Apr 20, 2011
SDL Perl も、あるんだよ!
以前もここで書いたかもしれませんが、SDL の Perlバインディング、SDL Perl はバージョン 2.2.6 以前とバージョン2.5xx では API が大きく変わりました。その上最近では SDL::Manual Writing Games with SDL Perl のような初心者向け文書も書かれています。本が出るくらい日本語文書が充実している Ruby/SDL には到底及びませんけども、ひたすら SDL関連モジュールに埋め込まれた POD を読むしかなかった頃に比べてみれば、SDL Perl を使う為の敷居は随分低くなったのではないでしょうか?
早速 SDL::Manual をちまちま読みながら、教材になってるポンクローンやテトリスクローンを作ってみようと思います。
Apr 18, 2011
Makefileってそいういう仕組みだったんだね…あたしってホント、馬鹿
かいてんパティシエ!とグリーンアイランドのビルドがきっかけで、make や Makefile をきちんと勉強しようと思って、週末にざっと GNU Make Manual を読んでみました。お蔭でぽち環境でのビルド時に悪さをしていた部分がやっとこさ分かりました。
一つは、Makefile.linux の include .depend
で .depend の中のリストを使ってヘッダファイルをインクルードしている部分です。これが、存在しない場所にあるヘッダファイルをインクルードしようとして、
make: *** `ram.o' に必要なターゲット `/usr/local/mingw32/include/SDL/SDL.h' を make するルールがありません. 中止.
というエラーを引き起こしていました。
もう一つはグリーンアイランドだけの問題なのですけども、展開して出来た bubble/src の中に make前にもかかわらず不要なオブジェクトファイルがどっさり入っています。
dconv.o: file not recognized: File format not recognized collect2: ld returned 1 exit status make[1]: *** [GreenIsland] エラー 1 make[1]: ディレクトリ `/home/pochi/Desktop/bubble/src' から出ます make: *** [recursive] エラー 2
これがまた、上のようなエラーに繋がっていました。これらの症状は make を行う前に make clean すれば回避出来ます。それに加えてグリーンアイランドの場合は Makefile.linux の中で RotateGear になっているターゲットの名前を、お作法に則ってきちんと GreenIsland にしてあげれば良いだけです。
その肝心の make clean ですが、make clean を実行する前に Makefile.linux の clean: のコマンド部分は、$(RM) $(OBJS) *~ .depend RotateGear.exe
から、出来上がる筈のバイナリに合わせて、$(RM) $(OBJS) *~ .depend RotateGear
なり、$(RM) $(OBJS) *~ .depend GreenIsland
なりに変更する必要があります。
とりあえずわかった事を日記に書いてみましたけども、近いうちにぽち*ぷ〜ちの Linux箱に置いてあるかいてんパティシエ!、グリーンアイランドを遊ぶも書き直さないと…。
Apr 16, 2011
愛がこもってるから
今日、男性向けエロ漫画家さんの性別を絵を見ただけで言い当てたら驚かれてしまいました。描いた男性キャラを見れば誰だって分かるんじゃないかな?女の子をかわいくエロく描く事に特化した男性向けエロ漫画でも、女性の漫画家さんだと男性キャラの描き方にも愛がこもっています。
しかし、けろりんさんという漫画家さんの絵柄は、ぽちが小学生の頃に読んだブルーソネットの影響を強く受けてる気がします。
Apr 14, 2011
もう Makefile も怖くない!(死亡フラグ)
あるふぁ〜秘密基地(Alpha Secret Base) のパズルアクションゲーム、かいてんパティシエ!とグリーンアイランドをビルドする時、Makefile について何も知らないのに野性の勘と当てずっぽうで変更を加えて、なんとなく make を通してしまいました。出来上がったバイナリを実行して遊んでみたところ、素敵に動いてくれて楽しく遊べます。
けど Makefile を理解出来てないので、どうして make が失敗したり成功したりしたのかは、周辺知識から野性の勘で予想する事は出来ても、確かな事は何一つ分かりません。これではいくらゲームがきちんと動いてるといっても、どうにも気持ち悪くなってしまっていけません。
ぽちは学習用の断片程度なら C を書いた事がありますけども、Makefile が必要なほどの規模のものを書いた事がないので、Makefile の書き方なんて知らないまま過ごして来ました。Linux を使う場合でも、必要なツールはパッケージ管理システムの apt任せにインストールするのばっかりで、必要に迫られてソースコードからビルドする場合でも、同梱の configure に頼り切りです。これも良い機会だと思って、理由もなく怖がっていた Makefile について少し調べてみると、何の事はない、Makefileってお料理の献立レシピみたいなものじゃないですか!!クックパッドのレシピと大差あるものじゃありません。
何だか良く分からないものに対する恐怖感もなくなった事だし、きちんと勉強してみる事にします。
Apr 13, 2011
Linux でゲームを遊ぶ - かいてんパティシエ!とグリーンアイランド
ぽちたて作りがぽちの実力不足で滞ってしまったので、気分転換にゲームで遊んでみる事にしました。ぽちは Linux の入った PC しか持っていないので、遊ぶゲームは当然 Linux のゲームです。Linux のゲームというと海外のものしかないという印象ですけども、日本でも Linux でビルド出来るゲームを作っている方がいらっしゃいます。
今回遊んでみる事にしたのはこれ。
DirectX ではなくてクロスプラットフォームなライブラリの SDL を使っているので、上手く行けば Windows だけじゃなく Linux でもソースコードからビルドして遊べる筈です。ダウンロードのリンクにはそれぞれ Windows とかしか書いてありませんけども、それは同梱されているビルド済みバイナリの話で、実はソースコードがきっちり入っていて Linux向けの Makefile まで準備されています。紆余曲折はありましたが、C の初歩の初歩のほんのさわりしかわからず Makefile の書き方なんて全然知らないぽちでも何とかビルド出来ました。かいてんパティシエ!の二倍ウィンドウやグリーンアイランドは、古過ぎるぽちPC のパワー不足のせいで少しモッサリした感じになってしまいましたけども、充分楽しく遊べます。もっと SDL を使ったゲームが増えるといいなあ。
具体的な紆余曲折はぽち*ぷ〜ちの Linux箱に書く予定です。

D.Kさん、Linux でも動くかわゆくも楽しい、素敵なゲームをありがとうございます。
Apr 12, 2011
Net::AozoraBunko で青空文庫を検索・取得
ぽちたてを青空文庫ビューワー化する為に「青空文庫」と「Perl」で Web を検索してたら、いきなりスゴイの見つけました。
- Perlで文学を嗜む Net::AozoraBunko - JPerl advent calendar 2010 casual Track
- Net::AozoraBunko - search.cpan.org
Net::AozoraBunko
というわけで書いてみました。Net::AozoraBunko。
このモジュールは、青空文庫の作家や作品を検索し、作品をダウンロードすることができます
まだ CPAN にはあげてなくて、 github においてあります。
最初の URI の記事の書かれた時点では、まだ CPAN に上げてない旨が書かれていて、GitHub へのリンクが張られていますけども、二番目の URI の記事でご覧の通り、2011年 4月 12日現在ではしっかり CPAN にあります。青空文庫好きのぽちにとっては断然便利な Perlモジュールなのですが、このモジュールをぽちたてで使ったりしたら色々と便利な事が出来そうです。
Apr 11, 2011
青空文庫形式テキストのパーサが欲しい!
連日ちまちま作っているぽちたてですけども、単純なテキスト縦書きビューワーとしては、だんだんとそれなりの物になって来ています。昨日も圧縮されたテキストファイルをそのまま読み込めるようにしました。こうなって来ると、青空文庫のテキストを読む時に青空文庫形式テキストをただそのまま素の縦書き表示するだけでなく、青空文庫形式テキストの注記を解釈してルビやレイアウトなどに反映させた縦書き表示をしたくなって来ます。その為に必要になるのが青空文庫形式テキストのパーサです。
ぽちたてを青空文庫ビューワー化させるには、まずこの青空文庫パーサを書かないといけません。ぽちの乏しい知識と泥臭いセンスからすると、安直に Perl の正規表現で書く事になると思います。本当は誰か Perl の凄いひとが、AozoraBunko::Parser(仮名)みたいな名前で Perlモジュールを書いてくれたら良いんだけどなあ…。
とりあえず今後の為に、参考になりそうなサイトをメモしておきます。
なんだか、本当にぽちたての青空文庫ビューワー化が出来るのか不安になって来てしまいました。
Apr 10, 2011
ぽちたて 0.1.4 をリリースしました

素のテキストファイルだけでなく、gzip、bzip2、zip形式に圧縮されたテキストファイルも受け取って表示出来るようになった、ぽちたて 0.1.4 をリリースしました。
これでファイルを保管するスペースをだいぶ節約出来るかも?
Apr 09, 2011
IO::Uncompress::AnyUncompress でファイルを展開してみる
ぽちたてで gzip、bzip2、zip といった形式に圧縮されたテキストファイルを直接読み込めるようにしたくて Perl でそうした圧縮ファイルを展開する方法を調べてみると、gzip、bzip2、zip、その他をまとめて扱ってくれる IO::Uncompress::AnyUncompress という、そのものズバリな名前の便利そうなモジュールを発見。早速試しに gzip、bzip2、zipファイルを展開するコードを書いてみました。
#!/usr/bin/perl
use strict;
use warnings;
use IO::Uncompress::AnyUncompress qw/$AnyUncompressError/;
my $file = $ARGV[0];
if ($file =~ /.+\.txt$/) {
open my $fh, '<', $file
or die "Couldn't open $file for reading: $!\n";
my $content .= join '', <$fh>;
close $fh;
print $content;
}
elsif ($file =~ /.+\.zip$|.+\.gz$|.+\.bz2$/) {
my $z = IO::Uncompress::AnyUncompress->new($file)
or die "anyuncompress failed: $AnyUncompressError\n";
my $content .= join '', <$z>;
close $z;
print $content;
}
else {
die "Illegal file name: $file\n";
}
exit;
ファイルを引き数に取って、そのファイルがテキストファイルの場合はそのままで、対応している圧縮ファイルの場合は展開してから、文字列の入った $content
を print
で標準出力へ流しています。改めてテキストファイルが必要なら > で新しいファイルへリダイレクトしてあげるといいかも?
ファイル判別にファイル名の拡張子を使ってるので、中身が何だか分からないアヤシゲなファイルには危なくて使えないけど、ぽちたての用途なら充分使えそうです。