[wiki]
FSWikiLite/Util

isnot.jp/wiki [Permalink] [編集] [差分]

最終更新:2004-08-30 05:02:13

FSWikiLite用の共通ライブラリ(Utilパッケージ)を拡張する、私家版ライブラリ集。

構成

方針を考える。

バージョン1

FSWikiLiteが動くところならば同様に動作することが期待できる。具体的には@niftyでも動作可能な実装。

バージョン2

標準ライブラリ(5.005、5.6.1もしくは5.8.0。どれがいいだろう)と、非XSモジュールを利用していて、FTPでアップロードして使える。

バージョン3

全てのCPANモジュールが利用可能で、それ以外のXSを含むモジュールも利用可能。バージョン依存の機能を利用している。RDBMSなどを利用している。

ソース

まだ整理されていないです。名前やインターフェイスが随時変更される、不安定バージョンです。

plugin_util.pl

package Util;
#===============================================================================
# 以下はプラグインなどから利用することができるユーティリティ
#===============================================================================

# package Util::Plugin::naoto;
#=============================================================================
# テーマの設定を一時的に上書きする
#=============================================================================
# いしだなおと 2004-05-05
# tDiaryと同じ配置でテーマが配置されていることが前提になります。
# {theme_dir}/{theme}/{theme}.css
# 有効なテーマ名が与えられた場合のみ、変更する。
# THEME_DIRの設定がない場合には、存在チェックができない。(「/」ではじまる絶対URLの場合に対応できないため)
sub set_tdiary_theme {
	my $select = shift || return 0, qq!error: theme name was required!;
	my $theme = $main::THEME_URL;

	# テーマ名を抽出&サニタイズ
	$select = &Util::escapeHTML($select);
	$select =~ s/[\Q&;:|<>\/\E]//g;
	$select =~ s/\.(?:\.+)//g;

	if ($main::THEME_DIR) {
		# THEME_DIRに指定のテーマがあるか調べる
		$main::THEME_DIR =~ s!(/*)$!!;
		$theme = "$main::THEME_DIR/$select/${select}.css";
		return 0, qq!error: file not found: $theme! unless (-e $theme);
	} else {
		# 元の設定からテーマのあるディレクトリを調べ、新しいテーマのURIを組み立てる
		$theme =~ m!^(.+?)/(\w+?)/\2.css$!;
		$theme = "$1/$select/${select}.css";
		my $themefile = &Util::site_base_dir() . $theme;
		return 0, qq!error: file not found: $theme! unless (-e $themefile);
	}

	# グローバル変数にセット
	$main::THEME_URL = $theme;

	# 成功時の返値は、テーマのURI
	return $theme;
}

#===============================================================================
# epochを受取り、W3C-DTF形式に変換した文字列を返す
#===============================================================================
# いしだなおと 2003-12-24
sub time2dcdate {
	# TimeZoneは、setup.plになければ決め打ち
	my $tz = $main::TIME_ZONE || '+09:00';

	my($time) = @_;
	my($sec,$min,$hour,$mday,$mon,$year) = (localtime($time))[0..5];
	$year += 1900;
	$mon++;

	my $dcdate = sprintf("%04d-%02d-%02dT%02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
	$dcdate .= $tz;

	return $dcdate;
}

#===============================================================================
# 指定文字数で切り詰め、(あれば)「…」などの文字をつけて返す
#===============================================================================
sub trim_euc {
	## via: http://nais.to/~yto/tools/jbuncut/
	## via: http://www.din.or.jp/~ohzaki/perl.htm
	# 文字を一文字ずつ処理(日本語対応。漢字コードはEUCとする)
	my $str = shift;
	my $limit = shift || 252;
	my $limit_hard = 4096;
	my $continue = shift;
	my($ret, $i) = ('', '0');
	while ($str =~ /([\xa1-\xfe]{2}|\x8e[\xa1-\xdf]|\x8f[\xa1-\xfe]{2}|.)/g) {
		$ret .= $1;
		if ($1 =~ /(。|.)/) {
			$ret .= "\n";
			last if $i++ > int($limit);
		}
		last if $i++ > int($limit_hard);
	}

	if ($continue) {
		$ret .= length($ret) < int($limit) ? '' : $continue;
	}
	return $ret
}

sub site_base_uri {
	my $uri = $ENV{'SCRIPT_NAME'};
	$uri =~ s!^(.*?)(?:[\./]+?)(?:\w+\.cgi|\w+\.pl|/)$!$1!;
	return 'http://' . $ENV{'HTTP_HOST'} . $uri;
}

sub site_base_dir {
	my $dir = $ENV{'SCRIPT_FILENAME'};
	$dir =~ s!^(.*?)(?:[\./]+?)(?:\w+\.cgi|\w+\.pl|/)$!$1!;
	return $dir;
}

#===============================================================================
# ページ名を受取り、絶対URLを返す。リストコンテキストでは、TrackBack Ping URLも一緒に返す
#===============================================================================
# いしだなおと 2003-12-24
sub abs_url {
	my $page = shift || $main::in{"p"} || 'FrontPage';

	# 拒否リストのページにはundefを返す
	my $deny_tb = '';
	my %special_page = ();
	foreach (@$main::WB_DENY_PAGE) {$special_page{$_} = 1;}
	if ($special_page{$page}) {$deny_tb = 1;}

	my $enc_page = &Util::url_encode($page);
	$page = &Util::escapeHTML($page);

# 	my $wikiurl = &main::MyBaseUrl();

	my $wikiurl = &Util::site_base_uri();

	my $url = "/${main::MAIN_SCRIPT}?p=$enc_page";
	$url =~ s!^//!/!;
#	$url =~ s!/\?!?!;
	$url = $wikiurl . $url;
	$url = &Util::escapeHTML($url);

	# setup.plで設定されていなければ規定値(tb.cgi)を使う
	my $tb_script = $main::TB_SCRIPT || 'tb.cgi';
	my $tb_url = "/$tb_script/$enc_page";
	$tb_url =~ s!^//!/!;
	$tb_url = $wikiurl . $tb_url;
	$tb_url = &Util::escapeHTML($tb_url);

	return $url if $deny_tb;
	return wantarray ? ($url, $tb_url) : $url;
}

#===============================================================================
# 受取った文字列が汎用属性であるかチェクする。
#===============================================================================
sub check_attribute {
	my $ref_check_attrib = shift;
	my @check_attrib = ref($ref_check_attrib) ? @$ref_check_attrib : @{[$ref_check_attrib]};
	my @allow_attrib = ref($_[0]) ? @{$_[0]} : @_;

	push(@allow_attrib, @{&Util::html_generic_attribute});
	my $allow_attrib_regex = join('|', @allow_attrib);

	my @res;
	map {s/^($allow_attrib_regex)/ push(@res, lc($1)) /ie;} @check_attrib;
	return wantarray ? @res : $res[$#res];
}

sub html_generic_attribute {
	return [
		'id',
		'class',
		'style',
		'title',
		'dir',
		'lang',
		'xml:lang',
	];
}

#===============================================================================
#  スカラー値の参照のリストを受け取り、それらの実体である文字列をエスケープします。
#===============================================================================
sub escapeXML {
	foreach my $refs (@_) {
		$$refs =~ s/&quot;/"/g;
		$$refs =~ s/&apos;/'/g;
		$$refs =~ s/&lt;/</g;
		$$refs =~ s/&gt;/>/g;
		$$refs =~ s/&/&/g;
		$$refs =~ s/&/&/g;
		$$refs =~ s/</&lt;/g;
		$$refs =~ s/>/&gt;/g;
		$$refs =~ s/\"/&quot;/g;
		$$refs =~ s/\'/&apos;/g;
	}
}

sub delete_tag2 {
	my $str = shift;
	my $ignore_br = shift;

	# <br />タグを保存する
	$str =~ s/(&lt;|<)\s*[b|B][r|R].*?(&gt;|>)/\0/g unless $ignore_br;

	## via: http://www.din.or.jp/~ohzaki/perl.htm
	# HTMLタグの正規表現 $tag_regex
	my $tag_regex_ = q{[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$(?!\n))}; #'}}}}
	my $comment_tag_regex = '<!(?:--[^-]*-(?:[^-]+-)*?-(?:[^>-]*(?:-[^>-]+)*?)??)*(?:>|$(?!\n)|--.*$)';
	my $tag_regex = qq{$comment_tag_regex|<$tag_regex_};
	my $text_regex = q{[^<]*};

	# $str の中のタグを削除した $result を作る
	my $result = '';
	while ($str =~ /($text_regex)($tag_regex)?/gso) {
	  last if (defined $1 and $1 eq '' and defined $2 and $2 eq '');
	  $result .= $1;
	  my $tag_tmp = $2 || '';
	  if ($tag_tmp =~ m/^<(XMP|PLAINTEXT|SCRIPT)(?![0-9A-Za-z])/i) {
	    $str =~ /(.*?)(?:<\/$1(?![0-9A-Za-z])$tag_regex_|$)/gsi;
	    (my $text_tmp = $1) =~ s/</&lt;/g;
	    $text_tmp =~ s/>/&gt;/g;
	    $result .= $text_tmp;
	  }
	}

	$result =~ tr/\0/\n/ unless $ignore_br;
	return $result;
}

sub trim_space {
	foreach my $refs (@_) {
		$$refs =~ tr/\x0D\x0A//;
		$$refs =~ s/[\r\n]//g;
		$$refs =~ s/[\f\t\a\b]//g;
		$$refs =~ s/^\s+(.*?)\s+$/$1/;
		$$refs =~ s/\s+/ /g;
	}
}

#=============================================================================
# カテゴリを調べる
#=============================================================================
sub get_category_from_souce {
	my $source = shift;
	foreach my $line (split(/\n/,$$source)){
		# コメントか整形済テキストの場合は飛ばす
		next if($line =~ /^(\t| |\/\/)/);
		
		# カテゴリにマッチしたらリスティング
		while($line =~ /{{category\s+(.+?)}}/g){
			return $1;
		}
	}
	return undef;
}

sub get_category_from_page {
	my $source = &Wiki::get_page($_[0]);
	return get_category_from_souce(\$source);
}



#==============================================================================
# http日付(rfc1123)
#==============================================================================
# Qz
sub format_date_http {
    my($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($_[0]);
    sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
        ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')[$wday],
        $mday,
        ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' )[$mon],
        $year+1900, $hour, $min, $sec );
}

#==============================================================================
# クッキー発行
#==============================================================================
# Qz
sub set_cookie {
    my @arg = @_;
    my %cook = %{$arg[0]};
    my @cook;
    while (my($n, $v) = each(%cook)) {
        push @cook, "$n\t$v";
    }
    my $expires = Util::format_date_http(time + $arg[1] * 24 * 60 * 60);
    $cook = join ",", @cook;
    $cook =~ s/([^0-9A-Za-z_ ])/'%'.unpack('H2',$1)/ge;
    $cook =~ s/\s/+/g;
    print "Set-Cookie: WIKI=$cook; expires=$expires\n";
}

#==============================================================================
# クッキー取得
#==============================================================================
# Qz
sub get_cookie {
    my($n, $v, %dummy, $cookie, %cook);
    $cookie = $ENV{'HTTP_COOKIE'};
    if (defined $cookie) {
        $cookie =~ tr/+/ /;
        $cookie =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        foreach (split(/;/, $cookie)) {
            ($n, $v) = split(/=/, $_);
            $n =~ s/ //g;
            $dummy{$n} = $v;
        }
        foreach (split(/,/, $dummy{WIKI})) {
            ($n, $v) = split(/\t/, $_);
            $cook{$n} = $v;
        }
    }
    return %cook;
}

1;

関数説明

About

メンテナ

コミットメント、取り込み

ライセンス

GNU GPL
(要検討)

フィードバック

 
 


※修正は「編集」メニューからしてください。

[FrontPage]

いしだなおと it@isnot.jp