カレンダープログラムは、いろんなふうに応用できますが、これをダイアリーを自動的に作成するプログラムに使ってみました。ダイアリーといっても、ウェブ・ダイアリーで、日付と曜日のならんだ HTML ファイルを作って、そこに日誌ふうの記事を書き、ウェブにアップロードするというものです。次がその全体です。
#!/usr/bin/perl # # diary.pl -- Web Diary Maker # @yobi = qw(日 月 火 水 木 金 土); $input = @ARGV[0]; if($input eq ""){ print "Input year and month in 4 digits.\n"; print "Example: Input '0204' for April, 2002.\n"; exit(0); } # 年月は4桁で入力する(2002年4月は 0204 と入れる) $c_month = $input % 100; $c_year = ($input - $c_month) / 100; $year = 2000 + $c_year; $month = $c_month; # 先月と次月を得る $p_year = $c_year - ($c_month == 1); $n_year = $c_year + ($c_month == 12); $p_month = $c_month - ($c_month > 1) + 11 * ($c_month == 1); $n_month = $c_month + ($c_month < 12) - 11 * ($c_month == 12); # 年月が1桁の場合、先頭に 0 をつける if ($c_year < 10){ $c_year = "0$c_year"; } if ($p_year < 10){ $p_year = "0$p_year"; } if ($n_year < 10){ $n_year = "0$n_year"; } if ($c_month < 10){ $c_month = "0$c_month"; } if ($p_month < 10){ $p_month = "0$p_month"; } if ($n_month < 10){ $n_month = "0$n_month"; } # 作成するファイル名を決め、それを書き込みファイルとして開く $datafile = "diary$c_year$c_month.html"; open OUT, "> $datafile" or die $!; # 作業バーを画面に表示する print "Making <$datafile> "; # HTML ファイルの先頭部分を記入する &print_top(); # 日付を入れる ($first_day, $last_date) = &find_first_last($year, $month); $date = 1; while ($date <= $last_date) { $day = ($first_day + $date -1) % 7; print OUT "<p><b>$month月$date日($yobi[$day])</b></p>\n\n"; $date++; print "."; } # HTML ファイルの終わりの部分を記入する &print_end(); print " done\n"; close(OUT); exit(0); sub find_first_last(){ local($year, $month, @month_days, $days, $i, $first_day, $last_day); ($year, $month) = @_; @month_days = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); # うるう年の計算 if(($year % 4) == 0 and ($year % 100) != 0 or ($year % 400) == 0) { $month_days[2] = 29; } # 1月1日の曜日の計算 $days = $year + int(($year-1)/4) - int(($year-1)/100) + int(($year-1)/400); $i = 0; while($i < $month){ $days += $month_days[$i]; $i++; } # その月の1日の曜日と日数を返す $first_day = $days % 7; $last_date = $month_days[$month]; return ($first_day, $last_date); } sub print_top() { my $print_text = << "_END_"; <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>My Diary</title> </head> <body> <h1 align="center">My Diary $year年$month月</h1> <p align="center"><a href="diary$p_year$p_month.html">先月</a> <a href="diary$n_year$n_month.html">次月</a></p> _END_ print OUT $print_text; } sub print_end() { my $print_text = << "_END_"; <br><div align="center"><form><input type=\"button\" value="ホームページにもどる" onclick="location='../index.html'"></form></div> </body> </html> _END_ print OUT $print_text; }
ここでは、こまかい部分の説明は抜きにして、大事なところだけ解説します。ファイルを開く命令は open <ファイルハンドル>, <ファイル名> で表します。次の部分がそうです。
# 作成するファイル名を決め、それを書き込みファイルとして開く $datafile = "diary$c_year$c_month.html"; open OUT, "> $datafile" or die $!;ここではファイルハンドルは、output の意味で OUT としましたが、好みのもので良いのです。伝統的に、大文字で書くことになっています。ファイル名は $datafile なんですが、書き込みファイルとして開くため "> $datafile" としました。
ファイルを読み込みファイルで開く場合は
open INP, "read.file";追記ファイルとして開く場合は
open ADD, ">> added.file"とすれば良く、コマンドラインで使う > や >> と同様で、わかりやすいと思います。ただし、
open OUT, > "write.file";とすると間違いになります。> や >> はかならず "" の中に入っていなければなりません。
open OUT, "> $datafile" or die $!; の die $! はエラーメッセージを出して終了するという意味です。それにしても「死ね」(die) なんて命令は穏やかではありませんね。
ファイルへの書き込みは
print OUT "<p><b>$month月$date日($yobi[$day])</b></p>\n\n";というように print <ファイルハンドル> <文字列> で行います。open の時と違って、ファイルハンドルのあとに , が入らないことにご注意ください。
書き込みが終わったら、開いたファイルは閉じておくほうが安全でしょう。exit(0) でも、ファイルを閉じることができるのですが、念のため
close(OUT);としておくと良いでしょう。
まとまった文字列を一挙にファイルに書き込むには、その文字列を変数にいれて、print OUT $print_text; としてやれば、print OUT "....."; という式を何行にもわたって書く必要がなくなります。そのテクニックが print_top() と print_end() で使っている $print_text = << "_END_"; という式です。
sub print_top() { my $print_text = << "_END_"; <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>My Diary</title> </head> <body> <h1 align="center">My Diary $year年$month月</h1> <p align="center"><a href="diary$p_year$p_month.html">先月</a> <a href="diary$n_year$n_month.html">次月</a></p> _END_ print OUT $print_text; }これは _END_ という文字が出てくるまで、そのあとに書かれた文字列を改行も含めてそのままの形で $print_text という変数に格納するさせる式です。print で "" でくくった文字列をあつかう場合、 " などの記号を場合は、次のように \ を使う必要があります。
print "<h1 align=\"center\">My Diary $year年$month月</h1>";しかし、上記の方法を使えば、\ は必要ありません。HTML ソースからカットしてきたものをそのまま使えるので便利です。