[Pyukiwiki-cvs 0008562] CVS update: PyukiWiki-Nekyo/019/plugin

Back to archive index

PyukiWiki CVS Commit pyuki****@lists*****
2012年 3月 18日 (日) 02:14:52 JST


Index: PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,32 @@
+##
+# 管理者用編集プラグイン~
+# ※内部で edit プラグインの機能を呼び出している。~
+# メニューから呼び出される。
+# :書式|
+# なし
+
+# @author: Nekyo (http://nekyo.hp.infoseek.co.jp/)
+# @license: GPL2 and/or Artistic or each later version.
+
+use strict;
+
+sub plugin_adminedit_action {
+	if (1 == &exist_plugin('edit')) {
+		my ($page) = &unarmor_name(&armor_name($::form{mypage}));
+		my $body;
+		if (not &is_editable($page)) {
+			$body .= qq(<p><strong>$::resource{cantchange}</strong></p>);
+		} else {
+			$body .= qq(<p><strong>$::resource{passwordneeded}</strong></p>);
+			$body .= &editform(
+				$::database{$page},
+				&get_info($page, $::info_ConflictChecker),
+				admin => 1
+			);
+		}
+		return ('msg'=>$page, 'body'=>$body);
+	}
+	return "";
+}
+1;
+__END__
Index: PyukiWiki-Nekyo/019/plugin/amazon.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/amazon.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/amazon.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,98 @@
+##
+# アマゾン(http://www.amazon.co.jp)の商品のイメージ、商品名を表示する。~
+# アフェリエイト対応。
+# :書式|
+#  &amazon(ASIN番号);
+#  #amazon
+#  #amazon(,clear)
+#  #amazon(ASIN番号,[left|right],[タイトル|image])
+# -left|right - 表示時の位置指定。省略時はright。~
+# -clear - テキスト回り込みの解除。~
+# -タイトル - 商品タイトルを指定。省略時は自動取得。
+# -image - 商品のイメージのみ表示。省略時はイメージとタイトルを表示。
+# :備考|
+# アマゾンのアソシエイトプログラムを確認すること。~
+use strict;
+package amazon;
+
+my $shop = 'http://www.amazon.co.jp/exec/obidos/ASIN/';
+my $af_id = 'pyukiwikipubl-22';
+
+sub plugin_block
+{
+	return &plugin_inline(@_);
+}
+
+sub plugin_inline
+{
+	my @aryargs = split(/,/, shift);
+
+	return '' if (@aryargs < 1 or @aryargs > 3);
+	my $asin_aid = '';
+	my $align = 'left';	# Set Dafault align;
+	$align = lc $aryargs[1] if (@aryargs > 1);
+	return '<div style="clear:both"></div>' if ($align eq 'clear'); # 改行挿入
+
+	$align = 'right' if ($align ne 'left');	# 配置決定
+
+	my $asin_all = &::escape($aryargs[0]);
+
+	my $asin = '';
+	if ($asin_all =~ /^([A-Z0-9]{10}).?([0-9][0-9])?$/) {
+		$asin = $1;
+		my $asin_ext = ($2 eq '') ? "09" : $2;
+		$asin_all = "$asin.$asin_ext";
+	} elsif ($align ne 'clear') {
+		return 'Not Asin Code';
+	}
+
+	my $title = '';
+	my $alt = '';
+	if ($aryargs[2] ne '' and $aryargs[2] ne 'image') { # タイトル指定か自動取得か
+		$title = &::escape($aryargs[2]); # for XSS
+		$alt = $title;
+	}
+	my $url = "http://images-jp.amazon.com/images/P/$asin_all.MZZZZZZZ.jpg";
+	my $div = "";
+
+	my $ref = 'ref=nosim';
+	$ref = $af_id if ($af_id ne '');
+	if ($title eq '') { # タイトルがなければ、画像のみ表示
+		$div .= <<"EOD";
+<div style="float:$align;margin:16px 16px 16px 16px;text-align:center">
+<a href="$shop$asin/@{[$asin_aid]}$ref"><img src="$url" alt="$alt" /></a>
+</div>
+EOD
+	} else {			# 通常表示
+		$div .= <<"EOD";
+<div style="float:$align;padding:.5em 1.5em .5em 1.5em;text-align:center">
+<table style="width:110px;border:0;text-align:center">
+  <tr>
+    <td style="text-align:center">
+      <a href="$shop$asin/@{[$asin_aid]}$ref"><img src="$url" alt="$alt" /></a>
+    </td>
+  </tr>
+  <tr>
+    <td style="text-align:center">
+      <a href="$shop$asin/@{[$asin_aid]}$ref">$title</a>
+    </td>
+  </tr>
+</table>
+</div>
+EOD
+	}
+	return $div;
+}
+
+sub plugin_usage {
+	return {
+		name => 'amazon',
+		version => '1.0',
+		author => 'Nekyo.',
+		syntax => '&amazon(...)',
+		description => 'show amazon books.',
+		example => '&amazon(asincode,...)',
+	};
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/aname.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/aname.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/aname.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,56 @@
+##
+# 指定した位置にアンカー(リンクの飛び先)を設定します。
+# :書式|
+#  &aname(アンカー名,[,{[super],[full],[noid]},アンカー文字列]);
+#  #aname(アンカー名,[,{[super],[full],[noid]},アンカー文字列])
+# アンカー名がアンカーの指定子に使用される。(省略不可)。半角英字(大文字/小文字)が使用可能。
+# super,full,noid でアンカーの出力方式を指定する。
+# -super - アンカー文字列を上付き表示する。省略時は上付き表示されない。
+# -full - フラグメント指定子以外のURIを補いアンカーを出力する。省略時はフラグメント指定子のみ出力される。
+# -noid − アンカーにフラグメント指定子を出力しない。
+# アンカー文字列が指定された場合、指定した文字列に対しアンカーが出力される。アンカーの存在を明示する場合に使用する。省略時は空文字となる。
+
+###############################################
+# aname plugin
+# aname.inc.pl
+# Copyright(c) 2004 Nekyo.
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+# Based on aname.inc.php by Mr.arino.
+
+sub plugin_aname_inline
+{
+	my ($args) = @_;
+	return plugin_aname_convert($args);
+}
+
+sub plugin_aname_convert
+{
+	return '' if (@_ < 1);	# no param
+	my @args = split(/,/, shift);
+	my $id = shift(@args);
+	return false if (!($id =~ /^[A-Za-z][\w\-]*$/));
+
+	my $body = '';
+	if (@args) {
+		$body = pop(@args);
+		$body =~ s/<\/?a[^>]*>//;
+	}
+	my $class = 'anchor';
+	my $url = '';
+	my $attr_id = " id=\"$id\"";
+
+	foreach (@args) {
+		if (/super/) {
+			$class = 'anchor_super';
+		}
+		if (/full/) {
+			$url = "$script?" . rawurlencode($vars['page']);
+		}
+		if (/noid/) {
+			$attr_id = '';
+		}
+	}
+	return "<a class=\"$class\"$attr_id href=\"$url#$id\" title=\"$id\">$body</a>";
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/article.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/article.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/article.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,86 @@
+##
+# 簡易掲示板を設置する。
+# :書式|
+#  #article 
+
+# PyukiWiki BBS風プラグイン
+# 2007/01/15 スパム対策
+# 2004/06/12 Nekyo(c) http://nekyo.hp.infoseek.co.jp/
+# Based on OKAWARA,Satoshi's PukiWiki Plugin
+use strict;
+
+$article::cols = 70;						# テキストエリアのカラム数
+$article::rows = 5;							# テキストエリアの行数
+$article::name_cols = 24;					# 名前テキストエリアのカラム数
+$article::subject_cols = 60;				# 題名テキストエリアのカラム数
+$article::name_format = '[[$name]]';		# 名前の挿入フォーマット
+$article::subject_format = '**$subject';	# 題名の挿入フォーマット
+$article::ins = 0;							# 挿入する位置 1:欄の前 0:欄の後
+$article::comment = 1;						# 書込み下に一行コメントを 1:入れる 0:入れない
+$article::auto_br = 1;						# 改行を自動的変換 1:する 0:しない
+$article::no = 0;
+
+my $_no_name = "";
+my $_no_subject = "no subject";
+
+sub plugin_article_action
+{
+	return if ($::form{msg} =~ /^\s*$/); # msg なしで処理しない。
+	my $postdata = $::form{msg};
+
+	&::spam_filter($postdata, 1);
+	my $name = $_no_name;
+	if ($::form{name} ne '') {
+		#&::spam_filter($::form{name}, 0);	# 日本語チェックは行わない。
+		$name = $article::name_format;
+		$name =~ s/\$name/$::form{name}/g;
+	}
+	my $subject = $article::subject_format;
+	if ($::form{subject} ne '') {
+		#&::spam_filter($::form{subject}, 0);	# 日本語チェックは行わない。
+		$subject =~ s/\$subject/$::form{subject}/g;
+	} else {
+		$subject =~ s/\$subject/$_no_subject/g;
+	}
+	my $artic = "$subject\n>$name (@{[&get_now]})~\n~\n$::form{msg}\n";
+	$artic .= "\n#comment\n" if ($article::comment);
+	$postdata = '';
+	my @postdata_old = split(/\r?\n/, $::database{$::form{'mypage'}});
+	my $_article_no = 0;
+
+	foreach (@postdata_old) {
+		$postdata .= $_ . "\n" if (!$article::ins);
+		if (/^#article/ && (++$_article_no == $::form{article_no})) {
+			$postdata .= "$artic\n";
+		}
+		$postdata .= $_ . "\n" if ($article::ins);
+	}
+	$::form{mymsg} = $postdata;
+	$::form{mytouch} = 'on';
+	&do_write("FrozenWrite");
+	&close_db;
+	exit;
+}
+
+sub plugin_article_convert
+{
+	$article::no++;
+	my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker);
+	return <<"EOD";
+<form action="$::script" method="post">
+ <div>
+  <input type="hidden" name="article_no" value="$article::no" />
+  <input type="hidden" name="cmd" value="article" />
+  <input type="hidden" name="mypage" value="$::form{'mypage'}" />
+  <input type="hidden" name="myConflictChecker" value="$conflictchecker" />
+  <input type="hidden" name="mytouch" value="on" />
+  $::resource{article_name} <input type="text" name="name" size="$article::name_cols" /><br />
+  $::resource{article_subject} <input type="text" name="subject" size="$article::subject_cols" /><br />
+  <textarea name="msg" rows="$article::rows" cols="$article::cols"></textarea><br />
+  <input type="submit" value="$::resource{article_btn}" />
+ </div>
+</form>
+EOD
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/attach.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/attach.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/attach.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,586 @@
+##
+# ページの添付ファイル一覧を表示し、ファイル添付のための入力フォームを設置する。
+# :書式|
+#  #attach([nolist][,noform])
+# -nolist - 添付ファイルの一覧を表示しない。省略時は表示。
+# -noform - ファイル添付フォームを表示しない。省略時は表示。
+use strict;
+use CGI qw(:standard);
+use Digest::MD5 qw(md5_hex);
+
+#--------------------------------------------------------
+my %mime = (
+	"\.hqx"           => "application/mac-binhex40",
+	"\.doc"           => "application/msword",
+	"\.pdf"           => "application/pdf",
+	"\.(ppt|pps|pot)" => "application/vnd.ms-powerpoint",
+	"\.xls"           => "application/vnd.ms-excel",
+	"\.sit"           => "application/x-stuffit",
+	"\.swf"           => "application/x-shockwave-flash",
+	"\.(zip|nar)"     => "application/zip",
+
+	"\.midi?"         => "audio/midi",
+	"\.mp3"           => "audio/mpeg",
+	"\.wav"           => "audio/x-wav",
+
+	"\.bmp"           => "image/bmp",
+	"\.gif"           => "image/gif",
+	"\.jpe?g"         => "image/jpeg",
+	"\.png"           => "image/png",
+
+	"\.txt"           => "text/plain",
+
+	"\.mpe?g"         => "video/mpeg",
+);
+
+# file icon image
+if (!$::file_icon) {
+	$::file_icon = '<img src="'
+		. $::image_dir
+		. '/file.png" width="20" height="20" alt="file" style="border-width:0px" />';
+}
+
+#-------- convert
+sub plugin_attach_convert
+{
+	if (!$::file_uploads) {
+		return 'file_uploads disabled';
+	}
+
+	my $nolist = 0;
+	my $noform = 0;
+
+	my @arg = split(/,/, shift);
+	if (@arg > 0) {
+		foreach (@arg) {
+			$_ = lc $_;
+			$nolist |= ($_ eq 'nolist');
+			$noform |= ($_ eq 'noform');
+		}
+	}
+	my $ret = '';
+	if (!$nolist) {
+	#	$obj = &new AttachPages($vars['page']);
+	#	$ret .= $obj->toString($vars['page'],1);
+	}
+	if (!$noform) {
+		$ret .= &attach_form($::form{mypage});
+	}
+	return $ret;
+}
+
+my %_attach_messages;
+
+#アップロードフォーム
+sub attach_form
+{
+	my $page = $::form{mypage};	#split(/,/, shift);
+#	$r_page = rawurlencode($page);
+	my $r_page = $page;
+	my $s_page = &::htmlspecialchars($page);
+	my $navi =<<"EOD";
+  <span class="small">
+   [<a href="$::script?cmd=attach&amp;mypage=$page&amp;pcmd=list&amp;refer=$r_page">$::resource{'attach_msg_listpage'}</a>]
+   [<a href="$::script?cmd=attach&amp;mypage=$page&amp;pcmd=list">$::resource{'attach_msg_listall'}</a>]
+  </span><br />
+EOD
+	return $navi if (!$::file_uploads);
+
+	my $maxsize = $::max_filesize;
+	my $msg_maxsize = $::resource{attach_msg_maxsize};
+	my $kb = $maxsize / 1000 . "kb";
+
+	$msg_maxsize =~ s/%s/$kb/g;
+
+	my $pass = '';
+	if ($::file_uploads == 2) {
+		$pass = '<br />' . $::resource{attach_msg_password}
+			. ': <input type="password" name="pass" size="8" />';
+	}
+	return <<"EOD";
+<form enctype="multipart/form-data" action="$::script" method="post">
+ <div>
+  <input type="hidden" name="cmd" value="attach" />
+  <input type="hidden" name="pcmd" value="post" />
+  <input type="hidden" name="refer" value="$s_page" />
+  <input type="hidden" name="mypage" value="$page" />
+  <input type="hidden" name="max_file_size" value="$maxsize" />
+  $navi
+  <span class="small">
+   $msg_maxsize
+  </span><br />
+  $::resource{'attach_msg_file'}: <input type="file" name="attach_file" />
+  $pass
+  <input type="submit" value="$::resource{'btn_upload'}" />
+ </div>
+</form>
+EOD
+}
+
+sub plugin_attach_action
+{
+	# backward compatible
+	if ($::form{'openfile'} ne '') {
+		$::form{'pcmd'} = 'open';
+		$::form{'file'} = $::from{'openfile'};
+	}
+	if ($::form{'delfile'} ne '') {
+		$::form{'pcmd'} = 'delete';
+		$::form{'file'} = $::form{'delfile'};
+	}
+
+	my $age = $::form{age} ? $::form{age} : 0;
+	my $pcmd = $::form{pcmd} ? $::form{pcmd} : '';
+
+	# Authentication
+#	if ($::form{refer} ne '') { #and is_pagename($vars['refer'])) {
+#		my @read_cmds = ('info','open','list');
+#		in_array($pcmd,$read_cmds) ?
+#			check_readable($vars['refer']) : check_editable($vars['refer']);
+#	}
+
+	# Upload
+	if ($::form{attach_file} ne '') {
+	#	my $pass = $::form{pass} ? md5_hex($::form{pass}) : '';
+		return &attach_upload($::form{attach_file}, $::form{refer}, $::form{pass});
+	}
+
+	if ($pcmd eq 'info') {
+		return &attach_info;
+	} elsif ($pcmd eq 'delete') {
+		return &attach_delete;
+	} elsif ($pcmd eq 'open') {
+		return &attach_open;
+	} elsif ($pcmd eq 'list') {
+		return &attach_list;
+	} elsif ($pcmd eq 'freeze') {
+		return &attach_freeze(1);
+	} elsif ($pcmd eq 'unfreeze') {
+		return &attach_freeze(0);
+	} elsif ($pcmd eq 'upload') {
+		return &attach_showform;
+	}
+	return &attach_list if ($::form{mypage} eq '' or !$::database{$::form{mypage}});
+	return ('msg'=>$::form{mypage}, 'body'=>&attach_form);
+}
+
+# 詳細フォームを表示
+sub attach_info
+{
+	my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age});
+	return $obj->getstatus() ? $obj->info()
+		: ('msg'=>$::form{refer}, 'body'=>"error:" . $::resource{attach_err_notfound});
+}
+
+# 削除
+sub attach_delete
+{
+	if ($::file_uploads == 2 && !&valid_password($::form{pass})) {
+		return ('msg'=>$::form{refer}, 'body'=>$::resource{attach_err_password});
+	}
+
+	my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age});
+	return $obj->getstatus()
+		? $obj->delete()
+		: ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_notfound});
+}
+
+# ダウンロード
+sub attach_open
+{
+	my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age});
+	return $obj->getstatus() ? $obj->open()
+		: ('msg'=>$::form{refer}, 'body'=>"error:" . $::resource{attach_err_notfound});
+}
+
+# 一覧取得
+sub attach_list
+{
+	my $refer = $::form{refer};
+	my $obj = new AttachPages($refer);
+	my $msg = $::resource{$refer eq '' ? 'attach_msg_listall' : 'attach_msg_listpage'};
+	my $body = $obj->toString(0, 1);
+	undef $obj;
+	return ('msg'=>$msg,'body'=>$body);
+}
+
+# ファイルアップロード
+sub attach_upload
+{
+	my ($filename, $page, $pass) = @_;
+
+	if ($::file_uploads == 2 && !&valid_password($pass)) {
+		return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_password});
+	}
+	my ($parsename, $path, $ffile);
+	$parsename = $filename;
+	$parsename =~ s#\\#/#g;	# \を/に変換
+	$parsename =~ s/^http:\/\///;
+	$parsename =~ /([^:\/]*)(:([0-9]+))?(\/.*)?$/;
+	$path = $4 || '/';
+	$path =~ /(.*\/)(.*)/;			#$ffileには直下のファイル名
+	$ffile = $2;			#ファイル名が無い場合'/')
+	$ffile =~ s/#.*$//;		# #はページ内リンクなので、削除する
+
+	my $obj = new AttachFile($page, $ffile);
+	if ($obj->{exist}) {
+		return ('msg'=>$::resource{_attach_err_exists});
+	}
+	#ファイルの保存
+	unless (open (FILE, ">" . $obj->{filename})) {
+		print "サーバ側の保存ファイルの作成に失敗しました。: $!\n";
+		exit;
+	}
+	binmode(FILE);
+	my $fsize = 0;
+	my ($byte, $buffer);
+	while ($byte = read($filename, $buffer, 1024)) {
+		print FILE $buffer;
+		$fsize += $byte;
+		if ($fsize > $::max_filesize) {
+			close FILE;
+			unlink $obj->{filename};
+			return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_exceed});
+		}
+	}
+	close FILE;
+	return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_msg_uploaded});
+
+#	$obj->getstatus();
+#	$obj->status['pass'] = ($pass !== TRUE and $pass !== NULL) ? $pass : '';
+#	$obj->putstatus();
+
+#	return array('result'=>TRUE,'msg'=>$_attach_messages['msg_uploaded'])
+#	# パーミッションを変更 
+#	chmod (0666, "$Temp/$basename"); 
+}
+
+# ファイル名からmimeタイプ取得。
+sub attach_mime_content_type
+{
+	my $filename = shift;
+	my $mime_type;
+	foreach (keys %mime) {
+		next unless ($_ && defined($mime{$_}));
+		if ($filename =~ /$_$/i) {
+			$mime_type = $mime{$_};
+			last;
+		}
+	}
+	return ($mime_type) ? $mime_type : 'application/octet-stream'; #default
+}
+
+
+# php互換関数。
+sub md5_file {
+	my ($path) = @_;
+	open(FILE, $path);
+	binmode(FILE);
+	my $contents;
+	read(FILE, $contents, 16384);
+	close(FILE);
+	return md5_hex($contents);
+}
+
+#----------------------------------------------------
+# 1ファイル単位のコンテナ
+package AttachFile;
+
+sub new
+{
+	my $this = bless {};
+	shift;
+	$this->{page} = shift;	# page
+	$this->{file} = shift;	# file
+	$this->{age}  = shift;	# age;
+	$this->{basename} = "$::upload_dir/"
+		. &::dbmname($this->{page}) . '_' . &::dbmname($this->{file});
+	$this->{filename} = $this->{basename} . ($this->{age} ? '.' . $this->{age} : '');
+	$this->{exist} = (-e $this->{filename}) ? 1 : 0;
+	$this->{logname}  = $this->{basename} . ".log";
+
+	$this->{time} = (stat($this->{filename}))[10];
+	$this->{md5hash} = ($this->{exist} == 1) ? &::md5_file($this->{filename}) : '';
+	return $this;
+}
+
+# 添付ファイルのオープン
+sub open
+{
+	my $this = shift;
+	my $query = new CGI;
+
+	print $query->header(
+		-type=>"$this->{type}",
+		-Content_disposition=>"filename=$this->{file}",
+		-Content_length=>$this->{size},
+		-expires=>"now",
+		-P3P=>""
+	);
+	open(FILE, $this->{filename}) || die $!;
+	binmode(FILE);
+	my $buffer;
+	print $buffer while (read(FILE, $buffer, 4096));
+	close(FILE);
+	exit;
+}
+
+# 情報表示
+sub info
+{
+	my $this = shift;
+
+	my $msg_delete = '<input type="radio" name="pcmd" value="delete" />'
+		 . $::resource{attach_msg_delete} . $::resource{attach_msg_require} . '<br />';
+
+	my $info = $this->toString(1, 0);
+	my %retval;
+
+	$retval{msg} = $::resource{attach_msg_info};
+	$retval{body} =<<EOD;
+<p class="small">
+ [<a href="$::script?cmd=attach&amp;mypage=$::form{mypage}&amp;pcmd=list&amp;refer=$::form{refer}">$::resource{attach_msg_listpage}</a>]
+ [<a href="$::script?cmd=attach&amp;pcmd=list">$::resource{attach_msg_listall}</a>]
+</p>
+<dl>
+ <dt>$info</dt>
+ <dd>$::resource{attach_msg_page}:$::form{refer}</dd>
+ <dd>$::resource{attach_msg_filename}:$this->{filename}</dd>
+ <dd>$::resource{attach_msg_md5hash}:$this->{md5hash}</dd>
+ <dd>$::resource{attach_msg_filesize}:$this->{size_str} ($this->{size} bytes)</dd>
+ <dd>Content-type:$this->{type}</dd>
+ <dd>$::resource{attach_msg_date}:$this->{time_str}</dd>
+</dl>
+EOD
+
+	if ($::file_uploads) {
+		my $msg_pass;
+
+		if ($::file_uploads == 2) {
+			$msg_pass = $::resource{attach_msg_password}
+			. '<input type="password" name="pass" size="8" />';
+		}
+
+		my $s_page = &::htmlspecialchars($this->{page});
+
+		$retval{body} .=<<EOD;
+<hr />
+<form action="$::script" method="get">
+ <div>
+  <input type="hidden" name="cmd" value="attach" />
+  <input type="hidden" name="mypage" value="$this->{page}" />
+  <input type="hidden" name="refer" value="$s_page" />
+  <input type="hidden" name="file" value="$this->{file}" />
+  <input type="hidden" name="age" value="$this->{age}" />
+  $msg_delete
+  $msg_pass
+  <input type="submit" value="$::resource{attach_btn_submit}" />
+ </div>
+</form>
+EOD
+	}
+	return %retval;
+}
+
+sub delete
+{
+	my $this = shift;
+
+	# バックアップ
+	if ($this->{age}) {
+		unlink($this->{filename});
+	} else {
+		my $age;
+		do {
+			$age = ++$this->{age};
+		} while (-e $this->{basename} . '.' . $age);
+
+		if (!rename($this->{basename}, $this->{basename} . '.' . $age)) {
+			# rename 失敗
+			return ('msg'=>$this->{page}, 'body'=>$::resource{attach_err_delete});
+		}
+	}
+	return ('msg'=>$this->{page}, 'body'=>$::resource{attach_msg_deleted});
+}
+
+# ステータス取得
+sub getstatus
+{
+	my $this = shift;
+
+	return 0 if (!$this->{exist});
+
+	# ログファイル取得
+	if (-e $this->{logname}) {
+	#	$data = file($this->logname);
+	#	foreach ($this->status as $key=>$value)
+	#	{
+	#		$this->status[$key] = chop(array_shift($data));
+	#	}
+	#	$this->status['count'] = explode(',',$this->status['count']);
+	}
+#	$this->time_str = get_date('Y/m/d H:i:s',$this->time);
+	my ($sec, $min, $hour, $day, $mon, $year) = localtime($this->{time});
+	$this->{time_str} = sprintf("%d/%02d/%02d %02d:%02d:%02d",
+			$year + 1900, $mon + 1, $day, $hour, $min, $sec);
+	$this->{size} = -s $this->{filename};
+	$this->{size_str} = sprintf('%01.1f', $this->{size}/1000) . 'KB';
+	$this->{type} = &::attach_mime_content_type($this->{file});
+	return 1;
+}
+
+# ステータス保存
+sub putstatus
+{
+#	$this->status['count'] = join(',',$this->status['count']);
+#	$fp = fopen($this->logname,'wb')
+#		or die_message('cannot write '.$this->logname);
+#	flock($fp,LOCK_EX);
+#	foreach ($this->status as $key=>$value)
+#	{
+#		fwrite($fp,$value."\n");
+#	}
+#	flock($fp,LOCK_UN);
+#	fclose($fp);
+}
+
+# ファイルのリンクを作成
+sub toString {
+	my $this = shift;
+	my $showicon = shift;
+	my $showinfo = shift;
+
+	my $body;
+	my $finfo = "&file=" . &::encode($this->{file})
+		. "&mypage=" . &::encode($::form{mypage})
+		. "&refer="  . &::encode($this->{page})
+		. ($this->{age} >= 1 ? "&age=$this->{age}" : "");
+
+	$body .= $::file_icon if ($showicon);
+	$body .= "<a href=\"$::script?cmd=attach&pcmd=open$finfo\">$this->{file} "
+		. ($this->{age} >= 1 ? "(Backup No.$this->{age})" : "") . "</a>";
+
+	if ($showinfo) {
+		$body .= " [<a href=\"$::script?cmd=attach&pcmd=info"
+		. "$finfo\">$::resource{attach_msg_description}</a>]";
+	}
+	return $body;
+}
+
+#----------------------------------------------------
+# ファイル一覧コンテナ作成
+package AttachFiles;
+my %files;
+
+sub new {
+	my $this = bless {};
+	shift;
+	$this->{page} = shift;	# page
+	return $this;
+}
+
+sub add {
+	my $this = shift;
+	my $file = shift;
+	my $age  = shift;
+
+	# 美しくないけど3次元配列
+	$files{$this->{page}}{$file}{$age} = new AttachFile($this->{page}, $file, $age);
+}
+
+# ページ単位の一覧表示
+sub toString {
+	my $this = shift;
+	my $flat = shift;
+	my $page = $this->{page};
+
+	my $ret = "";
+	my $files = $this->{files};
+	$ret .= "<li>" . &::make_link($this->{page}) . "\n<ul>\n";
+	my ($target, $notarget, $backup);
+	foreach my $key (sort keys %{$files{$page}}) {
+		$target = '';
+		$notarget = '';
+		$backup = '';
+		foreach (sort keys %{$files{$page}{$key}}) {
+			if ($_ >= 1) {
+				$backup .= "<li>" . $files{$page}{$key}{$_}->toString(0, 1) . "</li>\n";
+				$notarget = $files{$page}{$key}{$_}->{file};
+			} else {
+				$target .= $files{$page}{$key}{$_}->toString(0, 1);
+			}
+		}
+		$ret .= "<li>" . ($target ? $target : $notarget);
+		$ret .= "\n<ul>\n$backup\n</ul>\n" if ($backup);
+		$ret .= "</li>\n";
+	}
+	return $ret . "</ul>\n</li>\n";
+}
+
+sub to_flat {
+	my $this = shift;
+	my $flat = shift;
+	my $ret = "";
+	my %files = $this->{files};
+	foreach my $key (sort keys %files) {
+		foreach (sort keys %{$files{$key}}) {
+			$ret .= $key . "." . $_ . $files{$key}{$_}->toString(1, 1) . ' ';
+		}
+	}
+	return $ret;
+}
+
+#-------------------------------------------------
+# ページコンテナ作成
+package AttachPages;
+
+my %pages;
+
+# ページコンテナ作成
+sub new {
+	my $this = bless {};
+	shift;
+	$this->{page} = shift;
+	my $age = shift;
+
+	opendir(DIR, "$::upload_dir/")
+		or die('directory ' . $::upload_dir . ' is not exist or not readable.');
+	my @file = readdir(DIR);
+	closedir(DIR);
+
+	my $page_pattern = ($this->{page} eq '')
+		? '(?:[0-9A-F]{2})+' : &::dbmname($::form{mypage});
+	my $age_pattern = ($age eq '') ? '(?:\.([0-9]+))?' : ($age ? "\.($age)" : '');
+	my $pattern = "^($page_pattern)_((?:[0-9A-F]{2})+)$age_pattern\$";
+
+	my ($_page, $_file, $_age);
+
+	foreach (@file) {
+		next if (!/$pattern/);
+		$_page = pack("H*", $1);
+		$_file = pack("H*", $2);
+		$_age = $3 ? $3 : 0;
+
+		$pages{$_page} = new AttachFiles($_page) if (!exists($pages{$_page}));
+		$pages{$_page}->add($_file, $_age);
+	}
+	return $this;
+}
+
+# 全ページの添付一覧表示
+sub toString {
+	my $this = shift;
+	my $page = shift;
+	my $flat = shift;
+
+	# page exist check;
+	my $body = "";
+	foreach (sort keys %pages) {
+		$body .= $pages{$_}->toString($flat);
+	}
+	return "\n<div id=\"body\">" . $::resource{attach_err_noexist} . "</div>\n"
+			if ($body eq "");
+	return "\n<ul>\n$body</ul>\n";
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/br.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/br.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/br.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,30 @@
+##
+# 文章中で改行を行う。
+# :書式|
+#  #br
+#  &br;
+# @author Nekyo.(http://nekyo.hp.infoseek.co.jp/)
+# @version 1.00
+
+use strict;
+package br;
+
+sub plugin_block {
+	return &plugin_inline;
+}
+
+sub plugin_inline {
+	return qq(<br />);
+}
+
+sub plugin_usage {
+	return {
+		name => 'br',
+		version => '1.00',
+		author => 'Nekyo',
+		syntax => '&br',
+		description => 'line break.',
+		example => '&br',
+	};
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,311 @@
+##
+# バグレポートの入力フォームを設置する。
+# :書式|
+#  #bugtrack([[ページ名][カテゴリー1…カテゴリーn]])
+# -ページ名はバグレポートとして作成されるページの親階層のページ名を指定。省略時は設置ページとなる。
+# バグレポートは指定したページの子階層に自動的に番号が振られてページが作成される。(ページ名/1,ページ名/2,...)
+# -カテゴリーはバグ対象となりうる要素を指定する。
+
+# Based on Pukiwiki BugTrackプラグイン (c)Y.MASUI GPL2 http:#masui.net/pukiwiki/
+# Special Thanks! kamo http://kamoland.com/
+# 
+# 変更履歴:
+#  2002.06.17: 作り始め
+#
+use strict;
+
+ @ bugtrack::priority_list = ('緊急','重要','普通','低');
+ @ bugtrack::state_list = ('提案','着手','CVS待ち','完了','保留','却下');
+ @ bugtrack::state_sort = ('着手','CVS待ち','保留','完了','提案','却下');
+ @ bugtrack::state_bgcolor = ('#ccccff','#ffcc99','#ccddcc','#ccffcc','#ffccff','#cccccc','#ff3333');
+
+$bugtrack::title = '$1 Bugtrack Plugin';
+$bugtrack::base = 'ページ';
+$bugtrack::summary = 'サマリ';
+$bugtrack::priority = '優先順位';
+$bugtrack::state = '状態';
+$bugtrack::name = '投稿者';
+$bugtrack::date = '投稿日';
+$bugtrack::body = 'メッセージ';
+$bugtrack::category = 'カテゴリー';
+$bugtrack::pagename = 'ページ名';
+$bugtrack::pagename_comment = '<small>空欄のままだと自動的にページ名が振られます。</small>';
+$bugtrack::version_comment = '<small>空欄でも構いません</small>';
+$bugtrack::version = 'バージョン';
+$bugtrack::submit = '追加';
+
+sub plugin_bugtrack_action
+{
+	if ($::form{mode} eq 'submit') {
+		&plugin_bugtrack_write(
+			$::form{base}, $::form{pagename}, $::form{summary}, $::form{name}, $::form{priority},
+			$::form{state}, $::form{category}, $::form{version}, $::form{body}
+		);
+		exit;
+	}
+	return ('msg'=>$bugtrack::title, 'body'=>&plugin_bugtrack_print_form($::form{category}));
+}
+
+sub plugin_bugtrack_print_form
+{
+	my ($base, @category) = @_;
+	my $select_priority = '';
+	my $i;
+	for ($i = 0; $i < @bugtrack::priority_list; ++$i) {
+		my $selected = ($i < @bugtrack::lugin_priority_list - 1) ? '' : ' selected="selected"';
+		$select_priority .= "<option value=\"$bugtrack::priority_list[$i]\"$selected>$bugtrack::priority_list[$i]</option>\n";
+	}
+
+	my $select_state = '';
+	for ($i = 0; $i < @bugtrack::state_list; ++$i) {
+		$select_state .= "<option value=\"$bugtrack::state_list[$i]\">$bugtrack::state_list[$i]</option>\n";
+	}
+
+	my $encoded_category = '<input name="category" type="text" />';
+	if (@category != 0) {
+		$encoded_category = '<select name="category">';
+		foreach my $_category (@category) {
+			my $s_category = &htmlspecialchars($_category);
+			$encoded_category .= "<option value=\"$s_category\">$s_category</option>\n";
+		}
+		$encoded_category .= '</select>';
+	}
+
+	my $s_base = &htmlspecialchars($base);
+	my $body = <<"EOD";
+<form action="$::script" method="post">
+ <table border="0">
+  <tr>
+   <th>$bugtrack::name</th>
+   <td><input name="name" size="20" type="text" /></td>
+  </tr>
+  <tr>
+   <th>$bugtrack::category</th>
+   <td>$encoded_category</td>
+  </tr>
+  <tr>
+   <th>$bugtrack::priority</th>
+   <td><select name="priority">$select_priority</select></td>
+  </tr>
+  <tr>
+   <th>$bugtrack::state</th>
+   <td><select name="state">$select_state</select></td>
+  </tr>
+  <tr>
+   <th>$bugtrack::pagename</th>
+   <td><input name="pagename" size="20" type="text" />$bugtrack::pagename_comment</td>
+  </tr>
+  <tr>
+   <th>$bugtrack::version</th>
+   <td><input name="version" size="10" type="text" />$bugtrack::version_comment</td>
+  </tr>
+  <tr>
+   <th>$bugtrack::summary</th>
+   <td><input name="summary" size="60" type="text" /></td>
+  </tr>
+  <tr>
+   <th>$bugtrack::body</th>
+   <td><textarea name="body" cols="60" rows="6"></textarea></td>
+  </tr>
+  <tr>
+   <td colspan="2" align="center">
+    <input type="submit" value="$bugtrack::submit" />
+    <input type="hidden" name="cmd" value="bugtrack" />
+    <input type="hidden" name="mode" value="submit" />
+    <input type="hidden" name="base" value="$s_base" />
+   </td>
+  </tr>
+ </table>
+</form>
+EOD
+	return $body;
+}
+
+sub plugin_bugtrack_template
+{
+	my ($base, $summary, $name, $priority, $state, $category, $version, $body) = @_;
+
+	$name = &::armor_name($name);
+	$base = &::armor_name($base);
+	return <<"EOD";
+*$summary
+
+-$bugtrack::base: $base
+-$bugtrack::name: $name
+-$bugtrack::priority: $priority
+-$bugtrack::state: $state
+-$bugtrack::category: $category
+-$bugtrack::date: @{[&get_now]}
+-$bugtrack::version: $version
+
+**$bugtrack::body
+$body
+----
+
+#comment
+EOD
+}
+
+sub plugin_bugtrack_write
+{
+	my ($base, $pagename, $summary, $name, $priority, $state, $category, $version, $body) = @_;
+
+	$base = &::unarmor_name($base);
+	$pagename = &::unarmor_name($pagename);
+
+	my $postdata = &plugin_bugtrack_template($base, $summary, $name, $priority, $state, $category, $version, $body);
+
+	my $page;
+	my $i = 0;
+	do {
+		$i++;
+		$page = "$base/$i";
+	} while ($::database{$page});
+
+	if ($pagename == '') {
+		$::form{mypage} = $page;
+		$::form{mymsg} = $postdata;
+		$::form{mytouch} = 'on';
+		&do_write;
+		exit;
+	} else {
+	#	$pagename = get_fullname($pagename,$base);
+		# すでにページが存在するか、無効なページ名が指定された
+	#	if (is_page($pagename) or !$::database{$pagename}) {
+			# ページ名をデフォルトに戻す
+			$pagename = $page;
+	#	} else {
+	#		page_write($page,"move to [[$pagename]]");
+	#	}
+	#	page_write($pagename,$postdata);
+	}
+
+	return $page;
+}
+
+sub plugin_bugtrack_convert
+{
+	my $base = $::form{mypage};
+	my @category = split(/,/, shift);
+	if (@category > 0) {
+		my $_base = &::unarmor_name(shift(@category));
+		if ($::database{$_base}) {
+			$base = $_base;
+		}
+	}
+	return &plugin_bugtrack_print_form($base, @category);
+}
+
+
+sub plugin_bugtrack_pageinfo
+{
+	my ($page, $no) = @_;
+
+	if (@_ == 1) {
+		$no = ($page =~ /\/([0-9]+)$/) ? $1 : 0;
+	}
+	my $body = $::database{$page};
+
+	if ($body =~ /move\s*to\s*($::WikiName|$::InterWikiName|\[\[$::BracketName\]\])/) {
+		return &plugin_bugtrack_pageinfo(&::unarmor_name($1), $no);
+	}
+	my ($summary, $name, $priority, $state, $category);
+	$summary = $name = $priority = $state = $category = 'test';
+	my @itemlist = ($bugtrack::summary, $bugtrack::name, $bugtrack::priority, $bugtrack::state, $bugtrack::category);
+	foreach my $itemname (@itemlist) {
+		if ($body =~ /-\s*$itemname\s*:\s*(.*)\s*/) {
+			if ($itemname eq $bugtrack::name) {
+				$name = &htmlspecialchars(&::unarmor_name($1));
+			} elsif ($itemname eq $bugtrack::summary) {
+				$summary = &::htmlspecialchars($1);
+			} elsif ($itemname eq $bugtrack::priority) {
+				$priority = &::htmlspecialchars($1);
+			} elsif ($itemname eq $bugtrack::state) {
+				$state = &::htmlspecialchars($1);
+			} elsif ($itemname eq $bugtrack::category) {
+				$category = &::htmlspecialchars($1);
+			}
+		}
+	}
+
+	if ($body =~ /\*([^\n]+)/) {
+		$summary = $1;
+	}
+	return join('<>', ($page, $no, $summary, $name, $priority, $state, $category));
+}
+
+sub plugin_bugtrack_list_convert
+{
+	my ($_page) = split(',', shift);
+	my $page = $::form{mypage};
+
+	# 引数で指定されたページが存在したら、そのページを使用する。
+	$page = $_page if ($::database{$_page});
+
+	my @data = ();
+	my $pattern = "$page/";
+	my $pattern_len = length($pattern);
+	my ($line, $i);
+
+	foreach $page (keys %::database) {
+		if (index($page, $pattern) == 0 && substr($page, $pattern_len) =~ /[1-9][0-9]*/) {
+			$line = &plugin_bugtrack_pageinfo($page);
+			push(@data, $line);
+		}
+	}
+
+	my @table;
+	for ($i = 0; $i < @bugtrack::state_list; $i++) {
+		$table[$i] = '';
+	}
+
+	foreach $line (@data) {
+		my ($page, $no, $summary, $name, $priority, $state, $category) = split(/<>/, $line);
+		my $state_no = $#bugtrack::state_list;
+		for ($i = 0; $i <= $#bugtrack::state_sort; $i++) {
+			if ($bugtrack::state_sort[$i] eq $state) {
+				$state_no = $i;
+				last;
+			}
+		}
+		my $page_link = &::make_link($page);
+		my $bgcolor = $bugtrack::state_bgcolor[$state_no];
+		my $row = <<"EOD";
+ <tr>
+  <td style="background-color:$bgcolor">$page_link</td>
+  <td style="background-color:$bgcolor">$state</td>
+  <td style="background-color:$bgcolor">$priority</td>
+  <td style="background-color:$bgcolor">$category</td>
+  <td style="background-color:$bgcolor">$name</td>
+  <td style="background-color:$bgcolor">$summary</td>
+ </tr>
+EOD
+		$table[$state_no] .= "$no<>$row\n\n";
+	}
+	my $table_html = <<"EOD";
+<table border="1">
+ <tr>
+  <th>&nbsp;</th>
+  <th>$bugtrack::state</th>
+  <th>$bugtrack::priority</th>
+  <th>$bugtrack::category</th>
+  <th>$bugtrack::name</th>
+  <th>$bugtrack::summary</th>
+ </tr>
+EOD
+
+	for ($i = 0; $i <= $#bugtrack::state_list; $i++) {
+		my (%rowlist) = {};
+		foreach my $tab (split(/\n\n/, $table[$i])) {
+			my($no, $row) = split(/<>/, $tab);
+			$rowlist{$no} = $row;
+		}
+		my (@newkeys) = sort {$b <=> $a} keys(%rowlist);
+		foreach my $newkey (@newkeys) {
+			$table_html .= "$rowlist{$newkey}\n";
+		}
+	}
+	return $table_html . "</table>";
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,9 @@
+##
+# バグレポートを一覧表示する。
+# :書式|
+#  #bugtrack_list([ページ名])
+# -ページ名はバグレポートとして作成されるページの親階層のページ名を指定。省略時は設置ページとなる。~
+# bugtrackプラグインの機能を使用しているため、bugtrackプラグイン必須。
+
+require $::plugin_dir . '/bugtrack.inc.pl';
+1;
Index: PyukiWiki-Nekyo/019/plugin/calendar.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/calendar.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/calendar.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,146 @@
+##
+# カレンダーを設置する。
+# :書式|
+#  #calendar([{[ページ名],[年月]}])
+# -ページ名を指定する。省略時は設置ページとなる。
+# -年月は表示カレンダーの西暦と月をyyyymm形式で指定する。省略時は現在年月。
+
+# calendar.inc.pl v0.0.3 cooked up by Birgus-Latro.
+# for "PyukiWiki" copyright 2004 by Nekyo.
+# based on calendar.inc.php  v1.18  2003/06/04 14:20:36 arino.
+#          calendar2.inc.php v1.20  2003/06/03 11:59:07 arino.
+#          calendar.pl       v1.2                       Seiji Zenitani.
+use strict;
+use Time::Local;
+
+sub plugin_calendar_convert {
+	my ($page, $arg_date) = split(/,/, shift);
+	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
+	my ($disp_wday,$today,$start,$end,$i,$label,$cookedpage,$d);
+	my ($prefix,$splitter);
+	my $empty = '&nbsp;';
+	my $calendar = "";
+
+	($sec, $min, $hour, $mday, $mon, $year) = localtime();
+	$today = ($year+1900)*10000 + ($mon+1)*100 + $mday;
+
+	if    ($page eq '') {
+		$prefix = $::form{mypage};
+		$splitter = '/';
+	}
+	elsif ($page eq '*') {
+		$prefix = '';
+		$splitter = '';
+	}
+	else {
+		$prefix = $page;
+		$splitter = '/';
+	}
+	$page = &htmlspecialchars($prefix);
+	if ($page eq '') {
+		$cookedpage = '*';
+	} else {
+		$cookedpage = &encode($page);
+	}
+
+	if ($arg_date =~ /^(\d{4})[^\d]?(\d{1,2})$/ ) {
+		$year = $1 - 1900;
+		$mon = ($2-1) % 12;
+	}
+	my $disp_year  = $year+1900;
+	my $disp_month = $mon+1;
+
+	my $start_time = timelocal(0,0,0,1,$mon,$year);
+	($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($start_time);
+	$label = "$disp_year.$disp_month";
+	$start = ($year+1900)*10000 + ($mon+1)*100 + $mday;
+
+	if ( $mon == 11 ) {
+		$end = ($year+1900)*10000 + ($mon+1)*100 + 31;
+	} else {
+		my $end_time = timelocal(0,0,0,1,$mon+1,$year) - 24*60*60;
+		($sec, $min, $hour, $mday, $mon, $year ) = localtime($end_time);
+		$end = ($year+1900)*10000 + ($mon+1)*100 + $mday;
+	}
+
+	my $pagelink;
+	if ($::database{$page}) {
+		$pagelink = qq(<br />[<a title="$page" href="$::script?$cookedpage">$page</a>]);
+	} elsif ($page eq '') {
+		$pagelink = '';
+	} else {
+		$pagelink = qq(<br />[$page<a title="$::resource{editthispage}" class="editlink" href="$::script?cmd=adminedit&amp;mypage=$cookedpage">?</a>]);
+	}
+
+	my $prev_date_str = ($disp_month ==  1)? sprintf('%04d%02d',$disp_year - 1,12) : sprintf('%04d%02d',$disp_year,$disp_month - 1);
+	my $next_date_str = ($disp_month == 12)? sprintf('%04d%02d',$disp_year + 1, 1) : sprintf('%04d%02d',$disp_year,$disp_month + 1);
+
+	$calendar =<<"END";
+<table class="style_calendar" summary="calendar body">
+<tr>
+<td class="style_td_caltop" colspan="7">
+  <a href="$::script?cmd=calendar&amp;mymsg=$cookedpage&amp;date=$prev_date_str">&lt;&lt;</a>
+  <strong>$label</strong>
+  <a href="$::script?cmd=calendar&amp;mymsg=$cookedpage&amp;date=$next_date_str">&gt;&gt;
+  $pagelink</td>
+</tr>
+<tr>
+<td class="style_td_week">日</td>
+<td class="style_td_week">月</td>
+<td class="style_td_week">火</td>
+<td class="style_td_week">水</td>
+<td class="style_td_week">木</td>
+<td class="style_td_week">金</td>
+<td class="style_td_week">土</td>
+</tr>
+<tr>
+END
+
+	for ( $i = 0; $i < $wday; $i++ ) {
+		$calendar .= "<td class=\"style_td_blank\">$empty</td>";
+	}
+	my $style = '';
+	for ( $i=$start; $i<=$end; $i++ ) {
+		$d = $i % 100;
+		$disp_wday = ($wday + $i - $start) % 7;
+		my $pagename = sprintf "%s%s%04d-%02d-%02d", $page, $splitter, $disp_year, $disp_month, $d;
+		my $cookedname = &encode($pagename);
+
+		if (($disp_wday == 0) && ($i > $start)) {
+ 			$calendar .= "</tr>\n<tr>\n";
+		}
+
+		if ( $i == $today ) {		# today
+			$style = 'style_td_today';
+		} elsif ($disp_wday == 0) {	# Sunday 
+			$style = 'style_td_sun';
+		} elsif ($disp_wday == 6) {	# Saturday 
+			$style = 'style_td_sat';
+		} else {
+			$style = 'style_td_day';
+		}
+
+		if ($::database{$pagename}) {
+			$calendar .= qq(<td class="$style"><a title="$pagename" href="$::script?$cookedname"><strong>$d</strong></a></td>);
+		} else {
+			$calendar .= qq(<td class="$style"><a class="small" title="$::resource{editthispage}" href="$::script?cmd=adminedit&amp;mypage=$cookedname">$d</a></td>);
+		}
+	}
+	for ( $i = $disp_wday + 1; $i < 7; $i++ ) {
+		$calendar .= "<td class=\"style_td_blank\">$empty</td>";
+	}
+
+	$calendar .= "</tr>\n</table>\n";
+	return $calendar;
+}
+
+sub plugin_calendar_action {
+	my $page = &escape($::form{mymsg});
+	my $date = &escape($::form{date});
+	my $body = &plugin_calendar_convert(qq($page,$date));
+
+	my $yy = sprintf("%04d.%02d",substr($date,0,4),substr($date,4,2));
+	my $s_page = htmlspecialchars($page);
+	return ('msg'=>qq(calendar $s_page/$yy), 'body'=>$body);
+}
+1;
\ No newline at end of file
Index: PyukiWiki-Nekyo/019/plugin/clear.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/clear.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/clear.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,13 @@
+##
+# 他のプラグインで有効になったテキスト回り込み指定を解除する。
+# :書式|
+#  #clear
+# @author: Nanami <nanam****@daiba*****>
+
+use strict;
+package clear;
+
+sub plugin_inline {
+	return '<div class="clear"></div>';
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/color.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/color.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/color.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,38 @@
+##
+# 引数で指定したインライン要素の、文字色・背景色を指定する。
+# :書式|
+#  &color([文字色][,背景色]){文章};
+
+# @author nekyo.
+# @version 1.00
+use strict;
+package color;
+
+sub plugin_inline {
+	my @args = split(/,/, shift);
+	my $bgcolor = '';
+	my ($color, $bgcolor, $body);
+
+	if (@args == 3) {
+		$color = $args[0];
+		$bgcolor = $args[1];
+		$body = $args[2];
+		if ($body eq '') {
+			$body = $bgcolor;
+			$bgcolor = '';
+		}
+	} elsif (@args == 2) {
+		$color = $args[0];
+		$body = $args[1];
+	} else {
+		return '';
+	}
+	if ($color eq '' or $body eq '') {
+		return '';
+	}
+	if ($bgcolor ne '') {
+		$color .= ';background-color:'.$bgcolor;
+	}
+	return "<span style=\"color:$color\">$body</span>";
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/comment.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/comment.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/comment.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,111 @@
+##
+# コメント入力欄を表示する。
+# :書式|
+#  #comment({[above],[below],[nodate],[noname]})
+# -above - コメントを入力欄の上に追加する。
+# -below - コメントを入力欄の下に追加する。(default)
+# -nodate - コメントに挿入時刻を付加しない。(省略時は付加する。)
+# -noname - 記入者名の入力欄を非表示とする。(省略時は表示。)
+
+# Copyright(c) 2004 Nekyo.
+# v 0.0.3 - 2006/01/15 Tnx:Birgus-Latro
+# v 0.0.2 - 2004/10/28 Tnx:Birgus-Latro
+# v 0.0.1 - ProtoType
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+# Based on comment.inc.php by Mr.arino.
+# 1TAB=4Spaces
+use strict;
+
+my $comment_format = "\x08MSG\x08 -- \x08NAME\x08 \x08NOW\x08";
+
+sub plugin_comment_action {
+	my $comment = $::form{mymsg};
+
+	&::spam_filter($comment, 1);
+
+	my $lines = $::database{$::form{mypage}};
+	my @lines = split(/\r?\n/, $lines);
+	my $datestr = ($::form{nodate} == 1) ? '' : &get_now;
+	my $_name = " ";
+
+	if ($::form{myname}) {
+	#	&::spam_filter($::form{myname}, 0);
+		$_name = " ''[[$::form{myname}]]'' : ";
+	}
+	my $_now = "&new{$datestr};";
+	my $postdata = '';
+	my $_comment_no = 0;
+
+	$comment = $comment_format;
+	$comment =~ s/\x08MSG\x08/$::form{mymsg}/;
+	$comment =~ s/\x08NAME\x08/$_name/;
+	$comment =~ s/\x08NOW\x08/$_now/;
+	$comment = "-" . $comment;
+
+	foreach (@lines) {
+		if (/^#comment/ && (++$_comment_no == $::form{comment_no})) {
+			if ($::form{above} == 1) {
+				$_ = ($comment . "\n" . $_);
+			} else {
+				$_ .= ("\n" . $comment);
+			}
+		}
+		$postdata .= $_ . "\n";
+	}
+	if ($::form{mymsg}) {
+		$::form{mymsg} = $postdata;
+		$::form{mytouch} = 'on';
+
+		&do_write('FrozenWrite');
+	} else {
+		$::form{cmd} = 'read';
+		&do_read;
+	}
+	&close_db;
+	exit;
+}
+
+my $comment_no = 0;
+my %comment_numbers = {}; # Tnx:Birgus-Latro
+
+sub plugin_comment_convert {
+	my @argv = split(/,/, shift);
+
+	my $above = 1;
+	my $nodate = '';
+	my $nametags = $::resource{yourname} . '<input type="text" name="myname" value="" size="10">';
+
+	foreach (@argv) {
+		chomp;
+		if (/below/) {
+			$above = 0;
+		} elsif (/nodate/) {
+			$nodate = 1;
+		} elsif (/noname/) {
+			$nametags = '';
+		}
+	}
+	if (!exists $comment_numbers{$::form{mypage}}) { # Tnx:Birgus-Latro
+		$comment_numbers{$::form{mypage}} = 0;
+	}
+	$comment_no = ++$comment_numbers{$::form{mypage}};
+	my $escapedmypage = &htmlspecialchars($::form{mypage});
+	my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker);
+	return <<"EOD";
+<form action="$::script" method="post">
+ <div>
+   <input type="hidden" name="comment_no" value="$comment_no" />
+   <input type="hidden" name="cmd" value="comment" />
+   <input type="hidden" name="mypage" value="$escapedmypage" />
+   <input type="hidden" name="myConflictChecker" value="$conflictchecker" />
+   <input type="hidden" name="mytouch" value="on" />
+   <input type="hidden" name="nodate" value="$nodate" />
+   <input type="hidden" name="above" value="$above" />
+   $nametags
+   <input type="text" name="mymsg" value="" size="40" />
+   <input type="submit" value="$::resource{commentbutton}" />
+ </div>
+</form>
+EOD
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/contents.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/contents.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/contents.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,51 @@
+##
+# ページ中の見出し一覧を表示する。
+# :書式|
+#  #contents
+# pyukiwiki独自拡張~
+#  #contents([ページ])
+# で指定のページの見出し一覧を表示する。
+
+# @author nekyo.
+# @version 1.01
+# @license:GPL
+use strict;
+
+sub plugin_contents_convert {
+	my @args = &func_get_args(shift);
+	my $page;
+	if (@args > 0) {
+		$page = $args[0];
+		$::pushedpage = $page;
+	} else {
+		$page = $::form{mypage};
+	}
+	my ($txt) = $::database{$page};
+	my (@txt) = split(/\r?\n/, $txt);
+	my $tocnum = 0;
+	my (@tocsaved, @tocresult);
+	my $title;
+	my $nametag = ($::IsMenu == 1) ? "m" : "i";
+
+	foreach (@txt) {
+		chomp;
+		if (/^(\*{1,5})(.+)/) {
+			&back_push('ul', length($1), \@tocsaved, \@tocresult);
+			$title = &::inline($2);
+			$title =~ s/<[^>]+>//g;
+			push(@tocresult, qq(<li><a href="?)
+				# &::encode($::form{mypage})
+				. &::rawurlencode($::pushedpage eq '' ? $::form{mypage} : $::pushedpage)
+				. qq(#$nametag$tocnum">$title</a></li>\n));
+			$tocnum++;
+		}
+	}
+	push(@tocresult, splice(@tocsaved));
+	my $body = <<EOD;
+<div class="contents">
+<a id="contents_1"></a>
+EOD
+	$body .= join("\n", @tocresult) . "</div>\n";
+	return $body;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/counter.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/counter.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/counter.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,121 @@
+##
+# ページカウンタを設置する。
+# :書式|
+#  #counter
+#  &counter([total|today|yesterday]);
+# -total - 総参照回数。(デフォルト)
+# -today - 本日参照回数。
+# -yesterday − 昨日参照回数
+# @author nekyo.
+# @version 0.0.2
+
+sub plugin_counter_inline {
+	my $arg = shift;
+	my %counter = plugin_counter_get_count($::form{mypage});
+	my $count;
+	if ($arg =~/(today|yesterday)/i) {
+		$count = $counter{$arg};
+	} else {
+		$count = $counter{'total'}
+	}
+	return " $count";
+}
+
+sub plugin_counter_convert {
+	my %counter = plugin_counter_get_count($::form{mypage});
+	return <<"EOD";
+<div class="counter">
+Counter: $counter{'total'},
+today: $counter{'today'},
+yesterday: $counter{'yesterday'}
+</div>
+EOD
+}
+
+sub plugin_counter_get_count {
+	my $page = shift;
+
+	my ($mday, $mon, $year) = (localtime(time))[3..5];
+	$year += 1900;
+	$mon += 1;
+	my $date = "$year/$mon/$mday";
+
+	my %default = (
+		'total'     => 0,
+		'date'      => $date,
+		'today'     => 0,
+		'yesterday' => 0,
+		'ip'        => ''
+	);
+
+	my %counter = %default;
+
+	if (!&is_exist_page($page)) {
+		return %default;
+	}
+
+	$page =~ s/(\C)/unpack('H2', $1)/eg;
+
+	my $file = $::counter_dir . "/" . $page . $::counter_ext;
+
+	my @keys = keys(%default);
+	my $modify = 0;
+	if (-e $file) {
+		open(FILE, "+<$file") or return "Counter Conflict.<br />\n";
+		flock(FILE, 2);
+		$_ = <FILE>;
+		chomp;
+		$counter{'total'} = $_;
+		$_ = <FILE>;
+		chomp;
+		$counter{'date'} = $_;
+		$_ = <FILE>;
+		chomp;
+		$counter{'today'} = $_;
+		$_ = <FILE>;
+		chomp;
+		$counter{'yesterday'} = $_;
+		$_ = <FILE>;
+		chomp;
+		$counter{'ip'} = $_;
+	} else {
+		open(FILE, ">$file") or return "Counter Conflict.<br />\n";
+		flock(FILE, 2);
+		$counter{'date'} = "";
+	}
+
+	if ($counter{'date'} ne $default{'date'}) {
+		$modify = 1;
+		$counter{'ip'}        = $ENV{'REMOTE_ADDR'};
+		$counter{'date'}      = $default{'date'};
+		$counter{'yesterday'} = $counter{'today'};
+		$counter{'today'}     = 1;
+		$counter{'total'}++;
+	} elsif ($counter{'ip'} ne $ENV{'REMOTE_ADDR'}) {
+		$modify = 1;
+		$counter{'ip'}        = $ENV{'REMOTE_ADDR'};
+		$counter{'today'}++;
+		$counter{'total'}++;
+	}
+
+	if ($modify == 1) {
+		if (FILE) {
+			truncate(FILE, 0);	#
+			seek(FILE, 0, 0);	#
+		} else {
+			open(FILE, ">$file") or return "Counter Conflict.<br />\n";
+			flock(FILE, 2);
+		}
+		print FILE $counter{'total'} . "\n";
+		print FILE $counter{'date'} . "\n";
+		print FILE $counter{'today'} . "\n";
+		print FILE $counter{'yesterday'} . "\n";
+		print FILE $counter{'ip'} . "\n";
+	}
+	if (FILE) {
+		flock(FILE, 8);
+		close(FILE);
+	}
+	return %counter;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/diff.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/diff.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/diff.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,43 @@
+##
+# 指定ページの現内容と最後のバックアップ状態との差分を表示する。
+# :書式|
+#  ?cmd=diff&mypage=ページ名
+# -ページ名はエンコードされている必要がある。
+
+# diff Plugin
+# diff.inc.pl
+# Copyright(c) 2004 Nekyo.
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+# v0.2 BugFix $diffbase -> $::diffbase Tnx! Mr.Yashigani-modoki.
+# v0.1 Proto
+# 1TAB=4Spaces
+
+sub plugin_diff_action {
+	if (not &is_editable($::form{mypage})) {
+		&do_read;
+		&close_db;
+		exit;
+	}
+	&open_diff;
+	my $title = $::form{mypage};
+	$_ = &htmlspecialchars($::diffbase{$::form{mypage}});
+	&close_diff;
+	my $body = qq(<h3>$::resource{difftitle}</h3>);
+	$body .= qq($::resource{diffnotice});
+	$body .= qq(<pre class="diff">);
+	foreach (split(/\n/, $_)) {
+		if (/^\+(.*)/) {
+			$body .= qq(<b class="added">$1</b>\n);
+		} elsif (/^\-(.*)/) {
+			$body .= qq(<s class="deleted">$1</s>\n);
+		} elsif (/^\=(.*)/) {
+			$body .= qq(<span class="same">$1</span>\n);
+		} else {
+			$body .= qq|??? $_\n|;
+		}
+	}
+	$body .= qq(</pre>);
+	$body .= qq(<hr>);
+	return ('msg' => $title, 'body' => $body);
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/edit.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/edit.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/edit.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,115 @@
+##
+# ページ編集。
+# :書式|
+#  ?cmd=edit&mypage=ページ名
+# ページ名はエンコードされていなければならない。
+
+# @auther Nekyo (http://nekyo.hp.infoseek.co.jp)
+# @license: GPL2 and/or Artistic or each later version.
+# 1TAB=4Spaces
+use strict;
+
+sub plugin_edit_action {
+	my ($page) = &unarmor_name(&armor_name($::form{mypage}));
+	my $body;
+	if (not &is_editable($page)) {
+		$body .= qq(<p><strong>$::resource{cantchange}</strong></p>);
+	} elsif (&is_frozen($page)) {
+		$body .= qq(<p><strong>$::resource{cantchange}</strong></p>);
+	} else {
+		$body .= &editform($::database{$page},
+			&get_info($page, $::info_ConflictChecker), admin=>0);
+	}
+	return ('msg'=>$page, 'body'=>$body);
+}
+
+sub editform {
+	my ($mymsg, $conflictchecker, %mode) = @_;
+	my $frozen = &is_frozen($::form{mypage});
+	my $body = '';
+
+	if ($::form{mypreview}) {
+		if ($::form{mymsg}) {
+			unless ($mode{conflict}) {
+				$body .= qq(<h3>$::resource{previewtitle}</h3>\n);
+				$body .= qq($::resource{previewnotice}\n);
+				$body .= qq(<div class="preview">\n);
+				$body .= &text_to_html($::form{mymsg}, toc=>1);
+				$body .= qq(</div>\n);
+			}
+		} else {
+			$body .= qq($::resource{previewempty});
+		}
+		$mymsg = $::form{mymsg};
+	}
+	$mymsg =~ s/\n?#freeze\r?\n//g;
+	$mymsg = &htmlspecialchars($mymsg);
+
+	my $edit = $mode{admin} ? 'adminedit' : 'edit';
+	my $escapedmypage = &htmlspecialchars($::form{mypage});
+	my $escapedmypassword = &htmlspecialchars($::form{mypassword});
+	if ($::extend_edit) {
+		$body .= <<"EOD";
+<div>
+<a href="javascript:insTag('\\'\\'','\\'\\'','bold');"><b>B</b></a>
+<a href="javascript:insTag('\\'\\'\\'','\\'\\'\\'','italic');"><i>I</i></a>
+<a href="javascript:insTag('%%%','%%%','underline');"><u>U</u></a>
+<a href="javascript:insTag('%%','%%','delline');"><del>D</del></a>
+<a href="javascript:insTag('\\n-','','list');">
+<img src="$::image_dir/list.gif" alt="list" border="0" vspace="0"
+  hspace="1"></a>
+<a href="javascript:insTag('\\n+','','list');">
+<img src="$::image_dir/numbered.gif" alt="list" border="0" vspace="0"
+  hspace="1"></a>
+<a href="javascript:insTag('\\nCENTER:','\\n','centering');">
+<img src="$::image_dir/center.gif" alt="center" border="0" vspace="0"
+  hspace="1"></a>
+<a href="javascript:insTag('\\nLEFT:','\\n','left');">
+<img src="$::image_dir/left_just.gif" alt="left" border="0" vspace="0"
+  hspace="1"></a>
+<a href="javascript:insTag('\\nRIGHT:','\\n','right');">
+<img src="$::image_dir/right_just.gif" alt="right" border="0" vspace="0"
+  hspace="1"></a>
+<a href="javascript:insTag('\\n*','','title');"><b>H</b></a>
+<a href="javascript:insTag('[[',']]','wikipage');">[[]]</a>
+<a href="javascript:insTag('','~\\n','');">&lt;br&gt;</a>
+<a href="javascript:insTag('\\n----\\n','','');"><b>--</b></a>
+</div>
+EOD
+	}
+	$body .= <<"EOD";
+<form action="$::script" method="post" id="editform" name="editform">
+  @{[ $mode{admin} ? qq($::resource{frozenpassword} <input type="password" name="mypassword" value="$escapedmypassword" size="10"><br>) : "" ]}
+  <input type="hidden" name="myConflictChecker" value="$conflictchecker">
+  <input type="hidden" name="mypage" value="$escapedmypage">
+  <textarea cols="$::cols" rows="$::rows" name="mymsg">$mymsg</textarea><br />
+@{[
+  $mode{admin} ?
+  qq(
+  <input type="radio" name="myfrozen" value="1" @{[$frozen ? qq(checked="checked") : ""]}>$::resource{frozenbutton}
+  <input type="radio" name="myfrozen" value="0" @{[$frozen ? "" : qq(checked="checked")]}>$::resource{notfrozenbutton}<br>)
+  : ""
+]}
+@{[$mode{conflict} ? '' :
+  qq(
+  <input type="submit" name="mypreview_$edit" value="$::resource{previewbutton}">
+  <input type="submit" name="mypreview_write" value="$::resource{savebutton}">
+  <input type="checkbox" name="mytouch" value="on" checked="checked">$::resource{touch}&nbsp;
+  <input type="button" value="$::resource{cancel}" onClick="JavaScript:location.href='$::script?$::form{mypage}'">
+)]}
+</form>
+EOD
+	unless ($mode{conflict}) {
+		# Show the format rule.
+		#open(FILE, $::file_format) or &print_error("($::file_format)");
+		#my $content = join('', <FILE>);
+		#&code_convert(\$content, $::kanjicode);
+		#close(FILE);
+		#$body .= &text_to_html($content, toc=>0);
+		$body .= &text_to_html($::database{$::rule_page}, toc=>0);
+
+	}
+	return $body;
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/facemark.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/facemark.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/facemark.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,27 @@
+##
+# フェイスマークをイメージに変換する。(pyukiwiki独自プラグイン)~
+# :書式|
+#  #facemark(フェイスマーク)
+#  &facemark(フェイスマーク);
+# フェイスマーク機能を分離してプラグイン化しました。~
+# このプラグインを改造することで、フェイスマークを拡張できます。~
+# PyukiWiki Classic v0.1.7 or later
+use strict;
+
+sub plugin_facemark_inline {
+	return &plugin_facemark_convert(shift);
+}
+
+sub plugin_facemark_convert {
+	my $line = shift;
+	$line =~ s!\s(\:\)|\(\^\^\))! <img src="$::image_dir/face/smile.png" alt="$1" width="15" height="15"/>!g;
+	$line =~ s!\s(\:D|\(\^-\^\))! <img src="$::image_dir/face/bigsmile.png" alt="$1"  width="15" height="15"/>!g;
+	$line =~ s!\s(\:p|\:d)! <img src="$::image_dir/face/huh.png" alt="$1"  width="15" height="15"/>!g;
+	$line =~ s!\s(XD|X\(|\(\.\.;)! <img src="$::image_dir/face/oh.png" alt="$1" width="15" height="15"/>!g;
+	$line =~ s!\s(;\)|\(\^_-\))! <img src="$::image_dir/face/wink.png" alt="$1" width="15" height="15"/>!g;
+	$line =~ s!\s(;\(|\:\(|\(--;\))! <img src="$::image_dir/face/sad.png" alt="$1" width="15" height="15"/>!g;
+	$line =~ s!&(heart);!<img src="$::image_dir/face/heart.png" alt="$1" width="15" height="15"/>!g;
+	$line =~ s!\s\(\^\^;\)?! <img src="$::image_dir/face/worried.png" alt="$1" width="15" height="15"/>!g;
+	return $line;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/img.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/img.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/img.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,51 @@
+##
+# 画像を表示する。
+# :書式|
+#  #img(画像のURI[[,書式],altコメント])
+# 書式:r,right(右寄せ) or l,left(左寄せ) or module(index.cgi からの呼び出し)
+# or それ以外(クリア)~
+# v0.1.6b よりこの関数を index.cgi の img 変換でも呼び出すよう修正。(必須)
+
+######################################################################
+# img.inc.pl
+# PyukiClassic v 0.1.6b or laiter
+# Author: Nekyo
+# Copyright (C) 2004-2006 by Nekyo.
+# http://nekyo.hp.infoseek.co.jp/
+# License: GPL2
+######################################################################
+use strict;
+
+sub plugin_img_convert {
+	my ($uri, $align, $alt) = split(/,/, shift);
+	$uri   = &trim($uri);
+	$align = &trim($align);
+	$alt   = &trim($alt);
+	my $module = 0;
+	my $res = '';
+
+	if ($align =~ /^(r|right)/i) {
+		$align = 'right';
+	} elsif ($align =~ /^(l|left)/i) {
+		$align = 'left';
+	} elsif ($align =~ /^module$/i) {
+		$module = 1;
+	} else {
+		return '<div style="clear:both"></div>';
+	}
+#	if ($uri =~ /^(https?|ftp):/) {
+		if ($uri =~ /\.(gif|png|jpe?g)$/i) {
+			if ($module == 1) {
+				# 必要であれば、この部分を拡張する。
+				$res .= "<a href=\"$uri\"><img src=\"$uri\" /></a>\n";
+			} else {
+				$res .= "<div style=\"float:$align; padding:.5em 1.5em .5em 1.5em;\"><img src=\"$uri\"";
+				$res .= " alt=\"$alt\"" if ($alt ne '');
+				$res .= " /></div>\n";
+			}
+		}
+#	}
+	return $res;
+}
+1;
+__END__
Index: PyukiWiki-Nekyo/019/plugin/include.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/include.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/include.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,25 @@
+##
+# 記述した位置に引数で指定したページを表示する。
+# :書式|
+#  #include(ページ名)
+sub plugin_include_convert {
+	my $page = shift;
+	if ($page eq '') { return ''; }
+	my $body = '';
+	if (&is_exist_page($page)) {
+		my $rawcontent = $::database{$page};
+		$body = &text_to_html($rawcontent, toc=>1);
+		my $cookedpage = &encode($page);
+		my $link = "<a href=\"$::script?$cookedpage\">$page</a>";
+		if ($::form{mypage} eq $::MenuBar) {
+			$body = <<"EOD";
+<span align="center"><h5 class="side_label">$link</h5></span>
+<small>$body</small>
+EOD
+		} else {
+			$body = "<h1>$link</h1>\n$body\n";
+		}
+	}
+	return $body;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/index.html
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/index.html:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/index.html	Sun Mar 18 02:14:52 2012
@@ -0,0 +1 @@
+data files are placed here.
Index: PyukiWiki-Nekyo/019/plugin/list.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/list.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/list.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,46 @@
+##
+# ページ一覧を表示。
+# :書式|
+#  ?cmd=list
+
+# Copyright(c) 2004 Nekyo.
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+# v0.2 non_list
+# v0.1
+
+sub plugin_list_action {
+	my $navi = qq(<div id="body"><div id="top" style="text-align:center">);
+	my $body = qq(</div>);
+	my $prev = '';
+	my $char = '';
+	my $idx = 1;
+	my $page_num = 0;
+
+	foreach my $page (sort keys %::database) {
+		next if ($page =~ $::non_list);
+		$char = substr($page, 0, 1);
+		if (!($char =~ /[a-zA-Z0-9]/)) {
+			$char = "日本語";
+		}
+		if ($prev ne $char) {
+			if ($prev ne '') {
+				$navi .= " |\n";
+				$body .= "  </ul>\n </li>\n</ul>\n";
+			}
+			$prev = $char;
+			$navi .= qq(<a id="top_$idx" href="#head_$idx"><strong>$prev</strong></a>);
+			$body .= <<"EOD";
+<ul>
+ <li><a id="head_$idx" href="#top_$idx"><strong>$prev</strong></a>
+  <ul>
+EOD
+			$idx++;
+		}
+		$body .= qq(<li><a href="$::script?@{[&encode($page)]}">@{[&htmlspecialchars($page)]}</a>@{[&htmlspecialchars(&get_subjectline($page))]}</li>\n);
+		$page_num++;
+	}
+	$body .= qq(</li></ul>Total:) . $page_num . qq( Pages);
+
+	return ('msg' => $::IndexPage, 'body' => $navi . $body);
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/lookup.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/lookup.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/lookup.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,56 @@
+##
+# 記述位置に入力欄とボタンと表示し、ボタンを押下するとラベルと入力値から生成されたURLへジャンプする。
+# URI生成ルールはInterWikiと同じ。
+# :書式|
+#  #lookup(ラベル,ボタン名,入力値)
+# @author Nekyo.
+use strict;
+
+sub plugin_lookup_convert {
+	my @args = split(/,/, shift);
+#	if (@args < 2) { return ''; }
+	my $iwn = &htmlspecialchars(&trim($args[0]));
+	my $btn = &htmlspecialchars(&trim($args[1]));
+
+	my $default = '';
+	if (@args > 2) {
+		$default = &htmlspecialchars(trim($args[2]));
+	}
+	my $s_page = &htmlspecialchars($::form{mypage});
+	my $ret = <<"EOD";
+<form action="$::script" method="post">
+ <div>
+  <input type="hidden" name="cmd" value="lookup" />
+  <input type="hidden" name="inter" value="$iwn" />
+  $iwn:
+  <input type="text" name="page" size="30" value="$default" />
+  <input type="submit" value="$btn" />
+ </div>
+</form>
+EOD
+	return $ret;
+}
+
+sub plugin_lookup_action {
+	my $text = &::rawurldecode($::form{page});	# 入力テキスト
+
+	my ($code, $uri) = %{$::interwiki2{$::form{inter}}};
+	if ($uri) {	# pukiコンパチ
+		if ($uri =~ /\$1/) {
+			$uri =~ s/\$1/&interwiki_convert($code, $text)/e;
+		} else {
+			$uri .= &interwiki_convert($code, $text);
+		}
+	} else {	# yukiコンパチ
+		$uri = $::interwiki{$::form{inter}};
+		if ($uri) {
+			$uri =~ s/\b(utf8|euc|sjis|ykwk|yw|asis)\(\$1\)/&interwiki_convert($1, $text)/e;
+		}
+	}
+	if ($uri) {
+		print("Location: $uri\n\n");
+		exit;
+	}
+	return "";
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/ls2.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ls2.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/ls2.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,75 @@
+########################/
+# 配下のページの見出し(*,**,***)の一覧を表示する
+# :書式|
+#  #ls2(パターン[,パラメータ])
+# -パターン(最初に指定)
+# -title:見出しの一覧を表示する
+# -reverse:ページの並び順を反転し、降順にする
+
+# 以下は未対応
+# -include:インクルードしているページの見出しを再帰的に列挙する
+# -link:actionプラグインを呼び出すリンクを表示
+# -compact:
+
+# @author Nekyo.
+# @version v0.1 2005/04/01 encode バグ Fix Tnx:Junichiさん
+# @version v0.0 2004/11/01 簡易版 title,reverse 対応、その他は非対応
+# @see based on ls2.inc.php by arino
+
+use strict;
+
+sub plugin_ls2_convert
+{
+	my $prefix = '';
+	my @args = split(/,/, shift);
+	my $title = 0;
+	my $reverse = 0;
+	my (@pages, $txt, @txt, $tocnum);
+	my $body = '';
+
+    if (@args > 0) {
+		$prefix = shift(@args);
+		foreach my $arg (@args) {
+			if (lc $arg eq "title") {
+				$title = 1;
+			} elsif (lc $arg eq "reverse") {
+				$reverse = 1;
+			}
+		}
+	}
+	$prefix = $::form{mypage} . "/" if ($prefix eq '');
+
+	foreach my $page (sort keys %::database) {
+		push(@pages, $page) if ($page =~ /^$prefix/);
+	}
+	@pages = reverse(@pages) if ($reverse);
+	foreach my $page (@pages) {
+		$body .= <<"EOD";
+<li><a id ="list_1" href="$::script?cmd=read&amp;mypage=@{[&encode($page)]}" title="$page">$page</a></li>
+EOD
+		if ($title) {
+			$txt = $::database{$page};
+			@txt = split(/\r?\n/, $txt);
+			$tocnum = 0;
+			my (@tocsaved, @tocresult);
+			foreach (@txt) {
+				chomp;
+				if (/^(\*{1,3})(.+)/) {
+					&back_push('ul', length($1), \@tocsaved, \@tocresult);
+					push(@tocresult, qq( <li><a href="$::script?$page#i$tocnum">@{[&escape($2)]}</a></li>\n));	
+					$tocnum++;
+				}
+			}
+			push(@tocresult, splice(@tocsaved));
+			$body .= join("\n", @tocresult);
+		}
+	}
+	if ($body ne '') {
+		return << "EOD";
+<ul class="list1" style="padding-left:16px;margin-left:16px">$body</ul>
+EOD
+	}
+	return "No page of a low rank layer in '$prefix'<br />\n";
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/new.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/new.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/new.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,26 @@
+##
+# 日時が規定の日付以内の場合にNewと表示する。
+# :書式|
+#  &new(日時);
+# 5日以内の場合に New、1日以内の場合に New! を表示する。
+# @author Nekyo. for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+
+sub plugin_new_inline {
+	my $date = shift;
+	return '' if ($date eq '');
+
+	my $retval = $date;
+	my ($mday, $mon, $year) = (localtime())[3..5];
+
+	my $now = &mktime(0, 0, 0, $mon + 1, $mday, $year + 1900);
+	$date =~ /(\d+)-(\d+)-(\d+)/;
+	my $past = &mktime(0, 0, 0, $2, $3, $1);
+
+	if (($now - $past) <= 1*60*60*24) {
+		$retval .= ' <span class="new1">New!</span>';
+	} elsif (($now - $past) <= 5*60*60*24) {
+		$retval .= ' <span class="new5">New</span>';
+	}
+	return '<span class="comment_date">' . $retval . '</span>';
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/newpage.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/newpage.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/newpage.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,25 @@
+##
+# ページを新規作成する。
+# :書式|
+#  ?plugin=newpage
+
+############################################################
+# newpage プラグイン
+# newpage.inc.pl
+# Copyright(c) 2004 Nekyo.
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+#
+# 1TAB=4Spaces
+
+sub plugin_newpage_action {
+	my $body =<<"EOD";
+<form action="$::script" method="post">
+    <input type="hidden" name="cmd" value="edit">
+    $::resource{newpagename}
+    <input type="text" name="mypage" value="" size="20">
+    <input type="submit" value="$::resource{createbutton}"><br>
+</form>
+EOD
+	return ('msg' => $::CreatePage, 'body' => $body);
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,13 @@
+##
+# pukiwiki互換用のダミー関数
+# @author Nanami <nanam****@daiba*****>
+
+sub plugin_nofollow_inline {
+	return ' ';
+}
+
+sub plugin_nofollow_convert {
+	return ' ';
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/norelated.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/norelated.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/norelated.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,13 @@
+##
+# pukiwiki互換用のダミー関数
+# @author Nanami <nanam****@daiba*****>
+
+sub plugin_norelated_inline {
+	return ' ';
+}
+
+sub plugin_norelated_convert {
+	return ' ';
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/online.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/online.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/online.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,50 @@
+##
+# 現在参照中のおおよそのユーザー数を表示する。
+# :書式|
+#  #online
+#  &online;
+# @author Nekyo.
+# @version v0.2 2004/12/06 問題があったので、排他lockなし版
+use strict;
+
+my $timeout = 300;
+
+sub plugin_online_inline {
+	return &plugin_online_convert;
+}
+
+sub plugin_online_convert {
+	my $file = $::counter_dir . '/user.dat';
+	my $addr = $ENV{'REMOTE_ADDR'};
+
+	my @usr_arr = ();
+	if (-e $file) {
+		open(FILE, "<$file");
+		@usr_arr = <FILE>;
+		close(FILE);
+	}
+
+	if (!open(FILE, ">$file")) {
+		return 'online: "COUNTER_DIR/' . $file . '" not writable';
+	}
+#	flock(FILE, 2);		# lock WriteBlock
+	my $now = time();
+	my ($ip_addr, $tim_stmp);
+	foreach (@usr_arr) {
+		chomp;
+		($ip_addr, $tim_stmp) = split(/|/);
+
+		if (($now - $tim_stmp) < $timeout and $ip_addr ne $addr) {
+			print FILE "$ip_addr|$tim_stmp\n";
+		}
+	}
+	print FILE "$addr|$now\n";
+#	flock(FILE, 8);		# unlock
+	close(FILE);
+
+	open(FILE, "<$file");
+	@usr_arr = <FILE>;
+	close(FILE);
+	return @usr_arr;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/recent.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/recent.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/recent.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,85 @@
+############################################################
+# 最近更新されたページ一覧を表示。省略時件数は10件。
+# :書式|
+#  #recent([件数])
+
+# @author Copyright(c) 2004 Nekyo.
+# v 0.0.3 : + ページ名は一覧に表示しない。
+# v 0.0.2 ダイナミック生成から RecentChanges を除外した。
+# v 0.0.1 Actionによりダイナミック生成機能追加
+# v 0.0.0
+# for PyukiWiki(http://nekyo.hp.infoseek.co.jp)
+
+##
+# 時間を返す
+# @param unix time
+# @return yyyy-mm-dd 形式
+sub get_date {
+	my ($time) = @_;
+	my ($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime($time);
+	$year += 1900;
+	$mon++;
+	$mon = "0$mon" if $mon < 10;
+	$day = "0$day" if $day < 10;
+	return "$year-$mon-$day";
+}
+
+##
+# 最終更新の一覧を表示
+# @return 最終更新の一覧
+sub plugin_recent_action {
+	my $update;
+	my %rclist;
+	my $atime;
+	foreach my $page (sort keys %::database) {
+		$atime = (stat($::data_dir . "/" . &::dbmname($page) . ".txt"))[9];	# statで最終更新日付を取得
+		$rclist{$page} = $atime;
+	}
+	my @updates;
+	foreach my $page (sort { $rclist{$b} <=> $rclist{$a} } keys %rclist) {
+		next if ($page eq '');
+		$atime = $rclist{$page};
+		$update = "- @{[&get_date($atime)]} @{[&armor_name($page)]}";
+		push(@updates, $update);
+	}
+	splice(@updates, $::maxrecent + 1);
+	return ('msg' => $::resource{recentchangesbutton}, 'body' => &::text_to_html(join("\n", @updates)));
+}
+
+##
+# 最終更新の一覧を表示
+# @param 表示数(省略時:10)
+# @return 最終更新の一覧
+sub plugin_recent_convert {
+	my $limit = shift;
+	$limit = 10 if ($limit eq '');
+	my $recentchanges = $::cache_dir . '/recent.dat';
+
+	open(fp, "<$recentchanges");
+	@lines = <fp>;
+	close(fp);
+
+	my $count = 0;
+	my $date = "";
+	my $_date;
+	my $out = "";
+	foreach (@lines) {
+		last if ($count >= $limit);
+		/(\d+)\t(\S+)/;	# date format.
+		next if ($2 =~ /\[*:/); # 先頭が : の場合は表示しない。
+
+		$_date = get_date($1);
+		if ($2) {
+			if ($date ne $_date) {
+				$out .= "</ul>\n" if ($date ne '');
+				$date = $_date;
+				$out .= "<strong>$date</strong><ul class=\"recent_list\">\n";
+			}
+			$out .= "<li>" . &make_link($2) . "</li>\n";
+			$count++;
+		}
+	}
+	$out .= "</ul>\n" if ($date ne '');
+	return $out;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/ref.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ref.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/ref.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,260 @@
+######################################################
+# ページに添付されたファイルを展開する
+# URIを展開する
+# :書式|
+#  #ref(ファイル名[,ページ][,パラメータ][,title])
+# -ファイル名 - 添付ファイル名、またはURI。
+# 'ページ名/添付ファイル名'を指定すると、そのページの添付ファイルを参照。
+# -ページ - ファイルを添付したページ名(省略可)~
+# -パラメータ
+# --Left|Center|Right:横の位置合わせ
+# --Wrap|Nowrap:テーブルタグで囲む/囲まない
+# -Around - テキストの回り込み
+# -noicon - アイコンを表示しない
+# -nolink - 元ファイルへのリンクを張らない
+# -noimg - 画像を展開しない
+# -zoom - 縦横比を保持する
+# -999x999 - サイズを指定(幅x高さ)
+# -999% - サイズを指定(拡大率)
+# -その他 - imgのalt/hrefのtitleとして使用~
+# ページ名やパラメータに見える文字列を使用するときは、#ref(hoge.png,,zoom)のように
+# タイトルの前にカンマを余分に入れる
+use strict;
+
+my $file_icon = '<img src="'
+	. $::image_dir
+	. '/file.png" width="20" height="20" alt="file" style="border-width:0px" />';
+
+# default alignment
+my $ref_default_align = 'left'; # 'left','center','right'
+
+# force wrap on default
+my $REF_WRAP_TABLE = 0; # 1,0
+
+sub plugin_ref_inline
+{
+	my ($args) = @_;
+	my @args = split(/,/, $args);
+	return 'no argument(s).' if (@args < 1);	#エラーチェック
+	my %params = &plugin_ref_body($args, $::form{mypage});
+	return ($params{_error}) ? $params{_error} : $params{_body};
+}
+
+sub plugin_ref_convert
+{
+	my ($args) = @_;
+	my @args = split(/,/, $args);
+	return '<p>no argument(s).</p>' if (@args < 1);	#エラーチェック
+	my %params = &plugin_ref_body($args, $::form{mypage});
+
+	# divで包む
+	my $style;
+	if ($params{around}) {
+		$style = ($params{_align} eq 'right') ? 'float:right' : 'float:left';
+	} else {
+		$style = "text-align:$params{_align}";
+	}
+	return "<div class=\"img_margin\" style=\"$style\">$params{_body}</div>\n";
+}
+
+sub getimagesize
+{
+	my ($imgfile, $datafile) = @_;
+	my $width  = 0;
+	my $height = 0;
+	my ($data, $m, $c, $l);
+
+	if (!$datafile) {
+		$datafile = $imgfile;
+	}
+
+	if ($imgfile =~ /\.jpe?g$/i) {
+		open(FILE, "$datafile") || return (0, 0);
+		binmode FILE;
+		read(FILE, $data, 2);
+		while (1) { # read Exif Blocks
+			read(FILE, $data, 4);
+			($m, $c, $l) = unpack("a a n", $data);
+			if ($m ne "\xFF") {
+				$width = $height = 0;
+				last;
+			} elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) {
+				read(FILE, $data, 5);
+				($height, $width) = unpack("xnn", $data);
+				last;
+			} else {
+				read(FILE, $data, ($l - 2));
+			}
+		}
+		close(FILE);
+	} elsif ($imgfile =~ /\.gif$/i) {
+		open(FILE, "$datafile") || return (0,0);
+		binmode(FILE);
+		sysread(FILE, $data, 10);
+		close(FILE);
+		$data = substr($data, -4) if ($data =~ /^GIF/);
+
+		$width  = unpack("v", substr($data, 0, 2));
+		$height = unpack("v", substr($data, 2, 2));
+	} elsif ($imgfile =~ /\.png$/i) {
+		open(FILE, "$datafile") || return (0,0);
+		binmode(FILE);
+		read(FILE, $data, 24);
+		close(FILE);
+
+		$width  = unpack("N", substr($data, 16, 20));
+		$height = unpack("N", substr($data, 20, 24));
+	}
+	return ($width, $height);
+}
+
+sub plugin_ref_body
+{
+	my ($args) = @_;
+	my @args = split(/,/, $args);
+	my $name = &trim(shift(@args));
+	my $page;
+
+#	my %params = {
+#		'left'   => 0,	# 左寄せ
+#		'center' => 0,	# 中央寄せ
+#		'right'  => 0,	# 右寄せ
+#		'wrap'   => 0,	# TABLEで囲む
+#		'nowrap' => 0,	# TABLEで囲まない
+#		'around' => 0,	# 回り込み
+#		'noicon' => 0,	# アイコンを表示しない
+#		'nolink' => 0,	# 元ファイルへのリンクを張らない
+#		'noimg'  => 0,	# 画像を展開しない
+#		'zoom'   => 0,	# 縦横比を保持する
+#		'_size'  => 0,	# (サイズ指定あり)
+#		'_w'     => 0,	# (幅)
+#		'_h'     => 0,	# (高さ)
+#		'_%'     => 0,	# (拡大率)
+#		'_args'  => '',
+#		'_done'  => 0,
+#		'_error' => ''
+#	};
+
+	my (%params, $_title, $_backup);
+	foreach (@args) {
+		$_backup = $_;
+		$_ = &trim($_);
+		if (/^([0-9]+)x([0-9]+)$/i) { # size pixcel
+			$params{_size} = 1;
+			$params{_w} = $1;
+			$params{_h} = $2;
+		} elsif (/^([0-9.]+)%$/i) { # size %
+			$params{_par} = $1;
+		} elsif (/(left|center|right|wrap|nowrap|around|noicon|nolink|noimg|zoom)/i) { # align
+			$params{lc $_} = 1;
+		} else {
+			if (!$page and &is_exist_page($_)) {
+				$page = $_;
+			} else {
+				$_title = $_backup;
+			}
+		}
+	}
+
+	my ($url, $url2, $title, $is_image, $info);
+	my $width  = 0;
+	my $height = 0;
+
+	if ($name =~ /^(https?|ftp|news)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]*)$/) {	#URL
+		$url = $url2 = &htmlspecialchars($name);
+		$title = &htmlspecialchars(($name =~ '/([^\/]+)$/') ? $1 : $url);
+		$is_image = (!$params{noimg} and $name =~ /\.(gif|png|jpe?g)$/i);
+	} else {	# 添付ファイル
+		if (!-d "$::upload_dir/") {
+			$params{_error} = 'no $::upload_dir.';
+			return %params;
+		}
+		# ページ指定のチェック
+		$page = $::form{mypage} if (!$page);
+		if ($name =~ /^(.+)\/([^\/]+)$/) {
+			$1 .= '/' if ($1 eq '.' or $1 eq '..');
+			$page = get_fullname($1, $page);
+			$name = $2;
+		}
+		$title = &htmlspecialchars($name);
+		my $file  = "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name);
+		# my $file2 = "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name);
+		if (!-e $file) {
+			$params{_error} = 'file not found.' . $file;
+			return %params;
+		}
+		$is_image = (!$params{noimg} and $name =~ /\.(gif|png|jpe?g)$/i);
+
+		$url = "$::script?cmd=attach&amp;pcmd=open"
+			. "&amp;file=$name&amp;mypage=$page&amp;refer=$page";
+		if ($is_image) {
+			($width, $height) = getimagesize($name, $file);
+			$url2 = $url;
+		#	$url = $file2;
+			$url =($::download_dir ne '') ? "$::download_dir/" : "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name);
+		} else {
+			my ($sec, $min, $hour, $day, $mon, $year) = localtime((stat($file))[10]);
+			$info = sprintf("%d/%02d/%02d %02d:%02d:%02d %01.1fK",
+				$year + 1900, $mon + 1, $day, $hour, $min, $sec,
+				(-s $file) / 1000
+			);
+		}
+	}
+
+	# 画像サイズ調整
+	if ($is_image) {
+		# 指定されたサイズを使用する
+		if ($params{_size}) {
+			if ($width == 0 and $height == 0) {
+				$width  = $params{_w};
+				$height = $params{_h};
+			} elsif ($params{zoom}) {
+				my $_w = $params{_w} ? $width  / $params{_w} : 0;
+				my $_h = $params{_h} ? $height / $params{_h} : 0;
+				my $zoom = ($_w > $_h) ? $_w : $_h;
+				if ($zoom != 0) {
+					$width  = ($width  / $zoom);
+					$height = ($height / $zoom);
+				}
+			} else {
+				$width  = $params{_w} ? $params{_w} : $width;
+				$height = $params{_h} ? $params{_h} : $height;
+			}
+		}
+		if ($params{_par}) {
+			$width  = ($width  * $params{_par} / 100);
+			$height = ($height * $params{_par} / 100);
+		}
+		if ($width and $height) {
+			$info = "width=\"$width\" height=\"$height\" ";
+		}
+	}
+
+	#アラインメント判定
+	if ($params{right}) {
+		$params{_align} = 'right';
+	} elsif ($params{left}) {
+		$params{_align} = 'left';
+	} elsif ($params{center}) {
+		$params{_align} = 'center';
+	} else {
+		$params{_align} = $ref_default_align;
+	}
+
+	$title = $_title if ($_title);
+
+	# ファイル種別判定
+	if ($is_image) {	# 画像
+		my $_url = "<img src=\"$url\" alt=\"$title\" title=\"$title\" $info/>";
+		if (!$params{nolink} and $url2) {
+			$_url = "<a href=\"$url2\" title=\"$title\">$_url</a>";
+		}
+		$params{_body} = $_url;
+	} else {	# 通常ファイル
+		my $icon = $params{noicon} ? '' : $file_icon;
+		$params{_body} = "<a href=\"$url\" title=\"$info\">$icon$title</a>\n";
+	}
+	return %params;
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/rss10.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/rss10.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/rss10.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,64 @@
+##
+# 最新更新をRSS(RDF Site Summary)に変換して出力する。
+# :書式|
+#  ?cmd=rss10
+
+# @author Nekyo.
+# v0.0.2 2005/03/11 Add dc:date
+
+sub plugin_rss10_action {
+	my $recentchanges = $::database{$::RecentChanges};
+	my $count = 0;
+
+	print <<"EOD";
+Content-type: text/xml
+
+<?xml version="1.0" encoding="$::charset"?>
+  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/">
+  <channel rdf:about="$::modifier_rss_link">
+  <title>$::modifier_rss_title</title> 
+  <link>$::modifier_rss_link</link> 
+  <discription>$::modifier_rss_description</discription>
+  <items>
+  <rdf:Seq>
+EOD
+
+	my $items;
+
+	foreach (split(/\n/, $recentchanges)) {
+		last if ($count >= 15);
+		/^\- (\d\d\d\d\-\d\d\-\d\d) \(...\) (\d\d:\d\d:\d\d) (\S+)/;    # data format.
+		my $title = &unarmor_name($3);
+		my $escaped_title = &htmlspecialchars($title);
+		my $link = $modifier_rss_link . '?' . &rawurlencode($title);
+		my $description = $escaped_title . &htmlspecialchars(&get_subjectline($title));
+
+		print <<"EOD";
+  <rdf:li rdf:resource="$link" />
+EOD
+
+		$gmt = ((localtime(time))[2] + (localtime(time))[3] * 24)
+			- ((gmtime(time))[2] + (gmtime(time))[3] * 24);
+		my $date = $1 . "T" . $2 . sprintf("%+02d:00", $gmt);
+
+		$items .=<<"EOD";
+  <item rdf:about="$link">
+  <title>$escaped_title</title> 
+  <link>$link</link> 
+  <discription>$description</discription> 
+  <dc:date>$date</dc:date> 
+  </item>
+EOD
+		$count++;
+	}
+	print <<"EOD";
+  </rdf:Seq>
+  </items>
+  </channel>
+  $items
+</rdf:RDF>
+EOD
+	&close_db;
+	exit;
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/ruby.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ruby.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/ruby.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,17 @@
+##
+# 文字列にルビをふる。
+# :書式|
+#  &ruby(ルビ){ルビをふる文字列};
+# @author Nekyo.
+sub plugin_ruby_inline {
+	@arg = split(/,/, shift);
+	my $ruby = $arg[0];
+	my $body = $arg[1];
+
+	if ($ruby eq '' or $body eq '') {
+		return '';
+	}
+	my $s_ruby = &htmlspecialchars($ruby);
+	return "<ruby><rb>$body</rb><rp>(</rp><rt>$s_ruby</rt><rp>)</rp></ruby>";
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/search.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/search.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/search.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,120 @@
+##
+# 指定文字列を含むページを検索する。
+# :書式|
+#  ?cmd=search[パラメータ]
+# パラメータに検索条件を指定する。~
+# word − 検索文字列。~
+# type − 'OR' 指定時、OR検索を行う。(省略時はAND検索)~
+# @author Nekyo.
+use strict;
+
+sub search {
+	my ($word, $type, $base) = @_;
+	my %found;
+	my $body = "";
+	if ($word) {
+		my @words = split(/\s+/, $word);
+		my $total = 0;
+		if (uc($type) eq 'OR') {
+			my $firsttime = 1;
+			foreach my $wd (@words) {
+				foreach my $page (sort keys %::database) {
+					if ($base ne '') {
+						if ($page !~ /^$base/) {
+							next;
+						}
+					}
+					if (($::database{$page} =~ /\Q$wd\E/i) or ($page =~ /\Q$wd\E/i)) {
+						$found{$page} = 1;
+					}
+					if ($firsttime) {
+						$total++;
+					}
+				}
+				$firsttime = 0;
+			}
+		} else {	# AND 検索
+			foreach my $page (sort keys %::database) {
+
+				my $exist = 1;
+				foreach my $wd (@words) {
+					if (!($::database{$page} =~ /\Q$wd\E/i or $page =~ /\Q$wd\E/i)) {
+						$exist = 0;
+					}
+				}
+				if ($exist) {
+					$found{$page} = 1;
+				}
+				$total++;
+			}
+		}
+		my $counter = 0;
+		foreach my $page (sort keys %found) {
+			$body .= qq|<!-- search result -->\n<ul>| if ($counter == 0);
+			$body .= qq(<li><a href ="$::script?@{[&::encode($page)]}">@{[&::htmlspecialchars($page)]}</a>@{[&::htmlspecialchars(&::get_subjectline($page))]}</li>);
+			$counter++;
+		}
+		$body .= ($counter == 0) ? $::resource{notfound} : qq|</ul>\n<!-- search end -->|;
+	#	$body .= "$counter / $total <br />\n";
+	}
+	return $body;
+}
+
+sub search_form {
+	my ($word, $type, @base) = @_;
+	my $result =<<"EOD";
+<form action="$::script" method="post">
+<div>
+  <input type="hidden" name="cmd" value="search">
+  <input type="text" name="word" value="$word" size="20" />
+  <input type="radio" name="type" value="AND" @{[ ($type ne 'OR' ? qq( checked="checked") : qq()) ]} />$::resource{searchand}
+  <input type="radio" name="type" value="OR" @{[ ($type eq 'OR' ? qq( checked="checked") : qq()) ]}/>$::resource{searchor}
+  <input type="submit" value="$::resource{searchbutton}" />
+</div>
+EOD
+	if (@base) {
+		my $first = ' checked';
+		foreach my $bs (@base) {
+			if ($bs) {
+				$result .= <<"EOD";
+  <input type="radio" name="base" value="$bs"$first><strong>$bs</strong>$::resource{search_pages}<br />
+EOD
+				$first = '';
+			}
+		}
+		if ($first eq '') {
+			$result .= <<"EOD";
+  <input type="radio" name="base" value=""$first>$::resource{search_all}<br />
+EOD
+
+
+		}
+	}
+	$result .= "</form>\n";
+	return $result;
+}
+
+##
+# 条件1, 条件2 ... 条件n
+sub plugin_search_convert {
+	my @arg = split(/,/, shift);
+	return &search_form('', 'OR', @arg);
+}
+
+##
+# PyukiWiki独自機能
+# インラインは機能が違う。検索した一覧を表示する。
+sub plugin_search_inline {
+	my @arg = split(/,/, shift);
+	return &search($arg[0], $arg[1]);
+}
+
+sub plugin_search_action {
+	my $word = &htmlspecialchars($::form{word});
+	my $body = &search($word, $::form{type}, $::form{base});
+	$body .= &search_form($word, $::form{type}, $::form{base});
+	return ('msg'=>$::resource{searchpage}, 'body'=>$body);
+}
+
+1;
+
Index: PyukiWiki-Nekyo/019/plugin/server.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/server.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/server.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,128 @@
+##
+# サーバー情報(サーバー名、サーバーソフトウエア、サーバー管理者)を表示する。
+# :書式|
+#  #server
+# @author Nekyo.
+use strict;
+package server;
+
+sub disp {
+	my ($s) = @_;
+
+	return ($s ? $s : "-");
+}
+
+sub plugin_block {
+	return &plugin_inline;
+}
+
+sub plugin_inline
+{
+	my $useragent = $::ENV{'HTTP_USER_AGENT'};
+	my $body =<<"EOD";
+<dl>
+<dt>Server Name</dt>
+<dd>@{[ $::ENV{'SERVER_NAME'} ]}</dd>
+<dt>Server Software</dt>
+<dd>@{[ $::ENV{'SERVER_SOFTWARE'} ]}</dd>
+<dt>Server Admin</dt>
+<dd><a href="mailto:@{[ $::ENV{'SERVER_ADMIN'} ]}">@{[
+	$::ENV{'SERVER_ADMIN'}
+]}</a></dd>
+<dt>User Agent</dt>
+<dd>@{[ $useragent ]}</dd>
+EOD
+	if ($useragent =~ /^(J-PHONE|Vodafon|SoftBank)\//) {
+# Color:色数 / Display:画面サイズ / GeoCode:位置情報 / Java:Vアプリ対応機種
+# MsName:端末機種名 / Region:利用地域(国内・外) / Smaf:Smaf種別
+# Sound:和音種別 / UID:ユーザID / Copyright:保存・送出・転送可否指定
+		$body .=<<"EOD";
+<dt>Color</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_COLOR'})     ]}</dd>
+<dt>Display</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_DISPLAY'})   ]}</dd>
+<dt>GeoCode</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_GEOCODE'})   ]}</dd>
+<dt>Java</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_JAVA'})      ]}</dd>
+<dt>MSName</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_MSNAME'})    ]}</dd>
+<dt>Region</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_REGION'})    ]}</dd>
+<dt>Smaf</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_SMAF'})      ]}</dd>
+<dt>Sound</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_SOUND'})     ]}</dd>
+<dt>UID</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_UID'})       ]}</dd>
+<dt>Copyright</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_COPYRIGHT'}) ]}</dd>
+EOD
+	} elsif ($useragent =~ /UP\.Browser\//) {
+#	} else {
+# HTTP_X_UP_DEVCAP_IMMED_ALERT:does(1) or does not(0) support immediate alerts.
+# HTTP_X_UP_DEVCAP_MAX_PDU:maximum packet size supported by device.
+# HTTP_X_UP_DEVCAP_GUI:device is(1) or is not(0) using a GUI browser.
+# HTTP_X_UP_DEVCAP_SCREENPIXELS / HTTP_X_UP_DEVCAP_SCREENCHARS / HTTP_X_UP_DEVCAP_SCREENDEPTH
+# HTTP_X_UP_DEVCAP_MSIZE:pixels of the character,"M"
+# HTTP_X_UP_DEVCAP_NUMSOFTKEYS / HTTP_X_UP_DEVCAP_SOFTKEYSIZE
+# HTTP_X_UP_DEVCAP_ISCOLOR
+# HTTP_X_UP_FAX_ACCEPTS / HTTP_X_UP_FAX_ENCODINGS / HTTP_X_UP_FAX_LIMIT
+# HTTP_X_UP_SUBNO
+# HTTP_X_UP_UPLINK
+# HTTP_X_UP_DEVCAP_SMARTDIALING ??
+#<dt>Accept Language</dt>
+#<dd>@{[ &disp($::ENV{'HTTP_ACCEPT_LANGUAGE'}) ]}</dd>
+#<dt>Cookie</dt>
+#<dd>@{[ &disp($::ENV{'HTTP_COOKIE'})          ]}</dd>
+#<dt>Refer</dt>
+#<dd>@{[ &disp($::ENV{'HTTP_REFERER'})         ]}</dd>
+
+		$body .=<<"EOD";
+<dt>Immidiate Alerts</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_IMMED_ALERT'})  ]}</dd>
+<dt>Max PDU</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_MAX_PDU'})      ]}</dd>
+<dt>GUI</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_GUI'})          ]}</dd>
+<dt>Screen Pixels</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENPIXELS'}) ]}</dd>
+<dt>Screen Chars</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENCHARS'})  ]}</dd>
+<dt>Screen Depth</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENDEPTH'})  ]}</dd>
+<dt>M Size</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_MSIZE'})        ]}</dd>
+<dt>Num Softkeys</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_NUMSOFTKEYS'})  ]}</dd>
+<dt>Softkey Size</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SOFTKEYSIZE'})  ]}</dd>
+<dt>Is Color</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_ISCOLOR'})      ]}</dd>
+<dt>Fax Accepts</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_ACCEPTS'})         ]}</dd>
+<dt>Fax Encodings</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_ENCODINGS'})       ]}</dd>
+<dt>Fax Limit</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_LIMIT'})           ]}</dd>
+<dt>Subno</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_SUBNO'})               ]}</dd>
+<dt>Uplink</dt>
+<dd>@{[ &disp($::ENV{'HTTP_X_UP_UPLINK'})              ]}</dd>
+EOD
+	}
+	return $body . "</dl>\n";
+}
+
+sub plugin_usage {
+	return {
+		name => 'server',
+		version => '1.0',
+		author => 'Nekyo <nekyo****@yaman*****>',
+		syntax => '#server',
+		description => 'Show Server Info.',
+		example => '#server',
+	};
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/showrss.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/showrss.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/showrss.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,189 @@
+##
+# 指定されたRSSを取得し、一覧表示する。
+# :書式|
+#  #showrss(RSSパス, テンプレート名, キャッシュ生存時間)
+# RSSパスにはRSSへのファイルパスやURLを指定する。(省略不可)~
+# テンプレート名には取得RSSの表示方法を指定。default(省略時), menubar, recent。~
+# キャッシュ生存時間はキャッシュをクリアする期限(1時間単位)。
+# 省略すると無効になる。
+
+# http://nekyo.hp.infoseek.co.jp/
+# License: GPL2
+# Return:LF Code=Shift-JIS 1TAB=4Spaces
+use strict;
+
+sub plugin_showrss_inline
+{
+	return &plugin_showrss_convert(shift);
+}
+
+sub plugin_showrss_convert
+{
+	my @arg = &func_get_args(shift);
+	return "argument error." if (@arg <= 0);
+	my $rssuri   = $arg[0];
+	my $tmplname = (@arg >= 2) ? $arg[1] : "";
+	my $usecache = (@arg >= 3) ? $arg[2] : 0;
+
+	my $expire = $usecache * 3600;
+	my $code = 'utf8';
+	my $cachefile = $::cache_dir . "/" . &dbmname($rssuri) . ".tmp";
+	my $stream;
+	my $body = "";
+
+	my $lastmod = (stat($cachefile))[9];
+	if ($lastmod + $expire < time || $lastmod == 0) {
+		my $fp = fopen($rssuri, "r");
+		my $result;
+		($result, $stream) = &get_rss($fp);
+		return $stream if ($result != 0); # $stream is errorcode.
+
+		if ($stream =~ /encoding="[Ee][Uu][Cc]/) {
+			$code = "euc";
+		} elsif($stream=~/encoding="[Ss][Hh][Ii][Ff][Tt]/) {
+			$code = "sjis";
+		}
+		$stream = &replace(&code_convert(\$stream, $::kanjicode, $code));
+		if (open(OUT, ">$cachefile")) {
+			flock(OUT, 2);	# lock WriteBlock
+			print OUT $stream;
+			flock(OUT, 8);	# unlock
+			close OUT;
+		}
+	} else {
+		# read_cache
+		my @line;
+		open(IN, "<$cachefile") || return "Can't read cache.";
+		@line = <IN>;
+		close IN;
+		undef $stream;
+		$stream = join('', @line);
+	}
+
+	my %xml = &xmlParser($stream);
+	my @title = split(/\n/,
+		($xml{'rdf:RDF/item/title'} ne ""
+		? $xml{'rdf:RDF/item/title'} : $xml{'rss/channel/item/title'}
+		)
+	);
+	my @date = split(/\n/,
+		($xml{'rdf:RDF/item/dc:date'} ne ""
+		? $xml{'rdf:RDF/item/dc:date'} : $xml{'rss/channel/dc:date'}
+		)
+	);
+	my @link = split(/\n/,
+		($xml{'rdf:RDF/item/link'} ne ""
+		? $xml{'rdf:RDF/item/link'} : $xml{'rss/channel/item/link'}
+		)
+	);
+
+#	my @desc  = split(/\n/, $xml{'rdf:RDF/item/description'});
+
+	my ($footer, $ll, $lr);
+
+	if (lc $tmplname eq "menubar") {
+		$body .=<<"EOD";
+<div class="small">
+<ul class="recent_list">
+EOD
+		$ll = "<li>";
+		$lr = "</li>\n";
+		$footer = "</ul>\n</div>\n";
+	} elsif (lc $tmplname eq "recent") {
+		$body .=<<"EOD";
+<div class="small">
+<string>$date[0]</strong>
+<ul class="recent_list">
+EOD
+		$ll = "<li>";
+		$lr = "</li>\n";
+		$footer = "</ul>\n</div>\n";
+	} else {
+		$ll = $footer = "";
+		$lr = "<br />\n";
+	}
+
+	my $count = 0;
+	foreach (@title) {
+		$body .=<<"EOD";
+$ll<a href="$link[$count]" title="$title[$count]">$title[$count]</a>$lr
+EOD
+		$count++;
+	}
+	$body .= $footer;
+
+	return $body;
+}
+
+sub get_rss
+{
+	my ($fp) = @_;
+	my (@log, $data);
+	@log = <$fp>;
+	sleep(1);
+	close($fp);
+	undef $data;
+	foreach (@log) {
+		s/\r\n/\n/g;
+		s/\r/\n/g;
+		s/\n//g;
+		$data .= $_;
+	}
+	return (0, $data);
+}
+
+sub replace
+{
+	my ($xmlStream) = @_;
+	$xmlStream =~ s/<\?(.*)\?>//g;
+	$xmlStream =~ s/<rdf:RDF(.*?)>/<rdf:RDF>/g;
+	$xmlStream =~ s/<rss(.*?)>/<rss>/g;
+	$xmlStream =~ s/<channel(.*?)>/<channel>/g;
+	$xmlStream =~ s/<item(.*?)>/<item>/g;
+	$xmlStream =~ s/<content:encoded>(.*?)<\/content:encoded>//g;
+	$xmlStream =~ s/\ *\/>/\/>/g;
+	$xmlStream =~ s/<([^<>\ ]*)\ ([^<>]*)\/>/<$1>$2<\/$1>/g;
+	$xmlStream =~ s/<([^<>\/]*)\/>/<$1><\/$1>/g;
+	return $xmlStream;
+}
+
+sub xmlParser
+{
+	my ($stream) = @_;
+	my ($i, $ch, $name, @node, $val, $key, %xml);
+	my $flg = 0;	# 1:key / 0:value
+	foreach $i (0..length $stream) {
+		$ch = substr($stream, $i, 1);
+		if ($ch eq '<') {
+			$flg = 1;
+			undef $name;
+			foreach (@node) {
+				$name .= "$_/";
+			}
+			chop $name;
+			$val =~ s/<//g;
+			$val =~ s/>//g;
+			$xml{$name} .= "$val\n";
+			undef $val;
+		}
+		if ($flg) {
+			$key .= $ch;
+		} else {
+			$val .= $ch;
+		}
+		if ($ch eq '>') {
+			$flg = 0;
+			if ($key =~ /\//) {
+				pop @node;
+			} else {
+				$key =~ s/<//g;
+				$key =~ s/>//g;
+				push @node, $key;
+			}
+			undef $key;
+		}
+	}
+	return %xml;
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/size.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/size.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/size.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,17 @@
+##
+# 文字の大きさを指定する。
+# :書式|
+#  &size(ピクセル数値){文字列}
+# ピクセル数値は文字の大きさを指定。
+# @author Nekyo.
+use strict;
+package size;
+
+sub plugin_inline {
+	my ($size, $body) = split(/,/, shift);
+	if ($size eq '' or $body eq '') {
+		return "";
+	}
+	return "<span style=\"font-size:" . $size . "px;display:inline-block;line-height:130%;text-indent:0px\">$body</span>";
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/source.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/source.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/source.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,15 @@
+##
+# ページのソースを表示する。
+# :書式|
+#  ?cmd=source&page=ページ名
+# @author: Nekyo.
+use strict;
+sub plugin_source_action {
+	return if ($::form{'page'} eq '');
+	my $page = $::form{'page'};
+	print "Content-Type: text/plain\r\n\r\n";
+	print $::database{$page};
+	&close_db;
+	exit(0);
+}
+1;
Index: PyukiWiki-Nekyo/019/plugin/sub.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/sub.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/sub.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,30 @@
+##
+# 上付き文字表示~
+# pyukiwiki独自実装で ^2つで包むと上付きになる。
+#  2^^2^^=4
+# 2^^2^^=4 と表示。~
+# yukiwiki, pukiwiki との互換性を重視される方はこのプラグインを使用すること。
+#  2&sup(2);=4
+# 2&sup(2);=4 と表示。
+use strict;
+
+package sub;
+
+sub plugin_inline {
+    my ($escaped_argument) = @_;
+    my ($string) = split(/,/, $escaped_argument);
+    return qq(<sub>$string</sub>);
+}
+
+sub plugin_usage {
+    return {
+        name => 'sub',
+        version => '1.0',
+        author => 'Nekyo',
+        syntax => '&sub(string)',
+        description => 'Make sub.',
+        example => '&sub(string)',
+    };
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/sup.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/sup.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/sup.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,30 @@
+##
+# 下付き文字表示~
+# pyukiwiki独自実装で _2つで包むと下付きになる。
+#  11001011__2__=0xa9
+# 11001011__2__=0xa9 と表示。~
+# yukiwiki, pukiwiki との互換性を重視される方はこのプラグインを使用すること。
+#  11001011&sub(2);=0xa9
+# 11001011&sub(2);=0xa9 と表示。
+use strict;
+
+package sup;
+
+sub plugin_inline {
+    my ($escaped_argument) = @_;
+    my ($string) = split(/,/, $escaped_argument);
+    return qq(<sup>$string</sup>);
+}
+
+sub plugin_usage {
+    return {
+        name => 'sup',
+        version => '1.0',
+        author => 'Nekyo',
+        syntax => '&sup(string)',
+        description => 'Make sub.',
+        example => '&sup(string)',
+    };
+}
+
+1;
Index: PyukiWiki-Nekyo/019/plugin/vote.inc.pl
diff -u /dev/null PyukiWiki-Nekyo/019/plugin/vote.inc.pl:1.1
--- /dev/null	Sun Mar 18 02:14:52 2012
+++ PyukiWiki-Nekyo/019/plugin/vote.inc.pl	Sun Mar 18 02:14:52 2012
@@ -0,0 +1,125 @@
+##
+# 簡易投票フォームの表示
+# :書式|
+#  #vote(選択肢1[1の投票数][,選択肢2[2の投票数]…[,選択肢n[nの投票数]]])
+# 選択肢1〜nに投票項目を指定する。
+
+# @auther Nekyo.(http://nekyo.hp.infoseek.co.jp)
+# @version 0.2 不具合修正版
+use strict;
+
+sub plugin_vote_action
+{
+	my $lines = $::database{$::form{mypage}};
+	my @lines = split(/\r?\n/, $lines);
+
+	my $vote_no = 0;
+	my $title = '';
+	my $body = '';
+	my $postdata = '';
+	my @args = ();
+	my $cnt = 0;
+	my $write = 0;
+	my $vote_str = '';
+
+	foreach (@lines) {
+		if (/^#vote\(([^\)]*)\)s*$/) {
+			if (++$vote_no != $::form{vote_no}) {
+				$postdata .= $_ . "\n";
+				next;
+			}
+			@args = split(/,/, $1);
+			$vote_str = '';
+			foreach my $arg (@args) {
+				$cnt = 0;
+				if ($arg =~ /^(.+)\[(\d+)\]$/) {
+					$arg = $1;
+					$cnt = $2;
+				}
+				my $e_arg = &rawurlencode($arg);
+				my $vote_e_arg = "vote_" . $e_arg;
+
+				if ($::form{$vote_e_arg} && ($::form{$vote_e_arg} eq $::resource{vote_plugin_votes})) {
+					$cnt++;
+				}
+				if ($vote_str ne '') {
+					$vote_str .= ',';
+				}
+				$vote_str .= $arg . '[' . $cnt . ']';
+			}
+			$vote_str = '#vote(' . $vote_str . ")\n";
+			$postdata .= $vote_str;
+			$write = 1;
+		} else {
+			$postdata .= $_ . "\n";
+		}
+	}
+	if ($write) {
+		$::form{mymsg} = $postdata;
+		$::form{mytouch} = 'on';
+		&do_write('FrozenWrite');
+	} else {
+		$::form{cmd} = 'read';
+		&do_read;
+	}
+	&close_db;
+	exit;
+}
+
+my $vote_no = 0;
+
+sub plugin_vote_convert
+{
+	$vote_no++;
+	my @args = split(/,/, shift);
+	return '' if (@args == 0);
+
+	my $escapedmypage = &htmlspecialchars($::form{mypage});
+	my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker);
+
+	my $body = <<"EOD";
+<form action="$::script" method="post">
+ <table cellspacing="0" cellpadding="2" class="style_table" summary="vote">
+  <tr>
+   <td align="left" class="vote_label" style="padding-left:1em;padding-right:1em"><strong>$::resource{vote_plugin_choice}</strong>
+    <input type="hidden" name="vote_no" value="$vote_no" />
+    <input type="hidden" name="cmd" value="vote" />
+    <input type="hidden" name="mypage" value="$escapedmypage" />
+    <input type="hidden" name="myConflictChecker" value="$conflictchecker" />
+    <input type="hidden" name="mytouch" value="on" />
+   </td>
+   <td align="center" class="vote_label"><strong>$::resource{vote_plugin_votes}</strong></td>
+  </tr>
+EOD
+
+	my $tdcnt = 0;
+	my $cnt = 0;
+	my ($link, $e_arg, $cls);
+	foreach (@args) {
+		$cnt = 0;
+
+		if (/^(.+)\[(\d+)\]$/) {
+			$link = $1;
+			$cnt = $2;
+		} else {
+			$link = $_;
+		}
+		$e_arg = &rawurlencode($link);
+		$cls = ($tdcnt++ % 2)  ? 'vote_td1' : 'vote_td2';
+		$body .= <<"EOD";
+  <tr>
+   <td align="left" class="$cls" style="padding-left:1em;padding-right:1em;">$link</td>
+   <td align="right" class="$cls">$cnt&nbsp;&nbsp;
+    <input type="submit" name="vote_$e_arg" value="$::resource{vote_plugin_votes}" class="submit" />
+   </td>
+  </tr>
+EOD
+	}
+
+	$body .= <<"EOD";
+ </table>
+</form>
+EOD
+	return $body;
+}
+1;



Pyukiwiki-cvs メーリングリストの案内
Back to archive index