############################################################################### # # HTMLパーサ # ############################################################################### package Wiki::HTMLParser; use Wiki::Parser; use vars qw(@ISA); use strict; @ISA = qw(Wiki::Parser); #============================================================================== # コンストラクタ #============================================================================== sub new { my $class = shift; my $wiki = shift; my $mainflg = shift; if(!defined($mainflg) || $mainflg eq ""){ $mainflg = 0; } my $self = Wiki::Parser->new($wiki); $self->{html} = ""; $self->{pre} = ""; $self->{quote} = ""; $self->{table} = 0; $self->{level} = 0; $self->{para} = 0; $self->{p_cnt} = 0; $self->{main} = $mainflg; return bless $self,$class; } #============================================================================== # リスト #============================================================================== sub l_list { my $self = shift; my $level = shift; my $obj = shift; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_verbatim; $self->end_table; $self->end_quote; my $html = join("",@$obj); my $plus = 1; if($level < $self->{level}){ $plus = -1; } if($level==$self->{level}){ $self->{html} .= "</li>\n"; } while($level != $self->{level}){ if($plus==1){ $self->{html} .= "<ul>\n"; push(@{$self->{close_list}},"</ul>\n"); } else { $self->{html} .= "</li>\n"; $self->{html} .= pop(@{$self->{close_list}}); } $self->{level} += $plus; } $self->{html} .= "<li>".$html; } #============================================================================== # 番号付きリスト #============================================================================== sub l_numlist { my $self = shift; my $level = shift; my $obj = shift; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_verbatim; $self->end_table; $self->end_quote; my $html = join("",@$obj); my $plus = 1; if($level < $self->{level}){ $plus = -1; } if($level==$self->{level}){ $self->{html} .= "</li>\n"; } while($level != $self->{level}){ if($plus==1){ $self->{html} .= "<ol>\n"; push(@{$self->{close_list}},"</ol>\n"); } else { $self->{html} .= "</li>\n"; $self->{html} .= pop(@{$self->{close_list}}); } $self->{level} += $plus; } $self->{html} .= "<li>".$html; } #============================================================================== # リストの終了 #============================================================================== sub end_list { my $self = shift; if ($self->{level}!=0) { $self->{html} .= "</li>\n"; while($self->{level}!=0){ $self->{html} .= pop(@{$self->{close_list}}); $self->{level} += -1; } } } #============================================================================== # ヘッドライン #============================================================================== sub l_headline { my $self = shift; my $level = shift; my $obj = shift; my $wiki = $self->{wiki}; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; my $html = join("",@$obj); # メインの表示領域でないとき if(!$self->{main}){ $self->{html} .= "<h".($level+1).">".$html."</h".($level+1).">\n"; # メインの表示領域の場合はアンカを出力 } else { if($level==2){ $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\"><span class=\"sanchor\"> </span>". $html."</a></h".($level+1).">\n"; } else { $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\">".$html."</a></h".($level+1).">\n"; } # パート編集がONかつ編集可能な場合は編集アンカを出力 if($self->{no_partedit}!=1){ my $page = $wiki->get_CGI()->param("page"); my $part_edit = ""; # パートリンクがONの場合は移動用のアンカを出力 if ($wiki->config("partlink") == 1) { $part_edit .= "<a class=\"partedit\" href=\"#\">TOP</a> "; $part_edit .= "<a class=\"partedit\" href=\"#p".($self->{p_cnt} - 1)."\">↑</a> "; $part_edit .= "<a class=\"partedit\" href=\"#p".($self->{p_cnt} + 1)."\">↓</a> "; } # パート編集がONかつ編集可能な場合は編集アンカを出力 if($wiki->config("partedit")==1 && $wiki->can_modify_page($page)){ unless(defined($self->{partedit}->{$page})){ $self->{partedit}->{$page} = 0; } else { $self->{partedit}->{$page}++; } # InterWiki形式の場合 my $full = $page; my $path = $self->{wiki}->config('script_name'); if(index($page,":")!=-1){ ($path,$page) = split(/:/,$page); $path = $self->{wiki}->config('script_name')."/$path"; } $part_edit .= "<a class=\"partedit\" href=\"$path?action=EDIT". "&page=".&Util::url_encode($page). "&artno=".$self->{partedit}->{$full}."\" rel=\"nofollow\">編集</a>"; } if($part_edit ne ""){ $self->{html} .= "<div class=\"partedit\">$part_edit</div>\n"; } } } $self->{p_cnt}++; } #============================================================================== # 水平線 #============================================================================== sub l_line { my $self = shift; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; $self->{html} .= "<hr>\n"; } #============================================================================== # 段落区切り #============================================================================== sub l_paragraph { my $self = shift; $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } elsif($self->{wiki}->config('br_mode')==1){ $self->{html} .= "<br>\n"; } } #============================================================================== # 整形済テキスト #============================================================================== sub l_verbatim { my $self = shift; my $text = shift; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_list; $self->end_table; $self->end_quote; $text =~ s/^\s//; $self->{pre} .= Util::escapeHTML($text)."\n"; } sub end_verbatim { my $self = shift; if($self->{pre} ne ""){ $self->{html} .= "<pre>".$self->{pre}."</pre>\n"; $self->{pre} = ""; } } #============================================================================== # テーブル #============================================================================== sub l_table { my $self = shift; my $row = shift; $self->end_list; $self->end_verbatim; $self->end_quote; if($self->{table}==0){ $self->{table}=1; $self->{html} .= "<table>\n"; $self->{html} .= "<tr>\n"; foreach(@$row){ my $html = join("",@$_); $self->{html} .= "<th>".$html."</th>\n"; } $self->{html} .= "</tr>\n"; } else { $self->{table}=2; $self->{html} .= "<tr>\n"; foreach(@$row){ my $html = join("",@$_); $self->{html} .= "<td>".$html."</td>\n"; } $self->{html} .= "</tr>\n"; } } sub end_table { my $self = shift; if($self->{table}!=0){ $self->{table} = 0; $self->{html} .= "</table>\n"; } } #============================================================================== # パース終了時の処理 #============================================================================== sub end_parse { my $self = shift; $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } } #============================================================================== # 行書式に該当しない行 #============================================================================== sub l_text { my $self = shift; my $obj = shift; $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; my $html = join("",@$obj); if($self->{para}==0){ $self->{html} .= "<p>"; $self->{para} = 1; } $self->{html} .= $html; # brモードに設定されている場合は<br>を足す if($self->{wiki}->config('br_mode')==1){ $self->{html} .= "<br>\n"; } } #============================================================================== # 引用 #============================================================================== sub l_quotation { my $self = shift; my $obj = shift; $self->end_list; $self->end_verbatim; $self->end_table; my $html = join("",@$obj); $self->{quote} .= "<p>".$html."</p>\n"; } sub end_quote { my $self = shift; if($self->{quote} ne ""){ $self->{html} .= "<blockquote>".$self->{quote}."</blockquote>\n"; $self->{quote} = ""; } } #============================================================================== # 説明 #============================================================================== sub l_explanation { my $self = shift; my $obj1 = shift; my $obj2 = shift; $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; my $html1 = join("",@$obj1); my $html2 = join("",@$obj2); $self->{html} .= "<dl>\n<dt>".$html1."</dt>\n<dd>".$html2."</dd>\n</dl>\n"; } #============================================================================== # ボールド #============================================================================== sub bold { my $self = shift; my $text = shift; return "<strong>".join("",$self->parse_line($text))."</strong>"; } #============================================================================== # イタリック #============================================================================== sub italic { my $self = shift; my $text = shift; return "<em>".join("",$self->parse_line($text))."</em>"; } #============================================================================== # 下線 #============================================================================== sub underline { my $self = shift; my $text = shift; return "<ins>".join("",$self->parse_line($text))."</ins>"; } #============================================================================== # 打ち消し線 #============================================================================== sub denialline { my $self = shift; my $text = shift; return "<del>".join("",$self->parse_line($text))."</del>"; } #============================================================================== # URLアンカ #============================================================================== sub url_anchor { my $self = shift; my $url = shift; my $name = shift; if($name eq ""){ $name = $url; } if($url eq $name && $url=~/\.(gif|jpg|jpeg|bmp|png)$/i && $self->{'wiki'}->config('display_image')==1){ return "<img src=\"".$url."\">"; } else { if($self->{wiki}->config('open_new_window')==1 && ($self->{wiki}->config('inside_same_window')==0 || ($self->{wiki}->config('inside_same_window')==1 && index($url,'://') > 0))){ return "<a href=\"$url\" target=\"_blank\">".Util::escapeHTML($name)."</a>"; } else { return "<a href=\"$url\">".Util::escapeHTML($name)."</a>"; } } } #============================================================================== # Wikiページへのアンカ #============================================================================== sub wiki_anchor { my $self = shift; my $page = shift; my $name = shift; if(!defined($name) || $name eq ""){ $name = $page; } if($self->{wiki}->page_exists($page)){ return "<a href=\"".$self->{wiki}->create_page_url($page)."\" class=\"wikipage\">". &Util::escapeHTML($name)."</a>"; } else { return "<span class=\"nopage\">".&Util::escapeHTML($name)."</span>". "<a href=\"".$self->{wiki}->create_page_url($page)."\">?</a>"; } } #============================================================================== # ただのテキスト #============================================================================== sub text { my $self = shift; my $text = shift; return &Util::escapeHTML($text); } #============================================================================== # プラグイン #============================================================================== sub plugin { my $self = shift; my $plugin = shift; my @result = $self->{wiki}->process_plugin($plugin,$self); return @result; } #============================================================================== # パラグラフプラグイン #============================================================================== sub l_plugin { my $self = shift; my $plugin = shift; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; my $result = $self->{wiki}->process_plugin($plugin,$self); if(defined($result) && $result ne ""){ $self->{html} .= $result; } } #============================================================================== # イメージ #============================================================================== sub l_image { my $self = shift; my $page = shift; my $file = shift; my $wiki = $self->{wiki}; if($self->{para}==1){ $self->{html} .= "</p>\n"; $self->{para} = 0; } $self->end_list; $self->end_verbatim; $self->end_table; $self->end_quote; $self->{html} .= "<div><img src=\"".$wiki->create_url({action=>"ATTACH",page=>$page,file=>$file})."\"></div>\n"; } #============================================================================== # エラーメッセージ #============================================================================== sub error { my $self = shift; my $label = shift; return "<span class=\"error\">".Util::escapeHTML($label)."</span>"; } 1;