• R/O
  • SSH
  • HTTPS

fswiki: Commit


Commit MetaInfo

Revision201 (tree)
Zeit2018-04-11 17:42:34
Autorkgsoft

Log Message

FSWikiLite 0.1.0リリース

Ändern Zusammenfassung

Diff

--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Footer.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Footer.wiki (revision 201)
@@ -0,0 +1 @@
1+{{lastmodified}}
\ No newline at end of file
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/FrontPage.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/FrontPage.wiki (revision 201)
@@ -0,0 +1,19 @@
1+!!!FSWikiLite
2+FSWikiLiteはPerlによるWikiクローンです。
3+元になっているFreeStyleWikiほど高機能ではありませんが、機能を限定することで軽快に動作します。
4+プラグインは一部しか使用できませんが、文法はFSWikiと完全互換です。
5+また、FSWikiと比べると構造がシンプルな分、設置も容易です。
6+
7+その他にFSWikiLiteは以下のような特徴があります。
8+
9+*Perlで書かれておりDBも使用しないため、CGIが動作するサーバであればほとんどのサーバに設置可能。
10+*FSWikiとは異なるシンプルなプラグイン機構を備えている。
11+*全ページ共通のヘッダ、フッタ、サイドバーを表示可能。
12+*[tDiary|http://www.tdiary.org]のテーマを使用可能。
13+*.htaccessを使用することで編集を管理人のみに限定することが可能。
14+*ページのカテゴライズが可能。
15+*ファイルの添付が可能。
16+
17+*PDF生成、キーワードリンク、InterWikiなどは使用不可。
18+
19+FreeStyle WikiはGNU GPLライセンスの元で配布、改変が許可されるフリーソフトウェアです。
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Header.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Header.wiki (revision 201)
@@ -0,0 +1 @@
1+{{outline}}
\ No newline at end of file
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Help.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Help.wiki (revision 201)
@@ -0,0 +1,122 @@
1+!!!見出し
2+行を!ではじめると見出しになります。見出しは3レベルあります。
3+ !!!大見出し
4+ !!中見出し
5+ !小見出し
6+!!!大見出し
7+!!中見出し
8+!小見出し
9+
10+!!!テキスト装飾
11+ シングルクォート2つで囲むと''イタリック''になります。
12+ シングルクォート3つで囲むと'''ボールド'''になります。
13+ これは==打ち消し線==です。
14+ これは__下線__です。
15+シングルクォート2つで囲むと''イタリック''になります。
16+シングルクォート3つで囲むと'''ボールド'''になります。
17+これは==打ち消し線==です。
18+これは__下線__です。
19+
20+!!!引用
21+ ""これは引用です。
22+ ""これも引用です。
23+""これは引用です。
24+""これも引用です。
25+
26+!!!説明
27+ :項目:説明文
28+:項目:説明文
29+
30+ ::項目
31+ :::説明文は複数行にわけて書くこともできます。
32+ :::こんな感じで。
33+::項目
34+:::説明文は複数行にわけて書くこともできます。
35+:::こんな感じで。
36+
37+!!!項目
38+行を*ではじめるとリストになります。リストは*の個数に応じて3段階までネストすることができます。
39+ *項目1-1
40+ **項目2-1
41+ **項目2-2
42+ ***項目3-1
43+ *項目1-2
44+ **項目2-3
45+*項目1-1
46+**項目2-1
47+**項目2-2
48+***項目3-1
49+*項目1-2
50+**項目2-3
51+行を+ではじめると番号付きリストになります。
52+ +番号付き項目1
53+ ++番号付き項目1-1
54+ +番号付き項目2
55+ +番号付き項目3
56++番号付き項目1
57+++番号付き項目1-1
58++番号付き項目2
59++番号付き項目3
60+
61+!!!リンク
62+ *http://www.yahoo.co.jp/
63+ *[Google|http://www.google.co.jp/]
64+ *[[FrontPage]]
65+ *[[トップ|FrontPage]]
66+ *[[トップの最初の見出し|FrontPage#p0]]
67+ *[[このページの「リンク」見出し|#p8]]
68+ *mailto:foo@xxx.dom
69+ *[メールはこちら|mailto:foo@xxx.dom?subject=TEST&body=TESTMAIL]
70+*http://www.yahoo.co.jp/
71+*[Google|http://www.google.co.jp/]
72+*[[FrontPage]]
73+*[[トップ|FrontPage]]
74+*[[トップの最初の見出し|FrontPage#p0]]
75+*[[このページの「リンク」見出し|#p8]]
76+*mailto:foo@xxx.dom
77+*[メールはこちら|mailto:foo@xxx.dom?subject=TEST&body=TESTMAIL]
78+
79+!!!テーブル
80+CSVはテーブルになります。1行目がヘッダになります。
81+
82+ ,h-1,h-2,h-3
83+ ,1-1,1-2,1-3
84+ ,2-1,2-2,2-3
85+,h-1,h-2,h-3
86+,1-1,1-2,1-3
87+,2-1,2-2,2-3
88+
89+セル内にカンマを含めたい場合は値をダブルクォートで囲みます。また、ダブルクォートで囲んだセルにダブルクォートを表示したい場合はダブルクォートを2つ続けて記述します。
90+
91+ ,カンマ,ダブルクォート
92+ ,"セルの中にカンマ,を表示","セルの中にダブルクォート""を表示"
93+,カンマ,ダブルクォート
94+,"セルの中にカンマ,を表示","セルの中にダブルクォート""を表示"
95+
96+セル内に"<<"を記述すると左側のセルと結合します。
97+ ,h-1,h-2,h-3
98+ ,1-1,1-2,1-3
99+ ,2-1,<<,2-3
100+,h-1,h-2,h-3
101+,1-1,1-2,1-3
102+,2-1,<<,2-3
103+
104+
105+!!!整形済テキスト
106+行頭をスペースまたはタブではじめると整形済テキストとして扱われます。
107+ これは整形済テキストです。
108+ 入力したとおりに表示されます。
109+
110+!!!水平線
111+行頭に----と書くと水平線になります。
112+ ----
113+----
114+
115+!!!コメント
116+行を//ではじめるとその行はコメントとみなされます。コメント行は一切出力されません。
117+
118+ //これはコメントになります。画面には出力されません。
119+//これはコメントになります。画面には出力されません。
120+
121+!!!ヘッダ、フッタ、サイドバー
122+[[Header]]、[[Footer]]、[[Menu]]という名前のページを作成するとそれぞれヘッダ、フッタ、サイドバーが表示されます。また、[[EditHelper]]というページを作成するとページの編集画面の下部にヘルプとして表示されます。
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Menu.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/Menu.wiki (revision 201)
@@ -0,0 +1,12 @@
1+{{search v}}
2+
3+!!!メニュー
4+*[[トップ|FrontPage]]
5+*[[ヘルプ|Help]]
6+*[[プラグイン|PluginHelp]]
7+
8+*[FSWikiLiteとは?|./docs/readme.html]
9+*[プラグイン開発|./docs/plugindev.html]
10+
11+!!!最新
12+{{recentdays 10}}
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/PluginHelp.wiki (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/data/PluginHelp.wiki (revision 201)
@@ -0,0 +1,117 @@
1+!!!使用可能なプラグイン
2+
3+!!category
4+
5+ページをカテゴライズするためのプラグインです。引数にカテゴリ名を指定します。
6+
7+ {{category カテゴリ名}}
8+
9+!!category_list
10+
11+カテゴリごとのページ一覧を表示します。
12+
13+ {{category_list}}
14+
15+引数として表示するカテゴリを指定することもできます。
16+
17+ {{category_list カテゴリ名}}
18+
19+!!lastmodified
20+
21+ページの最終更新日時を表示します。
22+
23+ {{lastmodified}}
24+
25+引数でページ名を指定すると指定したページの最終更新日時を表示します。
26+
27+ {{lastmodified ページ名}}
28+
29+!!outline
30+
31+ページのアウトラインを表示します。見出しがツリー形式で表示され、クリックするとその見出しにジャンプします。Headerなどに入れておくと便利です。
32+
33+ {{outline}}
34+
35+引数でページ名を指定すると指定したページを対象とします。
36+
37+ {{outline ページ名}}
38+
39+!!pre
40+
41+preタグを出力するブロックプラグインです。
42+
43+ {{pre
44+ ここにテキストを書く
45+ }}
46+
47+引数に"num"を指定すると行番号付きになります。
48+ {{pre num
49+ ここにテキストを書く
50+ }}
51+
52+!!raw
53+
54+引数で指定した文字列をそのまま表示します。
55+
56+ {{raw テキスト}}
57+
58+!!recent
59+
60+更新日時順にページ名の一覧を出力します。引数で表示件数を指定できます。引数に"v"を指定すると縦に表示します。表示件数を省略すると全件出力します。
61+
62+ {{recent 10}}
63+ {{recent 10,v}}
64+
65+!!recentdays
66+
67+日付ごとに更新されたページを一覧表示します。引数で表示日数を指定できます。表示日数を省略すると最新の5日分を出力します。
68+
69+ {{recentdays 10}}
70+
71+!!ref
72+
73+添付ファイルへのリンクを出力するプラグインです。
74+
75+ {{ref ファイル名}}
76+
77+引数でページ名を指定すると指定したページの添付ファイルを対象とします。
78+
79+ {{ref ファイル名,ページ名}}
80+
81+通常はアンカとしてファイル名が表示されますが、 別名として任意の文字列を表示することもできます。
82+
83+ {{ref ファイル名,ページ名,別名}}
84+
85+!!ref_image
86+
87+添付ファイルを画像として表示するプラグインです。
88+
89+ {{ref_image ファイル名}}
90+
91+オプションで画像のサイズを指定することができます。 以下の例では幅650ピクセル、高さ400ピクセルで画像を表示します。
92+
93+ {{ref_image ファイル名,w650,h400}}
94+
95+別のページに添付されたファイルを参照することもできます。
96+
97+ {{ref_image ファイル名,ページ名}}
98+
99+!!ref_text
100+
101+添付ファイルを整形済テキストとして表示するプラグインです。
102+
103+ {{ref_text ファイル名}}
104+
105+別のページに添付されたファイルを参照することもできます。
106+
107+ {{ref_text ファイル名,ページ名}}
108+
109+!!search
110+
111+検索フォームを表示します。
112+
113+ {{search}}
114+
115+引数に"v"を指定すると縦に表示します。サイドバーなどに入れておくと便利です。
116+
117+ {{search v}}
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/default.css (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/default.css (revision 201)
@@ -0,0 +1,129 @@
1+body {
2+ background-color: #FFFFFF;
3+ color : #000000;
4+ font-family : Verdana,Arial,Helvetica,sans-serif;
5+}
6+
7+p.adminmenu {
8+ text-align : right;
9+ padding-bottom : 5px;
10+ margin-bottom : 5px;
11+ border-bottom : #000088 1px dotted;
12+ font-size : 80%;
13+ text-indent : 10px;
14+}
15+
16+.footer {
17+ border-top : #000088 1px dotted;
18+ margin-top : 20px;
19+ padding-top : 5px;
20+ text-align : right;
21+ font-size : 80%;
22+ font-style : italic;
23+}
24+
25+hr {
26+ color : #FFFFFF;
27+}
28+
29+pre {
30+ border : #888888 1px solid;
31+ padding : 4px;
32+ margin-left : 40px;
33+}
34+
35+p {
36+ padding-left : 20pt;
37+}
38+
39+strong {
40+ font-weight : normal;
41+}
42+
43+h1 {
44+ background-color : #FFFFFF;
45+ border-bottom : #AABBFF 1px solid;
46+ font-family : Verdana,Arial,Helvetica,sans-serif;
47+ padding-left : 4pt;
48+}
49+
50+
51+h2 {
52+ background-color : #AABBFF;
53+ font-family : Verdana,Arial,Helvetica,sans-serif;
54+ padding-left : 4pt;
55+}
56+
57+h3 {
58+ border-left : #AABBFF 10px solid;
59+ border-top : #AABBFF 5px solid;
60+ border-right : #AABBFF 1px solid;
61+ border-bottom : #AABBFF 1px solid;
62+ font-family : Verdana,Arial,Helvetica,sans-serif;
63+ font-size : 100%;
64+ padding-left : 4pt;
65+}
66+
67+h4 {
68+ border-left : #AABBFF 10px solid;
69+ padding-left : 4px;
70+ font-family : Verdana,Arial,Helvetica,sans-serif;
71+ padding-left : 4pt;
72+}
73+
74+table {
75+ border : #888888 2px solid;
76+}
77+
78+th {
79+ border : #888888 1px solid;
80+ background-color : #88AAFF;
81+}
82+
83+td {
84+ border : #888888 1px solid;
85+}
86+
87+A:link {
88+ color : #4444FF;
89+ text-decoration : none;
90+}
91+A:visited {
92+ color : #4444FF;
93+ text-decoration : none;
94+}
95+A:hover {
96+ color : #FF4444;
97+ text-decoration : underline;
98+}
99+
100+div.main {
101+ margin-left: 20%;
102+}
103+
104+div.sidebar {
105+ position : absolute;
106+ top : 0px;
107+ left : 0px;
108+ width : 20%;
109+ font-size : x-small;
110+ padding: 2px 2px 100% 2px;
111+ border-style: solid;
112+ border-color: #CCCCFF;
113+ border-width: 2px;
114+ color : #000000;
115+ background-color: #EEEEFF;
116+}
117+
118+div.comment {
119+ margin-top : 10px;
120+ margin-bottom : 10px;
121+ background-color : DDDDFF;
122+ border : AAAAFF 2px solid;
123+ font-size : 80%;
124+}
125+
126+.error {
127+ color : #FF0000;
128+ font-weight : bold;
129+}
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/makedoc.sh (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/makedoc.sh (revision 201)
@@ -0,0 +1,4 @@
1+#!/bin/sh
2+# HTMLファイルに変換
3+perl ../../tools/wiki2html.pl "http://fswiki.osdn.jp/cgi-bin/wiki.cgi/docs?action=SOURCE&page=FSWikiLite%2Freadme" -css=default.css -title=README > readme.html
4+perl ../../tools/wiki2html.pl "http://fswiki.osdn.jp/cgi-bin/wiki.cgi/docs?action=SOURCE&page=FSWikiLite%2F%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3%B3%AB%C8%AF" -css=default.css -title=プラグイン開発 > plugindev.html
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/plugindev.html (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/plugindev.html (revision 201)
@@ -0,0 +1,124 @@
1+<html>
2+<head>
3+ <title>プラグイン開発</title>
4+ <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
5+ <link rel="stylesheet" type="text/css" href="default.css">
6+</head>
7+<body>
8+<h1>プラグイン開発</h1>
9+<h2>サポートするプラグイン</h2>
10+<p>FSWikiLiteはFSWikiとは違い、Wikiページに記述して使用するタイプのプラグイン(インラインプラグインとパラグラフプラグイン、ブロックプラグイン)しかサポートしていません。ただし、FSWikiでアクションプラグインと呼ばれているものについては別のCGIスクリプトを用意することで対応することができます(Liteのcategory.cgiなどがこれにあたります)。</p>
11+<p>プラグインは〜.plという名前を付けてpluginディレクトリに配置します。そしてlib/setup.plでrequireします。デフォルトのsetup.plではcore.plのみ読み込むよう設定されています。</p>
12+<pre>require &quot;./plugin/core.pl&quot;;
13+</pre>
14+<h2>インラインプラグイン</h2>
15+<p>インラインプラグインはWiki::Pluginパッケージで定義されたPerl関数のリファレンスです。関数の引数にはWikiソースで記述した引数がそのまま渡されます。関数は戻り値としてHTMLを返すように実装します。また、スクリプトのBEGIN節で関数のリファレンスをインラインプラグインとして登録します。</p>
16+<pre>package Wiki::Plugin;
17+BEGIN {
18+ $main::I_PLUGIN-&gt;{hello} = \&amp;hello;
19+}
20+sub hello {
21+ my $name = shift;
22+ if($name eq ''){
23+ return &quot;名前を入力してください。&quot;;
24+ } else {
25+ return &quot;こんにちは&quot;.&amp;Util::escapeHTML($name).&quot;さん&quot;;
26+ }
27+}
28+1;
29+</pre>
30+<p>ページ編集時に以下の書式で使用することができます。</p>
31+<pre>{{hello たろう}}
32+</pre>
33+<h2>パラグラフプラグイン</h2>
34+<p>パラグラフプラグインも実装方法はインラインプラグインと同様です。ブロック要素を含むHTMLを返却する場合にはパラグラフプラグインとして実装します。BEGIN節での登録方法のみが異なります。</p>
35+<pre>BEGIN {
36+ $main::P_PLUGIN-&gt;{hello} = \&amp;hello;
37+}
38+</pre>
39+<h2>ブロックプラグイン</h2>
40+<p>ブロックプラグインも実装方法はインラインプラグインと同様です。複数行に渡るパラメータを使用する場合にはブロックプラグインとして実装します。</p>
41+<pre>BEGIN {
42+ $main::B_PLUGIN-&amp;gt;{hello} = \&amp;amp;hello;
43+}
44+sub hello {
45+ my $text = shift;
46+ my $name = shift;
47+ if($name eq ''){
48+ return &quot;名前を入力してください。&quot;;
49+ } else {
50+ return &quot;こんにちは&quot;.&amp;Util::escapeHTML($name).&quot;さん&amp;lt;br&amp;gt;\n&quot;.$text;
51+ }
52+}
53+---- Wikiコード ----
54+{{hello たろう
55+ご機嫌いかがですか?
56+今日は良い天気ですね。
57+}}
58+</pre>
59+<h2>リクエストパラメータへのアクセス</h2>
60+<p>プラグイン内部からリクエストパラメータにアクセスするには%main::inという変数を利用します。これはcgi-lib.plでパースされたリクエストパラメータが格納された連想配列です。</p>
61+<pre># ページ名を取得
62+my $p = $main::in{'p'};
63+</pre>
64+<h2>プラグインから利用可能なユーティリティ</h2>
65+<p>プラグイン内部ではUtilパッケージに定義されたユーティリティ関数を使用することができます。Utilパッケージには以下のような関数が定義されています。</p>
66+<table>
67+<tr>
68+<th colspan="1">関数名</th>
69+<th colspan="1">説明</th>
70+</tr>
71+<tr>
72+<td colspan="1">url_encode</td>
73+<td colspan="1">URLエンコードします。</td>
74+</tr>
75+<tr>
76+<td colspan="1">url_decode</td>
77+<td colspan="1">URLエンコードされた文字列をデコードします。</td>
78+</tr>
79+<tr>
80+<td colspan="1">escapeHTML</td>
81+<td colspan="1">HTMLをエスケープします。</td>
82+</tr>
83+<tr>
84+<td colspan="1">format_date</td>
85+<td colspan="1">日付をフォーマットします。</td>
86+</tr>
87+<tr>
88+<td colspan="1">trim</td>
89+<td colspan="1">文字列の前後の空白を取り除きます。</td>
90+</tr>
91+<tr>
92+<td colspan="1">delete_tag</td>
93+<td colspan="1">タグを削除して文字列のみを取得します。</td>
94+</tr>
95+<tr>
96+<td colspan="1">check_pagename</td>
97+<td colspan="1">文字列が使用可能なページ名かどうかチェックします。</td>
98+</tr>
99+<tr>
100+<td colspan="1">check_numeric</td>
101+<td colspan="1">文字列が数値かどうかチェックします。</td>
102+</tr>
103+<tr>
104+<td colspan="1">send_mail</td>
105+<td colspan="1">メールを送信します。</td>
106+</tr>
107+<tr>
108+<td colspan="1">error</td>
109+<td colspan="1">エラー画面を表示します。</td>
110+</tr>
111+<tr>
112+<td colspan="1">handyphone</td>
113+<td colspan="1">携帯電話かどうかを判断します。</td>
114+</tr>
115+<tr>
116+<td colspan="1">smartphone</td>
117+<td colspan="1">スマートフォンかどうかチェックします。</td>
118+</tr>
119+</table>
120+<h2>アクションスクリプト</h2>
121+<p>FSWikiでアクションプラグインとして実装されているプラグインは別途CGIスクリプトを作成することで対応することが出来ます。actionパラメータの代わりにそのCGIスクリプトを呼び出すようにします。CGIスクリプトからはcommon.plに定義された関数群を使用してページの取得や保存などを行うことが出来ます。</p>
122+<p>FSWikiLiteではデフォルトでedit.cgi(ページの編集)、download.cgi(添付ファイルのダウンロード)、category.cgi(カテゴリ表示)という3つのアクションスクリプトが用意されていますので、これらを参考にしてください。</p>
123+</body>
124+</html>
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/readme.html (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/readme.html (revision 201)
@@ -0,0 +1,172 @@
1+<html>
2+<head>
3+ <title>README</title>
4+ <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
5+ <link rel="stylesheet" type="text/css" href="default.css">
6+</head>
7+<body>
8+<h1>README</h1>
9+<h2>FSWikiLiteとは?</h2>
10+<p>FSWikiLiteの元になっているFreeStyleWikiはPerlによるmodulableなWikiクローンです。プラグインによって様々な機能を追加することができます。ただし、高機能な分、通常のCGIスクリプトと比較すると動作が重いという欠点がありました。</p>
11+<p>FSWikiLiteはFSWikiほど高機能ではありませんが、機能を限定することで軽快に動作します。プラグインは一部しか使用できませんが、文法はFSWikiと完全互換です。また、FSWikiと比べると構造がシンプルな分、設置も容易です。</p>
12+<p>その他にFSWikiLiteは以下のような特徴があります。</p>
13+<ul>
14+<li>tDiaryのテーマを使用可能。</li>
15+<li>サイドバーやヘッダ、フッタを表示可能。</li>
16+<li>FSWikiとは異なるシンプルなプラグイン機構を備えている。</li>
17+<li>.htaccessを使用することで編集を管理人のみに限定することが可能。</li>
18+<li>ページのカテゴライズが可能。</li>
19+<li>ファイルの添付が可能。</li>
20+<li>PDF生成、キーワードリンク、InterWikiなどは使用不可。</li>
21+</ul>
22+<h2>インストール</h2>
23+<p>lib/setup.plを編集し、各自の設定を行います。</p>
24+<ul>
25+<li>$DATA_DIR - データファイルの格納場所。</li>
26+<li>$BACKUP_DIR - バックアップファイルの格納場所。</li>
27+<li>$ATTACH_DIR - 添付ファイルの格納場所。</li>
28+<li>$THEME_URL - テーマ(CSS)の場所。</li>
29+<li>$SEND_MAIL - sendmailのパス。更新通知を受け取る場合は設定してください。</li>
30+<li>$ADMIN_MAIL- 管理者のメールアドレス。更新通知を受け取る場合は設定してください。</li>
31+<li>$WIKI_NAME - WikiNameを使用する場合は1、使用しない場合は0を指定してください。</li>
32+<li>$BR_MODE - 改行箇所でBRタグを出力したい場合は1、BRタグを出力したくない場合は0を指定してください。</li>
33+<li>$DISPLAY_IMAGE - 画像のURLをIMGタグで表示する場合は1、通常のリンクとして表示する場合は0を指定してください。</li>
34+<li>$MAIN_SCRIPT - メインスクリプトのファイル名。変更しなくてもいいです。</li>
35+<li>$EDIT_SCRIPT - 編集用スクリプトのファイル名。変更しなくてもいいです。</li>
36+<li>$DOWNLOAD_SCRIPT - 添付ファイルのダウンロード用スクリプトのファイル名。変更しなくてもいいです。</li>
37+<li>$CATEGORY_SCRIPT - カテゴリ表示用スクリプトのファイル名。変更しなくてもいいです。</li>
38+<li>$SITE_TITLE - サイト名。自由に変更してください。</li>
39+<li>$VERSION - FSWikiLiteのバージョン。変更しなくてもいいです。</li>
40+<li>$SITE_URL - FSWiki公式サイトのURL。変更しなくてもいいです。</li>
41+</ul>
42+<p>FTPなどで以下のようにファイルを配置します(デフォルトの設定の場合)。</p>
43+<pre>-+- wiki.cgi
44+ |
45+ +- edit.cgi
46+ |
47+ +- category.cgi
48+ |
49+ +- download.cgi
50+ |
51+ +- /lib (ライブラリを配置します)
52+ | |
53+ | +- jcode.pl
54+ | |
55+ | +- cgi-lib.pl
56+ | |
57+ | +- setup.pl
58+ | |
59+ | +- common.pl
60+ | |
61+ | +- mimew.pl
62+ |
63+ +- /plugin (プラグインを配置します)
64+ | |
65+ | +- core.pl
66+ |
67+ +- /data (ページデータが出力されます)
68+ |
69+ +- /backup (バックアップファイルが出力されます)
70+ |
71+ +- /attach(添付ファイルが出力されます)
72+ |
73+ +-/theme (テーマを配置します)
74+ |
75+ +- /default
76+ |
77+ +- default.css
78+</pre>
79+<p>wiki.cgi、edit.cgi、category.cgi、download.cgiのパーミッションをCGIとして実行可能なように設定します。また、dataディレクトリ、backupディレクトリ、attachディレクトリはCGIから書き込み可能なパーミッションに設定します。なお、ディレクトリ構成に関してはsetup.plを編集することで任意の構造に変更することができます。</p>
80+<p>テーマに関しては現在のFSWikiLiteの配布アーカイブには同梱されていません。FSWikiのディストリビューションや、tDiaryのWebサイトよりお好みのテーマを取得してください。</p>
81+<h2>編集を管理者に限定する</h2>
82+<p>.htaccessを使ってedit.cgiにアクセス制限をかけます。詳細についてはそのうち。</p>
83+<h2>使用可能なプラグイン</h2>
84+<h3>category</h3>
85+<p>ページをカテゴライズするためのプラグインです。引数にカテゴリ名を指定します。</p>
86+<pre>{{category カテゴリ名}}
87+</pre>
88+<h3>category_list</h3>
89+<p>カテゴリごとのページ一覧を表示します。</p>
90+<pre>{{category_list}}
91+</pre>
92+<p>引数として表示するカテゴリを指定することもできます。</p>
93+<pre>{{category_list カテゴリ名}}
94+</pre>
95+<h3>lastmodified</h3>
96+<p>ページの最終更新日時を表示します。</p>
97+<pre>{{lastmodified}}
98+</pre>
99+<p>引数でページ名を指定すると指定したページの最終更新日時を表示します。</p>
100+<pre>{{lastmodified ページ名}}
101+</pre>
102+<h3>outline</h3>
103+<p>ページのアウトラインを表示します。見出しがツリー形式で表示され、クリックするとその見出しにジャンプします。Headerなどに入れておくと便利です。</p>
104+<pre>{{outline}}
105+</pre>
106+<p>引数でページ名を指定すると指定したページを対象とします。</p>
107+<pre>{{outline ページ名}}
108+</pre>
109+<h3>pre</h3>
110+<p>preタグを出力するブロックプラグインです。</p>
111+<pre>{{pre
112+ここにテキストを書く
113+}}
114+</pre>
115+<p>引数に&quot;num&quot;を指定すると行番号付きになります。</p>
116+<pre>{{pre num
117+ここにテキストを書く
118+}}
119+</pre>
120+<h3>raw</h3>
121+<p>引数で指定した文字列をそのまま表示します。</p>
122+<pre>{{raw テキスト}}
123+</pre>
124+<h3>recent</h3>
125+<p>更新日時順にページ名の一覧を出力します。引数で表示件数を指定できます。引数に&quot;v&quot;を指定すると縦に表示します。表示件数を省略すると全件出力します。</p>
126+<pre>{{recent 10}}
127+{{recent 10,v}}
128+</pre>
129+<h3>recentdays</h3>
130+<p>日付ごとに更新されたページを一覧表示します。引数で表示日数を指定できます。表示日数を省略すると最新の5日分を出力します。</p>
131+<pre>{{recentdays 10}}
132+</pre>
133+<h3>ref</h3>
134+<p>添付ファイルへのリンクを出力するプラグインです。</p>
135+<pre>{{ref ファイル名}}
136+</pre>
137+<p>別のページに添付されたファイルを参照することもできます。</p>
138+<pre>{{ref ファイル名,ページ名}}
139+</pre>
140+<p>通常はアンカとしてファイル名が表示されますが、 別名として任意の文字列を表示することもできます。</p>
141+<pre>{{ref ファイル名,ページ名,別名}}
142+</pre>
143+<h3>ref_image</h3>
144+<p>添付ファイルを画像として表示するプラグインです。</p>
145+<pre>{{ref_image ファイル名}}
146+</pre>
147+<p>オプションで画像のサイズを指定することができます。 以下の例では幅650ピクセル、高さ400ピクセルで画像を表示します。 </p>
148+<pre>{{ref_image ファイル名,w650,h400}}
149+</pre>
150+<p>別のページに添付されたファイルを参照することもできます。</p>
151+<pre>{{ref_image ファイル名,ページ名}}
152+</pre>
153+<h3>ref_text</h3>
154+<p>添付ファイルを整形済テキストとして表示するプラグインです。</p>
155+<pre>{{ref_text ファイル名}}
156+</pre>
157+<p>別のページに添付されたファイルを参照することもできます。</p>
158+<pre>{{ref_text ファイル名,ページ名}}
159+</pre>
160+<h3>search</h3>
161+<p>検索フォームを表示します。</p>
162+<pre>{{search}}
163+</pre>
164+<p>引数に&quot;v&quot;を指定すると縦に表示します。サイドバーなどに入れておくと便利です。</p>
165+<pre>{{search v}}
166+</pre>
167+<h2>ライセンス</h2>
168+<p>FSWikiLiteはGNUL GPLライセンスに基づいて改変、再配布が可能です。</p>
169+<h2>作成者</h2>
170+<p>Copyright (C) 2002 Naoki Takezoe, FreeStyleWiki Development Team.</p>
171+</body>
172+</html>
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/gpl.txt (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/docs/gpl.txt (revision 201)
@@ -0,0 +1,340 @@
1+ GNU GENERAL PUBLIC LICENSE
2+ Version 2, June 1991
3+
4+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6+ Everyone is permitted to copy and distribute verbatim copies
7+ of this license document, but changing it is not allowed.
8+
9+ Preamble
10+
11+ The licenses for most software are designed to take away your
12+freedom to share and change it. By contrast, the GNU General Public
13+License is intended to guarantee your freedom to share and change free
14+software--to make sure the software is free for all its users. This
15+General Public License applies to most of the Free Software
16+Foundation's software and to any other program whose authors commit to
17+using it. (Some other Free Software Foundation software is covered by
18+the GNU Library General Public License instead.) You can apply it to
19+your programs, too.
20+
21+ When we speak of free software, we are referring to freedom, not
22+price. Our General Public Licenses are designed to make sure that you
23+have the freedom to distribute copies of free software (and charge for
24+this service if you wish), that you receive source code or can get it
25+if you want it, that you can change the software or use pieces of it
26+in new free programs; and that you know you can do these things.
27+
28+ To protect your rights, we need to make restrictions that forbid
29+anyone to deny you these rights or to ask you to surrender the rights.
30+These restrictions translate to certain responsibilities for you if you
31+distribute copies of the software, or if you modify it.
32+
33+ For example, if you distribute copies of such a program, whether
34+gratis or for a fee, you must give the recipients all the rights that
35+you have. You must make sure that they, too, receive or can get the
36+source code. And you must show them these terms so they know their
37+rights.
38+
39+ We protect your rights with two steps: (1) copyright the software, and
40+(2) offer you this license which gives you legal permission to copy,
41+distribute and/or modify the software.
42+
43+ Also, for each author's protection and ours, we want to make certain
44+that everyone understands that there is no warranty for this free
45+software. If the software is modified by someone else and passed on, we
46+want its recipients to know that what they have is not the original, so
47+that any problems introduced by others will not reflect on the original
48+authors' reputations.
49+
50+ Finally, any free program is threatened constantly by software
51+patents. We wish to avoid the danger that redistributors of a free
52+program will individually obtain patent licenses, in effect making the
53+program proprietary. To prevent this, we have made it clear that any
54+patent must be licensed for everyone's free use or not licensed at all.
55+
56+ The precise terms and conditions for copying, distribution and
57+modification follow.
58+
59+ GNU GENERAL PUBLIC LICENSE
60+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61+
62+ 0. This License applies to any program or other work which contains
63+a notice placed by the copyright holder saying it may be distributed
64+under the terms of this General Public License. The "Program", below,
65+refers to any such program or work, and a "work based on the Program"
66+means either the Program or any derivative work under copyright law:
67+that is to say, a work containing the Program or a portion of it,
68+either verbatim or with modifications and/or translated into another
69+language. (Hereinafter, translation is included without limitation in
70+the term "modification".) Each licensee is addressed as "you".
71+
72+Activities other than copying, distribution and modification are not
73+covered by this License; they are outside its scope. The act of
74+running the Program is not restricted, and the output from the Program
75+is covered only if its contents constitute a work based on the
76+Program (independent of having been made by running the Program).
77+Whether that is true depends on what the Program does.
78+
79+ 1. You may copy and distribute verbatim copies of the Program's
80+source code as you receive it, in any medium, provided that you
81+conspicuously and appropriately publish on each copy an appropriate
82+copyright notice and disclaimer of warranty; keep intact all the
83+notices that refer to this License and to the absence of any warranty;
84+and give any other recipients of the Program a copy of this License
85+along with the Program.
86+
87+You may charge a fee for the physical act of transferring a copy, and
88+you may at your option offer warranty protection in exchange for a fee.
89+
90+ 2. You may modify your copy or copies of the Program or any portion
91+of it, thus forming a work based on the Program, and copy and
92+distribute such modifications or work under the terms of Section 1
93+above, provided that you also meet all of these conditions:
94+
95+ a) You must cause the modified files to carry prominent notices
96+ stating that you changed the files and the date of any change.
97+
98+ b) You must cause any work that you distribute or publish, that in
99+ whole or in part contains or is derived from the Program or any
100+ part thereof, to be licensed as a whole at no charge to all third
101+ parties under the terms of this License.
102+
103+ c) If the modified program normally reads commands interactively
104+ when run, you must cause it, when started running for such
105+ interactive use in the most ordinary way, to print or display an
106+ announcement including an appropriate copyright notice and a
107+ notice that there is no warranty (or else, saying that you provide
108+ a warranty) and that users may redistribute the program under
109+ these conditions, and telling the user how to view a copy of this
110+ License. (Exception: if the Program itself is interactive but
111+ does not normally print such an announcement, your work based on
112+ the Program is not required to print an announcement.)
113+
114+These requirements apply to the modified work as a whole. If
115+identifiable sections of that work are not derived from the Program,
116+and can be reasonably considered independent and separate works in
117+themselves, then this License, and its terms, do not apply to those
118+sections when you distribute them as separate works. But when you
119+distribute the same sections as part of a whole which is a work based
120+on the Program, the distribution of the whole must be on the terms of
121+this License, whose permissions for other licensees extend to the
122+entire whole, and thus to each and every part regardless of who wrote it.
123+
124+Thus, it is not the intent of this section to claim rights or contest
125+your rights to work written entirely by you; rather, the intent is to
126+exercise the right to control the distribution of derivative or
127+collective works based on the Program.
128+
129+In addition, mere aggregation of another work not based on the Program
130+with the Program (or with a work based on the Program) on a volume of
131+a storage or distribution medium does not bring the other work under
132+the scope of this License.
133+
134+ 3. You may copy and distribute the Program (or a work based on it,
135+under Section 2) in object code or executable form under the terms of
136+Sections 1 and 2 above provided that you also do one of the following:
137+
138+ a) Accompany it with the complete corresponding machine-readable
139+ source code, which must be distributed under the terms of Sections
140+ 1 and 2 above on a medium customarily used for software interchange; or,
141+
142+ b) Accompany it with a written offer, valid for at least three
143+ years, to give any third party, for a charge no more than your
144+ cost of physically performing source distribution, a complete
145+ machine-readable copy of the corresponding source code, to be
146+ distributed under the terms of Sections 1 and 2 above on a medium
147+ customarily used for software interchange; or,
148+
149+ c) Accompany it with the information you received as to the offer
150+ to distribute corresponding source code. (This alternative is
151+ allowed only for noncommercial distribution and only if you
152+ received the program in object code or executable form with such
153+ an offer, in accord with Subsection b above.)
154+
155+The source code for a work means the preferred form of the work for
156+making modifications to it. For an executable work, complete source
157+code means all the source code for all modules it contains, plus any
158+associated interface definition files, plus the scripts used to
159+control compilation and installation of the executable. However, as a
160+special exception, the source code distributed need not include
161+anything that is normally distributed (in either source or binary
162+form) with the major components (compiler, kernel, and so on) of the
163+operating system on which the executable runs, unless that component
164+itself accompanies the executable.
165+
166+If distribution of executable or object code is made by offering
167+access to copy from a designated place, then offering equivalent
168+access to copy the source code from the same place counts as
169+distribution of the source code, even though third parties are not
170+compelled to copy the source along with the object code.
171+
172+ 4. You may not copy, modify, sublicense, or distribute the Program
173+except as expressly provided under this License. Any attempt
174+otherwise to copy, modify, sublicense or distribute the Program is
175+void, and will automatically terminate your rights under this License.
176+However, parties who have received copies, or rights, from you under
177+this License will not have their licenses terminated so long as such
178+parties remain in full compliance.
179+
180+ 5. You are not required to accept this License, since you have not
181+signed it. However, nothing else grants you permission to modify or
182+distribute the Program or its derivative works. These actions are
183+prohibited by law if you do not accept this License. Therefore, by
184+modifying or distributing the Program (or any work based on the
185+Program), you indicate your acceptance of this License to do so, and
186+all its terms and conditions for copying, distributing or modifying
187+the Program or works based on it.
188+
189+ 6. Each time you redistribute the Program (or any work based on the
190+Program), the recipient automatically receives a license from the
191+original licensor to copy, distribute or modify the Program subject to
192+these terms and conditions. You may not impose any further
193+restrictions on the recipients' exercise of the rights granted herein.
194+You are not responsible for enforcing compliance by third parties to
195+this License.
196+
197+ 7. If, as a consequence of a court judgment or allegation of patent
198+infringement or for any other reason (not limited to patent issues),
199+conditions are imposed on you (whether by court order, agreement or
200+otherwise) that contradict the conditions of this License, they do not
201+excuse you from the conditions of this License. If you cannot
202+distribute so as to satisfy simultaneously your obligations under this
203+License and any other pertinent obligations, then as a consequence you
204+may not distribute the Program at all. For example, if a patent
205+license would not permit royalty-free redistribution of the Program by
206+all those who receive copies directly or indirectly through you, then
207+the only way you could satisfy both it and this License would be to
208+refrain entirely from distribution of the Program.
209+
210+If any portion of this section is held invalid or unenforceable under
211+any particular circumstance, the balance of the section is intended to
212+apply and the section as a whole is intended to apply in other
213+circumstances.
214+
215+It is not the purpose of this section to induce you to infringe any
216+patents or other property right claims or to contest validity of any
217+such claims; this section has the sole purpose of protecting the
218+integrity of the free software distribution system, which is
219+implemented by public license practices. Many people have made
220+generous contributions to the wide range of software distributed
221+through that system in reliance on consistent application of that
222+system; it is up to the author/donor to decide if he or she is willing
223+to distribute software through any other system and a licensee cannot
224+impose that choice.
225+
226+This section is intended to make thoroughly clear what is believed to
227+be a consequence of the rest of this License.
228+
229+ 8. If the distribution and/or use of the Program is restricted in
230+certain countries either by patents or by copyrighted interfaces, the
231+original copyright holder who places the Program under this License
232+may add an explicit geographical distribution limitation excluding
233+those countries, so that distribution is permitted only in or among
234+countries not thus excluded. In such case, this License incorporates
235+the limitation as if written in the body of this License.
236+
237+ 9. The Free Software Foundation may publish revised and/or new versions
238+of the General Public License from time to time. Such new versions will
239+be similar in spirit to the present version, but may differ in detail to
240+address new problems or concerns.
241+
242+Each version is given a distinguishing version number. If the Program
243+specifies a version number of this License which applies to it and "any
244+later version", you have the option of following the terms and conditions
245+either of that version or of any later version published by the Free
246+Software Foundation. If the Program does not specify a version number of
247+this License, you may choose any version ever published by the Free Software
248+Foundation.
249+
250+ 10. If you wish to incorporate parts of the Program into other free
251+programs whose distribution conditions are different, write to the author
252+to ask for permission. For software which is copyrighted by the Free
253+Software Foundation, write to the Free Software Foundation; we sometimes
254+make exceptions for this. Our decision will be guided by the two goals
255+of preserving the free status of all derivatives of our free software and
256+of promoting the sharing and reuse of software generally.
257+
258+ NO WARRANTY
259+
260+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268+REPAIR OR CORRECTION.
269+
270+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278+POSSIBILITY OF SUCH DAMAGES.
279+
280+ END OF TERMS AND CONDITIONS
281+
282+ How to Apply These Terms to Your New Programs
283+
284+ If you develop a new program, and you want it to be of the greatest
285+possible use to the public, the best way to achieve this is to make it
286+free software which everyone can redistribute and change under these terms.
287+
288+ To do so, attach the following notices to the program. It is safest
289+to attach them to the start of each source file to most effectively
290+convey the exclusion of warranty; and each file should have at least
291+the "copyright" line and a pointer to where the full notice is found.
292+
293+ <one line to give the program's name and a brief idea of what it does.>
294+ Copyright (C) <year> <name of author>
295+
296+ This program is free software; you can redistribute it and/or modify
297+ it under the terms of the GNU General Public License as published by
298+ the Free Software Foundation; either version 2 of the License, or
299+ (at your option) any later version.
300+
301+ This program is distributed in the hope that it will be useful,
302+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304+ GNU General Public License for more details.
305+
306+ You should have received a copy of the GNU General Public License
307+ along with this program; if not, write to the Free Software
308+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309+
310+
311+Also add information on how to contact you by electronic and paper mail.
312+
313+If the program is interactive, make it output a short notice like this
314+when it starts in an interactive mode:
315+
316+ Gnomovision version 69, Copyright (C) year name of author
317+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318+ This is free software, and you are welcome to redistribute it
319+ under certain conditions; type `show c' for details.
320+
321+The hypothetical commands `show w' and `show c' should show the appropriate
322+parts of the General Public License. Of course, the commands you use may
323+be called something other than `show w' and `show c'; they could even be
324+mouse-clicks or menu items--whatever suits your program.
325+
326+You should also get your employer (if you work as a programmer) or your
327+school, if any, to sign a "copyright disclaimer" for the program, if
328+necessary. Here is a sample; alter the names:
329+
330+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
332+
333+ <signature of Ty Coon>, 1 April 1989
334+ Ty Coon, President of Vice
335+
336+This General Public License does not permit incorporating your program into
337+proprietary programs. If your program is a subroutine library, you may
338+consider it more useful to permit linking proprietary applications with the
339+library. If this is what you want to do, use the GNU Library General
340+Public License instead of this License.
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/common.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/common.pl (revision 201)
@@ -0,0 +1,1589 @@
1+################################################################################
2+#
3+# FSWikiLite 共通関数ファイル
4+#
5+################################################################################
6+require "./lib/cgi-lib.pl";
7+require "./lib/jcode.pl";
8+require "./lib/mimew.pl";
9+require "./lib/setup.pl";
10+#-------------------------------------------------------------------------------
11+# ヘッダを表示
12+#-------------------------------------------------------------------------------
13+sub print_header {
14+ my $title = shift;
15+ my $show = shift;
16+
17+ print "Content-Type: text/html;charset=EUC-JP\n";
18+ print "Pragma: no-cache\n";
19+ print "Cache-Control: no-cache\n\n";
20+ print "<html>\n";
21+ print "<head>\n";
22+ print "<title>".&Util::escapeHTML($title)." - $SITE_TITLE</title>\n";
23+ print "<link rel=\"stylesheet\" type=\"text/css\" href=\"$THEME_URL\">\n";
24+ print "</head>\n";
25+ print "<body>\n";
26+
27+ print "<div class=\"adminmenu\">\n";
28+ print " <span class=\"adminmenu\">\n";
29+ print " <a href=\"".&Wiki::create_url({p=>"FrontPage"})."\">FrontPage</a>\n";
30+ print " <a href=\"".&Wiki::create_url({a=>"new"})."\">新規</a>\n";
31+ if($show==1){
32+ print " <a href=\"".&Wiki::create_url({a=>"edit",p=>$in{"p"}})."\">編集</a>\n";
33+ }
34+ print " <a href=\"".&Wiki::create_url({a=>"search"})."\">検索</a>\n";
35+ print " <a href=\"".&Wiki::create_url({a=>"list"})."\">一覧</a>\n";
36+ print " <a href=\"".&Wiki::create_url({p=>"Help"})."\">ヘルプ</a>\n";
37+ print " </span>\n";
38+ print "</div>\n";
39+
40+ print "<h1>".&Util::escapeHTML($title)."</h1>\n";
41+ if(&Wiki::page_exists("Menu")){
42+ print "<div class=\"main\">\n";
43+ }
44+}
45+
46+#-------------------------------------------------------------------------------
47+# フッタを表示
48+#-------------------------------------------------------------------------------
49+sub print_footer {
50+ if(&Wiki::page_exists("Menu")){
51+ print "</div>\n";
52+ print "<div class=\"sidebar\">\n";
53+ print &Wiki::process_wiki(&Wiki::get_page("Menu"));
54+ print "</div>\n";
55+ }
56+ print "<div class=\"footer\">Powered by <a href=\"".$main::SITE_URL."\">FreeStyleWikiLite ".$main::VERSION."</a></div>\n";
57+ print "</body></html>\n";
58+}
59+
60+#-------------------------------------------------------------------------------
61+# 旧Ver(0.0.11)互換性維持
62+# 次期バージョンで削除されます。
63+#-------------------------------------------------------------------------------
64+sub redirect { return &Wiki::redirect($@); }
65+sub redirectURL { return &Wiki::redirectURL($@); }
66+
67+package Wiki;
68+sub exists_page { return &page_exists(shift); }
69+sub send_mail { return &Util::send_mail($@); }
70+
71+package HTMLParser;
72+
73+package Util;
74+sub parse_plugin { return &Wiki::parse_inline_plugin($@); }
75+
76+###############################################################################
77+#
78+# Wiki関連の関数を提供するパッケージ
79+#
80+###############################################################################
81+package Wiki;
82+
83+local @current_parser = [];
84+
85+#==============================================================================
86+# プラグインの情報を取得します
87+#==============================================================================
88+sub get_plugin_info {
89+ my $name = shift;
90+ return defined($main::P_PLUGIN->{$name}) ? {FUNCTION=>$main::P_PLUGIN->{$name}, TYPE=>'paragraph'} :
91+ defined($main::I_PLUGIN->{$name}) ? {FUNCTION=>$main::I_PLUGIN->{$name}, TYPE=>'inline' } :
92+ defined($main::B_PLUGIN->{$name}) ? {FUNCTION=>$main::B_PLUGIN->{$name}, TYPE=>'block' } :
93+ {};
94+}
95+
96+#==============================================================================
97+# Wikiソースを渡してHTMLを取得します
98+#==============================================================================
99+sub process_wiki {
100+ my $source = shift;
101+ my $mainflg = shift;
102+ my $parser = HTMLParser->new($mainflg);
103+
104+ # 裏技用(プラグイン内部からパーサを使う場合)
105+ push(@current_parser, $parser);
106+
107+ $parser->parse($source);
108+
109+ # パーサの参照を解放
110+ pop(@current_parser);
111+
112+ return $parser->{html};
113+}
114+
115+#==============================================================================
116+# パース中の場合、現在有効なHTMLParserのインスタンスを返却します。
117+# パース中の内容をプラグインから変更したい場合に使用します。
118+#==============================================================================
119+sub get_current_parser {
120+ return $current_parser[$#current_parser];
121+}
122+
123+#===============================================================================
124+# インラインプラグインをパースしてコマンドと引数に分割
125+#===============================================================================
126+sub parse_inline_plugin {
127+ my $text = shift;
128+ my ($cmd, @args_tmp) = split(/ /,$text);
129+ my $args_txt = &Util::trim(join(" ",@args_tmp));
130+ if($cmd =~ s/\}\}(.*?)$//){
131+ return { command=>$cmd, args=>[], post=>"$1 $args_txt"};
132+ }
133+
134+ my @ret_args;
135+ my $tmp = "";
136+ my $escape = 0;
137+ my $quote = 0;
138+ my $i = 0;
139+
140+ for($i = 0; $i<length($args_txt); $i++){
141+ my $c = substr($args_txt,$i,1);
142+ if($quote!=1 && $c eq ","){
143+ if($quote==3){
144+ $tmp .= '}';
145+ }
146+ push(@ret_args,$tmp);
147+ $tmp = "";
148+ $quote = 0;
149+ } elsif($quote==1 && $c eq "\\"){
150+ if($escape==0){
151+ $escape = 1;
152+ } else {
153+ $tmp .= $c;
154+ $escape = 0;
155+ }
156+ } elsif($quote==0 && $c eq '"'){
157+ if($tmp eq ""){
158+ $quote = 1;
159+ } else {
160+ $tmp .= $c;
161+ }
162+ } elsif($quote==1 && $c eq '"'){
163+ if($escape==1){
164+ $tmp .= $c;
165+ $escape = 0;
166+ } else {
167+ $quote = 2;
168+ }
169+ } elsif(($quote==0 || $quote==2) && $c eq '}'){
170+ $quote = 3;
171+ } elsif($quote==3){
172+ if($c eq '}'){
173+ last;
174+ } else {
175+ $tmp .= '}'.$c;
176+ $quote = 0;
177+ }
178+ } elsif($quote==2){
179+ return {error=>"インラインプラグインの構文が不正です。"};
180+ } else {
181+ $tmp .= $c;
182+ $escape = 0;
183+ }
184+ }
185+
186+ if($quote!=3){
187+ my $info = &Wiki::get_plugin_info($cmd);
188+ return undef if (defined($info->{TYPE}) && $info->{TYPE} ne 'block');
189+ }
190+
191+ if($tmp ne ""){
192+ push(@ret_args,$tmp);
193+ }
194+
195+ return { command=>$cmd, args=>\@ret_args,
196+ post=>substr($args_txt, $i + 1, length($args_txt) - $i)};
197+}
198+
199+#==============================================================================
200+# ページ表示のURLを生成
201+#==============================================================================
202+sub create_page_url {
203+ my $page = shift;
204+ return create_url({p=>$page});
205+}
206+
207+#==============================================================================
208+# 任意のURLを生成
209+#==============================================================================
210+sub create_url {
211+ my $params = shift;
212+ my $script = shift;
213+ my $url = '';
214+ my $query = '';
215+ my $action = '';
216+ foreach my $key (keys(%$params)){
217+ my $val = $params->{$key};
218+ if ($key eq 'a') {
219+ $action = $val;
220+ }
221+ if($query ne ''){
222+ $query .= '&amp;';
223+ }
224+ $query .= Util::url_encode($key)."=".Util::url_encode($val);
225+ }
226+ if(!defined($script)){
227+ if ($action =~ /^(edit|new|delconf)$/){
228+ $script = $main::EDIT_SCRIPT;
229+ }else{
230+ $script = $main::MAIN_SCRIPT;
231+ }
232+ }
233+ $url = $script;
234+ if($query ne ''){
235+ $url .= '?'.$query;
236+ }
237+ return $url;
238+}
239+
240+#==============================================================================
241+# ページの一覧を取得
242+#==============================================================================
243+sub get_page_list {
244+ opendir(DIR, $main::DATA_DIR);
245+ my ($fileentry, @files);
246+ while($fileentry = readdir(DIR)){
247+ my $type = substr($fileentry,rindex($fileentry,"."));
248+ if($type eq ".wiki"){
249+ push(@files, "$main::DATA_DIR/$fileentry");
250+ }
251+ }
252+ closedir(DIR);
253+
254+ my @pages;
255+ foreach my $entry (@files){
256+ my @stat = stat($entry);
257+ my $time = $stat[9];
258+
259+ $entry = substr($entry,length($main::DATA_DIR)+1);
260+ $entry =~ /(.+?)\.wiki/;
261+ my $page = &Util::url_decode($1);
262+ push(@pages,{NAME=>$page,TIME=>$time});
263+ }
264+
265+ @pages = sort { $b->{TIME}<=>$a->{TIME} } @pages;
266+ return @pages;
267+}
268+
269+#==============================================================================
270+# ページの更新日時を取得
271+#==============================================================================
272+sub get_last_modified {
273+ my $page = shift;
274+ if(&page_exists($page)){
275+ my $file = sprintf("%s/%s.wiki",$main::DATA_DIR,&Util::url_encode($page));
276+ my @stat = stat($file);
277+ return $stat[9];
278+ } else {
279+ return undef;
280+ }
281+}
282+
283+#==============================================================================
284+# ページを取得
285+#==============================================================================
286+sub get_page {
287+ my $page = &Util::url_encode(shift);
288+
289+ open(DATA,"$main::DATA_DIR/$page.wiki") or &Util::error("$main::DATA_DIR/$page.wikiのオープンに失敗しました。");
290+ my $content = "";
291+ while(<DATA>){
292+ $content .= $_;
293+ }
294+ close(DATA);
295+
296+ return $content;
297+}
298+#==============================================================================
299+# ページを保存
300+#==============================================================================
301+sub save_page {
302+ my $page = shift;
303+ my $source = shift;
304+
305+ $page = &Util::trim($page);
306+ $source =~ s/\r\n/\n/g;
307+ $source =~ s/\r/\n/g;
308+
309+ my $enc_page = &Util::url_encode($page);
310+ my $action = 'MODIFY';
311+ unless(-e "$main::DATA_DIR/$enc_page.wiki"){
312+ $action = 'CREATE';
313+ }
314+
315+ # バックアップファイルを作成
316+ if(-e "$main::DATA_DIR/$enc_page.wiki"){
317+ open(BACKUP,">$main::BACKUP_DIR/$enc_page.bak") or &Util::error("$main::BACKUP_DIR/$enc_page.bakのオープンに失敗しました。");
318+ open(DATA ,"$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。");
319+ while(<DATA>){
320+ print BACKUP $_;
321+ }
322+ close(DATA);
323+ close(BACKUP);
324+ }
325+
326+ # 入力内容を保存
327+ open(DATA,">$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiのオープンに失敗しました。");
328+ print DATA $source;
329+ close(DATA);
330+
331+ &Util::send_mail($action,$page);
332+}
333+
334+#==============================================================================
335+# ページが存在するかどうか
336+#==============================================================================
337+sub page_exists {
338+ my $page = &Util::url_encode(shift);
339+ if(-e "$main::DATA_DIR/$page.wiki"){
340+ return 1;
341+ } else {
342+ return 0;
343+ }
344+}
345+
346+#==============================================================================
347+# 引数で渡したページに遷移
348+#==============================================================================
349+sub redirect {
350+ my $page = shift;
351+ my $url = &Wiki::create_url({p=>$page});
352+ &redirectURL($url);
353+}
354+
355+#==============================================================================
356+# 引数で渡したURLに遷移
357+#==============================================================================
358+sub redirectURL {
359+ my $url = shift;
360+
361+ print "Content-Type: text/html;charset=EUC-JP\n";
362+ print "Pragma: no-cache\n";
363+ print "Cache-Control: no-cache\n\n";
364+ print "<html>\n";
365+ print " <head>\n";
366+ print " <title>moving...</title>\n";
367+ print " <meta http-equiv=\"Refresh\" content=\"0;URL=$url\">\n";
368+ print " </head>\n";
369+ print " <body>\n";
370+ print " Wait or <a href=\"$url\">Click Here!!</a>\n";
371+ print " </body>\n";
372+ print "</html>\n";
373+
374+ exit;
375+}
376+
377+#==============================================================================
378+# ページを削除
379+#==============================================================================
380+sub remove_page {
381+ my $page = shift;
382+ my $enc_page = &Util::url_encode($page);
383+ unlink("$main::DATA_DIR/$enc_page.wiki") or &Util::error("$main::DATA_DIR/$enc_page.wikiの削除に失敗しました。");
384+
385+ &Util::send_mail('DELETE',$page);
386+}
387+
388+###############################################################################
389+#
390+# HTMLパーサ
391+#
392+###############################################################################
393+package HTMLParser;
394+#==============================================================================
395+# コンストラクタ
396+#==============================================================================
397+sub new {
398+ my $class = shift;
399+ my $mainflg = shift;
400+ my $self = {};
401+
402+ if(!defined($mainflg) || $mainflg eq ""){ $mainflg = 0; }
403+
404+ $self->{dl_flag} = 0;
405+ $self->{dt} = "";
406+ $self->{dd} = "";
407+
408+ $self->{html} = "";
409+ $self->{pre} = "";
410+ $self->{quote} = "";
411+ $self->{table} = 0;
412+ $self->{level} = 0;
413+ $self->{list} = 0;
414+ $self->{para} = 0;
415+ $self->{p_cnt} = 0;
416+ $self->{main} = $mainflg;
417+ return bless $self,$class;
418+}
419+
420+#===============================================================================
421+# パース
422+#===============================================================================
423+sub parse {
424+ my $self = shift;
425+ my $source = shift;
426+
427+ $self->start_parse;
428+ $source =~ s/\r//g;
429+
430+ my @lines = split(/\n/,$source);
431+
432+ foreach my $line (@lines){
433+ chomp $line;
434+
435+ # 複数行の説明
436+ $self->multi_explanation($line);
437+
438+ my $word1 = substr($line,0,1);
439+ my $word2 = substr($line,0,2);
440+ my $word3 = substr($line,0,3);
441+
442+ # 空行
443+ if($line eq "" && !$self->{block}){
444+ $self->l_paragraph();
445+ next;
446+ }
447+
448+ # ブロック書式のエスケープ
449+ if($word2 eq "\\\\" || $word1 eq "\\"){
450+ my @obj = $self->parse_line(substr($line, 1));
451+ $self->l_text(\@obj);
452+ next;
453+ }
454+
455+ # パラグラフプラグイン
456+ if($line =~ /^\{\{(.+\}\})$/){
457+ if(!$self->{block}){
458+ my $plugin = &Wiki::parse_inline_plugin($1);
459+ my $info = &Wiki::get_plugin_info($plugin->{command});
460+ if($info->{TYPE} eq "paragraph"){
461+ $self->l_plugin($plugin);
462+ } else {
463+ my @obj = $self->parse_line($line);
464+ $self->l_text(\@obj);
465+ }
466+ next;
467+ }
468+ } elsif($line =~ /^\{\{(.+)$/){
469+ if ($self->{block}) {
470+ my $plugin = &Wiki::parse_inline_plugin($1);
471+ my $info = &Wiki::get_plugin_info($plugin->{command});
472+ $self->{block}->{level}++ if($info->{TYPE} eq "block");
473+ $self->{block}->{args}->[0] .= $line."\n";
474+ next;
475+ }
476+ my $plugin = &Wiki::parse_inline_plugin($1);
477+ my $info = &Wiki::get_plugin_info($plugin->{command});
478+ if($info->{TYPE} eq "block"){
479+ unshift(@{$plugin->{args}}, "");
480+ $self->{block} = $plugin;
481+ $self->{block}->{level} = 0;
482+ } else {
483+ my @obj = $self->parse_line($line);
484+ $self->l_text(\@obj);
485+ }
486+ next;
487+ }
488+ if($self->{block}){
489+ if($line eq "}}"){
490+ if ($self->{block}->{level} > 0) {
491+ $self->{block}->{level}--;
492+ $self->{block}->{args}->[0] .= $line."\n";
493+ next;
494+ }
495+ my $plugin = $self->{block};
496+ delete($self->{block});
497+ $self->l_plugin($plugin);
498+ } else {
499+ $self->{block}->{args}->[0] .= $line."\n";
500+ }
501+ next;
502+ }
503+
504+ # PRE
505+ if($word1 eq " " || $word1 eq "\t"){
506+ $self->l_verbatim($line);
507+
508+ # 見出し
509+ } elsif($word3 eq "!!!"){
510+ my @obj = $self->parse_line(substr($line,3));
511+ $self->l_headline(1,\@obj);
512+
513+ } elsif($word2 eq "!!"){
514+ my @obj = $self->parse_line(substr($line,2));
515+ $self->l_headline(2,\@obj);
516+
517+ } elsif($word1 eq "!"){
518+ my @obj = $self->parse_line(substr($line,1));
519+ $self->l_headline(3,\@obj);
520+
521+ # 項目
522+ } elsif($word3 eq "***"){
523+ my @obj = $self->parse_line(substr($line,3));
524+ $self->l_list(3,\@obj);
525+
526+ } elsif($word2 eq "**"){
527+ my @obj = $self->parse_line(substr($line,2));
528+ $self->l_list(2,\@obj);
529+
530+ } elsif($word1 eq "*"){
531+ my @obj = $self->parse_line(substr($line,1));
532+ $self->l_list(1,\@obj);
533+
534+ # 番号付き項目
535+ } elsif($word3 eq "+++"){
536+ my @obj = $self->parse_line(substr($line,3));
537+ $self->l_numlist(3,\@obj);
538+
539+ } elsif($word2 eq "++"){
540+ my @obj = $self->parse_line(substr($line,2));
541+ $self->l_numlist(2,\@obj);
542+
543+ } elsif($word1 eq "+"){
544+ my @obj = $self->parse_line(substr($line,1));
545+ $self->l_numlist(1,\@obj);
546+
547+ # 水平線
548+ } elsif($line eq "----"){
549+ $self->l_line();
550+
551+ # 引用
552+ } elsif($word2 eq '""'){
553+ my @obj = $self->parse_line(substr($line,2));
554+ $self->l_quotation(\@obj);
555+
556+ # 説明
557+ } elsif(index($line,":")==0 && index($line,":",1)!=-1){
558+ if(index($line,":::")==0){
559+ $self->{dd} .= substr($line,3);
560+ next;
561+ }
562+ if($self->{dt} ne "" || $self->{dd} ne ""){
563+ $self->multi_explanation;
564+ }
565+ if(index($line,"::")==0){
566+ $self->{dt} = substr($line,2);
567+ $self->{dl_flag} = 1;
568+ next;
569+ }
570+ my $dt = substr($line,1,index($line,":",1)-1);
571+ my $dd = substr($line,index($line,":",1)+1);
572+ my @obj1 = $self->parse_line($dt);
573+ my @obj2 = $self->parse_line($dd);
574+ $self->l_explanation(\@obj1,\@obj2);
575+
576+ # テーブル
577+ } elsif($word1 eq ","){
578+ if($line =~ /,$/){
579+ $line .= " ";
580+ }
581+ my @spl = map {/^"(.*)"$/ ? scalar($_ = $1, s/\"\"/\"/g, $_) : $_}
582+ ($line =~ /,\s*(\"[^\"]*(?:\"\"[^\"]*)*\"|[^,]*)/g);
583+ my @array;
584+ foreach my $value (@spl){
585+ my @cell = $self->parse_line($value);
586+ push @array,\@cell;
587+ }
588+ $self->l_table(\@array);
589+
590+ # コメント
591+ } elsif($word2 eq "//"){
592+
593+ # 何もない行
594+ } else {
595+ my @obj = $self->parse_line($line);
596+ $self->l_text(\@obj);
597+ }
598+ }
599+
600+ # 複数行の説明
601+ $self->multi_explanation;
602+
603+ # パース中のブロックプラグインがあった場合、とりあえず評価しておく?
604+ if($self->{block}){
605+ my $plugin = $self->{block};
606+ delete($self->{block});
607+ $self->l_plugin($plugin);
608+ }
609+
610+ $self->end_parse;
611+}
612+
613+#===============================================================================
614+# 複数行の説明
615+#===============================================================================
616+sub multi_explanation {
617+ my $self = shift;
618+ my $line = shift;
619+ if($self->{dl_flag}==1 && (index($line,":")!=0 || !defined($line))){
620+ my @obj1 = $self->parse_line($self->{dt});
621+ my @obj2 = $self->parse_line($self->{dd});
622+ $self->l_explanation(\@obj1,\@obj2);
623+ $self->{dl_flag} = 0;
624+ $self->{dt} = "";
625+ $self->{dd} = "";
626+ }
627+}
628+
629+#===============================================================================
630+# 1行分をパース
631+#===============================================================================
632+sub parse_line {
633+ my ($self, $source) = @_;
634+
635+ return () if (not defined $source);
636+
637+ my @array = ();
638+ my $pre = q{};
639+ my @parsed = ();
640+
641+ # $source が空になるまで繰り返す。
642+ SOURCE:
643+ while ($source ne q{}) {
644+
645+ # どのインライン Wiki 書式の先頭にも match しない場合
646+ if (!($source =~ /^(.*?)((?:\{\{|\[\[?|https?:|mailto:|f(?:tp:|ile:)|'''?|==|__|<<).*)$/)) {
647+ # WikiName検索・置換処理のみ実施して終了する
648+ push @array, $self->_parse_line_wikiname($pre . $source);
649+ return @array;
650+ }
651+
652+ $pre .= $1; # match しなかった先頭部分は溜めておいて後で処理する
653+ $source = $2; # match 部分は後続処理にて詳細チェックを行う
654+ @parsed = ();
655+
656+ # プラグイン
657+ if ($source =~ /^\{\{/) {
658+ $source = $';
659+ my $plugin = &Wiki::parse_inline_plugin($source);
660+ unless($plugin){
661+ push @parsed, '{{';
662+ push @parsed, $self->parse_line($source);
663+ } else {
664+ my $info = &Wiki::get_plugin_info($plugin->{command});
665+ if($info->{TYPE} eq "inline"){
666+ push @parsed, $self->plugin($plugin);
667+ } else {
668+ push @parsed, $self->parse_line("<<".$plugin->{command}."プラグインは存在しません。>>");
669+ }
670+ if ($source ne "") {
671+ $source = $plugin->{post};
672+ }
673+ }
674+ }
675+
676+ # ページ別名リンク
677+ elsif ($source =~ /^\[\[([^\[]+?)\|([^\|\[]+?)\]\]/) {
678+ my $label = $1;
679+ my $page = $2;
680+ $source = $';
681+ push @parsed, $self->wiki_anchor($page, $label);
682+ }
683+
684+ # URL別名リンク
685+ elsif ($source
686+ =~ /^\[([^\[]+?)\|((?:http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*)\]/
687+ || $source =~ /^\[([^\[]+?)\|(file:[^\[\]]*)\]/
688+ || $source
689+ =~ /^\[([^\[]+?)\|((?:\/|\.\/|\.\.\/)+[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*)\]/
690+ )
691+ {
692+ my $label = $1;
693+ my $url = $2;
694+ $source = $';
695+ if ( index($url, q{"}) >= 0
696+ || index($url, '><') >= 0
697+ || index($url, 'javascript:') >= 0)
698+ {
699+ push @parsed, $self->parse_line('<<不正なリンクです。>>');
700+ }
701+ else {
702+ push @parsed, $self->url_anchor($url, $label);
703+ }
704+ }
705+
706+ # URLリンク
707+ elsif ($source
708+ =~ /^(?:https?|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!&=:;\*#\@'\$]*/
709+ || $source =~ /^file:[^\[\]]*/)
710+ {
711+ my $url = $&;
712+ $source = $';
713+ if ( index($url, q{"}) >= 0
714+ || index($url, '><') >= 0
715+ || index($url, 'javascript:') >= 0)
716+ {
717+ push @parsed, $self->parse_line('<<不正なリンクです。>>');
718+ }
719+ else {
720+ push @parsed, $self->url_anchor($url);
721+ }
722+ }
723+
724+ # ページリンク
725+ elsif ($source =~ /^\[\[([^\|]+?)\]\]/) {
726+ my $page = $1;
727+ $source = $';
728+ push @parsed, $self->wiki_anchor($page);
729+ }
730+
731+ # 任意のURLリンク
732+ elsif ($source =~ /^\[([^\[]+?)\|(.+?)\]/) {
733+ my $label = $1;
734+ my $url = $2;
735+ $source = $';
736+ if ( index($url, q{"}) >= 0
737+ || index($url, '><') >= 0
738+ || index($url, 'javascript:') >= 0)
739+ {
740+ push @parsed, $self->parse_line('<<不正なリンクです。>>');
741+ }
742+ else {
743+ # URIを作成
744+ my $uri = &main::MyBaseUrl().$ENV{"PATH_INFO"};
745+ push @parsed, $self->url_anchor($uri . '/../' . $url, $label);
746+ }
747+ }
748+
749+ # ボールド、イタリック、取り消し線、下線
750+ elsif ($source =~ /^('''?|==|__)(.+?)\1/) {
751+ my $type = $1;
752+ my $label = $2;
753+ $source = $';
754+ if ($type eq q{'''}) {
755+ push @parsed, $self->bold($label);
756+ }
757+ elsif ($type eq q{__}) {
758+ push @parsed, $self->underline($label);
759+ }
760+ elsif ($type eq q{''}) {
761+ push @parsed, $self->italic($label);
762+ }
763+ else { ## elsif ($type eq q{==}) {
764+ push @parsed, $self->denialline($label);
765+ }
766+ }
767+
768+ # エラーメッセージ
769+ elsif ($source =~ /^<<(.+?)>>/) {
770+ my $label = $1;
771+ $source = $';
772+ push @parsed, $self->error($label);
773+ }
774+
775+ # インライン Wiki 書式全体には macth しなかったとき
776+ else {
777+ # 1 文字進む。
778+ if ($source =~ /^(.)/) {
779+ $pre .= $1;
780+ $source = $';
781+ }
782+
783+ # parse 結果を @array に保存する処理を飛ばして繰り返し。
784+ next SOURCE;
785+ }
786+
787+ # インライン Wiki 書式全体に macth した後の
788+ # parse 結果を @array に保存する処理。
789+
790+ # もし $pre が溜まっているなら、WikiNameの処理を実施。
791+ if ($pre ne q{}) {
792+ push @array, $self->_parse_line_wikiname($pre);
793+ $pre = q{};
794+ }
795+
796+ push @array, @parsed;
797+ }
798+
799+ # もし $pre が溜まっているなら、WikiNameの処理を実施。
800+ if ($pre ne q{}) {
801+ push @array, $self->_parse_line_wikiname($pre);
802+ }
803+
804+ return @array;
805+}
806+
807+#========================================================================
808+# parse_line() から呼び出され、WikiNameの検索・置換処理を行います。
809+#========================================================================
810+sub _parse_line_wikiname {
811+ my $self = shift;
812+ my $source = shift;
813+
814+ return () if (not defined $source);
815+
816+ my @array = ();
817+
818+ # $source が空になるまで繰り返す。
819+ while ($source ne q{}) {
820+
821+ # WikiName
822+ if ($main::WIKI_NAME == 1 && $source =~ /[A-Z]+?[a-z]+?(?:[A-Z]+?[a-z]+)+/) {
823+ my $pre = $`;
824+ my $page = $&;
825+ $source = $';
826+ if ($pre ne q{}) {
827+ push @array, $self->_parse_line_wikiname($pre);
828+ }
829+ push @array, $self->wiki_anchor($page);
830+ }
831+
832+ # WikiName も見つからなかったとき
833+ else {
834+ push @array, $self->text($source);
835+ return @array;
836+ }
837+ }
838+ return @array;
839+}
840+
841+#===============================================================================
842+# <p>
843+# パースを開始前に呼び出されます。
844+# サブクラスで必要な処理がある場合はオーバーライドしてください。
845+# </p>
846+#===============================================================================
847+sub start_parse {}
848+
849+#==============================================================================
850+# リスト
851+#==============================================================================
852+sub l_list {
853+ my $self = shift;
854+ my $level = shift;
855+ my $obj = shift;
856+
857+ if($self->{para}==1){
858+ $self->{html} .= "</p>\n";
859+ $self->{para} = 0;
860+ }
861+
862+ if($self->{list} == 1 && $level <= $self->{level}){
863+ $self->end_list;
864+ }
865+ $self->{list} = 0;
866+
867+ $self->end_verbatim;
868+ $self->end_table;
869+ $self->end_quote;
870+
871+ my $html = join("",@$obj);
872+
873+ if($level > $self->{level}){
874+ while($level != $self->{level}){
875+ $self->{html} .= "<ul>\n";
876+ push(@{$self->{close_list}},"</ul>\n");
877+ $self->{level}++;
878+ }
879+ } elsif($level <= $self->{level}){
880+ while($level-1 != $self->{level}){
881+ if($self->{'list_close_'.$self->{level}} == 1){
882+ $self->{html} .= "</li>\n";
883+ $self->{'list_close_'.$self->{level}} = 0;
884+ }
885+ if($level == $self->{level}){
886+ last;
887+ }
888+ $self->{html} .= pop(@{$self->{close_list}});
889+ $self->{level}--;
890+ }
891+ }
892+
893+ $self->{html} .= "<li>".$html;
894+ $self->{'list_close_'.$level} = 1;
895+}
896+
897+#==============================================================================
898+# 番号付きリスト
899+#==============================================================================
900+sub l_numlist {
901+ my $self = shift;
902+ my $level = shift;
903+ my $obj = shift;
904+
905+ if($self->{para}==1){
906+ $self->{html} .= "</p>\n";
907+ $self->{para} = 0;
908+ }
909+
910+ if($self->{list} == 0 && $level <= $self->{level}){
911+ $self->end_list;
912+ }
913+ $self->{list} = 1;
914+
915+ $self->end_verbatim;
916+ $self->end_table;
917+ $self->end_quote;
918+
919+ my $html = join("",@$obj);
920+
921+ if($level > $self->{level}){
922+ while($level != $self->{level}){
923+ $self->{html} .= "<ol>\n";
924+ push(@{$self->{close_list}},"</ol>\n");
925+ $self->{level}++;
926+ }
927+ } elsif($level <= $self->{level}){
928+ while($level-1 != $self->{level}){
929+ if($self->{'list_close_'.$self->{level}} == 1){
930+ $self->{html} .= "</li>\n";
931+ $self->{'list_close_'.$self->{level}} = 0;
932+ }
933+ if($level == $self->{level}){
934+ last;
935+ }
936+ $self->{html} .= pop(@{$self->{close_list}});
937+ $self->{level}--;
938+ }
939+ }
940+
941+ $self->{html} .= "<li>".$html;
942+ $self->{'list_close_'.$level} = 1;
943+}
944+
945+#==============================================================================
946+# リストの終了
947+#==============================================================================
948+sub end_list {
949+ my $self = shift;
950+ while($self->{level} != 0){
951+ if($self->{'list_close_'.($self->{level})} == 1){
952+ $self->{html} .= "</li>\n";
953+ $self->{'list_close_'.$self->{level}} = 0;
954+ }
955+ $self->{html} .= pop(@{$self->{close_list}});
956+ $self->{level}--;
957+ }
958+}
959+
960+#==============================================================================
961+# ヘッドライン
962+#==============================================================================
963+sub l_headline {
964+ my $self = shift;
965+ my $level = shift;
966+ my $obj = shift;
967+
968+ if($self->{para}==1){
969+ $self->{html} .= "</p>\n";
970+ $self->{para} = 0;
971+ }
972+
973+ $self->end_list;
974+ $self->end_verbatim;
975+ $self->end_table;
976+ $self->end_quote;
977+
978+ my $html = join("",@$obj);
979+
980+ # メインの表示領域でないとき
981+ if(!$self->{main}){
982+ $self->{html} .= "<h".($level+1).">".$html."</h".($level+1).">\n";
983+
984+ # メインの表示領域の場合はアンカを出力
985+ } else {
986+ if($level==2){
987+ $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\"><span class=\"sanchor\">&nbsp;</span>".
988+ $html."</a></h".($level+1).">\n";
989+ } else {
990+ $self->{html} .= "<h".($level+1)."><a name=\"p".$self->{p_cnt}."\">".$html."</a></h".($level+1).">\n";
991+ }
992+ }
993+ $self->{p_cnt}++;
994+}
995+
996+#==============================================================================
997+# 水平線
998+#==============================================================================
999+sub l_line {
1000+ my $self = shift;
1001+
1002+ if($self->{para}==1){
1003+ $self->{html} .= "</p>\n";
1004+ $self->{para} = 0;
1005+ }
1006+
1007+ $self->end_list;
1008+ $self->end_verbatim;
1009+ $self->end_table;
1010+ $self->end_quote;
1011+
1012+ $self->{html} .= "<hr>\n";
1013+}
1014+
1015+#==============================================================================
1016+# 段落区切り
1017+#==============================================================================
1018+sub l_paragraph {
1019+ my $self = shift;
1020+
1021+ $self->end_list;
1022+ $self->end_verbatim;
1023+ $self->end_table;
1024+ $self->end_quote;
1025+
1026+ if($self->{para}==1){
1027+ $self->{html} .= "</p>\n";
1028+ $self->{para} = 0;
1029+ } elsif($main::BR_MODE==1){
1030+ $self->{html} .= "<br>\n";
1031+ }
1032+}
1033+
1034+#==============================================================================
1035+# 整形済テキスト
1036+#==============================================================================
1037+sub l_verbatim {
1038+ my $self = shift;
1039+ my $text = shift;
1040+
1041+ if($self->{para}==1){
1042+ $self->{html} .= "</p>\n";
1043+ $self->{para} = 0;
1044+ }
1045+
1046+ $self->end_list;
1047+ $self->end_table;
1048+ $self->end_quote;
1049+
1050+ $text =~ s/^\s//;
1051+ $self->{pre} .= Util::escapeHTML($text)."\n";
1052+}
1053+
1054+sub end_verbatim {
1055+ my $self = shift;
1056+ if($self->{pre} ne ""){
1057+ $self->{html} .= "<pre>".$self->{pre}."</pre>\n";
1058+ $self->{pre} = "";
1059+ }
1060+}
1061+
1062+#==============================================================================
1063+# テーブル
1064+#==============================================================================
1065+sub l_table {
1066+ my $self = shift;
1067+ my $row = shift;
1068+ $self->end_list;
1069+ $self->end_verbatim;
1070+ $self->end_quote;
1071+
1072+ my $tag = "td";
1073+
1074+ if($self->{table}==0){
1075+ $self->{table}=1;
1076+ $self->{html} .= "<table>\n";
1077+ $tag = "th";
1078+ } else {
1079+ $self->{table}=2;
1080+ }
1081+
1082+ my @columns = ();
1083+ foreach(@$row){
1084+ my $html = join("",@$_);
1085+ if($#columns != -1 && $html eq '&lt;&lt;'){
1086+ @columns[$#columns]->{colspan}++;
1087+ } else {
1088+ push(@columns, {colspan => 1, html => $html});
1089+ }
1090+ }
1091+ $self->{html} .= "<tr>\n";
1092+ foreach(@columns){
1093+ $self->{html} .= "<$tag colspan=\"".$_->{colspan}."\">".$_->{html}."</$tag>\n";
1094+ }
1095+ $self->{html} .= "</tr>\n";
1096+}
1097+
1098+sub end_table {
1099+ my $self = shift;
1100+ if($self->{table}!=0){
1101+ $self->{table} = 0;
1102+ $self->{html} .= "</table>\n";
1103+ }
1104+}
1105+
1106+#==============================================================================
1107+# パース終了時の処理
1108+#==============================================================================
1109+sub end_parse {
1110+ my $self = shift;
1111+ $self->end_list;
1112+ $self->end_verbatim;
1113+ $self->end_table;
1114+ $self->end_quote;
1115+
1116+ if($self->{para}==1){
1117+ $self->{html} .= "</p>\n";
1118+ $self->{para} = 0;
1119+ }
1120+}
1121+
1122+#==============================================================================
1123+# 行書式に該当しない行
1124+#==============================================================================
1125+sub l_text {
1126+ my $self = shift;
1127+ my $obj = shift;
1128+ $self->end_list;
1129+ $self->end_verbatim;
1130+ $self->end_table;
1131+ $self->end_quote;
1132+ my $html = join("",@$obj);
1133+
1134+ if($self->{para}==0){
1135+ $self->{html} .= "<p>";
1136+ $self->{para} = 1;
1137+ }
1138+ $self->{html} .= $html;
1139+
1140+ # brモードに設定されている場合は<br>を足す
1141+ if($main::BR_MODE==1){
1142+ $self->{html} .= "<br>\n";
1143+ }
1144+}
1145+
1146+#==============================================================================
1147+# 引用
1148+#==============================================================================
1149+sub l_quotation {
1150+ my $self = shift;
1151+ my $obj = shift;
1152+ $self->end_list;
1153+ $self->end_verbatim;
1154+ $self->end_table;
1155+ my $html = join("",@$obj);
1156+ $self->{quote} .= "<p>".$html."</p>\n";
1157+}
1158+
1159+sub end_quote {
1160+ my $self = shift;
1161+ if($self->{quote} ne ""){
1162+ $self->{html} .= "<blockquote>".$self->{quote}."</blockquote>\n";
1163+ $self->{quote} = "";
1164+ }
1165+}
1166+
1167+#==============================================================================
1168+# 説明
1169+#==============================================================================
1170+sub l_explanation {
1171+ my $self = shift;
1172+ my $obj1 = shift;
1173+ my $obj2 = shift;
1174+
1175+ $self->end_list;
1176+ $self->end_verbatim;
1177+ $self->end_table;
1178+ $self->end_quote;
1179+
1180+ my $html1 = join("",@$obj1);
1181+ my $html2 = join("",@$obj2);
1182+
1183+ $self->{html} .= "<dl>\n<dt>".$html1."</dt>\n<dd>".$html2."</dd>\n</dl>\n";
1184+}
1185+
1186+#==============================================================================
1187+# ボールド
1188+#==============================================================================
1189+sub bold {
1190+ my $self = shift;
1191+ my $text = shift;
1192+ return "<strong>".join("",$self->parse_line($text))."</strong>";
1193+}
1194+
1195+#==============================================================================
1196+# イタリック
1197+#==============================================================================
1198+sub italic {
1199+ my $self = shift;
1200+ my $text = shift;
1201+ return "<em>".join("",$self->parse_line($text))."</em>";
1202+}
1203+
1204+#==============================================================================
1205+# 下線
1206+#==============================================================================
1207+sub underline {
1208+ my $self = shift;
1209+ my $text = shift;
1210+ return "<ins>".join("",$self->parse_line($text))."</ins>";
1211+}
1212+
1213+#==============================================================================
1214+# 打ち消し線
1215+#==============================================================================
1216+sub denialline {
1217+ my $self = shift;
1218+ my $text = shift;
1219+ return "<del>".join("",$self->parse_line($text))."</del>";
1220+}
1221+
1222+#==============================================================================
1223+# URLアンカ
1224+#==============================================================================
1225+sub url_anchor {
1226+ my $self = shift;
1227+ my $url = shift;
1228+ my $name = shift;
1229+
1230+ if($name eq ""){
1231+ $name = $url;
1232+ }
1233+
1234+ if($url eq $name && $url=~/\.(gif|jpg|jpeg|bmp|png)$/i && $main::DISPLAY_IMAGE==1){
1235+ return "<img src=\"".$url."\">";
1236+ } else {
1237+ return "<a href=\"$url\">".Util::escapeHTML($name)."</a>";
1238+ }
1239+}
1240+
1241+#==============================================================================
1242+# Wikiページへのアンカ
1243+#==============================================================================
1244+sub wiki_anchor {
1245+ my $self = shift;
1246+ my $page = shift;
1247+ my $name = shift;
1248+
1249+ my $anchor = undef;
1250+ my $ppage = $page;
1251+
1252+ if(!defined($name) || $name eq ""){
1253+ $name = $page;
1254+ }
1255+
1256+ if(&Wiki::page_exists($page)){
1257+ #アンカーを含むページが存在する場合はリンクを優先
1258+ return "<a href=\"".&Wiki::create_page_url($page)."\" class=\"wikipage\">".
1259+ &Util::escapeHTML($name)."</a>";
1260+ } else {
1261+ #最後の"#"以降をアンカーとする
1262+ if($page =~ m/#([^#]+)$/) {
1263+ $page = $`;
1264+ $anchor = $1;
1265+ }
1266+ if(defined($anchor) && $page eq '') {
1267+ #同一ページのアンカーリンク
1268+ return "<a href=\"#$anchor\" class=\"wikipage\">".
1269+ &Util::escapeHTML($name)."</a>";
1270+ } elsif(&Wiki::page_exists($page)) {
1271+ #指定ページのアンカーリンク
1272+ return "<a href=\"".&Wiki::create_page_url($page).(defined($anchor)?"#".$anchor:"")."\" class=\"wikipage\">".
1273+ &Util::escapeHTML($name)."</a>";
1274+ } else {
1275+ #新規ページ作成用リンク
1276+ return "<span class=\"nopage\">".&Util::escapeHTML($name)."</span>".
1277+ "<a href=\"".&Wiki::create_page_url($page)."\">?</a>";
1278+ }
1279+ }
1280+}
1281+
1282+#==============================================================================
1283+# ただのテキスト
1284+#==============================================================================
1285+sub text {
1286+ my $self = shift;
1287+ my $text = shift;
1288+ return &Util::escapeHTML($text);
1289+}
1290+
1291+#==============================================================================
1292+# インラインプラグイン
1293+#==============================================================================
1294+sub plugin {
1295+ my $self = shift;
1296+ my $plugin = shift;
1297+
1298+ my $func_ref = &Wiki::get_plugin_info($plugin->{command})->{FUNCTION};
1299+ my $result = &$func_ref(@{$plugin->{args}});
1300+ if(defined($result) && $result ne ""){
1301+ return ($result);
1302+ }
1303+
1304+ return undef;
1305+}
1306+
1307+#==============================================================================
1308+# パラグラフプラグイン
1309+#==============================================================================
1310+sub l_plugin {
1311+ my $self = shift;
1312+ my $plugin = shift;
1313+
1314+ if($self->{para}==1){
1315+ $self->{html} .= "</p>\n";
1316+ $self->{para} = 0;
1317+ }
1318+
1319+ $self->end_list;
1320+ $self->end_verbatim;
1321+ $self->end_table;
1322+ $self->end_quote;
1323+
1324+ my $func_ref = &Wiki::get_plugin_info($plugin->{command})->{FUNCTION};
1325+ my $result = &$func_ref(@{$plugin->{args}});
1326+ if(defined($result) && $result ne ""){
1327+ $self->{html} .= $result;
1328+ }
1329+}
1330+
1331+#==============================================================================
1332+# イメージ
1333+#==============================================================================
1334+sub l_image {
1335+ my $self = shift;
1336+ my $page = shift;
1337+ my $file = shift;
1338+ my $width = shift;
1339+ my $height = shift;
1340+
1341+ if($self->{para}==1){
1342+ $self->{html} .= "</p>\n";
1343+ $self->{para} = 0;
1344+ }
1345+
1346+ $self->end_list;
1347+ $self->end_verbatim;
1348+ $self->end_table;
1349+ $self->end_quote;
1350+
1351+ $self->{html} .= "<div class=\"image\">";
1352+ $self->{html} .= "<img src=\"".&Wiki::create_url({'p'=>$page,'f'=>$file},$main::DOWNLOAD_SCRIPT)."\"";
1353+ $self->{html} .= " width=\"$width\"" if ($width ne "");
1354+ $self->{html} .= " height=\"$height\"" if ($height ne "");
1355+ $self->{html} .= "/>";
1356+ $self->{html} .= "</div>\n";
1357+}
1358+
1359+#==============================================================================
1360+# エラーメッセージ
1361+#==============================================================================
1362+sub error {
1363+ my $self = shift;
1364+ my $label = shift;
1365+
1366+ return "<span class=\"error\">".Util::escapeHTML($label)."</span>";
1367+}
1368+
1369+################################################################################
1370+#
1371+# ユーティリティ関数を提供するパッケージ
1372+#
1373+################################################################################
1374+package Util;
1375+#===============================================================================
1376+# 引数で渡された文字列をURLエンコードして返します。
1377+#===============================================================================
1378+sub url_encode {
1379+ my $retstr = shift;
1380+ &jcode::convert(\$retstr,"euc");
1381+
1382+ $retstr =~ s/([^ 0-9A-Za-z])/sprintf("%%%.2X", ord($1))/eg;
1383+ $retstr =~ tr/ /+/;
1384+ return $retstr;
1385+}
1386+
1387+#===============================================================================
1388+# 引数で渡された文字列をURLデコードして返します。
1389+#===============================================================================
1390+sub url_decode{
1391+ my $retstr = shift;
1392+
1393+ $retstr =~ tr/+/ /;
1394+ $retstr =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
1395+ return $retstr;
1396+}
1397+
1398+#===============================================================================
1399+# 引数で渡された文字列のHTMLタグをエスケープして返します。
1400+#===============================================================================
1401+sub escapeHTML {
1402+ my($retstr) = shift;
1403+ &jcode::convert(\$retstr,"euc");
1404+
1405+ my %table = (
1406+ '&' => '&amp;',
1407+ '"' => '&quot;',
1408+ '<' => '&lt;',
1409+ '>' => '&gt;',
1410+ );
1411+ $retstr =~ s/([&\"<>])/$table{$1}/go;
1412+ $retstr =~ s/&amp;#([0-9]{1,5});/&#$1;/go;
1413+ $retstr =~ s/&#(0*(0|9|10|13|38|60|62));/&amp;#$1;/g;
1414+# $retstr =~ s/&amp;([a-zA-Z0-9]{2,8});/&$1;/go;
1415+ return $retstr;
1416+}
1417+
1418+
1419+#===============================================================================
1420+# 日付をフォーマットします。
1421+#===============================================================================
1422+sub format_date {
1423+ my $t = shift;
1424+ my ($sec, $min, $hour, $mday, $mon, $year) = localtime($t);
1425+ return sprintf("%04d年%02d月%02d日 %02d時%02d分%02d秒",
1426+ $year+1900,$mon+1,$mday,$hour,$min,$sec);
1427+}
1428+
1429+#===============================================================================
1430+# 文字列の両端の空白を切り落とします。
1431+#===============================================================================
1432+sub trim {
1433+ my $text = shift;
1434+ if(!defined($text)){
1435+ return "";
1436+ }
1437+ $text =~ s/^(?:\s)+//o;
1438+ $text =~ s/(?:\s)+$//o;
1439+ return $text;
1440+}
1441+
1442+
1443+#===============================================================================
1444+# タグを削除して文字列のみを取得します。
1445+#===============================================================================
1446+sub delete_tag {
1447+ my $text = shift;
1448+ $text =~ s/<(.|\s)+?>//g;
1449+ return $text;
1450+}
1451+
1452+#===============================================================================
1453+# ページ名が使用可能かどうかチェックします。
1454+#===============================================================================
1455+sub check_pagename {
1456+ my $pagename = shift;
1457+
1458+ #ページ名をチェック
1459+ if( !defined($pagename)
1460+ || $pagename eq "" # 空
1461+ || $pagename =~ /[\|\[\]]/ # |[]
1462+ || $pagename =~ /^:/ # コロンで始まる
1463+ || $pagename =~ /[^:]:[^:]/ # コロン単体での使用
1464+ || $pagename =~ /^\s+$/ # 空白のみ
1465+ ){
1466+ return 0;
1467+ }
1468+ return 1;
1469+}
1470+
1471+#===============================================================================
1472+# 数値かどうかチェックします。
1473+#===============================================================================
1474+sub check_numeric {
1475+ my $text = shift;
1476+ if($text =~ /^[0-9]+$/){
1477+ return 1;
1478+ } else {
1479+ return 0;
1480+ }
1481+}
1482+
1483+#==============================================================================
1484+# メール送信
1485+#==============================================================================
1486+sub send_mail {
1487+ my $action = shift;
1488+ my $page = shift;
1489+ my $enc_page = &Util::url_encode($page);
1490+
1491+ if($main::ADMIN_MAIL eq "" || $main::SEND_MAIL eq ""){
1492+ return;
1493+ }
1494+
1495+ my $subject = "";
1496+ if($action eq 'CREATE'){
1497+ $subject = "[FSWikiLite]$pageが作成されました";
1498+
1499+ } elsif($action eq 'MODIFY'){
1500+ $subject = "[FSWikiLite]$pageが更新されました";
1501+
1502+ } elsif($action eq 'DELETE'){
1503+ $subject = "[FSWikiLite]$pageが削除されました";
1504+ }
1505+
1506+ # MIMEエンコード
1507+ $subject = &main::mimeencode($subject);
1508+
1509+ my $head = "Subject: $subject\n".
1510+ "From: $main::ADMIN_MAIL\n".
1511+ "Content-Transfer-Encoding: 7bit\n".
1512+ "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n".
1513+ "Reply-To: $main::ADMIN_MAIL\n".
1514+ "\n";
1515+
1516+ my $body = "IP:".$ENV{'REMOTE_ADDR'}."\n".
1517+ "UA:".$ENV{'HTTP_USER_AGENT'}."\n";
1518+
1519+ if($action eq 'MODIFY' || $action eq 'DELETE'){
1520+ if(-e "$main::BACKUP_DIR/$enc_page.bak"){
1521+ $body .= "以下は変更前のソースです。\n".
1522+ "-----------------------------------------------------\n";
1523+ open(BACKUP,"$main::BACKUP_DIR/$enc_page.bak");
1524+ while(my $line = <BACKUP>){
1525+ $body .= $line;
1526+ }
1527+ close(BACKUP);
1528+ }
1529+ }
1530+
1531+ # 文字コードの変換(jcode.plを使用する)
1532+ &jcode::convert(\$body,'jis');
1533+
1534+ open(MAIL,"| $main::SEND_MAIL $main::ADMIN_MAIL");
1535+ print MAIL $head;
1536+ print MAIL $body;
1537+ close(MAIL);
1538+}
1539+
1540+#===============================================================================
1541+# エラーを通知
1542+#===============================================================================
1543+sub error {
1544+ my $error = shift;
1545+
1546+ print "Content-Type: text/html;charset=EUC-JP\n\n";
1547+ print "<html>\n";
1548+ print "<head><title>エラー - FSWikiLite</title></head>\n";
1549+ print "<body>\n";
1550+ print "<h1>エラーが発生しました</h1>\n";
1551+ print "<pre>\n";
1552+ print &Util::escapeHTML($error);
1553+ print "</pre>\n";
1554+ print "</body><html>\n";
1555+
1556+ exit;
1557+}
1558+
1559+#===============================================================================
1560+# 携帯電話かどうかチェックします。
1561+#===============================================================================
1562+sub handyphone {
1563+ my $ua = $ENV{'HTTP_USER_AGENT'};
1564+ if(!defined($ua)){
1565+ return 0;
1566+ }
1567+ if($ua=~/^DoCoMo\// || $ua=~ /^J-PHONE\// || $ua=~ /UP\.Browser/ || $ua=~ /\(DDIPOCKET\;/ || $ua=~ /\(WILLCOM\;/ || $ua=~ /^Vodafone\// || $ua=~ /^SoftBank\//){
1568+ return 1;
1569+ } else {
1570+ return 0;
1571+ }
1572+}
1573+
1574+#===============================================================================
1575+# スマートフォンかどうかチェックします。
1576+#===============================================================================
1577+sub smartphone {
1578+ my $ua = $ENV{'HTTP_USER_AGENT'};
1579+ if(!defined($ua)){
1580+ return 0;
1581+ }
1582+ if($ua =~ /Android/ || $ua =~ /iPhone/){
1583+ return 1;
1584+ } else {
1585+ return 0;
1586+ }
1587+}
1588+
1589+1;
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/setup.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/setup.pl (revision 201)
@@ -0,0 +1,35 @@
1+################################################################################
2+#
3+# 設定ファイル
4+#
5+################################################################################
6+#===============================================================================
7+# 初期設定
8+#===============================================================================
9+$DATA_DIR = './data';
10+$BACKUP_DIR = './backup';
11+$ATTACH_DIR = './attach';
12+$THEME_URL = './theme/default/default.css';
13+$ADMIN_MAIL = '';
14+$SEND_MAIL = '';
15+$WIKI_NAME = 0;
16+$BR_MODE = 0;
17+$DISPLAY_IMAGE = 1;
18+$MAIN_SCRIPT = 'wiki.cgi';
19+$EDIT_SCRIPT = 'edit.cgi';
20+$CATEGORY_SCRIPT = 'category.cgi';
21+$DOWNLOAD_SCRIPT = 'download.cgi';
22+$SITE_TITLE = 'FSWikiLite';
23+
24+#===============================================================================
25+# プロダクト情報
26+#===============================================================================
27+$VERSION = '0.1.0';
28+$SITE_URL = 'http://fswiki.osdn.jp/cgi-bin/wiki.cgi';
29+
30+#===============================================================================
31+# プラグインの設定
32+#===============================================================================
33+require "./plugin/core.pl";
34+
35+1;
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/jcode.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/jcode.pl (revision 201)
@@ -0,0 +1,785 @@
1+package jcode;
2+;######################################################################
3+;#
4+;# jcode.pl: Perl library for Japanese character code conversion
5+;#
6+;# Copyright (c) 1995-2000 Kazumasa Utashiro <utashiro@iij.ad.jp>
7+;# Internet Initiative Japan Inc.
8+;# 3-13 Kanda Nishiki-cho, Chiyoda-ku, Tokyo 101-0054, Japan
9+;#
10+;# Copyright (c) 1992,1993,1994 Kazumasa Utashiro
11+;# Software Research Associates, Inc.
12+;#
13+;# Use and redistribution for ANY PURPOSE are granted as long as all
14+;# copyright notices are retained. Redistribution with modification
15+;# is allowed provided that you make your modified version obviously
16+;# distinguishable from the original one. THIS SOFTWARE IS PROVIDED
17+;# BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES ARE
18+;# DISCLAIMED.
19+;#
20+;# Original version was developed under the name of srekcah@sra.co.jp
21+;# February 1992 and it was called kconv.pl at the beginning. This
22+;# address was a pen name for group of individuals and it is no longer
23+;# valid.
24+;#
25+;# The latest version is available here:
26+;#
27+;# ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/
28+;#
29+;; $rcsid = q$Id: jcode.pl,v 2.13 2000/09/29 16:10:05 utashiro Exp $;
30+;#
31+;######################################################################
32+;#
33+;# PERL4 INTERFACE:
34+;#
35+;# &jcode'getcode(*line)
36+;# Return 'jis', 'sjis', 'euc' or undef according to
37+;# Japanese character code in $line. Return 'binary' if
38+;# the data has non-character code.
39+;#
40+;# When evaluated in array context, it returns a list
41+;# contains two items. First value is the number of
42+;# characters which matched to the expected code, and
43+;# second value is the code name. It is useful if and
44+;# only if the number is not 0 and the code is undef;
45+;# that case means it couldn't tell 'euc' or 'sjis'
46+;# because the evaluation score was exactly same. This
47+;# interface is too tricky, though.
48+;#
49+;# Code detection between euc and sjis is very difficult
50+;# or sometimes impossible or even lead to wrong result
51+;# when it includes JIS X0201 KANA characters. So JIS
52+;# X0201 KANA is ignored for automatic code detection.
53+;#
54+;# &jcode'convert(*line, $ocode [, $icode [, $option]])
55+;# Convert the contents of $line to the specified
56+;# Japanese code given in the second argument $ocode.
57+;# $ocode can be any of "jis", "sjis" or "euc", or use
58+;# "noconv" when you don't want the code conversion.
59+;# Input code is recognized automatically from the line
60+;# itself when $icode is not supplied (JIS X0201 KANA is
61+;# ignored in code detection. See the above descripton
62+;# of &getcode). $icode also can be specified, but
63+;# xxx2yyy routine is more efficient when both codes are
64+;# known.
65+;#
66+;# It returns the code of input string in scalar context,
67+;# and a list of pointer of convert subroutine and the
68+;# input code in array context.
69+;#
70+;# Japanese character code JIS X0201, X0208, X0212 and
71+;# ASCII code are supported. X0212 characters can not be
72+;# represented in SJIS and they will be replased by
73+;# "geta" character when converted to SJIS.
74+;#
75+;# See next paragraph for $option parameter.
76+;#
77+;# &jcode'xxx2yyy(*line [, $option])
78+;# Convert the Japanese code from xxx to yyy. String xxx
79+;# and yyy are any convination from "jis", "euc" or
80+;# "sjis". They return *approximate* number of converted
81+;# bytes. So return value 0 means the line was not
82+;# converted at all.
83+;#
84+;# Optional parameter $option is used to specify optional
85+;# conversion method. String "z" is for JIS X0201 KANA
86+;# to X0208 KANA, and "h" is for reverse.
87+;#
88+;# $jcode'convf{'xxx', 'yyy'}
89+;# The value of this associative array is pointer to the
90+;# subroutine jcode'xxx2yyy().
91+;#
92+;# &jcode'to($ocode, $line [, $icode [, $option]])
93+;# &jcode'jis($line [, $icode [, $option]])
94+;# &jcode'euc($line [, $icode [, $option]])
95+;# &jcode'sjis($line [, $icode [, $option]])
96+;# These functions are prepared for easy use of
97+;# call/return-by-value interface. You can use these
98+;# funcitons in s///e operation or any other place for
99+;# convenience.
100+;#
101+;# &jcode'jis_inout($in, $out)
102+;# Set or inquire JIS start and end sequences. Default
103+;# is "ESC-$-B" and "ESC-(-B". If you supplied only one
104+;# character, "ESC-$" or "ESC-(" is prepended for each
105+;# character respectively. Acutually "ESC-(-B" is not a
106+;# sequence to end JIS code but a sequence to start ASCII
107+;# code set. So `in' and `out' are somewhat misleading.
108+;#
109+;# &jcode'get_inout($string)
110+;# Get JIS start and end sequences from $string.
111+;#
112+;# &jcode'cache()
113+;# &jcode'nocache()
114+;# &jcode'flush()
115+;# Usually, converted character is cached in memory to
116+;# avoid same calculations have to be done many times.
117+;# To disable this caching, call &jcode'nocache(). It
118+;# can be revived by &jcode'cache() and cache is flushed
119+;# by calling &jcode'flush(). &cache() and &nocache()
120+;# functions return previous caching state.
121+;#
122+;# ---------------------------------------------------------------
123+;#
124+;# &jcode'h2z_xxx(*line)
125+;# JIS X0201 KANA (so-called Hankaku-KANA) to X0208 KANA
126+;# (Zenkaku-KANA) code conversion routine. String xxx is
127+;# any of "jis", "sjis" and "euc". From the difficulty
128+;# of recognizing code set from 1-byte KATAKANA string,
129+;# automatic code recognition is not supported.
130+;#
131+;# &jcode'z2h_xxx(*line)
132+;# X0208 to X0201 KANA code conversion routine. String
133+;# xxx is any of "jis", "sjis" and "euc".
134+;#
135+;# $jcode'z2hf{'xxx'}
136+;# $jcode'h2zf{'xxx'}
137+;# These are pointer to the corresponding function just
138+;# as $jcode'convf.
139+;#
140+;# ---------------------------------------------------------------
141+;#
142+;# &jcode'tr(*line, $from, $to [, $option])
143+;# &jcode'tr emulates tr operator for 2 byte code. Only 'd'
144+;# is interpreted as an option.
145+;#
146+;# Range operator like `A-Z' for 2 byte code is partially
147+;# supported. Code must be JIS or EUC, and first byte
148+;# have to be same on first and last character.
149+;#
150+;# CAUTION: Handling range operator is a kind of trick
151+;# and it is not perfect. So if you need to transfer `-'
152+;# character, please be sure to put it at the beginning
153+;# or the end of $from and $to strings.
154+;#
155+;# &jcode'trans($line, $from, $to [, $option)
156+;# Same as &jcode'tr but accept string and return string
157+;# after translation.
158+;#
159+;# ---------------------------------------------------------------
160+;#
161+;# &jcode'init()
162+;# Initialize the variables used in this package. You
163+;# don't have to call this when using jocde.pl by `do' or
164+;# `require' interface. Call it first if you embedded
165+;# the jcode.pl at the end of your script.
166+;#
167+;######################################################################
168+;#
169+;# PERL5 INTERFACE:
170+;#
171+;# Current jcode.pl is written in Perl 4 but it is possible to use
172+;# from Perl 5 using `references'. Fully perl5 capable version is
173+;# future issue.
174+;#
175+;# Since lexical variable is not a subject of typeglob, *string style
176+;# call doesn't work if the variable is declared as `my'. Same thing
177+;# happens to special variable $_ if the perl is compiled to use
178+;# thread capability. So using reference is generally recommented to
179+;# avoid the mysterious error.
180+;#
181+;# jcode::getcode(\$line)
182+;# jcode::convert(\$line, $ocode [, $icode [, $option]])
183+;# jcode::xxx2yyy(\$line [, $option])
184+;# &{$jcode::convf{'xxx', 'yyy'}}(\$line)
185+;# jcode::to($ocode, $line [, $icode [, $option]])
186+;# jcode::jis($line [, $icode [, $option]])
187+;# jcode::euc($line [, $icode [, $option]])
188+;# jcode::sjis($line [, $icode [, $option]])
189+;# jcode::jis_inout($in, $out)
190+;# jcode::get_inout($string)
191+;# jcode::cache()
192+;# jcode::nocache()
193+;# jcode::flush()
194+;# jcode::h2z_xxx(\$line)
195+;# jcode::z2h_xxx(\$line)
196+;# &{$jcode::z2hf{'xxx'}}(\$line)
197+;# &{$jcode::h2zf{'xxx'}}(\$line)
198+;# jcode::tr(\$line, $from, $to [, $option])
199+;# jcode::trans($line, $from, $to [, $option)
200+;# jcode::init()
201+;#
202+;######################################################################
203+;#
204+;# SAMPLES
205+;#
206+;# Convert any Kanji code to JIS and print each line with code name.
207+;#
208+;# while (defined($s = <>)) {
209+;# $code = &jcode'convert(*s, 'jis');
210+;# print $code, "\t", $s;
211+;# }
212+;#
213+;# Convert all lines to JIS according to the first recognized line.
214+;#
215+;# while (defined($s = <>)) {
216+;# print, next unless $s =~ /[\033\200-\377]/;
217+;# (*f, $icode) = &jcode'convert(*s, 'jis');
218+;# print;
219+;# defined(&f) || next;
220+;# while (<>) { &f(*s); print; }
221+;# last;
222+;# }
223+;#
224+;# The safest way of JIS conversion.
225+;#
226+;# while (defined($s = <>)) {
227+;# ($matched, $icode) = &jcode'getcode(*s);
228+;# if (@buf == 0 && $matched == 0) {
229+;# print $s;
230+;# next;
231+;# }
232+;# push(@buf, $s);
233+;# next unless $icode;
234+;# while (defined($s = shift(@buf))) {
235+;# &jcode'convert(*s, 'jis', $icode);
236+;# print $s;
237+;# }
238+;# while (defined($s = <>)) {
239+;# &jcode'convert(*s, 'jis', $icode);
240+;# print $s;
241+;# }
242+;# last;
243+;# }
244+;# print @buf if @buf;
245+;#
246+;######################################################################
247+
248+;#
249+;# Call initialize function if it is not called yet. This may sound
250+;# strange but it makes easy to embed the jcode.pl at the end of
251+;# script. Call &jcode'init at the beginning of the script in that
252+;# case.
253+;#
254+&init unless defined $version;
255+
256+;#
257+;# Initialize variables.
258+;#
259+sub init {
260+ $version = $rcsid =~ /,v ([\d.]+)/ ? $1 : 'unknown';
261+
262+ $re_bin = '[\000-\006\177\377]';
263+
264+ $re_jis0208_1978 = '\e\$\@';
265+ $re_jis0208_1983 = '\e\$B';
266+ $re_jis0208_1990 = '\e&\@\e\$B';
267+ $re_jis0208 = "$re_jis0208_1978|$re_jis0208_1983|$re_jis0208_1990";
268+ $re_jis0212 = '\e\$\(D';
269+ $re_jp = "$re_jis0208|$re_jis0212";
270+ $re_asc = '\e\([BJ]';
271+ $re_kana = '\e\(I';
272+
273+ $esc_0208 = "\e\$B";
274+ $esc_0212 = "\e\$(D";
275+ $esc_asc = "\e(B";
276+ $esc_kana = "\e(I";
277+
278+ $re_sjis_c = '[\201-\237\340-\374][\100-\176\200-\374]';
279+ $re_sjis_kana = '[\241-\337]';
280+
281+ $re_euc_c = '[\241-\376][\241-\376]';
282+ $re_euc_kana = '\216[\241-\337]';
283+ $re_euc_0212 = '\217[\241-\376][\241-\376]';
284+
285+ # Use `geta' for undefined character code
286+ $undef_sjis = "\x81\xac";
287+
288+ $cache = 1;
289+
290+ # X0201 -> X0208 KANA conversion table. Looks weird? Not that
291+ # much. This is simply JIS text without escape sequences.
292+ ($h2z_high = $h2z = <<'__TABLE_END__') =~ tr/\041-\176/\241-\376/;
293+! !# $ !" % !& " !V # !W
294+^ !+ _ !, 0 !<
295+' %! ( %# ) %% * %' + %)
296+, %c - %e . %g / %C
297+1 %" 2 %$ 3 %& 4 %( 5 %*
298+6 %+ 7 %- 8 %/ 9 %1 : %3
299+6^ %, 7^ %. 8^ %0 9^ %2 :^ %4
300+; %5 < %7 = %9 > %; ? %=
301+;^ %6 <^ %8 =^ %: >^ %< ?^ %>
302+@ %? A %A B %D C %F D %H
303+@^ %@ A^ %B B^ %E C^ %G D^ %I
304+E %J F %K G %L H %M I %N
305+J %O K %R L %U M %X N %[
306+J^ %P K^ %S L^ %V M^ %Y N^ %\
307+J_ %Q K_ %T L_ %W M_ %Z N_ %]
308+O %^ P %_ Q %` R %a S %b
309+T %d U %f V %h
310+W %i X %j Y %k Z %l [ %m
311+\ %o ] %s & %r 3^ %t
312+__TABLE_END__
313+ %h2z = split(/\s+/, $h2z . $h2z_high);
314+ %z2h = reverse %h2z;
315+
316+ $convf{'jis' , 'jis' } = *jis2jis;
317+ $convf{'jis' , 'sjis'} = *jis2sjis;
318+ $convf{'jis' , 'euc' } = *jis2euc;
319+ $convf{'euc' , 'jis' } = *euc2jis;
320+ $convf{'euc' , 'sjis'} = *euc2sjis;
321+ $convf{'euc' , 'euc' } = *euc2euc;
322+ $convf{'sjis' , 'jis' } = *sjis2jis;
323+ $convf{'sjis' , 'sjis'} = *sjis2sjis;
324+ $convf{'sjis' , 'euc' } = *sjis2euc;
325+ $h2zf{'jis' } = *h2z_jis;
326+ $z2hf{'jis' } = *z2h_jis;
327+ $h2zf{'euc' } = *h2z_euc;
328+ $z2hf{'euc' } = *z2h_euc;
329+ $h2zf{'sjis'} = *h2z_sjis;
330+ $z2hf{'sjis'} = *z2h_sjis;
331+}
332+
333+;#
334+;# Set escape sequences which should be put before and after Japanese
335+;# (JIS X0208) string.
336+;#
337+sub jis_inout {
338+ $esc_0208 = shift || $esc_0208;
339+ $esc_0208 = "\e\$$esc_0208" if length($esc_0208) == 1;
340+ $esc_asc = shift || $esc_asc;
341+ $esc_asc = "\e\($esc_asc" if length($esc_asc) == 1;
342+ ($esc_0208, $esc_asc);
343+}
344+
345+;#
346+;# Get JIS in and out sequences from the string.
347+;#
348+sub get_inout {
349+ local($esc_0208, $esc_asc);
350+ $_[$[] =~ /($re_jis0208)/o && ($esc_0208 = $1);
351+ $_[$[] =~ /($re_asc)/o && ($esc_asc = $1);
352+ ($esc_0208, $esc_asc);
353+}
354+
355+;#
356+;# Recognize character code.
357+;#
358+sub getcode {
359+ local(*s) = @_;
360+ local($matched, $code);
361+
362+ if ($s !~ /[\e\200-\377]/) { # not Japanese
363+ $matched = 0;
364+ $code = undef;
365+ } # 'jis'
366+ elsif ($s =~ /$re_jp|$re_asc|$re_kana/o) {
367+ $matched = 1;
368+ $code = 'jis';
369+ }
370+ elsif ($s =~ /$re_bin/o) { # 'binary'
371+ $matched = 0;
372+ $code = 'binary';
373+ }
374+ else { # should be 'euc' or 'sjis'
375+ local($sjis, $euc) = (0, 0);
376+
377+ while ($s =~ /(($re_sjis_c)+)/go) {
378+ $sjis += length($1);
379+ }
380+ while ($s =~ /(($re_euc_c|$re_euc_kana|$re_euc_0212)+)/go) {
381+ $euc += length($1);
382+ }
383+ $matched = &max($sjis, $euc);
384+ $code = ('euc', undef, 'sjis')[($sjis<=>$euc) + $[ + 1];
385+ }
386+ wantarray ? ($matched, $code) : $code;
387+}
388+sub max { $_[ $[ + ($_[ $[ ] < $_[ $[ + 1 ]) ]; }
389+
390+;#
391+;# Convert any code to specified code.
392+;#
393+sub convert {
394+ local(*s, $ocode, $icode, $opt) = @_;
395+ return (undef, undef) unless $icode = $icode || &getcode(*s);
396+ return (undef, $icode) if $icode eq 'binary';
397+ $ocode = 'jis' unless $ocode;
398+ $ocode = $icode if $ocode eq 'noconv';
399+ local(*f) = $convf{$icode, $ocode};
400+ &f(*s, $opt);
401+ wantarray ? (*f, $icode) : $icode;
402+}
403+
404+;#
405+;# Easy return-by-value interfaces.
406+;#
407+sub jis { &to('jis', @_); }
408+sub euc { &to('euc', @_); }
409+sub sjis { &to('sjis', @_); }
410+sub to {
411+ local($ocode, $s, $icode, $opt) = @_;
412+ &convert(*s, $ocode, $icode, $opt);
413+ $s;
414+}
415+sub what {
416+ local($s) = @_;
417+ &getcode(*s);
418+}
419+sub trans {
420+ local($s) = shift;
421+ &tr(*s, @_);
422+ $s;
423+}
424+
425+;#
426+;# SJIS to JIS
427+;#
428+sub sjis2jis {
429+ local(*s, $opt, $n) = @_;
430+ &sjis2sjis(*s, $opt) if $opt;
431+ $s =~ s/(($re_sjis_c|$re_sjis_kana)+)/&_sjis2jis($1) . $esc_asc/geo;
432+ $n;
433+}
434+sub _sjis2jis {
435+ local($s) = shift;
436+ $s =~ s/(($re_sjis_c)+|($re_sjis_kana)+)/&__sjis2jis($1)/geo;
437+ $s;
438+}
439+sub __sjis2jis {
440+ local($s) = shift;
441+ if ($s =~ /^$re_sjis_kana/o) {
442+ $n += $s =~ tr/\241-\337/\041-\137/;
443+ $esc_kana . $s;
444+ } else {
445+ $n += $s =~ s/($re_sjis_c)/$s2e{$1}||&s2e($1)/geo;
446+ $s =~ tr/\241-\376/\041-\176/;
447+ $esc_0208 . $s;
448+ }
449+}
450+
451+;#
452+;# EUC to JIS
453+;#
454+sub euc2jis {
455+ local(*s, $opt, $n) = @_;
456+ &euc2euc(*s, $opt) if $opt;
457+ $s =~ s/(($re_euc_c|$re_euc_kana|$re_euc_0212)+)/
458+ &_euc2jis($1) . $esc_asc
459+ /geo;
460+ $n;
461+}
462+sub _euc2jis {
463+ local($s) = shift;
464+ $s =~ s/(($re_euc_c)+|($re_euc_kana)+|($re_euc_0212)+)/&__euc2jis($1)/geo;
465+ $s;
466+}
467+sub __euc2jis {
468+ local($s) = shift;
469+ local($esc);
470+
471+ if ($s =~ tr/\216//d) {
472+ $esc = $esc_kana;
473+ } elsif ($s =~ tr/\217//d) {
474+ $esc = $esc_0212;
475+ } else {
476+ $esc = $esc_0208;
477+ }
478+
479+ $n += $s =~ tr/\241-\376/\041-\176/;
480+ $esc . $s;
481+}
482+
483+;#
484+;# JIS to EUC
485+;#
486+sub jis2euc {
487+ local(*s, $opt, $n) = @_;
488+ $s =~ s/($re_jp|$re_asc|$re_kana)([^\e]*)/&_jis2euc($1,$2)/geo;
489+ &euc2euc(*s, $opt) if $opt;
490+ $n;
491+}
492+sub _jis2euc {
493+ local($esc, $s) = @_;
494+ if ($esc !~ /^$re_asc/o) {
495+ $n += $s =~ tr/\041-\176/\241-\376/;
496+ if ($esc =~ /^$re_kana/o) {
497+ $s =~ s/([\241-\337])/\216$1/g;
498+ }
499+ elsif ($esc =~ /^$re_jis0212/o) {
500+ $s =~ s/([\241-\376][\241-\376])/\217$1/g;
501+ }
502+ }
503+ $s;
504+}
505+
506+;#
507+;# JIS to SJIS
508+;#
509+sub jis2sjis {
510+ local(*s, $opt, $n) = @_;
511+ &jis2jis(*s, $opt) if $opt;
512+ $s =~ s/($re_jp|$re_asc|$re_kana)([^\e]*)/&_jis2sjis($1,$2)/geo;
513+ $n;
514+}
515+sub _jis2sjis {
516+ local($esc, $s) = @_;
517+ if ($esc =~ /^$re_jis0212/o) {
518+ $s =~ s/../$undef_sjis/g;
519+ $n = length;
520+ }
521+ elsif ($esc !~ /^$re_asc/o) {
522+ $n += $s =~ tr/\041-\176/\241-\376/;
523+ if ($esc =~ /^$re_jp/o) {
524+ $s =~ s/($re_euc_c)/$e2s{$1}||&e2s($1)/geo;
525+ }
526+ }
527+ $s;
528+}
529+
530+;#
531+;# SJIS to EUC
532+;#
533+sub sjis2euc {
534+ local(*s, $opt,$n) = @_;
535+ $n = $s =~ s/($re_sjis_c|$re_sjis_kana)/$s2e{$1}||&s2e($1)/geo;
536+ &euc2euc(*s, $opt) if $opt;
537+ $n;
538+}
539+sub s2e {
540+ local($c1, $c2, $code);
541+ ($c1, $c2) = unpack('CC', $code = shift);
542+
543+ if (0xa1 <= $c1 && $c1 <= 0xdf) {
544+ $c2 = $c1;
545+ $c1 = 0x8e;
546+ } elsif (0x9f <= $c2) {
547+ $c1 = $c1 * 2 - ($c1 >= 0xe0 ? 0xe0 : 0x60);
548+ $c2 += 2;
549+ } else {
550+ $c1 = $c1 * 2 - ($c1 >= 0xe0 ? 0xe1 : 0x61);
551+ $c2 += 0x60 + ($c2 < 0x7f);
552+ }
553+ if ($cache) {
554+ $s2e{$code} = pack('CC', $c1, $c2);
555+ } else {
556+ pack('CC', $c1, $c2);
557+ }
558+}
559+
560+;#
561+;# EUC to SJIS
562+;#
563+sub euc2sjis {
564+ local(*s, $opt,$n) = @_;
565+ &euc2euc(*s, $opt) if $opt;
566+ $n = $s =~ s/($re_euc_c|$re_euc_kana|$re_euc_0212)/$e2s{$1}||&e2s($1)/geo;
567+}
568+sub e2s {
569+ local($c1, $c2, $code);
570+ ($c1, $c2) = unpack('CC', $code = shift);
571+
572+ if ($c1 == 0x8e) { # SS2
573+ return substr($code, 1, 1);
574+ } elsif ($c1 == 0x8f) { # SS3
575+ return $undef_sjis;
576+ } elsif ($c1 % 2) {
577+ $c1 = ($c1>>1) + ($c1 < 0xdf ? 0x31 : 0x71);
578+ $c2 -= 0x60 + ($c2 < 0xe0);
579+ } else {
580+ $c1 = ($c1>>1) + ($c1 < 0xdf ? 0x30 : 0x70);
581+ $c2 -= 2;
582+ }
583+ if ($cache) {
584+ $e2s{$code} = pack('CC', $c1, $c2);
585+ } else {
586+ pack('CC', $c1, $c2);
587+ }
588+}
589+
590+;#
591+;# JIS to JIS, SJIS to SJIS, EUC to EUC
592+;#
593+sub jis2jis {
594+ local(*s, $opt) = @_;
595+ $s =~ s/$re_jis0208/$esc_0208/go;
596+ $s =~ s/$re_asc/$esc_asc/go;
597+ &h2z_jis(*s) if $opt =~ /z/;
598+ &z2h_jis(*s) if $opt =~ /h/;
599+}
600+sub sjis2sjis {
601+ local(*s, $opt) = @_;
602+ &h2z_sjis(*s) if $opt =~ /z/;
603+ &z2h_sjis(*s) if $opt =~ /h/;
604+}
605+sub euc2euc {
606+ local(*s, $opt) = @_;
607+ &h2z_euc(*s) if $opt =~ /z/;
608+ &z2h_euc(*s) if $opt =~ /h/;
609+}
610+
611+;#
612+;# Cache control functions
613+;#
614+sub cache {
615+ ($cache, $cache = 1)[$[];
616+}
617+sub nocache {
618+ ($cache, $cache = 0)[$[];
619+}
620+sub flushcache {
621+ undef %e2s;
622+ undef %s2e;
623+}
624+
625+;#
626+;# X0201 -> X0208 KANA conversion routine
627+;#
628+sub h2z_jis {
629+ local(*s, $n) = @_;
630+ if ($s =~ s/$re_kana([^\e]*)/$esc_0208 . &_h2z_jis($1)/geo) {
631+ 1 while $s =~ s/(($re_jis0208)[^\e]*)($re_jis0208)/$1/o;
632+ }
633+ $n;
634+}
635+sub _h2z_jis {
636+ local($s) = @_;
637+ $n += $s =~ s/(([\041-\137])([\136\137])?)/
638+ $h2z{$1} || $h2z{$2} . $h2z{$3}
639+ /ge;
640+ $s;
641+}
642+
643+sub h2z_euc {
644+ local(*s) = @_;
645+ $s =~ s/\216([\241-\337])(\216([\336\337]))?/
646+ $h2z{"$1$3"} || $h2z{$1} . $h2z{$3}
647+ /ge;
648+}
649+
650+sub h2z_sjis {
651+ local(*s, $n) = @_;
652+ $s =~ s/(($re_sjis_c)+)|(([\241-\337])([\336\337])?)/
653+ $1 || ($n++, $h2z{$3} ? $e2s{$h2z{$3}} || &e2s($h2z{$3})
654+ : &e2s($h2z{$4}) . ($5 && &e2s($h2z{$5})))
655+ /geo;
656+ $n;
657+}
658+
659+;#
660+;# X0208 -> X0201 KANA conversion routine
661+;#
662+sub z2h_jis {
663+ local(*s, $n) = @_;
664+ $s =~ s/($re_jis0208)([^\e]+)/&_z2h_jis($2)/geo;
665+ $n;
666+}
667+sub _z2h_jis {
668+ local($s) = @_;
669+ $s =~ s/((\%[!-~]|![\#\"&VW+,<])+|([^!%][!-~]|![^\#\"&VW+,<])+)/
670+ &__z2h_jis($1)
671+ /ge;
672+ $s;
673+}
674+sub __z2h_jis {
675+ local($s) = @_;
676+ return $esc_0208 . $s unless $s =~ /^%/ || $s =~ /^![\#\"&VW+,<]/;
677+ $n += length($s) / 2;
678+ $s =~ s/(..)/$z2h{$1}/g;
679+ $esc_kana . $s;
680+}
681+
682+sub z2h_euc {
683+ local(*s, $n) = @_;
684+ &init_z2h_euc if !%z2h_euc;
685+ $s =~ s/($re_euc_c|$re_euc_kana)/
686+ $z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1
687+ /geo;
688+ $n;
689+}
690+
691+sub z2h_sjis {
692+ local(*s, $n) = @_;
693+ &init_z2h_sjis if !%z2h_sjis;
694+ $s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
695+ $n;
696+}
697+
698+;#
699+;# Initializing JIS X0208 to X0201 KANA table for EUC and SJIS. This
700+;# can be done in &init but it's not worth doing. Similarly,
701+;# precalculated table is not worth to occupy the file space and
702+;# reduce the readability. The author personnaly discourages to use
703+;# X0201 Kana character in the any situation.
704+;#
705+sub init_z2h_euc {
706+ local($k, $s);
707+ while (($k, $s) = each %z2h) {
708+ $s =~ s/([\241-\337])/\216$1/g && ($z2h_euc{$k} = $s);
709+ }
710+}
711+sub init_z2h_sjis {
712+ local($s, $v);
713+ while (($s, $v) = each %z2h) {
714+ $s =~ /[\200-\377]/ && ($z2h_sjis{&e2s($s)} = $v);
715+ }
716+}
717+
718+;#
719+;# TR function for 2-byte code
720+;#
721+sub tr {
722+ # $prev_from, $prev_to, %table are persistent variables
723+ local(*s, $from, $to, $opt) = @_;
724+ local(@from, @to);
725+ local($jis, $n) = (0, 0);
726+
727+ $jis++, &jis2euc(*s) if $s =~ /$re_jp|$re_asc|$re_kana/o;
728+ $jis++ if $to =~ /$re_jp|$re_asc|$re_kana/o;
729+
730+ if (!defined($prev_from) || $from ne $prev_from || $to ne $prev_to) {
731+ ($prev_from, $prev_to) = ($from, $to);
732+ undef %table;
733+ &_maketable;
734+ }
735+
736+ $s =~ s/([\200-\377][\000-\377]|[\000-\377])/
737+ defined($table{$1}) && ++$n ? $table{$1} : $1
738+ /ge;
739+
740+ &euc2jis(*s) if $jis;
741+
742+ $n;
743+}
744+
745+sub _maketable {
746+ local($ascii) = '(\\\\[\\-\\\\]|[\0-\133\135-\177])';
747+
748+ &jis2euc(*to) if $to =~ /$re_jp|$re_asc|$re_kana/o;
749+ &jis2euc(*from) if $from =~ /$re_jp|$re_asc|$re_kana/o;
750+
751+ grep(s/(([\200-\377])[\200-\377]-\2[\200-\377])/&_expnd2($1)/ge,
752+ $from, $to);
753+ grep(s/($ascii-$ascii)/&_expnd1($1)/geo,
754+ $from, $to);
755+
756+ @to = $to =~ /[\200-\377][\000-\377]|[\000-\377]/g;
757+ @from = $from =~ /[\200-\377][\000-\377]|[\000-\377]/g;
758+ push(@to, ($opt =~ /d/ ? '' : $to[$#to]) x (@from - @to)) if @to < @from;
759+ @table{@from} = @to;
760+}
761+
762+sub _expnd1 {
763+ local($s) = @_;
764+ $s =~ s/\\(.)/$1/g;
765+ local($c1, $c2) = unpack('CxC', $s);
766+ if ($c1 <= $c2) {
767+ for ($s = ''; $c1 <= $c2; $c1++) {
768+ $s .= pack('C', $c1);
769+ }
770+ }
771+ $s;
772+}
773+
774+sub _expnd2 {
775+ local($s) = @_;
776+ local($c1, $c2, $c3, $c4) = unpack('CCxCC', $s);
777+ if ($c1 == $c3 && $c2 <= $c4) {
778+ for ($s = ''; $c2 <= $c4; $c2++) {
779+ $s .= pack('CC', $c1, $c2);
780+ }
781+ }
782+ $s;
783+}
784+
785+1;
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/cgi-lib.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/cgi-lib.pl (revision 201)
@@ -0,0 +1,456 @@
1+# Perl Routines to Manipulate CGI input
2+# S.E.Brenner@bioc.cam.ac.uk
3+# $Id: cgi-lib.pl,v 1.2 2004/05/24 14:35:08 takezoe Exp $
4+#
5+# Copyright (c) 1996 Steven E. Brenner
6+# Unpublished work.
7+# Permission granted to use and modify this library so long as the
8+# copyright above is maintained, modifications are documented, and
9+# credit is given for any use of the library.
10+#
11+# Thanks are due to many people for reporting bugs and suggestions
12+# especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen,
13+# Andrew Dalke, Mark-Jason Dominus, Dave Dittrich, Jason Mathews
14+
15+# For more information, see:
16+# http://www.bio.cam.ac.uk/cgi-lib/
17+
18+$cgi_lib'version = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
19+
20+
21+# Parameters affecting cgi-lib behavior
22+# User-configurable parameters affecting file upload.
23+$cgi_lib'maxdata = 131072; # maximum bytes to accept via POST - 2^17
24+$cgi_lib'writefiles = 0; # directory to which to write files, or
25+ # 0 if files should not be written
26+$cgi_lib'filepre = "cgi-lib"; # Prefix of file names, in directory above
27+
28+# Do not change the following parameters unless you have special reasons
29+$cgi_lib'bufsize = 8192; # default buffer size when reading multipart
30+$cgi_lib'maxbound = 100; # maximum boundary length to be encounterd
31+$cgi_lib'headerout = 0; # indicates whether the header has been printed
32+
33+
34+# ReadParse
35+# Reads in GET or POST data, converts it to unescaped text, and puts
36+# key/value pairs in %in, using "\0" to separate multiple selections
37+
38+# Returns >0 if there was input, 0 if there was no input
39+# undef indicates some failure.
40+
41+# Now that cgi scripts can be put in the normal file space, it is useful
42+# to combine both the form and the script in one place. If no parameters
43+# are given (i.e., ReadParse returns FALSE), then a form could be output.
44+
45+# If a reference to a hash is given, then the data will be stored in that
46+# hash, but the data from $in and @in will become inaccessable.
47+# If a variable-glob (e.g., *cgi_input) is the first parameter to ReadParse,
48+# information is stored there, rather than in $in, @in, and %in.
49+# Second, third, and fourth parameters fill associative arrays analagous to
50+# %in with data relevant to file uploads.
51+
52+# If no method is given, the script will process both command-line arguments
53+# of the form: name=value and any text that is in $ENV{'QUERY_STRING'}
54+# This is intended to aid debugging and may be changed in future releases
55+
56+sub ReadParse {
57+ local (*in) = shift if @_; # CGI input
58+ local (*incfn, # Client's filename (may not be provided)
59+ *inct, # Client's content-type (may not be provided)
60+ *insfn) = @_; # Server's filename (for spooled files)
61+ local ($len, $type, $meth, $errflag, $cmdflag, $perlwarn, $got);
62+
63+ # Disable warnings as this code deliberately uses local and environment
64+ # variables which are preset to undef (i.e., not explicitly initialized)
65+ $perlwarn = $^W;
66+ $^W = 0;
67+
68+ binmode(STDIN); # we need these for DOS-based systems
69+ binmode(STDOUT); # and they shouldn't hurt anything else
70+ binmode(STDERR);
71+
72+ # Get several useful env variables
73+ $type = $ENV{'CONTENT_TYPE'};
74+ $len = $ENV{'CONTENT_LENGTH'};
75+ $meth = $ENV{'REQUEST_METHOD'};
76+
77+ if ($len > $cgi_lib'maxdata) { #'
78+ &CgiDie("cgi-lib.pl: Request to receive too much data: $len bytes\n");
79+ }
80+
81+ if (!defined $meth || $meth eq '' || $meth eq 'GET' || $meth eq 'HEAD' ||
82+ $type eq 'application/x-www-form-urlencoded') {
83+ local ($key, $val, $i);
84+
85+ # Read in text
86+ if (!defined $meth || $meth eq '') {
87+ $in = $ENV{'QUERY_STRING'};
88+ $cmdflag = 1; # also use command-line options
89+ } elsif($meth eq 'GET' || $meth eq 'HEAD') {
90+ $in = $ENV{'QUERY_STRING'};
91+ } elsif ($meth eq 'POST') {
92+ if (($got = read(STDIN, $in, $len) != $len))
93+ {$errflag="Short Read: wanted $len, got $got\n";};
94+ } else {
95+ &CgiDie("cgi-lib.pl: Unknown request method: $meth\n");
96+ }
97+
98+ @in = split(/[&;]/,$in);
99+ push(@in, @ARGV) if $cmdflag; # add command-line parameters
100+
101+ foreach $i (0 .. $#in) {
102+ # Convert plus to space
103+ $in[$i] =~ s/\+/ /g;
104+
105+ # Split into key and value.
106+ ($key, $val) = split(/=/,$in[$i],2); # splits on the first =.
107+
108+ # Convert %XX from hex numbers to alphanumeric
109+ $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
110+ $val =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
111+
112+ # Associate key and value
113+ $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator
114+ $in{$key} .= $val;
115+ }
116+
117+ } elsif ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) {
118+ # for efficiency, compile multipart code only if needed
119+$errflag = !(eval <<'END_MULTIPART');
120+
121+ local ($buf, $boundary, $head, @heads, $cd, $ct, $fname, $ctype, $blen);
122+ local ($bpos, $lpos, $left, $amt, $fn, $ser);
123+ local ($bufsize, $maxbound, $writefiles) =
124+ ($cgi_lib'bufsize, $cgi_lib'maxbound, $cgi_lib'writefiles);
125+
126+
127+ # The following lines exist solely to eliminate spurious warning messages
128+ $buf = '';
129+
130+ ($boundary) = $type =~ /boundary="([^"]+)"/; #"; # find boundary
131+ ($boundary) = $type =~ /boundary=(\S+)/ unless $boundary;
132+ &CgiDie ("Boundary not provided: probably a bug in your server")
133+ unless $boundary;
134+ $boundary = "--" . $boundary;
135+ $blen = length ($boundary);
136+
137+ if ($ENV{'REQUEST_METHOD'} ne 'POST') {
138+ &CgiDie("Invalid request method for multipart/form-data: $meth\n");
139+ }
140+
141+ if ($writefiles) {
142+ local($me);
143+ stat ($writefiles);
144+ $writefiles = "/tmp" unless -d _ && -r _ && -w _;
145+ # ($me) = $0 =~ m#([^/]*)$#;
146+ $writefiles .= "/$cgi_lib'filepre";
147+ }
148+
149+ # read in the data and split into parts:
150+ # put headers in @in and data in %in
151+ # General algorithm:
152+ # There are two dividers: the border and the '\r\n\r\n' between
153+ # header and body. Iterate between searching for these
154+ # Retain a buffer of size(bufsize+maxbound); the latter part is
155+ # to ensure that dividers don't get lost by wrapping between two bufs
156+ # Look for a divider in the current batch. If not found, then
157+ # save all of bufsize, move the maxbound extra buffer to the front of
158+ # the buffer, and read in a new bufsize bytes. If a divider is found,
159+ # save everything up to the divider. Then empty the buffer of everything
160+ # up to the end of the divider. Refill buffer to bufsize+maxbound
161+ # Note slightly odd organization. Code before BODY: really goes with
162+ # code following HEAD:, but is put first to 'pre-fill' buffers. BODY:
163+ # is placed before HEAD: because we first need to discard any 'preface,'
164+ # which would be analagous to a body without a preceeding head.
165+
166+ $left = $len;
167+ PART: # find each part of the multi-part while reading data
168+ while (1) {
169+ die $@ if $errflag;
170+
171+ $amt = ($left > $bufsize+$maxbound-length($buf)
172+ ? $bufsize+$maxbound-length($buf): $left);
173+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
174+ die "Short Read: wanted $amt, got $got\n" if $errflag;
175+ $left -= $amt;
176+
177+ $in{$name} .= "\0" if defined $in{$name};
178+ $in{$name} .= $fn if $fn;
179+
180+ $name=~/([-\w]+)/; # This allows $insfn{$name} to be untainted
181+ if (defined $1) {
182+ $insfn{$1} .= "\0" if defined $insfn{$1};
183+ $insfn{$1} .= $fn if $fn;
184+ }
185+
186+ BODY:
187+ while (($bpos = index($buf, $boundary)) == -1) {
188+ die $@ if $errflag;
189+ if ($name) { # if no $name, then it's the prologue -- discard
190+ if ($fn) { print FILE substr($buf, 0, $bufsize); }
191+ else { $in{$name} .= substr($buf, 0, $bufsize); }
192+ }
193+ $buf = substr($buf, $bufsize);
194+ $amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
195+ $errflag = (($got = read(STDIN, $buf, $amt, $maxbound)) != $amt);
196+ die "Short Read: wanted $amt, got $got\n" if $errflag;
197+ $left -= $amt;
198+ }
199+ if (defined $name) { # if no $name, then it's the prologue -- discard
200+ if ($fn) { print FILE substr($buf, 0, $bpos-2); }
201+ else { $in {$name} .= substr($buf, 0, $bpos-2); } # kill last \r\n
202+ }
203+ close (FILE);
204+ last PART if substr($buf, $bpos + $blen, 4) eq "--\r\n";
205+ substr($buf, 0, $bpos+$blen+2) = '';
206+ $amt = ($left > $bufsize+$maxbound-length($buf)
207+ ? $bufsize+$maxbound-length($buf) : $left);
208+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
209+ die "Short Read: wanted $amt, got $got\n" if $errflag;
210+ $left -= $amt;
211+
212+
213+ undef $head; undef $fn;
214+ HEAD:
215+ while (($lpos = index($buf, "\r\n\r\n")) == -1) {
216+ die $@ if $errflag;
217+ $head .= substr($buf, 0, $bufsize);
218+ $buf = substr($buf, $bufsize);
219+ $amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
220+ $errflag = (($got = read(STDIN, $buf, $amt, $maxbound)) != $amt);
221+ die "Short Read: wanted $amt, got $got\n" if $errflag;
222+ $left -= $amt;
223+ }
224+ $head .= substr($buf, 0, $lpos+2);
225+ push (@in, $head);
226+ @heads = split("\r\n", $head);
227+ ($cd) = grep (/^\s*Content-Disposition:/i, @heads);
228+ ($ct) = grep (/^\s*Content-Type:/i, @heads);
229+
230+ ($name) = $cd =~ /\bname="([^"]+)"/i; #";
231+ ($name) = $cd =~ /\bname=([^\s:;]+)/i unless defined $name;
232+
233+ ($fname) = $cd =~ /\bfilename="([^"]*)"/i; #"; # filename can be null-str
234+ ($fname) = $cd =~ /\bfilename=([^\s:;]+)/i unless defined $fname;
235+ $incfn{$name} .= (defined $in{$name} ? "\0" : "") .
236+ (defined $fname ? $fname : "");
237+
238+ ($ctype) = $ct =~ /^\s*Content-type:\s*"([^"]+)"/i; #";
239+ ($ctype) = $ct =~ /^\s*Content-Type:\s*([^\s:;]+)/i unless defined $ctype;
240+ $inct{$name} .= (defined $in{$name} ? "\0" : "") . $ctype;
241+
242+ if ($writefiles && defined $fname) {
243+ $ser++;
244+ $fn = $writefiles . ".$$.$ser";
245+ open (FILE, ">$fn") || &CgiDie("Couldn't open $fn\n");
246+ binmode (FILE); # write files accurately
247+ }
248+ substr($buf, 0, $lpos+4) = '';
249+ undef $fname;
250+ undef $ctype;
251+ }
252+
253+1;
254+END_MULTIPART
255+ if ($errflag) {
256+ local ($errmsg, $value);
257+ $errmsg = $@ || $errflag;
258+ foreach $value (values %insfn) {
259+ unlink(split("\0",$value));
260+ }
261+ &CgiDie($errmsg);
262+ } else {
263+ # everything's ok.
264+ }
265+ } else {
266+ &CgiDie("cgi-lib.pl: Unknown Content-type: $ENV{'CONTENT_TYPE'}\n");
267+ }
268+
269+ # no-ops to avoid warnings
270+ $insfn = $insfn;
271+ $incfn = $incfn;
272+ $inct = $inct;
273+
274+ $^W = $perlwarn;
275+
276+ return ($errflag ? undef : scalar(@in));
277+}
278+
279+
280+# PrintHeader
281+# Returns the magic line which tells WWW that we're an HTML document
282+
283+sub PrintHeader {
284+ return "Content-type: text/html\n\n";
285+}
286+
287+
288+# HtmlTop
289+# Returns the <head> of a document and the beginning of the body
290+# with the title and a body <h1> header as specified by the parameter
291+
292+sub HtmlTop
293+{
294+ local ($title) = @_;
295+
296+ return <<END_OF_TEXT;
297+<html>
298+<head>
299+<title>$title</title>
300+</head>
301+<body>
302+<h1>$title</h1>
303+END_OF_TEXT
304+}
305+
306+
307+# HtmlBot
308+# Returns the </body>, </html> codes for the bottom of every HTML page
309+
310+sub HtmlBot
311+{
312+ return "</body>\n</html>\n";
313+}
314+
315+
316+# SplitParam
317+# Splits a multi-valued parameter into a list of the constituent parameters
318+
319+sub SplitParam
320+{
321+ local ($param) = @_;
322+ local (@params) = split ("\0", $param);
323+ return (wantarray ? @params : $params[0]);
324+}
325+
326+
327+# MethGet
328+# Return true if this cgi call was using the GET request, false otherwise
329+
330+sub MethGet {
331+ return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "GET");
332+}
333+
334+
335+# MethPost
336+# Return true if this cgi call was using the POST request, false otherwise
337+
338+sub MethPost {
339+ return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "POST");
340+}
341+
342+
343+# MyBaseUrl
344+# Returns the base URL to the script (i.e., no extra path or query string)
345+sub MyBaseUrl {
346+ local ($ret, $perlwarn);
347+ $perlwarn = $^W; $^W = 0;
348+ $ret = 'http://' . $ENV{'SERVER_NAME'} .
349+ ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
350+ $ENV{'SCRIPT_NAME'};
351+ $^W = $perlwarn;
352+ return $ret;
353+}
354+
355+
356+# MyFullUrl
357+# Returns the full URL to the script (i.e., with extra path or query string)
358+sub MyFullUrl {
359+ local ($ret, $perlwarn);
360+ $perlwarn = $^W; $^W = 0;
361+ $ret = 'http://' . $ENV{'SERVER_NAME'} .
362+ ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
363+ $ENV{'SCRIPT_NAME'} . $ENV{'PATH_INFO'} .
364+ (length ($ENV{'QUERY_STRING'}) ? "?$ENV{'QUERY_STRING'}" : '');
365+ $^W = $perlwarn;
366+ return $ret;
367+}
368+
369+
370+# MyURL
371+# Returns the base URL to the script (i.e., no extra path or query string)
372+# This is obsolete and will be removed in later versions
373+sub MyURL {
374+ return &MyBaseUrl;
375+}
376+
377+
378+# CgiError
379+# Prints out an error message which which containes appropriate headers,
380+# markup, etcetera.
381+# Parameters:
382+# If no parameters, gives a generic error message
383+# Otherwise, the first parameter will be the title and the rest will
384+# be given as different paragraphs of the body
385+
386+sub CgiError {
387+ local (@msg) = @_;
388+ local ($i,$name);
389+
390+ if (!@msg) {
391+ $name = &MyFullUrl;
392+ @msg = ("Error: script $name encountered fatal error\n");
393+ };
394+
395+ if (!$cgi_lib'headerout) { #')
396+ print &PrintHeader;
397+ print "<html>\n<head>\n<title>$msg[0]</title>\n</head>\n<body>\n";
398+ }
399+ print "<h1>$msg[0]</h1>\n";
400+ foreach $i (1 .. $#msg) {
401+ print "<p>$msg[$i]</p>\n";
402+ }
403+
404+ $cgi_lib'headerout++;
405+}
406+
407+
408+# CgiDie
409+# Identical to CgiError, but also quits with the passed error message.
410+
411+sub CgiDie {
412+ local (@msg) = @_;
413+ &CgiError (@msg);
414+ die @msg;
415+}
416+
417+
418+# PrintVariables
419+# Nicely formats variables. Three calling options:
420+# A non-null associative array - prints the items in that array
421+# A type-glob - prints the items in the associated assoc array
422+# nothing - defaults to use %in
423+# Typical use: &PrintVariables()
424+
425+sub PrintVariables {
426+ local (*in) = @_ if @_ == 1;
427+ local (%in) = @_ if @_ > 1;
428+ local ($out, $key, $output);
429+
430+ $output = "\n<dl compact>\n";
431+ foreach $key (sort keys(%in)) {
432+ foreach (split("\0", $in{$key})) {
433+ ($out = $_) =~ s/\n/<br>\n/g;
434+ $output .= "<dt><b>$key</b>\n <dd>:<i>$out</i>:<br>\n";
435+ }
436+ }
437+ $output .= "</dl>\n";
438+
439+ return $output;
440+}
441+
442+# PrintEnv
443+# Nicely formats all environment variables and returns HTML string
444+sub PrintEnv {
445+ &PrintVariables(*ENV);
446+}
447+
448+
449+# The following lines exist only to avoid warning messages
450+$cgi_lib'writefiles = $cgi_lib'writefiles;
451+$cgi_lib'bufsize = $cgi_lib'bufsize ;
452+$cgi_lib'maxbound = $cgi_lib'maxbound;
453+$cgi_lib'version = $cgi_lib'version;
454+$cgi_lib'filepre = $cgi_lib'filepre;
455+
456+1; #return true
\ No newline at end of file
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/mimew.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/lib/mimew.pl (revision 201)
@@ -0,0 +1,322 @@
1+package MIME;
2+# Copyright (C) 1993-94,1997 Noboru Ikuta <noboru@ikuta.ichihara.chiba.jp>
3+#
4+# mimew.pl: MIME encoder library Ver.2.02 (1997/12/30)
5+
6+$main'mimew_version = "2.02";
7+
8+# インストール : @INC のディレクトリ(通常は /usr/local/lib/perl)にコピー
9+# して下さい。
10+#
11+# 使用例1 : require 'mimew.pl';
12+# $from = "From: 生田 昇 <noboru\@ikuta.ichihara.chiba.jp>";
13+# print &mimeencode($from);
14+#
15+# 使用例2 : # UNIXでBase64エンコードする場合
16+# require 'mimew.pl';
17+# undef $/;
18+# $body = <>;
19+# print &bodyencode($body);
20+# print &benflush;
21+#
22+# &bodyencode($data,$coding):
23+# データをBase64形式またはQuoted-Printable形式でエンコードする。
24+# 第2パラメータに"qp"または"b64"を指定することによりコーディング形式
25+# を指示することができる。第2パラメータを省略するとBase64形式でエン
26+# コードする。
27+# Base64形式のエンコードの場合は、$foldcol*3/4 バイト単位で変換する
28+# ので、渡されたデータのうち半端な部分はバッファに保存され次に呼ばれ
29+# たときに処理される。最後にバッファに残ったデータは&benflushを呼ぶ
30+# ことにより処理されバッファからクリアされる。
31+# Quoted-Printable形式のエンコードの場合は、行単位で変換するため、
32+# データの最後に改行文字が無い場合、最後の改行文字の後ろのデータは
33+# バッファに保存され、次に呼ばれたときに処理される。最後にバッファ
34+# に残ったデータは&benflush("qp")を呼ぶことにより処理されバッファ
35+# からクリアされる。
36+#
37+# &benflush($coding):
38+# 第1パラメータに"b64"または"qp"を指定することにより、それぞれBase64
39+# 形式またはQuoted-Printable形式のエンコードを指定することができる。
40+# 第1パラメータに何も指定しなければBase64形式でエンコードされる。
41+# Base64のエンコードの場合、&bodyencodeが処理し残したデータを処理し
42+# pad文字を出力する。Quoted-Printableの場合、行単位でなくブロック単
43+# 位で&bodyencodeを呼ぶ場合、&bodyencodeが処理し残したデータがもし
44+# バッファに残っていればそれを処理する。
45+# 一つのデータを(1回または何回かに分けて)&bodyencodeした後に必ず1回
46+# 呼ぶ必要がある。
47+#
48+# &mimeencode($text):
49+# 第1パラメータが日本語文字列を含んでいれば、その部分をISO-2022-JPに
50+# 変換したあと、MIME encoded-word(RFC2047参照)に変換する。必要に応じ
51+# てencoded-wordの分割とencoded-wordの前後での行分割を行う。
52+#
53+# 文字コードの自動判定は、同一行にShiftJISとEUCが混在している場合を
54+# 除いて漢字コードの混在にも対応している。ShiftJISかEUCかどうしても
55+# 判断できないときは$often_use_kanjiに設定されているコードと判定する。
56+# ISO-2022-JPのエスケープシーケンスは$jis_inと$jis_outに設定すること
57+# により変更可能である。
58+
59+$often_use_kanji = 'EUC'; # or 'SJIS'
60+
61+$jis_in = "\x1b\$B"; # ESC-$-B ( or ESC-$-@ )
62+$jis_out = "\x1b\(B"; # ESC-(-B ( or ESC-(-J )
63+
64+# 配布条件 : 著作権は放棄しませんが、配布・改変は自由とします。改変して
65+# 配布する場合は、オリジナルと異なることを明記し、オリジナル
66+# のバージョンナンバーに改変版バージョンナンバーを付加した形
67+# 例えば Ver.2.02-XXXXX のようなバージョンナンバーを付けて下
68+# さい。なお、Copyright表示は変更しないでください。
69+#
70+# 注意 : &mimeencodeをjperl1.X(の2バイト文字対応モード)で使用すると、SJIS
71+# とEUCをうまく7bit JIS(ISO-2022-JP)に変換できません。
72+# 入力に含まれる文字が7bit JIS(ISO-2022-JP)とASCIIのみであること
73+# が保証されている場合を除き、必ずoriginalの英語版のperl(または
74+# jperl1.4以上を -Llatin オプション付き)で動かしてください。
75+# なお、Perl5対応のjperlは試したことがないのでどのような動作になる
76+# かわかりません。
77+#
78+# 参照 : RFC1468, RFC2045, RFC2047
79+
80+## MIME base64 アルファベットテーブル(RFC2045より)
81+%mime = (
82+"000000", "A", "000001", "B", "000010", "C", "000011", "D",
83+"000100", "E", "000101", "F", "000110", "G", "000111", "H",
84+"001000", "I", "001001", "J", "001010", "K", "001011", "L",
85+"001100", "M", "001101", "N", "001110", "O", "001111", "P",
86+"010000", "Q", "010001", "R", "010010", "S", "010011", "T",
87+"010100", "U", "010101", "V", "010110", "W", "010111", "X",
88+"011000", "Y", "011001", "Z", "011010", "a", "011011", "b",
89+"011100", "c", "011101", "d", "011110", "e", "011111", "f",
90+"100000", "g", "100001", "h", "100010", "i", "100011", "j",
91+"100100", "k", "100101", "l", "100110", "m", "100111", "n",
92+"101000", "o", "101001", "p", "101010", "q", "101011", "r",
93+"101100", "s", "101101", "t", "101110", "u", "101111", "v",
94+"110000", "w", "110001", "x", "110010", "y", "110011", "z",
95+"110100", "0", "110101", "1", "110110", "2", "110111", "3",
96+"111000", "4", "111001", "5", "111010", "6", "111011", "7",
97+"111100", "8", "111101", "9", "111110", "+", "111111", "/",
98+);
99+
100+## JISコード(byte数)→encoded-word の文字数対応
101+%mimelen = (
102+ 8,30, 10,34, 12,34, 14,38, 16,42,
103+18,42, 20,46, 22,50, 24,50, 26,54,
104+28,58, 30,58, 32,62, 34,66, 36,66,
105+38,70, 40,74, 42,74,
106+);
107+
108+## ヘッダエンコード時の行の長さの制限
109+$limit=74; ## *注意* $limitを75より大きい数字に設定してはいけない。
110+
111+## ボディbase64エンコード時の行の長さの制限
112+$foldcol=72; ## *注意* $foldcolは76以下の4の倍数に設定すること。
113+
114+## ボディQuoted-Printableエンコード時の行の長さの制限
115+$qfoldcol=75; ## *注意* $foldcolは76以下に設定すること。
116+
117+## null bitの挿入と pad文字の挿入のためのテーブル
118+@zero = ( "", "00000", "0000", "000", "00", "0" );
119+@pad = ( "", "===", "==", "=" );
120+
121+## ASCII, 7bit JIS, Shift-JIS 及び EUC の各々にマッチするパターン
122+$match_ascii = '\x1b\([BHJ]([\t\x20-\x7e]*)';
123+$match_jis = '\x1b\$[@B](([\x21-\x7e]{2})*)';
124+$match_sjis = '([\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])+';
125+$match_euc = '([\xa1-\xfe]{2})+';
126+
127+## MIME Part 2(charset=`ISO-2022-JP',encoding=`B') の head と tail
128+$mime_head = '=?ISO-2022-JP?B?';
129+$mime_tail = '?=';
130+
131+## &bodyencode が使う処理残しデータ用バッファ
132+$benbuf = "";
133+
134+## &bodyencode の処理単位(バイト)
135+$bensize = int($foldcol/4)*3;
136+
137+## &mimeencode interface ##
138+sub main'mimeencode {
139+ local($_) = @_;
140+ s/$match_jis/$jis_in$1/go;
141+ s/$match_ascii/$jis_out$1/go;
142+ $kanji = &checkkanji;
143+ s/$match_sjis/&s2j($&)/geo if ($kanji eq 'SJIS');
144+ s/$match_euc/&e2j($&)/geo if ($kanji eq 'EUC');
145+ s/(\x1b[\$\(][BHJ@])+/$1/g;
146+ 1 while s/(\x1b\$[B@][\x21-\x7e]+)\x1b\$[B@]/$1/;
147+ 1 while s/$match_jis/&mimeencode($&,$`,$')/eo;
148+ s/$match_ascii/$1/go;
149+ $_;
150+}
151+
152+## &bodyencode interface ##
153+sub main'bodyencode {
154+ local($_,$coding) = @_;
155+ if (!defined($coding) || $coding eq "" || $coding eq "b64"){
156+ $_ = $benbuf . $_;
157+ local($cut) = int((length)/$bensize)*$bensize;
158+ $benbuf = substr($_, $cut+$[);
159+ $_ = substr($_, $[, $cut);
160+ $_ = &base64encode($_);
161+ s/.{$foldcol}/$&\n/g;
162+ }elsif ($coding eq "qp"){
163+ # $benbuf が空でなければデータの最初に追加する
164+ $_ = $benbuf . $_;
165+
166+ # 改行文字を正規化する
167+ s/\r\n/\n/g;
168+ s/\r/\n/g;
169+
170+ # データを行単位に分割する(最後の改行文字以降を $benbuf に保存する)
171+ @line = split(/\n/,$_,-1);
172+ $benbuf = pop(@line);
173+
174+ local($result) = "";
175+ foreach (@line){
176+ $_ = &qpencode($_);
177+ $result .= $_ . "\n";
178+ }
179+ $_ = $result;
180+ }
181+ $_;
182+}
183+
184+## &benflush interface ##
185+sub main'benflush {
186+ local($coding) = @_;
187+ local($ret) = "";
188+ if ((!defined($coding) || $coding eq "" || $coding eq "b64")
189+ && $benbuf ne ""){
190+ $ret = &base64encode($benbuf) . "\n";
191+ $benbuf = "";
192+ }elsif ($coding eq "qp" && $benbuf ne ""){
193+ $ret = &qpencode($benbuf) . "\n";
194+ $benbuf = "";
195+ }
196+ $ret;
197+}
198+
199+## MIME ヘッダエンコーディング
200+sub mimeencode {
201+ local($_, $befor, $after) = @_;
202+ local($back, $forw, $blen, $len, $flen, $str);
203+ $befor = substr($befor, rindex($befor, "\n")+1);
204+ $after = substr($after, 0, index($after, "\n")-$[);
205+ $back = " " unless ($befor eq ""
206+ || $befor =~ /[ \t\(]$/);
207+ $forw = " " unless ($after =~ /^\x1b\([BHJ]$/
208+ || $after =~ /^\x1b\([BHJ][ \t\)]/);
209+ $blen = length($befor);
210+ $flen = length($forw)+length($&)-3 if ($after =~ /^$match_ascii/o);
211+ $len = length($_);
212+ return "" if ($len <= 3);
213+ if ($len > 39 || $blen + $mimelen{$len+3} > $limit){
214+ if ($limit-$blen < 30){
215+ $len = 0;
216+ }else{
217+ $len = int(($limit-$blen-26)/4)*2+3;
218+ }
219+ if ($len >= 5){
220+ $str = substr($_, 0, $len).$jis_out;
221+ $str = &base64encode($str);
222+ $str = $mime_head.$str.$mime_tail;
223+ $back.$str."\n ".$jis_in.substr($_, $len);
224+ }else{
225+ "\n ".$_;
226+ }
227+ }else{
228+ $_ .= $jis_out;
229+ $_ = &base64encode($_);
230+ $_ = $back.$mime_head.$_.$mime_tail;
231+ if ($blen + (length) + $flen > $limit){
232+ $_."\n ";
233+ }else{
234+ $_.$forw;
235+ }
236+ }
237+}
238+
239+## MIME base64 エンコーディング
240+sub base64encode {
241+ local($_) = @_;
242+ $_ = unpack("B".((length)<<3), $_);
243+ $_ .= $zero[(length)%6];
244+ s/.{6}/$mime{$&}/go;
245+ $_.$pad[(length)%4];
246+}
247+
248+## Quoted-Printable エンコーディング
249+sub qpencode {
250+ local($_) = @_;
251+
252+ # `=' 文字を16進表現に変換する
253+ s/=/=3D/g;
254+
255+ # 行末のタブとスペースを16進表現に変換する
256+ s/\t$/=09/;
257+ s/ $/=20/;
258+
259+ # 印字可能文字(`!'〜`~')以外の文字を16進表現に変換する
260+ s/([^!-~ \t])/&qphex($1)/ge;
261+
262+ # 1行が$qfoldcol文字以下になるようにソフト改行をいれる
263+ local($folded, $line) = "";
264+ while (length($_) > $qfoldcol){
265+ $line = substr($_, 0, $qfoldcol-1);
266+ if ($line =~ /=$/){
267+ $line = substr($_, 0, $qfoldcol-2);
268+ $_ = substr($_, $qfoldcol-2);
269+ }elsif ($line =~ /=[0-9A-Fa-f]$/){
270+ $line = substr($_, 0, $qfoldcol-3);
271+ $_ = substr($_, $qfoldcol-3);
272+ }else{
273+ $_ = substr($_, $qfoldcol-1);
274+ }
275+ $folded .= $line . "=\n";
276+ }
277+ $folded . $_;
278+}
279+
280+sub qphex {
281+ local($_) = @_;
282+ $_ = '=' . unpack("H2", $_);
283+ tr/a-f/A-F/;
284+ $_;
285+}
286+
287+## Shift-JIS と EUC のどちらの漢字コードが含まれるかをチェック
288+sub checkkanji {
289+ local($sjis,$euc);
290+ $sjis += length($&) while(/$match_sjis/go);
291+ $euc += length($&) while(/$match_euc/go);
292+ return 'NONE' if ($sjis == 0 && $euc == 0);
293+ return 'SJIS' if ($sjis > $euc);
294+ return 'EUC' if ($sjis < $euc);
295+ $often_use_kanji;
296+}
297+
298+## EUC を 7bit JIS に変換
299+sub e2j {
300+ local($_) = @_;
301+ tr/\xa1-\xfe/\x21-\x7e/;
302+ $jis_in.$_.$jis_out;
303+}
304+
305+## Shift-JIS を 7bit JIS に変換
306+sub s2j {
307+ local($string);
308+ local(@ch) = split(//, $_[0]);
309+ while(($j1,$j2)=unpack("CC",shift(@ch).shift(@ch))){
310+ if ($j2 > 0x9e){
311+ $j1 = (($j1>0x9f ? $j1-0xb1 : $j1-0x71)<<1)+2;
312+ $j2 -= 0x7e;
313+ }
314+ else{
315+ $j1 = (($j1>0x9f ? $j1-0xb1 : $j1-0x71)<<1)+1;
316+ $j2 -= ($j2>0x7e ? 0x20 : 0x1f);
317+ }
318+ $string .= pack("CC", $j1, $j2);
319+ }
320+ $jis_in.$string.$jis_out;
321+}
322+1;
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/plugin/core.pl (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/plugin/core.pl (revision 201)
@@ -0,0 +1,419 @@
1+################################################################################
2+#
3+# コアプラグインの実装
4+#
5+################################################################################
6+package Wiki::Plugin;
7+
8+BEGIN {
9+ # パラグラフプラグインのエントリ
10+ $main::P_PLUGIN->{recent} = \&Wiki::Plugin::recent;
11+ $main::P_PLUGIN->{recentdays} = \&Wiki::Plugin::recentdays;
12+ $main::P_PLUGIN->{category_list} = \&Wiki::Plugin::category_list;
13+ $main::P_PLUGIN->{ref_image} = \&Wiki::Plugin::ref_image;
14+ $main::P_PLUGIN->{ref_text} = \&Wiki::Plugin::ref_text;
15+ $main::P_PLUGIN->{outline} = \&Wiki::Plugin::outline;
16+ $main::P_PLUGIN->{search} = \&Wiki::Plugin::search;
17+
18+ # インラインプラグインのエントリ
19+ $main::I_PLUGIN->{category} = \&Wiki::Plugin::category;
20+ $main::I_PLUGIN->{lastmodified} = \&Wiki::Plugin::lastmodified;
21+ $main::I_PLUGIN->{ref} = \&Wiki::Plugin::ref;
22+ $main::I_PLUGIN->{raw} = \&Wiki::Plugin::raw;
23+
24+ # ブロックプラグインのエントリ
25+ $main::B_PLUGIN->{pre} = \&Wiki::Plugin::pre;
26+ $main::B_PLUGIN->{bq} = \&Wiki::Plugin::bq;
27+}
28+
29+#==============================================================================
30+# ページの一覧を更新日時順に表示するプラグイン。
31+#==============================================================================
32+sub recent {
33+ my $max = shift;
34+ my $way = shift;
35+
36+ # 表示方式を決定
37+ if($way eq ""){
38+ $way = "H";
39+ }
40+ if($max eq "V" || $max eq "v"){
41+ $way = "V";
42+ $max = 0;
43+ } elsif($max eq "H" || $max eq "h"){
44+ $way = "H";
45+ $max = 0;
46+ } elsif($max eq ""){
47+ $max = 0;
48+ }
49+
50+ # 表示内容を作成
51+ my $buf = "";
52+ my $content = "";
53+
54+ my @pages = &Wiki::get_page_list();
55+ my $count = 0;
56+
57+ foreach my $page (@pages){
58+ $content = "<a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">".&Util::escapeHTML($page->{NAME})."</a>";
59+ if($way eq "H" || $way eq "h"){
60+ if($count!=0){
61+ $buf .= " / ";
62+ }
63+ $buf .= $content;
64+ } else {
65+ if($count==0){
66+ $buf .= "<ul>\n";
67+ }
68+ $buf .= "<li>".$content."</li>\n";
69+ }
70+ $count++;
71+ last if($count==$max && $max!=0);
72+ }
73+ if($count>0 && $way ne "H" && $way ne "h"){
74+ $buf .= "</ul>\n";
75+ }
76+ return $buf;
77+}
78+
79+#==============================================================================
80+# 日付ごとに更新されたページを一覧表示するプラグイン。
81+#==============================================================================
82+sub recentdays {
83+ my $max = shift;
84+ $max = 5 if($max eq "");
85+ my $buf = "";
86+
87+ my @pages = &Wiki::get_page_list();
88+ my $count = 0;
89+
90+ my $last_year = 0;
91+ my $last_mon = 0;
92+ my $last_day = 0;
93+
94+ foreach my $page (@pages){
95+ my ($sec, $min, $hour, $day, $mon, $year) = localtime($page->{TIME});
96+
97+ $year += 1900;
98+ $mon += 1;
99+
100+ if($last_year!=$year || $last_mon!=$mon || $last_day!=$day){
101+
102+ $count++;
103+ last if($count == $max+1);
104+
105+ $last_year = $year;
106+ $last_mon = $mon;
107+ $last_day = $day;
108+
109+ $buf .= "</ul>\n" if($buf ne "");
110+ $buf .= sprintf("<b>%04d/%02d/%02d</b>\n",$year,$mon,$day);
111+ $buf .= "<ul>\n";
112+ }
113+
114+ $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">".
115+ &Util::escapeHTML($page->{NAME})."</a></li>\n";
116+ }
117+
118+ if($buf ne ""){
119+ $buf .= "</UL>\n";
120+ }
121+
122+ return $buf;
123+}
124+
125+#==============================================================================
126+# ページをカテゴライズするためのプラグイン。
127+#==============================================================================
128+sub category {
129+ my $category = shift;
130+ if($category eq ""){
131+ return "<span class=\"error\">カテゴリが指定されていません。</span>";
132+ } else {
133+ return "[<a href=\"".&Wiki::create_url({c=>$category},$main::CATEGORY_SCRIPT)."\">".
134+ "カテゴリ:".&Util::escapeHTML($category)."</a>]";
135+ }
136+}
137+
138+#=============================================================================
139+# ページの最終更新日時を表示するプラグイン。
140+#=============================================================================
141+sub lastmodified {
142+ my $page = shift || $main::in{"p"};
143+ if(&Wiki::page_exists($page)){
144+ return "最終更新時間:".&Util::format_date(&Wiki::get_last_modified($page));
145+ } else {
146+ return undef;
147+ }
148+}
149+
150+#=============================================================================
151+# カテゴリごとのページ一覧を表示するプラグイン。
152+#=============================================================================
153+sub category_list {
154+ my $category = shift;
155+ my $buf = "";
156+
157+ # 指定されたカテゴリを表示
158+ if($category ne ""){
159+ my @pages = &Wiki::get_page_list();
160+ $buf .= "<h2>".&Util::escapeHTML($category)."</h2>\n";
161+ $buf .= "<ul>\n";
162+ #foreach my $page (sort(@pages)){
163+ foreach my $page (sort {$a->{NAME} cmp $b->{NAME}} @pages){
164+ my $source = &Wiki::get_page($page->{NAME});
165+ foreach my $line (split(/\n/,$source)){
166+ # コメントか整形済テキストの場合は飛ばす
167+ next if($line =~ /^(\t| |\/\/)/);
168+
169+ # カテゴリにマッチしたらリスティング
170+ if($line =~ /{{category\s+$category}}/){
171+ $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page->{NAME}})."\">".
172+ &Util::escapeHTML($page->{NAME})."</a></li>";
173+ last;
174+ }
175+ }
176+ }
177+ $buf .= "</ul>\n";
178+
179+ # 全てのカテゴリを表示
180+ } else {
181+ my $category = {};
182+ my @pages = &Wiki::get_page_list();
183+
184+ foreach my $page (@pages){
185+ my $source = &Wiki::get_page($page->{NAME});
186+ foreach my $line (split(/\n/,$source)){
187+ # コメントか整形済テキストの場合は飛ばす
188+ next if($line =~ /^(\t| |\/\/)/);
189+
190+ # カテゴリにマッチしたらリスティング
191+ while($line =~ /\{\{category\s+(.+?)\}\}/g){
192+ $category->{$1}->{$page->{NAME}} = 1;
193+ }
194+ }
195+ }
196+
197+ foreach my $name (sort(keys(%$category))){
198+ $buf .= "<h2>".&Util::escapeHTML($name)."</h2>\n";
199+ $buf .= "<ul>\n";
200+ foreach my $page (sort(keys(%{$category->{$name}}))){
201+ $buf .= "<li><a href=\"".&Wiki::create_url({p=>$page})."\">".
202+ &Util::escapeHTML($page)."</a></li>\n";
203+ }
204+ $buf .= "</ul>\n";
205+ }
206+ }
207+ return $buf;
208+}
209+
210+#=============================================================================
211+# 添付ファイルへのリンクを表示するためのプラグイン。
212+#=============================================================================
213+sub ref {
214+ my $file = shift;
215+ my $page = shift;
216+ my $alias = shift;
217+
218+ if($file eq ""){
219+ return "<p class=\"error\">ファイルが指定されていません。</p>\n";
220+ }
221+ if(!defined($page) || $page eq ""){
222+ $page = $main::in{"p"};
223+ }
224+ if(!defined($alias) || $alias eq ""){
225+ $alias = $file;
226+ }
227+
228+ my $filename = sprintf("$main::ATTACH_DIR/%s.%s",
229+ &Util::url_encode($page),&Util::url_encode($file));
230+ unless(-e $filename){
231+ return "<p class=\"error\">ファイルが存在しません。</p>\n";
232+ }
233+
234+ return "<a href=\"".&Wiki::create_url({p=>$page,f=>$file},$main::DOWNLOAD_SCRIPT)."\">".&Util::escapeHTML($alias)."</a>";
235+}
236+
237+#=============================================================================
238+# 添付ファイルを画像として表示するためのプラグイン。
239+#=============================================================================
240+sub ref_image {
241+ my $file = shift;
242+ my $page = "";
243+
244+ my @options = @_;
245+ my $width = "";
246+ my $height = "";
247+
248+ if($file eq ""){
249+ return "<p class=\"error\">ファイルが指定されていません。</p>\n";
250+ }
251+ foreach my $option (@options){
252+ if($option =~ /^w([0-9]+)$/){
253+ $width = $1;
254+ } elsif($option =~ /^h([0-9]+)$/){
255+ $height = $1;
256+ } else {
257+ $page = $option;
258+ }
259+ }
260+ if($page eq ""){
261+ $page = $main::in{"p"};
262+ }
263+
264+ my $filename = sprintf("$main::ATTACH_DIR/%s.%s",
265+ &Util::url_encode($page),&Util::url_encode($file));
266+ unless(-e $filename){
267+ return "<p class=\"error\">ファイルが存在しません。</p>\n";
268+ }
269+
270+ &Wiki::get_current_parser()->l_image($page, $file, $width, $height);
271+ return undef;
272+}
273+
274+#=============================================================================
275+# 添付ファイルを画像として表示するためのプラグイン。
276+#=============================================================================
277+sub ref_text {
278+ my $file = shift;
279+ my $page = shift || $main::in{"p"};
280+
281+ if($file eq ""){
282+ return "<p class=\"error\">ファイルが指定されていません。</p>\n";
283+ }
284+
285+ my $filename = sprintf("$main::ATTACH_DIR/%s.%s",
286+ &Util::url_encode($page),&Util::url_encode($file));
287+ unless(-e $filename){
288+ return "<p class=\"error\">ファイルが存在しません。</p>\n";
289+ }
290+
291+ my $text = "";
292+ open(DATA,$filename);
293+ while(<DATA>){
294+ $text .= $_;
295+ }
296+ close(DATA);
297+
298+ # 改行コードを変換
299+ $text =~ s/\r\n/\n/g;
300+ $text =~ s/\r/\n/g;
301+ # 文字コードを変換
302+ &jcode::convert(\$text,"euc");
303+
304+ # preタグをつけて返却
305+ return "<pre>".&Util::escapeHTML($text)."</pre>\n";
306+}
307+
308+#=============================================================================
309+# アウトラインを表示するためのプラグイン
310+# 出力されるHTMLはちょっと手抜きです…
311+#=============================================================================
312+sub outline {
313+ my $page = shift;
314+ my $url = "";
315+
316+ if (!defined($page)) {
317+ $page = $main::in{'p'};
318+ } else {
319+ $url = &Wiki::create_url({p=>$page});
320+ }
321+
322+ my $source = "";
323+ my $level = 0;
324+ my $count = 0;
325+ my $buf = "";
326+
327+ if(&Wiki::page_exists($page)){
328+ $source = &Wiki::get_page($page);
329+ }
330+
331+ foreach my $line (split(/\n/,$source)){
332+ if($line=~/^(!{1,3})(.+)$/){
333+ my $find_level = 4 - length($1);
334+
335+ while($level < $find_level){
336+ $buf .= "<ul>\n";
337+ $level++;
338+ }
339+
340+ while($level > $find_level){
341+ $buf .= "</ul>\n";
342+ $level--;
343+ }
344+ my $section = &Util::delete_tag(&Wiki::process_wiki($2));
345+
346+ $buf .= "<li><a href=\"".$url."#p$count\">$section</a></li>\n";
347+ $count++;
348+ }
349+ }
350+ while($level > 0){
351+ $buf .= "</ul>\n";
352+ $level--;
353+ }
354+ return $buf;
355+}
356+
357+#=============================================================================
358+# 検索フォームを表示するためのプラグイン
359+#=============================================================================
360+sub search {
361+ my $way = shift;
362+ my $or_checked = $main::in{'t'} eq 'or';
363+ my $with_content = $main::in{'c'} eq 'true';
364+ return "<form action=\"".&Wiki::create_url({},$main::MAIN_SCRIPT)."\" method=\"GET\">\n".
365+ " キーワード <input type=\"text\" name=\"w\" size=\"20\" value=\"".&Util::escapeHTML($main::in{'w'})."\">\n".
366+ ($way eq "v" ? "<br>" : "").
367+ " <input type=\"radio\" name=\"t\" id=\"and\" value=\"and\"".(!$or_checked?" checked":"")."><label for=\"and\">AND</label>".
368+ " <input type=\"radio\" name=\"t\" id=\"or\" value=\"or\"".($or_checked?" checked":"")."><label for=\"or\">OR</label>".
369+ ($way eq "v" ? "<br>" : "").
370+ " <input type=\"checkbox\" name=\"c\" id=\"contents\" value=\"true\"".($with_content?" checked":"")."><label for=\"contents\">ページ内容も含める</label>".
371+ " <input type=\"submit\" value=\" 検 索 \">\n".
372+ " <input type=\"hidden\" name=\"a\" value=\"search\">\n".
373+ "</form>\n";
374+}
375+
376+#=============================================================================
377+# 引数で指定した文字列をそのまま表示するインラインプラグイン
378+#=============================================================================
379+sub raw {
380+ my $text = shift;
381+ return &Util::escapeHTML($text);
382+}
383+
384+#=============================================================================
385+# preタグを出力する複数行プラグイン
386+#=============================================================================
387+sub pre {
388+ my $text = shift;
389+ my $option = shift;
390+
391+ my $count = 1;
392+ my $buf = "<pre>";
393+ my @lines = split(/\n/, $text);
394+ my $len = length($#lines + 1);
395+ foreach my $line (@lines){
396+ if($option eq "num"){
397+ $buf .= sprintf("%0${len}d", $count) . "|";
398+ }
399+ $buf .= Util::escapeHTML($line) . "\n";
400+ $count++;
401+ }
402+
403+ return $buf . "</pre>";
404+}
405+
406+#=============================================================================
407+# blockquoteタグを出力する複数行プラグイン
408+#=============================================================================
409+sub bq {
410+ my $text = shift;
411+ my $buf = "<blockquote>";
412+ foreach my $line (split(/(\r\n)|\n|\r/,&Util::escapeHTML($text))){
413+ $buf .= "<p>$line<p>";
414+ }
415+ $buf .= "</blockquote>";
416+ return $buf;
417+}
418+
419+1;
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/theme/default/default.css (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/theme/default/default.css (revision 201)
@@ -0,0 +1,309 @@
1+body {
2+ background-color: #FFFFFF;
3+ color : #000000;
4+}
5+
6+div.adminmenu {
7+ text-align : right;
8+ padding-bottom : 5px;
9+ margin-bottom : 5px;
10+ border-bottom : #000088 1px dotted;
11+ font-size : 80%;
12+}
13+
14+div.footer {
15+ border-top : #000088 1px dotted;
16+ margin-top : 20px;
17+ padding-top : 5px;
18+ text-align : right;
19+ font-size : 80%;
20+ font-style : italic;
21+}
22+
23+hr {
24+ color : #AABBFF;
25+}
26+
27+pre {
28+ border : #888888 1px dotted;
29+ padding : 4px;
30+ margin-left : 20px;
31+ color : #666666;
32+}
33+
34+blockquote {
35+ border : #AABBFF 1px solid;
36+ padding : 4px;
37+ margin-left : 20px;
38+ font-style : italic;
39+}
40+
41+h1 {
42+ text-align : right;
43+ background-color : #FFFFFF;
44+ font-family : Verdana,Arial,Helvetica,sans-serif;
45+}
46+
47+
48+h2 {
49+ background-color : #AABBFF;
50+ font-family : Verdana,Arial,Helvetica,sans-serif;
51+ padding-left : 4pt;
52+ margin-bottom : 5px;
53+}
54+
55+h3 {
56+ border-left : #AABBFF 10px solid;
57+ border-top : #AABBFF 5px solid;
58+ border-right : #AABBFF 1px solid;
59+ border-bottom : #AABBFF 1px solid;
60+ font-family : Verdana,Arial,Helvetica,sans-serif;
61+ padding-left : 3pt;
62+ margin-bottom : 5px;
63+}
64+
65+h4 {
66+ border-left : #AABBFF 10px solid;
67+ padding-left : 4px;
68+ font-family : Verdana,Arial,Helvetica,sans-serif;
69+ padding-left : 2pt;
70+ margin-bottom : 5px;
71+}
72+
73+div.body {
74+ padding-left : 5px;
75+}
76+
77+div.body p {
78+ text-indent : 10px;
79+ line-height : 150%;
80+ margin-top : 10px;
81+ margin-bottom : 20px;
82+}
83+
84+div.body blockquote p {
85+ margin-top : 0px;
86+ margin-bottom : 0px;
87+ text-indent : 0px;
88+}
89+
90+table {
91+ border : #888888 2px solid;
92+}
93+
94+th {
95+ border : #888888 1px solid;
96+ background-color : #88AAFF;
97+}
98+
99+td {
100+ border : #888888 1px solid;
101+}
102+
103+A:link {
104+ color : #4444FF;
105+ text-decoration : none;
106+}
107+
108+A:visited {
109+ color : #4444FF;
110+ text-decoration : none;
111+}
112+
113+A:hover {
114+ color : #FF4444;
115+ text-decoration : underline;
116+}
117+
118+dt {
119+ border-bottom : #4444FF 1px dotted;
120+ margin-bottom : 5px;
121+ font-weight : bold;
122+}
123+
124+dd {
125+ margin-left : 20pt;
126+ margin-bottom : 5pt;
127+}
128+
129+div.main {
130+ margin-left: 150px;
131+}
132+
133+div.sidebar {
134+ position : absolute;
135+ top : 0px;
136+ left : 0px;
137+ width : 150px;
138+ font-size : x-small;
139+ padding : 2pt;
140+ border-right : #AABBFF 1px solid;
141+ border-bottom : #AABBFF 1px solid;
142+ color : #000000;
143+ background-color: #EEEEFF;
144+ word-break : break-all;
145+}
146+
147+div.comment {
148+ margin-top : 10px;
149+ margin-bottom : 10px;
150+ background-color : #EEEEFF;
151+ border : #AABBFF 1px solid;
152+ font-size : 80%;
153+}
154+
155+div.comment p {
156+ margin-top : 5pt;
157+ margin-bottom : 5pt;
158+}
159+
160+div.sidebar ul,div.sidebar li {
161+ padding-left : 0pt;
162+ margin-left : 10pt;
163+}
164+
165+div.sidebar ol,div.sidebar li {
166+ padding-left : 0pt;
167+ margin-left : 10pt;
168+}
169+
170+div.sidebar h2,div.sidebar h3,div.sidebar h4 {
171+ margin-top : 0px;
172+}
173+
174+/* calendar plugin */
175+table.calendar {
176+ font-size: 90%;
177+ line-height: 1.1em;
178+}
179+
180+table.calendar td {
181+ margin: 0px;
182+ text-align: right;
183+ padding: 0px;
184+}
185+
186+table.calendar td.calendar-prev-month,
187+table.calendar td.calendar-current-month,
188+table.calendar td.calendar-next-month {
189+ text-align: center;
190+}
191+
192+.calendar-sunday {
193+ color: #f00;
194+}
195+
196+.calendar-saturday {
197+ color: #00f;
198+}
199+
200+.calendar-weekday {
201+ color: #000;
202+}
203+
204+.calendar-prev-month, .calendar-current-month, .calendar-next-month,
205+.calendar-sunday, .calendar-weekday, .calendar-saturday {
206+ background-color : #88AAFF;
207+}
208+
209+@media print {
210+ div.sidebar {
211+ display: none;
212+ }
213+
214+ div.main {
215+ margin-left: 0px;
216+ }
217+
218+ div.adminmenu {
219+ display: none;
220+ }
221+
222+ div.footer {
223+ display: none;
224+ }
225+
226+ h1 {
227+ display: none;
228+ }
229+
230+ div.header {
231+ display: none;
232+ }
233+
234+ div.comment {
235+ display: none;
236+ }
237+
238+ a.partedit {
239+ display: none;
240+ }
241+}
242+
243+textarea.edit {
244+ width: 100%;
245+}
246+
247+div.diff {
248+ border : #888888 1px dotted;
249+ padding : 4px;
250+ margin-left : 20px;
251+ color : #666666;
252+}
253+
254+ins.diff {
255+ background-color: #AAFFAA;
256+ text-decoration: none;
257+}
258+
259+del.diff {
260+ background-color: #FFAAAA;
261+ text-decoration: none;
262+}
263+
264+/*----------------------------------------------------------------------------*/
265+/* User CSS */
266+/*----------------------------------------------------------------------------*/
267+/* エラーメッセージ */
268+.error {
269+ color : #FF0000;
270+ font-weight : bold;
271+}
272+
273+/* 存在しないWikiページ */
274+span.nopage {
275+ background-color : #FFFF88;
276+}
277+
278+/* Wikiページへのアンカ */
279+a.wikipage:link {
280+ text-decoration : underline;
281+}
282+
283+a.wikipage:visited {
284+ text-decoration : underline;
285+}
286+
287+a.wikipage:hover {
288+ background-color: #DDDDDD;
289+ text-decoration : underline;
290+}
291+
292+/* parteditプラグイン */
293+div.partedit {
294+ text-align : right;
295+ font-size : 80%;
296+}
297+
298+/* calendarプラグイン */
299+td.today {
300+ background-color : #FF8888;
301+}
302+
303+td.have {
304+ font-weight : bold;
305+}
306+
307+.calendar td {
308+ text-align : right;
309+}
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
--- fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/release.sh (nonexistent)
+++ fswiki-lite/tags/fswikilite0_1_0/fswiki-lite/release.sh (revision 201)
@@ -0,0 +1,70 @@
1+#!/bin/sh
2+##########################################################################
3+#
4+# FSWikiLiteリリース用シェルスクリプト
5+#
6+##########################################################################
7+#=========================================================================
8+# 引数のチェック
9+#=========================================================================
10+if [ $# -lt 1 ]
11+then
12+ echo "./release.sh version"
13+ exit 1
14+fi
15+
16+#=========================================================================
17+# バージョン情報
18+#=========================================================================
19+VERSION=$1
20+RELEASE="fswiki_lite_$VERSION"
21+
22+#=========================================================================
23+# テンポラリディレクトリがある場合は削除
24+#=========================================================================
25+if [ -e $RELEASE ]; then
26+ echo "delete temp directory..."
27+ rm -rf $RELEASE
28+fi
29+
30+#=========================================================================
31+# zipファイルがある場合は削除
32+#=========================================================================
33+if [ -e $RELEASE.zip ]; then
34+ echo "delete zip file..."
35+ rm -f $RELEASE.zip
36+fi
37+
38+#=========================================================================
39+# テンポラリディレクトリの作成
40+#=========================================================================
41+echo "create temp directory..."
42+mkdir $RELEASE
43+
44+#=========================================================================
45+# ファイルのコピー
46+#=========================================================================
47+echo "copy to temp directory..."
48+cp ./*.cgi $RELEASE
49+cp -r ./data $RELEASE
50+cp -r ./docs $RELEASE
51+cp -r ./lib $RELEASE
52+cp -r ./plugin $RELEASE
53+cp -r ./theme $RELEASE
54+
55+#=========================================================================
56+# zipファイルの作成
57+#=========================================================================
58+echo "create zip file..."
59+find ./$RELEASE \! -path '*/CVS*' -exec zip $RELEASE.zip {} \;
60+
61+#=========================================================================
62+# テンポラリディレクトリを削除
63+#=========================================================================
64+echo "remove temp directory..."
65+rm -rf $RELEASE
66+
67+#=========================================================================
68+# 終了
69+#=========================================================================
70+echo "complete."
Show on old repository browser