/[pub]/suikawiki/script/lib/suikawiki.pl
Suika

Diff of /suikawiki/script/lib/suikawiki.pl

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

revision 1.3 by wakaba, Thu Apr 3 01:09:07 2003 UTC revision 1.4 by wakaba, Tue Apr 29 10:41:07 2003 UTC
# Line 11  require SuikaWiki::View; Line 11  require SuikaWiki::View;
11  require SuikaWiki::Plugin;  require SuikaWiki::Plugin;
12  our %fmt;       ## formatter objects  our %fmt;       ## formatter objects
13  our %embed_command = (  our %embed_command = (
         searched        => '^\[\[#searched:([^\]]+)\]\]$',      ## Deprecated  
14          form    => qr/\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/,          form    => qr/\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/,
15  );  );
16  our ($modifier_dbtype,$url_cgi,%uri,%PathTo);  our ($modifier_dbtype,$url_cgi,%uri,%PathTo);
# Line 119  sub _do_view_msg (%) { Line 118  sub _do_view_msg (%) {
118    print $fmt{view}->replace ($view_def->as_string => $o, {formatter => $fmt{view}});    print $fmt{view}->replace ($view_def->as_string => $o, {formatter => $fmt{view}});
119  }  }
120    
 sub id_and_name ($) {  
     my $name = shift;  
     if ($UA =~ m#Mozilla/[12]\.|Microsoft Internet Explorer#) {  
       qq{id="$name"><a name="$name"></a};  
     } else {  
         qq{id="$name"};  
     }  
 }  
   
121  sub do_adminchangepassword {  sub do_adminchangepassword {
122      if ($form{mynewpassword} ne $form{mynewpassword2}) {      if ($form{mynewpassword} ne $form{mynewpassword2}) {
123          &_do_view_msg (-view => '-error', -page => $form{mypage},          &_do_view_msg (-view => '-error', -page => $form{mypage},
# Line 275  sub print_header ($;%) { Line 265  sub print_header ($;%) {
265          $option{o}->{-header}->{meta_ct} = qq{<meta http-equiv="content-type" content="$option{-media}->{type}; charset=@{[&get_charset_name($kanjicode,compatible=>1)]}">\n};          $option{o}->{-header}->{meta_ct} = qq{<meta http-equiv="content-type" content="$option{-media}->{type}; charset=@{[&get_charset_name($kanjicode,compatible=>1)]}">\n};
266      } else {      } else {
267          my $type = $option{-media}->{type};          my $type = $option{-media}->{type};
268          $type = 'application/xml' if $type eq 'application/rss+xml';          $type = 'application/xml' if ($type =~ m!^application/(?:rdf|rss)\+xml$!) && ($UA =~ m#Gecko#);
269          print qq{Content-Type: $type; charset=@{[&get_charset_name($kanjicode)]}\n};          print qq{Content-Type: $type; charset=@{[&get_charset_name($kanjicode)]}\n};
270      }      }
271      print <<"EOD";      ## TODO:      ## TODO: more Vary: support
272  Content-Language: $lang      print <<"EOD";
273    Vary: User-Agent,Accept-Language
274  Content-Style-Type: text/css  Content-Style-Type: text/css
275    
276  EOD  EOD
# Line 300  sub get_charset_name ($;%) { Line 291  sub get_charset_name ($;%) {
291    
292  sub escape {  sub escape {
293      my $s = shift;      my $s = shift;
     $s =~ s|\x0D\x0A|\x0A|g;  
294      $s =~ s|&|&amp;|g;      $s =~ s|&|&amp;|g;
295      $s =~ s|<|&lt;|g;      $s =~ s|<|&lt;|g;
296      $s =~ s|>|&gt;|g;      $s =~ s|>|&gt;|g;
# Line 310  sub escape { Line 300  sub escape {
300    
301  sub unescape {  sub unescape {
302      my $s = shift;      my $s = shift;
     # $s =~ s|\n|\r\n|g;  
303      $s =~ s|&lt;|<|g;      $s =~ s|&lt;|<|g;
304      $s =~ s|&gt;|>|g;      $s =~ s|&gt;|>|g;
305      $s =~ s|&quot;|"|g;      $s =~ s|&quot;|"|g;
# Line 335  sub convert_format ($$$;%) { Line 324  sub convert_format ($$$;%) {
324    }    }
325  }  }
326    
 sub text_to_html {  
     my ($txt, %option) = @_;  
     my $toc = $option{-toc} || (ref $option{toc} ? $option{toc} : []);  
     my $tocnum = 0;  
       
     ## Load constants  
     my %const;  
     if ($option{magic} =~ /import="([^"]+)"/) {  
       for (split /\s*,\s*/, $1) {  
         my $wp = $database{$_};  
         if ($wp =~ m!^\#\?SuikaWikiConst/(?:0.9|1.0)!) {  
           wiki::suikawikiconst::to_hash ($wp => \%const);  
         }  
       }  
     }  
       
     $txt =~ s{__&&([^&]+)&&__}{defined $const{$1}?$const{$1}:qq(__&&$1&&__)}ge;  
     my (@txt) = split(/\n/, $txt);  
     my (@saved, @result);  
     unshift(@saved, "</p>");  
     push(@result, "<p>");  
     foreach (@txt) {  
         chomp;  
         if (/^\*\*\*\*\*([^\x0D\x0A]*)/) {  
             push @$toc, [5, "i$tocnum" => ($1 || $tocnum)];  
             push(@result, splice(@saved), qq(<h6 @{[&id_and_name("i$tocnum")]}>) . &inline($1, %option, const => \%const) . '</h6>');  
             $tocnum++;  
         } elsif (/^\*\*\*\*([^\x0D\x0A]*)/) {  
             push @$toc, [4, "i$tocnum" => ($1 || $tocnum)];  
             push(@result, splice(@saved), qq(<h5 @{[&id_and_name("i$tocnum")]}>) . &inline($1, %option, const => \%const) . '</h5>');  
             $tocnum++;  
         } elsif (/^\*\*\*([^\x0D\x0A]*)/) {  
             push @$toc, [3, "i$tocnum" => ($1 || $tocnum)];  
             push(@result, splice(@saved), qq(<h4 @{[&id_and_name("i$tocnum")]}>) . &inline($1, %option, const => \%const) . '</h4>');  
             $tocnum++;  
         } elsif (/^\*\*([^\x0D\x0A]*)/) {  
         # if (/^\*\*(.*)/) {  
         # Walrus mod (6) end  
             push @$toc, [2, "i$tocnum" => ($1 || $tocnum)];  
             push(@result, splice(@saved), qq(<h3 @{[&id_and_name("i$tocnum")]}>) . &inline($1, %option, const => \%const) . '</h3>');  
             $tocnum++;  
         } elsif (/^\*([^\x0D\x0A]*)/) {  
             push @$toc, [1, "i$tocnum" => ($1 || $tocnum)];  
             push(@result, splice(@saved), qq(<h2 @{[&id_and_name("i$tocnum")]}>) . &inline($1, %option, const => \%const) . '</h2>');  
             $tocnum++;  
         } elsif (/^(={1,6})(.*)/) {  
             &back_push('ol', length($1), \@saved, \@result);  
             push(@result, '<li>' . &inline($2, %option, const => \%const) . '</li>');  
         } elsif (/^(-{1,6})(.*)/) {  
           &back_push('ul', length($1), \@saved, \@result);  
           my ($pf, $l) = ('', $2);  
           if (!$main::_EMBEDED && $l =~ s/^\s*\[([0-9]+)\]//) {  
             my $num = 0+$1;  
             $pf = qq(<a name="anchor-$num" id="anchor-$num" class="anchor">[$num]</a>);  
           }  
           push(@result, '<li>' . $pf . &inline ($l, %option, const => \%const) . '</li>');  
         } elsif (/^:([^:]+):(.*)/) {  
             &back_push('dl', 1, \@saved, \@result);  
             push(@result, '<dt>' . &inline($1, %option, const => \%const) . '</dt>', '<dd>' . &inline($2, %option, const => \%const) . '</dd>');  
         } elsif (/^(?!>>\d)(>{1,5})(.*)/) {  
             &back_push('blockquote', length($1), \@saved, \@result);  
             push @result, "<p>";  
             push(@result, &inline($2, %option, const => \%const));  
             unshift @saved, "</p>";  
         } elsif (/^\s*$/) {  
             push(@result, splice(@saved));  
             push(@result, "<p>");  
             unshift(@saved, "</p>");  
         } elsif (/^(\s+.*)$/) {  
             &back_push('pre', 1, \@saved, \@result);  
             push(@result, &inline($1, %option, const => \%const));  
         } elsif (/^\,(.*?)[\x0D\x0A]*$/) {  
             &back_push('table', 1, \@saved, \@result);  
             #######  
             # This part is taken from Mr. Ohzaki's Perl Memo and Makio Tsukamoto's WalWiki.  
             # XXXXX  
             my $tmp = "$1,";  
             my @value = map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_} ($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);  
             my @align = map {(s/^\s+//) ? ((s/\s+$//) ? ' align="center"' : ' align="right"') : ''} @value;  
             my @colspan = map {($_ eq '==') ? 0 : 1} @value;  
             for (my $i = 0; $i < @value; $i++) {  
                 if ($colspan[$i]) {  
                     while ($i + $colspan[$i] < @value and $value[$i + $colspan[$i]] eq '==') {  
                         $colspan[$i]++;  
                     }  
                     $colspan[$i] = ($colspan[$i] > 1) ? sprintf(' colspan="%d"', $colspan[$i]) : '';  
                     $value[$i] = sprintf('<td%s%s>%s</td>', $align[$i], $colspan[$i], &inline($value[$i], %option, const => \%const));  
                 } else {  
                     $value[$i] = '';  
                 }  
             }  
             push(@result, join('', '<tr>', @value, '</tr>'));  
             # XXXXX  
             #######  
         } elsif (/^\[(INS|DEL|PRE)\[\s*$/) {  
             push @result, splice (@saved), '<'.lc($1).'>';  
             unshift @saved, "</p>";  
             push @result, "<p>";  
         } elsif (/^\](INS|DEL|PRE)\]\s*$/) {  
             push @result, splice (@saved), '</'.lc($1).'>';  
         } elsif (/^\[([0-9]+)\](.*)$/ && !$main::_EMBEDED) {  
           my $num = 0+$1;  
           push @result, qq(<a name="anchor-$num" id="anchor-$num" class="anchor">[$num]</a>);  
           push @result, &inline ($2, %option, const => \%const);  
         } else {  
             push(@result, &inline($_, %option, const => \%const));  
         }  
     }  
     push(@result, splice(@saved));  
       
     my $r = join("\n", @result);  
     $r =~ s#<p>\x0D?\x0A</p>##g;  
     $r =~ s#[\x0D\x0A]+</#</#g;  
     $r =~ s#<pre>\x0D?\x0A#<pre>#g;  
     $r;  
 }  
   
 sub back_push {  
     my ($tag, $level, $savedref, $resultref, $attr) = @_;  
     while (@$savedref > $level) {  
         push(@$resultref, shift(@$savedref));  
     }  
     if ($savedref->[0] ne "</$tag>") {  
         push(@$resultref, splice(@$savedref));  
     }  
     while (@$savedref < $level) {  
         unshift(@$savedref, "</$tag>");  
         push(@$resultref, "<$tag$attr>");  
     }  
 }  
   
 sub inline ($;%) {  
     my ($line, %option) = @_;  
     $line = &escape($line);  
     $line =~ s{$embed_command{form}}{&make_custom_form ($1, $2, $3, $4, \%option)}ge;  
     $line =~ s{\[(INS|DEL|SUP|SUB|VAR|CODE|KBD|SAMP|DFN)(?:\(([A-Za-z0-9\x20-]+)\))?\[(.+?)\]\]}{<@{[lc $1]}@{[$2 ? qq( class="$2") : '']}>$3</@{[lc $1]}>}g;  
     $line =~ s:\[(WEAK)\[(.+?)\]\]:<span class="@{[lc $1]}">$2</span>:g;  
     $line =~ s:\[ABBR\[([^]]+)\] \[([^]]+)\]\]:<acronym title="$2">$1</acronym>:g;  
     $line =~ s:\[RUBYB\[([^]]+)\] \[([^]]+)\] \[([^]]+)\]\]:<span class="ruby"><ruby class="rb"><rb>$1</rb><rp>(</rp><rt>$2</rt><rp>)</rp></ruby><span class="rp"> (</span><span class="rt-below">$3</span><span class="rp">) </span></span>:g;  
     $line =~ s:\[RUBY\[([^]]+)\] \[([^]]+)\]\]:<ruby><rb>$1</rb><rp>(</rp><rt>$2</rt><rp>)</rp></ruby>:g;  
     $line =~ s:\[RUBYB\[([^]]+)\] \[([^]]+)\]\]:<span class="ruby"><span class="rb">$1</span><span class="rp"> (</span><span class="rt-below">$2</span><span class="rp">) </span></span>:g;  
     $line =~ s|'''([^']+)'''|<strong>$1</strong>|g;  
     $line =~ s|''([^']+)''|<em>$1</em>|g;  
     $line =~ s{  
       (\[\[(\#\S+?)\]\])  
       |\[\[([^[]+?)](?:&gt;&gt;([0-9]+))?]  
       |&gt;&gt;([0-9]+)  
       |&lt;([A-Za-z0-9%]+:(?:(?!&gt;).)+)&gt;  
     }{  
       my ($l, $page,$anchor, $anum, $uri) = ($1, $3,$4, 0+$5, $6);  
       if ($l) {  
         &embedded_to_html($1);  
       } elsif (defined $page) {  
         &make_wikilink (&unescape ($page), anchor => 0+$anchor, base => $option{page});  
       } elsif ($anum) {  
         qq(<a href="#anchor-$anum" class="wiki-anchor">&gt;&gt;$anum</a>);  
       } elsif ($uri) {  
         &make_urilink ($uri);  
       }  
     }gex;  
     return $line;  
 }  
   
327  sub make_wikilink ($%) {  sub make_wikilink ($%) {
328    my ($name, %option) = @_;    my ($name, %option) = @_;
329    my $ename = &escape (length $option{label} ? $option{label} : $name);    my $ename = &escape (length $option{label} ? $option{label} : $name);
# Line 635  sub init_form { Line 461  sub init_form {
461      $form{mypage} =~ tr/\x00-\x1F\x7F//d;      $form{mypage} =~ tr/\x00-\x1F\x7F//d;
462      $form{mypage} = SuikaWiki::Name::Space::normalize_name ($form{mypage});      $form{mypage} = SuikaWiki::Name::Space::normalize_name ($form{mypage});
463      $form{mycmd} ||= 'default';      $form{mycmd} ||= 'default';
464        $form{mycmd} =~ tr/-/_/;
465    
466      # mypreview_edit        -> do_edit, with preview.      # mypreview_edit        -> do_edit, with preview.
467      # mypreview_adminedit   -> do_adminedit, with preview.      # mypreview_adminedit   -> do_adminedit, with preview.
# Line 758  EOD Line 585  EOD
585    
586  sub is_editable {  sub is_editable {
587      my ($page) = @_;      my ($page) = @_;
588      if ($page =~ /[\x00-\x20\[\]\x7F]/) {      return 0 unless SuikaWiki::Name::Space::validate_name ($page);
589        return 0;      return 0 if $page =~ /[\x00-\x20\[\]\x7F]/;
     } elsif ($wiki::page::ns::delimiter) {      ## Use namespace  
       if ($page eq $wiki::page::ns::delimiter  
        || $page eq $wiki::page::ns::self  
        || $page eq $wiki::page::ns::parent) {  
         return 0;  
       } elsif ($page =~ /\Q$wiki::page::ns::delimiter\E(?:\Q$wiki::page::ns::self\E|\Q$wiki::page::ns::parent\E)\Q$wiki::page::ns::delimiter\E/) {  
         return 0;  
       } elsif ($page =~ /^(?:\Q$wiki::page::ns::self\E|\Q$wiki::page::ns::parent\E)\Q$wiki::page::ns::delimiter\E/) {  
         return 0;  
       } elsif ($page =~ /\Q$wiki::page::ns::delimiter\E(?:\Q$wiki::page::ns::self\E|\Q$wiki::page::ns::parent\E)$/) {  
         return 0;  
       }  
     }  
590      1;      1;
591  }  }
592    
# Line 877  sub get_new_anchor_index ($) { Line 691  sub get_new_anchor_index ($) {
691      $anchor + 1;      $anchor + 1;
692  }  }
693    
 my $CommentIndex = 0;  
 sub embedded_to_html {  
     my ($embedded) = @_;  
     if ($embedded eq '[[#comment]]' or $embedded eq '[[#rcomment]]') {  
       unless ($main::_EMBEDED) {  
         my $lastmodified = $database->mtime ($form{mypage});  
         return <<"EOD";  
 <form action="$url_cgi" method="post" id="x-comment-@{[++$CommentIndex]}" class="comment"><p>  
     <input type="hidden" name="mycmd" value="comment" />  
     <input type="hidden" name="mypage" value="$form{mypage}" />  
     <input type="hidden" name="myLastModified" value="$lastmodified" />  
     <input type="hidden" name="mytouch" value="on" />  
     <input type="hidden" name="comment_index" value="$CommentIndex" />  
     @{[&Resource('WikiForm:WikiComment:Name=',escape=>1)]}  
     <input type="text" name="myname" value="" size="10" class="comment-name" />  
     <input type="text" name="mymsg" value="" size="60" class="comment-msg" />  
     <input type="submit" value="@{[&Resource('WikiForm:Add',escape=>1)]}" title="@{[&Resource('WikiForm:AddLong',escape=>1)]}" class="comment-submit" />  
 </p></form>  
 EOD  
      } else {  
         return <<"EOD";  
 <del><form action="$url_cgi" method="get">  
     <input type="hidden" name="mycmd" value="default" />  
     <input type="hidden" name="mypage" value="$form{mypage}" />  
     @{[&Resource('WikiForm:WikiComment:Name=',escape=>1)]}  
     <input type="text" name="myname" value="" size="10" disabled="disabled" />  
     <input type="text" name="mymsg" value="" size="60" disabled="disabled" />  
 </form></del>  
 EOD  
     }  
   } elsif ($embedded =~ /$embed_command{searched}/) {  
     return get_search_result ($1, -match_myself => 1);  
   } elsif ($embedded =~ /^\[\[\#embed:(.+)\]\]$/) {  
     my ($name, $r) = ($1, '');  
     if ($name =~ s/^IMG://) {  
       my ($magic, $content) = SuikaWiki::Plugin->magic_and_content ($database{$name});  
       $r = &convert_format ($content, $magic => 'HTML_fragment', page => $name, magic => $magic, -error_no_return => 1);  
       if (defined $r) {  
         return $r;  
       } else {  
         return '<span class="error-embed-image">'.&Resource ('Embed:ImageNotSupported', escape=>1).'</span>';  
       }  
     } else {  
       if ($main::_EMBEDED != 1) {  
         my ($cf, $content) = SuikaWiki::Plugin->magic_and_content ($database{$name});  
         $cf ||= '#?SuikaWiki/0.9';  
         if ($cf =~ m!^#\?SuikaWiki/0.9(?:$|\s)!) {  
           $main::_EMBEDED = 1;  
           $r = &text_to_html ($content, magic => $cf, page => $name);  
           $main::_EMBEDED = 0;  
         } elsif (length $content) {  
           $r = "<pre>@{[&escape ($content)]}</pre>";  
         } else {  
           $r = &text_to_html ("[INS[\n[[$name]]: @{[&Resource('Embed:PageNotFound')]}\n]INS]\n", magic => '#?SuikaWiki/0.9');  
         }  
       } else {  ## nested #EMBED  
         $r = &text_to_html ("[INS[\n[[$name]]: @{[&Resource('Embed:Nested',escape=>1)]}\n]INS]\n", magic => '#?SuikaWiki/0.9');  
       }  
       return qq(<blockquote title="@{[&escape($name)]}" class="wiki-embed">$r<div class="cite-note">¡Ø<cite><a href="$url_cgi?@{[&encode($name)]}" class="wiki">@{[&escape($name)]}</a></cite>¡Ù</div></blockquote>);  
     }  
   } else {  
     return $embedded;  
   }  
 }  
   
694  sub load_formatter (@) {  sub load_formatter (@) {
695      my $x = SuikaWiki::Plugin->feature ('SuikaWiki::Markup::XML');
696      for my $t (@_) {      for my $t (@_) {
697          unless ($fmt{$t}) {          unless ($fmt{$t}) {
698              require Message::Util::Formatter;              require Message::Util::Formatter;
# Line 950  sub load_formatter (@) { Line 700  sub load_formatter (@) {
700              for (@{$SuikaWiki::Plugin::List{'wiki'.$t}||[]}) {              for (@{$SuikaWiki::Plugin::List{'wiki'.$t}||[]}) {
701                  $_->load_formatter ($fmt{$t}, type => 'wiki'.$t);                  $_->load_formatter ($fmt{$t}, type => 'wiki'.$t);
702              }              }
703                $fmt{$t}->option (return_class => 'SuikaWiki::Markup::XML') if $x;
704          }          }
705      }      }
706  }  }
# Line 1169  sub __get_datetime ($) { main::get_now ( Line 920  sub __get_datetime ($) { main::get_now (
920  sub resource ($$;%) { shift; &main::Resource (@_) }  sub resource ($$;%) { shift; &main::Resource (@_) }
921  sub uri ($$) { $main::uri{$_[1]} }  sub uri ($$) { $main::uri{$_[1]} }
922  sub user_agent_names ($) { $main::UA }  sub user_agent_names ($) { $main::UA }
923    sub _path_to ($$) { $main::PathTo{$_[1]} }
924    
925  sub formatter ($$) {  sub formatter ($$) {
926    &main::load_formatter ($_[1]);    &main::load_formatter ($_[1]);
# Line 1179  sub format_converter ($$$) { Line 931  sub format_converter ($$$) {
931    $main::fmt{format}->{($_[1]=~/([A-Za-z0-9]\S+)/?$1:'SuikaWiki/0.9').'_to_'.$_[2]}    $main::fmt{format}->{($_[1]=~/([A-Za-z0-9]\S+)/?$1:'SuikaWiki/0.9').'_to_'.$_[2]}
932    || $main::fmt{format}->{($_[1]=~/([A-Za-z0-9](?:(?!\/)\S)+)/?$1:'SuikaWiki').'_to_'.$_[2]};    || $main::fmt{format}->{($_[1]=~/([A-Za-z0-9](?:(?!\/)\S)+)/?$1:'SuikaWiki').'_to_'.$_[2]};
933  }  }
934  sub formatter_replace_if_not_parsed_yet ($$$$) {  sub formatter_replace_if_not_parsed_yet ($$$$;$) {
935    my ($o, $context, $p, $attr_name) = @_;    my ($o, $context, $p, $attr_name, $option) = @_;
936    &main::load_formatter ($context);    &main::load_formatter ($context);
937    index ($p->{-option}->{$attr_name}, 'p') > -1 ?    if ((ref $p->{$attr_name} && $p->{$attr_name}->flag ('parsed'))
938      $p->{$attr_name}    ## Already parsed     || (!ref $p->{$attr_name} && index ($p->{-option}->{$attr_name}, 'p') > -1)) {
939      :      $p->{$attr_name};   ## Already parsed
940      $main::fmt{$context}->replace ($p->{$attr_name}, $o, {formatter => $main::fmt{$context}})    } else {
941    ;      $main::fmt{$context}->replace ($p->{$attr_name}, $o, {formatter => $main::fmt{$context}});
942      }
943  }  }
944    
945  sub cache ($$) {  sub cache ($$) {
# Line 1268  package main; Line 1021  package main;
1021    
1022  =head1 NAME  =head1 NAME
1023    
1024  lib/suikawiki.pl --- SuikaWiki  lib/suikawiki.pl --- SuikaWiki transitional library
1025    
1026  =head1 AUTHOR  =head1 AUTHOR
1027    
1028  Hiroshi Yuki <hyuki@hyuki.com> <http://www.hyuki.com/yukiwiki/>  Hiroshi Yuki <hyuki@hyuki.com> <http://www.hyuki.com/yukiwiki/> (YukiWiki)
1029    
1030  Makio Tsukamoto <http://digit.que.ne.jp/>  Makio Tsukamoto <http://digit.que.ne.jp/> (WalWiki)
1031    
1032  Wakaba <w@suika.fam.cx>  Wakaba <w@suika.fam.cx>
1033    
1034  =head1 LICENSE  =head1 LICENSE
1035    
1036  Copyright (C) 2000-2003 AUTHORS  Copyright AUTHORS 2000-2003
1037    
1038  This program is free software; you can redistribute it and/or  This program is free software; you can redistribute it and/or
1039  modify it under the same terms as Perl itself.  modify it under the same terms as Perl itself.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24