表紙 | 新規 | 一覧 | RSS | 検索 | 閲覧履歴 | 作成履歴 | 更新履歴

wiki.cgi全体(PonyWikiのソース) - YukiWikiベースのPonyWikiのソースを読んでみる そのxxx

差分表示


[[YukiWikiベースのPonyWikiのソースを読んでみる]] そのxxx

[[PonyWiki]]のwiki.cgi全部です。ver. 0600508.2 &br()
- Bugfix
-- Compress::Zlibがない場合に出力されるRSSが不正だったバグ修正 
-- URL以降の文に自動リンクが適用されなかったバグを修正 
-- URLのリンク化とページへの自動リンクが干渉するバグを修正
[[PonyWiki]]のwiki.cgi全部です。ver. 060614.0 &br()
- Bugfixと変更
-- 色々更新したので、詳しくは[[Changelog]]参照

- 変更
--メニューなど自動生成している箇所にGoogleよけを設置 

- 詳しくは[[Changelog]]参照

---(
 #!/usr/bin/perl
 #!perl
 # perl -d:DProf
 # wiki.cgi - This is [[PonyWiki]], yet another Wiki clone based on [[YukiWiki]].
 #
 # Copyright (C) 2004-2006 by Kisara.
 # <ponytail@you-like.to>
 # http://you-like.to/ponytail/
 # Copyright (C) 2000-2004 by Hiroshi Yuki.
 # <hyuki@hyuki.com>
 # http://www.hyuki.com/yukiwiki/
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the same terms as Perl itself.
 #
 # [[PonyWiki]]は[[YukiWiki]]2.1.2をベースに、きさらによる独自の拡張と[[WalWiki]]や各種パッチを取り込んだWikiです。
 # キーワードは「検索重要」
 #
 ##############################
 # Libraries.
 use strict;
 use lib qw(.);
 use CGI qw(:standard);
 use CGI::Carp qw(fatalsToBrowser);
 use Yuki::RSS;
 use Yuki::DiffText qw(difftext);
 use Yuki::PluginManager;

 #use Jcode;
 use utf8;
 use Encode ();
 use Encode::Guess;
 use Tie::FileArray;

 use HTTP::Lite;							# Walrus add [wiki antenna]
 use Walrus::Antenna;					# Walrus add [wiki antenna]
 use Fcntl;
 eval "use Compress::Zlib";				# 使えたらRSS圧縮配信に利用


 # DEBUG
 #my $searchtime;
 #use Time::HiRes;
 #$searchtime = Time::HiRes::time;
 my $searchtime;
 use Time::HiRes;
 $searchtime = Time::HiRes::time;

 # Version
 my $version = '060508.2';
 my $version = '060614.0';
 my $orgversion = '2.1.2';


  ##############################
  #設定項目開始
  ##############################
  # DB関連
 # 使用するDBMを選択して下さい。
 # use AnyDBM_File; my $modifier_dbtype = 'AnyDBM_File';
 # use DB_File;  my $modifier_dbtype = 'DB_File';
 # use Yuki::[[YukiWikiDB]]x; my $modifier_dbtype = '[[YukiWikiDB]]x';
 # use Yuki::[[YukiWikiDB]]_Backup; my $modifier_dbtype = '[[YukiWikiDB]]_Backup'; use Yuki::[[YukiWikiDB]];
 # use Yuki::[[YukiWikiDB]]; my $modifier_dbtype = '[[YukiWikiDB]]';
 #
 use Yuki::[[YukiWikiDB]]; my $modifier_dbtype = '[[YukiWikiDB]]';

  ##############################
  # URL関連
  #
 my $url_cgi = 'http://localhost/ponywiki/';		# my $url_cgi = 'wiki.cgi';
 my $action_url = 'http://localhost/ponywiki/?';	# my $action_url = 'wiki.cgi?';
 my $url_stylesheet = "./wiki.css";
  # Trackback config系
 my $url_cgi_trackback = 'http://localhost/ponywiki/wiki.cgi'; # add [trackback]
 my $embed_trackback = '[[#trackback]]'; # add [trackback]
 my $embed_rtrackback = '[[#rtrackback]]'; # add [trackback]

  ##############################
  # ディレクトリ関連
 my $modifier_favicon = './favicon.ico'; #faviconのパス
 my $modifier_favicon = 'http://localhost/ponywiki/favicon.ico'; #faviconのパス
 my $modifier_dir_data = '.'; # Your data directory (not URL, but DIRECTORY).
 my $modifier_url_data = '.'; # Your data URL (not DIRECTORY, but URL).
 my $modifier_dir_plugin = './plugin';
  # データ系
 my $dataname = "$modifier_dir_data/wiki"; # データ本体
 my $infoname = "$modifier_dir_data/info"; # 更新日時やアクセス数などの情報
 my $diffname = "$modifier_dir_data/diff"; # 差分
 my $antennaname = "$modifier_dir_data/antenna";				# Walrus add [wiki antenna]
 my $cachename = "$modifier_dir_data/cache";	  				# htmlのキャッシュ用
  # 検索系
 my $modifier_dir_index = "$modifier_dir_data/index";		# インデックス用のディレクトリ
 my $search_cache = "$modifier_dir_index/cache"; 			# 検索結果キャッシュ
 my $search_index_name = "$modifier_dir_index/search_index.dat";		# 検索インデックスファイル
 my $autolink_index_name = "$modifier_dir_index/autolink_index.dat";	# 自動リンクインデックスファイル

  ##############################
  # ファイル関連
 my $file_touch = "$modifier_dir_data/touched.txt";
 my $file_resource = "$modifier_dir_data/resource.txt";
 my $file_[[FrontPage]] = "$modifier_dir_data/frontpage.txt";
 my $file_conflict = "$modifier_dir_data/conflict.txt";
 my $file_format = "$modifier_dir_data/format.txt";

  ##############################
  # Admin 関連
 my $modifier_mail = 'ponytail@you-like.to'; # Your mail address.
 my $modifier_url = 'http://you-like.to/ponytail/'; # Your web page.
 my $modifier_name = 'Kisara'; # Your name.
 my $modifier_sendmail = '';
 # my $modifier_sendmail = '/usr/sbin/sendmail -t -n';
 my $icontag = qq(<iframe src="http://ponytail.jpn.org/lightnovel/rand_banner.cgi" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"></iframe>); # 適当なものに置き換えて下さい
 $icontag = qq();


  ##############################
  # RSS
 my $modifier_rss_title = "[[PonyWiki]]"; # 日本語ダメ。アルファベットだけ。
 my $modifier_rss_title = "Lightnovel Wiki"; # 日本語ダメ。アルファベットだけ。
 my $modifier_rss_link = 'http://localhost/ponywiki/wiki.cgi';
 my $modifier_rss_description = 'all about [[PonyWiki]]'; # 日本語OK(たぶん)
 my $modifier_rss_description = 'all about Lightnovel'; # 日本語OK(たぶん)
 my $modifier_rss_timezone = '+09:00';

  ##############################
  # 設定値関連
 my $maxrecent = 50;
 my $cols = 80;
 my $rows = 20;
 my $autolink_length = 3;  #  自動リンクするページ名の最小文字数。
 my $admin_only_mode = 0; # 編集時にパスワード必須モード
 my $max_cache_length = 128; # アンテナや検索のキャッシュ長
 my $editchar = '?';
 my $subject_delimiter = ' - ';
 my $use_autoimg = 1; # automatically convert image URL into <img> tag.
 my $use_exists = 0; # If you can use 'exists' method for your DB.
 my $use_Fixed[[FrontPage]] = 0; # 1だとfrontpage.txtを使用。0だと普通のWikiページ
 my $no_spam = 1; # 1だとアルファベットだけの書込を拒否。0だと制限なし。
  # 文字コード系
 my $kanjicode = 'utf8';
 my $charset = 'utf-8';
 my $lang = 'ja';
  # Cache系
 my @no_cache_word = (	# この単語を含むページはキャッシュ対象外
 	'#antenna(',
 	'&random()',
 	'[[RecentSearches]]',
 	'[[RecentReads]]',
 );
  ##############################
  #設定項目終了
  ##############################


 ##############################
 my $[[RecentCreates]] = '[[RecentCreates]]';
 my $[[RecentChanges]] = '[[RecentChanges]]';
 my $[[RecentSearches]] = '[[RecentSearches]]';
 my $[[RecentReads]] = '[[RecentReads]]';

 my $AdminChangePassword = 'AdminChangePassword';
 my $CompletedSuccessfully = 'CompletedSuccessfully';
 my $[[FrontPage]] = '[[FrontPage]]';
 my $IndexPage = 'IndexPage';
 my $SearchPage = 'SearchPage';
 my $CreatePage = 'CreatePage';
 my $ErrorPage = 'ErrorPage';
 my $RssPage = 'RssPage';
 my $AdminSpecialPage = ' Admin Special Page '; # パスワード保管ページ。必ず先頭と末尾にスペースを入れて下さい
 my $ACPage = ' Access Counter Page '; # アクセス数用ページ。必ず先頭と末尾にスペースを入れて下さい

 ##############################
 # my $wiki_name = '\[\[(.+?)\]\]';
 # my $bracket_name = '\[\[(.+?)\]\]';
 my $wiki_name = '\[{2,}(.+?)\]{2,}';
 my $bracket_name = '\[{2,}(.+?)\]{2,}';

 my $embedded_name = '\[\[(#\S+?)\]\]';
 # Sorry for wierd regex.
 my $inline_plugin = '\&amp;(\w+)\((([^()]*(\([^()]*\))?)*)\)';
 ##############################
 my $embed_comment = '[[#comment]]';
 my $embed_rcomment = '[[#rcomment]]';
 ##############################
 my $info_ConflictChecker = 'ConflictChecker';
 my $info_LastModified = 'LastModified';
 my $info_IsFrozen = 'IsFrozen';
 my $info_AdminPassword = 'AdminPassword';
 # Access count Info
 my $info_TotalAccessCount ='TotalAccessCount';
 my $info_UniqAccessCount ='UniqAccessCount';
 my $info_LastAccessIP='LastAccessIP';

 ##############################
 my %fixedpage = (
 	$IndexPage => 1,
 	$CreatePage => 1,
 	$ErrorPage => 1,
 	$RssPage => 1,
 	$[[RecentReads]] => 1,
 	$[[RecentSearches]] => 1,
 	$[[RecentChanges]] => 1,
 	$[[RecentCreates]] => 1,
 	$SearchPage => 1,
 	$AdminChangePassword => 1,
 	$CompletedSuccessfully => 1,
 	$[[FrontPage]] => $use_Fixed[[FrontPage]],
 );
 my @search_index;
 my @autolink_index;
 my %form;
 my %resource;

 # Tie DB関連
 my %database;
 my %infobase;
 my %diffbase;
 my %antennabase;		# Walrus add [wiki antenna]
 my %cachebase;
 my %searchcachebase;
 my %recentbase;

 my $plugin_manager;
 my $plugin_context = {
 	debug => 0,
 	keitai => 0,
 	database => \%database,
 	infobase => \%infobase,
 	resource => \%resource,
 	form => \%form,
 	url_cgi => $url_cgi,
 };
 ##############################
 my %page_command = (
 	$IndexPage => 'index',
 	$SearchPage => 'searchform',
 	$CreatePage => 'create',
 	$RssPage => 'rss',
 	$AdminChangePassword => 'adminchangepasswordform',
 	$[[FrontPage]] => '[[FrontPage]]',
 );
 my %command_do = (
 	read => \&do_read,
 	edit => \&do_edit,
 	adminedit => \&do_adminedit,
 	adminchangepasswordform => \&do_adminchangepasswordform,
 	adminchangepassword => \&do_adminchangepassword,
 	write => \&do_write,
 	index => \&do_index,
 	searchform => \&do_searchform,
 	search => \&do_search,
 	create => \&do_create,
 	egg => \&do_convert,
 	createresult => \&do_createresult,
 	[[FrontPage]] => \&do_[[FrontPage]],
 	comment => \&do_comment,
 	rss => \&do_rss,
 	diff => \&do_diff,
 );
 ##############################
 &main;
 exit(0);
 ##############################

 sub main {
 	&init_resource;
 	&open_db;
 	&init_form;
 	&init_plugin;	# 必ずinit_formの後に実行。(携帯電話フラグを渡す為)
 	
 #### mod [tarackback] start
 	if (&is_trackback) {
 		&response_trackback;
 #### mod [tarackback] end
 	} elsif ($command_do{$form{mycmd}}) {
 		&{$command_do{$form{mycmd}}};
 	} else {
 		$form{mymsg} = $form{mypage};
 		&do_search;
 	}
 	&close_db;
 }

 sub do_read {
 	&print_header($form{mypage});
 	if($form{mypart}){			# 部分読み
 		my $mymsg = (&read_by_part($form{mypage}))[$form{mypart} - 1];
 		&print_content($mymsg);
 	} elsif($form{keitai}) {	# 携帯電話アクセス
 		&print_content($database{$form{mypage}});
 	} else {
 		&print_cache($form{mypage});
 	}
 	&update_recent_reads;
 	&print_footer($form{mypage});
 }

 sub do_edit {
 	my ($page) = &unarmor_name(&armor_name($form{mypage}));
 	
 	if($admin_only_mode){
 		&do_adminedit;
 		exit;
 	}
 	
 	&print_header($page);
 	print qq(\n<!--googleoff: all-->\n);
 	
 	if (not &is_editable($page)) {
 		&print_message($resource{cantchange});
 	} elsif (&is_frozen($page)) {
 		&print_message($resource{cantchange});
 	# Walrus add [part edit] start
 	} elsif ($form{mypart} =~ /^\d+$/ and $form{mypart}) {
 		my $mymsg = (&read_by_part($page))[$form{mypart} - 1];
 		&print_editform($mymsg, &get_info($page, $info_ConflictChecker), admin=>0);
 	# Walrus add [part edit] end
 	} else {
 		&print_editform($database{$page}, &get_info($page, $info_ConflictChecker), admin=>0);
 	}
 	
 	print q(<!--googleon: all-->);
 	&print_footer($page);
 }

 sub do_adminedit {
 	my ($page) = &unarmor_name(&armor_name($form{mypage}));
 	&print_header($page);
 	print qq(\n<!--googleoff: all-->\n);
 	
 	if (not &is_editable($page)) {
 		&print_message($resource{cantchange});
 	# Walrus add [part edit] start
 	} elsif ($form{mypart} =~ /^\d+$/ and $form{mypart}) {
 		my $mymsg = (&read_by_part($page))[$form{mypart} - 1];
 		&print_message($resource{passwordneeded});
 		&print_editform($mymsg, &get_info($page, $info_ConflictChecker), admin=>1);
 	# Walrus add [part edit] end
 	} else {
 		&print_message($resource{passwordneeded});
 		&print_editform($database{$page}, &get_info($page, $info_ConflictChecker), admin=>1);
 	}
 	
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer($page);
 }

 sub do_adminchangepasswordform {
 	&print_header($AdminChangePassword);
 	print qq(\n<!--googleoff: all-->\n);
 	&print_passwordform;
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer($AdminChangePassword);
 }

 sub do_adminchangepassword {
 	if ($form{mynewpassword} ne $form{mynewpassword2}) {
 		&print_error($resource{passwordmismatcherror});
 	}
 	my ($validpassword_crypt) = &get_info($AdminSpecialPage, $info_AdminPassword);
 	if ($validpassword_crypt) {
 		if (not &valid_password($form{myoldpassword})) {
 			&send_mail_to_admin(<<"EOD", "AdminChangePassword");
 myoldpassword=$form{myoldpassword}
 mynewpassword=$form{mynewpassword}
 mynewpassword2=$form{mynewpassword2}
 EOD
 			&print_error($resource{passworderror});
 		}
 	}
 	my ($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime(time);
 	my (@token) = ('0'..'9', 'A'..'Z', 'a'..'z');
 	my $salt1 = $token[(time | $$) % scalar(@token)];
 	my $salt2 = $token[($sec + $min*60 + $hour*60*60) % scalar(@token)];
 	my $crypted = crypt($form{mynewpassword}, "$salt1$salt2");
 	&set_info($AdminSpecialPage, $info_AdminPassword, $crypted);

 	&print_header($CompletedSuccessfully);
 	&print_message($resource{passwordchanged});
 	&print_footer($CompletedSuccessfully);
 }

 sub do_index {
 	my $cache_html;
 	&print_header($IndexPage);
 	print qq(<ul>);

 	if (exists $cachebase{$IndexPage}) {
 		$cache_html = $cachebase{$IndexPage};
 	} else {
 		if(&open_search_index){
 		if(&open_search_index('RDONLY')){
 			for (my $i=0; $i < @search_index; $i++){
 				my $page = $search_index[$i];
 				my $tmp;
 				my $subject;
 				($page,$tmp,$subject) = split(/\t/,$page);
 				$subject = $subject_delimiter . &escape(&escape_subject($subject));
 				
 				$cache_html .= qq(<li><a href="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[$subject]}</li>\n);
 			}
 			&close_search_index;
 		}
 		$cachebase{$IndexPage} = $cache_html;
 	}

 	print "$cache_html";
 	print qq(</ul>);
 	&print_footer($IndexPage);
 }

 sub spam_reject {
 	if($no_spam){
 		if(($form{mymsg} =~ /^([!-~]|\s)+$/i)){
 			&print_header($form{mypage});
 			&print_message($resource{no_spam});
 			&print_footer($form{mypage});
 			exit;
 		}
 	}
 }

 sub do_write {
 	my $mtime;
 	
 	# スパムチェック. アルファベットだけなら拒否
 	if(&spam_reject){
 		return;
 	}
 	
 	if (&frozen_reject()) {
 		return;
 	}

 	if (not &is_editable($form{mypage})) {
 		&print_header($form{mypage});
 		&print_message($resource{cantchange});
 		&print_footer($form{mypage});
 		return;
 	}

 	# Walrus add [part edit] start
 	if ($form{mypart} =~ /^\d+$/ and $form{mypart}) {
 		$form{mymsg} =~ s/\x0D\x0A|\x0D|\x0A/\n/g;
 		$form{mymsg} =~ s/\n*$/\n\n/ if ($form{mymsg});
 		my @parts = &read_by_part($form{mypage});
 		$parts[$form{mypart} - 1] = $form{mymsg};
 		$form{mymsg} = join('', @parts);
 	}
 	# Walrus add [part edit] end

 # 自動リンク処理開始
 	if(&open_autolink_index){
 		for (my $i=0; $i < @autolink_index; $i++){
 			my $pagename = $autolink_index[$i];
 			chomp $pagename;
 			next if $pagename =~ /^\Q$form{mypage}\E$/o;
 			$form{mymsg} =~ s|(?<![\[\[])(\Q$pagename\E)(?![\]\]])|[[$1]]|g;
 		}
 		&close_autolink_index;
 	}
 	
 	# ネストしている[[WikiName]]対策
 	while($form{mymsg} =~ s|\[\[([^\]]*)\[\[([^\]]*)\]\]([^\[]*)\]\]|\[\[$1$2$3\]\]|go){}
 	
 	# プラグイン用[[ ]]消し込み
 	while($form{mymsg} =~ s|\&([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\&$1$2$3\(|g){}
 	while($form{mymsg} =~ s|\&([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\&$1\($2$3$4\)|g){}
 	while($form{mymsg} =~ s|\#([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\#$1$2$3\(|g){}
 	while($form{mymsg} =~ s|\#([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\#$1\($2$3$4\)|g){}
 	
 	# URI用消し込み
 #	while($form{mymsg} =~ s/(mailto|http|https|ftp):([^\]\s]*)\[\[([^\]\s]*)\]\]([^\[\W]*)/$1:$2$3$4/g){}
 	while($form{mymsg} =~ s/(mailto|http|https|ftp):([^\]\s]|[\!-\~]*)\[\[([^\]\s]|[\!-\~]*)\]\](([^\[\s]|[\!-\~]*))/$1:$2$3$4/gi){}
 # 自動リンク処理終了
 	
 	# 競合チェック
 	if (&conflict($form{mypage}, $form{mymsg})) {
 		return;
 	} else {
 		&open_diff;
 		my @msg1 = split(/\r?\n/, $database{$form{mypage}});
 		my @msg2 = split(/\r?\n/, $form{mymsg});
 		$diffbase{$form{mypage}} = &difftext(\@msg1, \@msg2);
 		&close_diff;
 	}
 	
 	$mtime = localtime;
 	if ($form{mymsg}) {
 		# 先にinfobaseだけ更新
 		&set_info($form{mypage}, $info_ConflictChecker, '' . $mtime);
 		&set_info($form{mypage}, $info_IsFrozen, 0 + $form{myfrozen});
 		
 		# 新規ページの場合の処理
 		if(!exists $database{$form{mypage}}){
 			#作成履歴を更新
 			&update_recent_creates('update');
 			
 			# 既存ページへの自動リンク更新処理
 			if(&str_length($form{mypage}) >= $autolink_length){ 
 				# 既存ページへの自動リンク
 				&update_allpages_autolink($form{mypage},'link');
 				# 自動リンク用インデックスの更新
 				&update_autolink_index($form{mypage},'insert');
 			}
 		}
 		
 		# データベースの更新と、検索インデックスの更新
 		$database{$form{mypage}} = $form{mymsg};
 		&update_search_index($form{mypage},$form{mymsg},$mtime);
 		&send_mail_to_admin($form{mypage}, "Modify");
 		
 		# 更新履歴を更新
 		if ($form{mytouch}) {
 			&set_info($form{mypage}, $info_LastModified, '' . $mtime);
 			&update_recent_changes;
 		}
 		
 		# ブラウザへ応答を返す
 		&print_header($CompletedSuccessfully);
 		&print_message($resource{saved});
 		&print_content("$resource{continuereading} @{[&armor_name($form{mypage})]}");
 		&print_footer($CompletedSuccessfully);
 	} else {
 		# ページ削除処理
 		&send_mail_to_admin($form{mypage}, "Delete");
 		
 		# 消し込み作業
 		&update_recent_creates('delete');
 		delete $database{$form{mypage}};
 		delete $infobase{$form{mypage}};
 		&update_recent_changes;
 		&update_search_index($form{mypage},$form{mymsg},$mtime);
 		
 		# リンク解除処理
 		&update_allpages_autolink($form{mypage},'unlink');
 		# 自動リンク用インデックスの更新
 		&update_autolink_index($form{mypage},'delete');
 		
 		&print_header($form{mypage});
 		&print_message($resource{deleted});
 		&print_footer($form{mypage});
 	}
 }

 sub update_autolink_index {
 	my ($target_name,$flag) = @_;
 	
 	if(&open_autolink_index){
 		if($flag eq 'insert') {
 			push(@autolink_index,$target_name);
 		} elsif ($flag eq 'delete') {
 			for (my $i=0; $i < @autolink_index; $i++) {
 				$autolink_index[$i] =~ s/^\Q$target_name\E\n/\n/;
 			}
 		}
 		# ソート && クローズ
 		&autolink_index_sort;
 		&close_autolink_index;
 	}
 }

 sub update_allpages_autolink {
 	my ($target_name,$flag) = @_;
 	my @tgt_list;
 	my $search_name = lc(&asc($target_name));
 	
 	# 検索結果キャッシュがあれば、それを再利用
 	if (exists $searchcachebase{$search_name}) {
 		foreach my $tmp_idx (split(/\n/,$searchcachebase{$search_name})) {
 			push(@tgt_list,split(/\t/,$tmp_idx));
 		}
 	} elsif (&open_search_index){
 	} elsif (&open_search_index('RDONLY')){
 		for (my $i=0; $i < @search_index; $i++) {
 			my $index_data = $search_index[$i];
 			# 該当ページをリストアップ
 			if($index_data =~ /\Q$search_name\E/){
 			if($index_data =~ /\Q$search_name\E/i){
 				my ($tmp_p_name) = split(/\t/,$index_data);
 				push(@tgt_list,$tmp_p_name);
 			}
 		}
 		&close_search_index;
 	}
 	
 	if($flag eq 'link'){
 		# 自動リンクの処理
 		for (my $i=0; $i < @tgt_list; $i++) {
 			# ターゲット候補(検索結果)に新規ページ名があれば自動リンク
 			$database{$tgt_list[$i]} =~ s|(?<![\[\[])(\Q$target_name\E)(?![\]\]])|[[$1]]|go;
 			
 			# ネストしている[[WikiName]]対策
 			while ($database{$tgt_list[$i]} =~ s|\[\[([^\]]*)\[\[(\Q$target_name\E)\]\]([^\[]*)\]\]|\[\[$1$2$3\]\]|go) {next;}
 			# プラグイン用[[ ]]消し込み
 			$database{$tgt_list[$i]} =~ s|\&([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\&$1$2$3\(|go;
 			$database{$tgt_list[$i]} =~ s|\&([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\&$1\($2$3$4\)|go;
 			$database{$tgt_list[$i]} =~ s|\#([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\#$1$2$3\(|go;
 			$database{$tgt_list[$i]} =~ s|\#([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\#$1\($2$3$4\)|go;
 			$database{$tgt_list[$i]} =~ s/(mailto|http|https|ftp):([^\[\S]*)\[\[\Q$target_name\E\]\]([^\[\S]*)/$1:$2$target_name$3/go;
 		}
 	} elsif ($flag eq 'unlink') {
 		for (my $i=0; $i < @tgt_list; $i++) {
 			# 自動アンリンクの処理
 			# 既存ページでリンクを見つけたら、リンク解除
 			$database{$tgt_list[$i]} =~ s|\[\[(\Q$target_name\E)\]\]|$1|go;
 		}
 	}
 }

 sub update_search_index {
 	my ($name,$contents,$mtime) = @_;
 	my ($subject) = split(/\n/,$contents);
 	my $sort_flag = 0;
 	my $new_index;
 	my $old_index;
 	
 	# [[FrontPage]]の更新はインデックスに含まない
 	if ($name eq $[[FrontPage]]) {
 		$contents = '';
 	}
 	
 	# 全角スペース/記号を半角に変換
 	$contents = &asc($contents);
 		
 	# 改行コードの統一とブランケットネームの消し込み
 	$contents =~ s/\x0D|\x0A|\n|\t|\[\[|\]\]//g;
 	$subject  =~ s/\x0D|\x0A|\n|\t|\[\[|\]\]//g;
 	
 	
 	# 更新日時の数値化
 	$mtime = info_to_digit($mtime);
 	
 	if(&open_search_index){
 	if(&open_search_index('RDWR')){
 		my $index_point = &bsearch($name,\@search_index);
 		$new_index = "$name\t$contents\t$subject\t$mtime";
 		
 		# インデックスのアップデート
 		if ($contents && $index_point >= 0) {
 			# 更新時の処理
 			$old_index = $search_index[$index_point];
 			$search_index[$index_point] = $new_index;
 		} elsif($contents && $index_point == -1) {
 			# 新規追加時の処理
 			push(@search_index,"$new_index");
 			$sort_flag = 1;
 		} elsif(!$contents && $index_point >= 0) {
 			# 削除時の処理
 			$old_index = $search_index[$index_point];
 			
 			# 削除ページはソート後末尾に来るようにチェック
 			$search_index[$index_point] = "\xFF\xFF\xFF\xFF";
 			$sort_flag = 1;
 		}
 		
 		# 追加・削除に伴うインデックスのソート
 		if ($sort_flag) {
 			&search_index_sort;
 		}
 		&close_search_index;
 	}
 	
 	
 	# Search Cache Purge
 	# 検索キャッシュの単語が新旧indexとマッチすれば
 	# ダーティなので捨てる
 	# 効率非重視コード :-)
 	# 
 	while ( my $cname = each(%searchcachebase) ){
 		my (@words) = split(/\s/,$cname);
 		for(my $i=0; $i<@words; $i++){
 			if ($new_index =~ /\Q$words[$i]\E/i || $old_index =~ /\Q$words[$i]\E/i){
 				delete $searchcachebase{$cname} ;
 				last;
 			}
 		}
 	}
 	
 	# cache purge
 	while ( my $cname = each(%cachebase) ){
 		delete $cachebase{$cname} ;
 	}
 }

 sub do_searchform {
 	my $rawcontent = qq(*$resource{recentsearchesbutton});
 	
 	&print_header($SearchPage);
 	print qq(\n<!--googleoff: all-->\n);
 	
 	print qq(<div class="h1level">);
 	&print_searchform("");
 	
 	print &text_to_html($rawcontent, toc=>0, partinfo=>0);
 	&print_cache($[[RecentSearches]]);
 	print qq(</div>);
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer($SearchPage);
 }

 sub do_search {
 	# 全角スペースを半角に変換
 	my $word = &asc(&escape($form{mymsg}));
 	my $html;
 	
 	&print_header($SearchPage);
 	&print_searchform($word);
 	
 	$html = do_searchresult($word,'NAM+',0);
 	if ($html) {
 		print qq|$html|;
 	} else {
 		&print_message($resource{notfound});
 	}
 	&print_footer($SearchPage);
 }

 sub month_to_digit{
 	my ($mon) = @_;
 	my %month = ("jan" => "01"
 				,"feb" => "02"
 				,"mar" => "03"
 				,"apr" => "04"
 				,"may" => "05"
 				,"jun" => "06"
 				,"jul" => "07"
 				,"aug" => "08"
 				,"sep" => "09"
 				,"oct" => "10"
 				,"nov" => "11"
 				,"dec" => "12"
 				);

 	while(my ($key, $tgt) = each(%month)){
 		$mon =~ s/(.*)$key(.*)/$tgt/i;
 	}
 	return $mon;
 }

 sub info_to_digit{
 	my ($info) = @_;
 # Mon Oct 11 00:32:28 2004
 	my ($weekday, $mon, $day, $times, $year) = split(/\s+/, $info);
 	my ($hour, $min, $sec) = split(/:/, $times);

 	$mon = month_to_digit($mon);
 	$info = sprintf("%04d%02d%02d%02d%02d%02d", $year, $mon, $day, $hour, $min, $sec);
 	return $info;
 }

 sub do_searchresult {
 	my ($argword,$keyopt,$loop_cnt)  = @_;
 	$loop_cnt = 0 if $loop_cnt == '';
 	my $cache_key;
 	my $recent_key = $argword;
 	
 	my $counter = 0;
 	my $html;
 	my %name_list; my %mod_list; my %access_list;
 	my $sortopt;
 	
 	my @words;
 	my @tmpwords;
 	my $page_hit_cnt;
 	
 	$argword = &unescape($argword);
 	$argword = lc($argword);
 	$argword = &asc($argword);
 	# "   "でくくられたキー抽出
 	for (my $cnt = 0; $argword =~ s/"([^"]*)"//; $cnt++){
 		$words[$cnt] = $1;
 	}
 	$argword =~ s|^\s||;
 	@tmpwords = split(/\s+/, $argword);
 	@words = (@words, @tmpwords);
 	
 	# 検索キーワードの整列とキャッシュキーの生成
 	if(@words){
 		(@words) = sort @words;
 		$cache_key = join("\t",@words);
 	} else {
 		return undef;
 	}
 	
 	# 検索キャッシュ検索 or インデックス検索
 	if (exists $searchcachebase{$cache_key}) {
 		foreach my $cache_string (split(/\n/,$searchcachebase{$cache_key})) {
 			my ($page,$idx_subject,$mtime) = split(/\t/,$cache_string);
 			$name_list{$page} = &escape($idx_subject);
 			$mod_list{$page} = $mtime;
 			if($keyopt =~ /ACC/i) { $access_list{$page} = &get_info($page, $info_UniqAccessCount); }
 			$counter++;
 		}
 	} elsif(&open_search_index){
 	} elsif(&open_search_index('RDONLY')){
 		my $tmp_search_cache;
 		for (my $i=0; $i < @search_index; $i++){
 			my ($page,$idx_contents,$idx_subject,$mtime) = split(/\t/o,$search_index[$i]);
 			for (my $cnt=0,$page_hit_cnt=0; $cnt < @words; $cnt++) {
 				if ($idx_contents =~ /\Q$words[$cnt]\E/i or $page =~ /\Q$words[$cnt]\E/i) {
 					$page_hit_cnt++;
 				}
 			}
 			
 			if($page_hit_cnt == @words){
 				$name_list{$page} = &escape($idx_subject);
 				chomp $mtime;
 				$mod_list{$page} = $mtime;
 				if($keyopt =~ /ACC/io) { $access_list{$page} = &get_info($page, $info_UniqAccessCount); }
 				$counter++;
 				$tmp_search_cache .= "$page\t$idx_subject\t$mtime\n";
 			}
 		}
 		if (length($cache_key) < $max_cache_length) {
 			$searchcachebase{$cache_key} = $tmp_search_cache;
 		}
 		&close_search_index;
 	}
 	
 	# ここからソート & html化
 	if ($counter == 0) {
 		$searchcachebase{$cache_key} = "\n";
 		$html .= "";
 	} elsif ($counter == 1 && (exists $name_list{$form{mypage}})){
 		$html .= "";
 	} else {
 		if ($keyopt eq 'NAM+') {		# Sort Order by PageName
 			$sortopt = 'sort keys %name_list';
 		} elsif ($keyopt eq 'MOD+') {	# Sort Order by LastMod
 			$sortopt = 'sort {$mod_list{$a} <=> $mod_list{$b} or $a cmp $b} keys %mod_list';
 		} elsif ($keyopt eq 'SBJ+') {	# Sort Order by Subject
 			$sortopt = 'sort {$name_list{$a} cmp $name_list{$b} or $a cmp $b} keys %name_list';
 		} elsif ($keyopt eq 'ACC+' or $keyopt eq 'acc+' ) {	# Sort Order by Access Count
 			$sortopt = 'sort {$access_list{$a} <=> $access_list{$b} or $a cmp $b} keys %access_list';
 		
 		} elsif ($keyopt eq 'NAM-') {	# Sort Order by PageName DESC
 			$sortopt = 'sort { $b cmp $a } keys %name_list';
 		} elsif ($keyopt eq 'MOD-') {	# Sort Order by LastMod DESC
 			$sortopt = 'sort {$mod_list{$b} <=> $mod_list{$a} or $b cmp $a} keys %mod_list';
 		} elsif ($keyopt eq 'SBJ-') {	# Sort Order by Subject DESC
 			$sortopt = 'sort {$name_list{$b} cmp $name_list{$a} or $b cmp $a} keys %name_list';
 		} elsif ($keyopt eq 'ACC-' or $keyopt eq 'acc-' ) {	# Sort Order by Access Count
 			$sortopt = 'sort {$access_list{$b} <=> $access_list{$a} or $b cmp $a} keys %access_list';
 		
 		} else {						# Sort Order by DEFAULT
 			$sortopt = 'sort keys %name_list';
 		}
 		
 		$html .= qq|<ul>|;
 		foreach my $page (eval $sortopt) {
 			next if $page eq $form{mypage};
 			if ($keyopt =~ /\Qacc\E/o) {
 				$html .= qq(<li><a href ="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[&escape(&get_subjectline($page))]}   $access_list{$page}access.</li>\n); 
 			} else {
 				$html .= qq(<li><a href ="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[&escape(&get_subjectline($page))]}</li>\n); 
 			}
 			$loop_cnt--;
 			if ($loop_cnt == 0) {last;}
 		}
 		$html .= qq|</ul>|;
 	}
 	
 # For debug
 #	$html .= join("<br>",@words);
 	
 	&update_recent_searches($recent_key,$counter);
 	return $html;
 }


 sub do_create {
 	&print_header($CreatePage);
 	print qq(\n<!--googleoff: all-->\n);
 	
 	print <<"EOD";

 <div class="form">
 <form action="$action_url" method="post">
     <input type="hidden" name="mycmd" value="edit">
     <strong>$resource{newpagename}</strong><br>
     <input class="createpage" type="text" name="mypage" value="" size="60">
     <input class="createpage" type="submit" value="$resource{createbutton}"><br>
 </form>
 </div>
 EOD
 	
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer($CreatePage);
 }

 sub do_[[FrontPage]] {
 	if ($fixedpage{$[[FrontPage]]}) {
 		open(FILE, $file_[[FrontPage]]) or &print_error("($file_[[FrontPage]])");
 		my $content = join('', <FILE>);
 		$content = &code_convert(\$content, $kanjicode);
 		close(FILE);
 		&print_header($[[FrontPage]]);
 		&print_content($content);
 		&print_footer($[[FrontPage]]);
 	} else {
 		$form{mycmd} = 'read';
 		$form{mypage} = $[[FrontPage]];
 		&do_read;
 	}
 }

 sub print_error {
 	my ($msg) = @_;
 	&print_header($ErrorPage);
 	print qq(<p><strong class="error">$msg</strong></p>);
 	&print_plugin_log;
 	&print_footer($ErrorPage);
 	exit(0);
 }

 sub print_header {
 	my ($page) = @_;
 	my $bodyclass = "normal";
 	my $editable = 0;
 	my $admineditable = 0;
 	my $editmode = 0;
 	my $favicon = 0;
 	
 	
 	if($modifier_favicon =~ /\.ico$/){
 		$favicon = 1;
 	}
 	
 	if($form{mycmd} =~ /edit$/ or $form{mycmd} =~ /^diff$/) {
 		$editmode = 1;
 	} elsif (&is_frozen($page) and $form{mycmd} =~ /^(read|write)$/) {
 		$editable = 0;
 		$admineditable = 1;
 		$bodyclass = "frozen";
 	} elsif (&is_editable($page) and $form{mycmd} =~ /^(read|write)$/) {
 		$admineditable = 1;
 		$editable = 1;
 	} else {
 		$editable = 0;
 	}
 	my $cookedpage = &encode($page);
 	my $escapedpage = &escape($page);
 	my $escapedsubject = &escape(&get_subjectline($page));
 	my $cookedpage_search = $cookedpage;
 	$escapedsubject =~ s/$subject_delimiter//;
 	# スペース入りのページ名なら「"」でくくる
 	if ($cookedpage_search =~ /%20/) {
 		$cookedpage_search = '%22' . $cookedpage_search . '%22';
 	}
 	
 	print <<"EOD";
 Content-type: text/html; charset=$charset

 <!DOCTYPE html
     PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
     "http://www.w3.org/TR/html4/loose.dtd">
 <html lang="$lang">
 <head>
     <meta http-equiv="Content-Language" content="$lang">
     <meta http-equiv="Content-Type" content="text/html; charset=$charset">
     @{[ $editmode
         ? qq(<meta name="robots" content="nofollow,noindex">)
         : qq()
     ]}
     @{[ $editable
         ? qq(<meta name="keywords" content="$escapedpage,$escapedsubject">)
         : qq()
     ]}
     <title>[$modifier_rss_title] $escapedpage @{[&escape(&get_subjectline($page))]}</title>
     <link rel="index" href="$url_cgi?$IndexPage">
     <link rev="made" href="mailto:$modifier_mail">
     <link rel="stylesheet" type="text/css" href="$url_stylesheet">
     <link rel="alternate" type="application/rss+xml" title="RSS" href="$modifier_rss_link?RssPage" />
     <link rel="alternate" type="application/rss+xml" title="RSS" href="$modifier_rss_link?RssPage">
     @{[ $favicon
         ? qq(<link rel="shortcut icon" href="$modifier_favicon">)
         : qq()
     ]}
 </head>
 <body class="$bodyclass">
 <!--googleoff: all-->
 <div class="tools">
     <a title="$resource{frontpage}" href="$url_cgi?" rel="nofollow">$resource{frontpage}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{createbutton}" href="$url_cgi?$CreatePage" rel="nofollow">$resource{createbutton}</a> <span class="toolsborder"> | </span> 
     @{[ $admineditable
         ? qq(<a title="$resource{admineditthispage}" href="$url_cgi?mycmd=adminedit&amp;mypage=$cookedpage" rel="nofollow">$resource{admineditbutton}</a> <span class="toolsborder"> | </span>)
         : qq()
     ]}
     @{[ $editable
         ? qq(<a title="$resource{editthispage}" href="$url_cgi?mycmd=edit&amp;mypage=$cookedpage" rel="nofollow">$resource{editbutton}</a> <span class="toolsborder"> | </span>)
         : qq()
     ]}
     @{[ $admineditable
         ? qq(<a title="$resource{diffbutton}" href="$url_cgi?mycmd=diff&amp;mypage=$cookedpage" rel="nofollow">$resource{diffbutton}</a> <span class="toolsborder"> | </span>)
         : qq()
     ]}
     <a title="$resource{indexbutton}" href="$url_cgi?$IndexPage" rel="nofollow">$resource{indexbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{rssbutton}" href="$url_cgi?$RssPage" rel="nofollow">$resource{rssbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{searchbutton}" href="$url_cgi?$SearchPage" rel="nofollow">$resource{searchbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{recentsearchesbutton}" href="$url_cgi?$[[RecentSearches]]" rel="nofollow">$resource{recentsearchesbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{recentreadsbutton}" href="$url_cgi?$[[RecentReads]]" rel="nofollow">$resource{recentreadsbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{recentcreatesbutton}" href="$url_cgi?$[[RecentCreates]]" rel="nofollow">$resource{recentcreatesbutton}</a> <span class="toolsborder"> | </span> 
     <a title="$resource{recentchangesbutton}" href="$url_cgi?$[[RecentChanges]]" rel="nofollow">$resource{recentchangesbutton}</a>
 </div>
 <div class="document-body"><a name="top">
 <div class="document-body"><a name="top"></a>
 <h1 class="header"><a
     title="$resource{searchthispage}"
     href="$url_cgi?mycmd=search&amp;mymsg=$cookedpage_search" rel="nofollow">@{[&escape($page)]}</a> @{[&escape(&get_subjectline($page))]}</h1>
 <!--googleon:  all-->
 EOD
 }

 sub total_access_count{
 	my ($page) = @_;
 	my $total;

 	$total = &get_info($page, $info_TotalAccessCount) +1;
 	&set_info($page, $info_TotalAccessCount,$total);

 	return $total;
 }

 sub uniq_access_count{
 	my ($page) = @_;
 	my $count = &get_info($page, $info_UniqAccessCount);
 	if ($ENV{'REMOTE_ADDR'} ne &get_info($page, $info_LastAccessIP)) {
 		$count += 1;
 		&set_info($page, $info_LastAccessIP, $ENV{'REMOTE_ADDR'});
 		&set_info($page, $info_UniqAccessCount, $count);
 	}
 	return $count;
 }

 sub print_footer {
 	my ($page) = @_;

 	my ($page_cnt,$count,$total);
 	my $lastmod;

 # Sun May 8 13:52:17 2005
 	if (!$fixedpage{$page} && $form{mycmd} eq 'read') {
 		my ($dow,$mon,$day,$time,$year);
 		my $tmp = &get_info($page, $info_ConflictChecker);
 		$tmp =~ /(...)\s(...)\s*(\d*)\s([^\s]*)\s(.*)/;
 		$dow = $1; $mon = $2; $day = $3; $time = $4; $year= $5; 
 		$mon = month_to_digit($mon);
 		$day = "0$day" if $day < 10; 
 		$lastmod = '<hr>'."\n".'<p class="footer">'.$resource{lastmod}.$year.'-'.$mon.'-'.$day.' ('.$dow.') '.$time.'</p>';
 	}

 # アクセスカウンタ処理
 	if(!$form{robots}){
 		$total = &total_access_count($ACPage);
 		$count = &uniq_access_count($ACPage);
 		$page_cnt = &uniq_access_count($page);
 	}
 	
 # いきなり</div>で始まっているのは、
 # print_headerの<div class="document-body">と対応させている為
 # キタナイのでそのうち修正します。

 # DEBUG
 #if($searchtime){
 #	$searchtime = int((Time::HiRes::time - $searchtime)*1000)/1000;
 #	$searchtime = "\n<br>$searchtime sec.\n";
 #}
 if($searchtime){
 	$searchtime = int((Time::HiRes::time - $searchtime)*1000)/1000;
 	$searchtime = "\n<br>$searchtime sec.\n";
 	
 	my $la = `uptime`;
 	$la =~ /load averages: (\d*\.\d\d), (\d*\.\d\d), (\d*\.\d\d)/;
 	$searchtime .= "<br>Load Averages: $1 $2 $3";
 }
 	print <<"EOD";
 </div>
 <div class="partinfo"><a class="partedit" title="$resource{returntop}" href="#top">$resource{returntop}</a></div>
 $lastmod
 <hr>
 <!--googleoff: all-->
 <address class="footer">
     <a href="http://ponytail.jpn.org/lightnovel/">PonyWiki</a> ver $version (C) 2004-2006 by <a href="http://you-like.to/cgi-bin/ponytail/yukiwiki/wiki.cgi">Kisara</a>.<br />
     <a href="http://ponytail.jpn.org/lightnovel/">PonyWiki</a> ver $version (C) 2004-2006 by <a href="http://you-like.to/cgi-bin/ponytail/yukiwiki/wiki.cgi" title="AUTHOR">Kisara</a>.<br>
     based on <a href="http://www.hyuki.com/yukiwiki/">YukiWiki</a> $orgversion
     (C) 2000-2004 by <a href="http://www.hyuki.com/">Hiroshi Yuki</a>.<br />
     Modified by <a href="$modifier_url">$modifier_name</a>.<br />
     (C) 2000-2004 by <a href="http://www.hyuki.com/">Hiroshi Yuki</a>.<br>
     Modified by <a href="$modifier_url" title="modifier_name">$modifier_name</a>.<br>
     $resource{license_notice}<br>
 </address>
 <p class="footer">$icontag <br><font color="ffffff">$page_cnt/$count/$total</font>
 <p class="footer">$icontag <br><font color="#ffffff">$page_cnt/$count/$total</font>
 $searchtime
 </p>
 <!--googleon:  all-->
 </body>
 </html>
 EOD
 }

 sub escape {
 	my $s = shift;
 #	$s =~ s|\r\n|\n|g;
 	$s =~ s|\&|&amp;|g;
 	$s =~ s|<|&lt;|g;
 	$s =~ s|>|&gt;|g;
 	$s =~ s|"|&quot;|g;
 	return $s;
 }

 sub unescape {
 	my $s = shift;
 	# $s =~ s|\n|\r\n|g;
 	$s =~ s|\&amp;|\&|g;
 	$s =~ s|\&lt;|\<|g;
 	$s =~ s|\&gt;|\>|g;
 	$s =~ s|\&quot;|\"|g;
 	return $s;
 }

 sub do_read_cache{
 	my ($page) = @_;
 	my $cache_html;
 	my ($no_cache_flag,$ng_word);

 	if (not exists $cachebase{$page}) {
 		if ($form{keitai}){$no_cache_flag = 1;}
 		foreach $ng_word (@no_cache_word){
 			if ($database{$page} =~ /\Q$ng_word\E/i || $page =~ /\Q$ng_word\E/i) { $no_cache_flag = 1;}
 		}
 		$cache_html = &text_to_html($database{$page}, toc=>1, partinfo=>1);
 		if (!$no_cache_flag){
 			$cachebase{$page} = $cache_html;
 		}
 	} else {
 		$cache_html = $cachebase{$page};
 	}
 	
 	return $cache_html;
 }

 sub print_cache{
 	my ($page) = @_;
 	print &do_read_cache($page);
 }

 sub print_content {
 	my ($rawcontent) = @_;
 	print &text_to_html($rawcontent, toc=>1, partinfo=>1);  # Walrus add [part edit]
 }

 sub text_to_html {
 	my ($txt, %option) = @_;

 	my (@toc);
 	my $verbatim;
 	my $tocnum = 0;
 	my (@saved, @result);

 	my @open_tag;
 	my ($depth, $nest_1st);

 	push(@result, "<p>");
 	unshift(@saved, "</p>");

 	foreach (split(/\r?\n/, $txt)) {
 		chomp;
 		# verbatim.
 		if ($verbatim->{func}) {
 			if (/^\Q$verbatim->{done}\E$/) {
 				undef $verbatim;
 				push(@result, splice(@saved));
 			} else {
 				push(@result, $verbatim->{func}->($_));
 			}
 			next;
 		}
 		
 		# non-verbatim follows.
 		push(@result, shift(@saved)) if (@saved and $saved[0] eq '</pre>' and /^[^ \t]/);
 		
 		if (/^(\*{1,5})(.+)/) {
 			# $hn = 'h2', 'h3', 'h4', 'h5' or 'h6'
 			my $hn = "h" . (length($1) + 1);
 			# Set $nest_1st
 			if (!$nest_1st) { $nest_1st = length($1);}
 			#
 			my $tmp_depth = length($1);
 		
 			if($depth == $tmp_depth) {
 				push(@result, splice(@saved), qq(</div>\n<$hn><a name="i$tocnum"> </a>) . &inline($2) . qq(</$hn>\n<div class="$hn).qq(level">));
 				push(@result, splice(@saved), qq(</div>\n<$hn><a name="i$tocnum"></a>) . &inline($2) . qq(</$hn>\n<div class="$hn).qq(level">));
 			} elsif ($depth < $tmp_depth) { # nest inc →
 				push(@result, splice(@saved), qq(<$hn><a name="i$tocnum"> </a>) . &inline($2) . qq(</$hn>\n<div class="$hn).qq(level">));
 				push(@result, splice(@saved), qq(<$hn><a name="i$tocnum"></a>) . &inline($2) . qq(</$hn>\n<div class="$hn).qq(level">));
 				$depth = $tmp_depth;
 				$open_tag[$depth] = 1;
 			} elsif ($depth > $tmp_depth) { # nest dec ←
 				$depth = $tmp_depth;
 				my $open_tag_cnt;
 				my $i;
 				
 				if($nest_1st > $tmp_depth) {
 					$nest_1st = $tmp_depth;
 					$i = 1;
 				} else {
 					$i=$depth;
 				}
 				for(; $i < 7; $i++){
 					$open_tag_cnt = $open_tag_cnt + $open_tag[$i];
 					$open_tag[$i] = 0;
 				}
 				
 				if($open_tag_cnt){
 					push(@result, splice(@saved));
 				}
 				while($open_tag_cnt) {
 					push(@result,qq(</div>));
 					$open_tag_cnt--;
 				}
 				push(@result, splice(@saved), qq(<$hn><a name="i$tocnum"> </a>) . &inline($2) . qq(</$hn><div class="$hn).qq(level">));
 				push(@result, splice(@saved), qq(<$hn><a name="i$tocnum"></a>) . &inline($2) . qq(</$hn><div class="$hn).qq(level">));
 				$open_tag[$depth] = 1;
 			}
 			
 			if($form{keitai}){
 				my $index_no = $tocnum +2;
 				my $cookedpage = &encode($form{mypage});
 				if($tocnum < 10){
 					push(@toc, '-' x length($1) . qq( <a href="$url_cgi?mycmd=read&amp;mypage=$cookedpage&amp;mypart=$index_no" accesskey="$tocnum">$tocnum: ) . &remove_tag(&inline($2)) . qq(</a>\n));
 				} else {
 					push(@toc, '-' x length($1) . qq( <a href="$url_cgi?mycmd=read&amp;mypage=$cookedpage&amp;mypart=$index_no">) . &remove_tag(&inline($2)) . qq(</a>\n));
 				}
 			} else {
 				push(@toc, '-' x length($1) . qq( <a href="#i$tocnum">) . &remove_tag(&inline($2)) . qq(</a>\n));
 				push(@toc, '-' x length($1) . qq( <a href="#i$tocnum" title="index_$tocnum">) . &remove_tag(&inline($2)) . qq(</a>\n));
 			}

 # part edit
 			if(!$form{mypart}){ # (携帯電話向け)部分読みの時は部分編集は表示しない
 				my $cookedpage = &encode($form{mypage});
 				$cookedpage =~ s/%/%%/g;
 				push(@result, sprintf(qq(<div class="partinfo"><a class="partedit" title="$resource{editthispart}" href="$url_cgi?mycmd=edit&amp;mypage=$cookedpage&amp;mypart=%d">$resource{editthispart}</a> <a class="partedit" title="$resource{returntop}" href="$url_cgi?$cookedpage#top">$resource{returntop}</a></div>), $tocnum + 2)) if ($option{'partinfo'});		# Walrus add [part edit]
 				push(@result, "<p>");
 				unshift(@saved, "</p>");
 			}
 			$tocnum++;
 		} elsif (/^(-{2,3})\($/) {
 			if ($& eq '--(') {
 				$verbatim = { func => \&inline, done => '--)', class => 'verbatim-soft' };
 			} else {
 				$verbatim = { func => \&escape, done => '---)', class => 'verbatim-hard' };
 			}
 			&back_push('pre', 1, \@saved, \@result, " class='$verbatim->{class}'");
 		} elsif (/^\/\//) {
 			# This is comment out. nop.
 		} elsif (/^----/) {
 			push(@result, splice(@saved), '<hr>');
 		} elsif (/^(-{1,3})(.+)/) {
 			&back_push('ul', length($1), \@saved, \@result);
 			push(@result, '<li>' . &inline($2) . '</li>');
 		} elsif (/^(={1,3})(.+)/) {
 			&back_push('ol', length($1), \@saved, \@result);
 			push(@result, '<li>' . &inline($2) . '</li>');
 		} elsif (/^:([^:]+):(.+)/) {
 			&back_push('dl', 1, \@saved, \@result);
 			push(@result, '<dt>' . &inline($1) . '</dt>', '<dd>' . &inline($2) . '</dd>');
 		} elsif (/^(>{1,3})(.+)/) {
 			&back_push('blockquote', length($1), \@saved, \@result);
 			push(@result, &inline($2));
 		} elsif (/^$/) {
 			push(@result, splice(@saved));
 			unshift(@saved, "</p>");
 			push(@result, "<p>");
 		} elsif (/^(\s+.*)$/) {
 			&back_push('pre', 1, \@saved, \@result);
 			push(@result, &escape($1)); # Not &inline, but &escape
 		} elsif (/^\,(.*?)[\x0D\x0A]*$/) {
 			&back_push('table', 1, \@saved, \@result, ' border="1"');
 			#######
 			# This part is taken from Mr. Ohzaki's Perl Memo and Makio Tsukamoto's [[WalWiki]].
 			# XXXXX
 			my $tmp = "$1,";
 			my @value = map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_} ($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
 			my @align = map {(s/^\s+//) ? ((s/\s+$//) ? ' align="center"' : ' align="right"') : ''} @value;
 			my @colspan = map {($_ eq '==') ? 0 : 1} @value;
 			for (my $i = 0; $i < @value; $i++) {
 				if ($colspan[$i]) {
 					while ($i + $colspan[$i] < @value and $value[$i + $colspan[$i]] eq '==') {
 						$colspan[$i]++;
 					}
 					$colspan[$i] = ($colspan[$i] > 1) ? sprintf(' colspan="%d"', $colspan[$i]) : '';
 					$value[$i] = sprintf('<td%s%s>%s</td>', $align[$i], $colspan[$i], &inline($value[$i]));
 				} else {
 					$value[$i] = '';
 				}
 			}
 			push(@result, join('', '<tr>', @value, '</tr>'));
 			# XXXXX
 			#######
 		} elsif (/^\#(\w+)(\((.*)\))?/) {
 			# BlockPlugin.
 			my $original_line = $_;
 			my $plugin_name = $1;
 			my $argument = &escape($3);
 			my $result = $plugin_manager->call($plugin_name, 'block', $argument);
 			if (defined($result)) {
 				push(@result, splice(@saved));
 			} else {
 				$result = $original_line;
 			}
 			push(@result, $result);
 		} else {
 			push(@result, &inline($_));
 		}
 	}
 #
 	if ($depth > 0) { # 見出しの<div>を全てクローズ
 		my $open_tag_cnt;
 		
 		for(my $i; $i < 7; $i++){
 			$open_tag_cnt = $open_tag_cnt + $open_tag[$i];
 			$open_tag[$i] = 0;
 		}
 		
 		if($open_tag_cnt){
 			push(@result, splice(@saved));
 		}
 		while($open_tag_cnt) {
 			push(@result,qq(</div>));
 			$open_tag_cnt--;
 		}
 	}
 #
 	push(@result, splice(@saved));
 	
 	if ($option{toc} && !$form{mypart}) {
 		# Convert @toc (table of contents) to HTML.
 		# This part is taken from Makio Tsukamoto's [[WalWiki]].
 		my (@tocsaved, @tocresult);
 		foreach (@toc) {
 			if (/^(-{1,5})(.*)/) {
 				&back_push('ul', length($1), \@tocsaved, \@tocresult);
 				push(@tocresult, '<li>' . $2 . '</li>');
 			}
 		}
 		push(@tocresult, splice(@tocsaved));
 		
 		# Insert "table of contents".
 		if (@tocresult) {
 			unshift(@tocresult, qq(<h2>$resource{table_of_contents}</h2>));
 		# Insert CSS <div class="index"> - </div>
 			unshift(@tocresult, qq(<div class="index">));
 			push(@tocresult, "</div>");
 		}
 		
 		unshift(@result, qq(<div class="h1level">));
 		push(@result, qq(</div>));
 		my $return_html = join("\n",@tocresult,@result);
 		$return_html =~ s/<p>\n<\/p>//mg;
 		
 		return $return_html;
 	} else {
 		my $return_html = join("\n",@result);
 		$return_html =~ s/<p>\n<\/p>//mg;
 		
 		return $return_html;
 	}
 }

 sub back_push {
 	my ($tag, $level, $savedref, $resultref, $attr) = @_;
 	while (@$savedref > $level) {
 		push(@$resultref, shift(@$savedref));
 	}
 	if ($savedref->[0] ne "</$tag>") {
 		push(@$resultref, splice(@$savedref));
 	}
 	while (@$savedref < $level) {
 		unshift(@$savedref, "</$tag>");
 		push(@$resultref, "<$tag$attr>");
 	}
 }

 sub remove_tag {
 	my ($line) = @_;
 	$line =~ s|\<\/?[A-Za-z][^>]*?\>||g;
 	return $line;
 }

 sub inline {
 	my ($line) = @_;
 	$line = &escape($line);
 	$line =~ s|(\d\d\d\d-\d\d-\d\d \(\w\w\w\) \d\d:\d\d:\d\d)|<span class="date">$1</span>|g;   # Date
 	$line =~ s!
 				(
 					((mailto|http|https|ftp):([^\x00-\x20()<>[\x7F-\xFF])*)  # Direct http://...
 #					((mailto|http|https|ftp):([^\x00-\x20()<>\x7F-\xFF])*)  # Direct http://...
 						|
 					($bracket_name)			 # [[likethis]], [[#comment]], [[Friend:remotelink]]
 						|
 					($wiki_name)				# LocalLinkLikeThis
 						|
 					($inline_plugin)			# &user_defined_plugin(123,hello)
 				)
 			!
 				&make_link($1)
 			!gex;
 	return $line;
 }

 sub make_link {
 	my $chunk = shift;
 	if ($chunk =~ /^(http|https|ftp):/) {
 		if ($use_autoimg and $chunk =~ /\.(gif|png|jpeg|jpg)$/) {
 			return qq(<a href="$chunk" rel="nofollow"><img src="$chunk"></a>);
 		} else {
 			return qq(<a href="$chunk" rel="nofollow">$chunk</a>);
 		}
 	} elsif ($chunk =~ /^(mailto):(.*)/) {
 		return qq(<a href="$chunk">$2</a>);
 	} elsif ($chunk =~ /^$embedded_name$/) {
 		return &embedded_to_html($chunk);
 	} elsif ($chunk =~ /^$inline_plugin$/) {
 		# InlinePlugin.
 		my $plugin_name = $1;
 		my $argument = $2;
 		my $result = $plugin_manager->call($plugin_name, 'inline', $argument);
 		if (defined($result)) {
 			return $result;
 		} else {
 			return $chunk;
 		}
 	} else {
 		$chunk = &unarmor_name($chunk);
 		$chunk = &unescape($chunk); # To treat '&' or '>' or '<' correctly.
 		my $cookedchunk = &encode($chunk);
 		my $escapedchunk = &escape($chunk);

 		if ($database{$chunk}) {
 			my $subject = &escape(&get_subjectline($chunk, delimiter => ''));
 			return qq(<a title="$subject" href="$url_cgi?$cookedchunk">$escapedchunk</a>);
 		} elsif ($page_command{$chunk}) {
 			return qq(<a title="$escapedchunk" href="$url_cgi?$cookedchunk">$escapedchunk</a>);
 		} else {
 			return qq($escapedchunk<a title="$resource{editthispage}" class="editlink" href="$url_cgi?mycmd=edit&amp;mypage=$cookedchunk">$editchar</a>);
 		}
 	}
 }

 sub print_message {
 	my ($msg) = @_;
 	print qq(<p><strong>$msg</strong></p>);
 }

 sub init_form {
 	if (param()) {
 		foreach my $var (param()) {
 			$form{$var} = param($var);
 		}
 	} else {
 		$ENV{QUERY_STRING} = $[[FrontPage]];
 	}

 	my $query = &decode($ENV{QUERY_STRING});
 	if ($page_command{$query}) {
 		$form{mycmd} = $page_command{$query};
 		$form{mypage} = $query;
 	} elsif ($query =~ /^($wiki_name)$/) {
 		$form{mycmd} = 'read';
 		$form{mypage} = $1;
 	} elsif ($database{$query}) {
 		$form{mycmd} = 'read';
 		$form{mypage} = $query;
 	}
 	
 	# mypreview_edit		-> do_edit, with preview.
 	# mypreview_adminedit   -> do_adminedit, with preview.
 	# mypreview_write	   -> do_write, without preview.
 	foreach (keys %form) {
 		if (/^mypreview_(.*)$/) {
 			$form{mycmd} = $1;
 			$form{mypreview} = 1;
 		}
 	}
 	
 	# 存在しないページ名で且つコマンドじゃない場合は、検索へ飛ばす準備
 	# $form{mycmd} is frozen here.
 	# $form{mypage} is frozen here.
 	if (!$form{mycmd}) {
 		$form{mypage} = $query;
 	}
 	
 	# とりあえず、最初に文字コード変換
 	$form{mymsg}  = &code_convert(\$form{mymsg}, $kanjicode);
 	$form{myname} = &code_convert(\$form{myname}, $kanjicode);
 	$form{mypage} = &code_convert(\$form{mypage}, $kanjicode);

 # Admin ONLY MODE
 	if ($admin_only_mode) {
 		$form{myfrozen} = 1;
 	}
 	
 # 携帯電話かどうかのチェック (かなり手抜き)
 		$form{keitai} = &is_mobile;
 		$plugin_context->{keitai} = $form{keitai};
 # ロボットかどうかのチェック (相当手抜き)
 		$form{robots} = &is_robots;
 # USER Agentをプラグインに渡す
 	$form{user_agent} = $ENV{'HTTP_USER_AGENT'};

 }

 sub is_mobile {
 	if(	$ENV{'HTTP_USER_AGENT'} =~ /UP\.BROWSER/i	||
 		$ENV{'HTTP_USER_AGENT'} =~ /DoCoMo/i		||
 		$ENV{'HTTP_USER_AGENT'} =~ /KDDI/i			||
 		$ENV{'HTTP_USER_AGENT'} =~ /Vodafone/i		||
 		$ENV{'HTTP_USER_AGENT'} =~ /jig browser/i	||
 		$ENV{'HTTP_USER_AGENT'} =~ /J-PHONE/i) { 
 		
 		return 1;
 		
 	} else {
 		return 0;
 	}
 }

 sub is_robots {
 	if(	$ENV{'HTTP_USER_AGENT'} =~ /crawler/i ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Spider/i ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Bot/i ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Slurp/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /J-BSC/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /J-DSC/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Hatena Antenna/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Mediapartners-Google/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /findlinks/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Infoseek SideWinder/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /Wget/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /ichiro/ ||
 		$ENV{'HTTP_USER_AGENT'} =~ /findlinks/) {
 	
 		return 1;
 		
 	} else {
 		return 0;
 	}
 }

 # update_recent_なんとかは、統合予定
 sub update_recent_changes {
 	my $update = "- @{[&get_now]} @{[&armor_name($form{mypage})]} @{[&get_subjectline($form{mypage})]}";
 	my @oldupdates = split(/\r?\n/, $database{$[[RecentChanges]]});
 	my @updates;
 	foreach (@oldupdates) {
 		/^\- \d\d\d\d\-\d\d\-\d\d \(...\) \d\d:\d\d:\d\d ($bracket_name)/o;   # date format.
 		my $name = &unarmor_name($1);
 		if (&is_exist_page($name) and ($name ne $form{mypage})) {
 			push(@updates, $_);
 		}
 	}
 	if (&is_exist_page($form{mypage})) {
 		unshift(@updates, $update);
 	}
 	splice(@updates, $maxrecent + 1);
 	$recentbase{$[[RecentChanges]]} = join("\n", @updates);
 	if ($file_touch) {
 		open(FILE, "> $file_touch");
 		print FILE localtime() . "\n";
 		close(FILE);
 	}
 }

 sub update_recent_creates {
 	my ($opt) = @_;
 	my $update;
 	my @oldupdates = split(/\r?\n/, $database{$[[RecentCreates]]});
 	my @updates;
 	
 	foreach (@oldupdates) {
 		/^\- \d\d\d\d\-\d\d\-\d\d \(...\) \d\d:\d\d:\d\d ($bracket_name)/o;   # date format.
 		my $name = &unarmor_name($1);
 		if ($name ne $form{mypage}) {
 			push(@updates, $_);
 		}
 	}
 	if ($opt eq 'update') {
 		$update = "- @{[&get_now]} @{[&armor_name($form{mypage})]}";
 	} elsif ($opt eq 'delete') {
 		$update = "- @{[&get_now]} @{[$form{mypage}]}";
 	} else {
 		$update = "- @{[&get_now]} @{[$form{mypage}]}";
 	}
 	unshift(@updates, $update);
 	splice(@updates, $maxrecent + 1);
 	$recentbase{$[[RecentCreates]]} = join("\n", @updates);
 }

 sub update_recent_searches {
 	my ($keyword, $hit_cnt) = @_;
 	
 	# ロボットならアップデートしない
 	if($form{robots}) {
 		return;
 	}
 	
 	$keyword = unescape($keyword);
 	my @oldupdates = split(/\r?\n/, $database{$[[RecentSearches]]});
 	my @updates;
 	
 	# 括弧のバランスが取れていない対策 (不十分 && ad hoc)
 	if(($keyword =~ tr/\(/\(/) > ($keyword =~ tr/\)/\)/)) {
 		$keyword =~ s/\(/ /;
 	} elsif(($keyword =~ tr/\(/\(/) < ($keyword =~ tr/\)/\)/)) {
 		$keyword =~ s/([^)]*)\)/$1 /;
 	}
 	
 	my $update = qq(- @{[&get_now]} \&search\($keyword\)$subject_delimiter$hit_cnt Hit);
 	foreach (@oldupdates) {
 		/^\- \d\d\d\d\-\d\d\-\d\d \(...\) \d\d:\d\d:\d\d \&search\((.*)\) \-/o;   # date format.
 		my $name = &unarmor_name($1);
 		if ($name ne $keyword) {
 			push(@updates, $_);
 		}
 	}
 #	my @updates = split(/\r?\n/, $database{$[[RecentSearches]]});
 	unshift(@updates, $update);
 	
 	splice(@updates, $maxrecent + 1);
 	$recentbase{$[[RecentSearches]]} = join("\n", @updates);
 }

 sub update_recent_reads {
 	# ロボットならアップデートしない
 	if($form{robots}) {
 		return;
 	}
 	
 	my $update = "- @{[&get_now]} @{[&armor_name($form{mypage})]}";
 	my @oldupdates = split(/\r?\n/, $database{$[[RecentReads]]});
 	my @updates;
 	foreach (@oldupdates) {
 		/^\- \d\d\d\d\-\d\d\-\d\d \(...\) \d\d:\d\d:\d\d ($bracket_name)/o;   # date format.
 		my $name = &unarmor_name($1);
 		if (($name ne $form{mypage}) && (&is_exist_page($name))) {
 			push(@updates, $_);
 		}
 	}
 	if ($form{mypage} !~ /^($[[RecentReads]]|$[[RecentChanges]]|$[[RecentSearches]]|$[[RecentCreates]]|$[[FrontPage]])$/) {
 		unshift(@updates, $update);
 	}
 	splice(@updates, $maxrecent + 1);
 	$recentbase{$[[RecentReads]]} = join("\n", @updates);
 }


 sub get_subjectline {
 	my ($page, %option) = @_;


 	if (not &is_editable($page)) {
 		return "";
 	} else {
 		# Delimiter check.
 		my $delim = $subject_delimiter;
 		if (defined($option{delimiter})) {
 			$delim = $option{delimiter};
 		}

 		# Get the subject of the page.
 		my $subject = $database{$page};
 		$subject =~ s/\r?\n.*//s;
 		# プラグイン書式等の除去
 		$subject = &escape_subject($subject);

 		return "$delim$subject";
 	}
 }

 sub escape_subject {
 	my ($subject) = @_;
 	
 # pluginをエスケープ なんとかしたいけど、手遅れな感じ
 	$subject =~ s/\&amazon\(([^)]*[^(])\,([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&bold\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&bolditalic\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&br\(\)//g;
 	$subject =~ s/\&center\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&color\(([^)]*[^(])\,([^)]*[^(])\)/$2/g;
 	$subject =~ s/\&decoration\(([^)]*[^(])\,([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&del\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&italic\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&left\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&link\(([^)]*[^(])\,([^)]*[^(]*)\)/$1/g;
 	$subject =~ s/\&listtotal\(\)//g;
 	$subject =~ s/\&random\(\)//g;
 	$subject =~ s/\&right\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&ruby\(([^)]*[^(])\,([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&search\(([^)]*[^(])\)/$1/g;
 	$subject =~ s/\&size\(([^)]*[^(])\,([^)]*[^(])\)/$2/g;
 	$subject =~ s/\&verb\(([^)]*[^(])\)/$1/g;
 	
 	$subject =~ s/($bracket_name)/&unarmor_name($1)/gex;
 	
 	return $subject;
 }

 sub send_mail_to_admin {
 	my ($page, $mode) = @_;
 	return unless $modifier_sendmail;
 	my $message = <<"EOD";
 To: $modifier_mail
 From: $modifier_mail
 Subject: [Wiki]
 MIME-Version: 1.0
 Content-Type: text/plain; charset=ISO-2022-JP
 Content-Transfer-Encoding: 7bit

 --------
 MODE = $mode
 REMOTE_ADDR = $ENV{REMOTE_ADDR}
 REMOTE_HOST = $ENV{REMOTE_HOST}
 --------
 $page
 --------
 $database{$page}
 --------
 EOD
 	&code_convert(\$message, 'jis');
 	open(MAIL, "| $modifier_sendmail");
 	print MAIL $message;
 	close(MAIL);
 }

 sub open_db {
 	if ($modifier_dbtype eq '[[YukiWikiDB]]') {
 		tie(%database, "Yuki::[[YukiWikiDB]]", $dataname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $dataname");
 		tie(%infobase, "Yuki::[[YukiWikiDB]]", $infoname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $infoname");
 		tie(%cachebase, "Yuki::[[YukiWikiDB]]", $cachename) or &print_error("(tie Yuki::[[YukiWikiDB]]) $cachename");
 		tie(%antennabase, "Yuki::[[YukiWikiDB]]", $antennaname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $antennaname");   # Walrus add [wiki antenna]
 		tie(%searchcachebase, "Yuki::[[YukiWikiDB]]", $search_cache) or &print_error("(tie Yuki::[[YukiWikiDB]]) $search_cache");
 		tie(%recentbase, "Yuki::[[YukiWikiDB]]", $dataname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $dataname");
 	} elsif ($modifier_dbtype eq '[[YukiWikiDB]]_Backup') {
 		tie(%database, "Yuki::[[YukiWikiDB]]_Backup", $dataname) or &print_error("(tie Yuki::[[YukiWikiDB]]_Backup) $dataname");
 		tie(%infobase, "Yuki::[[YukiWikiDB]]", $infoname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $infoname");
 		tie(%cachebase, "Yuki::[[YukiWikiDB]]", $cachename) or &print_error("(tie Yuki::[[YukiWikiDB]]) $cachename");
 		tie(%antennabase, "Yuki::[[YukiWikiDB]]", $antennaname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $antennaname");   # Walrus add [wiki antenna]
 		tie(%searchcachebase, "Yuki::[[YukiWikiDB]]", $search_cache) or &print_error("(tie Yuki::[[YukiWikiDB]]) $search_cache");
 		tie(%recentbase, "Yuki::[[YukiWikiDB]]", $dataname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $dataname");
 	} elsif ($modifier_dbtype eq '[[YukiWikiDB]]x') {
 		tie(%database, "Yuki::[[YukiWikiDB]]x", $dataname, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $dataname");
 		tie(%infobase, "Yuki::[[YukiWikiDB]]x", $infoname, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $infoname");
 		tie(%cachebase, "Yuki::[[YukiWikiDB]]x", $cachename, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $cachename");
 		tie(%antennabase, "Yuki::[[YukiWikiDB]]x", $antennaname, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $antennaname");
 		tie(%searchcachebase, "Yuki::[[YukiWikiDB]]x", $search_cache, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $search_cache");
 		tie(%recentbase, "Yuki::[[YukiWikiDB]]x", $dataname, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $dataname");
 	} elsif ($modifier_dbtype eq 'dbmopen') {
 		dbmopen(%database, $dataname, 0666) or &print_error("(dbmopen) $dataname");
 		dbmopen(%infobase, $infoname, 0666) or &print_error("(dbmopen) $infoname");
 		dbmopen(%antennabase, $antennaname, 0666) or &print_error("(dbmopen) $antennaname");
 		dbmopen(%cachebase, $cachename, 0666) or &print_error("(dbmopen) $cachename");
 		dbmopen(%searchcachebase, $search_cache, 0666) or &print_error("(dbmopen) $search_cache");
 		dbmopen(%recentbase, $dataname, 0666) or &print_error("(dbmopen) $dataname");
 	} elsif ($modifier_dbtype eq 'AnyDBM_File') {
 		tie(%database, "AnyDBM_File", $dataname, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $dataname");
 		tie(%infobase, "AnyDBM_File", $infoname, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $infoname");
 		tie(%antennabase, "AnyDBM_File", $antennaname, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $antennaname");
 		tie(%cachebase, "AnyDBM_File", $cachename, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $cachename");
 		tie(%searchcachebase, "AnyDBM_File", $search_cache, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $search_cache");
 		tie(%recentbase, "AnyDBM_File", $dataname, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $dataname");
 	} elsif ($modifier_dbtype eq 'DB_File') {
 		tie(%database, "DB_File", $dataname, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $dataname");
 		tie(%infobase, "DB_File", $infoname, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $infoname");
 		tie(%antennabase, "DB_File", $antennaname, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $antennaname");
 		tie(%cachebase, "DB_File", $cachename, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $cachename");
 		tie(%searchcachebase, "DB_File", $search_cache, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $search_cache");
 		tie(%recentbase, "DB_File", $dataname, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $dataname");
 	} else {
 		&print_error("ERROR modifier_dbtype ERROR");
 	}
 }

 sub close_db {
 	if ($modifier_dbtype eq 'dbmopen') {
 		dbmclose(%database);
 		dbmclose(%infobase);
 		dbmclose(%antennabase);
 		dbmclose(%cachebase);
 		dbmclose(%searchcachebase);
 		dbmclose(%recentbase);
 	} else {
 		untie(%database);
 		untie(%infobase);
 		untie(%antennabase);   # Walrus add [wiki antenna]
 		untie(%cachebase);
 		untie(%searchcachebase);
 		untie(%recentbase);
 	}
 }

 sub open_diff {
 	if ($modifier_dbtype eq '[[YukiWikiDB]]' || $modifier_dbtype eq '[[YukiWikiDB]]_Backup') {
 		tie(%diffbase, "Yuki::[[YukiWikiDB]]", $diffname) or &print_error("(tie Yuki::[[YukiWikiDB]]) $diffname");
 	} elsif ($modifier_dbtype eq 'dbmopen') {
 		dbmopen(%diffbase, $diffname, 0666) or &print_error("(dbmopen) $diffname");
 	} elsif ($modifier_dbtype eq 'AnyDBM_File') {
 		tie(%diffbase, "AnyDBM_File", $diffname, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $diffname");
 	} elsif ($modifier_dbtype eq 'DB_File') {
 		tie(%diffbase, "DB_File", $diffname, O_RDWR|O_CREAT, 0666) or &print_error("(tie DB_File) $diffname");
 	} elsif ($modifier_dbtype eq '[[YukiWikiDB]]x') {
 		tie(%diffbase, "Yuki::[[YukiWikiDB]]x", $diffname, 0700, 0) or &print_error("(tie Yuki::[[YukiWikiDB]]x) $diffname");
 	}
 }

 sub close_diff {
 	if ($modifier_dbtype eq 'dbmopen') {
 		dbmclose(%diffbase);
 	} else {
 		untie(%diffbase);
 	}
 }

 sub open_search_index {
 	tie (@search_index, 'Tie::FileArray', $search_index_name) or &print_error("(tie Tie::FileArray) $search_index_name");
 	my ($mode) = @_;
 	
 	# デフォルトは読み書きオープン (従来と同じ動き)
 	if($mode eq 'RDONLY') {
 		tie (@search_index, 'Tie::FileArray', $search_index_name, mode => 'RDONLY') or &print_error("(tie Tie::FileArray) $search_index_name");
 	} else {
 		tie (@search_index, 'Tie::FileArray', $search_index_name) or &print_error("(tie Tie::FileArray) $search_index_name");
 	}
 	
 	return 1;
 }

 sub close_search_index {
 	untie(@search_index);
 }

 sub open_autolink_index {
 	my $aidx = tie (@autolink_index, 'Tie::FileArray', $autolink_index_name) or &print_error("(tie Tie::FileArray) $autolink_index_name");
 	return 1;
 }

 sub close_autolink_index {
 	untie(@autolink_index);
 }


 sub print_searchform {
 	my ($word) = @_;
 	print <<"EOD";

 <div class="form">
 <form action="$action_url" method="get">
     <input type="hidden" name="mycmd" value="search">
     <input class="searchepage" type="text" name="mymsg" value="$word" size="60">
     <input class="searchepage" type="submit" value="$resource{searchbutton}">
 </form>
 </div>
 EOD
 }

 sub print_editform {
 	my ($mymsg, $conflictchecker, %mode) = @_;
 	my $frozen = &is_frozen($form{mypage});

 	if ($form{mypreview}) {
 		if ($form{mymsg}) {
 			unless ($mode{conflict}) {
 				print qq(<h3>$resource{previewtitle}</h3>\n);
 				print qq($resource{previewnotice}\n);
 				print qq(<div class="preview">\n);
 				&print_content($form{mymsg});
 				print qq(</div>\n);
 			}
 		} else {
 			print qq($resource{previewempty});
 		}
 		$mymsg = &escape($form{mymsg});
 	} else {
 		$mymsg = &escape($mymsg);
 	}

 	my $edit = $mode{admin} ? 'adminedit' : 'edit';
 	my $escapedmypage = &escape($form{mypage});
 	my $escapedmypassword = &escape($form{mypassword});

 	print <<"EOD";
 <form action="$action_url" method="post">
     <textarea cols="$cols" rows="$rows" name="mymsg" wrap="soft">
 $mymsg</textarea><br>
     @{[ $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">
     <input type="hidden" name="mypart" value="$form{mypart}">

 @{[
 	$mode{admin} ?
 	qq(
     <input type="radio" name="myfrozen" value="1" checked="checked" >$resource{frozenbutton}
     <input type="radio" name="myfrozen" value="0" >$resource{notfrozenbutton}<br>)
     : ""
 ]}
 @{[
 	$mode{conflict} ? "" :
 	qq(
         <input type="checkbox" name="mytouch" value="on" checked="checked">$resource{touch}<br>
         <input type="submit" name="mypreview_$edit" value="$resource{previewbutton}">
         <input type="submit" name="mypreview_write" value="$resource{savebutton}"><br>
     )
 ]}
 </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);
 		print &text_to_html($content, toc=>0);
 	}

 	unless ($mode{conflict}) {
 		# Show plugin information.
 		my $plugin_usage = <<"EOD";
 *$resource{available_plugins}
 EOD
 		foreach my $usage (@{$plugin_manager->usage}) {
 			$plugin_usage .= <<"EOD";
 ** $usage->{name}
 ---(
 $resource{plugin_usage_name}: $usage->{name}
 $resource{plugin_usage_version}: $usage->{version}
 $resource{plugin_usage_author}: $usage->{author}
 $resource{plugin_usage_syntax}: $usage->{syntax}
 $resource{plugin_usage_description}: $usage->{description}
 $resource{plugin_usage_example}: $usage->{example}
 ---)
 EOD
 		}
 		&code_convert(\$plugin_usage, $kanjicode);
 		print &text_to_html($plugin_usage, toc=>0);
 	}
 }

 sub print_passwordform {
 		print <<"EOD";
 <form action="$action_url" method="post">
     <input type="hidden" name="mycmd" value="adminchangepassword">
     $resource{oldpassword} <input type="password" name="myoldpassword" size="10"><br>
     $resource{newpassword} <input type="password" name="mynewpassword" size="10"><br>
     $resource{newpassword2} <input type="password" name="mynewpassword2" size="10"><br>
     <input type="submit" value="$resource{changepasswordbutton}"><br>
 </form>
 EOD
 }

 sub is_editable {
 	my ($page) = @_;
 	if (&is_bracket_name($page)) {
 		return 0;
 	} elsif ($fixedpage{$page}) {
 		return 0;
 	} elsif ($page =~ /^\#/) {
 		return 0;
 	} elsif ($page =~ /^\s|\s$/) {
 		return 0;
 	} elsif (not $page) {
 		return 0;
 	} elsif ($page =~ /\[\[.*\]\]/) {
 		return 0;
 	} else {
 		return 1;
 	}
 }

 # armor_name:
 #   [[WikiName]] -> [[WikiName]]
 #   not_wiki_name -> [[not_wiki_name]]
 sub armor_name {
 	my ($name) = @_;
 	return "[[$name]]";
 }

 # unarmor_name:
 #   [[bracket_name]] -> bracket_name
 #   [[WikiName]] -> [[WikiName]]
 sub unarmor_name {
 	my ($name) = @_;
 	if ($name =~ /^\[\[(.+?)\]\]$/) {
 		return $1;
 	} else {
 		return $name;
 	}
 }

 sub is_bracket_name {
 	my ($name) = @_;
 	if ($name =~ /^\[\[(.+?)\]\]$/) {
 		return 1;
 	} else {
 		return 0;
 	}
 }

 sub decode {
 	my ($s) = @_;
 	$s =~ tr/+/ /;
 	$s =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;
 	return $s;
 }

 # Thanks to [[WalWiki]] for [better encode].
 sub encode {
 	my ($encoded) = @_;
 	$encoded =~ s/(\W)/'%' . unpack('H2', $1)/eg;
 	return $encoded;
 }

 sub init_resource {
 	open(FILE, $file_resource) or &print_error("(resource)");
 	while (<FILE>) {
 		chomp;
 		next if /^#/;
 		my ($key, $value) = split(/=/, $_, 2);
 		$resource{$key} = &code_convert(\$value, $kanjicode);
 	}
 	close(FILE);
 }

 sub conflict {
 	my ($page, $rawmsg) = @_;
 	if ($form{myConflictChecker} eq &get_info($page, $info_ConflictChecker)) {
 		return 0;
 	}
 	open(FILE, $file_conflict) or &print_error("(conflict)");
 	my $content = join('', <FILE>);
 	&code_convert(\$content, $kanjicode);
 	close(FILE);
 	&print_header($page);
 	&print_content($content);
 	&print_editform($rawmsg, $form{myConflictChecker}, frozen=>0, conflict=>1);
 	&print_footer($page);
 	return 1;
 }


 sub get_now {
 	my (@week) = qw(Sun Mon Tue Wed Thu Fri Sat);
 	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;
 	$hour = "0$hour" if $hour < 10;
 	$min = "0$min" if $min < 10;
 	$sec = "0$sec" if $sec < 10;
 	$weekday = $week[$weekday];
 	return "$year-$mon-$day ($weekday) $hour:$min:$sec";
 }

 sub get_info {
 	my ($page, $key) = @_;
 	my %info = map { split(/=/, $_, 2) } split(/\n/, $infobase{$page});
 	return $info{$key};
 }

 sub set_info {
 	my ($page, $key, $value) = @_;
 	my %info = map { split(/=/, $_, 2) } split(/\n/, $infobase{$page});
 	$info{$key} = $value;
 	my $s = '';
 	for (keys %info) {
 		$s .= "$_=$info{$_}\n";
 	}
 	$infobase{$page} = $s;
 }

 sub frozen_reject {
 #	my ($isfrozen) = &get_info($form{mypage}, $info_IsFrozen);
 	my ($isfrozen) = &is_frozen($form{mypage});
 	my ($willbefrozen) = $form{myfrozen};
 	if (not $isfrozen and not $willbefrozen) {
 		# You need no check.
 		return 0;
 	 } elsif ($isfrozen and $form{mycmd} eq 'comment') {
 		# keep frozen
 		$form{myfrozen} = 1;
 		# Comment is always allowed.
 		return 0;
 	} elsif (valid_password($form{mypassword})) {
 		# You are admin.
 		return 0;
 	} else {
 		&print_error($resource{passworderror});
 		return 1;
 	}
 }

 sub valid_password {
 	my ($givenpassword) = @_;
 	my ($validpassword_crypt) = &get_info($AdminSpecialPage, $info_AdminPassword);
 	if (crypt($givenpassword, $validpassword_crypt) eq $validpassword_crypt) {
 		return 1;
 	} else {
 		return 0;
 	}
 }

 sub is_frozen {
 	my ($page) = @_;
 	if (&get_info($page, $info_IsFrozen)) {
 		return 1;
 	} else {
 		return 0;
 	}
 }

 sub do_comment {
 	my ($content) = $database{$form{mypage}};
 	
 	# スパムチェック. アルファベットだけなら拒否
 	if(&spam_reject){
 		return;
 	}

 	my $datestr = &get_now;
 	my $namestr = $form{myname} ? " &bold($form{myname}) : " : " &bold($resource{comment_nanashi}) : ";
 	if ($content =~ s/(^|\n)(\Q$embed_comment\E)/$1- $datestr$namestr$form{mymsg}\n$2/) {
 		;
 	} else {
 		$content =~ s/(^|\n)(\Q$embed_rcomment\E)/$1$2\n- $datestr$namestr$form{mymsg}/;
 	}
 	if ($form{mymsg}) {
 		$form{mymsg} = $content;
 		$form{mytouch} = 'on';
 		&do_write;
 	} else {
 		$form{mycmd} = 'read';
 		&do_read;
 	}
 }

 sub embedded_to_html {
 	my ($embedded) = @_;
 	my $escapedmypage = &escape($form{mypage});
 	if ($embedded eq $embed_comment or $embedded eq $embed_rcomment) {
 		my $conflictchecker = &get_info($form{mypage}, $info_ConflictChecker);
 		return <<"EOD";
 <form action="$action_url" method="post" class="commentform">
     <input type="hidden" name="mycmd" value="comment">
     <input type="hidden" name="mypage" value="$escapedmypage">
     <input type="hidden" name="myConflictChecker" value="$conflictchecker">
     <input type="hidden" name="mytouch" value="on">
     $resource{yourname}
     <input type="text" name="myname" value="" size="10">
     <input type="text" name="mymsg" value="" size="40">
     <input type="submit" value="$resource{commentbutton}">
 </form>
 EOD
 	# add [trackback] start
 	} elsif ($embedded eq $embed_trackback or $embedded eq $embed_rtrackback) {
 		 $_ = qq(<p class="trackback">''[[TrackBack]]'' - $url_cgi_trackback/@{[&encode($form{mypage})]}</p>); # この書き方は[[WalWiki]]用かな[[YukiWiki]]だと<b></b>で囲わないと太字にならないんじゃ?試してないけど…
 		 return ($_) ? $_ : &escape($embedded);
 	# add [trackback] end
 	} else {
 		return $embedded;
 	}
 }

 sub make_antenna_data {
 	my ($url, $limit) = @_;
 	my $cache_name = $url . $limit;
 	my $type = 'rss';
 	my ($time, $status, $data) = ($antennabase{$cache_name}) ? split(/\n/, $antennabase{$cache_name}, 3) : (0, 'Not Retriebed', '');
 	my @lines = $data;
 	
 	if (($time < time - 2400) or ($time < time - rand()*2400)) {
 		my $http = new HTTP::Lite;
 		$http->proxy($ENV{HTTP_PROXY}) if ($ENV{HTTP_PROXY});
 		my $req = $http->request($url);
 		
 		if (not $req){
 			($time, $status, $data) = (time, "Unable to get document: $!", undef); 
 		}elsif ($req ne "200") {
 			($time, $status, $data) = (time, $http->status_message(), undef); 
 		}else{
 			# ゴチャゴチャしているので、そのうち書き換え。
 			($time, $status, $data) = (time, undef, $http->body);
 			@lines = ();
 			my $no_cut_flag =1;
 			foreach my $tmp (split(/\n/, $data)){
 				if ($tmp =~ /<content:encoded>/i){$no_cut_flag =0;}
 				if ($no_cut_flag){push(@lines,$tmp);}
 				if ($tmp =~ /<\/content:encoded>/i){$no_cut_flag =1;}
 			}
 			$data = join("\n", @lines);
 		}
 		
 		if($status){
 			@lines = qq(<p>$url   .........   $status</p>);
 			$antennabase{$cache_name} = join("\n", $time, $status, qq(<p>$url   .........   $status</p>));
 		}elsif($data){
 			&code_convert(\$data, $kanjicode);
 			@lines = &convert_list($url, \$data, $type, $limit);
 			if(length($url) < $max_cache_length){
 				$antennabase{$cache_name} = join("\n", $time, $status, @lines);
 			}
 		}
 	}
 	return join("\n", @lines);
 }

 # for Encode.pm START
 #
 sub str_length {
 	my ($str) = @_;
 	my $length;
 	if(!utf8::is_utf8($str)) {
 		&str2utf8(\$str);
 		utf8::decode($str);
 	}
 	$length =length($str);

 	return $length;
 }

 # Patch from http://www.hoso.net/~yu-ji/wiki/wiki.cgi
 # thanks Mr.Yu-ji Hosokawa.
 sub str2utf8 {
 	my($source_ref) = shift(@_);
 	
 	my $decoder = guess_encoding($$source_ref, qw(utf8));
 	if(not ref($decoder)) {
 		$decoder = guess_encoding($$source_ref, qw(euc-jp shiftjis 7bit-jis));
 		if (not ref($decoder)) {
 			$decoder = guess_encoding($$source_ref, qw(euc-jp));
 			if (not ref($decoder)) {
 				# warn('Cannot guessed it...');
 				return;
 			}
 		}
 	}
 	
 	$$source_ref = $decoder->decode($$source_ref);
 }

 # Patch from http://www.hoso.net/~yu-ji/wiki/wiki.cgi
 # thanks Mr.Yu-ji Hosokawa.
 sub code_convert {
 	my ($contentref, $kanjicode) = @_;

 	&str2utf8($contentref);
 	for ($kanjicode) {
 		s/^utf8$/utf-8/;
 		s/^euc$/euc-jp/;
 		s/^sjis$/shiftjis/;
 		s/^jis$/iso-2022-jp/;
 	}
 	$$contentref = Encode::encode($kanjicode, $$contentref);
 	return $$contentref;
 }


 sub asc {
 # 代表的なやつだけ変換
 	my ($contents) = @_;
 	&str2utf8(\$contents);
 	
 	$contents =~ s/(\x{3000})/\x{0020}/g;	#全角スペース
 	$contents =~ s/(\x{ff01})/\x{0021}/g;	#全角!
 	$contents =~ s/(\x{ff03})/\x{0023}/g;	#全角#
 	$contents =~ s/(\x{ff04})/\x{0024}/g;	#全角$
 	$contents =~ s/(\x{ff05})/\x{0025}/g;	#全角%
 	$contents =~ s/(\x{ff06})/\x{0026}/g;	#全角&
 	$contents =~ s/(\x{ff08})/\x{0028}/g;	#全角(
 	$contents =~ s/(\x{ff09})/\x{0029}/g;	#全角)
 	$contents =~ s/(\x{ff1d})/\x{003d}/g;	#全角=
 	
 	$contents =~ s/(\x{ff10})/\x{0030}/g;	#全角0
 	$contents =~ s/(\x{ff11})/\x{0031}/g;	#全角1
 	$contents =~ s/(\x{ff12})/\x{0032}/g;	#全角2
 	$contents =~ s/(\x{ff13})/\x{0033}/g;	#全角3
 	$contents =~ s/(\x{ff14})/\x{0034}/g;	#全角4
 	$contents =~ s/(\x{ff15})/\x{0035}/g;	#全角5
 	$contents =~ s/(\x{ff16})/\x{0036}/g;	#全角6
 	$contents =~ s/(\x{ff17})/\x{0037}/g;	#全角7
 	$contents =~ s/(\x{ff18})/\x{0038}/g;	#全角8
 	$contents =~ s/(\x{ff19})/\x{0039}/g;	#全角9
 	
 	utf8::encode($contents);
 	&code_convert(\$contents,$kanjicode);
 	return $contents;
 }
 # for Encode.pm END


 # for Jcode.pm START
 # sub asc {
 # # 代表的なやつだけ変換
 # 	my ($contents) = @_;
 # 	my @from = ("\xa1\xa1","\xa1\xaa","\xa1\xf4","\xa1\xf0","\xa1\xf3","\xa1\xf5","\xa1\xca","\xa1\xcb","\xa1\xe1","\xa3\xb0","\xa3\xb1","\xa3\xb2","\xa3\xb3","\xa3\xb4","\xa3\xb5","\xa3\xb6","\xa3\xb7","\xa3\xb8","\xa3\xb9");
 # 	my @to   = ("\x20","\x21","\x23","\x24","\x25","\x26","\x28","\x29","\x3d","\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39");
 # 	
 # 	my $j = Jcode->new(\$contents,$kanjicode);
 # 	for (my $cnt=0; $cnt < @from; $cnt++){
 # 		$j->tr($from[$cnt], $to[$cnt]);
 # 	}
 # 	
 # 	return $contents;
 # }
 # 
 # sub str_length {
 # 	my ($str) = @_;
 # 	my $length;
 # 	$length =length($str);
 # 
 # 	return $length;
 # }
 # 
 # sub code_convert {
 # 	my ($contentref, $kanjicode) = @_;
 # 	&Jcode::convert($contentref, $kanjicode);
 # 	return $$contentref;
 # }
 # for Jcode.pm END

 #### add [trackback] start
 sub is_trackback {
 	 if ( $form{url} && $ENV{'PATH_INFO'} ) {
 		 return ( 1 );
 	 }
 	 return ( 0 );
 }
 #### add [trackback] end

 #### add [trackback] start
 sub response_trackback {
 	# 一応エスケープします。
 	$form{url} = &escape(&code_convert(\$form{url}, $kanjicode));
 	$form{title} = &escape(&code_convert(\$form{title}, $kanjicode));
 	$form{excerpt} = &escape(&code_convert(\$form{excerpt}, $kanjicode));
 	$form{blog_name} = &escape(&code_convert(\$form{blog_name}, $kanjicode));

 	# titleが空の場合対策
 	if ($form{title} eq ''){
 		$form{title} = &escape(&code_convert(\$form{url}, $kanjicode));
 	}

 	# コメントを書き込む際の状態に近づけます。
 	$form{mycmd} = 'comment';
 	$form{mypage} = &unarmor_name(&armor_name(&escape(substr($ENV{'PATH_INFO'},1,length($ENV{'PATH_INFO'})-1))));
 	$form{myLastModified} = &get_info($form{mypage}, $info_LastModified);
 	$form{mytouch} = 'on';

 	# ここからdo_commentをベースに書き込みを設定。
 	my ($content) = $database{$form{mypage}};
 	my $datestr = &get_now;
 	my $namestr = $form{blog_name} ? " ''$form{blog_name}'' : " : " ";
 	my $error = 1;
 	my $error_msg = 'Error Error Error'; # エラーメッセージはそれぞれお好みで書き換えてください。
 	$form{mymsg} = $content;
 	if (not $content) {
 		$error_msg = "Ping ID is Invalid  not content $content";
 	} elsif ($form{url} && $form{mypage}) {
 		if ($content =~ s/(^|\n)(\Q$embed_trackback\E)/- $datestr &verb($namestr) &link($form{title},$form{url})\n--$form{excerpt}\n$1$2/) {
 			;
 		} else {
 			$content =~ s/(^|\n)(\Q$embed_rtrackback\E)/$1$2\n- $datestr &verb($namestr) &link($form{title},$form{url})\n--$form{excerpt}/;
 		}
 		if ($form{mymsg} eq $content) {
 			$error_msg = 'Ping ID is Invalid eq content';
 			last;
 		}
 		$form{mymsg} = $content;

 		# ここからはdo_writeをベースにデータベースに書き込み。
 		if (&frozen_reject()) {
 			$error_msg = 'Ping ID is Invalid frozen_reject';
 			last;
 		}
 		if (not &is_editable($form{mypage})) {
 			$error_msg = 'Ping ID is Invalid is_editable';
 			last;
 		}
 		if ($form{myLastModified} ne &get_info($form{mypage}, $info_LastModified)) {
 			$error_msg = 'Ping ID is Invalid';
 			last;
 		 }
 		# Making diff
 		if (1) {
 			&open_diff;
 			my @msg1 = split(/\n/, $database{$form{mypage}});
 			my @msg2 = split(/\n/, $form{mymsg});
 			$diffbase{$form{mypage}} = &difftext(\@msg1, \@msg2);
 			&close_diff;
 		}

 		$database{$form{mypage}} = $form{mymsg};
 		&send_mail_to_admin($form{mypage}, "Modify");
 		if ($form{mytouch}) {
 			&set_info($form{mypage}, $info_LastModified, '' . localtime);
 			&update_recent_changes;
 		}
 		&set_info($form{mypage}, $info_IsFrozen, 0 + $form{myfrozen});

 		# エラーが発生しなかったことを設定してxml発行。
 		$error = 0;
 		print <<"EOD";
 Content-type: text/xml

 <?xml version="1.0" encoding="iso-8859-1"?>
 <response>
 <error>0</error>
 </response>
 EOD
 	}

 	# エラーが発生した場合の処理。(エラーxmlの発行)
 	if ($error) {
 		print <<"EOD";
 Content-type: text/xml

 <?xml version="1.0" encoding="iso-8859-1"?>
 <response>
 <error>1</error>
 <message>$error_msg</message>
 </response>
 EOD
 	}
 }
 #### add [trackback] end



 sub do_diff {
 	if (not &is_editable($form{mypage})) {
 		&do_read;
 		return;
 	}
 	&open_diff;
 	my $title = $form{mypage};
 	&print_header($title);
 	print qq(\n<!--googleoff: all-->\n);
 	
 	$_ = &escape($diffbase{$form{mypage}});
 	&close_diff;
 	print qq(<h3>$resource{difftitle}</h3>);
 	print qq($resource{diffnotice});
 	print qq(<pre class="diff">);
 	foreach (split(/\n/, $_)) {
 		if (/^\+(.*)/) {
 			print qq(<b class="added">$1</b>\n);
 		} elsif (/^\-(.*)/) {
 			print qq(<s class="deleted">$1</s>\n);
 		} elsif (/^\=(.*)/) {
 			print qq(<span class="same">$1</span>\n);
 		} else {
 			print qq|??? $_\n|;
 		}
 	}
 	print qq(</pre>);
 	print qq(<hr>\n);
 	
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer($title);
 }

 sub do_rss {
 	# RSSキャッシュがあれば利用
 	if (exists $cachebase{$RssPage}) {
 		my $cache_rss = $cachebase{$RssPage};
 		my $gzip;
 		my $Content_Encoding;
 		
 		# gzip転送可能ならする
 		if ($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/ && UNIVERSAL::can('Compress::Zlib', 'memGzip')) {
 			my $compress_cache_RssPage = " $RssPage -gzip ";
 			$gzip = "gzip";
 			$gzip = "x-gzip" if ($ENV{HTTP_ACCEPT_ENCODING} =~ /x-gzip/);
 			$Content_Encoding = "Content-Encoding:$gzip" if $gzip;
 			
 			# gzip圧縮済みキャッシュの有無
 			if (exists $cachebase{$compress_cache_RssPage}) {
 				$cache_rss = $cachebase{$compress_cache_RssPage};
 			} else {
 				$cache_rss = Compress::Zlib::memGzip($cache_rss);
 				$cachebase{$compress_cache_RssPage} = $cache_rss;
 			}
 		}
 		# RSS送信
 		print "Content-type: text/xml; charset=$charset\n";
 		print "$Content_Encoding\n" if $Content_Encoding;
 		print "\n";
 		print "$cache_rss\n";
 	} else {
 		&do_rss_cache;
 	}
 }

 sub do_rss_cache {
 	my $org_mypage = $form{mypage};
 	my $rss = new Yuki::RSS(
 		version => '1.0',
 		encoding => $charset,
 	);
 	$rss->channel(
 		title => $modifier_rss_title,
 		link  => $modifier_rss_link,
 		about  => "$modifier_rss_link?RssPage",
 		description => $modifier_rss_description,
 	);
 	my $recentchanges = $database{$[[RecentChanges]]};
 	my $count = 0;
 	foreach (split(/\n/, $recentchanges)) {
 		last if ($count >= 15);
 		/^\- (\d\d\d\d\-\d\d\-\d\d) \(...\) (\d\d:\d\d:\d\d) ($bracket_name)/;	# date format.
 		
 		my $dc_date = "$1T$2$modifier_rss_timezone";
 		my $title = &unarmor_name($3);
 		my $escaped_title = &escape($title);
 		my $link = $modifier_rss_link . '?' . &encode($title);
 		my $description = &escape(&get_subjectline($title, delimiter => ''));
 		
 		$form{mypage} = $title;
 		my $content_encoded ='<div class="document-body"><a name="top">' .  &do_read_cache($title) . '</div>';
 		my $content_encoded ='<div class="document-body"><a name="top"></a>' .  &do_read_cache($title) . '</div>';
 		
 		$rss->add_item(
 			title => $escaped_title,
 			link  => $link,
 			description => $description,
 			content_encoded => $content_encoded,
 			dc_date => $dc_date,
 		);
 		$count++;
 	}
 	$form{mypage} = $org_mypage;
 	# RSS Cache
 	$cachebase{$RssPage} = join("\n",$rss->as_string);
 	
 	# print RSS information (as XML).
 	print <<"EOD"
 Content-type: text/xml; charset=$charset

 @{[$rss->as_string]}
 EOD
 }

 # Walrus add [read by part] start
 sub read_by_part {
 	my ($page) = @_;
 	return unless &is_exist_page($page);
 	my @lines = map { $_."\n" } split(/\x0D\x0A|\x0D|\x0A/, $database{$page});
 	my @parts = ('');
 	foreach my $line (@lines) {
 		if ($line =~ /^\*{1,3}/)			{ push @parts, $line; }
 		else								{ $parts[$#parts] .= $line; }
 	}
 	return @parts;
 }
 # Walrus add [read by part] end


 sub is_exist_page {
 	my ($name) = @_;
 	if ($use_exists) {
 		return exists($database{$name});
 	} else {
 		return $database{$name};
 	}
 }


 # Initialize plugins.
 sub init_plugin {
 	$plugin_manager = new Yuki::PluginManager($plugin_context, $modifier_dir_plugin);
 }

 sub print_plugin_log {
 	if ($plugin_context->{debug}) {
 		print "<pre>(print_plugin_log)\n", join("\n", @{$plugin_manager->{log}}), "</pre>";
 	}
 }

 sub insertsort {
 	my ($list) = @_;
 	my $array_size = @$list;
 	for (my $i=1; $i < $array_size; $i++) {
 		my $j = $i;
         
 		while (($j > 0) && ($$list[$j - 1] gt $$list[$j])) {
 			my $tmp = $$list[$j - 1];
 			$$list[$j - 1] = $$list[$j];
 			$$list[$j] = $tmp;
 			$j--;
 		}
 	}
 	
 	while ($$list[-1] eq "\xFF\xFF\xFF\xFF\n") {
 		pop @$list;
 	}
 }

 sub autolink_index_sort {
 	my @tmp = sort { str_length($b) <=> str_length($a) or $b cmp $a } @autolink_index;
 	while ($tmp[-1] eq "\n") {
 		pop @tmp;
 	}
 	@autolink_index = (@tmp);
 }

 sub search_index_sort {
 	&insertsort(\@search_index);
 }

 sub bsearch {
 	my ($key, $list) = @_;
 	my $max = @$list;
 	my $min = 0;
 	my $mid;
 	
 	if($max == 1){
 		my ($string) = split(/\t/, $$list[0]);
 		if($string eq $key) {
 			return 0;
 		} else {
 			return -1;
 		}
 	}
 	
 	while ($max - $min > 1) {
 		$mid = int(($max + $min) / 2);
 		my ($string) = split(/\t/, $$list[$mid]);
 		chomp $string;
 		if ($string eq $key) {
 			return $mid;
 		} elsif ($string lt $key) {
 	    	$min = $mid;
 		} else {
 		    $max = $mid;
 		}
 	}
 	
 	return -1;
 }


 sub do_convert {
 	my $content = '%bd%f4%b7%af%a1%a1%bb%e4%a4%cf%c3%cf%cd%eb%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%bd%f4%b7%af%a1%a1%bb%e4%a4%cf%c3%cf%cd%eb%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%bd%f4%b7%af%a1%a1%bb%e4%a4%cf%c3%cf%cd%eb%a4%ac%c2%e7%b9%a5%a4%ad%a4%c0%26br%28%29%0a%26br%28%29%0a%b3%d1%c0%ee%a5%b9%a5%cb%a1%bc%a5%ab%a1%bc%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%c9%d9%bb%ce%b8%ab%a5%d5%a5%a1%a5%f3%a5%bf%a5%b8%a5%a2%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%c5%c5%b7%e2%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%c4%ab%c6%fc%a5%bd%a5%ce%a5%e9%a5%de%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%a5%b3%a5%d0%a5%eb%a5%c8%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%b9%d6%c3%cc%bc%d2%a5%db%a5%ef%a5%a4%a5%c8%a5%cf%a1%bc%a5%c8%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%c6%c1%b4%d6%a5%c7%a5%e5%a5%a2%a5%eb%a4%ac%b9%a5%a4%ad%a4%c0%a1%a1%a5%b9%a1%bc%a5%d1%a1%bc%a5%c0%a5%c3%a5%b7%a5%e5%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%b8%bd%c2%e5%a4%c7%a1%a1%b3%d8%b1%e0%a4%c7%a1%a1%b6%e1%cc%a4%cd%e8%a4%c7%a1%a1%c3%e6%c0%a4%a4%c7%a1%a1%b0%db%c0%a4%b3%a6%a4%c7%a1%a1%b1%a7%c3%e8%a4%c7%a1%a1%cb%eb%cb%f6%a4%c7%a1%a1%c0%ef%b9%f1%bb%fe%c2%e5%a4%c7%26br%28%29%0a%a4%b3%a4%ce%bb%e6%a4%ce%be%e5%a4%cb%bd%f1%a4%ab%a4%ec%a4%bf%a1%a1%a4%a2%a4%ea%a4%c8%a4%a2%a4%e9%a4%e6%a4%eb%c3%cf%cd%eb%a4%ac%c2%e7%b9%a5%a4%ad%a4%c0%26br%28%29%0a%c8%fe%be%af%bd%f7%cb%e2%cb%a1%bb%c8%a4%a4%a4%ce%b6%af%ce%cf%cc%b5%c8%e6%a4%ca%b0%ec%b7%e2%a4%ac%a1%a1%b9%ec%b2%bb%a4%c8%b6%a6%a4%cb%bb%a8%b5%fb%a4%f2%bf%e1%a4%ad%c8%f4%a4%d0%a4%b9%a4%ce%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%c8%fe%c0%c4%c7%af%b7%f5%bb%ce%a4%ac%ce%a9%a4%c1%a4%d5%a4%b5%a4%ac%a4%eb%c5%a8%c1%b4%a4%c6%a4%f2%c6%fc%cb%dc%c5%e1%a4%ce%b0%ec%c5%e1%a4%c7%bb%c2%a4%ea%c9%fa%a4%bb%a4%bf%bb%fe%a4%ca%a4%c9%bf%b4%a4%ac%cc%f6%a4%eb%26br%28%29%0a%bd%f7%c1%ce%ce%b7%a4%ac%cc%b5%b0%c7%a4%e4%a4%bf%a4%e9%a4%cb%b4%f1%c0%d7%a4%f2%b5%af%a4%b3%a4%b9%a4%ce%a4%ac%b9%a5%a4%ad%a4%c0%26br%28%29%0a%c9%ce%bb%e0%a4%ce%bc%e7%bf%cd%b8%f8%a4%ac%b4%f1%c0%d7%a4%ce%a4%aa%b0%fe%a4%c7%a5%d1%a5%ef%a1%bc5%b3%e4%a4%ea%c1%fd%a4%b7%c9%fc%b3%e8%a4%b7%a4%bf%bb%fe%a4%ca%a4%c9%b6%bb%a4%ac%a4%b9%a4%af%a4%e8%a4%a6%a4%ca%b5%a4%bb%fd%a4%c1%a4%c0%a4%c3%a4%bf%26br%28%29%0a%a4%a2%a4%b6%a4%c8%a4%a4%a4%de%a4%c7%a4%cb%a4%aa%cc%f3%c2%ab%a4%cb%bb%d9%c7%db%a4%b5%a4%ec%a4%bf%a5%b7%a5%c1%a5%e5%a5%a8%a1%bc%a5%b7%a5%e7%a5%f3%a4%ac%b9%a5%a4%ad%a4%c0%a1%a3%26br%28%29%0a%c4%ab%a4%ce%c4%cc%b3%d8%c5%d3%c3%e6%a4%cb%a5%d1%a5%f3%a4%f2%a4%af%a4%ef%a4%a8%a4%bf%c0%ce%cc%f3%c2%ab%a4%f2%b8%f2%a4%ef%a4%b7%a4%bf%b4%e3%b6%c0%a4%c3%cc%bc%a4%ce%c5%be%b9%bb%c0%b8%a4%cb%be%d7%c6%cd%a4%b7%a4%c6%a4%a4%a4%eb%cd%cd%a4%ca%a4%c9%a1%a2%b4%b6%c6%b0%a4%b9%a4%e9%b3%d0%a4%a8%a4%eb%26br%28%29%0a%a4%b5%a4%b7%a4%bf%a4%eb%c6%c3%c4%a7%a4%e2%a4%ca%a4%a4%bc%e7%bf%cd%b8%f8%a4%ac%cd%a5%a4%b7%a4%a4%a4%c8%a4%a4%a4%a6%a4%c0%a4%b1%a4%c7%ca%a3%bf%f4%a4%ce%bd%f7%a4%ce%bb%d2%a4%cb%b9%a5%a4%ab%a4%ec%a4%c6%a4%a4%a4%eb%cd%cd%a4%cf%a4%cf%a4%e2%a4%a6%a4%bf%a4%de%a4%e9%a4%ca%a4%a4%a1%a3%26br%28%29%0a%c6%c8%ba%db%b9%f1%b2%c8%a4%ce%b7%b3%c2%e2%a4%ac%a4%bf%a4%c3%a4%bf%b0%ec%bf%cd%a4%ce%cd%c3%ca%bc%a4%cb%a4%e8%a4%c3%a4%c6%b7%b1%ce%fd%a4%b5%a4%ec%a4%bf%cc%b1%ca%bc%a4%cb%a4%e8%a4%c3%a4%c6%a4%d0%a4%bf%a4%d0%a4%bf%a4%c8%c6%e5%a4%ae%c5%dd%a4%b5%a4%ec%a4%eb%a4%ce%a4%e2%ba%c7%b9%e2%a4%c0%26br%28%29%0a%b0%ad%cc%f2%a4%ac%c4%b9%a1%b9%a4%c8%b8%fd%be%e5%a4%f2%ca%c2%a4%d9%a4%c6%a4%aa%a4%ad%a4%ca%a4%ac%a4%e9%bc%e7%bf%cd%b8%f8%a4%ce%b0%a6%a4%c8%cd%a6%b5%a4%a4%ce%ce%cf%a4%cb%a4%e8%a4%c3%a4%c6%c2%c7%a4%c1%c5%dd%a4%b5%a4%ec%a4%eb%bb%fe%a4%ca%a4%c9%c0%e4%c4%ba%a4%b9%a4%e9%b3%d0%a4%a8%a4%eb%26br%28%29%0a%b5%c1%cb%e5%a4%c8%cd%c4%c6%eb%c0%f7%a4%df%a4%ce%bb%b0%b3%d1%b4%d8%b7%b8%a4%ac%b9%a5%a4%ad%a4%c0%a1%a3%26br%28%29%0a%c1%aa%a4%d0%a4%ec%a4%ca%a4%ab%a4%c3%a4%bf%b0%ec%ca%fd%a4%ac%b5%e3%a4%ad%a4%ca%a4%ac%a4%e9%c1%f6%a4%ea%b5%ee%a4%c3%a4%c6%a4%a4%a4%af%cd%cd%a4%cf%a4%c8%a4%c6%a4%e2%a4%c8%a4%c6%a4%e2%c8%e1%a4%b7%a4%a4%a4%e2%a4%ce%a4%c0%26br%28%29%0a%a5%c4%a5%f3%a5%c7%a5%ec%a4%ca%bd%f7%a4%ce%bb%d2%a4%cb%b8%ed%b2%f2%a4%ab%a4%e9%cb%cb%a4%f2%c3%a1%a4%ab%a4%ec%a4%eb%a4%ce%a4%ac%b9%a5%a4%ad%a4%c0%a1%a3%26br%28%29%0a%a4%b3%a4%c1%a4%e9%a4%f2%b0%ec%ca%cd%a4%b7%a4%bf%b8%e5%a1%d6%ba%c7%c4%e3%a1%d7%a4%ca%a4%c9%a4%c8%c7%cd%a4%e9%a4%ec%a4%eb%a4%ce%a4%cf%b6%fe%bf%ab%a4%ce%b6%cb%a4%df%a4%c0%26br%28%29%0a%26br%28%29%0a%bd%f4%b7%af%a1%a1%bb%e4%a4%cf%c3%cf%cd%eb%a4%f2%a1%a1%c3%cf%b9%f6%a4%ce%cd%cd%a4%ca%c3%cf%cd%eb%a4%f2%cb%be%a4%f3%a4%c7%a4%a4%a4%eb%26br%28%29%0a%bd%f4%b7%af%a1%a1%bb%e4%a4%cb%c9%d5%a4%ad%bd%be%a4%a6%c3%cf%cd%eb%bd%e8%cd%fd%c9%f4%c2%e2%bd%f4%b7%af%a1%a1%b7%af%c3%a3%a4%cf%b0%ec%c2%ce%a1%a1%b2%bf%a4%f2%cb%be%a4%f3%a4%c7%a4%a4%a4%eb%a1%a9%26br%28%29%0a%b9%b9%a4%ca%a4%eb%c3%cf%cd%eb%a4%f2%cb%be%a4%e0%a4%ab%a1%a9%a1%a1%be%f0%a4%b1%cd%c6%bc%cf%a4%ce%a4%ca%a4%a4%a1%a1%ca%b5%a4%ce%cd%cd%a4%ca%b3%cb%c3%cf%cd%eb%a4%f2%cb%be%a4%e0%a4%ab%a1%a9%26br%28%29%0a%c8%e1%a4%b7%a4%df%a4%c8%c5%dc%a4%ea%a4%ce%b8%c2%a4%ea%a4%f2%b8%c6%a4%d3%b5%af%a4%b3%a4%b7%a1%a1%c1%b4%a4%c6%a4%ce%c6%c9%bd%f1%b2%c8%a4%f2%bb%a6%a4%b9%a1%a1%cd%f2%a4%ce%cd%cd%a4%ca%bd%f1%a4%ad%bc%ea%a4%f2%cb%be%a4%e0%a4%ab%a1%a9%26br%28%29%0a%26br%28%29%0a%c3%cf%cd%eb%a1%aa%a1%aa%a1%a1%c3%cf%cd%eb%a1%aa%a1%aa%a1%a1%c3%cf%cd%eb%a1%aa%a1%aa%26br%28%29%0a%26br%28%29%0a%a4%e8%a4%ed%a4%b7%a4%a4%a1%a1%a4%ca%a4%e9%a4%d0%c3%cf%cd%eb%a4%c0%26br%28%29%0a%b2%e6%a1%b9%a4%cf%cb%fe%bf%c8%a4%ce%ce%cf%a4%f2%a4%b3%a4%e1%a4%c6%ba%a3%a4%de%a4%b5%a4%cb%c3%a1%a4%ad%c9%d5%a4%b1%a4%e9%a4%ec%a4%f3%a4%c8%a4%b9%a4%eb%b7%ee%b2%d6%a4%c0%26br%28%29%0a%a4%c0%a4%ac%a1%a1%a4%b3%a4%ce%b0%c5%a4%a4%b0%c7%a4%ce%c4%ec%a4%c7%bf%f4%c7%af%a4%e2%a4%ce%b4%d6%a1%a1%b4%ae%a4%a8%c2%b3%a4%b1%a4%c6%cd%e8%a4%bf%b2%e6%a1%b9%a4%cb%a1%a1%a4%bf%a4%c0%a4%ce%c6%c9%bd%f1%a4%c7%a4%cf%a4%e2%a4%cf%a4%e4%c2%ad%a4%ea%a4%ca%a4%a4%a1%aa%a1%aa%26br%28%29%0a%26br%28%29%0a%c2%e7%c6%c9%bd%f1%a4%f2%a1%aa%a1%aa%a1%a1%b0%ec%bf%b4%c9%d4%cd%f0%a4%ce%c2%e7%c6%c9%bd%f1%a4%f2%a1%aa%a1%aa%26br%28%29%0a%26br%28%29%0a%b2%e6%a4%e9%a4%cf%a4%ef%a4%ba%a4%ab%a4%cb%b0%ec%c8%c4%bd%bb%bf%cd%c0%e9%bf%cd%a4%cb%cb%fe%a4%bf%a4%cc%c3%cf%cd%eb%bd%e8%cd%fd%c8%c9%a4%cb%b2%e1%a4%ae%a4%ca%a4%a4%26br%28%29%0a%a4%c0%a4%ac%bd%f4%b7%af%a4%cf%b0%ec%b5%b3%c5%f6%c0%e9%a4%ce%a5%d5%a5%a1%a5%df%c4%cc%ca%b8%b8%cb%a4%c0%a4%c8%a1%a1%bb%e4%a4%cf%bf%ae%b6%c4%a4%b7%a4%c6%a4%a4%a4%eb%26br%28%29%0a%a4%ca%a4%e9%a4%d0%b2%e6%a4%e9%a4%cf%bd%f4%b7%af%a4%c8%bb%e4%a4%c7%c1%ed%ca%bc%ce%cf100%cb%fc%a4%c81%bf%cd%a4%ce%c9%d9%bb%ce%b8%ab%a5%df%a5%b9%a5%c6%a5%ea%a1%bc%ca%b8%b8%cb%a4%c8%a4%ca%a4%eb%26br%28%29%0a%b2%e6%a1%b9%a4%f2%cb%ba%b5%d1%a4%ce%c8%e0%ca%fd%a4%d8%a4%c8%c4%c9%a4%a4%a4%e4%a4%ea%bf%cd%a4%ce%c9%be%b2%c1%a4%f2%ca%b9%a4%a4%a4%c6%a4%ab%a4%e9%a4%b7%a4%ab%cb%dc%a4%f2%c7%e3%a4%ef%a4%ca%a4%a4%cf%a2%c3%e6%a4%f2%c3%a1%a4%ad%b5%af%a4%b3%a4%bd%a4%a6%26br%28%29%0a%c8%b1%a4%ce%cc%d3%a4%f2%a4%c4%a4%ab%a4%f3%a4%c7%b0%fa%a4%ad%a4%ba%a4%ea%b2%bc%a4%ed%a4%b7%b4%e3%a4%f2%b3%ab%a4%b1%a4%b5%a4%bb%a1%a1%bb%d7%a4%a4%bd%d0%a4%b5%a4%bb%a4%e8%a4%a6%26br%28%29%0a%cf%a2%c3%e6%a4%cb%b6%b2%c9%dd%a4%ce%cc%a3%a4%f2%bb%d7%a4%a4%bd%d0%a4%b5%a4%bb%a4%c6%a4%e4%a4%eb%26br%28%29%0a%cf%a2%c3%e6%a4%cb%be%a6%b6%c8%ce%ae%c4%cc%a4%b9%a4%eb%c3%cf%cd%eb%a4%ce%b0%d5%cc%a3%a4%f2%bb%d7%a4%a4%bd%d0%a4%b5%a4%bb%a4%c6%a4%e4%a4%eb%26br%28%29%0a%be%a6%b6%c8%a4%c8%c6%b1%bf%cd%a4%c8%a4%ce%a4%cf%a4%b6%a4%de%a4%cb%a4%cf%c5%db%a4%e9%a4%ce%c5%af%b3%d8%a4%c7%a4%cf%bb%d7%a4%a4%a4%e2%a4%e8%a4%e9%a4%cc%bb%f6%a4%ac%a4%a2%a4%eb%bb%f6%a4%f2%bb%d7%a4%a4%bd%d0%a4%b5%a4%bb%a4%c6%a4%e4%a4%eb%26br%28%29%0a%b0%ec%c0%e9%bf%cd%a4%ce%c3%cf%cd%eb%bd%e8%cd%fd%a4%ce%c6%c9%bd%f1%c3%c4%a4%c7%ca%b8%c3%c5%a4%f2%c7%b3%a4%e4%a4%b7%bf%d4%a4%af%a4%b7%a4%c6%a4%e4%a4%eb%26br%28%29%0a%26br%28%29%0a%c0%ac%a4%af%a4%be%a1%a1%bd%f4%b7%af%26br%28%29%0a';
 	$content = &decode($content);
 	&code_convert(\$content, $kanjicode);
 	
 	&print_header('[[FrontPage]]');
 	print qq(\n<!--googleoff: all-->\n);
 	&print_content($content);
 	print qq(\n<!--googleon: all-->\n);
 	&print_footer('[[FrontPage]]');
 }

 1;
 __END__
 =head1 NAME

 wiki.cgi - This is [[PonyWiki]], yet another Wiki clone.

 =head1 DESCRIPTION

 [[PonyWiki]] is yet another Wiki clone.

 [[PonyWiki]] can treat Japanese [[WikiName]]s (enclosed with [[ and ]]).
 [[PonyWiki]] provides RDF Site Summary (RSS),
 and some embedded commands (such as [[#comment]] to add comments).

 =head1 AUTHOR

 Kisara <ponytail@you-like.to>

 =head1 LICENSE

 Copyright (C) 2004-2006 by Kisara
 Copyright (C) 2000-2004 by Hiroshi Yuki.

 This program is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.

 =cut
---)

先頭へ