2000-08-26  yuminet技術資料

以前,YUMIネットオフライン会で話題に上がった,「ユミ日記生成スクリプト」を公開いたします。スクリプトは幾度となくバージョンアップされているのですが,今回公開するのはその最新バージョンです。

これから二つのスクリプトを取り上げます。“yumi-formatter.pl”は,プレーンテキストで記述されたユミ日記をハイパーテキスト化します。そしてその目次リンクファイルを生成します。“js-animation@2000081741.js”は,複数コマの画像を切り替えてアニメートさせるスクリプトです。このスクリプトは,「ハイパーテキスト化」とは直接関係ありません。

yumi-formatter.pl

決められた書式によって,プレーンテキストをHTML4相当のHTMLファイルに変換します。もう少し動作を説明しましょう。プレーンテキストは順序付けされており,それらは昇順に並べ替えられます。そして書式化された(タグを埋め込んだ)HTMLファイルには,それらを双方向に行き来できるようなハイパーリンクが設置されます。図で説明しないと分かりにくいかもしれませんが,やっていることは難しくありません。

あ,そうそう「1行は80文字以内じゃないとダメなんだ。」などと些細なことに口うるさい人には,「もうそろそろモグタンに紹介されそうなくらい古いエディタ使うのやめたら?」と申し上げておきます(ウェブブラウザで閲覧すると水平方向にスクロールバーが表示されますが,わざわざスクロールして見るほど重要なことは書かれておりませんのであしからず)。

$_outputpath         ="z:\\~yumi-ii\\yuminet";
$_masterdirectory    ="z:\\~yumi-ii\\temp\\master";

$_onclick = "if (confirm('かえっちゃうの?')) alert ('アユのメイクみた?\\n
すごいよねフランス人形みたい ユミね アユが使っている洗顔料を知りたい\\n
神田うのちゃんがコマーシャルしてるヤツかな?\\n
知ってたら教えてね バイバイ ユミより'); else return false;"; main: { my (@dir, @htmlfile, @indexes); #### opendir(DIR, $_masterdirectory); @dir = sort(readdir(DIR)); closedir(DIR); foreach (@dir) { /^(.*)\./; push(@htmlfile, "html-$1.html"); } for (my $index = 2; $index <= $#dir; $index ++) { my ($type, $subject, $body, $current, $prev, $next); #### readfile: { my $masterfilename = $dir[$index]; open(HANDLE, "$_masterdirectory\\$masterfilename"); while (<HANDLE>) { ($type) = /^type:(.*)$/ unless $type; ($subject) = /^sub:(.*)$/ unless $subject; ($body) = /^body:(.*)$/ unless $body; } close HANDLE; } $current = $htmlfile[$index]; $prev = $index > 2 ? $htmlfile[$index - 1] : "root.html"; $next = $index < $#dir ? $htmlfile[$index + 1] : "final.html"; write: { open(HANDLE, ">$_outputpath\\$current"); select HANDLE; doFormating("HTML4", $type, $subject, $body, $current, $prev, $next); close(HANDLE); } push(@indexes, qq!<a href="$next">$subject</a> | !) if $type eq "eyecatcher"; } open(HANDLE, ">index.txt"); foreach (@indexes) { print; } close(HANDLE); } sub doFormating { sub outputHTML4form; # 入れ子になったサブルーチンのプロトタイプ宣言 #### local ($markupType, $type, $subject, $body, $current, $prev, $next) = @_; for ($markupType) { /^HTML4/ && do { local ($title = "ユミの日記 「$subject」"); outputHTML4form; }; /^NTT_imode/ && do { }; } return; #### sub outputHTML4form { ######## HEADER ######## print <<"EOB"; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> \t<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> \t<script language="JavaScript1.1" src="./js-animation\@2000081741.js"></script> \t<title>$title</title> </head> EOB ######## BODY ######## for ($type) { my $exchanger = "http://www.sjk.co.jp/c/w.exe?y=www2s.biglobe.ne.jp/~yumi-ii/yuminet/$current"; /^diary/ && do { print <<"EOB"; <body text="black" bgcolor="#fffcff" vlink="#e78180" link="#9c3033" background="./imgs/gizapinkl.gif"> \t<div align=right><a href="$exchanger" accesskey=I><img src="./imgs/img-\@2000081614.gif" width=16 height=16 alt="*" border=0>
iモード</a> <a href="$prev" accesskey="7"><img src="./imgs/img-\@2000081610.gif" width=16 height=16 alt="*" border=0>
まえ (7)</a> <a href="$next" accesskey="9"><img src="./imgs/img-\@2000081611.gif" width=16 height=16 alt="*" border=0> つぎ (9)</a>
<br><a href="./root.html" accesskey="0" onclick="$_onclick" onMouseOver="startAnimation();" onMouseOut="stopAnimation()">
<img src="./imgs/img-128x96\@1998102010.jpg" width="128" height="96" vspace=16 alt="かえるよ (0)" border=0 name=animation></a></div> \t<table border=0><tr><td width=120><td width=400> \t<h2><font color="#073228">$subject</font></h2> \t\t<p style="line-height:150%">$body</p> \t</tr></table> EOB }; /^eyecatcher/ && do { print <<"EOB"; <body text="white" bgcolor="black" link="#63cfcc" vlink="#187e7f" background="./imgs/gizadarkl.gif"> \t<div align=right><a href="$exchanger" accesskey=I><img src="./imgs/img-\@2000081617.gif" width=16 height=16 alt="*" border=0>
iモード</a> <a href="$prev" accesskey="7"><img src="./imgs/img-\@2000081615.gif" width=16 height=16 alt="*" border=0>
まえ (7)</a> <a href="$next" accesskey="9"><img src="./imgs/img-\@2000081616.gif" width=16 height=16 alt="*" border=0> つぎ (9)</a>
<br><a href="./root.html" onclick="$_onclick" accesskey="0">
<img src="./imgs/yumititlesn.jpg" width="128" height="96" vspace=16 alt="かえるよ (0)" border=0></a></div> \t<table border=0><tr><td width=120><td width=400> \t\t<p style="line-height:150%">$body</p> \t</tr></table> EOB }; } ######## FOOTER ######## print <<"EOB"; </body> </html> EOB } # end of subroutine }

旧バージョンと比較すると,ずいぶん軽量化されていますね。さすが,テキスト処理に特化した処理系なだけあります(旧バージョンは「yumi-ii/area_mruono YUMIちゃんページ広報室 『yumi-ii/yuminet 始動 (23 FEB 1999)』で閲覧できます)。ちなみに私はPerlをよく知りませんので,「よい子」の質問には答えられません。この程度のコードならだれにでも書けるはずです(書けない人はMS-Officeのイルカに尋ねてみてください。彼はおそらく何でも知ってます)

js-animation@2000081741.js

あなたは「画像にマウスカーソルを合わせると画像が変る。」といったウェブページを見たことがありませんか。このスクリプトはまさにあの動作をします。しかし,切り替わる画像はひとコマだけではありません。マウスカーソルを合わせっぱなしにすると,次々にコマが進みます。つまりアニメートします。似たような動作はアニメーションGIFを使えばもっと簡単にできます。でも何となくね,JPEG画像をアニメートさせたかったんです。だから,わざわざスクリプトで画像を切り替えることにしました。原理的にはアニメーションPNGとかアニメーションXBM,さらには一コマ目はGIF画像で二コマ目はPNG,三コマ目はJPEGなんていう無駄なこともできます。

このスクリプトはHTMLファイルにインポート(インクルード)して使われます。このコードだけを凝視しても,何をするのか(メソッドがいつ実行されるのか)さっぱり分からないでしょう。本当はHTMLファイルの実装と併せて説明しないといけないんですよね(そんなこと面倒です。自分でやってください)

var numberOfImages = 4;
var remainCount = numberOfImages;
var eventID = null;
var enable = false;
var checkCompletion = new Function("enable = (--remainCount <= 0)");    
var frame = 0;
var intervalTime = 200; // msec
////    
images = new Array(numberOfImages);
for (var i = 0; i < numberOfImages; i ++) {
    images[i] = new Image();
    images[i].onload = checkCompletion;
}
images[0].src = "./imgs/img-128x96q60@2000081720.jpg";
images[1].src = "./imgs/img-128x96q60@2000081721.jpg";
images[2].src = "./imgs/img-128x96q60@2000081722.jpg";
images[3].src = "./imgs/img-128x96@1998102010.jpg";
images['default'] = images[3];

////
function startAnimation() {
    if (!enable) return;
    document.animation.src = images[frame].src;
    frame = (frame + 1) % (numberOfImages - 1);
    eventID = setTimeout("startAnimation()", intervalTime);
}
function stopAnimation() {
    if (!enable) return;
    clearTimeout(eventID);
    document.animation.src = images['default'].src;
}

こういうコードってよく本に載っているんですよね。実際ほとんど同じです。あ,言い忘れましたがNavigatorを使っている人は,自動画像読み込みを「有効」にしないとアニメートしません(「画像ボタン」を押しても全コマがロードされません)。