/[pub]/suikawiki/script/lib/suikawiki.pl
Suika

Contents of /suikawiki/script/lib/suikawiki.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.18 - (show annotations) (download)
Thu Oct 30 07:46:09 2003 UTC (21 years, 8 months ago) by wakaba
Branch: MAIN
Changes since 1.17: +37 -83 lines
File MIME type: text/plain
view_in_mode: new method

1 use strict;
2 package main;
3 binmode STDOUT; binmode STDIN;
4 our $WIKI;
5 require SuikaWiki::Plugin;
6 our %embed_command = ( # Map, main
7 form => qr/\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/,
8 );
9 our $database = bless {}, 'wiki::dummy';
10 require SuikaWiki::Name::Space;
11 require Message::Markup::XML;
12 require SuikaWiki::SrcFormat;
13
14 # [to be obsolete]
15 sub do_comment {
16 my ($content) = $main::database{$main::form{mypage}};
17 my $default_name; ## this code is not strict.
18 $default_name = $1 if $content =~ /default-name="([^"]+)"/;
19 my @time = gmtime (time);
20 my $datestr = sprintf '[WEAK[%04d-%02d-%02d %02d:%02d:%02d +00:00]]', $time[5]+1900,$time[4]+1,@time[3,2,1,0];
21 my $namestr = $main::form{myname} || $default_name || &Resource('WikiForm:WikiComment:DefaultName');
22 ($namestr = '', $datestr = '') if $main::form{myname} eq 'nodate';
23 if ($namestr =~ /^(?:>>)?[0-9]/) {
24 $namestr = qq( ''$namestr'': );
25 } elsif (length $namestr) {
26 $namestr = qq( ''[[$namestr]]'': );
27 }
28 my $anchor = &get_new_anchor_index ($content);
29 my $i = 1; my $o = 0;
30 $content =~ s{(\[\[\#r?comment\]\])}{
31 my $embed = $1;
32 if ($i == $main::form{comment_index}) {
33 if ($embed ne '[[#rcomment]]') {
34 $embed = "- [$anchor] $datestr$namestr$main::form{mymsg}\n$embed"; $o = 1;
35 } else {
36 $embed .= "\n- [$anchor] $datestr$namestr$main::form{mymsg}"; $o = 1;
37 }
38 }
39 $i++; $embed;
40 }ge;
41 unless ($o) {
42 $content = "#?SuikaWiki/0.9\n\n" unless $content;
43 $content .= "\n" unless $content =~ /\n$/s;
44 $content .= "- [$anchor] $datestr$namestr$main::form{mymsg}\n";
45 }
46 $main::form{__comment_anchor_index} = $anchor;
47 if ($main::form{mymsg} || $main::form{myname}) {
48 $main::form{mymsg} = $content;
49 $main::form{mytouch} = 'on';
50 &do_write;
51 } else { ## Don't write
52 #$main::form{mycmd} = 'default';
53 #&do_view;
54 die "No comment specified";
55 }
56 }
57
58 # [move to SuikaWiki::Plugin::WikiForm]
59 sub get_new_anchor_index ($) {
60 my $content = shift;
61 my $anchor = 0;
62 $content =~ s/^(?:[-=]+\s*)?\[([0-9]+)\]/$anchor = $1 if $1 > $anchor; $&/mge;
63 $anchor + 1;
64 }
65
66 # [move to SuikaWiki::Plugin::WikiForm]
67 sub do_wikiform {
68 my $content = $main::database{$main::form{mypage}};
69 my $anchor = &get_new_anchor_index ($content);
70 my $write = 0;
71 my $i = 1;
72 $content =~ s{$embed_command{form}}{
73 my ($embed, $wfname, $template, $option) = ($&, $1, $3, $4);
74 if (($wfname && $wfname eq $main::form{wikiform_targetform})
75 || $i == $main::form{wikiform_index}) {
76 $template =~ s/\\([\\'])/$1/g;
77 $option =~ s/\\([\\'])/$1/g;
78 my $param = bless {depth=>10}, 'SuikaWiki::Plugin';
79 $param->{page} = $main::form{mypage};
80 $param->{form_index} = $i;
81 $param->{form_name} = $wfname;
82 $param->{anchor_index} = $anchor;
83 $param->{argv} = \%main::form;
84 $param->{default_name} = $1 if $content =~ /default-name="([^"]+)"/;
85 $param->{default_name} ||= &Resource('WikiForm:WikiComment:DefaultName');
86 SuikaWiki::Plugin->formatter ('form_option')->replace ($option, $param);
87 my $t = 1;
88 for (keys %{$param->{require}||{}}) {
89 (undef $t, last) unless length $param->{argv}->{'wikiform__'.$_};
90 }
91 $t = SuikaWiki::Plugin->formatter ('form_template')->replace ($template, $param) if $t;
92 if (length $t) {
93 if ($param->{output}->{reverse}) {
94 $embed .= "\n" . $t;
95 } else {
96 $embed = $t . "\n" . $embed;
97 }
98 $write = 1;
99 $main::form{__comment_anchor_index} = $anchor
100 if $param->{anchor_index_}; ## $anchor is used!
101 }
102 $main::form{__wikiform_anchor_index} = $i;
103 undef $main::form{wikiform_targetform}; ## Make sure never to match
104 undef $main::form{wikiform_index}; ## with WikiForm in rest of page!
105 }
106 $i++; $embed;
107 }ge;
108 unless ($write) {
109 #$content = "#?SuikaWiki/0.9\n\n" unless $content;
110 #$content .= "\n" unless $content =~ /\n$/s;
111 #
112 }
113 if ($write) {
114 $main::form{mymsg} = $content;
115 $main::form{mytouch} = 'on';
116 &do_write;
117 } else { ## Don't write!
118 #$main::form{mycmd} = 'default';
119 #&do_view;
120 die "No content specified";
121 }
122 }
123
124 # [to be obsolete] ->Message::MIME::Charset
125 sub code_convert {
126 require Jcode;
127 my ($contentref, $code, $srccode) = @_;
128 $code ||= $WIKI->{config}->{charset}->{internal};
129 for ($code, $srccode) {
130 if ($_ eq 'euc-jp') { $_ = 'euc' }
131 elsif ($_ eq 'iso-2022-jp') { $_ = 'jis' }
132 elsif ($_ eq 'utf-8') { $_ = 'utf8' }
133 elsif ($_ eq 'shift_jis') { $_ = 'sjis' }
134 }
135 $$contentref = Jcode->new ($contentref, $srccode)
136 ## Normalize FULLWIDTH characters and IDEOGRAPHIC SPACE
137 ->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\xA1\xE4\xA1\xE3\xA1\xA1\xA2\xAF\xA2\xB0\xA2\xB2\xA2\xB1\xA1\xA1\xC0" => q(0-9A-Za-z&,.:;?!`^_/|()[]{}+$%#*@=>< '"~-))
138 ->tr (qq(\x8E\xDE\x8E\xDF) => qq(\xA1\xAB\xA1\xAC))
139 ->h2z
140 ->$code;
141 return $$contentref;
142 }
143
144 # [to be obsolete] ->Message::Field::Date : Map
145 sub _rfc3339_date ($) {
146 my @time = gmtime (shift);
147 sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', $time[5]+1900,$time[4]+1,@time[3,2,1,0];
148 }
149
150 # [obsolete] ->SuikaWiki::SrcFormat : SuikaWiki09 plugin
151 sub convert_format ($$$;%) {
152 my ($content, $d => $t, %option) = @_;
153 my $f = SuikaWiki::Plugin->format_converter ($d => $t);
154 if (ref $f) {
155 $option{content} = $content;
156 $option{from} = $d;
157 $option{to} = $t;
158 &$f ({}, bless (\%option, 'SuikaWiki::Plugin'));
159 } elsif ($option{-error_no_return}) {
160 return undef;
161 } elsif ($t =~ /HTML|xml/) {
162 if (length $content) {
163 my $NS_XHTML1 = 'http://www.w3.org/1999/xhtml';
164 my $r = SuikaWiki::Markup::XML->new (namespace_uri => $NS_XHTML1, local_name => 'pre');
165 $r->append_text ($content);
166 return $r;
167 } else {
168 return '';
169 }
170 } else {
171 $content;
172 }
173 }
174
175 package wiki::transitional::uri_param;
176 require Tie::Hash;
177 our @ISA = 'Tie::Hash';
178
179 sub TIEHASH ($@) {
180 bless {http => $_[1]}, $_[0];
181 }
182
183 sub FETCH ($$) {
184 my ($self, $key) = @_;
185 exists $self->{val}->{$key} ?
186 $self->{val}->{$key}:
187 $self->{http}->parameter ($key);
188 }
189
190 sub STORE ($$$) {
191 my ($self, $key, $val) = @_;
192 $self->{val}->{$key} = $val;
193 }
194
195 sub DELETE ($$) {
196 my ($self, $key) = @_;
197 $self->{val}->{$key} = undef;
198 }
199
200 sub EXISTS ($$) {
201 my ($self, $key) = @_;
202 exists $self->{val}->{$key} ?
203 1:
204 defined $self->{http}->parameter ($key);
205 }
206
207 package main;
208 our $VERSION = do{my @r=(q$Revision: 1.171 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
209 push @{$WIKI->{event}->{setting_initial_variables}}, sub {
210 my $wiki = shift;
211 $wiki->{implementation_version} = 'wd'.$VERSION;
212
213 ## Error output
214 require SuikaWiki::Output::CGICarp;
215 $SuikaWiki::Output::CGICarp::CUSTOM_REASON_TEXT
216 = 'Internal WikiEngine Error';
217 CGI::Carp::set_message (sub {
218 my $msg = shift;
219 #$msg =~ s/&/&amp;/g;
220 #$msg =~ s/</&lt;/g;
221 my $wiki_name_version = $wiki->{implementation_name} .'/'. $wiki->version;
222 for ($wiki_name_version) { s/&/&amp;/g; s/</&lt;/g;
223 s/([^\x20-\x7E])/sprintf '&#x%02X;',
224 ord $1/g; };
225 print STDOUT <<EOH;
226 <!DOCTYPE html SYSTEM>
227 <title>500 Internal WikiEngine Error</title>
228 <h1>Internal WikiEngine Error</h1>
229 <p>$msg</p>
230 <address>$wiki_name_version</address>
231 EOH
232 });
233
234 $wiki->{var}->{db}->{read_only}->{'#default'} = 1;
235
236 require SuikaWiki::Input::HTTP;
237 $wiki->{input} = SuikaWiki::Input::HTTP->new;
238 $wiki->{input}->{decoder}->{'#default'} = sub {
239 my ($http, $s, $temp_params) = @_;
240 return main::code_convert (\$s, $wiki->{config}->{charset}->{internal},
241 lc (@{$temp_params->{_charset_}||[]}[0])
242 || $wiki->{config}->{charset}->{uri_param});
243 };
244 $wiki->{var}->{client}->{user_agent_name}
245 = $wiki->{input}->meta_variable ('HTTP_USER_AGENT');
246 $wiki->{var}->{client}->{used_for_negotiate} = ['User-Agent'];
247
248 ## TODO: PATH_INFO support
249 my $page = $wiki->{input}->meta_variable ('QUERY_STRING');
250 if ($page && !(index ($page, '=') > -1)) {
251 $page =~ tr/+/ /;
252 $page =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack 'C', hex $1/ge;
253 $page = main::code_convert
254 (\$page, $wiki->{config}->{charset}->{internal},
255 $wiki->{config}->{charset}->{uri_query});
256 } else {
257 $page = $wiki->{input}->parameter ('mypage');
258 }
259
260
261 ## TODO: SuikaWiki 3 WikiName
262 $page =~ tr/\x00-\x20\x7F//d;
263 $page = SuikaWiki::Name::Space::normalize_name ($page);
264 if ($page) {
265 $wiki->{var}->{page} = [split '//', $page];
266 } else {
267 $wiki->{var}->{page} = $wiki->{config}->{page}->{Default};
268 }
269
270 ## Mode
271 my $mode = $wiki->{input}->parameter ('mode')
272 || $wiki->{input}->parameter ('mycmd') ## for compatibility with
273 || 'default'; ## YukiWiki and SuikaWiki 2
274 $mode =~ tr/-/_/;
275 if ($mode eq 'default' || $mode =~ /[^0-9A-Za-z_]/) {
276 ## BUG: this code is not strict
277 my $cookie = $wiki->{input}->meta_variable ('HTTP_COOKIE');
278 if ($cookie =~ /SelectedMode=([0-9A-Za-z_-]+)/) {
279 $mode = $1; $mode =~ tr/-/_/;
280 } else {
281 $mode = 'read';
282 }
283 push @{$wiki->{var}->{client}->{used_for_negotiate}}, 'Cookie';
284 }
285 $wiki->{var}->{mode} = $mode;
286
287 ## Transitional variables
288 tie %main::form, 'wiki::transitional::uri_param', $wiki->{input};
289 $main::UA = $wiki->{var}->{client}->{user_agent_name};
290 $main::form{mypage} = join '//', @{$wiki->{var}->{page}};
291 $main::form{mycmd} = $mode;
292 };
293
294 push @{$WIKI->{event}->{view_in_mode}}, sub {
295 my ($wiki, $opt) = @_;
296 my $arg = {condition => {mode => $opt->{mode} || '-error',
297 output => 'http-cgi',
298 http_method => $opt->{method} || 'GET'}};
299 my $viewobj = $wiki->{view}->instantiate ($opt->{mode} || '-error', $arg);
300 if (ref $viewobj) {
301 $viewobj->main ($arg);
302 } elsif ($opt->{mode} ne '-error') {
303 $wiki->view_in_mode (mode => '-error', method => 'GET');
304 ## TODO: cache control for non-GET
305 } else {
306 die "Some error happens. Additionally, error reporting mode not defined";
307 }
308 };
309
310 ## Initialization of various functions
311 $WIKI->init_variables;
312 $WIKI->init_plugin;
313 $WIKI->init_view;
314 $WIKI->{view}->register_common_modes;
315
316 ## Main
317 $WIKI->view_in_mode
318 (mode => $WIKI->{var}->{mode},
319 method => $WIKI->{input}->meta_variable ('REQUEST_METHOD'));
320
321 exit;
322 END {
323 $WIKI->exit;
324 }
325
326 =head1 NAME
327
328 lib/suikawiki.pl --- SuikaWiki : WikiEngine driver for HTTP CGI
329
330 =head1 LICENSE
331
332 Copyright 2000-2003 Wakaba <w@suika.fam.cx>, et. al
333
334 This program is free software; you can redistribute it and/or
335 modify it under the same terms as Perl itself.
336
337 =cut
338
339 1; # $Date: 2003/10/25 06:38:18 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24