/[pub]/suikawiki/script/wiki.cgi
Suika

Diff of /suikawiki/script/wiki.cgi

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by wakaba, Mon Feb 4 13:19:08 2002 UTC revision 1.4 by wakaba, Mon Feb 4 15:03:23 2002 UTC
# Line 1  Line 1 
1  #!/usr/local/bin/perl  #!/usr/bin/perl
2  use lib "../lib";  use lib "../lib";
3  use CGI::Carp 'fatalsToBrowser';  use CGI::Carp 'fatalsToBrowser';
4  use Algorithm::Diff qw(traverse_sequences);  use Algorithm::Diff qw(traverse_sequences);
5  # use strict;  # use strict;
6  #  #
7  # yukiwiki.cgi - Yet another WikiWikiWeb clone.  # yukiwiki.cgi - Yet another WikiWikiWeb clone.
8  #  #
9  # Copyright (C) 2000,2001 by Hiroshi Yuki.  # Copyright (C) 2000,2001 by Hiroshi Yuki.
10  # <hyuki@hyuki.com>  # <hyuki@hyuki.com>
11  # http://www.hyuki.com/yukiwiki/  # http://www.hyuki.com/yukiwiki/
12  #  #
13  # This program is free software; you can redistribute it and/or modify  # This program is free software; you can redistribute it and/or modify
14  # it under the terms of the GNU General Public License as published by  # it under the terms of the GNU General Public License as published by
15  # the Free Software Foundation; either version 2 of the License, or  # the Free Software Foundation; either version 2 of the License, or
16  # (at your option) any later version.  # (at your option) any later version.
17  #  #
18  # This program is distributed in the hope that it will be useful,  # This program is distributed in the hope that it will be useful,
19  # but WITHOUT ANY WARRANTY; without even the implied warranty of  # but WITHOUT ANY WARRANTY; without even the implied warranty of
20  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  # GNU General Public License for more details.  # GNU General Public License for more details.
22  #  #
23  # $Id$  # $Id$
24  ##############################  ##############################
25  my $version = "1.6.6";  my $version = "1.6.6";
26  ##############################  ##############################
27  # 単独テストのときには 1 にする。  # テアニネ・ニ・ケ・ネ、ホ、ネ、ュ、ヒ、マ 1 、ヒ、ケ、。」
28  my $testing = 0;  my $testing = 0;
29  ##############################  ##############################
30  # 漢字ライブラリ  # エチサ・鬣、・ヨ・鬣
31  my $jcodelib = 'jcode.pl';  my $jcodelib = 'jcode.pl';
32  ##############################  ##############################
33  # 保存・表示の漢字コード  # ハンツク。ヲノスシィ、ホエチサ・ウ。シ・ノ
34  my $kanjicode = 'sjis';     # 'sjis' 'euc'  my $kanjicode = 'euc';     # 'sjis' 'euc'
35  my $charset = 'Shift_JIS';  # 'Shift_JIS' 'EUC-JP'  my $charset = 'euc-jisx0213';  # 'Shift_JIS' 'EUC-JP'
36  ##############################  ##############################
37  # dbmopenが使えるなら1、使えないなら0  # dbmopen、ャサネ、ィ、、ハ、1。「サネ、ィ、ハ、、、ハ、0
38  my $dbmopen = 0;  my $dbmopen = 0;
39  ##############################  ##############################
40  # データベース名(.pag, .dir, .dbなどは不要)  # ・ヌ。シ・ソ・ル。シ・ケフセ。ハ.pag, .dir, .db、ハ、ノ、マノヤヘラ。ヒ
41  # $dbmopen = 1のときはデータベース名、  # $dbmopen = 1、ホ、ネ、ュ、マ・ヌ。シ・ソ・ル。シ・ケフセ。「
42  # $dbmopen = 0のときはディレクトリ名になる。  # $dbmopen = 0、ホ、ネ、ュ、マ・ヌ・」・・ッ・ネ・フセ、ヒ、ハ、。」
43  my $dbname = './yukiwiki';  my $dbname = './wikidata';
44  my $diffdbname = './yukidiff';  my $diffdbname = './wikidiff';
45  ##############################  ##############################
46  # 修正者の氏名(自由に変更してください)  # ス、タオシヤ、ホサ睥セ。ハシォヘウ、ヒハムケケ、キ、ニ、ッ、タ、オ、、。ヒ
47  my $modifier = 'Hiroshi Yuki';  my $modifier = 'suika';
48  ##############################  ##############################
49  # 修正者のWebページ(自由に変更してください)  # ス、タオシヤ、ホWeb・レ。シ・ク。ハシォヘウ、ヒハムケケ、キ、ニ、ッ、タ、オ、、。ヒ
50  my $modifierlink = 'http://www.hyuki.com/';  my $modifierlink = 'http://suika.fam.cx/';
51  ##############################  ##############################
52  # このページのURL  # 、ウ、ホ・レ。シ・ク、ホURL
53  my $thisurl = 'yukiwiki.cgi';  my $thisurl = 'wiki';
54  ##############################  ##############################
55  # 開始ページ名  # ウォサマ・レ。シ・クフセ
56  my $toppage = 'FrontPage';  my $toppage = 'HomePage';
57  ##############################  ##############################
58  # 最終更新ページ名  # コヌスェケケソキ・レ。シ・クフセ
59  my $whatsnew = 'RecentChanges';  my $whatsnew = 'RecentChanges';
60  ##############################  ##############################
61  # 最終更新に掲載するページ数  # コヌスェケケソキ、ヒキヌコワ、ケ、・レ。シ・クソ
62  my $maxnew = 50;  my $maxnew = 50;
63  ##############################  ##############################
64  # アイコンファイル名(カラー版)  # ・「・、・ウ・・ユ・。・、・フセ。ハ・ォ・鬘シネヌ。ヒ
65  my $iconfile = 'yukiwiki.gif';  my $iconfile = '';
66  ##############################  ##############################
67  # アイコンファイル名(モノクロ版)  # ・「・、・ウ・・ユ・。・、・フセ。ハ・筵ホ・ッ・ネヌ。ヒ
68  # my $iconfile = 'yukimono.gif';  # my $iconfile = '';
69  ##############################  ##############################
70  # ページを変更したときにtouchするファイル(''なら何もしない)  # ・レ。シ・ク、ハムケケ、キ、ソ、ネ、ュ、ヒtouch、ケ、・ユ・。・、・。ハ''、ハ、魎ソ、筅キ、ハ、、。ヒ
71  my $touchfile = 'touch.txt';  my $touchfile = 'touch.txt';
72  ##############################  ##############################
73  # プレビュー用の背景色  # ・ラ・・モ・蝪シヘム、ホヌリキハソァ
74  my $preview_color = '#FFCCCC';  my $preview_color = '#FFCCCC';
75  ##############################  ##############################
76  # 全ページのスタイル  # チエ・レ。シ・ク、ホ・ケ・ソ・、・
77  my $style = <<'EOD';  my $style = <<'EOD';
78  pre, dl, ul, ol, p, blockquote { line-height:120%; }  pre, dl, ul, ol, p, blockquote { line-height:120%; }
79  a { text-decoration: none; }  a { text-decoration: none; }
80  a:link { color: #0000FF; background-color: #FFFFFF; }  a:link { color: #0000FF; background-color: #FFFFFF; }
81  a:visited { color: #9900CC; background-color: #FFFFFF; }  a:visited { color: #9900CC; background-color: #FFFFFF; }
82  a:hover { text-decoration: underline; }  a:hover { text-decoration: underline; }
83  EOD  EOD
84  ##############################  ##############################
85  # テキスト入力部分の大きさ  # ・ニ・ュ・ケ・ネニホマノハャ、ホツ遉ュ、オ
86  my $cols = 80;  my $cols = 80;
87  my $rows = 20;  my $rows = 20;
88  ##############################  ##############################
89  my %form = ();  my %form = ();
90  my %database = ();  my %database = ();
91  my %diffbase = ();  my %diffbase = ();
92  my $diff_text = '';  my $diff_text = '';
93  my @diff_added = ();  my @diff_added = ();
94  my @diff_deleted = ();  my @diff_deleted = ();
95  my $msgrefA;  my $msgrefA;
96  my $msgrefB;  my $msgrefB;
97  ##############################  ##############################
98  # 編集不可ページ名一覧  # ハヤスクノヤイト・レ。シ・クフセーヘ
99  my @uneditable = ( $whatsnew );  my @uneditable = ( $whatsnew );
100  ##############################  ##############################
101  # リンク用の正規表現  # ・・・ッヘム、ホタオオャノスクス
102  # YukiWikiのリンクは2種類ある。  # YukiWiki、ホ・・・ッ、マ2シホ爨「、。」
103  #  #
104  # (1) WikiName (RecentChangesとかFrontPageのようなもの)  # (1) WikiName (RecentChanges、ネ、ォFrontPage、ホ、隍ヲ、ハ、筅ホ)
105  # (2) BracketName ([[結城浩]]とか[[トラブルシュート]]のようなもの)  # (2) BracketName ([[キセケタ]]、ネ、ォ[[・ネ・鬣ヨ・・キ・蝪シ・ネ]]、ホ、隍ヲ、ハ、筅ホ)
106  #  #
107  # ※シフトJISの2バイト目には ']' が来うるので、  # 「ィ・キ・ユ・ネJIS、ホ2・ミ・、・ネフワ、ヒ、マ ']' 、ャヘ隍ヲ、、ホ、ヌ。「
108  # 文字']'を1つ多くとるようにしている。  # ハクサ']'、1、トツソ、ッ、ネ、、隍ヲ、ヒ、キ、ニ、、、。」
109  #  #
110  my $WikiName = '([A-Z][a-z]+([A-Z][a-z]+)+)';  my $WikiName = '([A-Z][a-z]+([A-Z][a-z]+)+)';
111  my $BracketName = '\[\[([^>\s]+?\]?)\]\]';  my $BracketName = '\[\[([^>\s]+?\]?)\]\]';
112    
113  # アイコン部分のタグ  # ・「・、・ウ・ノハャ、ホ・ソ・ー
114  my $IconTag = <<"EOD";  my $IconTag = ''; #<<"EOD";
115  <a href="http://www.hyuki.com/yukiwiki/"><img src="$iconfile"  #<a href="http://www.hyuki.com/yukiwiki/"><img src="$iconfile"
116   border="0" width="80" height="80" alt="[YukiWiki]" /></a>  # border="0" width="80" height="80" alt="[YukiWiki]" /></a>
117  EOD  #EOD
118    
119  require "$jcodelib";  require "$jcodelib";
120    
121  &init_form($kanjicode);  &init_form($kanjicode);
122    
123  if ($testing) {  if ($testing) {
124      %form = (      %form = (
125          # 'mycmd' => 'write',          # 'mycmd' => 'write',
126          'mycmd' => 'read',          'mycmd' => 'read',
127          #'mycmd' => 'search',          #'mycmd' => 'search',
128          #'mycmd' => 'edit',          #'mycmd' => 'edit',
129          'mymsg' => <<"EOD",          'mymsg' => <<"EOD",
130  はじめまして。  、マ、ク、皃゙、キ、ニ。」
131  これからいろいろ書き込みますね。  、ウ、、ォ、鬢、、、、、ス、ュケ、゚、゙、ケ、ヘ。」
132  LinkPageも見てください。  LinkPage、篋ォ、ニ、ッ、タ、オ、、。」
133  TestPageはどうでしょうか。  TestPage、マ、ノ、ヲ、ヌ、キ、遉ヲ、ォ。」
134  どうぞよろしく。  、ノ、ヲ、セ、隍、キ、ッ。」
135  http://www.hyuki.com/  http://www.hyuki.com/
136  [[結城浩]]  [[キセケタ]]
137  EOD  EOD
138          'mypage' => '<結城浩>',          'mypage' => '<キセケタ>',
139          'myword' => '結',          'myword' => 'キ',
140          # '3C8C8B8FE98D5F3E' => '',          # '3C8C8B8FE98D5F3E' => '',
141          # 'TestPage' => '',          # 'TestPage' => '',
142      );      );
143  }  }
144  &main;  &main;
145  exit(0);  exit(0);
146    
147  # メイン  # ・皈、・
148  sub main {  sub main {
149      &normalize_form;      &normalize_form;
150      if ($dbmopen) {      if ($dbmopen) {
151          if (!dbmopen(%database, $dbname, 0666)) {          if (!dbmopen(%database, $dbname, 0666)) {
152              &print_error("(dbmopen) $dbname が作れません。");              &print_error("(dbmopen) $dbname 、ャコ、、゙、サ、。」");
153          }          }
154      } else {      } else {
155          if (!tie(%database, "YukiWikiDB", $dbname)) {          if (!tie(%database, "YukiWikiDB", $dbname)) {
156              &print_error("(tie error)");              &print_error("(tie error)");
157          }          }
158      }      }
159    
160      # myspecial対応      # myspecialツミア
161      foreach (keys %form) {      foreach (keys %form) {
162          if (/^myspecial_(.*)/) {          if (/^myspecial_(.*)/) {
163              $form{mycmd} = $1;              $form{mycmd} = $1;
164              last;              last;
165          }          }
166      }      }
167    
168      if ($form{mycmd} eq 'read') {      if ($form{mycmd} eq 'read') {
169          &do_read;          &do_read;
170      } elsif ($form{mycmd} eq 'preview') {      } elsif ($form{mycmd} eq 'preview') {
171          &do_preview;          &do_preview;
172      } elsif ($form{mycmd} eq 'write') {      } elsif ($form{mycmd} eq 'write') {
173          &do_write;          &do_write;
174      } elsif ($form{mycmd} eq 'edit') {      } elsif ($form{mycmd} eq 'edit') {
175          &do_edit;          &do_edit;
176      } elsif ($form{mycmd} eq 'reedit') {      } elsif ($form{mycmd} eq 'reedit') {
177          &do_reedit;          &do_reedit;
178      } elsif ($form{mycmd} eq 'search') {      } elsif ($form{mycmd} eq 'search') {
179          &do_search;          &do_search;
180      } elsif ($form{mycmd} eq 'list') {      } elsif ($form{mycmd} eq 'list') {
181          &do_list;          &do_list;
182      } elsif ($form{mycmd} eq 'diff') {      } elsif ($form{mycmd} eq 'diff') {
183          &do_diff;          &do_diff;
184      } else {      } else {
185          $form{mypage} = $toppage;          $form{mypage} = $toppage;
186          &do_read;          &do_read;
187      }      }
188      if ($dbmopen) {      if ($dbmopen) {
189          dbmclose(%database);          dbmclose(%database);
190      } else {      } else {
191          untie(%database);          untie(%database);
192      }      }
193  }  }
194    
195  # ページの表示  # ・レ。シ・ク、ホノスシィ
196  sub do_read {  sub do_read {
197      my $page_name = $form{mypage};      my $page_name = $form{mypage};
198      my $percent_name = &encode_percent($page_name);      my $percent_name = &encode_percent($page_name);
199      &print_header($page_name);      &print_header($page_name);
200      print qq|<h1>$IconTag<a href="$thisurl?mycmd=search&myword=$percent_name">$page_name</a></h1>\n|;      print qq|<h1>$IconTag<a href="$thisurl?mycmd=search;myword=$percent_name">$page_name</a></h1>\n|;
201      &print_toolbar($page_name);      &print_toolbar($page_name);
202      print &convert_html(&get_page($page_name));      print &convert_html(&get_page($page_name));
203      &print_footer;      &print_footer;
204  }  }
205    
206  # ページの編集  # ・レ。シ・ク、ホハヤスク
207  sub do_edit {  sub do_edit {
208      if (not &is_editable($form{mypage})) {      if (not &is_editable($form{mypage})) {
209          # 編集不可ページは表示のみ          # ハヤスクノヤイト・レ。シ・ク、マノスシィ、ホ、゚
210          &do_read;          &do_read;
211          return;          return;
212      }      }
213      &editpage(&get_page($form{mypage}));      &editpage(&get_page($form{mypage}));
214  }  }
215    
216  # ページの再編集  # ・レ。シ・ク、ホコニハヤスク
217  sub do_reedit {  sub do_reedit {
218      if (not &is_editable($form{mypage})) {      if (not &is_editable($form{mypage})) {
219          # 編集不可ページは表示のみ          # ハヤスクノヤイト・レ。シ・ク、マノスシィ、ホ、゚
220          &do_read;          &do_read;
221      } else {      } else {
222          &editpage($form{mymsg});          &editpage($form{mymsg});
223      }      }
224  }  }
225    
226  sub editpage {  sub editpage {
227      my $page_msg = shift;      my $page_msg = shift;
228      my $page_name = $form{mypage};      my $page_name = $form{mypage};
229      my $digest = &calc_message_digest($page_msg);      my $digest = &calc_message_digest($page_msg);
230      &print_header($page_name);      &print_header($page_name);
231      print qq|<h1>$IconTag${page_name}の編集</h1>\n|;      print qq|<h1>$IconTag${page_name}、ホハヤスク</h1>\n|;
232      &print_toolbar($page_name);      &print_toolbar($page_name);
233      $page_msg = &escape($page_msg);      $page_msg = &escape($page_msg);
234      print <<"EOD";      print <<"EOD";
235  <form action="$thisurl" method="post">  <form action="$thisurl" method="post">
236  <input type="hidden" name="mycmd" value="preview">  <!--<input type="hidden" name="mycmd" value="preview">-->
237  <input type="hidden" name="mypage" value="$page_name">  <input type="hidden" name="mypage" value="$page_name">
238  <input type="hidden" name="mydigest" value="$digest">  <input type="hidden" name="mydigest" value="$digest">
239  <textarea cols="$cols" rows="$rows" name="mymsg" wrap="virtual">$page_msg</textarea><br>  <textarea cols="$cols" rows="$rows" name="mymsg" wrap="virtual">$page_msg</textarea><br>
240  <input type="submit" value="プレビュー">  <input type="submit" name="myspecial_preview" value="ウホヌァ">
241  </form>  <input type="submit" name="myspecial_write" value="ウホヌァ、サ、コハムケケ">
242  <hr>  </form>
243  <h3>テキスト整形のルール</h3>  <hr>
244    <h3>・ニ・ュ・ケ・ネターキチ、ホ・。シ・</h3>
245  <p>通常は入力した文字がそのまま出力されますが、  
246  以下のルールに従ってテキスト整形を行うことができます。</p>  <p>トフセ、マニホマ、キ、ソハクサ、ャ、ス、ホ、゙、゙スミホマ、オ、、゙、ケ、ャ。「
247    ーハイシ、ホ・。シ・、ヒスセ、テ、ニ・ニ・ュ・ケ・ネターキチ、ケヤ、ヲ、ウ、ネ、ャ、ヌ、ュ、゙、ケ。」</p>
248  <ul>  
249  <li>  <ul>
250  空行は段落の区切りとなります。  <li>
251    カケヤ、マテハヘ、ホカ霏レ、熙ネ、ハ、熙゙、ケ。」
252  <li>  
253  HTMLのタグは書けません。  <li>
254    HTML、ホ・ソ・ー、マス、ア、゙、サ、。」
255  <li>  
256  ''ボールド''のようにシングルクォート二つではさむと、ボールドになります。  <li>
257    ''カットエ''、ホ、隍ヲ、ヒ・キ・・ー・・ッ・ゥ。シ・ネニ、ト、ヌ、マ、オ、爨ネ。「カットエ、ヒ、ハ、熙゙、ケ。」
258  <li>  
259  '''イタリック'''のようにシングルクォート三つではさむと、イタリックになります。  <li>
260    '''ケケ、ヒカットエ'''、ホ、隍ヲ、ヒ・キ・・ー・・ッ・ゥ。シ・ネサー、ト、ヌ、マ、オ、爨ネ。「ケケ、ヒカットエ、ヒ、ハ、熙゙、ケ。」
261  <li>  
262  ----のようにマイナス4つがあると、水平線になります。  <li>
263    ----、ホ、隍ヲ、ヒ・゙・、・ハ・ケ4、ト、ャ、「、、ネ。「ソ衞ソタ、ヒ、ハ、熙゙、ケ。」
264  <li>  
265  *を行頭に書くと大見出しになります。  <li>
266    *、ケヤニャ、ヒス、ッ、ネツ邵ォスミ、キ、ヒ、ハ、熙゙、ケ。」
267  <li>  
268  **を行頭に書くと小見出しになります。  <li>
269    **、ケヤニャ、ヒス、ッ、ネセョクォスミ、キ、ヒ、ハ、熙゙、ケ。」
270  <li>  
271  -を行頭に書くと箇条書きになります。- -- --- の3レベルがあります。  <li>
272    -、ケヤニャ、ヒス、ッ、ネイユセス、ュ、ヒ、ハ、熙゙、ケ。」- -- --- 、ホ3・・ル・、ャ、「、熙゙、ケ。」
273  <li>  
274  :を行頭に書くと用語と解説文が作れます。  <li>
275    :、ケヤニャ、ヒス、ッ、ネヘムク、ネイタ簗ク、ャコ、、゙、ケ。」
276  <pre>  
277      :用語1:いろいろ書いた解説文1  <pre>
278      :用語2:いろいろ書いた解説文2      :ヘムク1:、、、、、、ス、、、ソイタ簗ク1
279      :用語3:いろいろ書いた解説文3      :ヘムク2:、、、、、、ス、、、ソイタ簗ク2
280  </pre>      :ヘムク3:、、、、、、ス、、、ソイタ簗ク3
281    </pre>
282  <li>  
283  http://www.hyuki.com/ のようなURLは自動的にリンクになります。  <li>
284    http://www.hyuki.com/ 、ホ、隍ヲ、ハURL、マシォニーナェ、ヒ・・・ッ、ヒ、ハ、熙゙、ケ。」
285  <li>  
286  YukiWikiのように大文字小文字を混ぜた英文字列を書くと、  <li>
287  YukiWikiのページ名になります。  YukiWiki、ホ、隍ヲ、ヒツ醋クサセョハクサ、コョ、シ、ソアムハクサホ、ス、ッ、ネ。「
288    YukiWiki、ホ・レ。シ・クフセ、ヒ、ハ、熙゙、ケ。」
289  <li>  
290  [[結城浩]]のように二重の大かっこ[[ ]]でくくった文字列を書くと、  <li>
291  YukiWikiのページ名になります。  [[キセケタ]]、ホ、隍ヲ、ヒニスナ、ホツ遉ォ、テ、ウ[[ ]]、ヌ、ッ、ッ、テ、ソハクサホ、ス、ッ、ネ。「
292  大かっこの中にはスペースを含めてはいけません。  YukiWiki、ホ・レ。シ・クフセ、ヒ、ハ、熙゙、ケ。」
293  日本語も使えます。  ツ遉ォ、テ、ウ、ホテ讀ヒ、マ・ケ・レ。シ・ケ、エ゙、皃ニ、マ、、、ア、゙、サ、。」
294    ニヒワク、篏ネ、ィ、゙、ケ。」
295  <li>  
296  行頭がスペースで始まっていると、  <li>
297  その段落は整形済み扱われます。  ケヤニャ、ャ・ケ・レ。シ・ケ、ヌサマ、゙、テ、ニ、、、、ネ。「
298  プログラムを書き込むときに使うと便利です。  、ス、ホテハヘ、マターキチコム、゚ーキ、、、゙、ケ。」
299    ・ラ・・ー・鬣爨ス、ュケ、爨ネ、ュ、ヒサネ、ヲ、ネハリヘ、ヌ、ケ。」
300  <li>  
301  > を行頭に書くと、  <li>
302  引用文が書けます。  &gt; 、ケヤニャ、ヒス、ッ、ネ。「
303  >の数が多いとインデントが深くなります(3レベルまで)。  ーヘムハク、ャス、ア、゙、ケ。」
304    &gt; 、ホソ、ャツソ、、、ネ・、・・ヌ・・ネ、ャソシ、ッ、ハ、熙゙、ケ。ハ3・・ル・、゙、ヌ。ヒ。」
305  </ul>  
306  EOD  </ul>
307      &print_footer;  EOD
308  }      &print_footer;
309    }
310  # ページの検索  
311  sub do_search {  # ・レ。シ・ク、ホク。コ
312      if ($form{myword}) {  sub do_search {
313          &print_header('検索結果');      if ($form{myword}) {
314          print qq|<h1>$IconTag$form{myword}の検索結果</h1>\n|;          &print_header('ク。コキイフ');
315          &print_toolbar();          print qq|<h1>$IconTag$form{myword}、ホク。コキイフ</h1>\n|;
316          print qq|<ul>\n|;          &print_toolbar();
317          my $count = 0;          print qq|<ul>\n|;
318          foreach my $page_name (sort keys %database) {    # sortするのは無謀かな          my $count = 0;
319              if ($database{$page_name} =~ /\Q$form{'myword'}\E/) {          foreach my $page_name (sort keys %database) {    # sort、ケ、、ホ、マフオヒナ、ォ、ハ
320                  my $encoded = &encode_percent($page_name);              if ($database{$page_name} =~ /\Q$form{'myword'}\E/) {
321                  print qq|<li><a href="$thisurl?mycmd=read&mypage=$encoded">$page_name</a>\n|;                  my $encoded = &encode_percent($page_name);
322                  $count++;                  print qq|<li><a href="$thisurl?mycmd=read;mypage=$encoded">$page_name</a>\n|;
323              }                  $count++;
324          }              }
325          print qq|</ul>\n|;          }
326          if ($count > 0) {          print qq|</ul>\n|;
327              print qq|<p><b>$form{myword}</b>を含むページは、上に示す<b>$count</b>ページです。</p>\n|;          if ($count > 0) {
328          } else {              print qq|<p><strong>$form{myword}</strong>、エ゙、爭レ。シ・ク、マ。「セ螟ヒシィ、ケ<strong>$count</strong> ・レ。シ・ク、ヌ、ケ。」</p>\n|;
329              print qq|<p><b>$form{myword}</b>を含むページは見つかりません。</p>\n|;          } else {
330          }              print qq|<p><strong>$form{myword}</strong>、エ゙、爭レ。シ・ク、マクォ、ト、ォ、熙゙、サ、。」</p>\n|;
331      } else {          }
332          &print_header('単語検索');      } else {
333          print qq|<h1>$IconTag単語検索</h1>\n|;          &print_header('テアクク。コ');
334          &print_toolbar();          print qq|<h1>$IconTagテアクク。コ</h1>\n|;
335      }          &print_toolbar();
336      print <<"EOD";      }
337  <p>      print <<"EOD";
338  <form action="$thisurl" method="post">  <p>
339  <input type="hidden" name="mycmd" value="search">  <form action="$thisurl" method="post">
340  <input type="text" name="myword" size="20" value="$form{myword}">  <input type="hidden" name="mycmd" value="search">
341  <input type="submit" value="単語検索">  <input type="text" name="myword" size="20" value="$form{myword}">
342  </form>  <input type="submit" value="テアクク。コ">
343  </p>  </form>
344  EOD  </p>
345      &print_footer;  EOD
346  }      &print_footer;
347    }
348  # ページの一覧  
349  sub do_list {  # ・レ。シ・ク、ホーヘ
350      &print_header('ページ一覧');  sub do_list {
351      print qq|<h1>$IconTag ページ一覧</h1>\n|;      &print_header('・レ。シ・クーヘ');
352      &print_toolbar();      print qq|<h1>$IconTag ・レ。シ・クーヘ</h1>\n|;
353      print qq|<ul>\n|;      &print_toolbar();
354      foreach my $page_name (sort keys %database) {    # sortするのは無謀かな      print qq|<ul>\n|;
355          my $encoded = &encode_percent($page_name);      foreach my $page_name (sort keys %database) {    # sort、ケ、、ホ、マフオヒナ、ォ、ハ
356          print qq|<li><a href="$thisurl?mycmd=read&mypage=$encoded">$page_name</a>\n|          my $encoded = &encode_percent($page_name);
357      }          print qq|<li><a href="$thisurl?mycmd=read;mypage=$encoded">$page_name</a>\n|
358      print qq|</ul>\n|;      }
359      &print_footer;      print qq|</ul>\n|;
360  }      &print_footer;
361    }
362  # プレビュー  
363  sub do_preview {  # ・ラ・・モ・蝪シ
364      my $page_name = $form{mypage};  sub do_preview {
365      my $escapedmsg = &escape($form{mymsg});      my $page_name = $form{mypage};
366      &print_header($page_name);      my $escapedmsg = &escape($form{mymsg});
367      print qq|<h1>$IconTag${page_name}のプレビュー</h1>\n|;      &print_header($page_name);
368      &print_toolbar($page_name);      print qq|<h1>$IconTag${page_name}、ホ・ラ・・モ・蝪シ</h1>\n|;
369      # local $percent_name = &encode_percent($page_name);      &print_toolbar($page_name);
370      print qq|<p>以下のプレビューを確認して、よければページ下部のボタンで更新してください。</p>\n|;      # local $percent_name = &encode_percent($page_name);
371      if ($form{mymsg}) {      print qq|<p>ーハイシ、ホ・ラ・・モ・蝪シ、ウホヌァ、キ、ニ。「、隍ア、、ミ・レ。シ・クイシノ、ホ・ワ・ソ・、ヌケケソキ、キ、ニ、ッ、タ、オ、、。」</p>\n|;
372          print qq|<table width="100%" bgcolor="$preview_color" ><tr><td>\n|;      if ($form{mymsg}) {
373          # print &convert_html($escapedmsg);          print qq|<table width="100%" bgcolor="$preview_color" ><tr><td>\n|;
374          print &convert_html($form{mymsg});          # print &convert_html($escapedmsg);
375          print qq|</td></tr></table>\n|;          print &convert_html($form{mymsg});
376      } else {          print qq|</td></tr></table>\n|;
377          print qq|<p>(ページの内容は空です。更新するとこのページは<b>削除</b>されます。)</p>\n|;      } else {
378      }          print qq|<p>。ハ・レ。シ・ク、ホニ簣ニ、マカ、ヌ、ケ。」ケケソキ、ケ、、ネ、ウ、ホ・レ。シ・ク、マ<strong>コス</strong>、オ、、゙、ケ。」。ヒ</p>\n|;
379      &print_preview_buttons($page_name, $escapedmsg, $form{mydigest});      }
380      &print_footer;      &print_preview_buttons($page_name, $escapedmsg, $form{mydigest});
381  }      &print_footer;
382    }
383  sub print_preview_buttons {  
384      my ($page_name, $escapedmsg, $digest) = @_;  sub print_preview_buttons {
385      print <<"EOD";      my ($page_name, $escapedmsg, $digest) = @_;
386      <form action="$thisurl" method="post">      print <<"EOD";
387      <textarea cols="$cols" rows="$rows" name="mymsg" wrap="virtual">$escapedmsg</textarea>      <form action="$thisurl" method="post">
388      <br />      <textarea cols="$cols" rows="$rows" name="mymsg" wrap="virtual">$escapedmsg</textarea>
389      <input type="hidden" name="mypage" value="$page_name">      <br />
390      <input type="hidden" name="mydigest" value="$digest">      <input type="hidden" name="mypage" value="$page_name">
391      <input type="submit" name="myspecial_preview" value="再度プレビュー">      <input type="hidden" name="mydigest" value="$digest">
392      <input type="submit" name="myspecial_write" value="ページの更新">      <input type="submit" name="myspecial_preview" value="コニナル・ラ・・モ・蝪シ">
393      </form>      <input type="submit" name="myspecial_write" value="・レ。シ・ク、ホケケソキ">
394  EOD      </form>
395  }  EOD
396    }
397  # 書き込む  
398  sub do_write {  # ス、ュケ、
399      if (not &is_editable($form{mypage})) {  sub do_write {
400          # 編集不可ページは表示のみ      if (not &is_editable($form{mypage})) {
401          &do_read;          # ハヤスクノヤイト・レ。シ・ク、マノスシィ、ホ、゚
402          return;          &do_read;
403      }          return;
404        }
405      my $page_name = $form{mypage};  
406        my $page_name = $form{mypage};
407      # digestを使って、更新の衝突チェック  
408      my $original_digest = &calc_message_digest(&get_page($page_name));      # digest、サネ、テ、ニ。「ケケソキ、ホセラニヘ・チ・ァ・テ・ッ
409      if ($form{mydigest} ne $original_digest) {      my $original_digest = &calc_message_digest(&get_page($page_name));
410          &print_header($page_name);      if ($form{mydigest} ne $original_digest) {
411          print qq|<h1>$IconTag${page_name}で【更新の衝突】が起きました</h1>\n|;          &print_header($page_name);
412          print <<"EOD";          print qq|<h1>$IconTag${page_name}、ヌ。レケケソキ、ホセラニヘ。ロ、ャオッ、ュ、゙、キ、ソ</h1>\n|;
413  <p>あなたがこのページを編集している間に、          print <<"EOD";
414  他の人が同じページを更新してしまったようです。  <p>、「、ハ、ソ、ャ、ウ、ホ・レ。シ・ク、ハヤスク、キ、ニ、、、エヨ、ヒ。「
415  </p><p>  ツセ、ホソヘ、ャニア、ク・レ。シ・ク、ケケソキ、キ、ニ、キ、゙、テ、ソ、隍ヲ、ヌ、ケ。」
416  以下に、あなたの編集したテキストがありますので、  </p><p>
417  あなたの編集内容が失われないように、  ーハイシ、ヒ。「、「、ハ、ソ、ホハヤスク、キ、ソ・ニ・ュ・ケ・ネ、ャ、「、熙゙、ケ、ホ、ヌ。「
418  いますぐ、メモ帳などにコピー&ペーストしてください。  、「、ハ、ソ、ホハヤスクニ簣ニ、ャシコ、、、ハ、、、隍ヲ、ヒ。「
419  </p><p>  、、、゙、ケ、ー。「・皈籠「、ハ、ノ、ヒ・ウ・ヤ。シ。・レ。シ・ケ・ネ、キ、ニ、ッ、タ、オ、、。」
420  コピー&ペーストが済んでから、  </p><p>
421  最新の内容を見て再度編集し直してください。  ・ウ・ヤ。シ。・レ。シ・ケ・ネ、ャコム、、ヌ、ォ、鬘「
422  最新の内容は  コヌソキ、ホニ簣ニ、クォ、ニコニナルハヤスク、キトセ、キ、ニ、ッ、タ、オ、、。」
423  <a target="_blank" href="$thisurl?mycmd=read&mypage=$form{mypage}">$form{mypage}</a>  コヌソキ、ホニ簣ニ、マ
424  で見ることができます。  <a target="_blank" href="$thisurl?mycmd=read;mypage=$form{mypage}">$form{mypage}</a>
425  </p>  、ヌクォ、、ウ、ネ、ャ、ヌ、ュ、゙、ケ。」
426  EOD  </p>
427          # &print_toolbar($page_name);  EOD
428          &print_preview_buttons($page_name, &escape($form{mymsg}), $form{mydigest});          # &print_toolbar($page_name);
429          &print_footer;          &print_preview_buttons($page_name, &escape($form{mymsg}), $form{mydigest});
430          return;          &print_footer;
431      }          return;
432        }
433      # diff生成  
434      {      # diffタクタョ
435          &opendiff;      {
436          my @msg1 = split(/\n/, &get_page($page_name));          &opendiff;
437          my @msg2 = split(/\n/, $form{mymsg});          my @msg1 = split(/\n/, &get_page($page_name));
438          $msgrefA = \@msg1;          my @msg2 = split(/\n/, $form{mymsg});
439          $msgrefB = \@msg2;          $msgrefA = \@msg1;
440          &diff_check;          $msgrefB = \@msg2;
441          $diffbase{$form{mypage}} = $diff_text;          &diff_check;
442          $diff_text = '';          $diffbase{$form{mypage}} = $diff_text;
443          &closediff;          $diff_text = '';
444      }          &closediff;
445        }
446      &print_header($page_name);  
447      &set_page($page_name, $form{mymsg});      &print_header($page_name);
448      if ($form{mymsg}) {      &set_page($page_name, $form{mymsg});
449          print qq|<h1>$IconTag${page_name}を更新しました</h1>\n|;      if ($form{mymsg}) {
450          &print_toolbar($page_name);          print qq|<h1>$IconTag${page_name}、ケケソキ、キ、゙、キ、ソ</h1>\n|;
451          print &convert_html(&get_page($page_name));          &print_toolbar($page_name);
452      } else {          print &convert_html(&get_page($page_name));
453          print qq|<h1>$IconTag${page_name}を削除しました</h1>\n|;      } else {
454          &print_toolbar($page_name);          print qq|<h1>$IconTag${page_name}、コス、キ、゙、キ、ソ</h1>\n|;
455          print qq|<p>${page_name}を削除しました。</p>\n|;          &print_toolbar($page_name);
456      }          print qq|<p>${page_name}、コス、キ、゙、キ、ソ。」</p>\n|;
457      &print_footer;      }
458      # 更新されたのでタッチしておく。      &print_footer;
459      if ($touchfile) {      # ケケソキ、オ、、ソ、ホ、ヌ・ソ・テ・チ、キ、ニ、ェ、ッ。」
460          open(FILE, "> $touchfile");      if ($touchfile) {
461          print FILE "\n";          open(FILE, "> $touchfile");
462          close(FILE);          print FILE "\n";
463      }          close(FILE);
464  }      }
465    }
466  # ページの変更点  
467  sub do_diff {  # ・レ。シ・ク、ホハムケケナタ
468      if (not &is_editable($form{mypage})) {  sub do_diff {
469          # 編集不可ページは表示のみ      if (not &is_editable($form{mypage})) {
470          &do_read;          # ハヤスクノヤイト・レ。シ・ク、マノスシィ、ホ、゚
471          return;          &do_read;
472      }          return;
473      &opendiff;      }
474      &print_header($form{mypage} . 'の変更点');      &opendiff;
475      print qq|<h1>$IconTag <a href="$thisurl?mycmd=read&mypage=$form{mypage}">$form{mypage}</a>の変更点</h1>\n|;      &print_header($form{mypage} . '、ホハムケケナタ');
476      &print_toolbar();      print qq|<h1>$IconTag <a href="$thisurl?mycmd=read&mypage=$form{mypage}">$form{mypage}</a>、ホハムケケナタ</h1>\n|;
477      $_ = &escape($diffbase{$form{mypage}});      &print_toolbar();
478      print <<"EOD";      $_ = &escape($diffbase{$form{mypage}});
479  <ul>      print <<"EOD";
480  <li>追加された行は<font color="blue">青色</font>です。  <ul>
481  <li>削除された行は<font color="red">赤色</font>です。  <li>トノイテ、オ、、ソケヤ、マ<ins>タトソァ</ins>、ヌ、ケ。」
482  <li><a href="$thisurl?mycmd=read&mypage=$form{mypage}">$form{mypage}</a>へ行く。  <li>コス、オ、、ソケヤ、マ<del>タヨソァ</del>、ヌ、ケ。」
483  </ul>  <li><a href="$thisurl?mycmd=read;mypage=$form{mypage}">$form{mypage}</a>、リケヤ、ッ。」
484  <hr />  </ul>
485  EOD  <hr />
486      print qq|<pre>\n|;  EOD
487      foreach (split(/\n/, $_)) {      print qq|<pre>\n|;
488          if (/^\+(.*)/) {      foreach (split(/\n/, $_)) {
489              print qq|<font color="blue">$1</font>\n|;          if (/^\+(.*)/) {
490          } elsif (/^\-(.*)/) {              print qq|<ins>$1</ins>\n|;
491              print qq|<font color="red">$1</font>\n|;          } elsif (/^\-(.*)/) {
492          } elsif (/^\=(.*)/) {              print qq|<del>$1</del>\n|;
493              print qq|$1\n|;          } elsif (/^\=(.*)/) {
494          } else {              print qq|$1\n|;
495              print qq|??? $_\n|;          } else {
496          }              print qq|??? $_\n|;
497      }          }
498      print qq|</pre>\n|;      }
499      &print_footer;      print qq|</pre>\n|;
500      &closediff;      &print_footer;
501  }      &closediff;
502    }
503  sub opendiff {  
504      if ($dbmopen) {  sub opendiff {
505          if (!dbmopen(%diffbase, $diffdbname, 0666)) {      if ($dbmopen) {
506              &print_error("(dbmopen) $diffdbname が作れません。");          if (!dbmopen(%diffbase, $diffdbname, 0666)) {
507          }              &print_error("(dbmopen) $diffdbname 、ャコ、、゙、サ、。」");
508      } else {          }
509          if (!tie(%diffbase, "YukiWikiDB", $diffdbname)) {      } else {
510              &print_error("(tie error)");          if (!tie(%diffbase, "YukiWikiDB", $diffdbname)) {
511          }              &print_error("(tie error)");
512      }          }
513  }      }
514    }
515  sub closediff {  
516      if ($dbmopen) {  sub closediff {
517          dbmclose(%diffbase);      if ($dbmopen) {
518      } else {          dbmclose(%diffbase);
519          untie(%diffbase);      } else {
520      }          untie(%diffbase);
521  }      }
522    }
523  # フォームからの情報を連想配列 %form に入れる  
524  # &init_form('euc');  # ・ユ・ゥ。シ・爨ォ、鬢ホセハ、マ「チロヌロホ %form 、ヒニ、、
525  sub init_form {  # &init_form('euc');
526      my ($charcode) = @_;  sub init_form {
527      my $query;      my ($charcode) = @_;
528      if ($ENV{REQUEST_METHOD} =~ /^post$/i) {      my $query;
529          read(STDIN, $query, $ENV{CONTENT_LENGTH});      if ($ENV{REQUEST_METHOD} =~ /^post$/i) {
530      } else {          read(STDIN, $query, $ENV{CONTENT_LENGTH});
531          $query = $ENV{QUERY_STRING};      } else {
532      }          $query = $ENV{QUERY_STRING};
533      my @assocarray = split(/&/, $query);      }
534      foreach my $assoc (@assocarray) {      my @assocarray = split(/[&;]/, $query);
535          my ($property, $value) = split(/=/, $assoc);      foreach my $assoc (@assocarray) {
536          $value =~ tr/+/ /;          my ($property, $value) = split(/=/, $assoc);
537          $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;          $value =~ tr/+/ /;
538          &jcode::convert(\$value, $charcode);          $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;
539          $form{$property} = $value;          &jcode::convert(\$value, $charcode);
540      }          $form{$property} = $value;
541  }      }
542    }
543  # エラーページを出力する  
544  sub print_error {  # ・ィ・鬘シ・レ。シ・ク、スミホマ、ケ、
545      my ($msg) = @_;  sub print_error {
546      &print_header('Error');      my ($msg) = @_;
547      print "<h1>$IconTag$msg</h1></body></html>";      &print_header('Error');
548      exit(0);      print "<h1>$IconTag$msg</h1></body></html>";
549  }      exit(0);
550    }
551  sub escape {  
552      my ($line) = shift;  sub escape {
553      $line =~ s|<|&lt;|g;      my ($line) = shift;
554      $line =~ s|>|&gt;|g;      $line =~ s|<|&lt;|g;
555      $line =~ s|"|&quot;|g;      $line =~ s|>|&gt;|g;
556      # $line =~ s|\&|&amp;|g;      $line =~ s|"|&quot;|g;
557      return $line;      # $line =~ s|\&|&amp;|g;
558  }      return $line;
559    }
560  sub inline {  
561      my ($line) = shift;  sub inline {
562      $line = &escape($line);      my ($line) = shift;
563      $line =~ s|'''([^']+?)'''|<i>$1</i>|g;              # Italic      $line = &escape($line);
564      $line =~ s|''([^']+?)''|<b>$1</b>|g;                # Bold      $line =~ s|'''([^']+?)'''|<strong>$1</strong>|g;
565      $line =~ s!      $line =~ s|''([^']+?)''|<em>$1</em>|g;          
566                  (      $line =~ s!
567                      ((mailto|http|https|ftp):[\x21-\x7E]*) # Direct http://...                  (
568                          |                      ((mailto|http|https|ftp):[\x21-\x7E]*) # Direct http://...
569                      ($WikiName)                         # LocalLinkLikeThis                          |
570                          |                      ($WikiName)                         # LocalLinkLikeThis
571                      ($BracketName)                      # [[日本語リンク]]                          |
572                  )                      ($BracketName)                      # [[ニヒワク・・・ッ]]
573              !                  )
574                  &make_link($1)              !
575              !gex;                  &make_link($1)
576      return $line;              !gex;
577  }      return $line;
578    }
579  # ページのタイトルからページの内容を得る  
580  sub get_page {  # ・レ。シ・ク、ホ・ソ・、・ネ・、ォ、鬣レ。シ・ク、ホニ簣ニ、ニタ、
581      my $page_name = shift;  sub get_page {
582      return $database{$page_name};      my $page_name = shift;
583  }      return $database{$page_name};
584    }
585  # ページの内容を与える  
586  # &set_page($title, $txt)  # ・レ。シ・ク、ホニ簣ニ、ヘソ、ィ、
587  sub set_page {  # &set_page($title, $txt)
588      # ページを更新する  sub set_page {
589      my $title = $_[0];      # ・レ。シ・ク、ケケソキ、ケ、
590      $database{$title} = $_[1];      my $title = $_[0];
591      # 空ページなら削除する      $database{$title} = $_[1];
592      unless ($database{$title}) {      # カ・レ。シ・ク、ハ、鮗ス、ケ、
593          delete $database{$title};      unless ($database{$title}) {
594      }          delete $database{$title};
595      # RecentChangesを更新する      }
596      my $delim = ' - ';      # RecentChanges、ケケソキ、ケ、
597      my @pages = split(/\n/, $database{$whatsnew});      my $delim = ' - ';
598      my $datestr = &get_current_datestr;      my @pages = split(/\n/, $database{$whatsnew});
599      unshift(@pages, qq|-$datestr$delim$title|);      my $datestr = &get_current_datestr;
600      # 同一ページの更新は最新のもののみにし、      unshift(@pages, qq|-$datestr$delim$title|);
601      # 存在しないページはスキップする。      # ニアー・レ。シ・ク、ホケケソキ、マコヌソキ、ホ、筅ホ、ホ、゚、ヒ、キ。「
602      my %count;      # ツクコ゚、キ、ハ、、・レ。シ・ク、マ・ケ・ュ・テ・ラ、ケ、。」
603      my @newpages;      my %count;
604      foreach my $line (@pages) {      my @newpages;
605          my ($prefix, $title) = split(/$delim/, $line);      foreach my $line (@pages) {
606          $count{$title}++;          my ($prefix, $title) = split(/$delim/, $line);
607          if ($count{$title} == 1 and exists($database{$title})) {          $count{$title}++;
608              push(@newpages, qq|$prefix - $title|);          if ($count{$title} == 1 and exists($database{$title})) {
609          }              push(@newpages, qq|$prefix - $title|);
610      }          }
611      # ここで本当に更新      }
612      $database{$whatsnew} = join("\n", splice(@newpages, 0, $maxnew));      # 、ウ、ウ、ヌヒワナ、ヒケケソキ
613  }      $database{$whatsnew} = join("\n", splice(@newpages, 0, $maxnew));
614    }
615  # ページのヘッダを出力  
616  sub print_header {  # ・レ。シ・ク、ホ・リ・テ・タ、スミホマ
617      my $title = shift;  sub print_header {
618      print <<"EOD";      my $title = shift;
619  Content-type: text/html      print <<"EOD";
620    Content-type: text/html
621  <html><head>  
622  <title>$title</title>  <html><head>
623  <style type="text/css">  <title>$title</title>
624  <!--  <style type="text/css">
625  $style  $style
626  -->  </style>
627  </style>  </head>
628  </head>  <body>
629  <body bgcolor="white">  EOD
630  EOD  }
631  }  
632    # ・ト。シ・・ミ。シ、スミホマ
633  # ツールバーを出力  sub print_toolbar {
634  sub print_toolbar {      my $page_name = shift;
635      my $page_name = shift;      my $percent_name = &encode_percent($page_name);
636      my $percent_name = &encode_percent($page_name);      my $editlink = '';
637      my $editlink = '';      if ($page_name ne '' and &is_editable($page_name)) {
638      if ($page_name ne '' and &is_editable($page_name)) {          $editlink = <<"EOD";
639          $editlink = <<"EOD";  <a href="$thisurl?mycmd=edit;mypage=$percent_name">ハヤスク</a> |
640  <a href="$thisurl?mycmd=edit&mypage=$percent_name">編集</a> |  <a href="$thisurl?mycmd=diff;mypage=$percent_name">コケハャ</a> |
641  <a href="$thisurl?mycmd=diff&mypage=$percent_name">差分</a> |  EOD
642  EOD      }
643      }      print <<"EOD";
644      print <<"EOD";  <p>
645  <p>   [
646   [  <a href="$thisurl?mycmd=read;mypage=$toppage">・ネ・テ・ラ</a> |
647  <a href="$thisurl?mycmd=read&mypage=$toppage">トップ</a> |  <a href="$thisurl?mycmd=list">ーヘ</a> |
648  <a href="$thisurl?mycmd=list">一覧</a> |  $editlink
649  $editlink  <a href="$thisurl?mycmd=search">テアクク。コ</a> |
650  <a href="$thisurl?mycmd=search">単語検索</a> |  <a href="$thisurl?mycmd=read;mypage=$whatsnew">コヌスェケケソキ</a>
651  <a href="$thisurl?mycmd=read&mypage=$whatsnew">最終更新</a>   ]
652   ]  </p>
653  </p>  EOD
654  EOD  }
655  }  
656    # ・レ。シ・ク、ホ・ユ・テ・ソ、スミホマ
657  # ページのフッタを出力  sub print_footer {
658  sub print_footer {      print <<"EOD";
659      print <<"EOD";  <address>
660  <hr>  <a href="http://www.hyuki.com/yukiwiki/">YukiWiki</a> 1.6.6 Copyright (C) 2000,2001 by <a href="http://www.hyuki.com/">Hiroshi Yuki.</a>
661  <p>  + <a href="$modifierlink">$modifier</a> ${version}.
662  <a href="http://www.hyuki.com/yukiwiki/">YukiWiki</a> $version Copyright (C) 2000,2001 by <a href="http://www.hyuki.com/">Hiroshi Yuki.</a><br />  [<a href="/" title="、ウ、ホ・オ。シ・ミ。シ、ホシハヌ">/</a>
663  Modified by <a href="$modifierlink">$modifier</a>.<br/>  <a href="/map" title="、ウ、ホ・オ。シ・ミ。シ、ホーニニ">テマゾ</a>
664  </p>  <a href="/search/" title="、ウ、ホ・オ。シ・ミ。シ、ホク。コ">ク。コ</a>]
665  </body></html>  </address>
666  EOD  </body></html>
667  }  EOD
668    }
669  # URLやページの名前からリンクを作る  
670  sub make_link {  # URL、茹レ。シ・ク、ホフセチー、ォ、鬣・・ッ、コ、
671      my $name = shift;  sub make_link {
672      if ($name =~ /^(http|https|ftp).*?(\.gif|\.png|\.jpeg|\.jpg)?$/) {      my $name = shift;
673          if ($2) {      if ($name =~ /^(http|https|ftp).*?(\.gif|\.png|\.jpeg|\.jpg)?$/) {
674              return qq|<a href="$name"><img border="0" src="$name" /></a>|;          if ($2) {
675          } else {              return qq|<a href="$name"><img border="0" src="$name" /></a>|;
676              return qq|<a href="$name">$name</a>|;          } else {
677          }              return qq|<a href="$name">$name</a>|;
678      } elsif ($name =~ /^mailto:(.*)/) {          }
679          my $address = $1;      } elsif ($name =~ /^mailto:(.*)/) {
680          return qq|<a href="$name">$address</a>|;          my $address = $1;
681      } elsif ($database{$name}) {          return qq|<a href="$name">$address</a>|;
682          my $percent_name = &encode_percent($name);      } elsif ($database{$name}) {
683          return qq|<a href="$thisurl?mycmd=read&mypage=$percent_name">$name</a>|;          my $percent_name = &encode_percent($name);
684      } else {          return qq|<a href="$thisurl?mycmd=read;mypage=$percent_name">$name</a>|;
685          my $percent_name = &encode_percent($name);      } else {
686          return qq|$name<a href="$thisurl?mycmd=edit&mypage=$percent_name">?</a>|;          my $percent_name = &encode_percent($name);
687      }          return qq|$name<a href="$thisurl?mycmd=edit;mypage=$percent_name">?</a>|;
688  }      }
689    }
690  # %xx の形式にエンコードする  
691  # これは、  # %xx 、ホキチシー、ヒ・ィ・・ウ。シ・ノ、ケ、
692  # http://www.hyuki.com/yukiwiki/yukiwiki.cgi?mycmd=read&mypage=%3C%8C%8B%8F%E9%8D_%3E  # 、ウ、、マ。「
693  # という形式のために使われる。  # http://www.hyuki.com/yukiwiki/yukiwiki.cgi?mycmd=read&mypage=%3C%8C%8B%8F%E9%8D_%3E
694  # '<結城浩>' → '%3C%8C%8B%8F%E9%8D_%3E'  # 、ネ、、、ヲキチシー、ホ、ソ、皃ヒサネ、、、。」
695  sub encode_percent {  # '<キセケタ>' 「ェ '%3C%8C%8B%8F%E9%8D_%3E'
696      my $name = shift;  sub encode_percent {
697      my $encoded = '';      my $name = shift;
698      foreach my $ch (split(//, $name)) {      my $encoded = '';
699          if ($ch =~ /[A-Za-z0-9_]/) {      foreach my $ch (split(//, $name)) {
700              $encoded .= $ch;          if ($ch =~ /[A-Za-z0-9_]/) {
701          } else {              $encoded .= $ch;
702              $encoded .= '%' . sprintf("%02X", ord($ch));          } else {
703          }              $encoded .= '%' . sprintf("%02X", ord($ch));
704      }          }
705      return $encoded;      }
706  }      return $encoded;
707    }
708  # テキスト本体をHTMLに変換する  
709  sub convert_html {  # ・ニ・ュ・ケ・ネヒワツホ、HTML、ヒハムエケ、ケ、
710      my ($txt) = shift;  sub convert_html {
711      my (@txt) = split(/\n/, $txt);      my ($txt) = shift;
712      foreach (@txt) {      my (@txt) = split(/\n/, $txt);
713          chomp;      foreach (@txt) {
714          if (/^\*\*(.*)/) {          chomp;
715              push(@result, splice(@saved), '<h3>' . &inline($1) . '</h3>');          if (/^\*\*(.*)/) {
716          } elsif (/^\*(.*)/) {              push(@result, splice(@saved), '<h3>' . &inline($1) . '</h3>');
717              push(@result, splice(@saved), '<h2>' . &inline($1) . '</h2>');          } elsif (/^\*(.*)/) {
718          } elsif (/^----/) {              push(@result, splice(@saved), '<h2>' . &inline($1) . '</h2>');
719              push(@result, splice(@saved), '<hr>');          } elsif (/^----/) {
720          } elsif (/^(-{1,3})(.*)/) {              push(@result, splice(@saved), '<hr>');
721              &back_push('ul', length($1));          } elsif (/^(-{1,3})(.*)/) {
722              push(@result, '<li>' . &inline($2) . '</li>');              &back_push('ul', length($1));
723          } elsif (/^:([^:]+):(.*)/) {              push(@result, '<li>' . &inline($2) . '</li>');
724              &back_push('dl', 1);          } elsif (/^:([^:]+):(.*)/) {
725              push(@result, '<dt>' . &inline($1) . '</dt>', '<dd>' . &inline($2) . '</dd>');              &back_push('dl', 1);
726          } elsif (/^(>{1,3})(.*)/) {              push(@result, '<dt>' . &inline($1) . '</dt>', '<dd>' . &inline($2) . '</dd>');
727              &back_push('blockquote', length($1));          } elsif (/^(>{1,3})(.*)/) {
728              push(@result, &inline($2));              &back_push('blockquote', length($1));
729          } elsif (/^\s*$/) {              push(@result, &inline($2));
730              push(@result, splice(@saved));          } elsif (/^\s*$/) {
731              unshift(@saved, "</p>");              push(@result, splice(@saved));
732              push(@result, "<p>");              unshift(@saved, "</p>");
733          } elsif (/^(\s+.*)$/) {              push(@result, "<p>");
734              &back_push('pre', 1);          } elsif (/^(\s+.*)$/) {
735              push(@result, &escape($1)); # Not &inline, but &escape              &back_push('pre', 1);
736          } else {              push(@result, &escape($1)); # Not &inline, but &escape
737              push(@result, &inline($_));          } else {
738          }              push(@result, &inline($_));
739      }          }
740      push(@result, splice(@saved));      }
741      return join("\n", @result);      push(@result, splice(@saved));
742  }      return join("\n", @result);
743    }
744  # &back_push($tag, $count)  
745  # $tagのタグを$levelレベルまで詰める。  # &back_push($tag, $count)
746  sub back_push {  # $tag、ホ・ソ・ー、$level・・ル・、゙、ヌオヘ、皃。」
747      my ($tag, $level) = @_;  sub back_push {
748      while (@saved > $level) {      my ($tag, $level) = @_;
749          push(@result, shift(@saved));      while (@saved > $level) {
750      }          push(@result, shift(@saved));
751      if ($saved[0] ne "</$tag>") {      }
752          push(@result, splice(@saved));      if ($saved[0] ne "</$tag>") {
753      }          push(@result, splice(@saved));
754      while (@saved < $level) {      }
755          unshift(@saved, "</$tag>");      while (@saved < $level) {
756          push(@result, "<$tag>");          unshift(@saved, "</$tag>");
757      }          push(@result, "<$tag>");
758  }      }
759    }
760  # 編集可能ページか?  
761  sub is_editable {  # ハヤスクイトヌス・レ。シ・ク、ォ。ゥ
762      my ($pagename) = @_;  sub is_editable {
763      foreach (@uneditable) {      my ($pagename) = @_;
764          if ($pagename eq $_) {      foreach (@uneditable) {
765              return 0;          if ($pagename eq $_) {
766          }              return 0;
767      }          }
768      if (&is_valid_name($pagename)) {      }
769          return 1;      if (&is_valid_name($pagename)) {
770      }          return 1;
771      return 0;      }
772  }      return 0;
773    }
774  # Validな名前か?  
775  sub is_valid_name {  # Valid、ハフセチー、ォ。ゥ
776      my ($pagename) = @_;  sub is_valid_name {
777      if ($pagename =~ /^$WikiName$/) {      my ($pagename) = @_;
778          return 1;      if ($pagename =~ /^$WikiName$/) {
779      } elsif ($pagename =~ /^$BracketName$/) {          return 1;
780          return 1;      } elsif ($pagename =~ /^$BracketName$/) {
781      } else {          return 1;
782          return 0;      } else {
783      }          return 0;
784  }      }
785    }
786  # 現在時刻の文字列を得る  
787  sub get_current_datestr {  # クスコ゚サケ、ホハクサホ、ニタ、
788      my (@wdays) = ( "日", "月", "火", "水", "木", "金", "土" );  sub get_current_datestr {
789      my ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time);      my (@wdays) = ( "ニ", "キ", "イミ", "ソ", "フレ", "カ", "ナレ" );
790      return sprintf("%4d-%02d-%02d (%s) %02d:%02d:%02d",      my ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time);
791          $year + 1900, $mon + 1, $mday, $wdays[$wday], $hour, $min, $sec);      return sprintf("%4d-%02d-%02d (%s) %02d:%02d:%02d",
792  }          $year + 1900, $mon + 1, $mday, $wdays[$wday], $hour, $min, $sec);
793    }
794  # URL?SomePageや、  
795  # URL?[[結城浩]]の形式だった場合、(not yet)  # URL?SomePage、茖「
796  # 強制的にmycmdをreadにして$formの内容を設定する。  # URL?[[キセケタ]]、ホキチシー、タ、テ、ソセケ遑「(not yet)
797  sub normalize_form {  # カッタゥナェ、ヒmycmd、read、ヒ、キ、ニ$form、ホニ簣ニ、タ゚ト熙ケ、。」
798      foreach my $key (keys %form) {  sub normalize_form {
799          if ($key =~ /^$WikiName$/) {      foreach my $key (keys %form) {
800              $form{mycmd} = 'read';          if ($key =~ /^$WikiName$/) {
801              $form{mypage} = $1;              $form{mycmd} = 'read';
802              last;              $form{mypage} = $1;
803          } elsif ($key =~ /^$BracketName$/) {              last;
804              $form{mycmd} = 'read';          } elsif ($key =~ /^$BracketName$/) {
805              $form{mypage} = $1;              $form{mycmd} = 'read';
806              last;              $form{mypage} = $1;
807          }              last;
808      }          }
809  }      }
810    }
811  # 変換テストを行なうときのサンプル  
812  sub print_sample {  # ハムエケ・ニ・ケ・ネ、ケヤ、ハ、ヲ、ネ、ュ、ホ・オ・・ラ・
813      my $txt = &convert_html(<<"EOD");  sub print_sample {
814  *大見出し1      my $txt = &convert_html(<<"EOD");
815  **小見出し1-1  *ツ邵ォスミ、キ1
816  -項目1  **セョクォスミ、キ1-1
817  -項目2  -ケ猯ワ1
818  -項目3  -ケ猯ワ2
819  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  -ケ猯ワ3
820  段落1段落1段落1段落1段落1段落''強調''1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
821  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ''カットエ''1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
822    テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
823  段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  
824  段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
825  段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
826  **小見出し1-2  テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
827  :用語1:いろいろ書いた解説文1と''強調単語''  **セョクォスミ、キ1-2
828  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  :ヘムク1:、、、、、、ス、、、ソイタ簗ク1、ネ''カットエテアク''
829  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
830  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
831  :用語2:いろいろ書いた解説文2  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
832  :用語3:いろいろ書いた解説文3  :ヘムク2:、、、、、、ス、、、ソイタ簗ク2
833  ----  :ヘムク3:、、、、、、ス、、、ソイタ簗ク3
834  *大見出し2  ----
835  **小見出し2-1  *ツ邵ォスミ、キ2
836  http://www.hyuki.com/  **セョクォスミ、キ2-1
837  **小見出し2-2  http://www.hyuki.com/
838    **セョクォスミ、キ2-2
839  [[結城浩]]  
840    [[キセケタ]]
841  段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1段落1  
842  段落1段落1段落1段落'''イタリック'''1段落1段落1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
843  段落1段落1段落1段落'''''イタボールド'''''1段落1段落1段落1段落1段落1段落1段落1段落1  テハヘ1テハヘ1テハヘ1テハヘ'''カットエ'''1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
844  >段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  テハヘ1テハヘ1テハヘ1テハヘ'''''カッ、、カットエ'''''1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1テハヘ1
845  >段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  >テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
846  >段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2段落2  >テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
847    >テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2テハヘ2
848  レベル0レベル0レベル0レベル0レベル0レベル0  
849    ・・ル・0・・ル・0・・ル・0・・ル・0・・ル・0・・ル・0
850  >レベル1  
851  >レベル1  >・・ル・1
852  >レベル1  >・・ル・1
853  >>レベル2  >・・ル・1
854  >>レベル2  >>・・ル・2
855  >>レベル2  >>・・ル・2
856  >>>レベル3  >>・・ル・2
857  -はろ1  >>>・・ル・3
858  --はろ2  -、マ、1
859  ろろろろ2  --、マ、2
860  ---はろ3  、、、、2
861  --はろ2  ---、マ、3
862  ---はろ3  --、マ、2
863  --はろ2  ---、マ、3
864  ---はろ3  --、マ、2
865  >>>レベル3  ---、マ、3
866  >>>レベル3  >>>・・ル・3
867  >>>レベル3  >>>・・ル・3
868  EOD  >>>・・ル・3
869      print $txt;  EOD
870      exit;      print $txt;
871  }      exit;
872    }
873  sub diff_check {  
874      traverse_sequences(  sub diff_check {
875              $msgrefA, $msgrefB,      traverse_sequences(
876              {              $msgrefA, $msgrefB,
877                  MATCH => \&df_match,              {
878                  DISCARD_A => \&df_delete,                  MATCH => \&df_match,
879                  DISCARD_B => \&df_add,                  DISCARD_A => \&df_delete,
880              }                  DISCARD_B => \&df_add,
881      );              }
882      &diff_flush;      );
883  }      &diff_flush;
884    }
885  sub diff_flush {  
886      $diff_text .= join('', map { "-$_\n" } splice(@diff_deleted));  sub diff_flush {
887      $diff_text .= join('', map { "+$_\n" } splice(@diff_added));      $diff_text .= join('', map { "-$_\n" } splice(@diff_deleted));
888  }      $diff_text .= join('', map { "+$_\n" } splice(@diff_added));
889    }
890  sub df_match {  
891      my ($a, $b) = @_;  sub df_match {
892      &diff_flush;      my ($a, $b) = @_;
893      $diff_text .= "=$msgrefA->[$a]\n";      &diff_flush;
894  }      $diff_text .= "=$msgrefA->[$a]\n";
895    }
896  sub df_delete {  
897      my ($a, $b) = @_;  sub df_delete {
898      push(@diff_deleted, $msgrefA->[$a]);      my ($a, $b) = @_;
899  }      push(@diff_deleted, $msgrefA->[$a]);
900    }
901  sub df_add {  
902      my ($a, $b) = @_;  sub df_add {
903      push(@diff_added, $msgrefB->[$b]);      my ($a, $b) = @_;
904  }      push(@diff_added, $msgrefB->[$b]);
905    }
906  sub calc_message_digest {   # You have to use MD5...  
907      my $text = shift;  sub calc_message_digest {   # You have to use MD5...
908      my @text = split(//, $text);      my $text = shift;
909      my $len = length($text);      my @text = split(//, $text);
910      my $checksum = 0;      my $len = length($text);
911      foreach (@text) {      my $checksum = 0;
912          $checksum += ord($_);      foreach (@text) {
913          $checksum = ($checksum * 2) % 65536 + (($checksum & 32768) ? 1 : 0); # 16bit rotate          $checksum += ord($_);
914      }          $checksum = ($checksum * 2) % 65536 + (($checksum & 32768) ? 1 : 0); # 16bit rotate
915      return "$len:$checksum";      }
916  }      return "$len:$checksum";
917    }
918  # Definition of YukiWikiDB  
919  package YukiWikiDB;  # Definition of YukiWikiDB
920    package YukiWikiDB;
921  my $debug = 1;  
922    my $debug = 1;
923  # Constructor  
924  sub new {  # Constructor
925      return shift->TIEHASH(@_);  sub new {
926  }      return shift->TIEHASH(@_);
927    }
928  # tying  
929  sub TIEHASH {  # tying
930      my ($class, $dbname) = @_;  sub TIEHASH {
931      my $self = {      my ($class, $dbname) = @_;
932          dir => $dbname,      my $self = {
933          keys => [],          dir => $dbname,
934      };          keys => [],
935      if (not -d $self->{dir}) {      };
936          if (!mkdir($self->{dir}, 0777)) {      if (not -d $self->{dir}) {
937              print "mkdir(" . $self->{dir} . ") fail\n" if ($debug);          if (!mkdir($self->{dir}, 0777)) {
938              return undef;              print "mkdir(" . $self->{dir} . ") fail\n" if ($debug);
939          }              return undef;
940      }          }
941      return bless($self, $class);      }
942  }      return bless($self, $class);
943    }
944  # Store  
945  sub STORE {  # Store
946      my ($self, $key, $val) = @_;  sub STORE {
947      my $file = &make_filename($self, $key);      my ($self, $key, $val) = @_;
948      if (open(FILE,"> $file")) {      my $file = &make_filename($self, $key);
949          binmode(FILE);      if (open(FILE,"> $file")) {
950          print FILE $val;          binmode(FILE);
951          close(FILE);          print FILE $val;
952          return $self->{$key} = $val;          close(FILE);
953      } else {          return $self->{$key} = $val;
954          print "$file create error.";      } else {
955      }          print "$file create error.";
956  }      }
957    }
958  # Fetch  
959  sub FETCH {  # Fetch
960      my ($self, $key) = @_;  sub FETCH {
961      my $file = &make_filename($self, $key);      my ($self, $key) = @_;
962      if (open(FILE, $file)) {      my $file = &make_filename($self, $key);
963          local $/;      if (open(FILE, $file)) {
964          $self->{$key} = <FILE>;          local $/;
965          close(FILE);          $self->{$key} = <FILE>;
966      }          close(FILE);
967      return $self->{$key};      }
968  }      return $self->{$key};
969    }
970  # Exists  
971  sub EXISTS {  # Exists
972      my ($self, $key) = @_;  sub EXISTS {
973      my $file = &make_filename($self, $key);      my ($self, $key) = @_;
974      return -e($file);      my $file = &make_filename($self, $key);
975  }      return -e($file);
976    }
977  # Delete  
978  sub DELETE {  # Delete
979      my ($self, $key) = @_;  sub DELETE {
980      my $file = &make_filename($self, $key);      my ($self, $key) = @_;
981      unlink $file;      my $file = &make_filename($self, $key);
982      return delete $self->{$key};      unlink $file;
983  }      return delete $self->{$key};
984    }
985  sub FIRSTKEY {  
986      my ($self) = @_;  sub FIRSTKEY {
987      opendir(DIR, $self->{dir}) or die $self->{dir};      my ($self) = @_;
988      @{$self->{keys}} = grep /\.txt$/, readdir(DIR);      opendir(DIR, $self->{dir}) or die $self->{dir};
989      foreach my $name (@{$self->{keys}}) {      @{$self->{keys}} = grep /\.txt$/, readdir(DIR);
990          $name =~ s/\.txt$//;      foreach my $name (@{$self->{keys}}) {
991          $name =~ s/[0-9A-F][0-9A-F]/pack("C", hex($&))/eg;          $name =~ s/\.txt$//;
992      }          $name =~ s/[0-9A-F][0-9A-F]/pack("C", hex($&))/eg;
993      return shift @{$self->{keys}};      }
994  }      return shift @{$self->{keys}};
995    }
996  sub NEXTKEY {  
997      my ($self) = @_;  sub NEXTKEY {
998      return shift @{$self->{keys}};      my ($self) = @_;
999  }      return shift @{$self->{keys}};
1000    }
1001  sub make_filename {  
1002      my ($self, $key) = @_;  sub make_filename {
1003      my $enkey = '';      my ($self, $key) = @_;
1004      foreach my $ch (split(//, $key)) {      my $enkey = '';
1005          $enkey .= sprintf("%02X", ord($ch));      foreach my $ch (split(//, $key)) {
1006      }          $enkey .= sprintf("%02X", ord($ch));
1007      return $self->{dir} . "/$enkey.txt";      }
1008  }      return $self->{dir} . "/$enkey.txt";
1009  __END__  }
1010    __END__
1011  =head1 NAME  
1012    =head1 NAME
1013  YukiWiki - 自由にページを追加・削除・編集できるWebページ構築CGI  
1014    YukiWiki - シォヘウ、ヒ・レ。シ・ク、トノイテ。ヲコス。ヲハヤスク、ヌ、ュ、Web・レ。シ・クケステロCGI
1015      Copyright (C) 2000,2001 by Hiroshi Yuki.  
1016      結城浩 <hyuki@hyuki.com>      Copyright (C) 2000,2001 by Hiroshi Yuki.
1017      http://www.hyuki.com/      キセケタ <hyuki@hyuki.com>
1018      http://www.hyuki.com/yukiwiki/      http://www.hyuki.com/
1019        http://www.hyuki.com/yukiwiki/
1020  =head1 SYNOPSIS  
1021    =head1 SYNOPSIS
1022      http://www.hyuki.com/yukiwiki/yukiwiki.cgi  
1023        http://www.hyuki.com/yukiwiki/yukiwiki.cgi
1024  =head1 DESCRIPTION  
1025    =head1 DESCRIPTION
1026  YukiWiki(結城ウィキィ)は参加者が自由にページを追加・削除・編集できる  
1027  不思議なWebページ群を作るCGIです。  YukiWiki。ハキセ・ヲ・」・ュ・」。ヒ、マサイイテシヤ、ャシォヘウ、ヒ・レ。シ・ク、トノイテ。ヲコス。ヲハヤスク、ヌ、ュ、
1028  Webで動作する掲示板とちょっと似ていますが、  ノヤサラオト、ハWeb・レ。シ・クキイ、コ、CGI、ヌ、ケ。」
1029  Web掲示板が単にメッセージを追加するだけなのに対して、  Web、ヌニーコ、ケ、キヌシィネト、ネ、チ、遉テ、ネサ、ニ、、、゙、ケ、ャ。「
1030  YukiWikiは、Webページ全体を自由に変更することができます。  Webキヌシィネト、ャテア、ヒ・皈テ・サ。シ・ク、トノイテ、ケ、、タ、ア、ハ、ホ、ヒツミ、キ、ニ。「
1031    YukiWiki、マ。「Web・レ。シ・クチエツホ、シォヘウ、ヒハムケケ、ケ、、ウ、ネ、ャ、ヌ、ュ、゙、ケ。」
1032  YukiWikiは、Cunningham & CunninghamのWikiWikiWebの  
1033  仕様を参考にして独自に作られました。  YukiWiki、マ。「Cunningham & Cunningham、ホWikiWikiWeb、ホ
1034    サナヘヘ、サイケヘ、ヒ、キ、ニニネシォ、ヒコ、鬢、゙、キ、ソ。」
1035  YukiWikiはPerlで書かれたCGIスクリプトとして実現されていますので、  
1036  Perlが動作するWebサーバならば比較的容易に設置できます。  YukiWiki、マPerl、ヌス、ォ、、ソCGI・ケ・ッ・・ラ・ネ、ネ、キ、ニシツクス、オ、、ニ、、、゙、ケ、ホ、ヌ。「
1037    Perl、ャニーコ、ケ、Web・オ。シ・ミ、ハ、鬢ミネ豕モナェヘニーラ、ヒタ゚テヨ、ヌ、ュ、゙、ケ。」
1038  あとはdbmopenが使える環境ならば設置できます(Version 1.5.0以降ならdbmopenが使えなくても設置できます)。  
1039    、「、ネ、マdbmopen、ャサネ、ィ、エトカュ、ハ、鬢ミタ゚テヨ、ヌ、ュ、゙、ケ(Version 1.5.0ーハケ゚、ハ、馘bmopen、ャサネ、ィ、ハ、ッ、ニ、簑゚テヨ、ヌ、ュ、゙、ケ)。」
1040    
1041  YukiWikiはフリーソフトです。  
1042  ご自由にお使いください。  YukiWiki、マ・ユ・遙シ・ス・ユ・ネ、ヌ、ケ。」
1043    、エシォヘウ、ヒ、ェサネ、、、ッ、タ、オ、、。」
1044  =head1 設置方法  
1045    =head1 タ゚テヨハヒ。
1046  =head2 入手  
1047    =head2 ニシ
1048  YukiWikiの最新版は、  
1049  http://www.hyuki.com/yukiwiki/  YukiWiki、ホコヌソキネヌ、マ。「
1050  から入手できます。  http://www.hyuki.com/yukiwiki/
1051    、ォ、鯣シ熙ヌ、ュ、゙、ケ。」
1052  =head2 ファイル一覧  
1053    =head2 ・ユ・。・、・ーヘ
1054      readme.txt      ドキュメント  
1055      yukiwiki.cgi    YukiWiki本体      readme.txt      ・ノ・ュ・螂皈・ネ
1056      yukiwiki.gif    ロゴ(カラー版)      yukiwiki.cgi    YukiWikiヒワツホ
1057      yukimono.gif    ロゴ(モノクロ版)      yukiwiki.gif    ・・エ。ハ・ォ・鬘シネヌ。ヒ
1058      jcode.pl        漢字コードライブラリ      yukimono.gif    ・・エ。ハ・筵ホ・ッ・ネヌ。ヒ
1059        jcode.pl        エチサ・ウ。シ・ノ・鬣、・ヨ・鬣
1060  =head2 インストール  
1061    =head2 ・、・・ケ・ネ。シ・
1062  =over 4  
1063    =over 4
1064  =item 1.  
1065    =item 1.
1066  アーカイブを解く。  
1067    ・「。シ・ォ・、・ヨ、イ、ッ。」
1068  =item 2.  
1069    =item 2.
1070  yukiwiki.cgiのはじめの方にある設定を確認します。  
1071  通常は何もしなくてよいが、  yukiwiki.cgi、ホ、マ、ク、皃ホハ、ヒ、「、タ゚ト熙ウホヌァ、キ、゙、ケ。」
1072  はじめは$touchfileを''にした方がよいでしょう。  トフセ、マイソ、筅キ、ハ、ッ、ニ、隍、、ャ。「
1073    、マ、ク、皃マ$touchfile、''、ヒ、キ、ソハ、ャ、隍、、ヌ、キ、遉ヲ。」
1074  =item 3.  
1075    =item 3.
1076  yukiwiki.cgiとjcode.plを同じところに設置します。  
1077    yukiwiki.cgi、ネjcode.pl、ニア、ク、ネ、ウ、、ヒタ゚テヨ、キ、゙、ケ。」
1078  =item 4.  
1079    =item 4.
1080  サイズ0のyukiwiki.dbというファイルを設置します。  
1081  (Perlシステムによってはyukiwiki.pag, yukiwiki.dir)  ・オ・、・コ0、ホyukiwiki.db、ネ、、、ヲ・ユ・。・、・、タ゚テヨ、キ、゙、ケ。」
1082    。ハPerl・キ・ケ・ニ・爨ヒ、隍テ、ニ、マyukiwiki.pag, yukiwiki.dir。ヒ
1083  =item 5.  
1084    =item 5.
1085  yukiwiki.cgiにブラウザからアクセスします。  
1086    yukiwiki.cgi、ヒ・ヨ・鬣ヲ・カ、ォ、鬣「・ッ・サ・ケ、キ、゙、ケ。」
1087  =back  
1088    =back
1089  =head2 パーミッション  
1090    =head2 ・ム。シ・゚・テ・キ・逾
1091          ファイル        パーミッション      転送モード  
1092          yukiwiki.cgi    755                 ASCII          ・ユ・。・、・        ・ム。シ・゚・テ・キ・逾      ナセチ・筍シ・ノ
1093          yukiwiki.gif    644                 BINARY          yukiwiki.cgi    755                 ASCII
1094          yukimono.gif    644                 BINARY          yukiwiki.gif    644                 BINARY
1095          jcode.pl        644                 ASCII          yukimono.gif    644                 BINARY
1096            jcode.pl        644                 ASCII
1097      $dbmopen = 1; にした場合:  
1098          yukiwiki.db     666                 BINARY      $dbmopen = 1; 、ヒ、キ、ソセケ:
1099          (yukiwiki.pag, yukiwiki.dirの場合もあり)          yukiwiki.db     666                 BINARY
1100            (yukiwiki.pag, yukiwiki.dir、ホセケ遉筅「、遙ヒ
1101      $dbmopen = 0; にした場合: (カレントディレクトリを777にしておく)  
1102          .               777                 (転送しない)      $dbmopen = 0; 、ヒ、キ、ソセケ: (・ォ・・・ネ・ヌ・」・・ッ・ネ・熙777、ヒ、キ、ニ、ェ、ッ)
1103            .               777                 (ナセチ、キ、ハ、、)
1104  =head1 データのバックアップ方法  
1105    =head1 ・ヌ。シ・ソ、ホ・ミ・テ・ッ・「・テ・ラハヒ。
1106  $dbmopen = 1;の場合は、  
1107  データはすべてyukiwiki.db(.dir, .pag)に入る。  $dbmopen = 1;、ホセケ遉マ。「
1108  これをバックアップすればよい。  ・ヌ。シ・ソ、マ、ケ、ル、ニyukiwiki.db(.dir, .pag)、ヒニ、。」
1109    、ウ、、・ミ・テ・ッ・「・テ・ラ、ケ、、ミ、隍、。」
1110  $dbmopen = 0;の場合は、  
1111  yukiwikiというディレクトリができるので、  $dbmopen = 0;、ホセケ遉マ。「
1112  これ以下をバックアップすればよい。  yukiwiki、ネ、、、ヲ・ヌ・」・・ッ・ネ・熙ャ、ヌ、ュ、、ホ、ヌ。「
1113    、ウ、ーハイシ、・ミ・テ・ッ・「・テ・ラ、ケ、、ミ、隍、。」
1114  =head1 新しいページの作り方  
1115    =head1 ソキ、キ、、・レ。シ・ク、ホコ、ハ
1116  =over 4  
1117    =over 4
1118  =item 1.  
1119    =item 1.
1120  まず、適当なページ(例えばFrontPage)を選び、  
1121  ページの下にある「編集」リンクをたどります。  、゙、コ。「ナャナ、ハ・レ。シ・ク。ハホ网ィ、ミFrontPage。ヒ、チェ、モ。「
1122    ・レ。シ・ク、ホイシ、ヒ、「、。ヨハヤスク。ラ・・・ッ、、ソ、ノ、熙゙、ケ。」
1123  =item 2.  
1124    =item 2.
1125  するとテキスト入力ができる状態になるので、  
1126  そこにNewPageのような単語  、ケ、、ネ・ニ・ュ・ケ・ネニホマ、ャ、ヌ、ュ、セツヨ、ヒ、ハ、、ホ、ヌ。「
1127  (大文字小文字混在している英文字列)  、ス、ウ、ヒNewPage、ホ、隍ヲ、ハテアク
1128  を書いて「保存」します。  。ハツ醋クサセョハクサコョコ゚、キ、ニ、、、アムハクサホ。ヒ
1129    、ス、、、ニ。ヨハンツク。ラ、キ、゙、ケ。」
1130  =item 3.  
1131    =item 3.
1132  保存すると、FrontPageのページが書き換わり、  
1133  あなたが書いたNewPageという文字列の後ろに ? というリンクが表示されます。  ハンツク、ケ、、ネ。「FrontPage、ホ・レ。シ・ク、ャス、ュエケ、、遙「
1134  この ? はそのページがまだ存在しないことを示す印です。  、「、ハ、ソ、ャス、、、ソNewPage、ネ、、、ヲハクサホ、ホク螟、ヒ ? 、ネ、、、ヲ・・・ッ、ャノスシィ、オ、、゙、ケ。」
1135    、ウ、ホ ? 、マ、ス、ホ・レ。シ・ク、ャ、゙、タツクコ゚、キ、ハ、、、ウ、ネ、シィ、ケー、ヌ、ケ。」
1136  =item 4.  
1137    =item 4.
1138  その ? をクリックすると新しいページNewPageができますので、  
1139  あなたの好きな文章をその新しいページに書いて保存します。  、ス、ホ ? 、・ッ・・テ・ッ、ケ、、ネソキ、キ、、・レ。シ・クNewPage、ャ、ヌ、ュ、゙、ケ、ホ、ヌ。「
1140    、「、ハ、ソ、ホケ・、ュ、ハハクセマ、、ス、ホソキ、キ、、・レ。シ・ク、ヒス、、、ニハンツク、キ、゙、ケ。」
1141  =item 5.  
1142    =item 5.
1143  NewPageページができるとFrontPageの ? は消えて、リンクとなります。  
1144    NewPage・レ。シ・ク、ャ、ヌ、ュ、、ネFrontPage、ホ ? 、マセテ、ィ、ニ。「・・・ッ、ネ、ハ、熙゙、ケ。」
1145  =back  
1146    =back
1147  =head1 テキスト整形のルール  
1148    =head1 ・ニ・ュ・ケ・ネターキチ、ホ・。シ・
1149  =over 4  
1150    =over 4
1151  =item *  
1152    =item *
1153  連続した複数行はフィルされて表示されます。  
1154    マ「ツウ、キ、ソハ」ソケヤ、マ・ユ・」・、オ、、ニノスシィ、オ、、゙、ケ。」
1155  =item *  
1156    =item *
1157  空行は段落C<< <p> >>の区切りとなります。  
1158    カケヤ、マテハヘC<< <p> >>、ホカ霏レ、熙ネ、ハ、熙゙、ケ。」
1159  =item *  
1160    =item *
1161  HTMLのタグは書けません。  
1162    HTML、ホ・ソ・ー、マス、ア、゙、サ、。」
1163  =item *  
1164    =item *
1165  B<''ボールド''>のようにシングルクォート二つではさむと、  
1166  ボールドC<< <b> >>になります。  B<''・ワ。シ・・ノ''>、ホ、隍ヲ、ヒ・キ・・ー・・ッ・ゥ。シ・ネニ、ト、ヌ、マ、オ、爨ネ。「
1167    ・ワ。シ・・ノC<< <b> >>、ヒ、ハ、熙゙、ケ。」
1168  =item *  
1169    =item *
1170  B<'''イタリック'''>のようにシングルクォート三つではさむと、  
1171  イタリックC<< <i> >>になります。  B<'''・、・ソ・・テ・ッ'''>、ホ、隍ヲ、ヒ・キ・・ー・・ッ・ゥ。シ・ネサー、ト、ヌ、マ、オ、爨ネ。「
1172    ・、・ソ・・テ・ッC<< <i> >>、ヒ、ハ、熙゙、ケ。」
1173  =item *  
1174    =item *
1175  B<---->のようにマイナス4つがあると、  
1176  水平線C<< <hr> >>になります。  B<---->、ホ、隍ヲ、ヒ・゙・、・ハ・ケ4、ト、ャ、「、、ネ。「
1177    ソ衞ソタC<< <hr> >>、ヒ、ハ、熙゙、ケ。」
1178  =item *  
1179    =item *
1180  行をB<*>ではじめると、  
1181  大見出しC<< <h2> >>になります。  ケヤ、B<*>、ヌ、マ、ク、皃、ネ。「
1182    ツ邵ォスミ、キC<< <h2> >>、ヒ、ハ、熙゙、ケ。」
1183  =item *  
1184    =item *
1185  行をB<**>ではじめると、  
1186  小見出しC<< <h3> >>になります。  ケヤ、B<**>、ヌ、マ、ク、皃、ネ。「
1187    セョクォスミ、キC<< <h3> >>、ヒ、ハ、熙゙、ケ。」
1188  =item *  
1189    =item *
1190  行をマイナス-ではじめると、  
1191  箇条書きC<< <ul> >>になります。  ケヤ、・゙・、・ハ・ケ-、ヌ、マ、ク、皃、ネ。「
1192  マイナスの数が増えるとレベルが下がります(3レベルまで)  イユセス、ュC<< <ul> >>、ヒ、ハ、熙゙、ケ。」
1193    ・゙・、・ハ・ケ、ホソ、ャチ、ィ、、ネ・・ル・、ャイシ、ャ、熙゙、ケ。ハ3・・ル・、゙、ヌ。ヒ
1194      -項目1  
1195      --項目1-1      -ケ猯ワ1
1196      --項目1-2      --ケ猯ワ1-1
1197      -項目2      --ケ猯ワ1-2
1198      -項目3      -ケ猯ワ2
1199      --項目3-1      -ケ猯ワ3
1200      ---項目3-1-1      --ケ猯ワ3-1
1201      ---項目3-1-2      ---ケ猯ワ3-1-1
1202      --項目3-2      ---ケ猯ワ3-1-2
1203        --ケ猯ワ3-2
1204  =item *  
1205    =item *
1206  コロンを使うと、  
1207  用語と解説文のリストC<< <dl> >>が書けます。  ・ウ・・、サネ、ヲ、ネ。「
1208    ヘムク、ネイタ簗ク、ホ・・ケ・ネC<< <dl> >>、ャス、ア、゙、ケ。」
1209      :用語1:いろいろ書いた解説文1  
1210      :用語2:いろいろ書いた解説文2      :ヘムク1:、、、、、、ス、、、ソイタ簗ク1
1211      :用語3:いろいろ書いた解説文3      :ヘムク2:、、、、、、ス、、、ソイタ簗ク2
1212        :ヘムク3:、、、、、、ス、、、ソイタ簗ク3
1213  =item *  
1214    =item *
1215  リンク  
1216    ・・・ッ
1217  =over 4  
1218    =over 4
1219  =item *  
1220    =item *
1221  LinkToSomePageやFrontPageのように、  
1222  英単語の最初の一文字を大文字にしたものが  LinkToSomePage、腱rontPage、ホ、隍ヲ、ヒ。「
1223  二つ以上連続したものはYukiWikiのページ名となり、  アムテアク、ホコヌス鬢ホーハクサ、ツ醋クサ、ヒ、キ、ソ、筅ホ、ャ
1224  それが文章中に含まれるとリンクになります。  ニ、トーハセ袞「ツウ、キ、ソ、筅ホ、マYukiWiki、ホ・レ。シ・クフセ、ネ、ハ、遙「
1225    、ス、、ャハクセマテ讀ヒエ゙、゙、、、ネ・・・ッ、ヒ、ハ、熙゙、ケ。」
1226  =item *  
1227    =item *
1228  http://www.hyuki.com/ のようなURLは自動的にリンクになります。  
1229    http://www.hyuki.com/ 、ホ、隍ヲ、ハURL、マシォニーナェ、ヒ・・・ッ、ヒ、ハ、熙゙、ケ。」
1230  =item *  
1231    =item *
1232  二重の大かっこ[[ ]]でくくった文字列も、  
1233  YukiWikiのページ名になります。  ニスナ、ホツ遉ォ、テ、ウ[[ ]]、ヌ、ッ、ッ、テ、ソハクサホ、筍「
1234  大かっこの中にはスペースを含めてはいけません。  YukiWiki、ホ・レ。シ・クフセ、ヒ、ハ、熙゙、ケ。」
1235  日本語も使えます。  ツ遉ォ、テ、ウ、ホテ讀ヒ、マ・ケ・レ。シ・ケ、エ゙、皃ニ、マ、、、ア、゙、サ、。」
1236    ニヒワク、篏ネ、ィ、゙、ケ。」
1237  =back  
1238    =back
1239  =item *  
1240    =item *
1241  行頭がスペースやタブで始まっていると、  
1242  それは整形済みの段落C<< <pre> >>として扱われます。  ケヤニャ、ャ・ケ・レ。シ・ケ、茹ソ・ヨ、ヌサマ、゙、テ、ニ、、、、ネ。「
1243  プログラムの表示などに使うと便利です。  、ス、、マターキチコム、゚、ホテハヘC<< <pre> >>、ネ、キ、ニーキ、、、゙、ケ。」
1244    ・ラ・・ー・鬣爨ホノスシィ、ハ、ノ、ヒサネ、ヲ、ネハリヘ、ヌ、ケ。」
1245    
1246  =item *  
1247    =item *
1248  行を > ではじめると、  
1249  引用文C<< <blockquote> >>が書けます。  ケヤ、 > 、ヌ、マ、ク、皃、ネ。「
1250  >の数が多いとインデントが深くなります(3レベルまで)。  ーヘムハクC<< <blockquote> >>、ャス、ア、゙、ケ。」
1251    >、ホソ、ャツソ、、、ネ・、・・ヌ・・ネ、ャソシ、ッ、ハ、熙゙、ケ。ハ3・・ル・、゙、ヌ。ヒ。」
1252      >文章  
1253      >文章      >ハクセマ
1254      >>さらなる引用      >ハクセマ
1255      >文章      >>、オ、鬢ハ、ーヘム
1256        >ハクセマ
1257  =back  
1258    =back
1259  =head1 更新履歴  
1260    =head1 ケケソキヘホ
1261  =over 4  
1262    =over 4
1263  =item *  
1264    =item *
1265  2001年10月20日、Version 1.6.6。  
1266    2001ヌッ10キ20ニ。「Version 1.6.6。」
1267  更新の衝突対策。  
1268  元ページの簡単なチェックサムを取っておき、  ケケソキ、ホセラニヘツミコ。」
1269  更新前にチェックサムを比較する。  クオ・レ。シ・ク、ホエハテア、ハ・チ・ァ・テ・ッ・オ・爨シ隍テ、ニ、ェ、ュ。「
1270  修正個所はdigestという文字列を検索すれば分かる。  ケケソキチー、ヒ・チ・ァ・テ・ッ・オ・爨ネ豕モ、ケ、。」
1271  本来はMD5などでちゃんとやった方がいいのだけれど。  ス、タオクトス熙マdigest、ネ、、、ヲハクサホ、ク。コ、ケ、、ミハャ、ォ、。」
1272    ヒワヘ隍マMD5、ハ、ノ、ヌ、チ、网、ネ、荀テ、ソハ、ャ、、、、、ホ、タ、ア、、ノ。」
1273  衝突時に表示されるメッセージなどは「極悪」さんのページを参考にした。  
1274    セラニヘサ、ヒノスシィ、オ、、・皈テ・サ。シ・ク、ハ、ノ、マ。ヨカヒーュ。ラ、オ、、ホ・レ。シ・ク、サイケヘ、ヒ、キ、ソ。」
1275  =item *  
1276    =item *
1277  2001年10月17日、Version 1.6.5。  
1278    2001ヌッ10キ17ニ。「Version 1.6.5。」
1279  プレビュー画面で、更新ボタンを押したときに送信される  
1280  メッセージの内容をinput要素のtype="hidden"を使って埋め込むのをやめる。  ・ラ・・モ・蝪シイ靂フ、ヌ。「ケケソキ・ワ・ソ・、イ。、キ、ソ、ネ、ュ、ヒチソョ、オ、、
1281  代わりに、textarea要素を使う。  ・皈テ・サ。シ・ク、ホニ簣ニ、inputヘラチヌ、ホtype="hidden"、サネ、テ、ニヒ荀盪、爨ホ、、荀皃。」
1282  再プレビュー用にmyspecial_を導入。でもきれいな対策ではない。  ツ螟、熙ヒ。「textareaヘラチヌ、サネ、ヲ。」
1283    コニ・ラ・・モ・蝪シヘム、ヒmyspecial_、ニウニ。」、ヌ、筅ュ、、、、ハツミコ、ヌ、マ、ハ、、。」
1284  =item *  
1285    =item *
1286  2001年8月30日、Version 1.6.4。  
1287    2001ヌッ8キ30ニ。「Version 1.6.4。」
1288  URLでダイレクトにページ名を指定しても、  
1289  $WikiNameと$BracketName以外のページを作れないようにした。  URL、ヌ・タ・、・・ッ・ネ、ヒ・レ。シ・クフセ、サリト熙キ、ニ、筍「
1290  (is_valid_nameとis_editable参照)。  $WikiName、ネ$BracketNameーハウー、ホ・レ。シ・ク、コ、、ハ、、、隍ヲ、ヒ、キ、ソ。」
1291    (is_valid_name、ネis_editableサイセネ)。」
1292  =item *  
1293    =item *
1294  2001年8月30日、Version 1.6.3。  
1295    2001ヌッ8キ30ニ。「Version 1.6.3。」
1296  RecentChangesを編集・再編集不可とした。  
1297  編集不可ページは@uneditableにページ名を入れる。  RecentChanges、ハヤスク。ヲコニハヤスクノヤイト、ネ、キ、ソ。」
1298    ハヤスクノヤイト・レ。シ・ク、マ@uneditable、ヒ・レ。シ・クフセ、ニ、、。」
1299  =item *  
1300    =item *
1301  2001年2月25日、Version 1.6.1, 1.6.2。  
1302    2001ヌッ2キ25ニ。「Version 1.6.1, 1.6.2。」
1303  差分機能のバグ修正。  
1304  do_previewで'>'が扱えないバグを修正  コケハャオ。ヌス、ホ・ミ・ース、タオ。」
1305  (ユーザからの指摘)。  do_preview、ヌ'>'、ャーキ、ィ、ハ、、・ミ・ー、ス、タオ
1306    。ハ・譯シ・カ、ォ、鬢ホサリナヲ。ヒ。」
1307  =item *  
1308    =item *
1309  2001年2月22日、Version 1.6.0。  
1310  差分機能を実装した。  2001ヌッ2キ22ニ。「Version 1.6.0。」
1311    コケハャオ。ヌス、シツチ、キ、ソ。」
1312  =item *  
1313    =item *
1314  2001年2月19日、Version 1.5.4。  
1315  画像ファイルへのリンクは画像にしてみた。  2001ヌッ2キ19ニ。「Version 1.5.4。」
1316    イ霖・ユ・。・、・、リ、ホ・・・ッ、マイ霖、ヒ、キ、ニ、゚、ソ。」
1317  =item *  
1318    =item *
1319  2001年2月19日、Version 1.5.3。  
1320  RecentChangesの中に削除したページがあるのをやめた。  2001ヌッ2キ19ニ。「Version 1.5.3。」
1321  use strict;で引っかかる部分を少し整理(完全ではない)。  RecentChanges、ホテ讀ヒコス、キ、ソ・レ。シ・ク、ャ、「、、ホ、、荀皃ソ。」
1322    use strict;、ヌー、テ、ォ、ォ、ノハャ、セッ、キターヘ(エーチエ、ヌ、マ、ハ、、)。」
1323  =item *  
1324    =item *
1325  2001年2月16日、Version 1.5.2。  
1326  textareaに表示およびプレビューする前に < や > を &lt; や &gt; に変換した  2001ヌッ2キ16ニ。「Version 1.5.2。」
1327  (do_preview, editpage, print_preview_buttons)。  textarea、ヒノスシィ、ェ、隍モ・ラ・・モ・蝪シ、ケ、チー、ヒ < 、 > 、 &lt; 、 &gt; 、ヒハムエケ、キ、ソ
1328    (do_preview, editpage, print_preview_buttons)。」
1329  =item *  
1330    =item *
1331  2000年12月27日、Version 1.5.1。  
1332  プレビュー画面を整理した。  2000ヌッ12キ27ニ。「Version 1.5.1。」
1333    ・ラ・・モ・蝪シイ靂フ、ターヘ、キ、ソ。」
1334  =item *  
1335    =item *
1336  2000年12月22日、Version 1.5.0。  
1337  全体的にずいぶん書き直した。  2000ヌッ12キ22ニ。「Version 1.5.0。」
1338  一覧を別途作成するようにした(do_list)。  チエツホナェ、ヒ、コ、、、ヨ、ス、ュトセ、キ、ソ。」
1339  書き込む前に確認画面を出すようにした(do_preview)。  ーヘ、ハフナモコタョ、ケ、、隍ヲ、ヒ、キ、ソ(do_list)。」
1340  テキストの書き方を編集画面に入れた(do_edit, do_reedit)。  ス、ュケ、狠ー、ヒウホヌァイ靂フ、スミ、ケ、隍ヲ、ヒ、キ、ソ(do_preview)。」
1341  WhatsNew→RecentChanges、TopPage→FrontPageに変更した。  ・ニ・ュ・ケ・ネ、ホス、ュハ、ハヤスクイ靂フ、ヒニ、、ソ(do_edit, do_reedit)。」
1342    WhatsNew「ェRecentChanges。「TopPage「ェFrontPage、ヒハムケケ、キ、ソ。」
1343  =item *  
1344    =item *
1345  2000年12月20日、Version 1.1.0。  
1346  tieを利用して、dbmopenが使えない場合でも動作するように修正。  2000ヌッ12キ20ニ。「Version 1.1.0。」
1347  利用者の1人である「極悪」さんから  tie、ヘヘム、キ、ニ。「dbmopen、ャサネ、ィ、ハ、、セケ遉ヌ、簇ーコ、ケ、、隍ヲ、ヒス、タオ。」
1348  送っていただいたコードを元にしています。  ヘヘムシヤ、ホ1ソヘ、ヌ、「、。ヨカヒーュ。ラ、オ、、ォ、
1349    チ、テ、ニ、、、ソ、タ、、、ソ・ウ。シ・ノ、クオ、ヒ、キ、ニ、、、゙、ケ。」
1350  =item *  
1351    =item *
1352  2000年9月5日、Version 1.0.2。  
1353   <body color=...> → <body bgcolor=...>  2000ヌッ9キ5ニ。「Version 1.0.2。」
1354  利用者からの指摘による。感謝。   <body color=...> 「ェ <body bgcolor=...>
1355    ヘヘムシヤ、ォ、鬢ホサリナヲ、ヒ、隍。」エカシユ。」
1356  =item *  
1357    =item *
1358  2000年8月6日、Version 1.0.1を公開。  
1359  C MAGAZINE(ソフトバンクパブリッシング)  2000ヌッ8キ6ニ。「Version 1.0.1、クウォ。」
1360  2000年10月号連載記事向け公開版。  C MAGAZINE。ハ・ス・ユ・ネ・ミ・・ッ・ム・ヨ・・テ・キ・・ー。ヒ
1361  [[ ]] の最後が「望」のようにシフトJISで  2000ヌッ10キケ賺「コワオュサク、アクウォネヌ。」
1362  0x5Dになる場合の回避を行なった。  [[ ]] 、ホコヌク螟ャ。ヨヒセ。ラ、ホ、隍ヲ、ヒ・キ・ユ・ネJIS、ヌ
1363    0x5D、ヒ、ハ、セケ遉ホイネ、ケヤ、ハ、テ、ソ。」
1364  =item *  
1365    =item *
1366  2000年8月5日、Version 1.0.0を公開。  
1367    2000ヌッ8キ5ニ。「Version 1.0.0、クウォ。」
1368  =item *  
1369    =item *
1370  2000年7月23日、Version 0.82を公開。  
1371  編集時のリンクミス。  2000ヌッ7キ23ニ。「Version 0.82、クウォ。」
1372  <textarea>の属性変更。  ハヤスクサ、ホ・・・ッ・゚・ケ。」
1373    <textarea>、ホツータュハムケケ。」
1374  =item *  
1375    =item *
1376  2000年7月22日、Version 0.81を公開。  
1377  ロゴを組み込む。  2000ヌッ7キ22ニ。「Version 0.81、クウォ。」
1378    ・・エ、チネ、゚ケ、爍」
1379  =item *  
1380    =item *
1381  2000年7月21日、Version 0.80を公開。  
1382  PODをCGI中に書き込む。  2000ヌッ7キ21ニ。「Version 0.80、クウォ。」
1383    POD、CGIテ讀ヒス、ュケ、爍」
1384  =item *  
1385    =item *
1386  2000年7月19日、Version 0.70を公開。  
1387  '''イタリック'''や、--、---、>>、>>>などを実装。  2000ヌッ7キ19ニ。「Version 0.70、クウォ。」
1388    '''・、・ソ・・テ・ッ'''、茖「--。「---。「>>。「>>>、ハ、ノ、シツチ。」
1389  =item *  
1390    =item *
1391  2000年7月18日、Version 0.60を公開。  
1392  *太字*を''太字''に変更  2000ヌッ7キ18ニ。「Version 0.60、クウォ。」
1393    *ツタサ*、''ツタサ''、ヒハムケケ
1394  =item *  
1395    =item *
1396  2000年7月17日、Version 0.50を公開。  
1397    2000ヌッ7キ17ニ。「Version 0.50、クウォ。」
1398  =item *  
1399    =item *
1400  2000年7月17日、さらにいろいろ追加する。  
1401    2000ヌッ7キ17ニ。「、オ、鬢ヒ、、、、、、トノイテ、ケ、。」
1402  =item *  
1403    =item *
1404  2000年7月16日、いろいろ追加。  
1405    2000ヌッ7キ16ニ。「、、、、、、トノイテ。」
1406  =item *  
1407    =item *
1408  2000年7月15日、公開。  
1409    2000ヌッ7キ15ニ。「クウォ。」
1410  =back  
1411    =back
1412  =head1 TODO  
1413    =head1 TODO
1414      - テキスト表示モード  
1415      - Charsetを明示。      - ・ニ・ュ・ケ・ネノスシィ・筍シ・ノ
1416      - textarea中の閉じタグ対応      - Charset、フタシィ。」
1417      - メニューの英語表記付記      - textareaテ讀ホハト、ク・ソ・ーツミア
1418      - プレビューのボタンで、mymsgをinputのvalueに入れているが、改行をそのままvalueにいれてはいけないのではないか。      - ・皈ヒ・蝪シ、ホアムクノスオュノユオュ
1419      - 「再編集」の機能はブラウザの back で充分ではないか。プレビューはもっとシンプルに。      - ・ラ・・モ・蝪シ、ホ・ワ・ソ・、ヌ。「mymsg、input、ホvalue、ヒニ、、ニ、、、、ャ。「イケヤ、、ス、ホ、゙、゙value、ヒ、、、、ニ、マ、、、ア、ハ、、、ホ、ヌ、マ、ハ、、、ォ。」
1420      - ページタイトル(Wikiname)が検索にかかるようにする。      - 。ヨコニハヤスク。ラ、ホオ。ヌス、マ・ヨ・鬣ヲ・カ、ホ back 、ヌスシハャ、ヌ、マ、ハ、、、ォ。」・ラ・・モ・蝪シ、マ、筅テ、ネ・キ・・ラ・、ヒ。」
1421      - InterWiki風の機能「URLを隠しつつ、リンクを張る」      - ・レ。シ・ク・ソ・、・ネ・。ハWikiname。ヒ、ャク。コ、ヒ、ォ、ォ、、隍ヲ、ヒ、ケ、。」
1422        - InterWikiノ、ホオ。ヌス。ヨURL、ア」、キ、ト、ト。「・・・ッ、ト・、。ラ
1423  =head1 作者  
1424    =head1 コシヤ
1425      Copyright (C) 2000 by Hiroshi Yuki.  
1426      結城浩 <hyuki@hyuki.com>      Copyright (C) 2000 by Hiroshi Yuki.
1427      http://www.hyuki.com/      キセケタ <hyuki@hyuki.com>
1428      http://www.hyuki.com/yukiwiki/      http://www.hyuki.com/
1429        http://www.hyuki.com/yukiwiki/
1430  質問、意見、バグ報告は hyuki@hyuki.com にメールしてください。  
1431    シチフ茖「ーユクォ。「・ミ・ーハケ、マ hyuki@hyuki.com 、ヒ・癸シ・、キ、ニ、ッ、タ、オ、、。」
1432  =head1 配布条件  
1433    =head1 ヌロノロセキ
1434  YukiWikiは、  
1435  GNU General Public Licenseにて公開します。  YukiWiki、マ。「
1436    GNU General Public License、ヒ、ニクウォ、キ、゙、ケ。」
1437  YukiWikiはフリーソフトです。  
1438  ご自由にお使いください。  YukiWiki、マ・ユ・遙シ・ス・ユ・ネ、ヌ、ケ。」
1439  自分好みのYukiWikiが作れるようにシンプルにしてあります。  、エシォヘウ、ヒ、ェサネ、、、ッ、タ、オ、、。」
1440    シォハャケ・、゚、ホYukiWiki、ャコ、、、隍ヲ、ヒ・キ・・ラ・、ヒ、キ、ニ、「、熙゙、ケ。」
1441  =head1 謝辞  
1442    =head1 シユシュ
1443  本家のWikiWikiを作ったCunningham & Cunningham, Inc.に  
1444  感謝します。  ヒワイネ、ホWikiWiki、コ、テ、ソCunningham & Cunningham, Inc.、ヒ
1445    エカシユ、キ、゙、ケ。」
1446  YukiWikiを楽しんで使ってくださる  
1447  ネット上の方々に感謝します。  YukiWiki、ウレ、キ、、ヌサネ、テ、ニ、ッ、タ、オ、
1448    ・ヘ・テ・ネセ螟ホハ。ケ、ヒエカシユ、キ、゙、ケ。」
1449  YukiWikiのロゴをデザインしてくださった橋本礼奈さん  
1450  http://city.hokkai.or.jp/~reina/  YukiWiki、ホ・・エ、・ヌ・カ・、・、キ、ニ、ッ、タ、オ、テ、ソカカヒワホ鯣爨オ、
1451  に感謝します。  http://city.hokkai.or.jp/~reina/
1452    、ヒエカシユ、キ、゙、ケ。」
1453  tieを使った版の元になるコードを送ってくださった  
1454  「極悪」さんに感謝します。  tie、サネ、テ、ソネヌ、ホクオ、ヒ、ハ、・ウ。シ・ノ、チ、テ、ニ、ッ、タ、オ、テ、ソ
1455    。ヨカヒーュ。ラ、オ、、ヒエカシユ、キ、゙、ケ。」
1456  =head1 参照リンク  
1457    =head1 サイセネ・・・ッ
1458  =over 4  
1459    =over 4
1460  =item *  
1461    =item *
1462  YukiWikiホームページ  
1463  http://www.hyuki.com/yukiwiki/  YukiWiki・ロ。シ・爭レ。シ・ク
1464    http://www.hyuki.com/yukiwiki/
1465  =item *  
1466    =item *
1467  本家のWikiWiki  
1468  http://c2.com/cgi/wiki?WikiWikiWeb  ヒワイネ、ホWikiWiki
1469    http://c2.com/cgi/wiki?WikiWikiWeb
1470  =item *  
1471    =item *
1472  本家のWikiWikiの作者(Cunningham & Cunningham, Inc.)  
1473  http://c2.com/  ヒワイネ、ホWikiWiki、ホコシヤ(Cunningham & Cunningham, Inc.)
1474    http://c2.com/
1475  =item *  
1476    =item *
1477  YukiWikiのロゴデザインをしてくださった橋本礼奈さんのページ  
1478  http://city.hokkai.or.jp/~reina/  YukiWiki、ホ・・エ・ヌ・カ・、・、、キ、ニ、ッ、タ、オ、テ、ソカカヒワホ鯣爨オ、、ホ・レ。シ・ク
1479    http://city.hokkai.or.jp/~reina/
1480  =back  
1481    =back
1482  =cut  
1483    =cut

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.4

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24