PyukiWiki CVS Commit
pyuki****@lists*****
2012年 3月 18日 (日) 02:14:52 JST
Index: PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/adminedit.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,32 @@ +## +# 管理者用編集プラグイン~ +# ※内部で edit プラグインの機能を呼び出している。~ +# メニューから呼び出される。 +# :書式| +# なし + +# @author: Nekyo (http://nekyo.hp.infoseek.co.jp/) +# @license: GPL2 and/or Artistic or each later version. + +use strict; + +sub plugin_adminedit_action { + if (1 == &exist_plugin('edit')) { + my ($page) = &unarmor_name(&armor_name($::form{mypage})); + my $body; + if (not &is_editable($page)) { + $body .= qq(<p><strong>$::resource{cantchange}</strong></p>); + } else { + $body .= qq(<p><strong>$::resource{passwordneeded}</strong></p>); + $body .= &editform( + $::database{$page}, + &get_info($page, $::info_ConflictChecker), + admin => 1 + ); + } + return ('msg'=>$page, 'body'=>$body); + } + return ""; +} +1; +__END__ Index: PyukiWiki-Nekyo/019/plugin/amazon.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/amazon.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/amazon.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,98 @@ +## +# アマゾン(http://www.amazon.co.jp)の商品のイメージ、商品名を表示する。~ +# アフェリエイト対応。 +# :書式| +# &amazon(ASIN番号); +# #amazon +# #amazon(,clear) +# #amazon(ASIN番号,[left|right],[タイトル|image]) +# -left|right - 表示時の位置指定。省略時はright。~ +# -clear - テキスト回り込みの解除。~ +# -タイトル - 商品タイトルを指定。省略時は自動取得。 +# -image - 商品のイメージのみ表示。省略時はイメージとタイトルを表示。 +# :備考| +# アマゾンのアソシエイトプログラムを確認すること。~ +use strict; +package amazon; + +my $shop = 'http://www.amazon.co.jp/exec/obidos/ASIN/'; +my $af_id = 'pyukiwikipubl-22'; + +sub plugin_block +{ + return &plugin_inline(@_); +} + +sub plugin_inline +{ + my @aryargs = split(/,/, shift); + + return '' if (@aryargs < 1 or @aryargs > 3); + my $asin_aid = ''; + my $align = 'left'; # Set Dafault align; + $align = lc $aryargs[1] if (@aryargs > 1); + return '<div style="clear:both"></div>' if ($align eq 'clear'); # 改行挿入 + + $align = 'right' if ($align ne 'left'); # 配置決定 + + my $asin_all = &::escape($aryargs[0]); + + my $asin = ''; + if ($asin_all =~ /^([A-Z0-9]{10}).?([0-9][0-9])?$/) { + $asin = $1; + my $asin_ext = ($2 eq '') ? "09" : $2; + $asin_all = "$asin.$asin_ext"; + } elsif ($align ne 'clear') { + return 'Not Asin Code'; + } + + my $title = ''; + my $alt = ''; + if ($aryargs[2] ne '' and $aryargs[2] ne 'image') { # タイトル指定か自動取得か + $title = &::escape($aryargs[2]); # for XSS + $alt = $title; + } + my $url = "http://images-jp.amazon.com/images/P/$asin_all.MZZZZZZZ.jpg"; + my $div = ""; + + my $ref = 'ref=nosim'; + $ref = $af_id if ($af_id ne ''); + if ($title eq '') { # タイトルがなければ、画像のみ表示 + $div .= <<"EOD"; +<div style="float:$align;margin:16px 16px 16px 16px;text-align:center"> +<a href="$shop$asin/@{[$asin_aid]}$ref"><img src="$url" alt="$alt" /></a> +</div> +EOD + } else { # 通常表示 + $div .= <<"EOD"; +<div style="float:$align;padding:.5em 1.5em .5em 1.5em;text-align:center"> +<table style="width:110px;border:0;text-align:center"> + <tr> + <td style="text-align:center"> + <a href="$shop$asin/@{[$asin_aid]}$ref"><img src="$url" alt="$alt" /></a> + </td> + </tr> + <tr> + <td style="text-align:center"> + <a href="$shop$asin/@{[$asin_aid]}$ref">$title</a> + </td> + </tr> +</table> +</div> +EOD + } + return $div; +} + +sub plugin_usage { + return { + name => 'amazon', + version => '1.0', + author => 'Nekyo.', + syntax => '&amazon(...)', + description => 'show amazon books.', + example => '&amazon(asincode,...)', + }; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/aname.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/aname.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/aname.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,56 @@ +## +# 指定した位置にアンカー(リンクの飛び先)を設定します。 +# :書式| +# &aname(アンカー名,[,{[super],[full],[noid]},アンカー文字列]); +# #aname(アンカー名,[,{[super],[full],[noid]},アンカー文字列]) +# アンカー名がアンカーの指定子に使用される。(省略不可)。半角英字(大文字/小文字)が使用可能。 +# super,full,noid でアンカーの出力方式を指定する。 +# -super - アンカー文字列を上付き表示する。省略時は上付き表示されない。 +# -full - フラグメント指定子以外のURIを補いアンカーを出力する。省略時はフラグメント指定子のみ出力される。 +# -noid − アンカーにフラグメント指定子を出力しない。 +# アンカー文字列が指定された場合、指定した文字列に対しアンカーが出力される。アンカーの存在を明示する場合に使用する。省略時は空文字となる。 + +############################################### +# aname plugin +# aname.inc.pl +# Copyright(c) 2004 Nekyo. +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) +# Based on aname.inc.php by Mr.arino. + +sub plugin_aname_inline +{ + my ($args) = @_; + return plugin_aname_convert($args); +} + +sub plugin_aname_convert +{ + return '' if (@_ < 1); # no param + my @args = split(/,/, shift); + my $id = shift(@args); + return false if (!($id =~ /^[A-Za-z][\w\-]*$/)); + + my $body = ''; + if (@args) { + $body = pop(@args); + $body =~ s/<\/?a[^>]*>//; + } + my $class = 'anchor'; + my $url = ''; + my $attr_id = " id=\"$id\""; + + foreach (@args) { + if (/super/) { + $class = 'anchor_super'; + } + if (/full/) { + $url = "$script?" . rawurlencode($vars['page']); + } + if (/noid/) { + $attr_id = ''; + } + } + return "<a class=\"$class\"$attr_id href=\"$url#$id\" title=\"$id\">$body</a>"; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/article.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/article.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/article.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,86 @@ +## +# 簡易掲示板を設置する。 +# :書式| +# #article + +# PyukiWiki BBS風プラグイン +# 2007/01/15 スパム対策 +# 2004/06/12 Nekyo(c) http://nekyo.hp.infoseek.co.jp/ +# Based on OKAWARA,Satoshi's PukiWiki Plugin +use strict; + +$article::cols = 70; # テキストエリアのカラム数 +$article::rows = 5; # テキストエリアの行数 +$article::name_cols = 24; # 名前テキストエリアのカラム数 +$article::subject_cols = 60; # 題名テキストエリアのカラム数 +$article::name_format = '[[$name]]'; # 名前の挿入フォーマット +$article::subject_format = '**$subject'; # 題名の挿入フォーマット +$article::ins = 0; # 挿入する位置 1:欄の前 0:欄の後 +$article::comment = 1; # 書込み下に一行コメントを 1:入れる 0:入れない +$article::auto_br = 1; # 改行を自動的変換 1:する 0:しない +$article::no = 0; + +my $_no_name = ""; +my $_no_subject = "no subject"; + +sub plugin_article_action +{ + return if ($::form{msg} =~ /^\s*$/); # msg なしで処理しない。 + my $postdata = $::form{msg}; + + &::spam_filter($postdata, 1); + my $name = $_no_name; + if ($::form{name} ne '') { + #&::spam_filter($::form{name}, 0); # 日本語チェックは行わない。 + $name = $article::name_format; + $name =~ s/\$name/$::form{name}/g; + } + my $subject = $article::subject_format; + if ($::form{subject} ne '') { + #&::spam_filter($::form{subject}, 0); # 日本語チェックは行わない。 + $subject =~ s/\$subject/$::form{subject}/g; + } else { + $subject =~ s/\$subject/$_no_subject/g; + } + my $artic = "$subject\n>$name (@{[&get_now]})~\n~\n$::form{msg}\n"; + $artic .= "\n#comment\n" if ($article::comment); + $postdata = ''; + my @postdata_old = split(/\r?\n/, $::database{$::form{'mypage'}}); + my $_article_no = 0; + + foreach (@postdata_old) { + $postdata .= $_ . "\n" if (!$article::ins); + if (/^#article/ && (++$_article_no == $::form{article_no})) { + $postdata .= "$artic\n"; + } + $postdata .= $_ . "\n" if ($article::ins); + } + $::form{mymsg} = $postdata; + $::form{mytouch} = 'on'; + &do_write("FrozenWrite"); + &close_db; + exit; +} + +sub plugin_article_convert +{ + $article::no++; + my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker); + return <<"EOD"; +<form action="$::script" method="post"> + <div> + <input type="hidden" name="article_no" value="$article::no" /> + <input type="hidden" name="cmd" value="article" /> + <input type="hidden" name="mypage" value="$::form{'mypage'}" /> + <input type="hidden" name="myConflictChecker" value="$conflictchecker" /> + <input type="hidden" name="mytouch" value="on" /> + $::resource{article_name} <input type="text" name="name" size="$article::name_cols" /><br /> + $::resource{article_subject} <input type="text" name="subject" size="$article::subject_cols" /><br /> + <textarea name="msg" rows="$article::rows" cols="$article::cols"></textarea><br /> + <input type="submit" value="$::resource{article_btn}" /> + </div> +</form> +EOD +} + +1; Index: PyukiWiki-Nekyo/019/plugin/attach.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/attach.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/attach.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,586 @@ +## +# ページの添付ファイル一覧を表示し、ファイル添付のための入力フォームを設置する。 +# :書式| +# #attach([nolist][,noform]) +# -nolist - 添付ファイルの一覧を表示しない。省略時は表示。 +# -noform - ファイル添付フォームを表示しない。省略時は表示。 +use strict; +use CGI qw(:standard); +use Digest::MD5 qw(md5_hex); + +#-------------------------------------------------------- +my %mime = ( + "\.hqx" => "application/mac-binhex40", + "\.doc" => "application/msword", + "\.pdf" => "application/pdf", + "\.(ppt|pps|pot)" => "application/vnd.ms-powerpoint", + "\.xls" => "application/vnd.ms-excel", + "\.sit" => "application/x-stuffit", + "\.swf" => "application/x-shockwave-flash", + "\.(zip|nar)" => "application/zip", + + "\.midi?" => "audio/midi", + "\.mp3" => "audio/mpeg", + "\.wav" => "audio/x-wav", + + "\.bmp" => "image/bmp", + "\.gif" => "image/gif", + "\.jpe?g" => "image/jpeg", + "\.png" => "image/png", + + "\.txt" => "text/plain", + + "\.mpe?g" => "video/mpeg", +); + +# file icon image +if (!$::file_icon) { + $::file_icon = '<img src="' + . $::image_dir + . '/file.png" width="20" height="20" alt="file" style="border-width:0px" />'; +} + +#-------- convert +sub plugin_attach_convert +{ + if (!$::file_uploads) { + return 'file_uploads disabled'; + } + + my $nolist = 0; + my $noform = 0; + + my @arg = split(/,/, shift); + if (@arg > 0) { + foreach (@arg) { + $_ = lc $_; + $nolist |= ($_ eq 'nolist'); + $noform |= ($_ eq 'noform'); + } + } + my $ret = ''; + if (!$nolist) { + # $obj = &new AttachPages($vars['page']); + # $ret .= $obj->toString($vars['page'],1); + } + if (!$noform) { + $ret .= &attach_form($::form{mypage}); + } + return $ret; +} + +my %_attach_messages; + +#アップロードフォーム +sub attach_form +{ + my $page = $::form{mypage}; #split(/,/, shift); +# $r_page = rawurlencode($page); + my $r_page = $page; + my $s_page = &::htmlspecialchars($page); + my $navi =<<"EOD"; + <span class="small"> + [<a href="$::script?cmd=attach&mypage=$page&pcmd=list&refer=$r_page">$::resource{'attach_msg_listpage'}</a>] + [<a href="$::script?cmd=attach&mypage=$page&pcmd=list">$::resource{'attach_msg_listall'}</a>] + </span><br /> +EOD + return $navi if (!$::file_uploads); + + my $maxsize = $::max_filesize; + my $msg_maxsize = $::resource{attach_msg_maxsize}; + my $kb = $maxsize / 1000 . "kb"; + + $msg_maxsize =~ s/%s/$kb/g; + + my $pass = ''; + if ($::file_uploads == 2) { + $pass = '<br />' . $::resource{attach_msg_password} + . ': <input type="password" name="pass" size="8" />'; + } + return <<"EOD"; +<form enctype="multipart/form-data" action="$::script" method="post"> + <div> + <input type="hidden" name="cmd" value="attach" /> + <input type="hidden" name="pcmd" value="post" /> + <input type="hidden" name="refer" value="$s_page" /> + <input type="hidden" name="mypage" value="$page" /> + <input type="hidden" name="max_file_size" value="$maxsize" /> + $navi + <span class="small"> + $msg_maxsize + </span><br /> + $::resource{'attach_msg_file'}: <input type="file" name="attach_file" /> + $pass + <input type="submit" value="$::resource{'btn_upload'}" /> + </div> +</form> +EOD +} + +sub plugin_attach_action +{ + # backward compatible + if ($::form{'openfile'} ne '') { + $::form{'pcmd'} = 'open'; + $::form{'file'} = $::from{'openfile'}; + } + if ($::form{'delfile'} ne '') { + $::form{'pcmd'} = 'delete'; + $::form{'file'} = $::form{'delfile'}; + } + + my $age = $::form{age} ? $::form{age} : 0; + my $pcmd = $::form{pcmd} ? $::form{pcmd} : ''; + + # Authentication +# if ($::form{refer} ne '') { #and is_pagename($vars['refer'])) { +# my @read_cmds = ('info','open','list'); +# in_array($pcmd,$read_cmds) ? +# check_readable($vars['refer']) : check_editable($vars['refer']); +# } + + # Upload + if ($::form{attach_file} ne '') { + # my $pass = $::form{pass} ? md5_hex($::form{pass}) : ''; + return &attach_upload($::form{attach_file}, $::form{refer}, $::form{pass}); + } + + if ($pcmd eq 'info') { + return &attach_info; + } elsif ($pcmd eq 'delete') { + return &attach_delete; + } elsif ($pcmd eq 'open') { + return &attach_open; + } elsif ($pcmd eq 'list') { + return &attach_list; + } elsif ($pcmd eq 'freeze') { + return &attach_freeze(1); + } elsif ($pcmd eq 'unfreeze') { + return &attach_freeze(0); + } elsif ($pcmd eq 'upload') { + return &attach_showform; + } + return &attach_list if ($::form{mypage} eq '' or !$::database{$::form{mypage}}); + return ('msg'=>$::form{mypage}, 'body'=>&attach_form); +} + +# 詳細フォームを表示 +sub attach_info +{ + my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age}); + return $obj->getstatus() ? $obj->info() + : ('msg'=>$::form{refer}, 'body'=>"error:" . $::resource{attach_err_notfound}); +} + +# 削除 +sub attach_delete +{ + if ($::file_uploads == 2 && !&valid_password($::form{pass})) { + return ('msg'=>$::form{refer}, 'body'=>$::resource{attach_err_password}); + } + + my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age}); + return $obj->getstatus() + ? $obj->delete() + : ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_notfound}); +} + +# ダウンロード +sub attach_open +{ + my $obj = new AttachFile($::form{refer}, $::form{file}, $::form{age}); + return $obj->getstatus() ? $obj->open() + : ('msg'=>$::form{refer}, 'body'=>"error:" . $::resource{attach_err_notfound}); +} + +# 一覧取得 +sub attach_list +{ + my $refer = $::form{refer}; + my $obj = new AttachPages($refer); + my $msg = $::resource{$refer eq '' ? 'attach_msg_listall' : 'attach_msg_listpage'}; + my $body = $obj->toString(0, 1); + undef $obj; + return ('msg'=>$msg,'body'=>$body); +} + +# ファイルアップロード +sub attach_upload +{ + my ($filename, $page, $pass) = @_; + + if ($::file_uploads == 2 && !&valid_password($pass)) { + return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_password}); + } + my ($parsename, $path, $ffile); + $parsename = $filename; + $parsename =~ s#\\#/#g; # \を/に変換 + $parsename =~ s/^http:\/\///; + $parsename =~ /([^:\/]*)(:([0-9]+))?(\/.*)?$/; + $path = $4 || '/'; + $path =~ /(.*\/)(.*)/; #$ffileには直下のファイル名 + $ffile = $2; #ファイル名が無い場合'/') + $ffile =~ s/#.*$//; # #はページ内リンクなので、削除する + + my $obj = new AttachFile($page, $ffile); + if ($obj->{exist}) { + return ('msg'=>$::resource{_attach_err_exists}); + } + #ファイルの保存 + unless (open (FILE, ">" . $obj->{filename})) { + print "サーバ側の保存ファイルの作成に失敗しました。: $!\n"; + exit; + } + binmode(FILE); + my $fsize = 0; + my ($byte, $buffer); + while ($byte = read($filename, $buffer, 1024)) { + print FILE $buffer; + $fsize += $byte; + if ($fsize > $::max_filesize) { + close FILE; + unlink $obj->{filename}; + return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_err_exceed}); + } + } + close FILE; + return ('msg'=>$::form{mypage}, 'body'=>$::resource{attach_msg_uploaded}); + +# $obj->getstatus(); +# $obj->status['pass'] = ($pass !== TRUE and $pass !== NULL) ? $pass : ''; +# $obj->putstatus(); + +# return array('result'=>TRUE,'msg'=>$_attach_messages['msg_uploaded']) +# # パーミッションを変更 +# chmod (0666, "$Temp/$basename"); +} + +# ファイル名からmimeタイプ取得。 +sub attach_mime_content_type +{ + my $filename = shift; + my $mime_type; + foreach (keys %mime) { + next unless ($_ && defined($mime{$_})); + if ($filename =~ /$_$/i) { + $mime_type = $mime{$_}; + last; + } + } + return ($mime_type) ? $mime_type : 'application/octet-stream'; #default +} + + +# php互換関数。 +sub md5_file { + my ($path) = @_; + open(FILE, $path); + binmode(FILE); + my $contents; + read(FILE, $contents, 16384); + close(FILE); + return md5_hex($contents); +} + +#---------------------------------------------------- +# 1ファイル単位のコンテナ +package AttachFile; + +sub new +{ + my $this = bless {}; + shift; + $this->{page} = shift; # page + $this->{file} = shift; # file + $this->{age} = shift; # age; + $this->{basename} = "$::upload_dir/" + . &::dbmname($this->{page}) . '_' . &::dbmname($this->{file}); + $this->{filename} = $this->{basename} . ($this->{age} ? '.' . $this->{age} : ''); + $this->{exist} = (-e $this->{filename}) ? 1 : 0; + $this->{logname} = $this->{basename} . ".log"; + + $this->{time} = (stat($this->{filename}))[10]; + $this->{md5hash} = ($this->{exist} == 1) ? &::md5_file($this->{filename}) : ''; + return $this; +} + +# 添付ファイルのオープン +sub open +{ + my $this = shift; + my $query = new CGI; + + print $query->header( + -type=>"$this->{type}", + -Content_disposition=>"filename=$this->{file}", + -Content_length=>$this->{size}, + -expires=>"now", + -P3P=>"" + ); + open(FILE, $this->{filename}) || die $!; + binmode(FILE); + my $buffer; + print $buffer while (read(FILE, $buffer, 4096)); + close(FILE); + exit; +} + +# 情報表示 +sub info +{ + my $this = shift; + + my $msg_delete = '<input type="radio" name="pcmd" value="delete" />' + . $::resource{attach_msg_delete} . $::resource{attach_msg_require} . '<br />'; + + my $info = $this->toString(1, 0); + my %retval; + + $retval{msg} = $::resource{attach_msg_info}; + $retval{body} =<<EOD; +<p class="small"> + [<a href="$::script?cmd=attach&mypage=$::form{mypage}&pcmd=list&refer=$::form{refer}">$::resource{attach_msg_listpage}</a>] + [<a href="$::script?cmd=attach&pcmd=list">$::resource{attach_msg_listall}</a>] +</p> +<dl> + <dt>$info</dt> + <dd>$::resource{attach_msg_page}:$::form{refer}</dd> + <dd>$::resource{attach_msg_filename}:$this->{filename}</dd> + <dd>$::resource{attach_msg_md5hash}:$this->{md5hash}</dd> + <dd>$::resource{attach_msg_filesize}:$this->{size_str} ($this->{size} bytes)</dd> + <dd>Content-type:$this->{type}</dd> + <dd>$::resource{attach_msg_date}:$this->{time_str}</dd> +</dl> +EOD + + if ($::file_uploads) { + my $msg_pass; + + if ($::file_uploads == 2) { + $msg_pass = $::resource{attach_msg_password} + . '<input type="password" name="pass" size="8" />'; + } + + my $s_page = &::htmlspecialchars($this->{page}); + + $retval{body} .=<<EOD; +<hr /> +<form action="$::script" method="get"> + <div> + <input type="hidden" name="cmd" value="attach" /> + <input type="hidden" name="mypage" value="$this->{page}" /> + <input type="hidden" name="refer" value="$s_page" /> + <input type="hidden" name="file" value="$this->{file}" /> + <input type="hidden" name="age" value="$this->{age}" /> + $msg_delete + $msg_pass + <input type="submit" value="$::resource{attach_btn_submit}" /> + </div> +</form> +EOD + } + return %retval; +} + +sub delete +{ + my $this = shift; + + # バックアップ + if ($this->{age}) { + unlink($this->{filename}); + } else { + my $age; + do { + $age = ++$this->{age}; + } while (-e $this->{basename} . '.' . $age); + + if (!rename($this->{basename}, $this->{basename} . '.' . $age)) { + # rename 失敗 + return ('msg'=>$this->{page}, 'body'=>$::resource{attach_err_delete}); + } + } + return ('msg'=>$this->{page}, 'body'=>$::resource{attach_msg_deleted}); +} + +# ステータス取得 +sub getstatus +{ + my $this = shift; + + return 0 if (!$this->{exist}); + + # ログファイル取得 + if (-e $this->{logname}) { + # $data = file($this->logname); + # foreach ($this->status as $key=>$value) + # { + # $this->status[$key] = chop(array_shift($data)); + # } + # $this->status['count'] = explode(',',$this->status['count']); + } +# $this->time_str = get_date('Y/m/d H:i:s',$this->time); + my ($sec, $min, $hour, $day, $mon, $year) = localtime($this->{time}); + $this->{time_str} = sprintf("%d/%02d/%02d %02d:%02d:%02d", + $year + 1900, $mon + 1, $day, $hour, $min, $sec); + $this->{size} = -s $this->{filename}; + $this->{size_str} = sprintf('%01.1f', $this->{size}/1000) . 'KB'; + $this->{type} = &::attach_mime_content_type($this->{file}); + return 1; +} + +# ステータス保存 +sub putstatus +{ +# $this->status['count'] = join(',',$this->status['count']); +# $fp = fopen($this->logname,'wb') +# or die_message('cannot write '.$this->logname); +# flock($fp,LOCK_EX); +# foreach ($this->status as $key=>$value) +# { +# fwrite($fp,$value."\n"); +# } +# flock($fp,LOCK_UN); +# fclose($fp); +} + +# ファイルのリンクを作成 +sub toString { + my $this = shift; + my $showicon = shift; + my $showinfo = shift; + + my $body; + my $finfo = "&file=" . &::encode($this->{file}) + . "&mypage=" . &::encode($::form{mypage}) + . "&refer=" . &::encode($this->{page}) + . ($this->{age} >= 1 ? "&age=$this->{age}" : ""); + + $body .= $::file_icon if ($showicon); + $body .= "<a href=\"$::script?cmd=attach&pcmd=open$finfo\">$this->{file} " + . ($this->{age} >= 1 ? "(Backup No.$this->{age})" : "") . "</a>"; + + if ($showinfo) { + $body .= " [<a href=\"$::script?cmd=attach&pcmd=info" + . "$finfo\">$::resource{attach_msg_description}</a>]"; + } + return $body; +} + +#---------------------------------------------------- +# ファイル一覧コンテナ作成 +package AttachFiles; +my %files; + +sub new { + my $this = bless {}; + shift; + $this->{page} = shift; # page + return $this; +} + +sub add { + my $this = shift; + my $file = shift; + my $age = shift; + + # 美しくないけど3次元配列 + $files{$this->{page}}{$file}{$age} = new AttachFile($this->{page}, $file, $age); +} + +# ページ単位の一覧表示 +sub toString { + my $this = shift; + my $flat = shift; + my $page = $this->{page}; + + my $ret = ""; + my $files = $this->{files}; + $ret .= "<li>" . &::make_link($this->{page}) . "\n<ul>\n"; + my ($target, $notarget, $backup); + foreach my $key (sort keys %{$files{$page}}) { + $target = ''; + $notarget = ''; + $backup = ''; + foreach (sort keys %{$files{$page}{$key}}) { + if ($_ >= 1) { + $backup .= "<li>" . $files{$page}{$key}{$_}->toString(0, 1) . "</li>\n"; + $notarget = $files{$page}{$key}{$_}->{file}; + } else { + $target .= $files{$page}{$key}{$_}->toString(0, 1); + } + } + $ret .= "<li>" . ($target ? $target : $notarget); + $ret .= "\n<ul>\n$backup\n</ul>\n" if ($backup); + $ret .= "</li>\n"; + } + return $ret . "</ul>\n</li>\n"; +} + +sub to_flat { + my $this = shift; + my $flat = shift; + my $ret = ""; + my %files = $this->{files}; + foreach my $key (sort keys %files) { + foreach (sort keys %{$files{$key}}) { + $ret .= $key . "." . $_ . $files{$key}{$_}->toString(1, 1) . ' '; + } + } + return $ret; +} + +#------------------------------------------------- +# ページコンテナ作成 +package AttachPages; + +my %pages; + +# ページコンテナ作成 +sub new { + my $this = bless {}; + shift; + $this->{page} = shift; + my $age = shift; + + opendir(DIR, "$::upload_dir/") + or die('directory ' . $::upload_dir . ' is not exist or not readable.'); + my @file = readdir(DIR); + closedir(DIR); + + my $page_pattern = ($this->{page} eq '') + ? '(?:[0-9A-F]{2})+' : &::dbmname($::form{mypage}); + my $age_pattern = ($age eq '') ? '(?:\.([0-9]+))?' : ($age ? "\.($age)" : ''); + my $pattern = "^($page_pattern)_((?:[0-9A-F]{2})+)$age_pattern\$"; + + my ($_page, $_file, $_age); + + foreach (@file) { + next if (!/$pattern/); + $_page = pack("H*", $1); + $_file = pack("H*", $2); + $_age = $3 ? $3 : 0; + + $pages{$_page} = new AttachFiles($_page) if (!exists($pages{$_page})); + $pages{$_page}->add($_file, $_age); + } + return $this; +} + +# 全ページの添付一覧表示 +sub toString { + my $this = shift; + my $page = shift; + my $flat = shift; + + # page exist check; + my $body = ""; + foreach (sort keys %pages) { + $body .= $pages{$_}->toString($flat); + } + return "\n<div id=\"body\">" . $::resource{attach_err_noexist} . "</div>\n" + if ($body eq ""); + return "\n<ul>\n$body</ul>\n"; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/br.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/br.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/br.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,30 @@ +## +# 文章中で改行を行う。 +# :書式| +# #br +# &br; +# @author Nekyo.(http://nekyo.hp.infoseek.co.jp/) +# @version 1.00 + +use strict; +package br; + +sub plugin_block { + return &plugin_inline; +} + +sub plugin_inline { + return qq(<br />); +} + +sub plugin_usage { + return { + name => 'br', + version => '1.00', + author => 'Nekyo', + syntax => '&br', + description => 'line break.', + example => '&br', + }; +} +1; Index: PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/bugtrack.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,311 @@ +## +# バグレポートの入力フォームを設置する。 +# :書式| +# #bugtrack([[ページ名][カテゴリー1…カテゴリーn]]) +# -ページ名はバグレポートとして作成されるページの親階層のページ名を指定。省略時は設置ページとなる。 +# バグレポートは指定したページの子階層に自動的に番号が振られてページが作成される。(ページ名/1,ページ名/2,...) +# -カテゴリーはバグ対象となりうる要素を指定する。 + +# Based on Pukiwiki BugTrackプラグイン (c)Y.MASUI GPL2 http:#masui.net/pukiwiki/ +# Special Thanks! kamo http://kamoland.com/ +# +# 変更履歴: +# 2002.06.17: 作り始め +# +use strict; + + @ bugtrack::priority_list = ('緊急','重要','普通','低'); + @ bugtrack::state_list = ('提案','着手','CVS待ち','完了','保留','却下'); + @ bugtrack::state_sort = ('着手','CVS待ち','保留','完了','提案','却下'); + @ bugtrack::state_bgcolor = ('#ccccff','#ffcc99','#ccddcc','#ccffcc','#ffccff','#cccccc','#ff3333'); + +$bugtrack::title = '$1 Bugtrack Plugin'; +$bugtrack::base = 'ページ'; +$bugtrack::summary = 'サマリ'; +$bugtrack::priority = '優先順位'; +$bugtrack::state = '状態'; +$bugtrack::name = '投稿者'; +$bugtrack::date = '投稿日'; +$bugtrack::body = 'メッセージ'; +$bugtrack::category = 'カテゴリー'; +$bugtrack::pagename = 'ページ名'; +$bugtrack::pagename_comment = '<small>空欄のままだと自動的にページ名が振られます。</small>'; +$bugtrack::version_comment = '<small>空欄でも構いません</small>'; +$bugtrack::version = 'バージョン'; +$bugtrack::submit = '追加'; + +sub plugin_bugtrack_action +{ + if ($::form{mode} eq 'submit') { + &plugin_bugtrack_write( + $::form{base}, $::form{pagename}, $::form{summary}, $::form{name}, $::form{priority}, + $::form{state}, $::form{category}, $::form{version}, $::form{body} + ); + exit; + } + return ('msg'=>$bugtrack::title, 'body'=>&plugin_bugtrack_print_form($::form{category})); +} + +sub plugin_bugtrack_print_form +{ + my ($base, @category) = @_; + my $select_priority = ''; + my $i; + for ($i = 0; $i < @bugtrack::priority_list; ++$i) { + my $selected = ($i < @bugtrack::lugin_priority_list - 1) ? '' : ' selected="selected"'; + $select_priority .= "<option value=\"$bugtrack::priority_list[$i]\"$selected>$bugtrack::priority_list[$i]</option>\n"; + } + + my $select_state = ''; + for ($i = 0; $i < @bugtrack::state_list; ++$i) { + $select_state .= "<option value=\"$bugtrack::state_list[$i]\">$bugtrack::state_list[$i]</option>\n"; + } + + my $encoded_category = '<input name="category" type="text" />'; + if (@category != 0) { + $encoded_category = '<select name="category">'; + foreach my $_category (@category) { + my $s_category = &htmlspecialchars($_category); + $encoded_category .= "<option value=\"$s_category\">$s_category</option>\n"; + } + $encoded_category .= '</select>'; + } + + my $s_base = &htmlspecialchars($base); + my $body = <<"EOD"; +<form action="$::script" method="post"> + <table border="0"> + <tr> + <th>$bugtrack::name</th> + <td><input name="name" size="20" type="text" /></td> + </tr> + <tr> + <th>$bugtrack::category</th> + <td>$encoded_category</td> + </tr> + <tr> + <th>$bugtrack::priority</th> + <td><select name="priority">$select_priority</select></td> + </tr> + <tr> + <th>$bugtrack::state</th> + <td><select name="state">$select_state</select></td> + </tr> + <tr> + <th>$bugtrack::pagename</th> + <td><input name="pagename" size="20" type="text" />$bugtrack::pagename_comment</td> + </tr> + <tr> + <th>$bugtrack::version</th> + <td><input name="version" size="10" type="text" />$bugtrack::version_comment</td> + </tr> + <tr> + <th>$bugtrack::summary</th> + <td><input name="summary" size="60" type="text" /></td> + </tr> + <tr> + <th>$bugtrack::body</th> + <td><textarea name="body" cols="60" rows="6"></textarea></td> + </tr> + <tr> + <td colspan="2" align="center"> + <input type="submit" value="$bugtrack::submit" /> + <input type="hidden" name="cmd" value="bugtrack" /> + <input type="hidden" name="mode" value="submit" /> + <input type="hidden" name="base" value="$s_base" /> + </td> + </tr> + </table> +</form> +EOD + return $body; +} + +sub plugin_bugtrack_template +{ + my ($base, $summary, $name, $priority, $state, $category, $version, $body) = @_; + + $name = &::armor_name($name); + $base = &::armor_name($base); + return <<"EOD"; +*$summary + +-$bugtrack::base: $base +-$bugtrack::name: $name +-$bugtrack::priority: $priority +-$bugtrack::state: $state +-$bugtrack::category: $category +-$bugtrack::date: @{[&get_now]} +-$bugtrack::version: $version + +**$bugtrack::body +$body +---- + +#comment +EOD +} + +sub plugin_bugtrack_write +{ + my ($base, $pagename, $summary, $name, $priority, $state, $category, $version, $body) = @_; + + $base = &::unarmor_name($base); + $pagename = &::unarmor_name($pagename); + + my $postdata = &plugin_bugtrack_template($base, $summary, $name, $priority, $state, $category, $version, $body); + + my $page; + my $i = 0; + do { + $i++; + $page = "$base/$i"; + } while ($::database{$page}); + + if ($pagename == '') { + $::form{mypage} = $page; + $::form{mymsg} = $postdata; + $::form{mytouch} = 'on'; + &do_write; + exit; + } else { + # $pagename = get_fullname($pagename,$base); + # すでにページが存在するか、無効なページ名が指定された + # if (is_page($pagename) or !$::database{$pagename}) { + # ページ名をデフォルトに戻す + $pagename = $page; + # } else { + # page_write($page,"move to [[$pagename]]"); + # } + # page_write($pagename,$postdata); + } + + return $page; +} + +sub plugin_bugtrack_convert +{ + my $base = $::form{mypage}; + my @category = split(/,/, shift); + if (@category > 0) { + my $_base = &::unarmor_name(shift(@category)); + if ($::database{$_base}) { + $base = $_base; + } + } + return &plugin_bugtrack_print_form($base, @category); +} + + +sub plugin_bugtrack_pageinfo +{ + my ($page, $no) = @_; + + if (@_ == 1) { + $no = ($page =~ /\/([0-9]+)$/) ? $1 : 0; + } + my $body = $::database{$page}; + + if ($body =~ /move\s*to\s*($::WikiName|$::InterWikiName|\[\[$::BracketName\]\])/) { + return &plugin_bugtrack_pageinfo(&::unarmor_name($1), $no); + } + my ($summary, $name, $priority, $state, $category); + $summary = $name = $priority = $state = $category = 'test'; + my @itemlist = ($bugtrack::summary, $bugtrack::name, $bugtrack::priority, $bugtrack::state, $bugtrack::category); + foreach my $itemname (@itemlist) { + if ($body =~ /-\s*$itemname\s*:\s*(.*)\s*/) { + if ($itemname eq $bugtrack::name) { + $name = &htmlspecialchars(&::unarmor_name($1)); + } elsif ($itemname eq $bugtrack::summary) { + $summary = &::htmlspecialchars($1); + } elsif ($itemname eq $bugtrack::priority) { + $priority = &::htmlspecialchars($1); + } elsif ($itemname eq $bugtrack::state) { + $state = &::htmlspecialchars($1); + } elsif ($itemname eq $bugtrack::category) { + $category = &::htmlspecialchars($1); + } + } + } + + if ($body =~ /\*([^\n]+)/) { + $summary = $1; + } + return join('<>', ($page, $no, $summary, $name, $priority, $state, $category)); +} + +sub plugin_bugtrack_list_convert +{ + my ($_page) = split(',', shift); + my $page = $::form{mypage}; + + # 引数で指定されたページが存在したら、そのページを使用する。 + $page = $_page if ($::database{$_page}); + + my @data = (); + my $pattern = "$page/"; + my $pattern_len = length($pattern); + my ($line, $i); + + foreach $page (keys %::database) { + if (index($page, $pattern) == 0 && substr($page, $pattern_len) =~ /[1-9][0-9]*/) { + $line = &plugin_bugtrack_pageinfo($page); + push(@data, $line); + } + } + + my @table; + for ($i = 0; $i < @bugtrack::state_list; $i++) { + $table[$i] = ''; + } + + foreach $line (@data) { + my ($page, $no, $summary, $name, $priority, $state, $category) = split(/<>/, $line); + my $state_no = $#bugtrack::state_list; + for ($i = 0; $i <= $#bugtrack::state_sort; $i++) { + if ($bugtrack::state_sort[$i] eq $state) { + $state_no = $i; + last; + } + } + my $page_link = &::make_link($page); + my $bgcolor = $bugtrack::state_bgcolor[$state_no]; + my $row = <<"EOD"; + <tr> + <td style="background-color:$bgcolor">$page_link</td> + <td style="background-color:$bgcolor">$state</td> + <td style="background-color:$bgcolor">$priority</td> + <td style="background-color:$bgcolor">$category</td> + <td style="background-color:$bgcolor">$name</td> + <td style="background-color:$bgcolor">$summary</td> + </tr> +EOD + $table[$state_no] .= "$no<>$row\n\n"; + } + my $table_html = <<"EOD"; +<table border="1"> + <tr> + <th> </th> + <th>$bugtrack::state</th> + <th>$bugtrack::priority</th> + <th>$bugtrack::category</th> + <th>$bugtrack::name</th> + <th>$bugtrack::summary</th> + </tr> +EOD + + for ($i = 0; $i <= $#bugtrack::state_list; $i++) { + my (%rowlist) = {}; + foreach my $tab (split(/\n\n/, $table[$i])) { + my($no, $row) = split(/<>/, $tab); + $rowlist{$no} = $row; + } + my (@newkeys) = sort {$b <=> $a} keys(%rowlist); + foreach my $newkey (@newkeys) { + $table_html .= "$rowlist{$newkey}\n"; + } + } + return $table_html . "</table>"; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/bugtrack_list.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,9 @@ +## +# バグレポートを一覧表示する。 +# :書式| +# #bugtrack_list([ページ名]) +# -ページ名はバグレポートとして作成されるページの親階層のページ名を指定。省略時は設置ページとなる。~ +# bugtrackプラグインの機能を使用しているため、bugtrackプラグイン必須。 + +require $::plugin_dir . '/bugtrack.inc.pl'; +1; Index: PyukiWiki-Nekyo/019/plugin/calendar.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/calendar.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/calendar.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,146 @@ +## +# カレンダーを設置する。 +# :書式| +# #calendar([{[ページ名],[年月]}]) +# -ページ名を指定する。省略時は設置ページとなる。 +# -年月は表示カレンダーの西暦と月をyyyymm形式で指定する。省略時は現在年月。 + +# calendar.inc.pl v0.0.3 cooked up by Birgus-Latro. +# for "PyukiWiki" copyright 2004 by Nekyo. +# based on calendar.inc.php v1.18 2003/06/04 14:20:36 arino. +# calendar2.inc.php v1.20 2003/06/03 11:59:07 arino. +# calendar.pl v1.2 Seiji Zenitani. +use strict; +use Time::Local; + +sub plugin_calendar_convert { + my ($page, $arg_date) = split(/,/, shift); + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); + my ($disp_wday,$today,$start,$end,$i,$label,$cookedpage,$d); + my ($prefix,$splitter); + my $empty = ' '; + my $calendar = ""; + + ($sec, $min, $hour, $mday, $mon, $year) = localtime(); + $today = ($year+1900)*10000 + ($mon+1)*100 + $mday; + + if ($page eq '') { + $prefix = $::form{mypage}; + $splitter = '/'; + } + elsif ($page eq '*') { + $prefix = ''; + $splitter = ''; + } + else { + $prefix = $page; + $splitter = '/'; + } + $page = &htmlspecialchars($prefix); + if ($page eq '') { + $cookedpage = '*'; + } else { + $cookedpage = &encode($page); + } + + if ($arg_date =~ /^(\d{4})[^\d]?(\d{1,2})$/ ) { + $year = $1 - 1900; + $mon = ($2-1) % 12; + } + my $disp_year = $year+1900; + my $disp_month = $mon+1; + + my $start_time = timelocal(0,0,0,1,$mon,$year); + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($start_time); + $label = "$disp_year.$disp_month"; + $start = ($year+1900)*10000 + ($mon+1)*100 + $mday; + + if ( $mon == 11 ) { + $end = ($year+1900)*10000 + ($mon+1)*100 + 31; + } else { + my $end_time = timelocal(0,0,0,1,$mon+1,$year) - 24*60*60; + ($sec, $min, $hour, $mday, $mon, $year ) = localtime($end_time); + $end = ($year+1900)*10000 + ($mon+1)*100 + $mday; + } + + my $pagelink; + if ($::database{$page}) { + $pagelink = qq(<br />[<a title="$page" href="$::script?$cookedpage">$page</a>]); + } elsif ($page eq '') { + $pagelink = ''; + } else { + $pagelink = qq(<br />[$page<a title="$::resource{editthispage}" class="editlink" href="$::script?cmd=adminedit&mypage=$cookedpage">?</a>]); + } + + my $prev_date_str = ($disp_month == 1)? sprintf('%04d%02d',$disp_year - 1,12) : sprintf('%04d%02d',$disp_year,$disp_month - 1); + my $next_date_str = ($disp_month == 12)? sprintf('%04d%02d',$disp_year + 1, 1) : sprintf('%04d%02d',$disp_year,$disp_month + 1); + + $calendar =<<"END"; +<table class="style_calendar" summary="calendar body"> +<tr> +<td class="style_td_caltop" colspan="7"> + <a href="$::script?cmd=calendar&mymsg=$cookedpage&date=$prev_date_str"><<</a> + <strong>$label</strong> + <a href="$::script?cmd=calendar&mymsg=$cookedpage&date=$next_date_str">>> + $pagelink</td> +</tr> +<tr> +<td class="style_td_week">日</td> +<td class="style_td_week">月</td> +<td class="style_td_week">火</td> +<td class="style_td_week">水</td> +<td class="style_td_week">木</td> +<td class="style_td_week">金</td> +<td class="style_td_week">土</td> +</tr> +<tr> +END + + for ( $i = 0; $i < $wday; $i++ ) { + $calendar .= "<td class=\"style_td_blank\">$empty</td>"; + } + my $style = ''; + for ( $i=$start; $i<=$end; $i++ ) { + $d = $i % 100; + $disp_wday = ($wday + $i - $start) % 7; + my $pagename = sprintf "%s%s%04d-%02d-%02d", $page, $splitter, $disp_year, $disp_month, $d; + my $cookedname = &encode($pagename); + + if (($disp_wday == 0) && ($i > $start)) { + $calendar .= "</tr>\n<tr>\n"; + } + + if ( $i == $today ) { # today + $style = 'style_td_today'; + } elsif ($disp_wday == 0) { # Sunday + $style = 'style_td_sun'; + } elsif ($disp_wday == 6) { # Saturday + $style = 'style_td_sat'; + } else { + $style = 'style_td_day'; + } + + if ($::database{$pagename}) { + $calendar .= qq(<td class="$style"><a title="$pagename" href="$::script?$cookedname"><strong>$d</strong></a></td>); + } else { + $calendar .= qq(<td class="$style"><a class="small" title="$::resource{editthispage}" href="$::script?cmd=adminedit&mypage=$cookedname">$d</a></td>); + } + } + for ( $i = $disp_wday + 1; $i < 7; $i++ ) { + $calendar .= "<td class=\"style_td_blank\">$empty</td>"; + } + + $calendar .= "</tr>\n</table>\n"; + return $calendar; +} + +sub plugin_calendar_action { + my $page = &escape($::form{mymsg}); + my $date = &escape($::form{date}); + my $body = &plugin_calendar_convert(qq($page,$date)); + + my $yy = sprintf("%04d.%02d",substr($date,0,4),substr($date,4,2)); + my $s_page = htmlspecialchars($page); + return ('msg'=>qq(calendar $s_page/$yy), 'body'=>$body); +} +1; \ No newline at end of file Index: PyukiWiki-Nekyo/019/plugin/clear.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/clear.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/clear.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,13 @@ +## +# 他のプラグインで有効になったテキスト回り込み指定を解除する。 +# :書式| +# #clear +# @author: Nanami <nanam****@daiba*****> + +use strict; +package clear; + +sub plugin_inline { + return '<div class="clear"></div>'; +} +1; Index: PyukiWiki-Nekyo/019/plugin/color.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/color.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/color.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,38 @@ +## +# 引数で指定したインライン要素の、文字色・背景色を指定する。 +# :書式| +# &color([文字色][,背景色]){文章}; + +# @author nekyo. +# @version 1.00 +use strict; +package color; + +sub plugin_inline { + my @args = split(/,/, shift); + my $bgcolor = ''; + my ($color, $bgcolor, $body); + + if (@args == 3) { + $color = $args[0]; + $bgcolor = $args[1]; + $body = $args[2]; + if ($body eq '') { + $body = $bgcolor; + $bgcolor = ''; + } + } elsif (@args == 2) { + $color = $args[0]; + $body = $args[1]; + } else { + return ''; + } + if ($color eq '' or $body eq '') { + return ''; + } + if ($bgcolor ne '') { + $color .= ';background-color:'.$bgcolor; + } + return "<span style=\"color:$color\">$body</span>"; +} +1; Index: PyukiWiki-Nekyo/019/plugin/comment.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/comment.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/comment.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,111 @@ +## +# コメント入力欄を表示する。 +# :書式| +# #comment({[above],[below],[nodate],[noname]}) +# -above - コメントを入力欄の上に追加する。 +# -below - コメントを入力欄の下に追加する。(default) +# -nodate - コメントに挿入時刻を付加しない。(省略時は付加する。) +# -noname - 記入者名の入力欄を非表示とする。(省略時は表示。) + +# Copyright(c) 2004 Nekyo. +# v 0.0.3 - 2006/01/15 Tnx:Birgus-Latro +# v 0.0.2 - 2004/10/28 Tnx:Birgus-Latro +# v 0.0.1 - ProtoType +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) +# Based on comment.inc.php by Mr.arino. +# 1TAB=4Spaces +use strict; + +my $comment_format = "\x08MSG\x08 -- \x08NAME\x08 \x08NOW\x08"; + +sub plugin_comment_action { + my $comment = $::form{mymsg}; + + &::spam_filter($comment, 1); + + my $lines = $::database{$::form{mypage}}; + my @lines = split(/\r?\n/, $lines); + my $datestr = ($::form{nodate} == 1) ? '' : &get_now; + my $_name = " "; + + if ($::form{myname}) { + # &::spam_filter($::form{myname}, 0); + $_name = " ''[[$::form{myname}]]'' : "; + } + my $_now = "&new{$datestr};"; + my $postdata = ''; + my $_comment_no = 0; + + $comment = $comment_format; + $comment =~ s/\x08MSG\x08/$::form{mymsg}/; + $comment =~ s/\x08NAME\x08/$_name/; + $comment =~ s/\x08NOW\x08/$_now/; + $comment = "-" . $comment; + + foreach (@lines) { + if (/^#comment/ && (++$_comment_no == $::form{comment_no})) { + if ($::form{above} == 1) { + $_ = ($comment . "\n" . $_); + } else { + $_ .= ("\n" . $comment); + } + } + $postdata .= $_ . "\n"; + } + if ($::form{mymsg}) { + $::form{mymsg} = $postdata; + $::form{mytouch} = 'on'; + + &do_write('FrozenWrite'); + } else { + $::form{cmd} = 'read'; + &do_read; + } + &close_db; + exit; +} + +my $comment_no = 0; +my %comment_numbers = {}; # Tnx:Birgus-Latro + +sub plugin_comment_convert { + my @argv = split(/,/, shift); + + my $above = 1; + my $nodate = ''; + my $nametags = $::resource{yourname} . '<input type="text" name="myname" value="" size="10">'; + + foreach (@argv) { + chomp; + if (/below/) { + $above = 0; + } elsif (/nodate/) { + $nodate = 1; + } elsif (/noname/) { + $nametags = ''; + } + } + if (!exists $comment_numbers{$::form{mypage}}) { # Tnx:Birgus-Latro + $comment_numbers{$::form{mypage}} = 0; + } + $comment_no = ++$comment_numbers{$::form{mypage}}; + my $escapedmypage = &htmlspecialchars($::form{mypage}); + my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker); + return <<"EOD"; +<form action="$::script" method="post"> + <div> + <input type="hidden" name="comment_no" value="$comment_no" /> + <input type="hidden" name="cmd" value="comment" /> + <input type="hidden" name="mypage" value="$escapedmypage" /> + <input type="hidden" name="myConflictChecker" value="$conflictchecker" /> + <input type="hidden" name="mytouch" value="on" /> + <input type="hidden" name="nodate" value="$nodate" /> + <input type="hidden" name="above" value="$above" /> + $nametags + <input type="text" name="mymsg" value="" size="40" /> + <input type="submit" value="$::resource{commentbutton}" /> + </div> +</form> +EOD +} +1; Index: PyukiWiki-Nekyo/019/plugin/contents.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/contents.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/contents.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,51 @@ +## +# ページ中の見出し一覧を表示する。 +# :書式| +# #contents +# pyukiwiki独自拡張~ +# #contents([ページ]) +# で指定のページの見出し一覧を表示する。 + +# @author nekyo. +# @version 1.01 +# @license:GPL +use strict; + +sub plugin_contents_convert { + my @args = &func_get_args(shift); + my $page; + if (@args > 0) { + $page = $args[0]; + $::pushedpage = $page; + } else { + $page = $::form{mypage}; + } + my ($txt) = $::database{$page}; + my (@txt) = split(/\r?\n/, $txt); + my $tocnum = 0; + my (@tocsaved, @tocresult); + my $title; + my $nametag = ($::IsMenu == 1) ? "m" : "i"; + + foreach (@txt) { + chomp; + if (/^(\*{1,5})(.+)/) { + &back_push('ul', length($1), \@tocsaved, \@tocresult); + $title = &::inline($2); + $title =~ s/<[^>]+>//g; + push(@tocresult, qq(<li><a href="?) + # &::encode($::form{mypage}) + . &::rawurlencode($::pushedpage eq '' ? $::form{mypage} : $::pushedpage) + . qq(#$nametag$tocnum">$title</a></li>\n)); + $tocnum++; + } + } + push(@tocresult, splice(@tocsaved)); + my $body = <<EOD; +<div class="contents"> +<a id="contents_1"></a> +EOD + $body .= join("\n", @tocresult) . "</div>\n"; + return $body; +} +1; Index: PyukiWiki-Nekyo/019/plugin/counter.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/counter.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/counter.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,121 @@ +## +# ページカウンタを設置する。 +# :書式| +# #counter +# &counter([total|today|yesterday]); +# -total - 総参照回数。(デフォルト) +# -today - 本日参照回数。 +# -yesterday − 昨日参照回数 +# @author nekyo. +# @version 0.0.2 + +sub plugin_counter_inline { + my $arg = shift; + my %counter = plugin_counter_get_count($::form{mypage}); + my $count; + if ($arg =~/(today|yesterday)/i) { + $count = $counter{$arg}; + } else { + $count = $counter{'total'} + } + return " $count"; +} + +sub plugin_counter_convert { + my %counter = plugin_counter_get_count($::form{mypage}); + return <<"EOD"; +<div class="counter"> +Counter: $counter{'total'}, +today: $counter{'today'}, +yesterday: $counter{'yesterday'} +</div> +EOD +} + +sub plugin_counter_get_count { + my $page = shift; + + my ($mday, $mon, $year) = (localtime(time))[3..5]; + $year += 1900; + $mon += 1; + my $date = "$year/$mon/$mday"; + + my %default = ( + 'total' => 0, + 'date' => $date, + 'today' => 0, + 'yesterday' => 0, + 'ip' => '' + ); + + my %counter = %default; + + if (!&is_exist_page($page)) { + return %default; + } + + $page =~ s/(\C)/unpack('H2', $1)/eg; + + my $file = $::counter_dir . "/" . $page . $::counter_ext; + + my @keys = keys(%default); + my $modify = 0; + if (-e $file) { + open(FILE, "+<$file") or return "Counter Conflict.<br />\n"; + flock(FILE, 2); + $_ = <FILE>; + chomp; + $counter{'total'} = $_; + $_ = <FILE>; + chomp; + $counter{'date'} = $_; + $_ = <FILE>; + chomp; + $counter{'today'} = $_; + $_ = <FILE>; + chomp; + $counter{'yesterday'} = $_; + $_ = <FILE>; + chomp; + $counter{'ip'} = $_; + } else { + open(FILE, ">$file") or return "Counter Conflict.<br />\n"; + flock(FILE, 2); + $counter{'date'} = ""; + } + + if ($counter{'date'} ne $default{'date'}) { + $modify = 1; + $counter{'ip'} = $ENV{'REMOTE_ADDR'}; + $counter{'date'} = $default{'date'}; + $counter{'yesterday'} = $counter{'today'}; + $counter{'today'} = 1; + $counter{'total'}++; + } elsif ($counter{'ip'} ne $ENV{'REMOTE_ADDR'}) { + $modify = 1; + $counter{'ip'} = $ENV{'REMOTE_ADDR'}; + $counter{'today'}++; + $counter{'total'}++; + } + + if ($modify == 1) { + if (FILE) { + truncate(FILE, 0); # + seek(FILE, 0, 0); # + } else { + open(FILE, ">$file") or return "Counter Conflict.<br />\n"; + flock(FILE, 2); + } + print FILE $counter{'total'} . "\n"; + print FILE $counter{'date'} . "\n"; + print FILE $counter{'today'} . "\n"; + print FILE $counter{'yesterday'} . "\n"; + print FILE $counter{'ip'} . "\n"; + } + if (FILE) { + flock(FILE, 8); + close(FILE); + } + return %counter; +} +1; Index: PyukiWiki-Nekyo/019/plugin/diff.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/diff.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/diff.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,43 @@ +## +# 指定ページの現内容と最後のバックアップ状態との差分を表示する。 +# :書式| +# ?cmd=diff&mypage=ページ名 +# -ページ名はエンコードされている必要がある。 + +# diff Plugin +# diff.inc.pl +# Copyright(c) 2004 Nekyo. +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) +# v0.2 BugFix $diffbase -> $::diffbase Tnx! Mr.Yashigani-modoki. +# v0.1 Proto +# 1TAB=4Spaces + +sub plugin_diff_action { + if (not &is_editable($::form{mypage})) { + &do_read; + &close_db; + exit; + } + &open_diff; + my $title = $::form{mypage}; + $_ = &htmlspecialchars($::diffbase{$::form{mypage}}); + &close_diff; + my $body = qq(<h3>$::resource{difftitle}</h3>); + $body .= qq($::resource{diffnotice}); + $body .= qq(<pre class="diff">); + foreach (split(/\n/, $_)) { + if (/^\+(.*)/) { + $body .= qq(<b class="added">$1</b>\n); + } elsif (/^\-(.*)/) { + $body .= qq(<s class="deleted">$1</s>\n); + } elsif (/^\=(.*)/) { + $body .= qq(<span class="same">$1</span>\n); + } else { + $body .= qq|??? $_\n|; + } + } + $body .= qq(</pre>); + $body .= qq(<hr>); + return ('msg' => $title, 'body' => $body); +} +1; Index: PyukiWiki-Nekyo/019/plugin/edit.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/edit.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/edit.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,115 @@ +## +# ページ編集。 +# :書式| +# ?cmd=edit&mypage=ページ名 +# ページ名はエンコードされていなければならない。 + +# @auther Nekyo (http://nekyo.hp.infoseek.co.jp) +# @license: GPL2 and/or Artistic or each later version. +# 1TAB=4Spaces +use strict; + +sub plugin_edit_action { + my ($page) = &unarmor_name(&armor_name($::form{mypage})); + my $body; + if (not &is_editable($page)) { + $body .= qq(<p><strong>$::resource{cantchange}</strong></p>); + } elsif (&is_frozen($page)) { + $body .= qq(<p><strong>$::resource{cantchange}</strong></p>); + } else { + $body .= &editform($::database{$page}, + &get_info($page, $::info_ConflictChecker), admin=>0); + } + return ('msg'=>$page, 'body'=>$body); +} + +sub editform { + my ($mymsg, $conflictchecker, %mode) = @_; + my $frozen = &is_frozen($::form{mypage}); + my $body = ''; + + if ($::form{mypreview}) { + if ($::form{mymsg}) { + unless ($mode{conflict}) { + $body .= qq(<h3>$::resource{previewtitle}</h3>\n); + $body .= qq($::resource{previewnotice}\n); + $body .= qq(<div class="preview">\n); + $body .= &text_to_html($::form{mymsg}, toc=>1); + $body .= qq(</div>\n); + } + } else { + $body .= qq($::resource{previewempty}); + } + $mymsg = $::form{mymsg}; + } + $mymsg =~ s/\n?#freeze\r?\n//g; + $mymsg = &htmlspecialchars($mymsg); + + my $edit = $mode{admin} ? 'adminedit' : 'edit'; + my $escapedmypage = &htmlspecialchars($::form{mypage}); + my $escapedmypassword = &htmlspecialchars($::form{mypassword}); + if ($::extend_edit) { + $body .= <<"EOD"; +<div> +<a href="javascript:insTag('\\'\\'','\\'\\'','bold');"><b>B</b></a> +<a href="javascript:insTag('\\'\\'\\'','\\'\\'\\'','italic');"><i>I</i></a> +<a href="javascript:insTag('%%%','%%%','underline');"><u>U</u></a> +<a href="javascript:insTag('%%','%%','delline');"><del>D</del></a> +<a href="javascript:insTag('\\n-','','list');"> +<img src="$::image_dir/list.gif" alt="list" border="0" vspace="0" + hspace="1"></a> +<a href="javascript:insTag('\\n+','','list');"> +<img src="$::image_dir/numbered.gif" alt="list" border="0" vspace="0" + hspace="1"></a> +<a href="javascript:insTag('\\nCENTER:','\\n','centering');"> +<img src="$::image_dir/center.gif" alt="center" border="0" vspace="0" + hspace="1"></a> +<a href="javascript:insTag('\\nLEFT:','\\n','left');"> +<img src="$::image_dir/left_just.gif" alt="left" border="0" vspace="0" + hspace="1"></a> +<a href="javascript:insTag('\\nRIGHT:','\\n','right');"> +<img src="$::image_dir/right_just.gif" alt="right" border="0" vspace="0" + hspace="1"></a> +<a href="javascript:insTag('\\n*','','title');"><b>H</b></a> +<a href="javascript:insTag('[[',']]','wikipage');">[[]]</a> +<a href="javascript:insTag('','~\\n','');"><br></a> +<a href="javascript:insTag('\\n----\\n','','');"><b>--</b></a> +</div> +EOD + } + $body .= <<"EOD"; +<form action="$::script" method="post" id="editform" name="editform"> + @{[ $mode{admin} ? qq($::resource{frozenpassword} <input type="password" name="mypassword" value="$escapedmypassword" size="10"><br>) : "" ]} + <input type="hidden" name="myConflictChecker" value="$conflictchecker"> + <input type="hidden" name="mypage" value="$escapedmypage"> + <textarea cols="$::cols" rows="$::rows" name="mymsg">$mymsg</textarea><br /> +@{[ + $mode{admin} ? + qq( + <input type="radio" name="myfrozen" value="1" @{[$frozen ? qq(checked="checked") : ""]}>$::resource{frozenbutton} + <input type="radio" name="myfrozen" value="0" @{[$frozen ? "" : qq(checked="checked")]}>$::resource{notfrozenbutton}<br>) + : "" +]} +@{[$mode{conflict} ? '' : + qq( + <input type="submit" name="mypreview_$edit" value="$::resource{previewbutton}"> + <input type="submit" name="mypreview_write" value="$::resource{savebutton}"> + <input type="checkbox" name="mytouch" value="on" checked="checked">$::resource{touch} + <input type="button" value="$::resource{cancel}" onClick="JavaScript:location.href='$::script?$::form{mypage}'"> +)]} +</form> +EOD + unless ($mode{conflict}) { + # Show the format rule. + #open(FILE, $::file_format) or &print_error("($::file_format)"); + #my $content = join('', <FILE>); + #&code_convert(\$content, $::kanjicode); + #close(FILE); + #$body .= &text_to_html($content, toc=>0); + $body .= &text_to_html($::database{$::rule_page}, toc=>0); + + } + return $body; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/facemark.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/facemark.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/facemark.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,27 @@ +## +# フェイスマークをイメージに変換する。(pyukiwiki独自プラグイン)~ +# :書式| +# #facemark(フェイスマーク) +# &facemark(フェイスマーク); +# フェイスマーク機能を分離してプラグイン化しました。~ +# このプラグインを改造することで、フェイスマークを拡張できます。~ +# PyukiWiki Classic v0.1.7 or later +use strict; + +sub plugin_facemark_inline { + return &plugin_facemark_convert(shift); +} + +sub plugin_facemark_convert { + my $line = shift; + $line =~ s!\s(\:\)|\(\^\^\))! <img src="$::image_dir/face/smile.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s(\:D|\(\^-\^\))! <img src="$::image_dir/face/bigsmile.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s(\:p|\:d)! <img src="$::image_dir/face/huh.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s(XD|X\(|\(\.\.;)! <img src="$::image_dir/face/oh.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s(;\)|\(\^_-\))! <img src="$::image_dir/face/wink.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s(;\(|\:\(|\(--;\))! <img src="$::image_dir/face/sad.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!&(heart);!<img src="$::image_dir/face/heart.png" alt="$1" width="15" height="15"/>!g; + $line =~ s!\s\(\^\^;\)?! <img src="$::image_dir/face/worried.png" alt="$1" width="15" height="15"/>!g; + return $line; +} +1; Index: PyukiWiki-Nekyo/019/plugin/img.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/img.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/img.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,51 @@ +## +# 画像を表示する。 +# :書式| +# #img(画像のURI[[,書式],altコメント]) +# 書式:r,right(右寄せ) or l,left(左寄せ) or module(index.cgi からの呼び出し) +# or それ以外(クリア)~ +# v0.1.6b よりこの関数を index.cgi の img 変換でも呼び出すよう修正。(必須) + +###################################################################### +# img.inc.pl +# PyukiClassic v 0.1.6b or laiter +# Author: Nekyo +# Copyright (C) 2004-2006 by Nekyo. +# http://nekyo.hp.infoseek.co.jp/ +# License: GPL2 +###################################################################### +use strict; + +sub plugin_img_convert { + my ($uri, $align, $alt) = split(/,/, shift); + $uri = &trim($uri); + $align = &trim($align); + $alt = &trim($alt); + my $module = 0; + my $res = ''; + + if ($align =~ /^(r|right)/i) { + $align = 'right'; + } elsif ($align =~ /^(l|left)/i) { + $align = 'left'; + } elsif ($align =~ /^module$/i) { + $module = 1; + } else { + return '<div style="clear:both"></div>'; + } +# if ($uri =~ /^(https?|ftp):/) { + if ($uri =~ /\.(gif|png|jpe?g)$/i) { + if ($module == 1) { + # 必要であれば、この部分を拡張する。 + $res .= "<a href=\"$uri\"><img src=\"$uri\" /></a>\n"; + } else { + $res .= "<div style=\"float:$align; padding:.5em 1.5em .5em 1.5em;\"><img src=\"$uri\""; + $res .= " alt=\"$alt\"" if ($alt ne ''); + $res .= " /></div>\n"; + } + } +# } + return $res; +} +1; +__END__ Index: PyukiWiki-Nekyo/019/plugin/include.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/include.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/include.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,25 @@ +## +# 記述した位置に引数で指定したページを表示する。 +# :書式| +# #include(ページ名) +sub plugin_include_convert { + my $page = shift; + if ($page eq '') { return ''; } + my $body = ''; + if (&is_exist_page($page)) { + my $rawcontent = $::database{$page}; + $body = &text_to_html($rawcontent, toc=>1); + my $cookedpage = &encode($page); + my $link = "<a href=\"$::script?$cookedpage\">$page</a>"; + if ($::form{mypage} eq $::MenuBar) { + $body = <<"EOD"; +<span align="center"><h5 class="side_label">$link</h5></span> +<small>$body</small> +EOD + } else { + $body = "<h1>$link</h1>\n$body\n"; + } + } + return $body; +} +1; Index: PyukiWiki-Nekyo/019/plugin/index.html diff -u /dev/null PyukiWiki-Nekyo/019/plugin/index.html:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/index.html Sun Mar 18 02:14:52 2012 @@ -0,0 +1 @@ +data files are placed here. Index: PyukiWiki-Nekyo/019/plugin/list.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/list.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/list.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,46 @@ +## +# ページ一覧を表示。 +# :書式| +# ?cmd=list + +# Copyright(c) 2004 Nekyo. +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) +# v0.2 non_list +# v0.1 + +sub plugin_list_action { + my $navi = qq(<div id="body"><div id="top" style="text-align:center">); + my $body = qq(</div>); + my $prev = ''; + my $char = ''; + my $idx = 1; + my $page_num = 0; + + foreach my $page (sort keys %::database) { + next if ($page =~ $::non_list); + $char = substr($page, 0, 1); + if (!($char =~ /[a-zA-Z0-9]/)) { + $char = "日本語"; + } + if ($prev ne $char) { + if ($prev ne '') { + $navi .= " |\n"; + $body .= " </ul>\n </li>\n</ul>\n"; + } + $prev = $char; + $navi .= qq(<a id="top_$idx" href="#head_$idx"><strong>$prev</strong></a>); + $body .= <<"EOD"; +<ul> + <li><a id="head_$idx" href="#top_$idx"><strong>$prev</strong></a> + <ul> +EOD + $idx++; + } + $body .= qq(<li><a href="$::script?@{[&encode($page)]}">@{[&htmlspecialchars($page)]}</a>@{[&htmlspecialchars(&get_subjectline($page))]}</li>\n); + $page_num++; + } + $body .= qq(</li></ul>Total:) . $page_num . qq( Pages); + + return ('msg' => $::IndexPage, 'body' => $navi . $body); +} +1; Index: PyukiWiki-Nekyo/019/plugin/lookup.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/lookup.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/lookup.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,56 @@ +## +# 記述位置に入力欄とボタンと表示し、ボタンを押下するとラベルと入力値から生成されたURLへジャンプする。 +# URI生成ルールはInterWikiと同じ。 +# :書式| +# #lookup(ラベル,ボタン名,入力値) +# @author Nekyo. +use strict; + +sub plugin_lookup_convert { + my @args = split(/,/, shift); +# if (@args < 2) { return ''; } + my $iwn = &htmlspecialchars(&trim($args[0])); + my $btn = &htmlspecialchars(&trim($args[1])); + + my $default = ''; + if (@args > 2) { + $default = &htmlspecialchars(trim($args[2])); + } + my $s_page = &htmlspecialchars($::form{mypage}); + my $ret = <<"EOD"; +<form action="$::script" method="post"> + <div> + <input type="hidden" name="cmd" value="lookup" /> + <input type="hidden" name="inter" value="$iwn" /> + $iwn: + <input type="text" name="page" size="30" value="$default" /> + <input type="submit" value="$btn" /> + </div> +</form> +EOD + return $ret; +} + +sub plugin_lookup_action { + my $text = &::rawurldecode($::form{page}); # 入力テキスト + + my ($code, $uri) = %{$::interwiki2{$::form{inter}}}; + if ($uri) { # pukiコンパチ + if ($uri =~ /\$1/) { + $uri =~ s/\$1/&interwiki_convert($code, $text)/e; + } else { + $uri .= &interwiki_convert($code, $text); + } + } else { # yukiコンパチ + $uri = $::interwiki{$::form{inter}}; + if ($uri) { + $uri =~ s/\b(utf8|euc|sjis|ykwk|yw|asis)\(\$1\)/&interwiki_convert($1, $text)/e; + } + } + if ($uri) { + print("Location: $uri\n\n"); + exit; + } + return ""; +} +1; Index: PyukiWiki-Nekyo/019/plugin/ls2.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ls2.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/ls2.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,75 @@ +########################/ +# 配下のページの見出し(*,**,***)の一覧を表示する +# :書式| +# #ls2(パターン[,パラメータ]) +# -パターン(最初に指定) +# -title:見出しの一覧を表示する +# -reverse:ページの並び順を反転し、降順にする + +# 以下は未対応 +# -include:インクルードしているページの見出しを再帰的に列挙する +# -link:actionプラグインを呼び出すリンクを表示 +# -compact: + +# @author Nekyo. +# @version v0.1 2005/04/01 encode バグ Fix Tnx:Junichiさん +# @version v0.0 2004/11/01 簡易版 title,reverse 対応、その他は非対応 +# @see based on ls2.inc.php by arino + +use strict; + +sub plugin_ls2_convert +{ + my $prefix = ''; + my @args = split(/,/, shift); + my $title = 0; + my $reverse = 0; + my (@pages, $txt, @txt, $tocnum); + my $body = ''; + + if (@args > 0) { + $prefix = shift(@args); + foreach my $arg (@args) { + if (lc $arg eq "title") { + $title = 1; + } elsif (lc $arg eq "reverse") { + $reverse = 1; + } + } + } + $prefix = $::form{mypage} . "/" if ($prefix eq ''); + + foreach my $page (sort keys %::database) { + push(@pages, $page) if ($page =~ /^$prefix/); + } + @pages = reverse(@pages) if ($reverse); + foreach my $page (@pages) { + $body .= <<"EOD"; +<li><a id ="list_1" href="$::script?cmd=read&mypage=@{[&encode($page)]}" title="$page">$page</a></li> +EOD + if ($title) { + $txt = $::database{$page}; + @txt = split(/\r?\n/, $txt); + $tocnum = 0; + my (@tocsaved, @tocresult); + foreach (@txt) { + chomp; + if (/^(\*{1,3})(.+)/) { + &back_push('ul', length($1), \@tocsaved, \@tocresult); + push(@tocresult, qq( <li><a href="$::script?$page#i$tocnum">@{[&escape($2)]}</a></li>\n)); + $tocnum++; + } + } + push(@tocresult, splice(@tocsaved)); + $body .= join("\n", @tocresult); + } + } + if ($body ne '') { + return << "EOD"; +<ul class="list1" style="padding-left:16px;margin-left:16px">$body</ul> +EOD + } + return "No page of a low rank layer in '$prefix'<br />\n"; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/new.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/new.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/new.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,26 @@ +## +# 日時が規定の日付以内の場合にNewと表示する。 +# :書式| +# &new(日時); +# 5日以内の場合に New、1日以内の場合に New! を表示する。 +# @author Nekyo. for PyukiWiki(http://nekyo.hp.infoseek.co.jp) + +sub plugin_new_inline { + my $date = shift; + return '' if ($date eq ''); + + my $retval = $date; + my ($mday, $mon, $year) = (localtime())[3..5]; + + my $now = &mktime(0, 0, 0, $mon + 1, $mday, $year + 1900); + $date =~ /(\d+)-(\d+)-(\d+)/; + my $past = &mktime(0, 0, 0, $2, $3, $1); + + if (($now - $past) <= 1*60*60*24) { + $retval .= ' <span class="new1">New!</span>'; + } elsif (($now - $past) <= 5*60*60*24) { + $retval .= ' <span class="new5">New</span>'; + } + return '<span class="comment_date">' . $retval . '</span>'; +} +1; Index: PyukiWiki-Nekyo/019/plugin/newpage.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/newpage.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/newpage.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,25 @@ +## +# ページを新規作成する。 +# :書式| +# ?plugin=newpage + +############################################################ +# newpage プラグイン +# newpage.inc.pl +# Copyright(c) 2004 Nekyo. +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) +# +# 1TAB=4Spaces + +sub plugin_newpage_action { + my $body =<<"EOD"; +<form action="$::script" method="post"> + <input type="hidden" name="cmd" value="edit"> + $::resource{newpagename} + <input type="text" name="mypage" value="" size="20"> + <input type="submit" value="$::resource{createbutton}"><br> +</form> +EOD + return ('msg' => $::CreatePage, 'body' => $body); +} +1; Index: PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/nofollow.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,13 @@ +## +# pukiwiki互換用のダミー関数 +# @author Nanami <nanam****@daiba*****> + +sub plugin_nofollow_inline { + return ' '; +} + +sub plugin_nofollow_convert { + return ' '; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/norelated.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/norelated.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/norelated.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,13 @@ +## +# pukiwiki互換用のダミー関数 +# @author Nanami <nanam****@daiba*****> + +sub plugin_norelated_inline { + return ' '; +} + +sub plugin_norelated_convert { + return ' '; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/online.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/online.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/online.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,50 @@ +## +# 現在参照中のおおよそのユーザー数を表示する。 +# :書式| +# #online +# &online; +# @author Nekyo. +# @version v0.2 2004/12/06 問題があったので、排他lockなし版 +use strict; + +my $timeout = 300; + +sub plugin_online_inline { + return &plugin_online_convert; +} + +sub plugin_online_convert { + my $file = $::counter_dir . '/user.dat'; + my $addr = $ENV{'REMOTE_ADDR'}; + + my @usr_arr = (); + if (-e $file) { + open(FILE, "<$file"); + @usr_arr = <FILE>; + close(FILE); + } + + if (!open(FILE, ">$file")) { + return 'online: "COUNTER_DIR/' . $file . '" not writable'; + } +# flock(FILE, 2); # lock WriteBlock + my $now = time(); + my ($ip_addr, $tim_stmp); + foreach (@usr_arr) { + chomp; + ($ip_addr, $tim_stmp) = split(/|/); + + if (($now - $tim_stmp) < $timeout and $ip_addr ne $addr) { + print FILE "$ip_addr|$tim_stmp\n"; + } + } + print FILE "$addr|$now\n"; +# flock(FILE, 8); # unlock + close(FILE); + + open(FILE, "<$file"); + @usr_arr = <FILE>; + close(FILE); + return @usr_arr; +} +1; Index: PyukiWiki-Nekyo/019/plugin/recent.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/recent.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/recent.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,85 @@ +############################################################ +# 最近更新されたページ一覧を表示。省略時件数は10件。 +# :書式| +# #recent([件数]) + +# @author Copyright(c) 2004 Nekyo. +# v 0.0.3 : + ページ名は一覧に表示しない。 +# v 0.0.2 ダイナミック生成から RecentChanges を除外した。 +# v 0.0.1 Actionによりダイナミック生成機能追加 +# v 0.0.0 +# for PyukiWiki(http://nekyo.hp.infoseek.co.jp) + +## +# 時間を返す +# @param unix time +# @return yyyy-mm-dd 形式 +sub get_date { + my ($time) = @_; + my ($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime($time); + $year += 1900; + $mon++; + $mon = "0$mon" if $mon < 10; + $day = "0$day" if $day < 10; + return "$year-$mon-$day"; +} + +## +# 最終更新の一覧を表示 +# @return 最終更新の一覧 +sub plugin_recent_action { + my $update; + my %rclist; + my $atime; + foreach my $page (sort keys %::database) { + $atime = (stat($::data_dir . "/" . &::dbmname($page) . ".txt"))[9]; # statで最終更新日付を取得 + $rclist{$page} = $atime; + } + my @updates; + foreach my $page (sort { $rclist{$b} <=> $rclist{$a} } keys %rclist) { + next if ($page eq ''); + $atime = $rclist{$page}; + $update = "- @{[&get_date($atime)]} @{[&armor_name($page)]}"; + push(@updates, $update); + } + splice(@updates, $::maxrecent + 1); + return ('msg' => $::resource{recentchangesbutton}, 'body' => &::text_to_html(join("\n", @updates))); +} + +## +# 最終更新の一覧を表示 +# @param 表示数(省略時:10) +# @return 最終更新の一覧 +sub plugin_recent_convert { + my $limit = shift; + $limit = 10 if ($limit eq ''); + my $recentchanges = $::cache_dir . '/recent.dat'; + + open(fp, "<$recentchanges"); + @lines = <fp>; + close(fp); + + my $count = 0; + my $date = ""; + my $_date; + my $out = ""; + foreach (@lines) { + last if ($count >= $limit); + /(\d+)\t(\S+)/; # date format. + next if ($2 =~ /\[*:/); # 先頭が : の場合は表示しない。 + + $_date = get_date($1); + if ($2) { + if ($date ne $_date) { + $out .= "</ul>\n" if ($date ne ''); + $date = $_date; + $out .= "<strong>$date</strong><ul class=\"recent_list\">\n"; + } + $out .= "<li>" . &make_link($2) . "</li>\n"; + $count++; + } + } + $out .= "</ul>\n" if ($date ne ''); + return $out; +} +1; Index: PyukiWiki-Nekyo/019/plugin/ref.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ref.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/ref.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,260 @@ +###################################################### +# ページに添付されたファイルを展開する +# URIを展開する +# :書式| +# #ref(ファイル名[,ページ][,パラメータ][,title]) +# -ファイル名 - 添付ファイル名、またはURI。 +# 'ページ名/添付ファイル名'を指定すると、そのページの添付ファイルを参照。 +# -ページ - ファイルを添付したページ名(省略可)~ +# -パラメータ +# --Left|Center|Right:横の位置合わせ +# --Wrap|Nowrap:テーブルタグで囲む/囲まない +# -Around - テキストの回り込み +# -noicon - アイコンを表示しない +# -nolink - 元ファイルへのリンクを張らない +# -noimg - 画像を展開しない +# -zoom - 縦横比を保持する +# -999x999 - サイズを指定(幅x高さ) +# -999% - サイズを指定(拡大率) +# -その他 - imgのalt/hrefのtitleとして使用~ +# ページ名やパラメータに見える文字列を使用するときは、#ref(hoge.png,,zoom)のように +# タイトルの前にカンマを余分に入れる +use strict; + +my $file_icon = '<img src="' + . $::image_dir + . '/file.png" width="20" height="20" alt="file" style="border-width:0px" />'; + +# default alignment +my $ref_default_align = 'left'; # 'left','center','right' + +# force wrap on default +my $REF_WRAP_TABLE = 0; # 1,0 + +sub plugin_ref_inline +{ + my ($args) = @_; + my @args = split(/,/, $args); + return 'no argument(s).' if (@args < 1); #エラーチェック + my %params = &plugin_ref_body($args, $::form{mypage}); + return ($params{_error}) ? $params{_error} : $params{_body}; +} + +sub plugin_ref_convert +{ + my ($args) = @_; + my @args = split(/,/, $args); + return '<p>no argument(s).</p>' if (@args < 1); #エラーチェック + my %params = &plugin_ref_body($args, $::form{mypage}); + + # divで包む + my $style; + if ($params{around}) { + $style = ($params{_align} eq 'right') ? 'float:right' : 'float:left'; + } else { + $style = "text-align:$params{_align}"; + } + return "<div class=\"img_margin\" style=\"$style\">$params{_body}</div>\n"; +} + +sub getimagesize +{ + my ($imgfile, $datafile) = @_; + my $width = 0; + my $height = 0; + my ($data, $m, $c, $l); + + if (!$datafile) { + $datafile = $imgfile; + } + + if ($imgfile =~ /\.jpe?g$/i) { + open(FILE, "$datafile") || return (0, 0); + binmode FILE; + read(FILE, $data, 2); + while (1) { # read Exif Blocks + read(FILE, $data, 4); + ($m, $c, $l) = unpack("a a n", $data); + if ($m ne "\xFF") { + $width = $height = 0; + last; + } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { + read(FILE, $data, 5); + ($height, $width) = unpack("xnn", $data); + last; + } else { + read(FILE, $data, ($l - 2)); + } + } + close(FILE); + } elsif ($imgfile =~ /\.gif$/i) { + open(FILE, "$datafile") || return (0,0); + binmode(FILE); + sysread(FILE, $data, 10); + close(FILE); + $data = substr($data, -4) if ($data =~ /^GIF/); + + $width = unpack("v", substr($data, 0, 2)); + $height = unpack("v", substr($data, 2, 2)); + } elsif ($imgfile =~ /\.png$/i) { + open(FILE, "$datafile") || return (0,0); + binmode(FILE); + read(FILE, $data, 24); + close(FILE); + + $width = unpack("N", substr($data, 16, 20)); + $height = unpack("N", substr($data, 20, 24)); + } + return ($width, $height); +} + +sub plugin_ref_body +{ + my ($args) = @_; + my @args = split(/,/, $args); + my $name = &trim(shift(@args)); + my $page; + +# my %params = { +# 'left' => 0, # 左寄せ +# 'center' => 0, # 中央寄せ +# 'right' => 0, # 右寄せ +# 'wrap' => 0, # TABLEで囲む +# 'nowrap' => 0, # TABLEで囲まない +# 'around' => 0, # 回り込み +# 'noicon' => 0, # アイコンを表示しない +# 'nolink' => 0, # 元ファイルへのリンクを張らない +# 'noimg' => 0, # 画像を展開しない +# 'zoom' => 0, # 縦横比を保持する +# '_size' => 0, # (サイズ指定あり) +# '_w' => 0, # (幅) +# '_h' => 0, # (高さ) +# '_%' => 0, # (拡大率) +# '_args' => '', +# '_done' => 0, +# '_error' => '' +# }; + + my (%params, $_title, $_backup); + foreach (@args) { + $_backup = $_; + $_ = &trim($_); + if (/^([0-9]+)x([0-9]+)$/i) { # size pixcel + $params{_size} = 1; + $params{_w} = $1; + $params{_h} = $2; + } elsif (/^([0-9.]+)%$/i) { # size % + $params{_par} = $1; + } elsif (/(left|center|right|wrap|nowrap|around|noicon|nolink|noimg|zoom)/i) { # align + $params{lc $_} = 1; + } else { + if (!$page and &is_exist_page($_)) { + $page = $_; + } else { + $_title = $_backup; + } + } + } + + my ($url, $url2, $title, $is_image, $info); + my $width = 0; + my $height = 0; + + if ($name =~ /^(https?|ftp|news)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]*)$/) { #URL + $url = $url2 = &htmlspecialchars($name); + $title = &htmlspecialchars(($name =~ '/([^\/]+)$/') ? $1 : $url); + $is_image = (!$params{noimg} and $name =~ /\.(gif|png|jpe?g)$/i); + } else { # 添付ファイル + if (!-d "$::upload_dir/") { + $params{_error} = 'no $::upload_dir.'; + return %params; + } + # ページ指定のチェック + $page = $::form{mypage} if (!$page); + if ($name =~ /^(.+)\/([^\/]+)$/) { + $1 .= '/' if ($1 eq '.' or $1 eq '..'); + $page = get_fullname($1, $page); + $name = $2; + } + $title = &htmlspecialchars($name); + my $file = "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name); + # my $file2 = "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name); + if (!-e $file) { + $params{_error} = 'file not found.' . $file; + return %params; + } + $is_image = (!$params{noimg} and $name =~ /\.(gif|png|jpe?g)$/i); + + $url = "$::script?cmd=attach&pcmd=open" + . "&file=$name&mypage=$page&refer=$page"; + if ($is_image) { + ($width, $height) = getimagesize($name, $file); + $url2 = $url; + # $url = $file2; + $url =($::download_dir ne '') ? "$::download_dir/" : "$::upload_dir/" . &::dbmname($page) . '_' . &::dbmname($name); + } else { + my ($sec, $min, $hour, $day, $mon, $year) = localtime((stat($file))[10]); + $info = sprintf("%d/%02d/%02d %02d:%02d:%02d %01.1fK", + $year + 1900, $mon + 1, $day, $hour, $min, $sec, + (-s $file) / 1000 + ); + } + } + + # 画像サイズ調整 + if ($is_image) { + # 指定されたサイズを使用する + if ($params{_size}) { + if ($width == 0 and $height == 0) { + $width = $params{_w}; + $height = $params{_h}; + } elsif ($params{zoom}) { + my $_w = $params{_w} ? $width / $params{_w} : 0; + my $_h = $params{_h} ? $height / $params{_h} : 0; + my $zoom = ($_w > $_h) ? $_w : $_h; + if ($zoom != 0) { + $width = ($width / $zoom); + $height = ($height / $zoom); + } + } else { + $width = $params{_w} ? $params{_w} : $width; + $height = $params{_h} ? $params{_h} : $height; + } + } + if ($params{_par}) { + $width = ($width * $params{_par} / 100); + $height = ($height * $params{_par} / 100); + } + if ($width and $height) { + $info = "width=\"$width\" height=\"$height\" "; + } + } + + #アラインメント判定 + if ($params{right}) { + $params{_align} = 'right'; + } elsif ($params{left}) { + $params{_align} = 'left'; + } elsif ($params{center}) { + $params{_align} = 'center'; + } else { + $params{_align} = $ref_default_align; + } + + $title = $_title if ($_title); + + # ファイル種別判定 + if ($is_image) { # 画像 + my $_url = "<img src=\"$url\" alt=\"$title\" title=\"$title\" $info/>"; + if (!$params{nolink} and $url2) { + $_url = "<a href=\"$url2\" title=\"$title\">$_url</a>"; + } + $params{_body} = $_url; + } else { # 通常ファイル + my $icon = $params{noicon} ? '' : $file_icon; + $params{_body} = "<a href=\"$url\" title=\"$info\">$icon$title</a>\n"; + } + return %params; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/rss10.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/rss10.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/rss10.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,64 @@ +## +# 最新更新をRSS(RDF Site Summary)に変換して出力する。 +# :書式| +# ?cmd=rss10 + +# @author Nekyo. +# v0.0.2 2005/03/11 Add dc:date + +sub plugin_rss10_action { + my $recentchanges = $::database{$::RecentChanges}; + my $count = 0; + + print <<"EOD"; +Content-type: text/xml + +<?xml version="1.0" encoding="$::charset"?> + <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <channel rdf:about="$::modifier_rss_link"> + <title>$::modifier_rss_title</title> + <link>$::modifier_rss_link</link> + <discription>$::modifier_rss_description</discription> + <items> + <rdf:Seq> +EOD + + my $items; + + foreach (split(/\n/, $recentchanges)) { + last if ($count >= 15); + /^\- (\d\d\d\d\-\d\d\-\d\d) \(...\) (\d\d:\d\d:\d\d) (\S+)/; # data format. + my $title = &unarmor_name($3); + my $escaped_title = &htmlspecialchars($title); + my $link = $modifier_rss_link . '?' . &rawurlencode($title); + my $description = $escaped_title . &htmlspecialchars(&get_subjectline($title)); + + print <<"EOD"; + <rdf:li rdf:resource="$link" /> +EOD + + $gmt = ((localtime(time))[2] + (localtime(time))[3] * 24) + - ((gmtime(time))[2] + (gmtime(time))[3] * 24); + my $date = $1 . "T" . $2 . sprintf("%+02d:00", $gmt); + + $items .=<<"EOD"; + <item rdf:about="$link"> + <title>$escaped_title</title> + <link>$link</link> + <discription>$description</discription> + <dc:date>$date</dc:date> + </item> +EOD + $count++; + } + print <<"EOD"; + </rdf:Seq> + </items> + </channel> + $items +</rdf:RDF> +EOD + &close_db; + exit; +} +1; Index: PyukiWiki-Nekyo/019/plugin/ruby.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/ruby.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/ruby.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,17 @@ +## +# 文字列にルビをふる。 +# :書式| +# &ruby(ルビ){ルビをふる文字列}; +# @author Nekyo. +sub plugin_ruby_inline { + @arg = split(/,/, shift); + my $ruby = $arg[0]; + my $body = $arg[1]; + + if ($ruby eq '' or $body eq '') { + return ''; + } + my $s_ruby = &htmlspecialchars($ruby); + return "<ruby><rb>$body</rb><rp>(</rp><rt>$s_ruby</rt><rp>)</rp></ruby>"; +} +1; Index: PyukiWiki-Nekyo/019/plugin/search.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/search.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/search.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,120 @@ +## +# 指定文字列を含むページを検索する。 +# :書式| +# ?cmd=search[パラメータ] +# パラメータに検索条件を指定する。~ +# word − 検索文字列。~ +# type − 'OR' 指定時、OR検索を行う。(省略時はAND検索)~ +# @author Nekyo. +use strict; + +sub search { + my ($word, $type, $base) = @_; + my %found; + my $body = ""; + if ($word) { + my @words = split(/\s+/, $word); + my $total = 0; + if (uc($type) eq 'OR') { + my $firsttime = 1; + foreach my $wd (@words) { + foreach my $page (sort keys %::database) { + if ($base ne '') { + if ($page !~ /^$base/) { + next; + } + } + if (($::database{$page} =~ /\Q$wd\E/i) or ($page =~ /\Q$wd\E/i)) { + $found{$page} = 1; + } + if ($firsttime) { + $total++; + } + } + $firsttime = 0; + } + } else { # AND 検索 + foreach my $page (sort keys %::database) { + + my $exist = 1; + foreach my $wd (@words) { + if (!($::database{$page} =~ /\Q$wd\E/i or $page =~ /\Q$wd\E/i)) { + $exist = 0; + } + } + if ($exist) { + $found{$page} = 1; + } + $total++; + } + } + my $counter = 0; + foreach my $page (sort keys %found) { + $body .= qq|<!-- search result -->\n<ul>| if ($counter == 0); + $body .= qq(<li><a href ="$::script?@{[&::encode($page)]}">@{[&::htmlspecialchars($page)]}</a>@{[&::htmlspecialchars(&::get_subjectline($page))]}</li>); + $counter++; + } + $body .= ($counter == 0) ? $::resource{notfound} : qq|</ul>\n<!-- search end -->|; + # $body .= "$counter / $total <br />\n"; + } + return $body; +} + +sub search_form { + my ($word, $type, @base) = @_; + my $result =<<"EOD"; +<form action="$::script" method="post"> +<div> + <input type="hidden" name="cmd" value="search"> + <input type="text" name="word" value="$word" size="20" /> + <input type="radio" name="type" value="AND" @{[ ($type ne 'OR' ? qq( checked="checked") : qq()) ]} />$::resource{searchand} + <input type="radio" name="type" value="OR" @{[ ($type eq 'OR' ? qq( checked="checked") : qq()) ]}/>$::resource{searchor} + <input type="submit" value="$::resource{searchbutton}" /> +</div> +EOD + if (@base) { + my $first = ' checked'; + foreach my $bs (@base) { + if ($bs) { + $result .= <<"EOD"; + <input type="radio" name="base" value="$bs"$first><strong>$bs</strong>$::resource{search_pages}<br /> +EOD + $first = ''; + } + } + if ($first eq '') { + $result .= <<"EOD"; + <input type="radio" name="base" value=""$first>$::resource{search_all}<br /> +EOD + + + } + } + $result .= "</form>\n"; + return $result; +} + +## +# 条件1, 条件2 ... 条件n +sub plugin_search_convert { + my @arg = split(/,/, shift); + return &search_form('', 'OR', @arg); +} + +## +# PyukiWiki独自機能 +# インラインは機能が違う。検索した一覧を表示する。 +sub plugin_search_inline { + my @arg = split(/,/, shift); + return &search($arg[0], $arg[1]); +} + +sub plugin_search_action { + my $word = &htmlspecialchars($::form{word}); + my $body = &search($word, $::form{type}, $::form{base}); + $body .= &search_form($word, $::form{type}, $::form{base}); + return ('msg'=>$::resource{searchpage}, 'body'=>$body); +} + +1; + Index: PyukiWiki-Nekyo/019/plugin/server.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/server.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/server.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,128 @@ +## +# サーバー情報(サーバー名、サーバーソフトウエア、サーバー管理者)を表示する。 +# :書式| +# #server +# @author Nekyo. +use strict; +package server; + +sub disp { + my ($s) = @_; + + return ($s ? $s : "-"); +} + +sub plugin_block { + return &plugin_inline; +} + +sub plugin_inline +{ + my $useragent = $::ENV{'HTTP_USER_AGENT'}; + my $body =<<"EOD"; +<dl> +<dt>Server Name</dt> +<dd>@{[ $::ENV{'SERVER_NAME'} ]}</dd> +<dt>Server Software</dt> +<dd>@{[ $::ENV{'SERVER_SOFTWARE'} ]}</dd> +<dt>Server Admin</dt> +<dd><a href="mailto:@{[ $::ENV{'SERVER_ADMIN'} ]}">@{[ + $::ENV{'SERVER_ADMIN'} +]}</a></dd> +<dt>User Agent</dt> +<dd>@{[ $useragent ]}</dd> +EOD + if ($useragent =~ /^(J-PHONE|Vodafon|SoftBank)\//) { +# Color:色数 / Display:画面サイズ / GeoCode:位置情報 / Java:Vアプリ対応機種 +# MsName:端末機種名 / Region:利用地域(国内・外) / Smaf:Smaf種別 +# Sound:和音種別 / UID:ユーザID / Copyright:保存・送出・転送可否指定 + $body .=<<"EOD"; +<dt>Color</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_COLOR'}) ]}</dd> +<dt>Display</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_DISPLAY'}) ]}</dd> +<dt>GeoCode</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_GEOCODE'}) ]}</dd> +<dt>Java</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_JAVA'}) ]}</dd> +<dt>MSName</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_MSNAME'}) ]}</dd> +<dt>Region</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_REGION'}) ]}</dd> +<dt>Smaf</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_SMAF'}) ]}</dd> +<dt>Sound</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_SOUND'}) ]}</dd> +<dt>UID</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_UID'}) ]}</dd> +<dt>Copyright</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_JPHONE_COPYRIGHT'}) ]}</dd> +EOD + } elsif ($useragent =~ /UP\.Browser\//) { +# } else { +# HTTP_X_UP_DEVCAP_IMMED_ALERT:does(1) or does not(0) support immediate alerts. +# HTTP_X_UP_DEVCAP_MAX_PDU:maximum packet size supported by device. +# HTTP_X_UP_DEVCAP_GUI:device is(1) or is not(0) using a GUI browser. +# HTTP_X_UP_DEVCAP_SCREENPIXELS / HTTP_X_UP_DEVCAP_SCREENCHARS / HTTP_X_UP_DEVCAP_SCREENDEPTH +# HTTP_X_UP_DEVCAP_MSIZE:pixels of the character,"M" +# HTTP_X_UP_DEVCAP_NUMSOFTKEYS / HTTP_X_UP_DEVCAP_SOFTKEYSIZE +# HTTP_X_UP_DEVCAP_ISCOLOR +# HTTP_X_UP_FAX_ACCEPTS / HTTP_X_UP_FAX_ENCODINGS / HTTP_X_UP_FAX_LIMIT +# HTTP_X_UP_SUBNO +# HTTP_X_UP_UPLINK +# HTTP_X_UP_DEVCAP_SMARTDIALING ?? +#<dt>Accept Language</dt> +#<dd>@{[ &disp($::ENV{'HTTP_ACCEPT_LANGUAGE'}) ]}</dd> +#<dt>Cookie</dt> +#<dd>@{[ &disp($::ENV{'HTTP_COOKIE'}) ]}</dd> +#<dt>Refer</dt> +#<dd>@{[ &disp($::ENV{'HTTP_REFERER'}) ]}</dd> + + $body .=<<"EOD"; +<dt>Immidiate Alerts</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_IMMED_ALERT'}) ]}</dd> +<dt>Max PDU</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_MAX_PDU'}) ]}</dd> +<dt>GUI</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_GUI'}) ]}</dd> +<dt>Screen Pixels</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENPIXELS'}) ]}</dd> +<dt>Screen Chars</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENCHARS'}) ]}</dd> +<dt>Screen Depth</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SCREENDEPTH'}) ]}</dd> +<dt>M Size</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_MSIZE'}) ]}</dd> +<dt>Num Softkeys</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_NUMSOFTKEYS'}) ]}</dd> +<dt>Softkey Size</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_SOFTKEYSIZE'}) ]}</dd> +<dt>Is Color</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_DEVCAP_ISCOLOR'}) ]}</dd> +<dt>Fax Accepts</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_ACCEPTS'}) ]}</dd> +<dt>Fax Encodings</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_ENCODINGS'}) ]}</dd> +<dt>Fax Limit</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_FAX_LIMIT'}) ]}</dd> +<dt>Subno</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_SUBNO'}) ]}</dd> +<dt>Uplink</dt> +<dd>@{[ &disp($::ENV{'HTTP_X_UP_UPLINK'}) ]}</dd> +EOD + } + return $body . "</dl>\n"; +} + +sub plugin_usage { + return { + name => 'server', + version => '1.0', + author => 'Nekyo <nekyo****@yaman*****>', + syntax => '#server', + description => 'Show Server Info.', + example => '#server', + }; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/showrss.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/showrss.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/showrss.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,189 @@ +## +# 指定されたRSSを取得し、一覧表示する。 +# :書式| +# #showrss(RSSパス, テンプレート名, キャッシュ生存時間) +# RSSパスにはRSSへのファイルパスやURLを指定する。(省略不可)~ +# テンプレート名には取得RSSの表示方法を指定。default(省略時), menubar, recent。~ +# キャッシュ生存時間はキャッシュをクリアする期限(1時間単位)。 +# 省略すると無効になる。 + +# http://nekyo.hp.infoseek.co.jp/ +# License: GPL2 +# Return:LF Code=Shift-JIS 1TAB=4Spaces +use strict; + +sub plugin_showrss_inline +{ + return &plugin_showrss_convert(shift); +} + +sub plugin_showrss_convert +{ + my @arg = &func_get_args(shift); + return "argument error." if (@arg <= 0); + my $rssuri = $arg[0]; + my $tmplname = (@arg >= 2) ? $arg[1] : ""; + my $usecache = (@arg >= 3) ? $arg[2] : 0; + + my $expire = $usecache * 3600; + my $code = 'utf8'; + my $cachefile = $::cache_dir . "/" . &dbmname($rssuri) . ".tmp"; + my $stream; + my $body = ""; + + my $lastmod = (stat($cachefile))[9]; + if ($lastmod + $expire < time || $lastmod == 0) { + my $fp = fopen($rssuri, "r"); + my $result; + ($result, $stream) = &get_rss($fp); + return $stream if ($result != 0); # $stream is errorcode. + + if ($stream =~ /encoding="[Ee][Uu][Cc]/) { + $code = "euc"; + } elsif($stream=~/encoding="[Ss][Hh][Ii][Ff][Tt]/) { + $code = "sjis"; + } + $stream = &replace(&code_convert(\$stream, $::kanjicode, $code)); + if (open(OUT, ">$cachefile")) { + flock(OUT, 2); # lock WriteBlock + print OUT $stream; + flock(OUT, 8); # unlock + close OUT; + } + } else { + # read_cache + my @line; + open(IN, "<$cachefile") || return "Can't read cache."; + @line = <IN>; + close IN; + undef $stream; + $stream = join('', @line); + } + + my %xml = &xmlParser($stream); + my @title = split(/\n/, + ($xml{'rdf:RDF/item/title'} ne "" + ? $xml{'rdf:RDF/item/title'} : $xml{'rss/channel/item/title'} + ) + ); + my @date = split(/\n/, + ($xml{'rdf:RDF/item/dc:date'} ne "" + ? $xml{'rdf:RDF/item/dc:date'} : $xml{'rss/channel/dc:date'} + ) + ); + my @link = split(/\n/, + ($xml{'rdf:RDF/item/link'} ne "" + ? $xml{'rdf:RDF/item/link'} : $xml{'rss/channel/item/link'} + ) + ); + +# my @desc = split(/\n/, $xml{'rdf:RDF/item/description'}); + + my ($footer, $ll, $lr); + + if (lc $tmplname eq "menubar") { + $body .=<<"EOD"; +<div class="small"> +<ul class="recent_list"> +EOD + $ll = "<li>"; + $lr = "</li>\n"; + $footer = "</ul>\n</div>\n"; + } elsif (lc $tmplname eq "recent") { + $body .=<<"EOD"; +<div class="small"> +<string>$date[0]</strong> +<ul class="recent_list"> +EOD + $ll = "<li>"; + $lr = "</li>\n"; + $footer = "</ul>\n</div>\n"; + } else { + $ll = $footer = ""; + $lr = "<br />\n"; + } + + my $count = 0; + foreach (@title) { + $body .=<<"EOD"; +$ll<a href="$link[$count]" title="$title[$count]">$title[$count]</a>$lr +EOD + $count++; + } + $body .= $footer; + + return $body; +} + +sub get_rss +{ + my ($fp) = @_; + my (@log, $data); + @log = <$fp>; + sleep(1); + close($fp); + undef $data; + foreach (@log) { + s/\r\n/\n/g; + s/\r/\n/g; + s/\n//g; + $data .= $_; + } + return (0, $data); +} + +sub replace +{ + my ($xmlStream) = @_; + $xmlStream =~ s/<\?(.*)\?>//g; + $xmlStream =~ s/<rdf:RDF(.*?)>/<rdf:RDF>/g; + $xmlStream =~ s/<rss(.*?)>/<rss>/g; + $xmlStream =~ s/<channel(.*?)>/<channel>/g; + $xmlStream =~ s/<item(.*?)>/<item>/g; + $xmlStream =~ s/<content:encoded>(.*?)<\/content:encoded>//g; + $xmlStream =~ s/\ *\/>/\/>/g; + $xmlStream =~ s/<([^<>\ ]*)\ ([^<>]*)\/>/<$1>$2<\/$1>/g; + $xmlStream =~ s/<([^<>\/]*)\/>/<$1><\/$1>/g; + return $xmlStream; +} + +sub xmlParser +{ + my ($stream) = @_; + my ($i, $ch, $name, @node, $val, $key, %xml); + my $flg = 0; # 1:key / 0:value + foreach $i (0..length $stream) { + $ch = substr($stream, $i, 1); + if ($ch eq '<') { + $flg = 1; + undef $name; + foreach (@node) { + $name .= "$_/"; + } + chop $name; + $val =~ s/<//g; + $val =~ s/>//g; + $xml{$name} .= "$val\n"; + undef $val; + } + if ($flg) { + $key .= $ch; + } else { + $val .= $ch; + } + if ($ch eq '>') { + $flg = 0; + if ($key =~ /\//) { + pop @node; + } else { + $key =~ s/<//g; + $key =~ s/>//g; + push @node, $key; + } + undef $key; + } + } + return %xml; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/size.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/size.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/size.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,17 @@ +## +# 文字の大きさを指定する。 +# :書式| +# &size(ピクセル数値){文字列} +# ピクセル数値は文字の大きさを指定。 +# @author Nekyo. +use strict; +package size; + +sub plugin_inline { + my ($size, $body) = split(/,/, shift); + if ($size eq '' or $body eq '') { + return ""; + } + return "<span style=\"font-size:" . $size . "px;display:inline-block;line-height:130%;text-indent:0px\">$body</span>"; +} +1; Index: PyukiWiki-Nekyo/019/plugin/source.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/source.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/source.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,15 @@ +## +# ページのソースを表示する。 +# :書式| +# ?cmd=source&page=ページ名 +# @author: Nekyo. +use strict; +sub plugin_source_action { + return if ($::form{'page'} eq ''); + my $page = $::form{'page'}; + print "Content-Type: text/plain\r\n\r\n"; + print $::database{$page}; + &close_db; + exit(0); +} +1; Index: PyukiWiki-Nekyo/019/plugin/sub.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/sub.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/sub.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,30 @@ +## +# 上付き文字表示~ +# pyukiwiki独自実装で ^2つで包むと上付きになる。 +# 2^^2^^=4 +# 2^^2^^=4 と表示。~ +# yukiwiki, pukiwiki との互換性を重視される方はこのプラグインを使用すること。 +# 2&sup(2);=4 +# 2&sup(2);=4 と表示。 +use strict; + +package sub; + +sub plugin_inline { + my ($escaped_argument) = @_; + my ($string) = split(/,/, $escaped_argument); + return qq(<sub>$string</sub>); +} + +sub plugin_usage { + return { + name => 'sub', + version => '1.0', + author => 'Nekyo', + syntax => '&sub(string)', + description => 'Make sub.', + example => '&sub(string)', + }; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/sup.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/sup.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/sup.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,30 @@ +## +# 下付き文字表示~ +# pyukiwiki独自実装で _2つで包むと下付きになる。 +# 11001011__2__=0xa9 +# 11001011__2__=0xa9 と表示。~ +# yukiwiki, pukiwiki との互換性を重視される方はこのプラグインを使用すること。 +# 11001011&sub(2);=0xa9 +# 11001011&sub(2);=0xa9 と表示。 +use strict; + +package sup; + +sub plugin_inline { + my ($escaped_argument) = @_; + my ($string) = split(/,/, $escaped_argument); + return qq(<sup>$string</sup>); +} + +sub plugin_usage { + return { + name => 'sup', + version => '1.0', + author => 'Nekyo', + syntax => '&sup(string)', + description => 'Make sub.', + example => '&sup(string)', + }; +} + +1; Index: PyukiWiki-Nekyo/019/plugin/vote.inc.pl diff -u /dev/null PyukiWiki-Nekyo/019/plugin/vote.inc.pl:1.1 --- /dev/null Sun Mar 18 02:14:52 2012 +++ PyukiWiki-Nekyo/019/plugin/vote.inc.pl Sun Mar 18 02:14:52 2012 @@ -0,0 +1,125 @@ +## +# 簡易投票フォームの表示 +# :書式| +# #vote(選択肢1[1の投票数][,選択肢2[2の投票数]…[,選択肢n[nの投票数]]]) +# 選択肢1〜nに投票項目を指定する。 + +# @auther Nekyo.(http://nekyo.hp.infoseek.co.jp) +# @version 0.2 不具合修正版 +use strict; + +sub plugin_vote_action +{ + my $lines = $::database{$::form{mypage}}; + my @lines = split(/\r?\n/, $lines); + + my $vote_no = 0; + my $title = ''; + my $body = ''; + my $postdata = ''; + my @args = (); + my $cnt = 0; + my $write = 0; + my $vote_str = ''; + + foreach (@lines) { + if (/^#vote\(([^\)]*)\)s*$/) { + if (++$vote_no != $::form{vote_no}) { + $postdata .= $_ . "\n"; + next; + } + @args = split(/,/, $1); + $vote_str = ''; + foreach my $arg (@args) { + $cnt = 0; + if ($arg =~ /^(.+)\[(\d+)\]$/) { + $arg = $1; + $cnt = $2; + } + my $e_arg = &rawurlencode($arg); + my $vote_e_arg = "vote_" . $e_arg; + + if ($::form{$vote_e_arg} && ($::form{$vote_e_arg} eq $::resource{vote_plugin_votes})) { + $cnt++; + } + if ($vote_str ne '') { + $vote_str .= ','; + } + $vote_str .= $arg . '[' . $cnt . ']'; + } + $vote_str = '#vote(' . $vote_str . ")\n"; + $postdata .= $vote_str; + $write = 1; + } else { + $postdata .= $_ . "\n"; + } + } + if ($write) { + $::form{mymsg} = $postdata; + $::form{mytouch} = 'on'; + &do_write('FrozenWrite'); + } else { + $::form{cmd} = 'read'; + &do_read; + } + &close_db; + exit; +} + +my $vote_no = 0; + +sub plugin_vote_convert +{ + $vote_no++; + my @args = split(/,/, shift); + return '' if (@args == 0); + + my $escapedmypage = &htmlspecialchars($::form{mypage}); + my $conflictchecker = &get_info($::form{mypage}, $::info_ConflictChecker); + + my $body = <<"EOD"; +<form action="$::script" method="post"> + <table cellspacing="0" cellpadding="2" class="style_table" summary="vote"> + <tr> + <td align="left" class="vote_label" style="padding-left:1em;padding-right:1em"><strong>$::resource{vote_plugin_choice}</strong> + <input type="hidden" name="vote_no" value="$vote_no" /> + <input type="hidden" name="cmd" value="vote" /> + <input type="hidden" name="mypage" value="$escapedmypage" /> + <input type="hidden" name="myConflictChecker" value="$conflictchecker" /> + <input type="hidden" name="mytouch" value="on" /> + </td> + <td align="center" class="vote_label"><strong>$::resource{vote_plugin_votes}</strong></td> + </tr> +EOD + + my $tdcnt = 0; + my $cnt = 0; + my ($link, $e_arg, $cls); + foreach (@args) { + $cnt = 0; + + if (/^(.+)\[(\d+)\]$/) { + $link = $1; + $cnt = $2; + } else { + $link = $_; + } + $e_arg = &rawurlencode($link); + $cls = ($tdcnt++ % 2) ? 'vote_td1' : 'vote_td2'; + $body .= <<"EOD"; + <tr> + <td align="left" class="$cls" style="padding-left:1em;padding-right:1em;">$link</td> + <td align="right" class="$cls">$cnt + <input type="submit" name="vote_$e_arg" value="$::resource{vote_plugin_votes}" class="submit" /> + </td> + </tr> +EOD + } + + $body .= <<"EOD"; + </table> +</form> +EOD + return $body; +} +1;