12 |
require 'wikidata/suikawiki-config.ph'; |
require 'wikidata/suikawiki-config.ph'; |
13 |
use Fcntl; |
use Fcntl; |
14 |
############################## |
############################## |
15 |
my %fmt; ## formatter objects |
our %fmt; ## formatter objects |
16 |
my %embed_command = ( |
my %embed_command = ( |
17 |
searched => '^\[\[#searched:([^\]]+)\]\]$', |
searched => '^\[\[#searched:([^\]]+)\]\]$', |
18 |
form => qr/\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/, |
form => qr/\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/, |
19 |
); |
); |
20 |
our ($modifier_dbtype,$url_cgi,%uri,%PathTo,$use_exists); |
our ($modifier_dbtype,$url_cgi,%uri,%PathTo,$use_exists); |
21 |
our (%PageName,$kanjicode,$lang,%FixedPage); |
our (%PageName,$kanjicode,$lang,%ViewDefinition); |
22 |
|
|
23 |
############################## |
############################## |
|
my $info_LastModified = 'LastModified'; |
|
|
my $info_IsFrozen = 'IsFrozen'; |
|
|
############################## |
|
24 |
my %form; |
my %form; |
25 |
our %database; |
our %database; |
26 |
our $database; |
our $database = bless {}, 'wiki::dummy'; |
|
my %infobase; |
|
27 |
my %interwiki; |
my %interwiki; |
28 |
############################## |
############################## |
29 |
my %page_command = ( |
my %page_command = ( |
32 |
my %command_do = ( |
my %command_do = ( |
33 |
read => \&do_read, |
read => \&do_read, |
34 |
TEXT_CSS => \&do_output_css, |
TEXT_CSS => \&do_output_css, |
35 |
edit => \&do_edit, |
edit => \&do_view, |
|
adminedit => \&do_adminedit, |
|
36 |
adminchangepassword => \&do_adminchangepassword, |
adminchangepassword => \&do_adminchangepassword, |
37 |
write => \&do_write, |
write => \&do_write, |
38 |
searchform => \&do_searchform, |
searchform => \&do_searchform, |
39 |
comment => \&do_comment, |
comment => \&do_comment, |
40 |
RandomJump => \&do_random_jump, |
RandomJump => \&do_random_jump, |
41 |
rss => \&do_rss, |
rss => \&do_rss, |
42 |
diff => \&do_diff, |
diff => \&do_view, |
43 |
wikiform => \&do_wikiform, |
wikiform => \&do_wikiform, |
44 |
map => \&do_map, |
map => \&do_view, |
45 |
); |
); |
46 |
my $UA = ''; ## User agent name |
my $UA = ''; ## User agent name |
47 |
$| = 1; |
$| = 1; |
61 |
|
|
62 |
sub do_read { |
sub do_read { |
63 |
my $content = $database{$form{mypage}}; |
my $content = $database{$form{mypage}}; |
64 |
#print "content-type:text/plain;charset=euc-jp\n\n".gmtime."Get Lastmodified\n"; |
my $lm = $database->mtime ($form{mypage}); |
|
my $lm = &get_info($form{mypage}, $info_LastModified); |
|
65 |
wiki::referer::add ($form{mypage}, $ENV{HTTP_REFERER}); |
wiki::referer::add ($form{mypage}, $ENV{HTTP_REFERER}); |
66 |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
|
#print gmtime."Search...\n"; |
|
|
my ($r, $c) = get_search_result ($form{mypage}); |
|
|
my $rl = wiki::referer::list_html ($form{mypage}); |
|
67 |
my @toc; |
my @toc; |
68 |
push @toc, qq(-<a href="#wikipage-see-also">@{[&Resource('SeeAlso',escape=>1)]}</a>) if $c; |
my ($magic, $content) = &SuikaWiki::Plugin::magic_and_content (undef, $content); |
69 |
push @toc, qq(-<a href="#wikipage-referer">@{[&Resource('Referers',escape=>1)]}</a>) if $rl; |
$magic ||= '#?SuikaWiki/0.9'; |
70 |
my $cf = 'SuikaWiki/0.9'; |
if ($magic =~ m!^\#\?SuikaWiki/0.9!) { |
71 |
## Should be support at least: |
my $expires = time; |
72 |
## - 'SuikaWiki/0.9' CRLF |
if ($magic =~ /interactive="yes"/) { |
73 |
## - 'H2H/' ("0.9" / "1.0" / "1.1") CRLF |
$lm = $expires; |
74 |
## - "/*" WSP* 'W3C-CSS/' ("1.0" / "2.0") "*/" CRLF |
} else { |
75 |
$cf = $1 if $content =~ s#^(?:/\*\s*|[\#<]\?)?([A-Z][A-Za-z0-9-]+/[0-9.]+(?:[^0-9.\x0D\x0A][^\x0D\x0A]*)?)[\x0D\x0A]+##s; |
$expires += 120; |
76 |
if ($cf =~ m!^(?:\#\?)?SuikaWiki/0.9(?:$|\s)!) { |
} |
77 |
#print gmtime."Header...\n"; |
&print_header ($form{mypage}, -last_modified => $lm, -expires => $expires, |
78 |
&print_header ($form{mypage}, -last_modified => $lm, -expires => time + 120, |
-content_format => $magic, -noindex => ($magic =~ /obsoleted="yes"/ ? 1 : 0)); |
|
-content_format => $cf, -noindex => ($cf =~ /obsoleted="yes"/ ? 1 : 0)); |
|
|
#print "\n". gmtime."Body...\n"; |
|
|
&print_content ($content, content_format => $cf, last_modified => $lm, |
|
|
-toc => \@toc); |
|
|
print &text_to_html (q([[#comment]])) if $cf !~ /obsoleted="yes"/ && !$FixedPage{$form{mypage}}; |
|
79 |
} else { |
} else { |
80 |
&print_header($form{mypage}, -expires => time + 120, -last_modified => $lm); |
&print_header($form{mypage}, -expires => time + 120, -content_format => $magic, -last_modified => $lm); |
|
print "<pre>@{[&escape($content)]}</pre>"; |
|
81 |
} |
} |
82 |
if ($c) { |
&load_formatter ('view'); |
83 |
print qq{<h2 @{[&id_and_name('wikipage-see-also')]}>@{[&Resource('SeeAlso',escape=>1)]}</h2>}; |
print $fmt{view}->replace ($ViewDefinition{read} => bless {param => \%form, page => $form{mypage}, toc => \@toc, formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
|
print $r; |
|
|
} |
|
|
if ($rl) { |
|
|
print qq(<div @{[&id_and_name('wikipage-referer')]}><h2>@{[&Resource('Referers',escape=>1)]}</h2>\n$rl</div>\n); |
|
|
} |
|
|
#print "\n". gmtime."Footer...\n"; |
|
|
&print_footer($form{mypage}, $lm); |
|
|
#print "\n". gmtime."Fin...\n"; |
|
84 |
} |
} |
85 |
|
|
86 |
sub do_output_css { |
sub do_output_css { |
88 |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
89 |
my $content = $database{$form{mypage}}; |
my $content = $database{$form{mypage}}; |
90 |
if ($content =~ m#^\s*/\*\s*W3C-CSS#) { |
if ($content =~ m#^\s*/\*\s*W3C-CSS#) { |
91 |
my $lm = gmtime &get_info($form{mypage}, $info_LastModified); |
my $lm = gmtime $database->mtime ($form{mypage}); |
92 |
print "Content-Type: text/css; charset=@{[&get_charset_name($kanjicode)]}\n"; |
print "Content-Type: text/css; charset=@{[&get_charset_name($kanjicode)]}\n"; |
93 |
print "Last-Modified: $lm\n"; |
print "Last-Modified: $lm\n"; |
94 |
print "Expires: @{[scalar gmtime time+3600]}\n"; ## TODO: don't use asctime |
print "Expires: @{[scalar gmtime time+3600]}\n"; ## TODO: don't use asctime |
97 |
} else { |
} else { |
98 |
print "Status: 406 Unsupported Media Type\n"; |
print "Status: 406 Unsupported Media Type\n"; |
99 |
&print_header('WikiPageIsNotCSS', -noindex => 1); |
&print_header('WikiPageIsNotCSS', -noindex => 1); |
100 |
&print_content($database{WikiPageIsNotCSS}); |
&load_formatter ('view'); |
101 |
&print_footer('WikiPageIsNotCSS'); |
print $fmt{view}->replace ($ViewDefinition{read} => bless {param => \%form, page => 'WikiPageIsNotCSS', toc => [], formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
102 |
} |
} |
103 |
} |
} |
104 |
|
|
111 |
} |
} |
112 |
} |
} |
113 |
|
|
114 |
sub do_edit { |
sub do_view { |
|
my ($page) = &unarmor_name(&armor_name($form{mypage})); |
|
|
if (not &is_editable($page)) { |
|
|
&print_header($page, -noindex => 1, -expires => time+60); |
|
|
&print_message(&Resource('Error:ThisPageIsUneditable')); |
|
|
} elsif (&is_frozen($page)) { |
|
|
&print_header($page, -noindex => 1, -expires => time+60); |
|
|
&print_message(&Resource('Error:ThisPageIsUneditable')); |
|
|
} else { |
|
|
&print_header($page, -noindex => 1, -expires => time+60); |
|
|
&print_editform($database{$page}, &get_info($page, $info_LastModified), admin=>0); |
|
|
} |
|
115 |
wiki::referer::add ($form{mypage}, $ENV{HTTP_REFERER}); |
wiki::referer::add ($form{mypage}, $ENV{HTTP_REFERER}); |
116 |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
117 |
my ($r, $c) = get_search_result ($form{mypage}); |
&print_header($form{mypage}, -noindex => 1, -expires => time+60); |
118 |
my $rl = wiki::referer::list_html ($form{mypage}); |
&load_formatter ('view'); |
119 |
if ($c) { |
my $view = $form{mycmd}; |
120 |
print qq{<h2 id="wikipage-see-also">@{[&Resource('SeeAlso',escape=>1)]}</h2>}; |
if ($view eq 'edit') { |
121 |
print $r; |
$view = 'adminedit' if $form{admin}; |
122 |
} |
} elsif ($view =~ /[^0-9A-Za-z]/) { |
123 |
if ($rl) { |
$view = 'view' |
|
print qq(<div id="wikipage-referer"><h2>@{[&Resource('Referers',escape=>1)]}</h2>\n$rl</div>\n); |
|
|
} |
|
|
&print_footer($page); |
|
|
} |
|
|
|
|
|
sub do_adminedit { |
|
|
my ($page) = &unarmor_name(&armor_name($form{mypage})); |
|
|
&print_header($page, -noindex => 1, -expires => time+60); |
|
|
if (not &is_editable($page)) { |
|
|
&print_message(&Resource('Error:ThisPageIsUneditable')); |
|
|
} else { |
|
|
&print_message(&Resource('Error:PasswordIsNotSpecified')); |
|
|
&print_editform($database{$page}, &get_info($page, $info_LastModified), admin=>1); |
|
124 |
} |
} |
125 |
&print_footer($page); |
print $fmt{view}->replace ($ViewDefinition{$view} => bless {param => \%form, page => $form{mypage}, toc => [], formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
126 |
} |
} |
127 |
|
|
128 |
sub do_adminchangepassword { |
sub do_adminchangepassword { |
129 |
if ($form{mynewpassword} ne $form{mynewpassword2}) { |
if ($form{mynewpassword} ne $form{mynewpassword2}) { |
130 |
&print_error(&Resource('Error:PasswordMismatch')); |
&print_error(&Resource('Error:PasswordMismatch')); |
131 |
} |
} |
132 |
my ($validpassword_crypt) = &get_info($PageName{AdminSpecialPage}, 'AdminPassword'); |
my ($validpassword_crypt) = $database->meta (AdminPassword => $PageName{AdminSpecialPage}); |
133 |
if ($validpassword_crypt) { |
if ($validpassword_crypt) { |
134 |
if (not &valid_password($form{myoldpassword})) { |
if (not &valid_password($form{myoldpassword})) { |
135 |
&print_error(&Resource('Error:PasswordIsIncorrect')); |
&print_error(&Resource('Error:PasswordIsIncorrect')); |
140 |
my $salt1 = $token[(time | $$) % scalar(@token)]; |
my $salt1 = $token[(time | $$) % scalar(@token)]; |
141 |
my $salt2 = $token[($sec + $min*60 + $hour*60*60) % scalar(@token)]; |
my $salt2 = $token[($sec + $min*60 + $hour*60*60) % scalar(@token)]; |
142 |
my $crypted = crypt($form{mynewpassword}, "$salt1$salt2"); |
my $crypted = crypt($form{mynewpassword}, "$salt1$salt2"); |
143 |
&set_info($PageName{AdminSpecialPage}, 'AdminPassword', $crypted); |
$database->meta (AdminPassword => $PageName{AdminSpecialPage} => $crypted); |
144 |
|
|
145 |
&print_header('CompletedSuccessfully', -noindex => 1); |
&print_header('CompletedSuccessfully', -noindex => 1); |
146 |
&print_message(&Resource('Error:PasswordIsChanged')); |
&print_message(&Resource('Error:PasswordIsChanged')); |
|
&print_footer('CompletedSuccessfully'); |
|
147 |
} |
} |
148 |
|
|
149 |
sub valid_password ($) { |
sub valid_password ($) { |
150 |
my ($validpassword_crypt) = &get_info($PageName{AdminSpecialPage}, 'AdminPassword'); |
my ($validpassword_crypt) = $database->meta (AdminPassword => $PageName{AdminSpecialPage}); |
151 |
return crypt (shift, $validpassword_crypt) eq $validpassword_crypt ? 1 : 0; |
return crypt (shift, $validpassword_crypt) eq $validpassword_crypt ? 1 : 0; |
152 |
} |
} |
153 |
|
|
159 |
if (not &is_editable($form{mypage})) { |
if (not &is_editable($form{mypage})) { |
160 |
&print_header($form{mypage}, -noindex => 1); |
&print_header($form{mypage}, -noindex => 1); |
161 |
&print_message(&Resource('Error:ThisPageIsUneditable')); |
&print_message(&Resource('Error:ThisPageIsUneditable')); |
|
&print_footer($form{mypage}); |
|
162 |
return; |
return; |
163 |
} |
} |
164 |
|
|
165 |
if (&conflict($form{mypage}, $form{mymsg})) { |
## Check confliction |
166 |
return; |
if ($form{myLastModified} ne $database->mtime ($form{mypage})) { |
167 |
|
&print_header($form{mypage}, -noindex => 1); |
168 |
|
&load_formatter ('view'); |
169 |
|
print $fmt{view}->replace ($ViewDefinition{-conflict} => bless {param => \%form, page => $form{mypage}, toc => [], formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
170 |
|
return; |
171 |
} |
} |
172 |
|
|
173 |
if ($form{mymsg}) { |
if ($form{mymsg}) { |
176 |
} else { |
} else { |
177 |
$database->STORE ($form{mypage} => $form{mymsg}, -touch => 0); |
$database->STORE ($form{mypage} => $form{mymsg}, -touch => 0); |
178 |
} |
} |
179 |
&set_info($form{mypage}, $info_IsFrozen, 0 + $form{myfrozen}); |
$database->meta (IsFrozen => $form{mypage} => 0 + $form{myfrozen}); |
180 |
my $fragment = ''; |
my $fragment = ''; |
181 |
$fragment .= qq(;after_edit_cmd=@{[&encode($form{after_edit_cmd})]}) if $form{after_edit_cmd}; |
$fragment .= qq(;after_edit_cmd=@{[&encode($form{after_edit_cmd})]}) if $form{after_edit_cmd}; |
182 |
if ($form{__comment_anchor_index}) { |
if ($form{__comment_anchor_index}) { |
184 |
} elsif ($form{__wikiform_anchor_index}) { |
} elsif ($form{__wikiform_anchor_index}) { |
185 |
$fragment .= qq(#wikiform-$form{__wikiform_anchor_index}); |
$fragment .= qq(#wikiform-$form{__wikiform_anchor_index}); |
186 |
} |
} |
187 |
&print_header('CompletedSuccessfully', -noindex => 1, -goto => $url_cgi.'?mycmd='.&encode($form{after_edit_cmd}||'read').';mypage='.&encode($form{mypage}).qq(;x-param=@{[time.[0..9]->[rand 10]]}$fragment)); |
&print_header($form{mypage}, -noindex => 1, -goto => $url_cgi.'?mycmd='.&encode($form{after_edit_cmd}||'read').';mypage='.&encode($form{mypage}).qq(;x-param=@{[time.[0..9]->[rand 10]]}$fragment)); |
188 |
&print_message(&Resource('Error:SavedSuccessfully')); |
&load_formatter ('view'); |
189 |
&print_content(&Resource('Error:ContinueReading')." @{[&armor_name($form{mypage})]}"); |
print $fmt{view}->replace ($ViewDefinition{-wrote} => bless {param => \%form, page => $form{mypage}, formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
|
&print_footer('CompletedSuccessfully'); |
|
190 |
} else { |
} else { |
191 |
delete $database{$form{mypage}}; |
delete $database{$form{mypage}}; |
|
delete $infobase{$form{mypage}}; |
|
192 |
&print_header($form{mypage}, -noindex => 1); |
&print_header($form{mypage}, -noindex => 1); |
193 |
&print_message(&Resource('Error:PageIsDeletedSuccessfully')); |
&load_formatter ('view'); |
194 |
&print_footer($form{mypage}); |
print $fmt{view}->replace ($ViewDefinition{-deleted} => bless {param => \%form, page => $form{mypage}, formatter => $fmt{view}, &_compatible_options ()}, 'SuikaWiki::Plugin'); |
195 |
} |
} |
196 |
} |
} |
197 |
|
|
198 |
|
sub _compatible_options () { |
199 |
|
(use_anchor_name => ($UA =~ m#Mozilla/[12]\.|Microsoft Internet Explorer# ? 1 : 0)); |
200 |
|
} |
201 |
|
|
202 |
sub get_search_result ($;%) { |
sub get_search_result ($;%) { |
203 |
my $word = lc shift; |
my $word = lc shift; |
204 |
my %option = @_; |
my %option = @_; |
235 |
my ($msg) = @_; |
my ($msg) = @_; |
236 |
&print_header($PageName{ErrorPage}, -noindex => 1); |
&print_header($PageName{ErrorPage}, -noindex => 1); |
237 |
print qq(<p><strong class="error">$msg</strong></p>); |
print qq(<p><strong class="error">$msg</strong></p>); |
|
&print_footer($PageName{ErrorPage}); |
|
238 |
exit(0); |
exit(0); |
239 |
} |
} |
240 |
|
|
271 |
} |
} |
272 |
push @head, qq(<title>@{[&escape($page)]}</title>); |
push @head, qq(<title>@{[&escape($page)]}</title>); |
273 |
if ($UA !~ m#Mozilla/[1-4]\.# || $UA =~ m#MSIE (?:[4-9]\.|\d\d)#) { |
if ($UA !~ m#Mozilla/[1-4]\.# || $UA =~ m#MSIE (?:[4-9]\.|\d\d)#) { |
274 |
push @head, qq(<link rel="stylesheet" type="text/css" href="@{[&escape($uri{wiki}.'?mycmd=TEXT_CSS;mypage='.&encode($PageName{DefaultStyleForHTML}).';x-lm='.&get_info($PageName{DefaultStyleForHTML}, $info_LastModified))]}"); |
push @head, qq(<link rel="stylesheet" type="text/css"). |
275 |
|
qq( href="@{[&escape($uri{wiki}.'?mycmd=TEXT_CSS;mypage='.&encode($PageName{DefaultStyleForHTML}).';x-lm='.$database->mtime ($PageName{DefaultStyleForHTML}))]}"); |
276 |
} |
} |
277 |
push @head, q(<meta name="ROBOTS" content="NOINDEX">) if $option{-noindex}; |
push @head, q(<meta name="ROBOTS" content="NOINDEX">) if $option{-noindex}; |
278 |
my ($Links, $links) = &make_navigate_links ($page); |
my ($Links, $links) = &make_navigate_links ($page); |
288 |
<head profile="http://suika.fam.cx/~wakaba/-temp/wiki/wiki?WikiHTMLMetaProfile"> |
<head profile="http://suika.fam.cx/~wakaba/-temp/wiki/wiki?WikiHTMLMetaProfile"> |
289 |
$links |
$links |
290 |
</head> |
</head> |
|
<body class="$option{body_class}"> |
|
|
EOD |
|
|
&print_navigate_links ($page); |
|
|
print <<EOD; |
|
|
<h1 class="header">@{[&escape($page)]}</h1> |
|
291 |
EOD |
EOD |
292 |
} |
} |
293 |
|
|
303 |
$charset; |
$charset; |
304 |
} |
} |
305 |
|
|
306 |
sub print_navigate_links (@) { |
sub _navigate_links (@) { |
307 |
my ($page) = @_; |
my ($page) = @_; |
308 |
my $editable = (&is_editable($page) && !&is_frozen($page)) ? 1 : 0; |
my $editable = (&is_editable($page) && !&is_frozen($page)) ? 1 : 0; |
309 |
my $cookedpage = &encode($page); |
my $cookedpage = &encode($page); |
310 |
print <<EOH; |
<<EOH; |
|
<div class="tools"> |
|
311 |
@{[ $editable |
@{[ $editable |
312 |
? qq(<a title="@{[&Resource('EditThisPageLong',escape=>1)]}" href="$url_cgi?mycmd=edit;mypage=$cookedpage" accesskey="E" class="wiki-cmd">@{[&Resource('EditThisPage',escape=>1)]}</a> | ) |
? qq(<a title="@{[&Resource('EditThisPageLong',escape=>1)]}" href="$url_cgi?mycmd=edit;mypage=$cookedpage" accesskey="E" class="wiki-cmd">@{[&Resource('EditThisPage',escape=>1)]}</a> | ) |
313 |
: qq() |
: qq() |
320 |
<a href="$url_cgi?$PageName{SearchPage}" class="wiki" title="@{[&Resource('GoToSearchPageLong',escape=>1)]}">@{[&Resource('GoToSearchPage',escape=>1)]}</a> | |
<a href="$url_cgi?$PageName{SearchPage}" class="wiki" title="@{[&Resource('GoToSearchPageLong',escape=>1)]}">@{[&Resource('GoToSearchPage',escape=>1)]}</a> | |
321 |
<a href="$url_cgi?mycmd=RandomJump;x-param=@{[time.[0..9]->[rand 10]]}" class="wiki randomlink" title="@{[&Resource('GoSomewhereLong',escape=>1)]}">@{[&Resource('GoSomewhere',escape=>1)]}</a> | |
<a href="$url_cgi?mycmd=RandomJump;x-param=@{[time.[0..9]->[rand 10]]}" class="wiki randomlink" title="@{[&Resource('GoSomewhereLong',escape=>1)]}">@{[&Resource('GoSomewhere',escape=>1)]}</a> | |
322 |
<a href="$url_cgi?$PageName{RecentChanges}" class="wiki" title="@{[&Resource('GoToRecentChangesLong',escape=>1)]}">@{[&Resource('GoToRecentChanges',escape=>1)]}</a> |
<a href="$url_cgi?$PageName{RecentChanges}" class="wiki" title="@{[&Resource('GoToRecentChangesLong',escape=>1)]}">@{[&Resource('GoToRecentChanges',escape=>1)]}</a> |
|
</div> |
|
323 |
EOH |
EOH |
324 |
} |
} |
325 |
|
|
327 |
my $page = shift; |
my $page = shift; |
328 |
my @link; |
my @link; |
329 |
push @link, {rel=>'edit', href=>"$url_cgi?mycmd=edit;mypage=@{[&encode($page)]}", class=>"wiki-command", title=>&Resource('EditThisPageLink')} if &is_editable ($page) && !&is_frozen ($page); |
push @link, {rel=>'edit', href=>"$url_cgi?mycmd=edit;mypage=@{[&encode($page)]}", class=>"wiki-command", title=>&Resource('EditThisPageLink')} if &is_editable ($page) && !&is_frozen ($page); |
330 |
push @link, {rel=>'edit', href=>"$url_cgi?mycmd=adminedit;mypage=@{[&encode($page)]}", class=>"wiki-command", title=>&Resource('AdminEditThisPageLink')} if &is_editable ($page) || &is_frozen ($page); |
push @link, {rel=>'edit', href=>"$url_cgi?mycmd=edit;admin=1;mypage=@{[&encode($page)]}", class=>"wiki-command", title=>&Resource('AdminEditThisPageLink')} if &is_editable ($page) || &is_frozen ($page); |
331 |
push @link, {rel=>'view', href=>"$url_cgi?mycmd=read;mypage=@{[&encode($page)]};x-p=@{[time.[0..9]->[rand 10]]}", class=>'wiki-command', title=>&Resource('ViewThisPageLink')}; |
push @link, {rel=>'view', href=>"$url_cgi?mycmd=read;mypage=@{[&encode($page)]};x-p=@{[time.[0..9]->[rand 10]]}", class=>'wiki-command', title=>&Resource('ViewThisPageLink')}; |
332 |
push @link, {rel=>'myself', href=>"$url_cgi?@{[&encode($page)]}", class=>'wiki', title=>&Resource('GoToMyselfLink')}; |
push @link, {rel=>'myself', href=>"$url_cgi?@{[&encode($page)]}", class=>'wiki', title=>&Resource('GoToMyselfLink')}; |
333 |
push @link, {rel=>'index', href=>"$url_cgi?$PageName{IndexPage}", class=>'wiki', title=>&Resource('GoToIndexPageLink')}; |
push @link, {rel=>'index', href=>"$url_cgi?$PageName{IndexPage}", class=>'wiki', title=>&Resource('GoToIndexPageLink')}; |
360 |
wantarray ? ($Links, $links) : $Links; |
wantarray ? ($Links, $links) : $Links; |
361 |
} |
} |
362 |
|
|
|
sub print_footer { |
|
|
my ($page, $lm) = @_; |
|
|
my $epage = &encode ($page); |
|
|
my $cvslog1 = q$Revision$; |
|
|
my $cvslog2 = q$Date$; |
|
|
print_navigate_links ($page); |
|
|
print <<"EOD"; |
|
|
@{[ $lm ? qq(<div id="wikipage-last-modified">@{[&Resource('LastModified=',escape=>1)]}@{[&_rfc3339_date ($lm)]}</div>) : '' ]} |
|
|
<div class="footer"> |
|
|
<a href="http://www.hyuki.com/yukiwiki/" title="YukiWiki 2.0.beta1.2002-05-29 © 2000-2002 by Hiroshi Yuki">@{[&Resource('About:Name:YukiWiki',escape=>1)]}</a> <a href="http://digit.que.ne.jp/work/" title="WalWiki 2.0.beta1.wal.1 © 2000-2002 by Makio Tsukamoto">@{[&Resource('About:Name:WalWiki',escape=>1)]}</a> |
|
|
<a href="/gate/cvs/wakaba/wiki/" title="@{[&Resource('About:SuikaWiki:JumpToCVS',escape=>1)]} ($cvslog2)">@{[&Resource('About:Name:SuikaWiki',escape=>1)]} $cvslog1</a> |
|
|
</div> |
|
|
</body> |
|
|
</html> |
|
|
EOD |
|
|
} |
|
|
|
|
363 |
sub escape { |
sub escape { |
364 |
my $s = shift; |
my $s = shift; |
365 |
$s =~ s|\r\n|\n|g; |
$s =~ s|\x0D\x0A|\x0A|g; |
366 |
$s =~ s|&|&|g; |
$s =~ s|&|&|g; |
367 |
$s =~ s|<|<|g; |
$s =~ s|<|<|g; |
368 |
$s =~ s|>|>|g; |
$s =~ s|>|>|g; |
380 |
return $s; |
return $s; |
381 |
} |
} |
382 |
|
|
383 |
sub print_content ($;$) { |
sub convert_format ($$$;%) { |
384 |
my ($rawcontent, %option) = @_; |
my ($content, $d => $t, %option) = @_; |
385 |
print &text_to_html($rawcontent, toc=>1, %option); |
&load_formatter ('format'); |
386 |
|
my $f = $fmt{format}->{$d.'_to_'.$t}; |
387 |
|
if (ref $f) { |
388 |
|
$option{content} = $content; |
389 |
|
&$f ({}, bless (\%option, 'SuikaWiki::Plugin')); |
390 |
|
} elsif ($t =~ /HTML|xml/) { |
391 |
|
length $content ? '<pre>'.&escape($content).'</pre>' : ''; |
392 |
|
} else { |
393 |
|
$content; |
394 |
|
} |
395 |
} |
} |
396 |
|
|
397 |
sub text_to_html { |
sub text_to_html { |
398 |
my ($txt, %option) = @_; |
my ($txt, %option) = @_; |
399 |
my @toc; |
my $toc = $option{-toc} || (ref $option{toc} ? $option{toc} : []); |
|
my @toc2 = @{$option{-toc}||[]}; |
|
400 |
my $tocnum = 0; |
my $tocnum = 0; |
401 |
|
|
402 |
## Load constants |
## Load constants |
418 |
foreach (@txt) { |
foreach (@txt) { |
419 |
chomp; |
chomp; |
420 |
if (/^\*\*\*\*\*([^\x0D\x0A]*)/) { |
if (/^\*\*\*\*\*([^\x0D\x0A]*)/) { |
421 |
push(@toc, qq(----- <a href="#i$tocnum">@{[&escape($1)||$tocnum]}</a>\n)); |
push @$toc, [5, "i$tocnum" => ($1 || $tocnum)]; |
422 |
push(@result, splice(@saved), qq(<h6 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h6>'); |
push(@result, splice(@saved), qq(<h6 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h6>'); |
423 |
$tocnum++; |
$tocnum++; |
424 |
} elsif (/^\*\*\*\*([^\x0D\x0A]*)/) { |
} elsif (/^\*\*\*\*([^\x0D\x0A]*)/) { |
425 |
push(@toc, qq(---- <a href="#i$tocnum">@{[&escape($1)||$tocnum]}</a>\n)); |
push @$toc, [4, "i$tocnum" => ($1 || $tocnum)]; |
426 |
push(@result, splice(@saved), qq(<h5 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h5>'); |
push(@result, splice(@saved), qq(<h5 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h5>'); |
427 |
$tocnum++; |
$tocnum++; |
428 |
} elsif (/^\*\*\*([^\x0D\x0A]*)/) { |
} elsif (/^\*\*\*([^\x0D\x0A]*)/) { |
429 |
push(@toc, qq(--- <a href="#i$tocnum">@{[&escape($1)||$tocnum]}</a>\n)); |
push @$toc, [3, "i$tocnum" => ($1 || $tocnum)]; |
430 |
push(@result, splice(@saved), qq(<h4 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h4>'); |
push(@result, splice(@saved), qq(<h4 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h4>'); |
431 |
$tocnum++; |
$tocnum++; |
432 |
} elsif (/^\*\*([^\x0D\x0A]*)/) { |
} elsif (/^\*\*([^\x0D\x0A]*)/) { |
433 |
# if (/^\*\*(.*)/) { |
# if (/^\*\*(.*)/) { |
434 |
# Walrus mod (6) end |
# Walrus mod (6) end |
435 |
push(@toc, qq(-- <a href="#i$tocnum">@{[&escape($1)||$tocnum]}</a>\n)); |
push @$toc, [2, "i$tocnum" => ($1 || $tocnum)]; |
436 |
push(@result, splice(@saved), qq(<h3 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h3>'); |
push(@result, splice(@saved), qq(<h3 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h3>'); |
437 |
$tocnum++; |
$tocnum++; |
438 |
} elsif (/^\*([^\x0D\x0A]*)/) { |
} elsif (/^\*([^\x0D\x0A]*)/) { |
439 |
push(@toc, qq(- <a href="#i$tocnum">@{[&escape($1)||$tocnum]}</a>\n)); |
push @$toc, [1, "i$tocnum" => ($1 || $tocnum)]; |
440 |
push(@result, splice(@saved), qq(<h2 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h2>'); |
push(@result, splice(@saved), qq(<h2 @{[&id_and_name("i$tocnum")]}>) . &inline($1, const => \%const) . '</h2>'); |
441 |
$tocnum++; |
$tocnum++; |
442 |
} elsif (/^(={1,6})(.*)/) { |
} elsif (/^(={1,6})(.*)/) { |
504 |
} |
} |
505 |
push(@result, splice(@saved)); |
push(@result, splice(@saved)); |
506 |
|
|
507 |
my $toc = ''; |
my $r = join("\n", @result); |
508 |
if ($option{toc}) { |
$r =~ s#<p>\x0D?\x0A</p>##g; |
509 |
# Convert @toc (table of contents) to HTML. |
$r =~ s#[\x0D\x0A]+</#</#g; |
510 |
# This part is taken from Makio Tsukamoto's WalWiki. |
$r =~ s#<pre>\x0D?\x0A#<pre>#g; |
511 |
my (@tocsaved, @tocresult); |
$r; |
|
foreach (@toc,@toc2) { |
|
|
if (/^(-{1,6})(.*)$/) { |
|
|
&back_push('ul', length($1), \@tocsaved, \@tocresult); |
|
|
push(@tocresult, '<li>' . $2 . '</li>'); |
|
|
} |
|
|
} |
|
|
push(@tocresult, splice(@tocsaved)); |
|
|
$toc = join("\n", @tocresult); |
|
|
$toc = $toc ? qq(<div id="wikipage-toc">$toc</div>) : ''; |
|
|
} |
|
|
$toc .= join("\n", @result); |
|
|
$toc =~ s#<p>\n</p>##g; |
|
|
$toc =~ s#[\x0D\x0A]+</#</#g; |
|
|
$toc =~ s#<pre>\n#<pre>#g; |
|
|
$toc; |
|
512 |
} |
} |
513 |
|
|
514 |
sub back_push { |
sub back_push { |
560 |
sub make_wikilink ($%) { |
sub make_wikilink ($%) { |
561 |
my ($ename, %option) = @_; |
my ($ename, %option) = @_; |
562 |
my $name = &unescape ($ename); |
my $name = &unescape ($ename); |
563 |
|
$option{latest} = $option{latest} ? qq(mycmd=read;x-param=@{[time.[0..9]->[rand 10]]};mypage=) : ''; |
564 |
if ($database{$name}) { |
if ($database{$name}) { |
565 |
my $subject = &escape (&get_subjectline ($name, delimiter => '')); |
my $subject = &escape (&get_subjectline ($name, delimiter => '')); |
566 |
if ($option{anchor}) { |
if ($option{anchor}) { |
567 |
return qq(<a title="$subject" href="$url_cgi?@{[&encode($name)]}#anchor-$option{anchor}" class="wiki">$ename>>$option{anchor}</a>); |
return qq(<a title="$subject" href="$uri{wiki}?$option{latest}@{[&encode($name)]}#anchor-$option{anchor}" class="wiki">$ename>>$option{anchor}</a>); |
568 |
} else { |
} else { |
569 |
return qq(<a title="$subject" href="$url_cgi?@{[&encode($name)]}" class="wiki">$ename</a>); |
return qq(<a title="$subject" href="$uri{wiki}?$option{latest}@{[&encode($name)]}" class="wiki">$ename</a>); |
570 |
} |
} |
571 |
} else { |
} else { |
572 |
return qq(<a title="@{[&Resource('JumpAndEditWikiPage',escape=>1)]}" href="$url_cgi?@{[&escape($name)]}" class="wiki not-exist">$ename<span class="mark">@{[&Resource('JumpAndEditWikiPageMark',escape=>1)]}</span></a>); |
return qq(<a title="@{[&Resource('JumpAndEditWikiPage',escape=>1)]}" href="$uri{wiki}?$option{latest}@{[&escape($name)]}" class="wiki not-exist">$ename<span class="mark">@{[&Resource('JumpAndEditWikiPageMark',escape=>1)]}</span></a>); |
573 |
} |
} |
574 |
} |
} |
575 |
|
|
620 |
$FormIndex++; |
$FormIndex++; |
621 |
if (length $definition) { |
if (length $definition) { |
622 |
my $param = bless {}, 'SuikaWiki::Plugin'; |
my $param = bless {}, 'SuikaWiki::Plugin'; |
623 |
my $lastmodified = &get_info($form{mypage}, $info_LastModified); |
my $lastmodified = $database->mtime ($form{mypage}); |
624 |
&load_formatter (qw/form_input form_option/); |
&load_formatter (qw/form_input form_option/); |
625 |
$definition = &unescape ($definition); |
$definition = &unescape ($definition); |
626 |
$definition =~ s/\\(.)/$1/g; |
$definition =~ s/\\(.)/$1/g; |
630 |
$param->{output}->{form} = 1 unless defined $param->{output}->{form}; |
$param->{output}->{form} = 1 unless defined $param->{output}->{form}; |
631 |
$definition .= ' %submit;' if $definition !~ /%submit/ && !$param->{output}->{nosubmit} && $param->{output}->{form}; |
$definition .= ' %submit;' if $definition !~ /%submit/ && !$param->{output}->{nosubmit} && $param->{output}->{form}; |
632 |
my $target_page = $param->{output}->{page} || $form{mypage}; |
my $target_page = $param->{output}->{page} || $form{mypage}; |
633 |
$param->{form_disabled} = 1 if $FixedPage{$target_page}; |
$param->{form_disabled} = 1 if $database->meta (IsFrozen => $form{mypage}); |
634 |
my $target_form = $param->{output}->{id}; |
my $target_form = $param->{output}->{id}; |
635 |
my $r = ''; |
my $r = ''; |
636 |
$r = <<EOH if $param->{output}->{form}; |
$r = <<EOH if $param->{output}->{form}; |
692 |
} |
} |
693 |
} |
} |
694 |
$form{mypage} ||= 'HomePage'; |
$form{mypage} ||= 'HomePage'; |
695 |
|
$form{mypage} =~ tr/\x00-\x1F\x7F//d; |
696 |
$form{mycmd} ||= 'read'; |
$form{mycmd} ||= 'read'; |
697 |
|
|
698 |
# mypreview_edit -> do_edit, with preview. |
# mypreview_edit -> do_edit, with preview. |
739 |
sub open_db { |
sub open_db { |
740 |
if ($modifier_dbtype eq 'dbmopen') { |
if ($modifier_dbtype eq 'dbmopen') { |
741 |
dbmopen(%database, $PathTo{WikiDataBase}, 0666) or &print_error("(dbmopen) $PathTo{WikiDataBase}"); |
dbmopen(%database, $PathTo{WikiDataBase}, 0666) or &print_error("(dbmopen) $PathTo{WikiDataBase}"); |
|
dbmopen(%infobase, $PathTo{WikiInfoBase}, 0666) or &print_error("(dbmopen) $PathTo{WikiInfoBase}"); |
|
742 |
} elsif ($modifier_dbtype eq 'AnyDBM_File') { |
} elsif ($modifier_dbtype eq 'AnyDBM_File') { |
743 |
eval q{use AnyDBM_File}; |
eval q{use AnyDBM_File}; |
744 |
tie(%database, "AnyDBM_File", $PathTo{WikiDataBase}, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $PathTo{WikiDataBase}"); |
tie(%database, "AnyDBM_File", $PathTo{WikiDataBase}, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $PathTo{WikiDataBase}"); |
745 |
tie(%infobase, "AnyDBM_File", $PathTo{WikiInfoBase}, O_RDWR|O_CREAT, 0666) or &print_error("(tie AnyDBM_File) $PathTo{WikiInfoBase}"); |
} elsif ($modifier_dbtype eq 'Yuki::YukiWikiDB') { |
|
} elsif ($modifier_dbtype eq 'YukiWikiDB') { |
|
746 |
eval q{use Yuki::YukiWikiDB}; |
eval q{use Yuki::YukiWikiDB}; |
747 |
tie(%database, "Yuki::YukiWikiDB", $PathTo{WikiDataBase}) or &print_error("(tie Yuki::YukiWikiDB) $PathTo{WikiDataBase}"); |
tie(%database, "Yuki::YukiWikiDB", $PathTo{WikiDataBase}) or &print_error("(tie Yuki::YukiWikiDB) $PathTo{WikiDataBase}"); |
748 |
tie(%infobase, "Yuki::YukiWikiDB", $PathTo{WikiInfoBase}) or &print_error("(tie Yuki::YukiWikiDB) $PathTo{WikiInfoBase}"); |
} else { ## Yuki::YukiWikiDB || Yuki::YukiWikiDBMeta |
|
} else { |
|
749 |
eval qq{use $modifier_dbtype}; |
eval qq{use $modifier_dbtype}; |
750 |
$database = tie(%database, $modifier_dbtype => $PathTo{WikiDataBase}, -lock => 2, -backup => $wiki::diff::UseDiff) or &print_error("(tie $modifier_dbtype) $PathTo{WikiDataBase}"); |
$database = tie(%database, $modifier_dbtype => $PathTo{WikiDataBase}, -lock => 2, -backup => $wiki::diff::UseDiff) or &print_error("(tie $modifier_dbtype) $PathTo{WikiDataBase}"); |
|
tie(%infobase, $modifier_dbtype => $PathTo{WikiInfoBase}, -lock => 2) or &print_error("(tie $modifier_dbtype) $PathTo{WikiInfoBase}"); |
|
751 |
} |
} |
752 |
} |
} |
753 |
|
|
754 |
sub close_db { |
sub close_db { |
755 |
if ($modifier_dbtype eq 'dbmopen') { |
if ($modifier_dbtype eq 'dbmopen') { |
756 |
dbmclose(%database); |
dbmclose(%database); |
|
dbmclose(%infobase); |
|
757 |
} else { |
} else { |
758 |
untie(%database); |
untie(%database); |
|
untie(%infobase); |
|
759 |
} |
} |
760 |
} |
} |
761 |
|
|
762 |
sub print_editform { |
sub editform (@) { |
763 |
my ($mymsg, $lastmodified, %mode) = @_; |
my %option = @_; |
764 |
my $frozen = &is_frozen($form{mypage}); |
my $frozen = &is_frozen ($option{page}); |
765 |
|
$option{content} = $database{$option{page}} unless defined $option{content}; |
766 |
if ($form{mypreview}) { |
$option{content} = $database{NewPageTemplate} unless length $option{content}; |
767 |
if ($form{mymsg}) { |
$option{last_modified} = $database->mtime ($option{page}) unless defined $option{last_modified}; |
768 |
unless ($mode{conflict}) { |
my $f = ''; |
769 |
print qq(<h3>@{[&Resource('Preview:Title',escape=>1)]}</h3>\n); |
my $magic = ''; |
770 |
print qq(<p>@{[&Resource('Preview:Notice',escape=>1)]}</p>\n); |
$magic = $1 if $option{content} =~ m/^([^\x0A\x0D]+)/s; |
771 |
print qq(<div class="preview">\n); |
|
772 |
&print_content($form{mymsg}); |
my $selected = 'read'; |
773 |
print qq(</div>\n); |
if ($form{after_edit_cmd}) { |
774 |
} |
$selected = $form{after_edit_cmd}; |
775 |
} else { |
} elsif ($magic =~ /Const|Config|CSS/) { |
776 |
print @{[&Resource('Preview:Empty',escape=>1)]}; |
$selected = 'edit'; |
777 |
} |
} |
778 |
$mymsg = &escape($form{mymsg}); |
my $afteredit = <<EOH; |
|
} else { |
|
|
$mymsg = &escape($mymsg || $database{NewPageTemplate}); |
|
|
} |
|
|
my $magic = ''; |
|
|
$magic = $1 if $mymsg =~ m/^([^\x0A\x0D]+)/s; |
|
|
|
|
|
my $edit = $mode{admin} ? 'adminedit' : 'edit'; |
|
|
my $selected = 'read'; |
|
|
if ($form{after_edit_cmd}) { |
|
|
$selected = $form{after_edit_cmd}; |
|
|
} elsif ($magic =~ /Const|Config|CSS/) { |
|
|
$selected = 'edit'; |
|
|
} |
|
|
my $afteredit = <<EOH; |
|
779 |
<select name="after_edit_cmd"> |
<select name="after_edit_cmd"> |
780 |
<option value="read" label="@{[&Resource('Edit:SaveAndView',escape=>1)]}"@{[$selected eq 'read' ? ' selected="selected"':'']}>@{[&Resource('Edit:SaveAndView',escape=>1)]}</option> |
<option value="read" label="@{[&Resource('Edit:SaveAndView',escape=>1)]}"@{[$selected eq 'read' ? ' selected="selected"':'']}>@{[&Resource('Edit:SaveAndView',escape=>1)]}</option> |
781 |
<option value="edit" label="@{[&Resource('Edit:SaveAndEdit',escape=>1)]}"@{[$selected eq 'edit' ? ' selected="selected"':'']}>@{[&Resource('Edit:SaveAndEdit',escape=>1)]}</option> |
<option value="edit" label="@{[&Resource('Edit:SaveAndEdit',escape=>1)]}"@{[$selected eq 'edit' ? ' selected="selected"':'']}>@{[&Resource('Edit:SaveAndEdit',escape=>1)]}</option> |
782 |
</select> |
</select> |
783 |
EOH |
EOH |
784 |
|
$f .= <<"EOD"; |
785 |
print <<"EOD"; |
<form action="$uri{wiki}" method="post"> |
786 |
<form action="$url_cgi" method="post"> |
@{[ $option{conflict} ? '' : qq(<label><input type="submit" name="mypreview_write" value="@{[&Resource('Edit:Save',escape=>1)]}"><kbd>S</kbd></label>) ]} |
787 |
<h2>@{[&Resource('Edit:Title',escape=>1)]}</h2> |
@{[ $option{admin} ? qq(<label>@{[&Resource('Edit:Password=',escape=>1)]}<input type="password" name="mypassword" value="" size="10"></label>) : "" ]} [@{[&get_new_anchor_index($option{content})]}]<br> |
788 |
@{[ $mode{conflict} ? '' : qq(<input type="submit" name="mypreview_write" value="@{[&Resource('Edit:Save',escape=>1)]}"><kbd>S</kbd>) ]} |
<input type="hidden" name="myLastModified" value="$option{last_modified}"> |
|
@{[ $mode{admin} ? qq(<label>@{[&Resource('Edit:Password=',escape=>1)]}<input type="password" name="mypassword" value="" size="10"></label>) : "" ]} [@{[do {my $n = 0; |
|
|
$mymsg =~ s/(?:-+\s)?\[([0-9]+)\]/$n = $1 if $1 > $n; $&/mge; |
|
|
++$n}]}]<br> |
|
|
<input type="hidden" name="myLastModified" value="$lastmodified"> |
|
789 |
<input type="hidden" name="mypage" value="@{[&escape($form{mypage})]}"> |
<input type="hidden" name="mypage" value="@{[&escape($form{mypage})]}"> |
790 |
<textarea cols="@{[&Resource('Edit:Form:Cols')+0||80]}" rows="@{[&Resource('Edit:Form:Rows')+0||20]}" name="mymsg" tabindex="1">$mymsg</textarea><br> |
<textarea cols="@{[&Resource('Edit:Form:Cols')+0||80]}" rows="@{[&Resource('Edit:Form:Rows')+0||20]}" name="mymsg" tabindex="1">@{[&escape($option{content})]}</textarea><br> |
791 |
@{[ |
@{[ |
792 |
$mode{admin} ? |
$option{admin} ? |
793 |
qq( |
qq( |
794 |
<label><input type="radio" name="myfrozen" value="1" @{[$frozen ? qq(checked="checked") : ""]}>@{[&Resource('Edit:Freeze',escape=>1)]}</label> |
<label><input type="radio" name="myfrozen" value="1" @{[$frozen ? qq(checked="checked") : ""]}>@{[&Resource('Edit:Freeze',escape=>1)]}</label> |
795 |
<label><input type="radio" name="myfrozen" value="0" @{[$frozen ? "" : qq(checked="checked")]}>@{[&Resource('Edit:DontFreeze',escape=>1)]}</label><br>) |
<label><input type="radio" name="myfrozen" value="0" @{[$frozen ? "" : qq(checked="checked")]}>@{[&Resource('Edit:DontFreeze',escape=>1)]}</label><br>) |
796 |
: "" |
: "" |
797 |
]} |
]} |
798 |
@{[ |
@{[ |
799 |
$mode{conflict} ? "" : |
$option{conflict} ? "" : |
800 |
qq( |
qq( |
801 |
<label><input type="checkbox" name="mytouch" value="on" checked="checked">@{[&Resource('Edit:UpdateTimeStamp',escape=>1)]}</label><br> |
<label><input type="checkbox" name="mytouch" value="on" checked="checked">@{[&Resource('Edit:UpdateTimeStamp',escape=>1)]}</label><br> |
|
<input type="submit" name="mypreview_$edit" value="@{[&Resource('Edit:Preview',escape=>1)]}"> |
|
802 |
<label><input type="submit" name="mypreview_write" value="@{[&Resource('Edit:Save',escape=>1)]}" accesskey="S"><kbd>S</kbd></label> |
<label><input type="submit" name="mypreview_write" value="@{[&Resource('Edit:Save',escape=>1)]}" accesskey="S"><kbd>S</kbd></label> |
803 |
$afteredit |
$afteredit |
804 |
) |
) |
805 |
]} |
]} |
806 |
</form> |
</form> |
807 |
EOD |
EOD |
808 |
unless ($mode{conflict}) { |
$f; |
|
## Show help text |
|
|
my $help = $database{WikiEditHelp}; |
|
|
$help =~ s!^\#\?([A-Z][A-Za-z0-9-]+/[0-9.]+(?:[^0-9.\x0D\x0A][^\x0D\x0A]*)?)[\x0D\x0A]+!!s; |
|
|
print &text_to_html ($help, toc => 0); |
|
|
} |
|
809 |
} |
} |
810 |
|
|
811 |
sub is_editable { |
sub is_editable { |
812 |
my ($page) = @_; |
my ($page) = @_; |
813 |
if ($FixedPage{$page} || $page =~ /\s/ || $page =~ /^\#/) { |
$page =~ /[\x00-\x1F\x7F]/ ? 0 : 1; |
|
return 0; |
|
|
} else { |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
# armor_name: |
|
|
# WikiName -> WikiName |
|
|
# not_wiki_name -> [[not_wiki_name]] |
|
|
sub armor_name { qq([[$_[0]]]) } |
|
|
|
|
|
# unarmor_name: |
|
|
# [[bracket_name]] -> bracket_name |
|
|
# WikiName -> WikiName |
|
|
sub unarmor_name { |
|
|
my ($name) = @_; |
|
|
if ($name =~ /^\[\[(\S+?)\]\]$/) { |
|
|
return $1; |
|
|
} else { |
|
|
return $name; |
|
|
} |
|
814 |
} |
} |
815 |
|
|
816 |
sub decode { |
sub decode { |
821 |
} |
} |
822 |
|
|
823 |
sub encode { |
sub encode { |
824 |
my ($s) = @_; |
my $s = shift; |
825 |
my $encoded = ''; |
$s =~ s/([^0-9A-Za-z_-])/sprintf '%%%02X', ord $1/g; |
826 |
foreach my $ch (split(//, $s)) { |
$s; |
|
if ($ch =~ /[A-Za-z0-9_]/) { |
|
|
$encoded .= $ch; |
|
|
} else { |
|
|
$encoded .= '%' . sprintf("%02X", ord($ch)); |
|
|
} |
|
|
} |
|
|
return $encoded; |
|
|
} |
|
|
|
|
|
sub conflict { |
|
|
my ($page, $rawmsg) = @_; |
|
|
if ($form{myLastModified} eq &get_info($page, $info_LastModified)) { |
|
|
return 0; |
|
|
} |
|
|
&print_header($page, -noindex => 1); |
|
|
&print_content(&Resource('Error:Conflict')); |
|
|
&print_editform($rawmsg, $form{myLastModified}, frozen=>0, conflict=>1); |
|
|
&print_footer($page); |
|
|
return 1; |
|
827 |
} |
} |
828 |
|
|
829 |
sub get_now { |
sub get_now { |
848 |
$interwiki{'[[]]'} = 1; ## dummy |
$interwiki{'[[]]'} = 1; ## dummy |
849 |
} |
} |
850 |
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
851 |
sub frozen_reject { |
sub frozen_reject { |
852 |
my ($isfrozen) = &get_info($form{mypage}, $info_IsFrozen); |
my ($isfrozen) = $database->meta (IsFrozen => $form{mypage}); |
853 |
my ($willbefrozen) = $form{myfrozen}; |
my ($willbefrozen) = $form{myfrozen}; |
854 |
if (not $isfrozen and not $willbefrozen) { |
if (not $isfrozen and not $willbefrozen) { |
855 |
# You need no check. |
# You need no check. |
863 |
} |
} |
864 |
} |
} |
865 |
|
|
866 |
sub is_frozen { |
sub is_frozen ($) { $database->meta (IsFrozen => $_[0]) ? 1 : 0 } |
|
my ($page) = @_; |
|
|
if (&get_info($page, $info_IsFrozen)) { |
|
|
return 1; |
|
|
} else { |
|
|
return 0; |
|
|
} |
|
|
} |
|
867 |
|
|
868 |
sub do_comment { |
sub do_comment { |
869 |
my ($content) = $database{$form{mypage}}; |
my ($content) = $database{$form{mypage}}; |
870 |
my $default_name; ## this code does not strict. |
my $default_name; ## this code is not strict. |
871 |
$default_name = $1 if $content =~ /default-name="([^"]+)"/; |
$default_name = $1 if $content =~ /default-name="([^"]+)"/; |
872 |
my $datestr = '[WEAK['.&get_now.']]'; |
my $datestr = '[WEAK['.&get_now.']]'; |
873 |
my $namestr = $form{myname} || $default_name || &Resource('WikiForm:WikiComment:DefaultName'); |
my $namestr = $form{myname} || $default_name || &Resource('WikiForm:WikiComment:DefaultName'); |
918 |
my ($embedded) = @_; |
my ($embedded) = @_; |
919 |
if ($embedded eq '[[#comment]]' or $embedded eq '[[#rcomment]]') { |
if ($embedded eq '[[#comment]]' or $embedded eq '[[#rcomment]]') { |
920 |
unless ($main::_EMBEDED) { |
unless ($main::_EMBEDED) { |
921 |
my $lastmodified = &get_info($form{mypage}, $info_LastModified); |
my $lastmodified = $database->mtime ($form{mypage}); |
922 |
return <<"EOD"; |
return <<"EOD"; |
923 |
<form action="$url_cgi" method="post" id="x-comment-@{[++$CommentIndex]}" class="comment"><p> |
<form action="$url_cgi" method="post" id="x-comment-@{[++$CommentIndex]}" class="comment"><p> |
924 |
<input type="hidden" name="mycmd" value="comment"> |
<input type="hidden" name="mycmd" value="comment"> |
1042 |
sub code_convert { |
sub code_convert { |
1043 |
require Jcode; |
require Jcode; |
1044 |
my ($contentref, $code) = (shift, shift || $kanjicode); |
my ($contentref, $code) = (shift, shift || $kanjicode); |
1045 |
$code = 'jis' if $code =~ /iso/; |
if ($code =~ /euc/) { $code = 'euc' } |
1046 |
$code = 'euc' if $code =~ /euc/; |
elsif ($code =~ /iso/) { $code = 'jis' } |
1047 |
$code = 'sjis' if $code =~ /shift/; |
elsif ($code =~ /shi/) { $code = 'sjis' } |
1048 |
$code = 'utf8' if $code =~ /utf/; |
elsif ($code =~ /utf/) { $code = 'utf8' } |
1049 |
$$contentref = Jcode->new ($contentref)->tr ("\xA3\xB0-\xA3\xB9\xA3\xC1-\xA3\xDA\xA3\xE1-\xA3\xFA\xA1\xF5\xA1\xA4\xA1\xA5\xA1\xA7\xA1\xA8\xA1\xA9\xA1\xAA\xA1\xAE\xA1\xB0\xA1\xB2\xA1\xBF\xA1\xC3\xA1\xCA\xA1\xCB\xA1\xCE\xA1\xCF\xA1\xD0\xA1\xD1\xA1\xDC\xA1\xF0\xA1\xF3\xA1\xF4\xA1\xF6\xA1\xF7\xA1\xE1\xA2\xAF\xA2\xB0\xA2\xB2\xA2\xB1\xA1\xE4\xA1\xE3\xA1\xC0\xA1\xA1" => q(0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@='"~-><\ ))->$code; |
$$contentref = Jcode->new ($contentref)->tr ("\xA3\xB0-\xA3\xB9\xA3\xC1-\xA3\xDA\xA3\xE1-\xA3\xFA\xA1\xF5\xA1\xA4\xA1\xA5\xA1\xA7\xA1\xA8\xA1\xA9\xA1\xAA\xA1\xAE\xA1\xB0\xA1\xB2\xA1\xBF\xA1\xC3\xA1\xCA\xA1\xCB\xA1\xCE\xA1\xCF\xA1\xD0\xA1\xD1\xA1\xDC\xA1\xF0\xA1\xF3\xA1\xF4\xA1\xF6\xA1\xF7\xA1\xE1\xA2\xAF\xA2\xB0\xA2\xB2\xA2\xB1\xA1\xE4\xA1\xE3\xA1\xC0\xA1\xA1" => q(0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@='"~-><\ ))->$code; |
1050 |
return $$contentref; |
return $$contentref; |
1051 |
} |
} |
1052 |
|
|
|
sub do_diff { |
|
|
my $title = $form{mypage}; |
|
|
&print_header($title, -noindex => 1); |
|
|
print qq(<h2>@{[&Resource('Diff:Title',escape=>1)]}</h2>); |
|
|
print qq(<p>@{[&Resource('Diff:Notice',escape=>1)]}</p>); |
|
|
print qq(<pre class="diff">); |
|
|
for (split(/\n/, &escape ($database->traverse_diff ($form{mypage})))) { |
|
|
if (/^\+(.*)/) { |
|
|
print qq(<ins class="added">$1</ins>\n); |
|
|
} elsif (/^\-(.*)/) { |
|
|
print qq(<del class="deleted">$1</del>\n); |
|
|
} elsif (/^\=(.*)/) { |
|
|
print qq(<span class="same">$1</span>\n); |
|
|
} else { |
|
|
print qq|??? $_\n|; |
|
|
} |
|
|
} |
|
|
print qq(</pre>); |
|
|
&print_footer($title); |
|
|
} |
|
|
|
|
1053 |
sub do_rss { |
sub do_rss { |
1054 |
eval q{use Yuki::RSS}; |
eval q{use Yuki::RSS}; |
1055 |
my $rss = new Yuki::RSS( |
my $rss = new Yuki::RSS( |
1079 |
title => &escape($title), |
title => &escape($title), |
1080 |
link => $myuri . '?' . &encode($title), |
link => $myuri . '?' . &encode($title), |
1081 |
description => &escape(&get_subjectline($title,delimiter=>'')), |
description => &escape(&get_subjectline($title,delimiter=>'')), |
1082 |
'dc:date' => &get_info ($title, $info_LastModified), |
'dc:date' => $database->mtime ($title), |
1083 |
); |
); |
1084 |
$count++; |
$count++; |
1085 |
} |
} |
1097 |
sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', $time[5]+1900,$time[4]+1,@time[3,2,1,0]; |
sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', $time[5]+1900,$time[4]+1,@time[3,2,1,0]; |
1098 |
} |
} |
1099 |
|
|
1100 |
sub is_exist_page { |
sub is_exist_page { $use_exists ? exists ($database{$_[0]}) : $database{$_[0]} } |
|
my ($name) = @_; |
|
|
if ($use_exists) { |
|
|
return exists($database{$name}); |
|
|
} else { |
|
|
return $database{$name}; |
|
|
} |
|
|
} |
|
|
|
|
1101 |
sub __get_database ($) { $database{ $_[0] } } |
sub __get_database ($) { $database{ $_[0] } } |
|
sub __set_database ($$) { $database{ $_[0] } = $_[1] } |
|
|
|
|
|
sub do_map { |
|
|
my $page = $form{mypage}; |
|
|
&print_header ($page); |
|
|
wiki::referer::add ($form{mypage}, $ENV{HTTP_REFERER}); |
|
|
wiki::useragent::add ($ENV{HTTP_USER_AGENT}); |
|
|
my ($r, $c) = get_search_result ($form{mypage}); |
|
|
my $rl = wiki::referer::list_html ($form{mypage}); |
|
|
print "<h2>@{[&Resource('Map:Title',escape=>1)]}</h2>\n<p>@{[&Resource('Map:Description',escape=>1)]}</p>\n"; |
|
|
my %option = (level => 0+&Resource('Map:Depth'), weight_list => {}, not_exist => {}, |
|
|
map_from_here => &Resource('Map:FromHere'), |
|
|
map_from_here_description => &Resource('Map:FromHereLong')); |
|
|
&wiki::map::make_list ($page, %option); |
|
|
print &wiki::map::list_to_html ($page, $option{weight_list}, %option); |
|
|
if ($c) { |
|
|
print qq{<h2 id="wikipage-see-also">@{[&Resource('SeeAlso',escape=>1)]}</h2>}; |
|
|
print $r; |
|
|
} |
|
|
if ($rl) { |
|
|
print qq(<div id="wikipage-referer"><h2>@{[&Resource('Referers',escape=>1)]}</h2>\n$rl</div>\n); |
|
|
} |
|
|
&print_footer ($page); |
|
|
} |
|
1102 |
|
|
1103 |
my %_Resource; |
my %_Resource; |
1104 |
sub Resource ($;%) { |
sub Resource ($;%) { |
1129 |
$list{ $uri }++; |
$list{ $uri }++; |
1130 |
set ($page, \%list); |
set ($page, \%list); |
1131 |
} |
} |
1132 |
sub get ($) { |
sub get ($) { split /"/, $main::database->meta (Referer => $_[0]) } |
|
my $page = shift; |
|
|
split /"/, main::get_info ($page, 'Referer'); |
|
|
} |
|
1133 |
sub set ($%) { |
sub set ($%) { |
1134 |
my $page = shift; |
my $page = shift; |
1135 |
my $list = shift; |
my $list = shift; |
1136 |
main::set_info ($page, Referer => join '"', %$list); |
$main::database->meta (Referer => $page => join '"', %$list); |
1137 |
} |
} |
1138 |
|
|
1139 |
sub get_dont_record () { |
sub get_dont_record () { |
1140 |
map {s/\$/\\\$/g; s/\@/\\\@/g; $_} |
map {s/\$/\\\$/g; s/\@/\\\@/g; $_} |
1141 |
grep !/^#/, |
grep !/^#/, |
1142 |
split /[\x0D\x0A]+/, &main::__get_database ('RefererDontRecord'); |
split /[\x0D\x0A]+/, $main::database{RefererDontRecord}; |
1143 |
} |
} |
1144 |
sub get_site_name () { |
sub get_site_name () { |
1145 |
my @lines = grep /[^#]/, split /[\x0D\x0A]+/, &main::__get_database('RefererSiteName'); |
my @lines = grep /[^#]/, split /[\x0D\x0A]+/, $main::database{RefererSiteName}; |
1146 |
my @item; |
my @item; |
1147 |
for (@lines) { |
for (@lines) { |
1148 |
next if /^#/; |
next if /^#/; |
1227 |
$h; |
$h; |
1228 |
} |
} |
1229 |
|
|
1230 |
|
package wiki::dummy; |
1231 |
|
sub mtime (@) {undef} |
1232 |
|
sub meta (@) {undef} |
1233 |
|
sub Yuki::YukiWikiDB2::meta (@) {undef} |
1234 |
|
|
1235 |
package SuikaWiki::Plugin; |
package SuikaWiki::Plugin; |
1236 |
our $plugin_directory; # defined in top of this file. |
our $plugin_directory; |
1237 |
our %List; |
our %List; |
1238 |
|
our %Index; |
1239 |
|
|
1240 |
sub escape ($$) { main::escape ($_[1]) } |
sub escape ($$) { main::escape ($_[1]) } |
1241 |
sub unescape ($$) { main::unescape ($_[1]) } |
sub unescape ($$) { main::unescape ($_[1]) } |
1244 |
sub __get_datetime ($) { main::get_now () } |
sub __get_datetime ($) { main::get_now () } |
1245 |
sub resource ($$;%) { shift; &main::Resource (@_) } |
sub resource ($$;%) { shift; &main::Resource (@_) } |
1246 |
sub uri ($$) { $main::uri{$_[1]} } |
sub uri ($$) { $main::uri{$_[1]} } |
1247 |
|
sub new_index ($$) { ++$Index{$_[1]} } |
1248 |
|
sub magic_and_content ($$) { |
1249 |
|
my $page = $_[1]; |
1250 |
|
$page =~ s!^((?:\#\?|/\*|<\?)[^\x02\x0A\x0D]+)[\x02\x0A\x0D]+!!s; |
1251 |
|
($1, $page); |
1252 |
|
} |
1253 |
|
sub formatter ($$) { |
1254 |
|
&main::load_formatter ($_[1]); |
1255 |
|
$main::fmt{$_[1]}; |
1256 |
|
} |
1257 |
|
|
1258 |
sub regist ($@) { |
sub regist ($@) { |
1259 |
my $pack = shift; |
my $pack = shift; |
1303 |
for my $lang (sort {$option->{accept_language}->{$b} <=> $option->{accept_language}->{$a}} grep {$option->{accept_language}->{$_}!=0} keys %{$option->{accept_language}}) { |
for my $lang (sort {$option->{accept_language}->{$b} <=> $option->{accept_language}->{$a}} grep {$option->{accept_language}->{$_}!=0} keys %{$option->{accept_language}}) { |
1304 |
while (length $lang) { |
while (length $lang) { |
1305 |
unless ($option->{accept_language}->{defined $option->{accept_language}->{$lang} ? $lang : '*'} == 0) { |
unless ($option->{accept_language}->{defined $option->{accept_language}->{$lang} ? $lang : '*'} == 0) { |
1306 |
$option->{resource}->{$lang} ||= &wiki::suikawikiconst::to_hash (&main::__get_database('WikiResource:'.$lang)); |
$option->{resource}->{$lang} ||= &wiki::suikawikiconst::to_hash ($main::database{'WikiResource:'.$lang}); |
1307 |
$v = $option->{resource}->{$lang}->{$resname}; |
$v = $option->{resource}->{$lang}->{$resname}; |
1308 |
last if defined $v; |
last if defined $v; |
1309 |
} |
} |
1314 |
defined $v ? $v : $resname; |
defined $v ? $v : $resname; |
1315 |
} |
} |
1316 |
|
|
|
package wiki::map; |
|
|
|
|
|
sub make_list ($;%) { |
|
|
my ($page, %option) = @_; |
|
|
$option{level} ||= 3; |
|
|
my %weight; |
|
|
my $content = &main::__get_database ($page); |
|
|
$content =~ s{^\#\?([^\x0A\x0D]+)}{ |
|
|
if ($1 =~ /import="([^"]+)"/) { |
|
|
for (split /\s*,\s*/, $1) { |
|
|
$weight{$_} += 2; |
|
|
} |
|
|
} |
|
|
$&; |
|
|
}ges; |
|
|
## Bug: this code does not support content type. |
|
|
$content =~ s{\[\[((?!\#)[^]]+)\](?:>>\d+)?\]}{ |
|
|
$weight{$1}++; $&; |
|
|
}ge; |
|
|
delete $weight{$page}; ## Delete myself |
|
|
for my $page (keys %weight) { |
|
|
my $w = ($content =~ s/\Q$page\E/$&/g); |
|
|
$weight{$page} += $w + $weight{$page}; ## Weight of [[name]] is x2. |
|
|
($weight{$page} *= 0.1, $option{not_exist}->{$page} = 1) unless &main::is_exist_page ($page); |
|
|
} |
|
|
$option{weight_list}->{$page} = \%weight; |
|
|
if (--$option{level}) { |
|
|
for my $page (keys %weight) { |
|
|
&make_list ($page, %option) unless $option{weight_list}->{$page}; |
|
|
} |
|
|
} |
|
|
$option{weight_list}; |
|
|
} |
|
|
|
|
|
sub list_to_html ($$;%) { |
|
|
my ($Page, $wlist, %option) = @_; |
|
|
my $r = ''; |
|
|
$option{outputed}->{$Page} = 1; |
|
|
for my $page (sort {$wlist->{$Page}->{$b} <=> $wlist->{$Page}->{$a}} keys %{$wlist->{$Page}}) { |
|
|
$r .= qq(<li><span class="weight">[@{[0+$wlist->{$Page}->{$page}]}]</span> <a href="$main::url_cgi?@{[&main::encode($page)]}" class="wiki@{[$option{not_exist}->{$page}?' not-exist':'']}">@{[&main::escape ($page).($option{not_exist}->{$page}?qq(<span class="mark">@{[&main::Resource('JumpAndEditWikiPageMark',escape=>1)]}</span>):'')]}</a> <a href="$main::url_cgi?mycmd=map;mypage=@{[&main::encode($page)]}" class="wiki-cmd map-from-here" title="@{[&main::escape($option{map_from_here_description})]}">@{[&main::escape($option{map_from_here})]}</a> <span class="summary">@{[&main::escape(&main::get_subjectline($page))]}</span>); |
|
|
unless ($option{outputed}->{$page}) { |
|
|
$r .= &list_to_html ($page, $wlist, %option); |
|
|
} |
|
|
$r .= "</li>\n"; |
|
|
} |
|
|
$r ? qq(<ul class="map">$r</ul>) : ''; |
|
|
} |
|
|
|
|
1317 |
package main; |
package main; |
1318 |
&main; |
&main; |
1319 |
exit 0; |
exit 0; |
1324 |
|
|
1325 |
wiki.cgi --- SuikaWiki: Yet yet another Wiki engine |
wiki.cgi --- SuikaWiki: Yet yet another Wiki engine |
1326 |
|
|
1327 |
|
=head1 SEE ALSO |
1328 |
|
|
1329 |
|
<IW:SuikaWiki:SuikaWiki> |
1330 |
|
|
1331 |
=head1 AUTHORS |
=head1 AUTHORS |
1332 |
|
|
1333 |
Hiroshi Yuki <hyuki@hyuki.com> <http://www.hyuki.com/yukiwiki/> |
Hiroshi Yuki <hyuki@hyuki.com> <http://www.hyuki.com/yukiwiki/> |