1################################################################################ 2# <p> 3# Wiki�ե����ޥåȤ�ʸ�����ѡ����������б������եå���åɤθƤӽФ���Ԥ��ޤ��� 4# Wiki::Parser��Ѿ����������Υեå���åɤ��С��饤�ɤ��뤳�Ȥ�Ǥ�դΥե����ޥåȤؤ��Ѵ�����ǽ�Ǥ��� 5# </p> 6################################################################################ 7package Wiki::Parser; 8use strict; 9use Wiki::Keyword; 10use Wiki::InterWiki; 11 12$Wiki::Parser::keyword = undef; 13$Wiki::Parser::interwiki = undef; 14 15#=============================================================================== 16# <p> 17# ���ȥ饯���� 18# </p> 19# <pre> 20# my $parser = Wiki::HTMLParser->new($wiki); 21# </pre> 22#=============================================================================== 23sub new { 24 my $class = shift; 25 my $wiki = shift; 26 27 my $self = {}; 28 $self->{wiki} = $wiki; 29 30 # Keyword��InterWiki�Ϲ�®���Τ���⥸�塼���ѿ��Ȥ����ݻ����� 31 #�ʤ�����mod_perl+Farm�ξ��ϥ���ʤΤ����new����� 32 if(exists $ENV{MOD_PERL}){ 33 $self->{interwiki} = Wiki::InterWiki->new($wiki); 34 $self->{keyword} = Wiki::Keyword->new($wiki,$self->{interwiki}); 35 } else { 36 unless(defined($Wiki::Parser::keyword)){ 37 $Wiki::Parser::interwiki = Wiki::InterWiki->new($wiki); 38 $Wiki::Parser::keyword = Wiki::Keyword->new($wiki,$Wiki::Parser::interwiki); 39 } 40 $self->{interwiki} = $Wiki::Parser::interwiki; 41 $self->{keyword} = $Wiki::Parser::keyword; 42 } 43 44 $self->{dl_flag} = 0; 45 $self->{dt} = ""; 46 $self->{dd} = ""; 47 48 return bless $self,$class; 49} 50 51#=============================================================================== 52# <p> 53# �ѡ��������Ϥ��ޤ��� 54# </p> 55# <pre> 56# $parser->parse($source); 57# </pre> 58#=============================================================================== 59sub parse { 60 my $self = shift; 61 my $source = shift; 62 63 $self->start_parse; 64 $source =~ s/\r//g; 65 66 my @lines = split(/\n/,$source); 67 68 foreach my $line (@lines){ 69 chomp $line; 70 71 # ʣ���Ԥ����� 72 $self->multi_explanation($line); 73 74 my $word1 = substr($line,0,1); 75 my $word2 = substr($line,0,2); 76 my $word3 = substr($line,0,3); 77 78 # ���� 79 if($line eq ""){ 80 $self->l_paragraph(); 81 next; 82 } 83 84 # �ѥ饰��եץ饰���� 85 if($line =~ /^{{((.|\s)+?)}}$/){ 86 my $plugin = $self->{wiki}->parse_inline_plugin($1); 87 my $info = $self->{wiki}->get_plugin_info($plugin->{command}); 88 if($info->{TYPE} eq "paragraph"){ 89 $self->l_plugin($plugin); 90 } else { 91 my @obj = $self->parse_line($line); 92 $self->l_text(\@obj); 93 } 94 next; 95 } 96 97 # PRE 98 if($word1 eq " " || $word1 eq "\t"){ 99 $self->l_verbatim($line); 100 101 # ���Ф� 102 } elsif($word3 eq "!!!"){ 103 my @obj = $self->parse_line(substr($line,3)); 104 $self->l_headline(1,\@obj); 105 106 } elsif($word2 eq "!!"){ 107 my @obj = $self->parse_line(substr($line,2)); 108 $self->l_headline(2,\@obj); 109 110 } elsif($word1 eq "!"){ 111 my @obj = $self->parse_line(substr($line,1)); 112 $self->l_headline(3,\@obj); 113 114 # ���� 115 } elsif($word3 eq "***"){ 116 my @obj = $self->parse_line(substr($line,3)); 117 $self->l_list(3,\@obj); 118 119 } elsif($word2 eq "**"){ 120 my @obj = $self->parse_line(substr($line,2)); 121 $self->l_list(2,\@obj); 122 123 } elsif($word1 eq "*"){ 124 my @obj = $self->parse_line(substr($line,1)); 125 $self->l_list(1,\@obj); 126 127 # �ֹ��դ����� 128 } elsif($word3 eq "+++"){ 129 my @obj = $self->parse_line(substr($line,3)); 130 $self->l_numlist(3,\@obj); 131 132 } elsif($word2 eq "++"){ 133 my @obj = $self->parse_line(substr($line,2)); 134 $self->l_numlist(2,\@obj); 135 136 } elsif($word1 eq "+"){ 137 my @obj = $self->parse_line(substr($line,1)); 138 $self->l_numlist(1,\@obj); 139 140 # ��ʿ�� 141 } elsif($line eq "----"){ 142 $self->l_line(); 143 144 # ���� 145 } elsif($word2 eq '""'){ 146 my @obj = $self->parse_line(substr($line,2)); 147 $self->l_quotation(\@obj); 148 149 # ���� 150 } elsif(index($line,":")==0 && index($line,":",1)!=-1){ 151 if(index($line,":::")==0){ 152 $self->{dd} .= substr($line,3); 153 next; 154 } 155 if(index($line,"::")==0){ 156 if($self->{dt} ne "" || $self->{dd} ne ""){ 157 $self->multi_explanation; 158 } 159 $self->{dt} = substr($line,2); 160 $self->{dl_flag} = 1; 161 next; 162 } 163 my $dt = substr($line,1,index($line,":",1)-1); 164 my $dd = substr($line,index($line,":",1)+1); 165 my @obj1 = $self->parse_line($dt); 166 my @obj2 = $self->parse_line($dd); 167 $self->l_explanation(\@obj1,\@obj2); 168 169 # �ơ��֥� 170 } elsif($word1 eq ","){ 171 if($line =~ /,$/){ 172 $line .= " "; 173 } 174 my @spl = map {/^"(.*)"$/ ? scalar($_ = $1, s/\"\"/\"/g, $_) : $_} 175 ($line =~ /,\s*(\"[^\"]*(?:\"\"[^\"]*)*\"|[^,]*)/g); 176 my @array; 177 foreach my $value (@spl){ 178 my @cell = $self->parse_line($value); 179 push @array,\@cell; 180 } 181 $self->l_table(\@array); 182 183 # ������ 184 } elsif($word2 eq "//"){ 185 186 # ����ʤ��� 187 } else { 188 my @obj = $self->parse_line($line); 189 $self->l_text(\@obj); 190 } 191 } 192 193 # ʣ���Ԥ����� 194 $self->multi_explanation; 195 196 $self->end_parse; 197} 198 199#=============================================================================== 200# <p> 201# ʣ���Ԥ�����ʸ��������ޤ��� 202# </p> 203#=============================================================================== 204sub multi_explanation { 205 my $self = shift; 206 my $line = shift; 207 if($self->{dl_flag}==1 && (index($line,":")!=0 || !defined($line))){ 208 my @obj1 = $self->parse_line($self->{dt}); 209 my @obj2 = $self->parse_line($self->{dd}); 210 $self->l_explanation(\@obj1,\@obj2); 211 $self->{dl_flag} = 0; 212 $self->{dt} = ""; 213 $self->{dd} = ""; 214 } 215} 216 217#=============================================================================== 218# <p> 219# ����ʬ��ѡ������ޤ���parse��åɤ��椫��ɬ�פ˱����ƸƤӽФ���ޤ��� 220# </p> 221#=============================================================================== 222sub parse_line { 223 my $self = shift; 224 my $source = shift; 225 my @array = (); 226 227 # �ץ饰���� 228 if($source =~ /{{((.|\s)+?)}}/){ 229 my $pre = $`; 230 my $post = $'; 231 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 232 my $plugin = $self->{wiki}->parse_inline_plugin($1); 233 my $info = $self->{wiki}->get_plugin_info($plugin->{command}); 234 if($info->{TYPE} eq "inline"){ 235 push @array,$self->plugin($plugin); 236 } else { 237 push @array,$self->text("{{$1}}"); 238 } 239 if($post ne ""){ push(@array,$self->parse_line($post)); } 240 241 # �ܡ���ɡ�������å������ä��������� 242 } elsif($source =~ /((''')|('')|(==)|(__))(.+?)(\1)/){ 243 my $pre = $`; 244 my $post = $'; 245 my $type = $1; 246 my $label = $6; 247 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 248 if($type eq "'''"){ 249 push @array,$self->bold($label); 250 } elsif($type eq "__"){ 251 push @array,$self->underline($label); 252 } elsif($type eq "''"){ 253 push @array,$self->italic($label); 254 } elsif($type eq "=="){ 255 push @array,$self->denialline($label); 256 } 257 if($post ne ""){ push(@array,$self->parse_line($post)); } 258 259 # InterWikiName 260 } elsif($self->{interwiki}->exists_interwiki($source)){ 261 my $pre = $self->{interwiki}->{g_pre}; 262 my $post = $self->{interwiki}->{g_post}; 263 my $label = $self->{interwiki}->{g_label}; 264 my $url = $self->{interwiki}->{g_url}; 265 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 266 push @array,$self->url_anchor($url,$label); 267 if($post ne ""){ push(@array,$self->parse_line($post)); } 268 269 # �ڡ�����̾��� 270 } elsif($source =~ /\[\[([^\[]+?)\|(.+?)\]\]/){ 271 my $pre = $`; 272 my $post = $'; 273 my $label = $1; 274 my $page = $2; 275 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 276 push @array,$self->wiki_anchor($page,$label); 277 if($post ne ""){ push(@array,$self->parse_line($post)); } 278 279 # URL��̾��� 280 } elsif($source =~ /\[([^\[]+?)\|((http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/ 281 || $source =~ /\[([^\[]+?)\|(file:[^\[\]]*)\]/ 282 || $source =~ /\[([^\[]+?)\|((\/|\.\/|\.\.\/)+[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/){ 283 my $pre = $`; 284 my $post = $'; 285 my $label = $1; 286 my $url = $2; 287 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 288 if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ 289 push @array,"<span class=\"error\">�����ʥ�Ǥ���</span>"; 290 } else { 291 push @array,$self->url_anchor($url,$label); 292 } 293 if($post ne ""){ push(@array,$self->parse_line($post)); } 294 295 # URL��� 296 } elsif($source =~ /(http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*/ 297 || $source =~ /\[([^\[]+?)\|(file:[^\[\]]*)\]/){ 298 my $pre = $`; 299 my $post = $'; 300 my $url = $&; 301 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 302 if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ 303 push @array,"<span class=\"error\">�����ʥ�Ǥ���</span>"; 304 } else { 305 push @array,$self->url_anchor($url); 306 } 307 if($post ne ""){ push(@array,$self->parse_line($post)); } 308 309 # �ڡ������ 310 } elsif($source =~ /\[\[([^\|]+?)\]\]/){ 311 my $pre = $`; 312 my $post = $'; 313 my $page = $1; 314 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 315 push @array,$self->wiki_anchor($page); 316 if($post ne ""){ push(@array,$self->parse_line($post)); } 317 318 # Ǥ�դ�URL��� 319 } elsif($source =~ /\[([^\[]+?)\|(.+?)\]/){ 320 my $pre = $`; 321 my $post = $'; 322 my $label = $1; 323 my $url = $2; 324 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 325 if(index($url,'"') >= 0 || index($url,'><') >= 0 || index($url, 'javascript:') >= 0){ 326 push @array,"<span class=\"error\">�����ʥ�Ǥ���</span>"; 327 } else { 328 # URI����� 329 my $wiki = $self->{wiki}; 330 my $uri = $wiki->config('server_host'); 331 if($uri eq ""){ 332 $uri = $wiki->get_CGI()->url(-path_info => 1); 333 } else { 334 $uri = $uri . $wiki->get_CGI->url(-absolute => 1) . $wiki->get_CGI()->path_info(); 335 } 336 push @array,$self->url_anchor($uri."/../".$url, $label); 337 } 338 if($post ne ""){ push(@array,$self->parse_line($post)); } 339 340 # ������� 341 } elsif($self->{keyword}->exists_keyword($source)){ 342 my $pre = $self->{keyword}->{g_pre}; 343 my $post = $self->{keyword}->{g_post}; 344 my $label = $self->{keyword}->{g_label}; 345 my $url = $self->{keyword}->{g_url}; 346 my $page = $self->{keyword}->{g_page}; 347 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 348 if(defined($url) && $url ne ""){ 349 push @array,$self->url_anchor($url,$label); 350 } else { 351 push @array,$self->wiki_anchor($page,$label); 352 } 353 if($post ne ""){ push(@array,$self->parse_line($post)); } 354 355 # WikiName 356 } elsif($self->{wiki}->config('wikiname')==1 && $source =~ /[A-Z]+?[a-z]+?([A-Z]+?[a-z]+)+/){ 357 my $pre = $`; 358 my $post = $'; 359 my $page = $&; 360 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 361 push @array,$self->wiki_anchor($page); 362 if($post ne ""){ push(@array,$self->parse_line($post)); } 363 364 # ���顼��å����� 365 } elsif($source =~ /(<<)(.+?)(>>)/){ 366 my $pre = $`; 367 my $post = $'; 368 my $label = $2; 369 if($pre ne ""){ push(@array,$self->parse_line($pre)); } 370 push @array,$self->error($label); 371 if($post ne ""){ push(@array,$self->parse_line($post)); } 372 373 } else { 374 push @array,$self->text($source); 375 } 376 377 return @array; 378} 379 380#=============================================================================== 381# <p> 382# �ѡ��������˸ƤӽФ���ޤ��� 383# ���֥��饹��ɬ�פʽ�����������ϥ����С��饤�ɤ��Ƥ��������� 384# </p> 385#=============================================================================== 386sub start_parse {} 387 388#=============================================================================== 389# <p> 390# �ѡ�����λ��˸ƤӽФ���ޤ��� 391# ���֥��饹��ɬ�פʽ�����������ϥ����С��饤�ɤ��Ƥ��������� 392# </p> 393#=============================================================================== 394sub end_parse {} 395 396#=============================================================================== 397# <p> 398# URL���˥ޥå��������˸ƤӽФ���ޤ��� 399# ���֥��饹�ˤƽ�����������ޤ��� 400# </p> 401#=============================================================================== 402sub url_anchor {} 403 404#=============================================================================== 405# <p> 406# �ڡ���̾���˥ޥå��������˸ƤӽФ���ޤ��� 407# ���֥��饹�ˤƽ�����������ޤ��� 408# </p> 409#=============================================================================== 410sub wiki_anchor {} 411 412#=============================================================================== 413# <p> 414# ������å��˥ޥå��������˸ƤӽФ���ޤ��� 415# ���֥��饹�ˤƽ�����������ޤ��� 416# </p> 417#=============================================================================== 418sub italic {} 419 420#=============================================================================== 421# <p> 422# �ܡ���ɤ˥ޥå��������˸ƤӽФ���ޤ��� 423# ���֥��饹�ˤƽ�����������ޤ��� 424# </p> 425#=============================================================================== 426sub bold {} 427 428#=============================================================================== 429# <p> 430# �����˥ޥå��������˸ƤӽФ���ޤ��� 431# ���֥��饹�ˤƽ�����������ޤ��� 432# </p> 433#=============================================================================== 434sub underline {} 435 436#=============================================================================== 437# <p> 438# �Ǥ��ä����˥ޥå��������˸ƤӽФ���ޤ��� 439# ���֥��饹�ˤƽ�����������ޤ��� 440# </p> 441#=============================================================================== 442sub denialline {} 443 444#=============================================================================== 445# <p> 446# �ץ饰����˥ޥå��������˸ƤӽФ���ޤ��� 447# ���֥��饹�ˤƽ�����������ޤ��� 448# </p> 449#=============================================================================== 450sub plugin {} 451 452#=============================================================================== 453# <p> 454# �ƥ����Ȥ˥ޥå��������˸ƤӽФ���ޤ��� 455# ���֥��饹�ˤƽ�����������ޤ��� 456# </p> 457#=============================================================================== 458sub text{} 459 460#=============================================================================== 461# <p> 462# ���ܤ˥ޥå��������˸ƤӽФ���ޤ��� 463# ���֥��饹�ˤƽ�����������ޤ��� 464# </p> 465#=============================================================================== 466sub l_list {} 467 468#=============================================================================== 469# <p> 470# �ֹ��դ����ܤ˥ޥå��������˸ƤӽФ���ޤ��� 471# ���֥��饹�ˤƽ�����������ޤ��� 472# </p> 473#=============================================================================== 474sub l_numlist {} 475 476#=============================================================================== 477# <p> 478# ���Ф��˥ޥå��������˸ƤӽФ���ޤ��� 479# ���֥��饹�ˤƽ�����������ޤ��� 480# </p> 481#=============================================================================== 482sub l_headline {} 483 484#=============================================================================== 485# <p> 486# PRE�����˥ޥå��������˸ƤӽФ���ޤ��� 487# ���֥��饹�ˤƽ�����������ޤ��� 488# </p> 489#=============================================================================== 490sub l_verbatim {} 491 492#=============================================================================== 493# <p> 494# ��ʿ���˥ޥå��������˸ƤӽФ���ޤ��� 495# ���֥��饹�ˤƽ�����������ޤ��� 496# </p> 497#=============================================================================== 498sub l_line {} 499 500#=============================================================================== 501# <p> 502# �äˤʤˤ�ʤ��Ԥ˥ޥå��������˸ƤӽФ���ޤ��� 503# ���֥��饹�ˤƽ�����������ޤ��� 504# </p> 505#=============================================================================== 506sub l_text {} 507 508#=============================================================================== 509# <p> 510# �����˥ޥå��������˸ƤӽФ���ޤ��� 511# ���֥��饹�ˤƽ�����������ޤ��� 512# </p> 513#=============================================================================== 514sub l_explanation {} 515 516#=============================================================================== 517# <p> 518# ���Ѥ˥ޥå��������˸ƤӽФ���ޤ��� 519# ���֥��饹�ˤƽ�����������ޤ��� 520# </p> 521#=============================================================================== 522sub l_quotation {} 523 524#=============================================================================== 525# <p> 526# �ѥ饰��դζ��ڤ�˥ޥå��������˸ƤӽФ���ޤ��� 527# ���֥��饹�ˤƽ�����������ޤ��� 528# </p> 529#=============================================================================== 530sub l_paragraph {} 531 532#=============================================================================== 533# <p> 534# �ơ��֥�˥ޥå��������˸ƤӽФ���ޤ��� 535# ���֥��饹�ˤƽ�����������ޤ��� 536# </p> 537#=============================================================================== 538sub l_table {} 539 540#=============================================================================== 541# <p> 542# �ѥ饰��եץ饰����˥ޥå��������˸ƤӽФ���ޤ��� 543# ���֥��饹�ˤƽ�����������ޤ��� 544# </p> 545#=============================================================================== 546sub l_plugin {} 547 548#=============================================================================== 549# <p> 550# �����˥ޥå��������˸ƤӽФ���ޤ��� 551# ���֥��饹�ˤƽ�����������ޤ��� 552# </p> 553#=============================================================================== 554sub l_image {} 555 556#=============================================================================== 557# <p> 558# ���顼��å������˥ޥå��������˸ƤӽФ���ޤ��� 559# ���֥��饹�ˤƽ�����������ޤ��� 560# </p> 561#=============================================================================== 562sub error {} 563 5641; 565