カレンダ−・プログラムの応用−ウェブ・ダイアリーの制作

カレンダープログラムは、いろんなふうに応用できますが、これをダイアリーを自動的に作成するプログラムに使ってみました。ダイアリーといっても、ウェブ・ダイアリーで、日付と曜日のならんだ 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, "&gt; $datafile" or die $!;
ここではファイルハンドルは、output の意味で OUT としましたが、好みのもので良いのです。伝統的に、大文字で書くことになっています。ファイル名は $datafile なんですが、書き込みファイルとして開くため "&gt; $datafile" としました。

ファイルを読み込みファイルで開く場合は

open INP, "read.file";
追記ファイルとして開く場合は
open ADD, ">> added.file"
とすれば良く、コマンドラインで使う > や >> と同様で、わかりやすいと思います。ただし、
open OUT, > "write.file";
とすると間違いになります。> や >> はかならず "" の中に入っていなければなりません。

open OUT, "&gt; $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 ソースからカットしてきたものをそのまま使えるので便利です。

[前のぺ−ジ] [目次] [次のぺ−ジ]