--- suikawiki/script/wiki.cgi 2002/04/23 10:14:12 1.15 +++ suikawiki/script/wiki.cgi 2002/06/02 05:03:38 1.16 @@ -1,1513 +1,1408 @@ #!/usr/bin/perl -use lib "../lib"; -use CGI::Carp 'fatalsToBrowser'; -use Algorithm::Diff qw(traverse_sequences); -# use strict; +#!perl # -# yukiwiki.cgi - Yet another WikiWikiWeb clone. +# wiki.cgi - This is YukiWiki, yet another Wiki clone. # -# Copyright (C) 2000,2001 by Hiroshi Yuki. +# Copyright (C) 2000-2002 by Hiroshi Yuki. # # http://www.hyuki.com/yukiwiki/ # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# $Id: wiki.cgi,v 1.15 2002/04/23 10:14:12 wakaba Exp $ -############################## -my $version = "1.6.6"; -############################## -# 単独テストのときには 1 にする。 -my $testing = 0; -############################## -# 漢字ライブラリ -my $jcodelib = 'jcode.pl'; -############################## -# 保存・表示の漢字コード -my $kanjicode = 'euc'; # 'sjis' 'euc' -my $charset = 'euc-jisx0213'; # 'Shift_JIS' 'EUC-JP' -############################## -# dbmopenが使えるなら1、使えないなら0 -my $dbmopen = 0; -############################## -# データベース名(.pag, .dir, .dbなどは不要) -# $dbmopen = 1のときはデータベース名、 -# $dbmopen = 0のときはディレクトリ名になる。 -my $dbname = './wikidata'; -my $diffdbname = './wikidiff'; -############################## -# 修正者の氏名(自由に変更してください) -my $modifier = 'suika'; -############################## -# 修正者のWebページ(自由に変更してください) -my $modifierlink = 'http://suika.fam.cx/'; ############################## -# このページのURL -my $thisurl = 'wiki'; -############################## -# 開始ページ名 -my $toppage = 'HomePage'; -############################## -# 最終更新ページ名 -my $whatsnew = 'RecentChanges'; -############################## -# 最終更新に掲載するページ数 -my $maxnew = 50; -############################## -# アイコンファイル名(カラー版) -my $iconfile = ''; -############################## -# アイコンファイル名(モノクロ版) -# my $iconfile = ''; -############################## -# ページを変更したときにtouchするファイル(''なら何もしない) -my $touchfile = 'touch.txt'; -############################## -# プレビュー用の背景色 -my $preview_color = '#FFCCCC'; +# +# walwiki.cgi based on yukiwiki.cgi - Yet another WikiWikiWeb clone. +# +# WalWikiの現バージョンは、YukiWiki 2.0.beta1をベースにしています。 +# +# * 更新内容 +# +# 2.0.beta1.wal.1 on 2002/05/19,22:32:19 +# (1) Footerの変更 +# (2) WikiNameの拡張 : PerlCEも包含、PPMInstallは含まない +# (3) 別名リンク([別名 URL])に対応。 +# (4) ISBNをアマゾン.jpのAsociateプログラムリンクに変換。 +# (5) [[#box:InterWikiName]]でInterWikiなテキストボックス生成 +# (6) HTMLモード対応。 +# +# 旧2.0.alpha0.wal.3版までの修正の内、以下に変更があります。 +# ・以下はYukiWiki2に実装されたため、独自コードはなくなりました。 +# - インラインの画像変換 +# - YukiWikiDB対応 +# - テーブル +# - DB関連モジュールuseのeval化 +# - BracketNameによるキーからブラケットを排除 +# ・ISBN番号への対応はWalWiki2.0より、InterWikiへのAdd-Onになりました。 +# [[ISBN http://www.amazon.co.jp/exec/obidos/ASIN/isbn($1)/walrdigi-22]]のように登録。 +# +#======================================= + +# Walrus add (debug) start +my $walrus_log; +my $walrus_debugging = 0; +# Walrus add (debug) end + +# Libraries. +use strict; +use lib qw(./WalWiki/lib); +use CGI qw(:standard); +use CGI::Carp qw(fatalsToBrowser); +use Yuki::RSS; +use Yuki::DiffText qw(difftext); +use Yuki::YukiWikiDB; +use AnyDBM_File; +require 'jcode.pl'; +# use Jcode; +use Fcntl; +my $version = '2.0.beta1.2002-05-29'; ############################## -# 全ページのスタイル -my $style = <<'EOD'; -@import '/s/simpledoc'; -pre, dl, ul, ol, p, blockquote { line-height:120%; -margin-bottom: 1em} -a.wiki .mark {vertical-align: sub, color: GrayText} -a { text-decoration: none; } -a:link { color: #0000FF; background-color: #FFFFFF; } -a:visited { color: #9900CC; background-color: #FFFFFF; } -a:hover { text-decoration: underline; } -EOD +# +# You MUST modify following '$modifier_...' variables. +# +my $modifier_mail = 'w@suika.fam.cx'; # Your mail address, like 'walrus@digit.que.ne.jp'. +my $modifier_url = 'http://suika.fam.cx/~wakaba/'; # Your web page, like 'http://digit.que.ne.jp/work/'. +my $modifier_name = '和'; # Your name, like 'Makio Tsukamoto'. +# my $modifier_dbtype = 'AnyDBM_File'; # Fast, not available on some server, page size limited. +# my $modifier_dbtype = 'dbmopen'; # Fast, not available on some server, page size limited. +my $modifier_dbtype = 'YukiWikiDB'; # Slow, available on all environment. +# my $modifier_sendmail = '/usr/sbin/sendmail -t -n'; # Your sendmail. +my $modifier_sendmail = ''; # If you don't need mail notification. +my $modifier_dir_data = '../wiki'; # Your data directory. +my $modifier_rss_title = "WalWiki $walversion"; +my $modifier_rss_link = 'http://suika.fam.cx/~wakaba/-temp/wiki2/wiki'; # Blank is not allowed. +my $modifier_rss_description = 'This is WalWiki, yet another Wiki clone based on YukiWiki'; ############################## -# テキスト入力部分の大きさ +# +# You MAY modify following variables. +# +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"; +my $url_cgi = 'wiki'; +my $url_stylesheet = './WalWiki/Theme/wiki.css'; +my $icontag = '*'; +my $maxrecent = 50; my $cols = 80; my $rows = 20; ############################## -my %form = (); -my %database = (); -my %diffbase = (); -my $diff_text = ''; -my @diff_added = (); -my @diff_deleted = (); -my $msgrefA; -my $msgrefB; -############################## -# 編集不可ページ名一覧 -my @uneditable = ( $whatsnew ); -############################## -# リンク用の正規表現 -# YukiWikiのリンクは2種類ある。 -# -# (1) WikiName (RecentChangesとかFrontPageのようなもの) -# (2) BracketName ([[結城浩]]とか[[トラブルシュート]]のようなもの) -# -# ※シフトJISの2バイト目には ']' が来うるので、 -# 文字']'を1つ多くとるようにしている。 # -my $WikiName = '([A-Z][a-z]+([A-Z][a-z]+)+)'; -my $BracketName = '\[\[([^>\x09]+?\]?)\]\]'; - -# アイコン部分のタグ -my $IconTag = ''; #<<"EOD"; -#[YukiWiki] -#EOD - -require "$jcodelib"; - -&init_form($kanjicode); - -if ($testing) { - %form = ( - # 'mycmd' => 'write', - 'mycmd' => 'read', - #'mycmd' => 'search', - #'mycmd' => 'edit', - 'mymsg' => <<"EOD", -はじめまして。 -これからいろいろ書き込みますね。 -LinkPageも見てください。 -TestPageはどうでしょうか。 -どうぞよろしく。 -http://www.hyuki.com/ -[[結城浩]] -EOD - 'mypage' => '<結城浩>', - 'myword' => '結', - # '3C8C8B8FE98D5F3E' => '', - # 'TestPage' => '', - ); -} +# You MAY, but do NOT NEED modify following variables. +# +my $dataname = "$modifier_dir_data/wiki"; +my $infoname = "$modifier_dir_data/info"; +my $diffname = "$modifier_dir_data/diff"; +my $editchar = '?'; +my $subject_delimiter = ' - '; +my $use_autoimg = 1; # automatically convert image URL into tag. +my $use_exists = 0; # If you can use 'exists' method for your DB. +############################## +my $InterWikiName = 'InterWikiName'; +my $RecentChanges = 'RecentChanges'; +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'; # must include spaces. +############################## +# my $wiki_name = '\b([A-Z][a-z]+([A-Z][a-z]+)+)\b'; # Walrus del (2) +my $wiki_name = '\b([A-Z][a-z]+([A-Z][a-z]*)+)\b'; # Walrus add (2) +my $bracket_name = '\[\[(\S+?)\]\]'; +my $embedded_name = '\[\[(#\S+?)\]\]'; +my $interwiki_definition = '\[\[(\S+?)\ (\S+?)\]\]'; +my $interwiki_name = '([^:]+):([^:].*)'; +############################## +my $embed_comment = '[[#comment]]'; +my $embed_rcomment = '[[#rcomment]]'; +my $embed_interwiki = '^\[\[#(box|text|password):(\S+)\]\]$'; # Walrus add (5) +############################## +my $info_LastModified = 'LastModified'; +my $info_IsFrozen = 'IsFrozen'; +my $info_AdminPassword = 'AdminPassword'; +############################## +my $kanjicode = 'euc'; +my $charset = 'EUC-JP'; +my $lang = 'ja'; +my %fixedpage = ( + $IndexPage => 1, + $CreatePage => 1, + $ErrorPage => 1, + $RssPage => 1, + $RecentChanges => 1, + $SearchPage => 1, + $AdminChangePassword => 1, + $CompletedSuccessfully => 1, + $FrontPage => 1, +); +my %form; +my %database; +my %infobase; +my %diffbase; +my %resource; +my %interwiki; +############################## +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, + createresult => \&do_createresult, + FrontPage => \&do_FrontPage, + comment => \&do_comment, + rss => \&do_rss, + diff => \&do_diff, + interwikibox => \&do_interwiki_box, # Walrus add (5) +); +############################## +my @ignore_html_page = ('FrontPage'); # Walrus add (6) +my @ignore_html_tags = ('a', 'br', 'img'); # Walrus add (6) +my $walversion = '2.0.beta1.wal.1'; # Walrus add (1) +############################## +# &test_convert; &main; exit(0); +############################## -# メイン sub main { - &normalize_form; - if ($dbmopen) { - if (!dbmopen(%database, $dbname, 0666)) { - &print_error("(dbmopen) $dbname が作れません。"); - } + &init_resource; + &open_db; + &init_form; + &init_InterWikiName; + if ($command_do{$form{mycmd}}) { + &{$command_do{$form{mycmd}}}; } else { - if (!tie(%database, "YukiWikiDB", $dbname)) { - &print_error("(tie error)"); - } - } - - # myspecial対応 - foreach (keys %form) { - if (/^myspecial_(.*)/) { - $form{mycmd} = $1; - last; - } - } - - if ($form{mycmd} eq 'read') { - &do_read; - } elsif ($form{mycmd} eq 'preview') { - &do_preview; - } elsif ($form{mycmd} eq 'write') { - &do_write; - } elsif ($form{mycmd} eq 'edit') { - &do_edit; - } elsif ($form{mycmd} eq 'reedit') { - &do_reedit; - } elsif ($form{mycmd} eq 'search') { - &do_search; - } elsif ($form{mycmd} eq 'list') { - &do_list; - } elsif ($form{mycmd} eq 'diff') { - &do_diff; - } else { - $form{mypage} = $toppage; - &do_read; - } - if ($dbmopen) { - dbmclose(%database); - } else { - untie(%database); + &do_FrontPage; } + &close_db; } -# ページの表示 sub do_read { - my $page_name = $form{mypage}; - my $percent_name = &encode_percent($page_name); - &print_header($page_name); - print qq|

$IconTag$page_name

\n|; - &print_toolbar($page_name); - print &convert_html(&get_page($page_name)); - &print_footer; + &print_header($form{mypage}); + &print_content($database{$form{mypage}}); + &print_footer($form{mypage}); } -# ページの編集 sub do_edit { - if (not &is_editable($form{mypage})) { - # 編集不可ページは表示のみ - &do_read; - return; + my ($page) = &unarmor_name(&armor_name($form{mypage})); + &print_header($page); + if (not &is_editable($page)) { + &print_message($resource{cantchange}); + } elsif (&is_frozen($page)) { + &print_message($resource{cantchange}); + } else { + &print_editform($database{$page}, &get_info($page, $info_LastModified), admin=>0); } - &editpage(&get_page($form{mypage})); + &print_footer($page); } -# ページの再編集 -sub do_reedit { - if (not &is_editable($form{mypage})) { - # 編集不可ページは表示のみ - &do_read; +sub do_adminedit { + my ($page) = &unarmor_name(&armor_name($form{mypage})); + &print_header($page); + if (not &is_editable($page)) { + &print_message($resource{cantchange}); } else { - &editpage($form{mymsg}); + &print_message($resource{passwordneeded}); + &print_editform($database{$page}, &get_info($page, $info_LastModified), admin=>1); } + &print_footer($page); } -sub editpage { - my $page_msg = shift; - my $page_name = $form{mypage}; - my $digest = &calc_message_digest($page_msg); - &print_header($page_name); - print qq|

$IconTag${page_name}の編集

\n|; - &print_toolbar($page_name); - $page_msg = &escape($page_msg); - print <<"EOD"; -
- - - -
- - -
-
-

テキスト整形のルール

- -

通常は入力した文字がそのまま出力されますが、 -以下のルールに従ってテキスト整形を行うことができます。

- - -EOD - &print_footer; +sub do_adminchangepasswordform { + &print_header($AdminChangePassword); + &print_passwordform; + &print_footer($AdminChangePassword); } -# ページの検索 -sub do_search { - if ($form{myword}) { - &print_header('検索結果'); - print qq|

$IconTag$form{myword}の検索結果

\n|; - &print_toolbar(); - print qq|\n|; - if ($count > 0) { - print qq|

$form{myword}を含むページは、上に示す$count ページです。

\n|; - } else { - print qq|

$form{myword}を含むページは見つかりません。

\n|; + } + 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 { + &print_header($IndexPage); + print qq(); + &print_footer($IndexPage); } -# ページの一覧 -sub do_list { - &print_header('ページ一覧'); - print qq|

$IconTag ページ一覧

\n|; - &print_toolbar(); - print qq|\n|; - &print_footer; -} - -# プレビュー -sub do_preview { - my $page_name = $form{mypage}; - my $escapedmsg = &escape($form{mymsg}); - &print_header($page_name); - print qq|

$IconTag${page_name}のプレビュー

\n|; - &print_toolbar($page_name); - # local $percent_name = &encode_percent($page_name); - print qq|

以下のプレビューを確認して、よければページ下部のボタンで更新してください。

\n|; - if ($form{mymsg}) { - print qq|
\n|; - # print &convert_html($escapedmsg); - print &convert_html($form{mymsg}); - print qq|
\n|; - } else { - print qq|

(ページの内容は空です。更新するとこのページは削除されます。)

\n|; +sub do_write { + if (&frozen_reject()) { + return; } - &print_preview_buttons($page_name, $escapedmsg, $form{mydigest}); - &print_footer; -} -sub print_preview_buttons { - my ($page_name, $escapedmsg, $digest) = @_; - print <<"EOD"; -
- -
- - - - -
-EOD -} - -# 書き込む -sub do_write { if (not &is_editable($form{mypage})) { - # 編集不可ページは表示のみ - &do_read; + &print_header($form{mypage}); + &print_message($resource{cantchange}); + &print_footer($form{mypage}); return; } - my $page_name = $form{mypage}; - - # digestを使って、更新の衝突チェック - my $original_digest = &calc_message_digest(&get_page($page_name)); - if ($form{mydigest} ne $original_digest) { - &print_header($page_name); - print qq|

$IconTag${page_name}で【更新の衝突】が起きました

\n|; - print <<"EOD"; -

あなたがこのページを編集している間に、 -他の人が同じページを更新してしまったようです。 -

-以下に、あなたの編集したテキストがありますので、 -あなたの編集内容が失われないように、 -いますぐ、メモ帳などにコピー&ペーストしてください。 -

-コピー&ペーストが済んでから、 -最新の内容を見て再度編集し直してください。 -最新の内容は -$form{mypage} -で見ることができます。 -

-EOD - # &print_toolbar($page_name); - &print_preview_buttons($page_name, &escape($form{mymsg}), $form{mydigest}); - &print_footer; + if (&conflict($form{mypage}, $form{mymsg})) { return; } - # diff生成 + # Making diff { - &opendiff; - my @msg1 = split(/\n/, &get_page($page_name)); + &open_diff; + my @msg1 = split(/\n/, $database{$form{mypage}}); my @msg2 = split(/\n/, $form{mymsg}); - $msgrefA = \@msg1; - $msgrefB = \@msg2; - &diff_check; - $diffbase{$form{mypage}} = $diff_text; - $diff_text = ''; - &closediff; + $diffbase{$form{mypage}} = &difftext(\@msg1, \@msg2); + &close_diff; } - &print_header($page_name); - &set_page($page_name, $form{mymsg}); if ($form{mymsg}) { - print qq|

$IconTag${page_name}を更新しました

\n|; - &print_toolbar($page_name); - print &convert_html(&get_page($page_name)); - } else { - print qq|

$IconTag${page_name}を削除しました

\n|; - &print_toolbar($page_name); - print qq|

${page_name}を削除しました。

\n|; - } - &print_footer; - # 更新されたのでタッチしておく。 - if ($touchfile) { - open(FILE, "> $touchfile"); - print FILE "\n"; - close(FILE); + $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}); + &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"); + delete $database{$form{mypage}}; + delete $infobase{$form{mypage}}; + if ($form{mytouch}) { + &update_recent_changes; + } + &print_header($form{mypage}); + &print_message($resource{deleted}); + &print_footer($form{mypage}); } } -# ページの変更点 -sub do_diff { - if (not &is_editable($form{mypage})) { - # 編集不可ページは表示のみ - &do_read; - return; - } - &opendiff; - &print_header($form{mypage} . 'の変更点'); - print qq|

$IconTag $form{mypage}の変更点

\n|; - &print_toolbar(); - $_ = &escape($diffbase{$form{mypage}}); - print <<"EOD"; - -
-EOD - print qq|
\n|;
-    foreach (split(/\n/, $_)) {
-        if (/^\+(.*)/) {
-            print qq|$1\n|;
-        } elsif (/^\-(.*)/) {
-            print qq|$1\n|;
-        } elsif (/^\=(.*)/) {
-            print qq|$1\n|;
-        } else {
-            print qq|??? $_\n|;
-        }
-    }
-    print qq|
\n|; - &print_footer; - &closediff; +sub do_searchform { + &print_header($SearchPage); + &print_searchform(""); + &print_footer($SearchPage); } -sub opendiff { - if ($dbmopen) { - if (!dbmopen(%diffbase, $diffdbname, 0666)) { - &print_error("(dbmopen) $diffdbname が作れません。"); +sub do_search { + my $word = &escape($form{mymsg}); + &print_header($SearchPage); + &print_searchform($word); + my $counter = 0; + foreach my $page (sort keys %database) { + next if $page =~ /^$RecentChanges$/; + if ($database{$page} =~ /\Q$form{mymsg}\E/ or $page =~ /\Q$form{mymsg}\E/) { + if ($counter == 0) { + print qq||; } + &print_footer($SearchPage); } -sub closediff { - if ($dbmopen) { - dbmclose(%diffbase); - } else { - untie(%diffbase); - } +sub do_create { + &print_header($CreatePage); + print <<"EOD"; +
+ + $resource{newpagename}
+ +
+
+EOD + &print_footer($CreatePage); } -# フォームからの情報を連想配列 %form に入れる -# &init_form('euc'); -sub init_form { - my ($charcode) = @_; - my $query; - if ($ENV{REQUEST_METHOD} =~ /^post$/i) { - read(STDIN, $query, $ENV{CONTENT_LENGTH}); - } else { - $query = $ENV{QUERY_STRING}; - } - my @assocarray = split(/[&;]/, $query); - foreach my $assoc (@assocarray) { - my ($property, $value) = split(/=/, $assoc); - $value =~ tr/+/ /; - $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; - &jcode::convert(\$value, $charcode); - $form{$property} = $value; - } +sub do_FrontPage { + open(FILE, $file_FrontPage) or &print_error("($file_FrontPage)"); + my $content = join('', ); + &code_convert(\$content, $kanjicode); + close(FILE); + &print_header($FrontPage); + &print_content($content); + &print_footer($FrontPage); } -# エラーページを出力する sub print_error { my ($msg) = @_; - &print_header('Error'); - print "

$IconTag$msg

"; + &print_header($ErrorPage); + print qq(

$msg

); + &print_footer($ErrorPage); exit(0); } -sub escape { - my ($line) = shift; - $line =~ s|<|<|g; - $line =~ s|>|>|g; - $line =~ s|"|"|g; - # $line =~ s|\&|&|g; - return $line; -} - -sub inline { - my ($line) = shift; - $line = &escape($line); - $line =~ s|'''([^']+?)'''|$1|g; - $line =~ s|''([^']+?)''|$1|g; - $line =~ s! - ( - (?:<(?:mailto|http|https|ftp|urn):[\x21-\x7E]*)> - #| (?:$WikiName) # LocalLinkLikeThis - | (?:$BracketName) # [[日本語リンク]] - ) - ! - &make_link($1) - !gex; - return $line; -} - -# ページのタイトルからページの内容を得る -sub get_page { - my $page_name = shift; - return $database{$page_name} || $database{'[['.$page_name.']]'}; -} - -# ページの内容を与える -# &set_page($title, $txt) -sub set_page { - # ページを更新する - my $title = $_[0]; - $database{$title} = $_[1]; - # 空ページなら削除する - unless ($database{$title}) { - delete $database{$title}; - } - # RecentChangesを更新する - my $delim = ' - '; - my @pages = split(/\n/, $database{$whatsnew}); - my $datestr = &get_current_datestr; - unshift(@pages, qq|-$datestr$delim$title|); - # 同一ページの更新は最新のもののみにし、 - # 存在しないページはスキップする。 - my %count; - my @newpages; - foreach my $line (@pages) { - my ($prefix, $title) = split(/$delim/, $line); - $count{$title}++; - if ($count{$title} == 1 and exists($database{$title})) { - push(@newpages, qq|$prefix - $title|); - } - } - # ここで本当に更新 - $database{$whatsnew} = join("\n", splice(@newpages, 0, $maxnew)); -} - -# ページのヘッダを出力 sub print_header { - my $title = shift; + my ($page) = @_; + my $bodyclass = "normal"; + my $editable = 0; + my $admineditable = 0; + if (&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); print <<"EOD"; -Content-type: text/html; charset=${charset} +Content-type: text/html; charset=$charset - -$title - + + + + + + $page @{[&escape(&get_subjectline($page))]} + + + - + +
+ @{[ $admineditable + ? qq($resource{admineditbutton} | ) + : qq() + ]} + @{[ $editable + ? qq($resource{editbutton} | ) + : qq() + ]} + @{[ $admineditable + ? qq($resource{diffbutton} | ) + : qq() + ]} + $resource{createbutton} | + $resource{indexbutton} | + $resource{rssbutton} | + $FrontPage | + $resource{searchbutton} | + $resource{recentchangesbutton} +
+

$page@{[&escape(&get_subjectline($page))]}

EOD } -# ツールバーを出力 -sub print_toolbar { - my $page_name = shift; - my $percent_name = &encode_percent($page_name); - my $editlink = ''; - if ($page_name ne '' and &is_editable($page_name)) { - $editlink = <<"EOD"; -編集 | -差分 | -EOD - } +sub print_footer { + my ($page) = @_; + $walrus_log = ($walrus_debugging) ? &text_to_html("----\n$walrus_log") : ''; # Walrus add (debug) + # Walrus mod (1) start + my $mod_info = $modifier_name ? qq(Modified by $modifier_name.) : ''; print <<"EOD"; +