2000-10-19 悪魔の公開メール
「最近の出来事」で使っているスクリプトです。主な機能を挙げますと, 「時系列に並べられたHTML文章に対して,隣接するページを双方向に行き来するためのハイパーリンクを設置する。」,「『目次ページ』を作成する。」などです。このスクリプトは「最近の出来事」の度重なる仕様変更,機能拡張に耐えてきました。私が思っている以上に柔軟性が高いのかもしれません。
ところで,このスクリプトは一般化されておりませんので(また導入方法を記した文章もありません),ヨソのサイトに適用するのは無理です。結局,自分で一から作るのが近道だと思います。
reportcreater.pl
#!/usr/bin/perl $_inputpath = "z:\\~yumi-ii\\master"; $_outputpath = "z:\\~yumi-ii\\area_murono\\htmlfiles\\diary"; $_contentpath = "z:\\~yumi-ii\\area_murono\\htmlfiles\\diary\\00index.html"; $email_address = q!murono@mtc.biglobe.ne.jp!; %registry = ( email_address => $email_address, sitename => q!yumi-ii/area_murono!, contentname => q!最近の出来事!, contenttitle => q!もくじ!, copyright => q!Copyright (c) MURONO 1997-2000!, content_type => q!HTML4.0, CSS1, SHIFT-JIS!, content => q!00index.html!, parent => q!../index.html!, http_location => q!www2s.biglobe.ne.jp/~yumi-ii/area_murono/htmlfiles/diary!, src => { chtml_exchanger => q!http://www.sjk.co.jp/c/w.exe!, }, htmltag => { doctype => q#<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">#, meta => { content-type => q!<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">!, }, link_rel => { navigation => q!<link rel=stylesheet href=".../styles/style-navi@2000090290.css" type="text/css">!, article => q!<link rel=stylesheet href=".../styles/style-content@2000090291.css" type="text/css">!, content => q!<link rel=stylesheet href=".../styles/style-index@2000090292.css" type="text/css">!, mailto => qq!<link rev=made href="mailto:$email_address">!, }, script => { secure => q!<script language="JavaScript1.1" src=".../scripts/js-@2000090240.js"></script>!, }, img => { imode => q!<img src=".../icons/img-imode@2000090110.gif" alt="*" width=16 height=16>!, home => q!<img src=".../icons/img-chpath@2000090113.gif" alt="*" width=16 height=16>!, prev => q!<img src=".../icons/img-prev@2000090112.gif" alt="*" width=16 height=16>!, next => q!<img src=".../icons/img-next@2000090111.gif" alt="*" width=16 height=16>!, }, email => qq!<a href="mailto:${email_address}">${email_address}</a>!, }, const => { imode => q!iモード!, home => q!ホーム!, content => q!目次!, prev => q!前のページ!, next => q!次のページ!, accesskey => { # アクセスキー imode => q!accesskey="I"!, home => q!accesskey="0"!, content => q!accesskey="0"!, prev => q!accesskey="7"!, next => q!accesskey="9"!, }, mnemonic => { # アクセスニーモニック imode => q!!, # なし home => q!(0)!, content => q!(0)!, prev => q!(7)!, next => q!(9)!, }, }, ); # エイリアス my $tag = $registry{htmltag}; my $img = $registry{htmltag}->{img}; my $mnemonic = $registry{const}->{mnemonic}; my $accesskey = $registry{const}->{accesskey}; my $str = $registry{const}; #### # ページ上部出力 sub outputHeader { my($suffix) = @_; print qq!$tag->{doctype}\n!; print qq!<html>\n!; print qq!<head>\n!; print qq!\t$tag->{meta}->{content-type}\n!; print qq!\t$tag->{link_rel}->{navigation}\n!; print qq!\t$tag->{link_rel}->{article}\n!; print qq!\t$tag->{link_rel}->{mailto}\n!; print qq!\t$tag->{script}->{secure}\n!; print qq!\t<title>$registry{sitename} $registry{contentname} ${suffix}</title>\n!; print qq!</head>\n!; } # ページ下部出力 sub outputFooter { my($suffix) = @_; print qq!<hr>\n!; print qq!<address>$registry{sitename} $registry{contentname} ${suffix}, !; print qq!$registry{copyright}, $registry{htmltag}->{email}, $registry{content_type}!; print qq!</addres>\n!; print qq!</body>\n!; print qq!</html>\n!; } # ナヴィゲーションリンク出力 sub outputNavigationLink { my($align, $currentFilename, $prevFilename, $nextFilename) = @_; my $src_exchanger = qq!$registry{src}->{chtml_exchanger}?y=$registry{http_location}${currentFilename}!; my $src_prev = $prevFilename; my $src_next = $nextFilename; #### output #### print "<div class=navi>\n\t"; if ($align eq "top") { print qq!<a href="$src_exchanger" $accesskey->{imode}>$img->{imode} $str->{imode}</a>!; print " "; } print qq!<a href="$registry{parent}" title="$registry{sitename}" !; print qq!onclick="gotoHome(this)">$img->{home} $str->{home}</a> / !; print qq!<a href="$registry{content}" title="$registry{contentname} $registry{contenttitle}" !; print qq!$accesskey->{content}> $img->{content} $registry{contenttitle} $mnemonic->{content}</a> !; my $s; $s = qq!$img->{prev} $str->{prev} $mnemonic->{prev}!; print $src_prev ? qq!<a href="$src_prev" $accesskey->{prev}>$s</a>! : $s; print " "; $s = qq!$img->{next} $str->{next} $mnemonic->{next}!; print $src_next ? qq!<a href="$src_next" $accesskey->{next}>$s</a>! : $s; print "\n</div>"; print "\n"; } # もくじページ出力 sub outputContents { $outputNavigationLink = sub { # 無名サブルーチン my($align) = @_; my $src_exchanger = qq!$registry{src}->{chtml_exchanger}?y=$registry{http_location}/$registry{content}!; #### output #### print "<div class=navi>\n"; print "\t"; if ($align eq "top") { print qq!<a href="$src_exchanger" $accesskey->{imode}>$img->{imode} $str->{imode}</a>!; print " "; } print qq!<a href="$registry{parent}" title="$registry{sitename}" onclick="gotoHome(this)" $accesskey->{home}>!; print qq!$img->{home} $str->{home} $mnemonic->{home}</a>!; print " "; print qq!$img->{prev} $str->{prev} $mnemonic->{prev}!; print " "; print qq!$img->{next} $str->{next} $mnemonic->{next}!; print "\n</div>"; print "\n"; }; my($path, @itemPropList) = @_; foreach (@itemPropList) { push (@itemList, qq!\t<li>$_->{htmlLink}\n!); } #### open(INDEX, ">$_contentpath"); select INDEX; print <<EOB; $tag->{doctype} <html> <head> \t$tag->{meta}->{content-type} \t$tag->{link_rel}->{navigation} \t$tag->{link_rel}->{content} \t$tag->{link_rel}->{mailto} \t$tag->{script}->{secure} \t<title>$registry{sitename} $registry{contentname} $registry{contenttitle}</title> </head> <body> EOB &$outputNavigationLink("top"); print <<EOB; <hr> <h1>最近の出来事</h1> <p>ぼくの日記のようなものです。痛くないハズですが,痛くても知りません。 </p> EOB print "<ul>\n"; foreach (reverse(sort(@itemList))) { print; } print "</ul>\n"; print "<hr>\n"; &$outputNavigationLink("buttom"); outputFooter("もくじ 1997-2000"); close(INDEX); } main: { opendir(DIR, $_inputpath); my @dir = readdir(DIR); closedir(DIR); my @itemPropList; # ファイルリスト取得 foreach $currentFilename (sort(@dir)) { next if ($currentFilename !~ /^(html-)|(dhtml-)/); open(HTMLFILE, "<$_inputpath\\$currentFilename"); @data = <HTMLFILE>; close(HTMLFILE); my $subject, $numOfArticle; foreach (@data) { if (!$title && /^<h2><a name="(\d{10})">(.*)<\/a>/) { $numOfArticle = $2; } if (!$subject && /^<h3>(.*)<\/h3>/) { $subject = $1; } } $refer = { # 無名ハッシュテーブルインスタンスの参照 filename => $currentFilename, numberOfArticle => $numOfArticle, subject => $subject, htmlLink => qq!<a href="./$currentFilename">$numOfArticle 「$subject」</a>!, }; push(@itemPropList, $refer); } my @updated; # 更新チェック for ($index = 0; $index <= $#itemPropList; $index ++) { my $currentFilename = @itemPropList[$index]->{filename}; #### my $inputFilename = "$_inputpath\\$currentFilename"; my $outputFilename = "$_outputpath\\$currentFilename"; #### # 出力先ファイルが存在しない,あるいはマスターが更新されているとき if (!-e $outputFilename or (-M $inputFilename < -M $outputFilename)) { # NOV 17, 1999 # ファイルテスト演算子 -M $file は,実行開始時刻を基準として,ファイルが # 修正されてから経過した日数を返す。値が大きいほど時刻の古いファイルである。 @updated[$index] = 1; @updated[$index - 1] = 1 if ($index > 0); #リンク先も更新対象 @updated[$index + 1] = 1 if ($index < $#itemPropList); } } # 本文HTMLファイル出力 for ($index = 0; $index <= $#itemPropList; $index ++) { # @updated[$index] が偽であればこのファイルを更新しない(真であれば更新する) next if (!@updated[$index]); $_ = @itemPropList[$index]; my $currentFilename = $_->{filename}; my $numberOfArticle = $_->{numberOfArticle}; my $subject = $_->{subject}; my $htmlLink = $_->{htmlLink}; my $inputFilename = qq!$_inputpath\\$currentFilename!; my $outputFilename = qq!$_outputpath\\$currentFilename!; my $prevItemProp = @itemPropList[$index - 1] if ($index > 0); my $nextItemProp = @itemPropList[$index + 1] if ($index < $#itemPropList); # ファイルオープン open(OUTPUT, ">$outputFilename"); select OUTPUT; write: { # ヘッダ出力 outputHeader(qq!$numberOfArticle $subject!); print "<body>\n"; outputNavigationLink("top", $currentFilename, $prevItemProp->{filename}, $nextItemProp->{filename}); print "<hr>\n"; # 本文出力 open(INPUT, "<$inputFilename"); print <INPUT>; close(INPUT); # フッタ出力 print "<hr>\n"; outputNavigationLink("buttom", $currentFilename, $prevItemProp->{filename}, $nextItemProp->{filename}); outputFooter(qq!$numberOfArticle $subject!); } close(OUTPUT); select STDOUT; print "updated. = $inputFilename\n"; } # もくじファイル出力 outputContents($_outputpath, @itemPropList); print "complete."; }