FSWiki3.6.5ベースにコードを変更。
@@ -8,37 +8,6 @@ | ||
8 | 8 | require "./lib/mimew.pl"; |
9 | 9 | require "./lib/setup.pl"; |
10 | 10 | #------------------------------------------------------------------------------- |
11 | -# 引数で渡したページに遷移 | |
12 | -#------------------------------------------------------------------------------- | |
13 | -sub redirect { | |
14 | - my $page = shift; | |
15 | - my $url = "$MAIN_SCRIPT?p=".&Util::url_encode($page); | |
16 | - &redirectURL($url); | |
17 | -} | |
18 | - | |
19 | -#------------------------------------------------------------------------------- | |
20 | -# 引数で渡したURLに遷移 | |
21 | -#------------------------------------------------------------------------------- | |
22 | -sub redirectURL { | |
23 | - my $url = shift; | |
24 | - | |
25 | - print "Content-Type: text/html;charset=EUC-JP\n"; | |
26 | - print "Pragma: no-cache\n"; | |
27 | - print "Cache-Control: no-cache\n\n"; | |
28 | - print "<html>\n"; | |
29 | - print " <head>\n"; | |
30 | - print " <title>moving...</title>\n"; | |
31 | - print " <meta http-equiv=\"Refresh\" content=\"0;URL=$url\">\n"; | |
32 | - print " </head>\n"; | |
33 | - print " <body>\n"; | |
34 | - print " Wait or <a href=\"$url\">Click Here!!</a>\n"; | |
35 | - print " </body>\n"; | |
36 | - print "</html>\n"; | |
37 | - | |
38 | - exit; | |
39 | -} | |
40 | - | |
41 | -#------------------------------------------------------------------------------- | |
42 | 11 | # ヘッダを表示 |
43 | 12 | #------------------------------------------------------------------------------- |
44 | 13 | sub print_header { |
@@ -57,22 +26,21 @@ | ||
57 | 26 | |
58 | 27 | print "<div class=\"adminmenu\">\n"; |
59 | 28 | print " <span class=\"adminmenu\">\n"; |
60 | - print " <a href=\"$MAIN_SCRIPT?p=FrontPage\">FrontPage</a>\n"; | |
61 | - print " <a href=\"$EDIT_SCRIPT?a=new\">新規</a>\n"; | |
29 | + print " <a href=\"".&Wiki::create_url({p=>"FrontPage"})."\">FrontPage</a>\n"; | |
30 | + print " <a href=\"".&Wiki::create_url({a=>"new"})."\">新規</a>\n"; | |
62 | 31 | if($show==1){ |
63 | - print " <a href=\"$EDIT_SCRIPT?a=edit&p=".&Util::url_encode($in{"p"})."\">編集</a>\n"; | |
32 | + print " <a href=\"".&Wiki::create_url({a=>"edit",p=>$in{"p"}})."\">編集</a>\n"; | |
64 | 33 | } |
65 | - print " <a href=\"$MAIN_SCRIPT?a=search\">検索</a>\n"; | |
66 | - print " <a href=\"$MAIN_SCRIPT?a=list\">一覧</a>\n"; | |
67 | - print " <a href=\"$MAIN_SCRIPT?p=Help\">ヘルプ</a>\n"; | |
34 | + print " <a href=\"".&Wiki::create_url({a=>"search"})."\">検索</a>\n"; | |
35 | + print " <a href=\"".&Wiki::create_url({a=>"list"})."\">一覧</a>\n"; | |
36 | + print " <a href=\"".&Wiki::create_url({p=>"Help"})."\">ヘルプ</a>\n"; | |
68 | 37 | print " </span>\n"; |
69 | 38 | print "</div>\n"; |
70 | 39 | |
71 | 40 | print "<h1>".&Util::escapeHTML($title)."</h1>\n"; |
72 | - if(&Wiki::exists_page("Menu")){ | |
41 | + if(&Wiki::page_exists("Menu")){ | |
73 | 42 | print "<div class=\"main\">\n"; |
74 | 43 | } |
75 | - | |
76 | 44 | } |
77 | 45 | |
78 | 46 | #------------------------------------------------------------------------------- |
@@ -79,16 +47,32 @@ | ||
79 | 47 | # フッタを表示 |
80 | 48 | #------------------------------------------------------------------------------- |
81 | 49 | sub print_footer { |
82 | - if(&Wiki::exists_page("Menu")){ | |
50 | + if(&Wiki::page_exists("Menu")){ | |
83 | 51 | print "</div>\n"; |
84 | 52 | print "<div class=\"sidebar\">\n"; |
85 | 53 | print &Wiki::process_wiki(&Wiki::get_page("Menu")); |
86 | 54 | print "</div>\n"; |
87 | 55 | } |
88 | - print "<div class=\"footer\">Powered by <a href=\"$main::SITE_URL\">FreeStyleWikiLite $main::VERSION</a></div>\n"; | |
56 | + print "<div class=\"footer\">Powered by <a href=\"".$main::SITE_URL."\">FreeStyleWikiLite ".$main::VERSION."</a></div>\n"; | |
89 | 57 | print "</body></html>\n"; |
90 | 58 | } |
91 | 59 | |
60 | +#------------------------------------------------------------------------------- | |
61 | +# 旧Ver(0.0.11)互換性維持 | |
62 | +# 次期バージョンで削除されます。 | |
63 | +#------------------------------------------------------------------------------- | |
64 | +sub redirect { return &Wiki::redirect($@); } | |
65 | +sub redirectURL { return &Wiki::redirectURL($@); } | |
66 | + | |
67 | +package Wiki; | |
68 | +sub exists_page { return &page_exists(shift); } | |
69 | +sub send_mail { return &Util::send_mail($@); } | |
70 | + | |
71 | +package HTMLParser; | |
72 | + | |
73 | +package Util; | |
74 | +sub parse_plugin { return &Wiki::parse_inline_plugin($@); } | |
75 | + | |
92 | 76 | ############################################################################### |
93 | 77 | # |
94 | 78 | # Wiki関連の関数を提供するパッケージ |
@@ -95,125 +79,167 @@ | ||
95 | 79 | # |
96 | 80 | ############################################################################### |
97 | 81 | package Wiki; |
98 | -#------------------------------------------------------------------------------- | |
99 | -# ページを取得 | |
100 | -#------------------------------------------------------------------------------- | |
101 | -sub get_page { | |
102 | - my $page = &Util::url_encode(shift); | |
103 | - | |
104 | - open(DATA,"$main::DATA_DIR/$page.wiki") or &Util::error("$main::DATA_DIR/$page.wikiのオープンに失敗しました。"); | |
105 | - my $content = ""; | |
106 | - while(<DATA>){ | |
107 | - $content .= $_; | |
108 | - } | |
109 | - close(DATA); | |
110 | - | |
111 | - return $content; | |
82 | + | |
83 | +local @current_parser = []; | |
84 | + | |
85 | +#============================================================================== | |
86 | +# プラグインの情報を取得します | |
87 | +#============================================================================== | |
88 | +sub get_plugin_info { | |
89 | + my $name = shift; | |
90 | + return defined($main::P_PLUGIN->{$name}) ? {FUNCTION=>$main::P_PLUGIN->{$name}, TYPE=>'paragraph'} : | |
91 | + defined($main::I_PLUGIN->{$name}) ? {FUNCTION=>$main::I_PLUGIN->{$name}, TYPE=>'inline' } : | |
92 | + defined($main::B_PLUGIN->{$name}) ? {FUNCTION=>$main::B_PLUGIN->{$name}, TYPE=>'block' } : | |
93 | + {}; | |
112 | 94 | } |
113 | -#------------------------------------------------------------------------------- | |
114 | -# ページを保存 | |
115 | -#------------------------------------------------------------------------------- | |
116 | -sub save_page { | |
117 | - my $page = shift; | |
118 | - my $source = shift; | |
95 | + | |
96 | +#============================================================================== | |
97 | +# Wikiソースを渡してHTMLを取得します | |
98 | +#============================================================================== | |
99 | +sub process_wiki { | |
100 | + my $source = shift; | |
101 | + my $mainflg = shift; | |
102 | + my $parser = HTMLParser->new($mainflg); | |
119 | 103 | |
120 | - $page = &Util::trim($page); | |
121 | - $source =~ s/\r\n/\n/g; | |
122 | - $source =~ s/\r/\n/g; | |
104 | + # 裏技用(プラグイン内部からパーサを使う場合) | |
105 | + push(@current_parser, $parser); | |
123 | 106 | |
124 | - my $enc_page = &Util::url_encode($page); | |
125 | - my $action = 'MODIFY'; | |
126 | - unless(-e "$main::DATA_DIR/$enc_page.wiki"){ | |
127 | - $action = 'CREATE'; | |
128 | - } | |
107 | + $parser->parse($source); | |
129 | 108 | |
130 | - # バックアップファイルを作成 | |
131 | - if(-e "$main::DATA_DIR/$enc_page.wiki"){ | |
132 | - open(BACKUP,">$main::BACKUP_DIR/$enc_page.bak") or &Util::error("$main::BACKUP_DIR/$enc_page.bakのオープンに失敗しました。"); | |
133 | - open(DATA ,"$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。"); | |
134 | - while(<DATA>){ | |
135 | - print BACKUP $_; | |
136 | - } | |
137 | - close(DATA); | |
138 | - close(BACKUP); | |
139 | - } | |
109 | + # パーサの参照を解放 | |
110 | + pop(@current_parser); | |
140 | 111 | |
141 | - # 入力内容を保存 | |
142 | - open(DATA,">$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。"); | |
143 | - print DATA $source; | |
144 | - close(DATA); | |
145 | - | |
146 | - &send_mail($action,$page); | |
112 | + return $parser->{html}; | |
147 | 113 | } |
148 | -#------------------------------------------------------------------------------- | |
149 | -# ページを削除 | |
150 | -#------------------------------------------------------------------------------- | |
151 | -sub remove_page { | |
152 | - my $page = shift; | |
153 | - my $enc_page = &Util::url_encode($page); | |
154 | - unlink("$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiの削除に失敗しました。"); | |
155 | - | |
156 | - &send_mail('DELETE',$page); | |
114 | + | |
115 | +#============================================================================== | |
116 | +# パース中の場合、現在有効なHTMLParserのインスタンスを返却します。 | |
117 | +# パース中の内容をプラグインから変更したい場合に使用します。 | |
118 | +#============================================================================== | |
119 | +sub get_current_parser { | |
120 | + return $current_parser[$#current_parser]; | |
157 | 121 | } |
158 | -#------------------------------------------------------------------------------- | |
159 | -# メール送信 | |
160 | -#------------------------------------------------------------------------------- | |
161 | -sub send_mail { | |
162 | - my $action = shift; | |
163 | - my $page = shift; | |
164 | - my $enc_page = &Util::url_encode($page); | |
165 | - | |
166 | - if($main::ADMIN_MAIL eq "" || $main::SEND_MAIL eq ""){ | |
167 | - return; | |
122 | + | |
123 | +#=============================================================================== | |
124 | +# インラインプラグインをパースしてコマンドと引数に分割 | |
125 | +#=============================================================================== | |
126 | +sub parse_inline_plugin { | |
127 | + my $text = shift; | |
128 | + my ($cmd, @args_tmp) = split(/ /,$text); | |
129 | + my $args_txt = &Util::trim(join(" ",@args_tmp)); | |
130 | + if($cmd =~ s/\}\}(.*?)$//){ | |
131 | + return { command=>$cmd, args=>[], post=>"$1 $args_txt"}; | |
168 | 132 | } |
169 | 133 | |
170 | - my $subject = ""; | |
171 | - if($action eq 'CREATE'){ | |
172 | - $subject = "[FSWikiLite]$pageが作成されました"; | |
173 | - | |
174 | - } elsif($action eq 'MODIFY'){ | |
175 | - $subject = "[FSWikiLite]$pageが更新されました"; | |
176 | - | |
177 | - } elsif($action eq 'DELETE'){ | |
178 | - $subject = "[FSWikiLite]$pageが削除されました"; | |
179 | - } | |
134 | + my @ret_args; | |
135 | + my $tmp = ""; | |
136 | + my $escape = 0; | |
137 | + my $quote = 0; | |
138 | + my $i = 0; | |
180 | 139 | |
181 | - # MIMEエンコード | |
182 | - $subject = &main::mimeencode($subject); | |
183 | - | |
184 | - my $head = "Subject: $subject\n". | |
185 | - "From: $main::ADMIN_MAIL\n". | |
186 | - "Content-Transfer-Encoding: 7bit\n". | |
187 | - "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n". | |
188 | - "Reply-To: $main::ADMIN_MAIL\n". | |
189 | - "\n"; | |
190 | - | |
191 | - my $body = "IP:".$ENV{'REMOTE_ADDR'}."\n". | |
192 | - "UA:".$ENV{'HTTP_USER_AGENT'}."\n"; | |
193 | - | |
194 | - if($action eq 'MODIFY' || $action eq 'DELETE'){ | |
195 | - if(-e "$main::BACKUP_DIR/$enc_page.bak"){ | |
196 | - $body .= "以下は変更前のソースです。\n". | |
197 | - "-----------------------------------------------------\n"; | |
198 | - open(BACKUP,"$main::BACKUP_DIR/$enc_page.bak"); | |
199 | - while(my $line = <BACKUP>){ | |
200 | - $body .= $line; | |
140 | + for($i = 0; $i<length($args_txt); $i++){ | |
141 | + my $c = substr($args_txt,$i,1); | |
142 | + if($quote!=1 && $c eq ","){ | |
143 | + if($quote==3){ | |
144 | + $tmp .= '}'; | |
201 | 145 | } |
202 | - close(BACKUP); | |
146 | + push(@ret_args,$tmp); | |
147 | + $tmp = ""; | |
148 | + $quote = 0; | |
149 | + } elsif($quote==1 && $c eq "\\"){ | |
150 | + if($escape==0){ | |
151 | + $escape = 1; | |
152 | + } else { | |
153 | + $tmp .= $c; | |
154 | + $escape = 0; | |
155 | + } | |
156 | + } elsif($quote==0 && $c eq '"'){ | |
157 | + if($tmp eq ""){ | |
158 | + $quote = 1; | |
159 | + } else { | |
160 | + $tmp .= $c; | |
161 | + } | |
162 | + } elsif($quote==1 && $c eq '"'){ | |
163 | + if($escape==1){ | |
164 | + $tmp .= $c; | |
165 | + $escape = 0; | |
166 | + } else { | |
167 | + $quote = 2; | |
168 | + } | |
169 | + } elsif(($quote==0 || $quote==2) && $c eq '}'){ | |
170 | + $quote = 3; | |
171 | + } elsif($quote==3){ | |
172 | + if($c eq '}'){ | |
173 | + last; | |
174 | + } else { | |
175 | + $tmp .= '}'.$c; | |
176 | + $quote = 0; | |
177 | + } | |
178 | + } elsif($quote==2){ | |
179 | + return {error=>"インラインプラグインの構文が不正です。"}; | |
180 | + } else { | |
181 | + $tmp .= $c; | |
182 | + $escape = 0; | |
203 | 183 | } |
204 | 184 | } |
205 | 185 | |
206 | - # 文字コードの変換(jcode.plを使用する) | |
207 | - &jcode::convert(\$body,'jis'); | |
186 | + if($quote!=3){ | |
187 | + my $info = &Wiki::get_plugin_info($cmd); | |
188 | + return undef if (defined($info->{TYPE}) && $info->{TYPE} ne 'block'); | |
189 | + } | |
208 | 190 | |
209 | - open(MAIL,"| $main::SEND_MAIL $main::ADMIN_MAIL"); | |
210 | - print MAIL $head; | |
211 | - print MAIL $body; | |
212 | - close(MAIL); | |
191 | + if($tmp ne ""){ | |
192 | + push(@ret_args,$tmp); | |
193 | + } | |
194 | + | |
195 | + return { command=>$cmd, args=>\@ret_args, | |
196 | + post=>substr($args_txt, $i + 1, length($args_txt) - $i)}; | |
213 | 197 | } |
214 | -#------------------------------------------------------------------------------- | |
198 | + | |
199 | +#============================================================================== | |
200 | +# ページ表示のURLを生成 | |
201 | +#============================================================================== | |
202 | +sub create_page_url { | |
203 | + my $page = shift; | |
204 | + return create_url({p=>$page}); | |
205 | +} | |
206 | + | |
207 | +#============================================================================== | |
208 | +# 任意のURLを生成 | |
209 | +#============================================================================== | |
210 | +sub create_url { | |
211 | + my $params = shift; | |
212 | + my $script = shift; | |
213 | + my $url = ''; | |
214 | + my $query = ''; | |
215 | + my $action = ''; | |
216 | + foreach my $key (keys(%$params)){ | |
217 | + my $val = $params->{$key}; | |
218 | + if ($key eq 'a') { | |
219 | + $action = $val; | |
220 | + } | |
221 | + if($query ne ''){ | |
222 | + $query .= '&'; | |
223 | + } | |
224 | + $query .= Util::url_encode($key)."=".Util::url_encode($val); | |
225 | + } | |
226 | + if(!defined($script)){ | |
227 | + if ($action =~ /^(edit|new|delconf)$/){ | |
228 | + $script = $main::EDIT_SCRIPT; | |
229 | + }else{ | |
230 | + $script = $main::MAIN_SCRIPT; | |
231 | + } | |
232 | + } | |
233 | + $url = $script; | |
234 | + if($query ne ''){ | |
235 | + $url .= '?'.$query; | |
236 | + } | |
237 | + return $url; | |
238 | +} | |
239 | + | |
240 | +#============================================================================== | |
215 | 241 | # ページの一覧を取得 |
216 | -#------------------------------------------------------------------------------- | |
242 | +#============================================================================== | |
217 | 243 | sub get_page_list { |
218 | 244 | opendir(DIR, $main::DATA_DIR); |
219 | 245 | my ($fileentry, @files); |
@@ -240,12 +266,12 @@ | ||
240 | 266 | return @pages; |
241 | 267 | } |
242 | 268 | |
243 | -#------------------------------------------------------------------------------- | |
269 | +#============================================================================== | |
244 | 270 | # ページの更新日時を取得 |
245 | -#------------------------------------------------------------------------------- | |
271 | +#============================================================================== | |
246 | 272 | sub get_last_modified { |
247 | 273 | my $page = shift; |
248 | - if(&exists_page($page)){ | |
274 | + if(&page_exists($page)){ | |
249 | 275 | my $file = sprintf("%s/%s.wiki",$main::DATA_DIR,&Util::url_encode($page)); |
250 | 276 | my @stat = stat($file); |
251 | 277 | return $stat[9]; |
@@ -254,10 +280,61 @@ | ||
254 | 280 | } |
255 | 281 | } |
256 | 282 | |
257 | -#------------------------------------------------------------------------------- | |
283 | +#============================================================================== | |
284 | +# ページを取得 | |
285 | +#============================================================================== | |
286 | +sub get_page { | |
287 | + my $page = &Util::url_encode(shift); | |
288 | + | |
289 | + open(DATA,"$main::DATA_DIR/$page.wiki") or &Util::error("$main::DATA_DIR/$page.wikiのオープンに失敗しました。"); | |
290 | + my $content = ""; | |
291 | + while(<DATA>){ | |
292 | + $content .= $_; | |
293 | + } | |
294 | + close(DATA); | |
295 | + | |
296 | + return $content; | |
297 | +} | |
298 | +#============================================================================== | |
299 | +# ページを保存 | |
300 | +#============================================================================== | |
301 | +sub save_page { | |
302 | + my $page = shift; | |
303 | + my $source = shift; | |
304 | + | |
305 | + $page = &Util::trim($page); | |
306 | + $source =~ s/\r\n/\n/g; | |
307 | + $source =~ s/\r/\n/g; | |
308 | + | |
309 | + my $enc_page = &Util::url_encode($page); | |
310 | + my $action = 'MODIFY'; | |
311 | + unless(-e "$main::DATA_DIR/$enc_page.wiki"){ | |
312 | + $action = 'CREATE'; | |
313 | + } | |
314 | + | |
315 | + # バックアップファイルを作成 | |
316 | + if(-e "$main::DATA_DIR/$enc_page.wiki"){ | |
317 | + open(BACKUP,">$main::BACKUP_DIR/$enc_page.bak") or &Util::error("$main::BACKUP_DIR/$enc_page.bakのオープンに失敗しました。"); | |
318 | + open(DATA ,"$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。"); | |
319 | + while(<DATA>){ | |
320 | + print BACKUP $_; | |
321 | + } | |
322 | + close(DATA); | |
323 | + close(BACKUP); | |
324 | + } | |
325 | + | |
326 | + # 入力内容を保存 | |
327 | + open(DATA,">$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。"); | |
328 | + print DATA $source; | |
329 | + close(DATA); | |
330 | + | |
331 | + &Util::send_mail($action,$page); | |
332 | +} | |
333 | + | |
334 | +#============================================================================== | |
258 | 335 | # ページが存在するかどうか |
259 | -#------------------------------------------------------------------------------- | |
260 | -sub exists_page { | |
336 | +#============================================================================== | |
337 | +sub page_exists { | |
261 | 338 | my $page = &Util::url_encode(shift); |
262 | 339 | if(-e "$main::DATA_DIR/$page.wiki"){ |
263 | 340 | return 1; |
@@ -266,18 +343,48 @@ | ||
266 | 343 | } |
267 | 344 | } |
268 | 345 | |
269 | -#------------------------------------------------------------------------------- | |
270 | -# Wikiソースを渡してHTMLを取得します | |
271 | -#------------------------------------------------------------------------------- | |
272 | -sub process_wiki { | |
273 | - my $source = shift; | |
274 | - my $main = shift; | |
275 | - my $parser = HTMLParser->new($main); | |
276 | - $parser->parse($source); | |
346 | +#============================================================================== | |
347 | +# 引数で渡したページに遷移 | |
348 | +#============================================================================== | |
349 | +sub redirect { | |
350 | + my $page = shift; | |
351 | + my $url = &Wiki::create_url({p=>$page}); | |
352 | + &redirectURL($url); | |
353 | +} | |
354 | + | |
355 | +#============================================================================== | |
356 | +# 引数で渡したURLに遷移 | |
357 | +#============================================================================== | |
358 | +sub redirectURL { | |
359 | + my $url = shift; | |
277 | 360 | |
278 | - return $parser->{html}; | |
361 | + print "Content-Type: text/html;charset=EUC-JP\n"; | |
362 | + print "Pragma: no-cache\n"; | |
363 | + print "Cache-Control: no-cache\n\n"; | |
364 | + print "<html>\n"; | |
365 | + print " <head>\n"; | |
366 | + print " <title>moving...</title>\n"; | |
367 | + print " <meta http-equiv=\"Refresh\" content=\"0;URL=$url\">\n"; | |
368 | + print " </head>\n"; | |
369 | + print " <body>\n"; | |
370 | + print " Wait or <a href=\"$url\">Click Here!!</a>\n"; | |
371 | + print " </body>\n"; | |
372 | + print "</html>\n"; | |
373 | + | |
374 | + exit; | |
279 | 375 | } |
280 | 376 | |
377 | +#============================================================================== | |
378 | +# ページを削除 | |
379 | +#============================================================================== | |
380 | +sub remove_page { | |
381 | + my $page = shift; | |
382 | + my $enc_page = &Util::url_encode($page); | |
383 | + unlink("$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiの削除に失敗しました。"); | |
384 | + | |
385 | + &Util::send_mail('DELETE',$page); | |
386 | +} | |
387 | + | |
281 | 388 | ############################################################################### |
282 | 389 | # |
283 | 390 | # HTMLパーサ |
@@ -294,14 +401,18 @@ | ||
294 | 401 | |
295 | 402 | if(!defined($mainflg) || $mainflg eq ""){ $mainflg = 0; } |
296 | 403 | |
404 | + $self->{dl_flag} = 0; | |
405 | + $self->{dt} = ""; | |
406 | + $self->{dd} = ""; | |
407 | + | |
297 | 408 | $self->{html} = ""; |
298 | 409 | $self->{pre} = ""; |
299 | 410 | $self->{quote} = ""; |
300 | 411 | $self->{table} = 0; |
301 | 412 | $self->{level} = 0; |
413 | + $self->{list} = 0; | |
302 | 414 | $self->{para} = 0; |
303 | 415 | $self->{p_cnt} = 0; |
304 | - $self->{explan} = 0; | |
305 | 416 | $self->{main} = $mainflg; |
306 | 417 | return bless $self,$class; |
307 | 418 | } |
@@ -313,7 +424,9 @@ | ||
313 | 424 | my $self = shift; |
314 | 425 | my $source = shift; |
315 | 426 | |
427 | + $self->start_parse; | |
316 | 428 | $source =~ s/\r//g; |
429 | + | |
317 | 430 | my @lines = split(/\n/,$source); |
318 | 431 | |
319 | 432 | foreach my $line (@lines){ |
@@ -327,17 +440,45 @@ | ||
327 | 440 | my $word3 = substr($line,0,3); |
328 | 441 | |
329 | 442 | # 空行 |
330 | - if($line eq ""){ | |
443 | + if($line eq "" && !$self->{block}){ | |
331 | 444 | $self->l_paragraph(); |
332 | 445 | next; |
333 | 446 | } |
334 | 447 | |
448 | + # ブロック書式のエスケープ | |
449 | + if($word2 eq "\\\\" || $word1 eq "\\"){ | |
450 | + my @obj = $self->parse_line(substr($line, 1)); | |
451 | + $self->l_text(\@obj); | |
452 | + next; | |
453 | + } | |
454 | + | |
335 | 455 | # パラグラフプラグイン |
336 | - if($line =~ /^{{((.|\s)+?)}}$/){ | |
337 | - my $plugin = &Util::parse_plugin($1); | |
338 | - my $class = $main::P_PLUGIN->{$plugin->{command}}; | |
339 | - if(defined($class)){ | |
340 | - $self->l_plugin($plugin); | |
456 | + if($line =~ /^\{\{(.+\}\})$/){ | |
457 | + if(!$self->{block}){ | |
458 | + my $plugin = &Wiki::parse_inline_plugin($1); | |
459 | + my $info = &Wiki::get_plugin_info($plugin->{command}); | |
460 | + if($info->{TYPE} eq "paragraph"){ | |
461 | + $self->l_plugin($plugin); | |
462 | + } else { | |
463 | + my @obj = $self->parse_line($line); | |
464 | + $self->l_text(\@obj); | |
465 | + } | |
466 | + next; | |
467 | + } | |
468 | + } elsif($line =~ /^\{\{(.+)$/){ | |
469 | + if ($self->{block}) { | |
470 | + my $plugin = &Wiki::parse_inline_plugin($1); | |
471 | + my $info = &Wiki::get_plugin_info($plugin->{command}); | |
472 | + $self->{block}->{level}++ if($info->{TYPE} eq "block"); | |
473 | + $self->{block}->{args}->[0] .= $line."\n"; | |
474 | + next; | |
475 | + } | |
476 | + my $plugin = &Wiki::parse_inline_plugin($1); | |
477 | + my $info = &Wiki::get_plugin_info($plugin->{command}); | |
478 | + if($info->{TYPE} eq "block"){ | |
479 | + unshift(@{$plugin->{args}}, ""); | |
480 | + $self->{block} = $plugin; | |
481 | + $self->{block}->{level} = 0; | |
341 | 482 | } else { |
342 | 483 | my @obj = $self->parse_line($line); |
343 | 484 | $self->l_text(\@obj); |
@@ -344,6 +485,21 @@ | ||
344 | 485 | } |
345 | 486 | next; |
346 | 487 | } |
488 | + if($self->{block}){ | |
489 | + if($line eq "}}"){ | |
490 | + if ($self->{block}->{level} > 0) { | |
491 | + $self->{block}->{level}--; | |
492 | + $self->{block}->{args}->[0] .= $line."\n"; | |
493 | + next; | |
494 | + } | |
495 | + my $plugin = $self->{block}; | |
496 | + delete($self->{block}); | |
497 | + $self->l_plugin($plugin); | |
498 | + } else { | |
499 | + $self->{block}->{args}->[0] .= $line."\n"; | |
500 | + } | |
501 | + next; | |
502 | + } | |
347 | 503 | |
348 | 504 | # PRE |
349 | 505 | if($word1 eq " " || $word1 eq "\t"){ |
@@ -403,10 +559,10 @@ | ||
403 | 559 | $self->{dd} .= substr($line,3); |
404 | 560 | next; |
405 | 561 | } |
562 | + if($self->{dt} ne "" || $self->{dd} ne ""){ | |
563 | + $self->multi_explanation; | |
564 | + } | |
406 | 565 | if(index($line,"::")==0){ |
407 | - if($self->{dt} ne "" || $self->{dd} ne ""){ | |
408 | - $self->multi_explanation; | |
409 | - } | |
410 | 566 | $self->{dt} = substr($line,2); |
411 | 567 | $self->{dl_flag} = 1; |
412 | 568 | next; |
@@ -423,7 +579,7 @@ | ||
423 | 579 | $line .= " "; |
424 | 580 | } |
425 | 581 | my @spl = map {/^"(.*)"$/ ? scalar($_ = $1, s/\"\"/\"/g, $_) : $_} |
426 | - ($line =~ /,\s*(\"[^\"]*(?:\"\"[^\"]*)*\"|[^,]*)/g); | |
582 | + ($line =~ /,\s*(\"[^\"]*(?:\"\"[^\"]*)*\"|[^,]*)/g); | |
427 | 583 | my @array; |
428 | 584 | foreach my $value (@spl){ |
429 | 585 | my @cell = $self->parse_line($value); |
@@ -444,6 +600,13 @@ | ||
444 | 600 | # 複数行の説明 |
445 | 601 | $self->multi_explanation; |
446 | 602 | |
603 | + # パース中のブロックプラグインがあった場合、とりあえず評価しておく? | |
604 | + if($self->{block}){ | |
605 | + my $plugin = $self->{block}; | |
606 | + delete($self->{block}); | |
607 | + $self->l_plugin($plugin); | |
608 | + } | |
609 | + | |
447 | 610 | $self->end_parse; |
448 | 611 | } |
449 | 612 |
@@ -467,121 +630,222 @@ | ||
467 | 630 | # 1行分をパース |
468 | 631 | #=============================================================================== |
469 | 632 | sub parse_line { |
470 | - my $self = shift; | |
471 | - my $source = shift; | |
472 | - my @array = (); | |
473 | - | |
474 | - # プラグイン | |
475 | - if($source =~ /{{((.|\s)+?)}}/){ | |
476 | - my $pre = $`; | |
477 | - my $post = $'; | |
478 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
479 | - my $plugin = &Util::parse_plugin($1); | |
480 | - my $class = $main::I_PLUGIN->{$plugin->{command}}; | |
481 | - if(defined($class)){ | |
482 | - push @array,$self->plugin($plugin); | |
483 | - } else { | |
484 | - push @array,$self->text("{{$1}}"); | |
633 | + my ($self, $source) = @_; | |
634 | + | |
635 | + return () if (not defined $source); | |
636 | + | |
637 | + my @array = (); | |
638 | + my $pre = q{}; | |
639 | + my @parsed = (); | |
640 | + | |
641 | + # $source が空になるまで繰り返す。 | |
642 | + SOURCE: | |
643 | + while ($source ne q{}) { | |
644 | + | |
645 | + # どのインライン Wiki 書式の先頭にも match しない場合 | |
646 | + if (!($source =~ /^(.*?)((?:\{\{|\[\[?|https?:|mailto:|f(?:tp:|ile:)|'''?|==|__|<<).*)$/)) { | |
647 | + # WikiName検索・置換処理のみ実施して終了する | |
648 | + push @array, $self->_parse_line_wikiname($pre . $source); | |
649 | + return @array; | |
485 | 650 | } |
486 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
487 | - | |
488 | - # ボールド、イタリック、取り消し線、下線 | |
489 | - } elsif($source =~ /((''')|('')|(==)|(__))(.+?)(\1)/){ | |
490 | - my $pre = $`; | |
491 | - my $post = $'; | |
492 | - my $type = $1; | |
493 | - my $label = $6; | |
494 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
495 | - if($type eq "'''"){ | |
496 | - push @array,$self->bold($label); | |
497 | - } elsif($type eq "__"){ | |
498 | - push @array,$self->underline($label); | |
499 | - } elsif($type eq "''"){ | |
500 | - push @array,$self->italic($label); | |
501 | - } elsif($type eq "=="){ | |
502 | - push @array,$self->denialline($label); | |
651 | + | |
652 | + $pre .= $1; # match しなかった先頭部分は溜めておいて後で処理する | |
653 | + $source = $2; # match 部分は後続処理にて詳細チェックを行う | |
654 | + @parsed = (); | |
655 | + | |
656 | + # プラグイン | |
657 | + if ($source =~ /^\{\{/) { | |
658 | + $source = $'; | |
659 | + my $plugin = &Wiki::parse_inline_plugin($source); | |
660 | + unless($plugin){ | |
661 | + push @parsed, '{{'; | |
662 | + push @parsed, $self->parse_line($source); | |
663 | + } else { | |
664 | + my $info = &Wiki::get_plugin_info($plugin->{command}); | |
665 | + if($info->{TYPE} eq "inline"){ | |
666 | + push @parsed, $self->plugin($plugin); | |
667 | + } else { | |
668 | + push @parsed, $self->parse_line("<<".$plugin->{command}."プラグインは存在しません。>>"); | |
669 | + } | |
670 | + if ($source ne "") { | |
671 | + $source = $plugin->{post}; | |
672 | + } | |
673 | + } | |
503 | 674 | } |
504 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
505 | - | |
506 | - # ページ別名リンク | |
507 | - } elsif($source =~ /\[\[([^\[]+?)\|(.+?)\]\]/){ | |
508 | - my $pre = $`; | |
509 | - my $post = $'; | |
510 | - my $label = $1; | |
511 | - my $page = $2; | |
512 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
513 | - push @array,$self->wiki_anchor($page,$label); | |
514 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
515 | 675 | |
516 | - # URL別名リンク | |
517 | - } elsif($source =~ /\[([^\[]+?)\|((http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/ | |
518 | - || $source =~ /\[([^\[]+?)\|(file:[^\[\]]*)\]/ | |
519 | - || $source =~ /\[([^\[]+?)\|((\/|\.\/|\.\.\/)+[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/){ | |
520 | - my $pre = $`; | |
521 | - my $post = $'; | |
522 | - my $label = $1; | |
523 | - my $url = $2; | |
524 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
525 | - if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ | |
526 | - push @array,"<span class=\"error\">不正なリンクです。</span>"; | |
527 | - } else { | |
528 | - push @array,$self->url_anchor($url,$label); | |
676 | + # ページ別名リンク | |
677 | + elsif ($source =~ /^\[\[([^\[]+?)\|([^\|\[]+?)\]\]/) { | |
678 | + my $label = $1; | |
679 | + my $page = $2; | |
680 | + $source = $'; | |
681 | + push @parsed, $self->wiki_anchor($page, $label); | |
529 | 682 | } |
530 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
531 | - | |
532 | - # URLリンク | |
533 | - } elsif($source =~ /(http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*/ | |
534 | - || $source =~ /\[([^\[]+?)\|(file:[^\[\]]*)\]/){ | |
535 | - my $pre = $`; | |
536 | - my $post = $'; | |
537 | - my $url = $&; | |
538 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
539 | - if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ | |
540 | - push @array,"<span class=\"error\">不正なリンクです。</span>"; | |
541 | - } else { | |
542 | - push @array,$self->url_anchor($url); | |
683 | + | |
684 | + # URL別名リンク | |
685 | + elsif ($source | |
686 | + =~ /^\[([^\[]+?)\|((?:http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*)\]/ | |
687 | + || $source =~ /^\[([^\[]+?)\|(file:[^\[\]]*)\]/ | |
688 | + || $source | |
689 | + =~ /^\[([^\[]+?)\|((?:\/|\.\/|\.\.\/)+[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*)\]/ | |
690 | + ) | |
691 | + { | |
692 | + my $label = $1; | |
693 | + my $url = $2; | |
694 | + $source = $'; | |
695 | + if ( index($url, q{"}) >= 0 | |
696 | + || index($url, '><') >= 0 | |
697 | + || index($url, 'javascript:') >= 0) | |
698 | + { | |
699 | + push @parsed, $self->parse_line('<<不正なリンクです。>>'); | |
700 | + } | |
701 | + else { | |
702 | + push @parsed, $self->url_anchor($url, $label); | |
703 | + } | |
543 | 704 | } |
544 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
545 | - | |
546 | - # ページリンク | |
547 | - } elsif($source =~ /\[\[([^\|]+?)\]\]/){ | |
548 | - my $pre = $`; | |
549 | - my $post = $'; | |
550 | - my $page = $1; | |
551 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
552 | - push @array,$self->wiki_anchor($page); | |
553 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
554 | 705 | |
555 | - # 任意のURLリンク | |
556 | - } elsif($source =~ /\[([^\[]+?)\|(.+?)\]/){ | |
557 | - my $pre = $`; | |
558 | - my $post = $'; | |
559 | - my $label = $1; | |
560 | - my $url = $2; | |
561 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
562 | - if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ | |
563 | - push @array,"<span class=\"error\">不正なリンクです。</span>"; | |
564 | - } else { | |
565 | - push @array,$self->url_anchor($url,$label); | |
706 | + # URLリンク | |
707 | + elsif ($source | |
708 | + =~ /^(?:https?|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*/ | |
709 | + || $source =~ /^file:[^\[\]]*/) | |
710 | + { | |
711 | + my $url = $&; | |
712 | + $source = $'; | |
713 | + if ( index($url, q{"}) >= 0 | |
714 | + || index($url, '><') >= 0 | |
715 | + || index($url, 'javascript:') >= 0) | |
716 | + { | |
717 | + push @parsed, $self->parse_line('<<不正なリンクです。>>'); | |
718 | + } | |
719 | + else { | |
720 | + push @parsed, $self->url_anchor($url); | |
721 | + } | |
566 | 722 | } |
567 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
568 | - | |
569 | - # WikiName | |
570 | - } elsif($main::WIKI_NAME==1 && $source =~ /[A-Z]+?[a-z]+?([A-Z]+?[a-z]+)+/){ | |
571 | - my $pre = $`; | |
572 | - my $post = $'; | |
573 | - my $page = $&; | |
574 | - if($pre ne ""){ push(@array,$self->parse_line($pre)); } | |
575 | - push @array,$self->wiki_anchor($page); | |
576 | - if($post ne ""){ push(@array,$self->parse_line($post)); } | |
577 | - | |
578 | - } else { | |
579 | - push @array,$self->text($source); | |
723 | + | |
724 | + # ページリンク | |
725 | + elsif ($source =~ /^\[\[([^\|]+?)\]\]/) { | |
726 | + my $page = $1; | |
727 | + $source = $'; | |
728 | + push @parsed, $self->wiki_anchor($page); | |
729 | + } | |
730 | + | |
731 | + # 任意のURLリンク | |
732 | + elsif ($source =~ /^\[([^\[]+?)\|(.+?)\]/) { | |
733 | + my $label = $1; | |
734 | + my $url = $2; | |
735 | + $source = $'; | |
736 | + if ( index($url, q{"}) >= 0 | |
737 | + || index($url, '><') >= 0 | |
738 | + || index($url, 'javascript:') >= 0) | |
739 | + { | |
740 | + push @parsed, $self->parse_line('<<不正なリンクです。>>'); | |
741 | + } | |
742 | + else { | |
743 | + # URIを作成 | |
744 | + my $uri = &main::MyBaseUrl().$ENV{"PATH_INFO"}; | |
745 | + push @parsed, $self->url_anchor($uri . '/../' . $url, $label); | |
746 | + } | |
747 | + } | |
748 | + | |
749 | + # ボールド、イタリック、取り消し線、下線 | |
750 | + elsif ($source =~ /^('''?|==|__)(.+?)\1/) { | |
751 | + my $type = $1; | |
752 | + my $label = $2; | |
753 | + $source = $'; | |
754 | + if ($type eq q{'''}) { | |
755 | + push @parsed, $self->bold($label); | |
756 | + } | |
757 | + elsif ($type eq q{__}) { | |
758 | + push @parsed, $self->underline($label); | |
759 | + } | |
760 | + elsif ($type eq q{''}) { | |
761 | + push @parsed, $self->italic($label); | |
762 | + } | |
763 | + else { ## elsif ($type eq q{==}) { | |
764 | + push @parsed, $self->denialline($label); | |
765 | + } | |
766 | + } | |
767 | + | |
768 | + # エラーメッセージ | |
769 | + elsif ($source =~ /^<<(.+?)>>/) { | |
770 | + my $label = $1; | |
771 | + $source = $'; | |
772 | + push @parsed, $self->error($label); | |
773 | + } | |
774 | + | |
775 | + # インライン Wiki 書式全体には macth しなかったとき | |
776 | + else { | |
777 | + # 1 文字進む。 | |
778 | + if ($source =~ /^(.)/) { | |
779 | + $pre .= $1; | |
780 | + $source = $'; | |
781 | + } | |
782 | + | |
783 | + # parse 結果を @array に保存する処理を飛ばして繰り返し。 | |
784 | + next SOURCE; | |
785 | + } | |
786 | + | |
787 | + # インライン Wiki 書式全体に macth した後の | |
788 | + # parse 結果を @array に保存する処理。 | |
789 | + | |
790 | + # もし $pre が溜まっているなら、WikiNameの処理を実施。 | |
791 | + if ($pre ne q{}) { | |
792 | + push @array, $self->_parse_line_wikiname($pre); | |
793 | + $pre = q{}; | |
794 | + } | |
795 | + | |
796 | + push @array, @parsed; | |
580 | 797 | } |
581 | - | |
798 | + | |
799 | + # もし $pre が溜まっているなら、WikiNameの処理を実施。 | |
800 | + if ($pre ne q{}) { | |
801 | + push @array, $self->_parse_line_wikiname($pre); | |
802 | + } | |
803 | + | |
582 | 804 | return @array; |
583 | 805 | } |
584 | 806 | |
807 | +#======================================================================== | |
808 | +# parse_line() から呼び出され、WikiNameの検索・置換処理を行います。 | |
809 | +#======================================================================== | |
810 | +sub _parse_line_wikiname { | |
811 | + my $self = shift; | |
812 | + my $source = shift; | |
813 | + | |
814 | + return () if (not defined $source); | |
815 | + | |
816 | + my @array = (); | |
817 | + | |
818 | + # $source が空になるまで繰り返す。 | |
819 | + while ($source ne q{}) { | |
820 | + | |
821 | + # WikiName | |
822 | + if ($main::WIKI_NAME == 1 && $source =~ /[A-Z]+?[a-z]+?(?:[A-Z]+?[a-z]+)+/) { | |
823 | + my $pre = $`; | |
824 | + my $page = $&; | |
825 | + $source = $'; | |
826 | + if ($pre ne q{}) { | |
827 | + push @array, $self->_parse_line_wikiname($pre); | |
828 | + } | |
829 | + push @array, $self->wiki_anchor($page); | |
830 | + } | |
831 | + | |
832 | + # WikiName も見つからなかったとき | |
833 | + else { | |
834 | + push @array, $self->text($source); | |
835 | + return @array; | |
836 | + } | |
837 | + } | |
838 | + return @array; | |
839 | +} | |
840 | + | |
841 | +#=============================================================================== | |
842 | +# <p> | |
843 | +# パースを開始前に呼び出されます。 | |
844 | +# サブクラスで必要な処理がある場合はオーバーライドしてください。 | |
845 | +# </p> | |
846 | +#=============================================================================== | |
847 | +sub start_parse {} | |
848 | + | |
585 | 849 | #============================================================================== |
586 | 850 | # リスト |
587 | 851 | #============================================================================== |
@@ -595,30 +859,39 @@ | ||
595 | 859 | $self->{para} = 0; |
596 | 860 | } |
597 | 861 | |
862 | + if($self->{list} == 1 && $level <= $self->{level}){ | |
863 | + $self->end_list; | |
864 | + } | |
865 | + $self->{list} = 0; | |
866 | + | |
598 | 867 | $self->end_verbatim; |
599 | 868 | $self->end_table; |
600 | 869 | $self->end_quote; |
601 | - $self->end_explan; | |
602 | 870 | |
603 | 871 | my $html = join("",@$obj); |
604 | - my $plus = 1; | |
605 | - | |
606 | - if($level < $self->{level}){ $plus = -1; } | |
607 | - if($level==$self->{level}){ | |
608 | - $self->{html} .= "</li>\n"; | |
609 | - } | |
610 | - while($level != $self->{level}){ | |
611 | - if($plus==1){ | |
872 | + | |
873 | + if($level > $self->{level}){ | |
874 | + while($level != $self->{level}){ | |
612 | 875 | $self->{html} .= "<ul>\n"; |
613 | 876 | push(@{$self->{close_list}},"</ul>\n"); |
614 | - } else { | |
615 | - $self->{html} .= "</li>\n"; | |
877 | + $self->{level}++; | |
878 | + } | |
879 | + } elsif($level <= $self->{level}){ | |
880 | + while($level-1 != $self->{level}){ | |
881 | + if($self->{'list_close_'.$self->{level}} == 1){ | |
882 | + $self->{html} .= "</li>\n"; | |
883 | + $self->{'list_close_'.$self->{level}} = 0; | |
884 | + } | |
885 | + if($level == $self->{level}){ | |
886 | + last; | |
887 | + } | |
616 | 888 | $self->{html} .= pop(@{$self->{close_list}}); |
889 | + $self->{level}--; | |
617 | 890 | } |
618 | - $self->{level} += $plus; | |
619 | 891 | } |
620 | 892 | |
621 | 893 | $self->{html} .= "<li>".$html; |
894 | + $self->{'list_close_'.$level} = 1; | |
622 | 895 | } |
623 | 896 | |
624 | 897 | #============================================================================== |
@@ -634,29 +907,39 @@ | ||
634 | 907 | $self->{para} = 0; |
635 | 908 | } |
636 | 909 | |
910 | + if($self->{list} == 0 && $level <= $self->{level}){ | |
911 | + $self->end_list; | |
912 | + } | |
913 | + $self->{list} = 1; | |
914 | + | |
637 | 915 | $self->end_verbatim; |
638 | 916 | $self->end_table; |
639 | 917 | $self->end_quote; |
640 | - $self->end_explan; | |
641 | 918 | |
642 | 919 | my $html = join("",@$obj); |
643 | - my $plus = 1; | |
644 | 920 | |
645 | - if($level < $self->{level}){ $plus = -1; } | |
646 | - if($level==$self->{level}){ | |
647 | - $self->{html} .= "</li>\n"; | |
648 | - } | |
649 | - while($level != $self->{level}){ | |
650 | - if($plus==1){ | |
921 | + if($level > $self->{level}){ | |
922 | + while($level != $self->{level}){ | |
651 | 923 | $self->{html} .= "<ol>\n"; |
652 | 924 | push(@{$self->{close_list}},"</ol>\n"); |
653 | - } else { | |
654 | - $self->{html} .= "</li>\n"; | |
925 | + $self->{level}++; | |
926 | + } | |
927 | + } elsif($level <= $self->{level}){ | |
928 | + while($level-1 != $self->{level}){ | |
929 | + if($self->{'list_close_'.$self->{level}} == 1){ | |
930 | + $self->{html} .= "</li>\n"; | |
931 | + $self->{'list_close_'.$self->{level}} = 0; | |
932 | + } | |
933 | + if($level == $self->{level}){ | |
934 | + last; | |
935 | + } | |
655 | 936 | $self->{html} .= pop(@{$self->{close_list}}); |
937 | + $self->{level}--; | |
656 | 938 | } |
657 | - $self->{level} += $plus; | |
658 | 939 | } |
940 | + | |
659 | 941 | $self->{html} .= "<li>".$html; |
942 | + $self->{'list_close_'.$level} = 1; | |
660 | 943 | } |
661 | 944 | |
662 | 945 | #============================================================================== |
@@ -664,12 +947,13 @@ | ||
664 | 947 | #============================================================================== |
665 | 948 | sub end_list { |
666 | 949 | my $self = shift; |
667 | - if ($self->{level}!=0) { | |
668 | - $self->{html} .= "</li>\n"; | |
669 | - while($self->{level}!=0){ | |
670 | - $self->{html} .= pop(@{$self->{close_list}}); | |
671 | - $self->{level} += -1; | |
950 | + while($self->{level} != 0){ | |
951 | + if($self->{'list_close_'.($self->{level})} == 1){ | |
952 | + $self->{html} .= "</li>\n"; | |
953 | + $self->{'list_close_'.$self->{level}} = 0; | |
672 | 954 | } |
955 | + $self->{html} .= pop(@{$self->{close_list}}); | |
956 | + $self->{level}--; | |
673 | 957 | } |
674 | 958 | } |
675 | 959 |
@@ -690,20 +974,20 @@ | ||
690 | 974 | $self->end_verbatim; |
691 | 975 | $self->end_table; |
692 | 976 | $self->end_quote; |
693 | - $self->end_explan; | |
694 | 977 | |
695 | 978 | my $html = join("",@$obj); |
696 | 979 | |
980 | + # メインの表示領域でないとき | |
697 | 981 | if(!$self->{main}){ |
698 | 982 | $self->{html} .= "<h".($level+1).">".$html."</h".($level+1).">\n"; |
983 | + | |
984 | + # メインの表示領域の場合はアンカを出力 | |
699 | 985 | } else { |
700 | 986 | if($level==2){ |
701 | - $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\">". | |
702 | - "<span class=\"sanchor\">_</span></a>".$html."</h".($level+1).">\n"; | |
987 | + $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\"><span class=\"sanchor\"> </span>". | |
988 | + $html."</a></h".($level+1).">\n"; | |
703 | 989 | } else { |
704 | - $self->{html} .= "<h".($level+1).">". | |
705 | - "<a name=\"p".$self->{p_cnt}."\">".$html."</a>". | |
706 | - "</h".($level+1).">\n"; | |
990 | + $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\">".$html."</a></h".($level+1).">\n"; | |
707 | 991 | } |
708 | 992 | } |
709 | 993 | $self->{p_cnt}++; |
@@ -715,11 +999,15 @@ | ||
715 | 999 | sub l_line { |
716 | 1000 | my $self = shift; |
717 | 1001 | |
1002 | + if($self->{para}==1){ | |
1003 | + $self->{html} .= "</p>\n"; | |
1004 | + $self->{para} = 0; | |
1005 | + } | |
1006 | + | |
718 | 1007 | $self->end_list; |
719 | 1008 | $self->end_verbatim; |
720 | 1009 | $self->end_table; |
721 | 1010 | $self->end_quote; |
722 | - $self->end_explan; | |
723 | 1011 | |
724 | 1012 | $self->{html} .= "<hr>\n"; |
725 | 1013 | } |
@@ -734,11 +1022,12 @@ | ||
734 | 1022 | $self->end_verbatim; |
735 | 1023 | $self->end_table; |
736 | 1024 | $self->end_quote; |
737 | - $self->end_explan; | |
738 | 1025 | |
739 | 1026 | if($self->{para}==1){ |
740 | 1027 | $self->{html} .= "</p>\n"; |
741 | 1028 | $self->{para} = 0; |
1029 | + } elsif($main::BR_MODE==1){ | |
1030 | + $self->{html} .= "<br>\n"; | |
742 | 1031 | } |
743 | 1032 | } |
744 | 1033 |
@@ -757,8 +1046,8 @@ | ||
757 | 1046 | $self->end_list; |
758 | 1047 | $self->end_table; |
759 | 1048 | $self->end_quote; |
760 | - $self->end_explan; | |
761 | 1049 | |
1050 | + $text =~ s/^\s//; | |
762 | 1051 | $self->{pre} .= Util::escapeHTML($text)."\n"; |
763 | 1052 | } |
764 | 1053 |
@@ -765,7 +1054,7 @@ | ||
765 | 1054 | sub end_verbatim { |
766 | 1055 | my $self = shift; |
767 | 1056 | if($self->{pre} ne ""){ |
768 | - $self->{html} .= "<pre>".$self->{pre}."</pre>"; | |
1057 | + $self->{html} .= "<pre>".$self->{pre}."</pre>\n"; | |
769 | 1058 | $self->{pre} = ""; |
770 | 1059 | } |
771 | 1060 | } |
@@ -779,26 +1068,31 @@ | ||
779 | 1068 | $self->end_list; |
780 | 1069 | $self->end_verbatim; |
781 | 1070 | $self->end_quote; |
782 | - $self->end_explan; | |
783 | 1071 | |
1072 | + my $tag = "td"; | |
1073 | + | |
784 | 1074 | if($self->{table}==0){ |
785 | 1075 | $self->{table}=1; |
786 | 1076 | $self->{html} .= "<table>\n"; |
787 | - $self->{html} .= "<tr>\n"; | |
788 | - foreach(@$row){ | |
789 | - my $html = join("",@$_); | |
790 | - $self->{html} .= "<th>".$html."</th>\n"; | |
791 | - } | |
792 | - $self->{html} .= "</tr>\n"; | |
1077 | + $tag = "th"; | |
793 | 1078 | } else { |
794 | 1079 | $self->{table}=2; |
795 | - $self->{html} .= "<tr>\n"; | |
796 | - foreach(@$row){ | |
797 | - my $html = join("",@$_); | |
798 | - $self->{html} .= "<td>".$html."</td>\n"; | |
1080 | + } | |
1081 | + | |
1082 | + my @columns = (); | |
1083 | + foreach(@$row){ | |
1084 | + my $html = join("",@$_); | |
1085 | + if($#columns != -1 && $html eq '<<'){ | |
1086 | + @columns[$#columns]->{colspan}++; | |
1087 | + } else { | |
1088 | + push(@columns, {colspan => 1, html => $html}); | |
799 | 1089 | } |
800 | - $self->{html} .= "</tr>\n"; | |
801 | 1090 | } |
1091 | + $self->{html} .= "<tr>\n"; | |
1092 | + foreach(@columns){ | |
1093 | + $self->{html} .= "<$tag colspan=\"".$_->{colspan}."\">".$_->{html}."</$tag>\n"; | |
1094 | + } | |
1095 | + $self->{html} .= "</tr>\n"; | |
802 | 1096 | } |
803 | 1097 | |
804 | 1098 | sub end_table { |
@@ -818,7 +1112,6 @@ | ||
818 | 1112 | $self->end_verbatim; |
819 | 1113 | $self->end_table; |
820 | 1114 | $self->end_quote; |
821 | - $self->end_explan; | |
822 | 1115 | |
823 | 1116 | if($self->{para}==1){ |
824 | 1117 | $self->{html} .= "</p>\n"; |
@@ -836,7 +1129,6 @@ | ||
836 | 1129 | $self->end_verbatim; |
837 | 1130 | $self->end_table; |
838 | 1131 | $self->end_quote; |
839 | - $self->end_explan; | |
840 | 1132 | my $html = join("",@$obj); |
841 | 1133 | |
842 | 1134 | if($self->{para}==0){ |
@@ -844,6 +1136,11 @@ | ||
844 | 1136 | $self->{para} = 1; |
845 | 1137 | } |
846 | 1138 | $self->{html} .= $html; |
1139 | + | |
1140 | + # brモードに設定されている場合は<br>を足す | |
1141 | + if($main::BR_MODE==1){ | |
1142 | + $self->{html} .= "<br>\n"; | |
1143 | + } | |
847 | 1144 | } |
848 | 1145 | |
849 | 1146 | #============================================================================== |
@@ -855,7 +1152,6 @@ | ||
855 | 1152 | $self->end_list; |
856 | 1153 | $self->end_verbatim; |
857 | 1154 | $self->end_table; |
858 | - $self->end_explan; | |
859 | 1155 | my $html = join("",@$obj); |
860 | 1156 | $self->{quote} .= "<p>".$html."</p>\n"; |
861 | 1157 | } |
@@ -876,35 +1172,17 @@ | ||
876 | 1172 | my $obj1 = shift; |
877 | 1173 | my $obj2 = shift; |
878 | 1174 | |
879 | - if($self->{para}==1){ | |
880 | - $self->{html} .= "</p>"; | |
881 | - $self->{para} = 0; | |
882 | - } | |
883 | - | |
884 | 1175 | $self->end_list; |
885 | 1176 | $self->end_verbatim; |
886 | 1177 | $self->end_table; |
887 | 1178 | $self->end_quote; |
888 | 1179 | |
889 | - if($self->{explan}==0){ | |
890 | - $self->{explan}=1; | |
891 | - $self->{html} .= "<dl>\n"; | |
892 | - } | |
893 | - | |
894 | 1180 | my $html1 = join("",@$obj1); |
895 | 1181 | my $html2 = join("",@$obj2); |
896 | 1182 | |
897 | - $self->{html} .= "<dt>".$html1."</dt>\n<dd>".$html2."</dd>\n"; | |
1183 | + $self->{html} .= "<dl>\n<dt>".$html1."</dt>\n<dd>".$html2."</dd>\n</dl>\n"; | |
898 | 1184 | } |
899 | 1185 | |
900 | -sub end_explan { | |
901 | - my $self = shift; | |
902 | - if($self->{explan}!=0){ | |
903 | - $self->{explan} = 0; | |
904 | - $self->{html} .= "</dl>\n"; | |
905 | - } | |
906 | -} | |
907 | - | |
908 | 1186 | #============================================================================== |
909 | 1187 | # ボールド |
910 | 1188 | #============================================================================== |
@@ -953,7 +1231,7 @@ | ||
953 | 1231 | $name = $url; |
954 | 1232 | } |
955 | 1233 | |
956 | - if($url eq $name && $url=~/\.(gif|jpg|jpeg|bmp|png)$/i){ | |
1234 | + if($url eq $name && $url=~/\.(gif|jpg|jpeg|bmp|png)$/i && $main::DISPLAY_IMAGE==1){ | |
957 | 1235 | return "<img src=\"".$url."\">"; |
958 | 1236 | } else { |
959 | 1237 | return "<a href=\"$url\">".Util::escapeHTML($name)."</a>"; |
@@ -968,16 +1246,36 @@ | ||
968 | 1246 | my $page = shift; |
969 | 1247 | my $name = shift; |
970 | 1248 | |
1249 | + my $anchor = undef; | |
1250 | + my $ppage = $page; | |
1251 | + | |
971 | 1252 | if(!defined($name) || $name eq ""){ |
972 | 1253 | $name = $page; |
973 | 1254 | } |
974 | 1255 | |
975 | - if(&Wiki::exists_page($page)){ | |
976 | - return "<a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page)."\" class=\"wikipage\">". | |
1256 | + if(&Wiki::page_exists($page)){ | |
1257 | + #アンカーを含むページが存在する場合はリンクを優先 | |
1258 | + return "<a href=\"".&Wiki::create_page_url($page)."\" class=\"wikipage\">". | |
977 | 1259 | &Util::escapeHTML($name)."</a>"; |
978 | 1260 | } else { |
979 | - return "<span class=\"nopage\">".&Util::escapeHTML($name)."</span>". | |
980 | - "<a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page)."\">?</a>"; | |
1261 | + #最後の"#"以降をアンカーとする | |
1262 | + if($page =~ m/#([^#]+)$/) { | |
1263 | + $page = $`; | |
1264 | + $anchor = $1; | |
1265 | + } | |
1266 | + if(defined($anchor) && $page eq '') { | |
1267 | + #同一ページのアンカーリンク | |
1268 | + return "<a href=\"#$anchor\" class=\"wikipage\">". | |
1269 | + &Util::escapeHTML($name)."</a>"; | |
1270 | + } elsif(&Wiki::page_exists($page)) { | |
1271 | + #指定ページのアンカーリンク | |
1272 | + return "<a href=\"".&Wiki::create_page_url($page).(defined($anchor)?"#".$anchor:"")."\" class=\"wikipage\">". | |
1273 | + &Util::escapeHTML($name)."</a>"; | |
1274 | + } else { | |
1275 | + #新規ページ作成用リンク | |
1276 | + return "<span class=\"nopage\">".&Util::escapeHTML($name)."</span>". | |
1277 | + "<a href=\"".&Wiki::create_page_url($page)."\">?</a>"; | |
1278 | + } | |
981 | 1279 | } |
982 | 1280 | } |
983 | 1281 |
@@ -997,7 +1295,7 @@ | ||
997 | 1295 | my $self = shift; |
998 | 1296 | my $plugin = shift; |
999 | 1297 | |
1000 | - my $func_ref = $main::I_PLUGIN->{$plugin->{command}}; | |
1298 | + my $func_ref = &Wiki::get_plugin_info($plugin->{command})->{FUNCTION}; | |
1001 | 1299 | my $result = &$func_ref(@{$plugin->{args}}); |
1002 | 1300 | if(defined($result) && $result ne ""){ |
1003 | 1301 | return ($result); |
@@ -1022,9 +1320,8 @@ | ||
1022 | 1320 | $self->end_verbatim; |
1023 | 1321 | $self->end_table; |
1024 | 1322 | $self->end_quote; |
1025 | - $self->end_explan; | |
1026 | 1323 | |
1027 | - my $func_ref = $main::P_PLUGIN->{$plugin->{command}}; | |
1324 | + my $func_ref = &Wiki::get_plugin_info($plugin->{command})->{FUNCTION}; | |
1028 | 1325 | my $result = &$func_ref(@{$plugin->{args}}); |
1029 | 1326 | if(defined($result) && $result ne ""){ |
1030 | 1327 | $self->{html} .= $result; |
@@ -1035,13 +1332,14 @@ | ||
1035 | 1332 | # イメージ |
1036 | 1333 | #============================================================================== |
1037 | 1334 | sub l_image { |
1038 | - my $self = shift; | |
1039 | - my $page = shift; | |
1040 | - my $file = shift; | |
1041 | - my $wiki = $self->{wiki}; | |
1335 | + my $self = shift; | |
1336 | + my $page = shift; | |
1337 | + my $file = shift; | |
1338 | + my $width = shift; | |
1339 | + my $height = shift; | |
1042 | 1340 | |
1043 | 1341 | if($self->{para}==1){ |
1044 | - $self->{html} .= "</p>"; | |
1342 | + $self->{html} .= "</p>\n"; | |
1045 | 1343 | $self->{para} = 0; |
1046 | 1344 | } |
1047 | 1345 |
@@ -1049,12 +1347,24 @@ | ||
1049 | 1347 | $self->end_verbatim; |
1050 | 1348 | $self->end_table; |
1051 | 1349 | $self->end_quote; |
1052 | - $self->end_explan; | |
1053 | 1350 | |
1054 | - $self->{html} .= "<img src=\"".$wiki->config('script_name')."?action=ATTACH&". | |
1055 | - "page=".&Util::url_encode($page)."&file=".&Util::url_encode($file)."\">"; | |
1351 | + $self->{html} .= "<div class=\"image\">"; | |
1352 | + $self->{html} .= "<img src=\"".&Wiki::create_url({'p'=>$page,'f'=>$file},$main::DOWNLOAD_SCRIPT)."\""; | |
1353 | + $self->{html} .= " width=\"$width\"" if ($width ne ""); | |
1354 | + $self->{html} .= " height=\"$height\"" if ($height ne ""); | |
1355 | + $self->{html} .= "/>"; | |
1356 | + $self->{html} .= "</div>\n"; | |
1056 | 1357 | } |
1057 | 1358 | |
1359 | +#============================================================================== | |
1360 | +# エラーメッセージ | |
1361 | +#============================================================================== | |
1362 | +sub error { | |
1363 | + my $self = shift; | |
1364 | + my $label = shift; | |
1365 | + | |
1366 | + return "<span class=\"error\">".Util::escapeHTML($label)."</span>"; | |
1367 | +} | |
1058 | 1368 | |
1059 | 1369 | ################################################################################ |
1060 | 1370 | # |
@@ -1067,6 +1377,8 @@ | ||
1067 | 1377 | #=============================================================================== |
1068 | 1378 | sub url_encode { |
1069 | 1379 | my $retstr = shift; |
1380 | + &jcode::convert(\$retstr,"euc"); | |
1381 | + | |
1070 | 1382 | $retstr =~ s/([^ 0-9A-Za-z])/sprintf("%%%.2X", ord($1))/eg; |
1071 | 1383 | $retstr =~ tr/ /+/; |
1072 | 1384 | return $retstr; |
@@ -1077,6 +1389,7 @@ | ||
1077 | 1389 | #=============================================================================== |
1078 | 1390 | sub url_decode{ |
1079 | 1391 | my $retstr = shift; |
1392 | + | |
1080 | 1393 | $retstr =~ tr/+/ /; |
1081 | 1394 | $retstr =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; |
1082 | 1395 | return $retstr; |
@@ -1087,6 +1400,8 @@ | ||
1087 | 1400 | #=============================================================================== |
1088 | 1401 | sub escapeHTML { |
1089 | 1402 | my($retstr) = shift; |
1403 | + &jcode::convert(\$retstr,"euc"); | |
1404 | + | |
1090 | 1405 | my %table = ( |
1091 | 1406 | '&' => '&', |
1092 | 1407 | '"' => '"', |
@@ -1094,6 +1409,9 @@ | ||
1094 | 1409 | '>' => '>', |
1095 | 1410 | ); |
1096 | 1411 | $retstr =~ s/([&\"<>])/$table{$1}/go; |
1412 | + $retstr =~ s/&#([0-9]{1,5});/&#$1;/go; | |
1413 | + $retstr =~ s/&#(0*(0|9|10|13|38|60|62));/&#$1;/g; | |
1414 | +# $retstr =~ s/&([a-zA-Z0-9]{2,8});/&$1;/go; | |
1097 | 1415 | return $retstr; |
1098 | 1416 | } |
1099 | 1417 |
@@ -1132,6 +1450,25 @@ | ||
1132 | 1450 | } |
1133 | 1451 | |
1134 | 1452 | #=============================================================================== |
1453 | +# ページ名が使用可能かどうかチェックします。 | |
1454 | +#=============================================================================== | |
1455 | +sub check_pagename { | |
1456 | + my $pagename = shift; | |
1457 | + | |
1458 | + #ページ名をチェック | |
1459 | + if( !defined($pagename) | |
1460 | + || $pagename eq "" # 空 | |
1461 | + || $pagename =~ /[\|\[\]]/ # |[] | |
1462 | + || $pagename =~ /^:/ # コロンで始まる | |
1463 | + || $pagename =~ /[^:]:[^:]/ # コロン単体での使用 | |
1464 | + || $pagename =~ /^\s+$/ # 空白のみ | |
1465 | + ){ | |
1466 | + return 0; | |
1467 | + } | |
1468 | + return 1; | |
1469 | +} | |
1470 | + | |
1471 | +#=============================================================================== | |
1135 | 1472 | # 数値かどうかチェックします。 |
1136 | 1473 | #=============================================================================== |
1137 | 1474 | sub check_numeric { |
@@ -1143,6 +1480,63 @@ | ||
1143 | 1480 | } |
1144 | 1481 | } |
1145 | 1482 | |
1483 | +#============================================================================== | |
1484 | +# メール送信 | |
1485 | +#============================================================================== | |
1486 | +sub send_mail { | |
1487 | + my $action = shift; | |
1488 | + my $page = shift; | |
1489 | + my $enc_page = &Util::url_encode($page); | |
1490 | + | |
1491 | + if($main::ADMIN_MAIL eq "" || $main::SEND_MAIL eq ""){ | |
1492 | + return; | |
1493 | + } | |
1494 | + | |
1495 | + my $subject = ""; | |
1496 | + if($action eq 'CREATE'){ | |
1497 | + $subject = "[FSWikiLite]$pageが作成されました"; | |
1498 | + | |
1499 | + } elsif($action eq 'MODIFY'){ | |
1500 | + $subject = "[FSWikiLite]$pageが更新されました"; | |
1501 | + | |
1502 | + } elsif($action eq 'DELETE'){ | |
1503 | + $subject = "[FSWikiLite]$pageが削除されました"; | |
1504 | + } | |
1505 | + | |
1506 | + # MIMEエンコード | |
1507 | + $subject = &main::mimeencode($subject); | |
1508 | + | |
1509 | + my $head = "Subject: $subject\n". | |
1510 | + "From: $main::ADMIN_MAIL\n". | |
1511 | + "Content-Transfer-Encoding: 7bit\n". | |
1512 | + "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n". | |
1513 | + "Reply-To: $main::ADMIN_MAIL\n". | |
1514 | + "\n"; | |
1515 | + | |
1516 | + my $body = "IP:".$ENV{'REMOTE_ADDR'}."\n". | |
1517 | + "UA:".$ENV{'HTTP_USER_AGENT'}."\n"; | |
1518 | + | |
1519 | + if($action eq 'MODIFY' || $action eq 'DELETE'){ | |
1520 | + if(-e "$main::BACKUP_DIR/$enc_page.bak"){ | |
1521 | + $body .= "以下は変更前のソースです。\n". | |
1522 | + "-----------------------------------------------------\n"; | |
1523 | + open(BACKUP,"$main::BACKUP_DIR/$enc_page.bak"); | |
1524 | + while(my $line = <BACKUP>){ | |
1525 | + $body .= $line; | |
1526 | + } | |
1527 | + close(BACKUP); | |
1528 | + } | |
1529 | + } | |
1530 | + | |
1531 | + # 文字コードの変換(jcode.plを使用する) | |
1532 | + &jcode::convert(\$body,'jis'); | |
1533 | + | |
1534 | + open(MAIL,"| $main::SEND_MAIL $main::ADMIN_MAIL"); | |
1535 | + print MAIL $head; | |
1536 | + print MAIL $body; | |
1537 | + close(MAIL); | |
1538 | +} | |
1539 | + | |
1146 | 1540 | #=============================================================================== |
1147 | 1541 | # エラーを通知 |
1148 | 1542 | #=============================================================================== |
@@ -1170,7 +1564,7 @@ | ||
1170 | 1564 | if(!defined($ua)){ |
1171 | 1565 | return 0; |
1172 | 1566 | } |
1173 | - if($ua=~/^DoCoMo\// || $ua=~ /^J-PHONE\// || $ua=~ /UP\.Browser/){ | |
1567 | + if($ua=~/^DoCoMo\// || $ua=~ /^J-PHONE\// || $ua=~ /UP\.Browser/ || $ua=~ /\(DDIPOCKET\;/ || $ua=~ /\(WILLCOM\;/ || $ua=~ /^Vodafone\// || $ua=~ /^SoftBank\//){ | |
1174 | 1568 | return 1; |
1175 | 1569 | } else { |
1176 | 1570 | return 0; |
@@ -1178,59 +1572,18 @@ | ||
1178 | 1572 | } |
1179 | 1573 | |
1180 | 1574 | #=============================================================================== |
1181 | -# インラインプラグインをパースしてコマンドと引数に分割 | |
1575 | +# スマートフォンかどうかチェックします。 | |
1182 | 1576 | #=============================================================================== |
1183 | -sub parse_plugin { | |
1184 | - my $text = shift; | |
1185 | - my ($cmd,@args_tmp) = split(/ /,$text); | |
1186 | - my $args_txt = &Util::trim(join(" ",@args_tmp)); | |
1187 | - | |
1188 | - my @ret_args; | |
1189 | - my $tmp = ""; | |
1190 | - my $escape = 0; | |
1191 | - my $quote = 0; | |
1192 | - | |
1193 | - for(my $i=0;$i<length($args_txt);$i++){ | |
1194 | - my $c = substr($args_txt,$i,1); | |
1195 | - | |
1196 | - if($quote!=1 && $c eq ","){ | |
1197 | - if($tmp ne ""){ | |
1198 | - push(@ret_args,$tmp); | |
1199 | - $tmp = ""; | |
1200 | - $quote = 0; | |
1201 | - } | |
1202 | - } elsif($quote==1 && $c eq "\\"){ | |
1203 | - if($escape==0){ | |
1204 | - $escape = 1; | |
1205 | - } else { | |
1206 | - $tmp .= $c; | |
1207 | - $escape = 0; | |
1208 | - } | |
1209 | - } elsif($quote==0 && $c eq '"'){ | |
1210 | - if($tmp eq ""){ | |
1211 | - $quote = 1; | |
1212 | - } else { | |
1213 | - $tmp .= $c; | |
1214 | - } | |
1215 | - } elsif($quote==1 && $c eq '"'){ | |
1216 | - if($escape==1){ | |
1217 | - $tmp .= $c; | |
1218 | - $escape = 0; | |
1219 | - } else { | |
1220 | - $quote = 2; | |
1221 | - } | |
1222 | - } elsif($quote==2){ | |
1223 | - return {error=>"インラインプラグインの構文が不正です。"}; | |
1224 | - } else { | |
1225 | - $tmp .= $c; | |
1226 | - } | |
1577 | +sub smartphone { | |
1578 | + my $ua = $ENV{'HTTP_USER_AGENT'}; | |
1579 | + if(!defined($ua)){ | |
1580 | + return 0; | |
1227 | 1581 | } |
1228 | - | |
1229 | - if($tmp ne ""){ | |
1230 | - push(@ret_args,$tmp); | |
1582 | + if($ua =~ /Android/ || $ua =~ /iPhone/){ | |
1583 | + return 1; | |
1584 | + } else { | |
1585 | + return 0; | |
1231 | 1586 | } |
1232 | - | |
1233 | - return {command=>$cmd,args=>\@ret_args}; | |
1234 | 1587 | } |
1235 | 1588 | |
1236 | 1589 | 1; |
@@ -13,6 +13,8 @@ | ||
13 | 13 | $ADMIN_MAIL = ''; |
14 | 14 | $SEND_MAIL = ''; |
15 | 15 | $WIKI_NAME = 0; |
16 | +$BR_MODE = 0; | |
17 | +$DISPLAY_IMAGE = 1; | |
16 | 18 | $MAIN_SCRIPT = 'wiki.cgi'; |
17 | 19 | $EDIT_SCRIPT = 'edit.cgi'; |
18 | 20 | $CATEGORY_SCRIPT = 'category.cgi'; |
@@ -22,7 +24,7 @@ | ||
22 | 24 | #=============================================================================== |
23 | 25 | # プロダクト情報 |
24 | 26 | #=============================================================================== |
25 | -$VERSION = '0.0.12'; | |
27 | +$VERSION = '0.1.0'; | |
26 | 28 | $SITE_URL = 'http://fswiki.osdn.jp/cgi-bin/wiki.cgi'; |
27 | 29 | |
28 | 30 | #=============================================================================== |
@@ -16,9 +16,14 @@ | ||
16 | 16 | $main::P_PLUGIN->{search} = \&Wiki::Plugin::search; |
17 | 17 | |
18 | 18 | # インラインプラグインのエントリ |
19 | - $main::I_PLUGIN->{category} = \&Wiki::Plugin::category; | |
20 | - $main::I_PLUGIN->{lastmodified} = \&Wiki::Plugin::lastmodified; | |
21 | - $main::I_PLUGIN->{ref} = \&Wiki::Plugin::ref; | |
19 | + $main::I_PLUGIN->{category} = \&Wiki::Plugin::category; | |
20 | + $main::I_PLUGIN->{lastmodified} = \&Wiki::Plugin::lastmodified; | |
21 | + $main::I_PLUGIN->{ref} = \&Wiki::Plugin::ref; | |
22 | + $main::I_PLUGIN->{raw} = \&Wiki::Plugin::raw; | |
23 | + | |
24 | + # ブロックプラグインのエントリ | |
25 | + $main::B_PLUGIN->{pre} = \&Wiki::Plugin::pre; | |
26 | + $main::B_PLUGIN->{bq} = \&Wiki::Plugin::bq; | |
22 | 27 | } |
23 | 28 | |
24 | 29 | #============================================================================== |
@@ -26,21 +31,48 @@ | ||
26 | 31 | #============================================================================== |
27 | 32 | sub recent { |
28 | 33 | my $max = shift; |
29 | - $max = 0 if($max eq ""); | |
34 | + my $way = shift; | |
35 | + | |
36 | + # 表示方式を決定 | |
37 | + if($way eq ""){ | |
38 | + $way = "H"; | |
39 | + } | |
40 | + if($max eq "V" || $max eq "v"){ | |
41 | + $way = "V"; | |
42 | + $max = 0; | |
43 | + } elsif($max eq "H" || $max eq "h"){ | |
44 | + $way = "H"; | |
45 | + $max = 0; | |
46 | + } elsif($max eq ""){ | |
47 | + $max = 0; | |
48 | + } | |
49 | + | |
50 | + # 表示内容を作成 | |
30 | 51 | my $buf = ""; |
52 | + my $content = ""; | |
31 | 53 | |
32 | 54 | my @pages = &Wiki::get_page_list(); |
33 | 55 | my $count = 0; |
34 | 56 | |
35 | - $buf .= "<ul>\n"; | |
36 | 57 | foreach my $page (@pages){ |
37 | - $buf .= "<li><a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page->{NAME})."\">". | |
38 | - &Util::escapeHTML($page->{NAME})."</a></li>\n"; | |
58 | + $content = "<a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">".&Util::escapeHTML($page->{NAME})."</a>"; | |
59 | + if($way eq "H" || $way eq "h"){ | |
60 | + if($count!=0){ | |
61 | + $buf .= " / "; | |
62 | + } | |
63 | + $buf .= $content; | |
64 | + } else { | |
65 | + if($count==0){ | |
66 | + $buf .= "<ul>\n"; | |
67 | + } | |
68 | + $buf .= "<li>".$content."</li>\n"; | |
69 | + } | |
39 | 70 | $count++; |
40 | 71 | last if($count==$max && $max!=0); |
41 | 72 | } |
42 | - $buf .= "</ul>\n"; | |
43 | - | |
73 | + if($count>0 && $way ne "H" && $way ne "h"){ | |
74 | + $buf .= "</ul>\n"; | |
75 | + } | |
44 | 76 | return $buf; |
45 | 77 | } |
46 | 78 |
@@ -79,7 +111,7 @@ | ||
79 | 111 | $buf .= "<ul>\n"; |
80 | 112 | } |
81 | 113 | |
82 | - $buf .= "<li><a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page->{NAME})."\">". | |
114 | + $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">". | |
83 | 115 | &Util::escapeHTML($page->{NAME})."</a></li>\n"; |
84 | 116 | } |
85 | 117 |
@@ -96,9 +128,9 @@ | ||
96 | 128 | sub category { |
97 | 129 | my $category = shift; |
98 | 130 | if($category eq ""){ |
99 | - return "カテゴリが指定されていません。"; | |
131 | + return "<span class=\"error\">カテゴリが指定されていません。</span>"; | |
100 | 132 | } else { |
101 | - return "[<a href=\"$main::CATEGORY_SCRIPT?c=".&Util::url_encode($category)."\">". | |
133 | + return "[<a href=\"".&Wiki::create_url({c=>$category},$main::CATEGORY_SCRIPT)."\">". | |
102 | 134 | "カテゴリ:".&Util::escapeHTML($category)."</a>]"; |
103 | 135 | } |
104 | 136 | } |
@@ -107,8 +139,8 @@ | ||
107 | 139 | # ページの最終更新日時を表示するプラグイン。 |
108 | 140 | #============================================================================= |
109 | 141 | sub lastmodified { |
110 | - my $page = $main::in{"p"}; | |
111 | - if(&Wiki::exists_page($page)){ | |
142 | + my $page = shift || $main::in{"p"}; | |
143 | + if(&Wiki::page_exists($page)){ | |
112 | 144 | return "最終更新時間:".&Util::format_date(&Wiki::get_last_modified($page)); |
113 | 145 | } else { |
114 | 146 | return undef; |
@@ -136,7 +168,7 @@ | ||
136 | 168 | |
137 | 169 | # カテゴリにマッチしたらリスティング |
138 | 170 | if($line =~ /{{category\s+$category}}/){ |
139 | - $buf .= "<li><a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page->{NAME})."\">". | |
171 | + $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">". | |
140 | 172 | &Util::escapeHTML($page->{NAME})."</a></li>"; |
141 | 173 | last; |
142 | 174 | } |
@@ -156,7 +188,7 @@ | ||
156 | 188 | next if($line =~ /^(\t| |\/\/)/); |
157 | 189 | |
158 | 190 | # カテゴリにマッチしたらリスティング |
159 | - while($line =~ /{{category\s+(.+?)}}/g){ | |
191 | + while($line =~ /\{\{category\s+(.+?)\}\}/g){ | |
160 | 192 | $category->{$1}->{$page->{NAME}} = 1; |
161 | 193 | } |
162 | 194 | } |
@@ -166,7 +198,7 @@ | ||
166 | 198 | $buf .= "<h2>".&Util::escapeHTML($name)."</h2>\n"; |
167 | 199 | $buf .= "<ul>\n"; |
168 | 200 | foreach my $page (sort(keys(%{$category->{$name}}))){ |
169 | - $buf .= "<li><a href=\"$main::MAIN_SCRIPT?p=".&Util::url_encode($page)."\">". | |
201 | + $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page})."\">". | |
170 | 202 | &Util::escapeHTML($page)."</a></li>\n"; |
171 | 203 | } |
172 | 204 | $buf .= "</ul>\n"; |
@@ -179,21 +211,27 @@ | ||
179 | 211 | # 添付ファイルへのリンクを表示するためのプラグイン。 |
180 | 212 | #============================================================================= |
181 | 213 | sub ref { |
182 | - my $page = $main::in{"p"}; | |
183 | - my $file = shift; | |
214 | + my $file = shift; | |
215 | + my $page = shift; | |
216 | + my $alias = shift; | |
184 | 217 | |
185 | 218 | if($file eq ""){ |
186 | - return "ファイルが指定されていません。"; | |
219 | + return "<p class=\"error\">ファイルが指定されていません。</p>\n"; | |
187 | 220 | } |
221 | + if(!defined($page) || $page eq ""){ | |
222 | + $page = $main::in{"p"}; | |
223 | + } | |
224 | + if(!defined($alias) || $alias eq ""){ | |
225 | + $alias = $file; | |
226 | + } | |
188 | 227 | |
189 | 228 | my $filename = sprintf("$main::ATTACH_DIR/%s.%s", |
190 | 229 | &Util::url_encode($page),&Util::url_encode($file)); |
191 | 230 | unless(-e $filename){ |
192 | - return "ファイルが存在しません。"; | |
231 | + return "<p class=\"error\">ファイルが存在しません。</p>\n"; | |
193 | 232 | } |
194 | 233 | |
195 | - return sprintf("<a href=\"$main::DOWNLOAD_SCRIPT?p=%s&f=%s\">%s</a>", | |
196 | - &Util::url_encode($page),&Util::url_encode($file),$file); | |
234 | + return "<a href=\"".&Wiki::create_url({p=>$page,f=>$file},$main::DOWNLOAD_SCRIPT)."\">".&Util::escapeHTML($alias)."</a>"; | |
197 | 235 | } |
198 | 236 | |
199 | 237 | #============================================================================= |
@@ -200,21 +238,37 @@ | ||
200 | 238 | # 添付ファイルを画像として表示するためのプラグイン。 |
201 | 239 | #============================================================================= |
202 | 240 | sub ref_image { |
203 | - my $page = $main::in{"p"}; | |
204 | - my $file = shift; | |
241 | + my $file = shift; | |
242 | + my $page = ""; | |
205 | 243 | |
244 | + my @options = @_; | |
245 | + my $width = ""; | |
246 | + my $height = ""; | |
247 | + | |
206 | 248 | if($file eq ""){ |
207 | - return "ファイルが指定されていません。"; | |
249 | + return "<p class=\"error\">ファイルが指定されていません。</p>\n"; | |
208 | 250 | } |
251 | + foreach my $option (@options){ | |
252 | + if($option =~ /^w([0-9]+)$/){ | |
253 | + $width = $1; | |
254 | + } elsif($option =~ /^h([0-9]+)$/){ | |
255 | + $height = $1; | |
256 | + } else { | |
257 | + $page = $option; | |
258 | + } | |
259 | + } | |
260 | + if($page eq ""){ | |
261 | + $page = $main::in{"p"}; | |
262 | + } | |
209 | 263 | |
210 | 264 | my $filename = sprintf("$main::ATTACH_DIR/%s.%s", |
211 | 265 | &Util::url_encode($page),&Util::url_encode($file)); |
212 | 266 | unless(-e $filename){ |
213 | - return "<p>ファイルが存在しません。</p>\n"; | |
267 | + return "<p class=\"error\">ファイルが存在しません。</p>\n"; | |
214 | 268 | } |
215 | 269 | |
216 | - return sprintf("<div><img src=\"$main::DOWNLOAD_SCRIPT?p=%s&f=%s\"></div>", | |
217 | - &Util::url_encode($page),&Util::url_encode($file)); | |
270 | + &Wiki::get_current_parser()->l_image($page, $file, $width, $height); | |
271 | + return undef; | |
218 | 272 | } |
219 | 273 | |
220 | 274 | #============================================================================= |
@@ -221,17 +275,17 @@ | ||
221 | 275 | # 添付ファイルを画像として表示するためのプラグイン。 |
222 | 276 | #============================================================================= |
223 | 277 | sub ref_text { |
224 | - my $page = $main::in{"p"}; | |
225 | 278 | my $file = shift; |
279 | + my $page = shift || $main::in{"p"}; | |
226 | 280 | |
227 | 281 | if($file eq ""){ |
228 | - return "ファイルが指定されていません。"; | |
282 | + return "<p class=\"error\">ファイルが指定されていません。</p>\n"; | |
229 | 283 | } |
230 | 284 | |
231 | 285 | my $filename = sprintf("$main::ATTACH_DIR/%s.%s", |
232 | 286 | &Util::url_encode($page),&Util::url_encode($file)); |
233 | 287 | unless(-e $filename){ |
234 | - return "<p>ファイルが存在しません。</p>\n"; | |
288 | + return "<p class=\"error\">ファイルが存在しません。</p>\n"; | |
235 | 289 | } |
236 | 290 | |
237 | 291 | my $text = ""; |
@@ -256,11 +310,24 @@ | ||
256 | 310 | # 出力されるHTMLはちょっと手抜きです… |
257 | 311 | #============================================================================= |
258 | 312 | sub outline { |
259 | - my $page = $main::in{'p'}; | |
260 | - my $source = &Wiki::get_page($page); | |
313 | + my $page = shift; | |
314 | + my $url = ""; | |
315 | + | |
316 | + if (!defined($page)) { | |
317 | + $page = $main::in{'p'}; | |
318 | + } else { | |
319 | + $url = &Wiki::create_url({p=>$page}); | |
320 | + } | |
321 | + | |
322 | + my $source = ""; | |
261 | 323 | my $level = 0; |
262 | 324 | my $count = 0; |
263 | 325 | my $buf = ""; |
326 | + | |
327 | + if(&Wiki::page_exists($page)){ | |
328 | + $source = &Wiki::get_page($page); | |
329 | + } | |
330 | + | |
264 | 331 | foreach my $line (split(/\n/,$source)){ |
265 | 332 | if($line=~/^(!{1,3})(.+)$/){ |
266 | 333 | my $find_level = 4 - length($1); |
@@ -276,7 +343,7 @@ | ||
276 | 343 | } |
277 | 344 | my $section = &Util::delete_tag(&Wiki::process_wiki($2)); |
278 | 345 | |
279 | - $buf .= "<li><a href=\"#p$count\">$section</a></li>\n"; | |
346 | + $buf .= "<li><a href=\"".$url."#p$count\">$section</a></li>\n"; | |
280 | 347 | $count++; |
281 | 348 | } |
282 | 349 | } |
@@ -291,11 +358,62 @@ | ||
291 | 358 | # 検索フォームを表示するためのプラグイン |
292 | 359 | #============================================================================= |
293 | 360 | sub search { |
294 | - return "<form action=\"$main::MAIN_SCRIPT\" method=\"GET\">\n". | |
361 | + my $way = shift; | |
362 | + my $or_checked = $main::in{'t'} eq 'or'; | |
363 | + my $with_content = $main::in{'c'} eq 'true'; | |
364 | + return "<form action=\"".&Wiki::create_url({},$main::MAIN_SCRIPT)."\" method=\"GET\">\n". | |
295 | 365 | " キーワード <input type=\"text\" name=\"w\" size=\"20\" value=\"".&Util::escapeHTML($main::in{'w'})."\">\n". |
366 | + ($way eq "v" ? "<br>" : ""). | |
367 | + " <input type=\"radio\" name=\"t\" id=\"and\" value=\"and\"".(!$or_checked?" checked":"")."><label for=\"and\">AND</label>". | |
368 | + " <input type=\"radio\" name=\"t\" id=\"or\" value=\"or\"".($or_checked?" checked":"")."><label for=\"or\">OR</label>". | |
369 | + ($way eq "v" ? "<br>" : ""). | |
370 | + " <input type=\"checkbox\" name=\"c\" id=\"contents\" value=\"true\"".($with_content?" checked":"")."><label for=\"contents\">ページ内容も含める</label>". | |
296 | 371 | " <input type=\"submit\" value=\" 検 索 \">\n". |
297 | 372 | " <input type=\"hidden\" name=\"a\" value=\"search\">\n". |
298 | 373 | "</form>\n"; |
299 | 374 | } |
300 | 375 | |
376 | +#============================================================================= | |
377 | +# 引数で指定した文字列をそのまま表示するインラインプラグイン | |
378 | +#============================================================================= | |
379 | +sub raw { | |
380 | + my $text = shift; | |
381 | + return &Util::escapeHTML($text); | |
382 | +} | |
383 | + | |
384 | +#============================================================================= | |
385 | +# preタグを出力する複数行プラグイン | |
386 | +#============================================================================= | |
387 | +sub pre { | |
388 | + my $text = shift; | |
389 | + my $option = shift; | |
390 | + | |
391 | + my $count = 1; | |
392 | + my $buf = "<pre>"; | |
393 | + my @lines = split(/\n/, $text); | |
394 | + my $len = length($#lines + 1); | |
395 | + foreach my $line (@lines){ | |
396 | + if($option eq "num"){ | |
397 | + $buf .= sprintf("%0${len}d", $count) . "|"; | |
398 | + } | |
399 | + $buf .= Util::escapeHTML($line) . "\n"; | |
400 | + $count++; | |
401 | + } | |
402 | + | |
403 | + return $buf . "</pre>"; | |
404 | +} | |
405 | + | |
406 | +#============================================================================= | |
407 | +# blockquoteタグを出力する複数行プラグイン | |
408 | +#============================================================================= | |
409 | +sub bq { | |
410 | + my $text = shift; | |
411 | + my $buf = "<blockquote>"; | |
412 | + foreach my $line (split(/(\r\n)|\n|\r/,&Util::escapeHTML($text))){ | |
413 | + $buf .= "<p>$line<p>"; | |
414 | + } | |
415 | + $buf .= "</blockquote>"; | |
416 | + return $buf; | |
417 | +} | |
418 | + | |
301 | 419 | 1; |