#?SuikaWikiConfig/2.0

Plugin:
  @Name: WikiFormBBS
  @FullName:
    WikiForm: BBS Features Support
  @Description:
    @@@:
      WikiFormBBS WikiPlugin module implements some features well-supported
      in Web BBS systems, such as "sage", "ID", and so on.
    @@lang: en
  @License: %%Perl%%
  @Author[list]:
     Wakaba <w@suika.fam.cx>
  @Date.RCS:
    $Date: 2004/03/29 03:00:52 $
  @RequiredModule[list]:
    Digest::MD5
  @RequiredPlugin[list]:
    WikiFormCore
  @Use:
    require Digest::MD5;
    my $WIKIRESOURCE;

PluginConst:
  @NS_XHTML1:
    http://www.w3.org/1999/xhtml
  @WIKIRESOURCE:
    {($WIKIRESOURCE ||= SuikaWiki::Plugin->module_package ('WikiResource'))}


FormattingRule:
  @Category[list]: form-template
  @Name: bbs--check-sage
  @Description:
    @@@:
      Check whether "sage" is in input and disable updating Last-Modified
      date-time feature if it is.
    @@lang: en
  @Parameter:
    @@Name: source
    @@Type: ID
    @@Default: "mail"
    @@Description:
      @@@@: Input field name
      @@@lang: en
  @After:
    my $name = $o->{wiki}->{input}->parameter
                                      ('wikiform__'.($p->{source} || 'mail'));
    if ($name =~ /sage/) {
      $o->{form}->{output}->{bbs__sage} = 1;
    }

FormattingRule:
  @Category[list]:
    form-template
  @Name: bbs--2ch-id
  @Description:
    @@@:
      This rule inserts 2ch style "ID" string.  Note that ID generating
      algorithm implemented by this rule is not exact same as one implemented
      by 2ch or other "ID" implementing BBSes.
    @@lang: en
  @Parameter:
    @@Name: name
    @@Type: string
    @@Default: (auto)
    @@Description:
      @@@@:
        Board name (aka bbskey).  If missing, defaulted to current WikiName.
      @@@lang: en
  @Parameter:
    @@Name: sage
    @@Type: ID
    @@Default: (none)
    @@Description:
      @@@@:
        WikiForm field name in which "sage" check is done.  If missing,
        hiding IDs by "sage" is not allowed.
      @@@lang: en 
  @After:
    if ($p->{sage}) {
      if ($o->{wiki}->{input}->parameter ('wikiform__'.$p->{sage}) =~ /sage/) {
        $p->{-result} .= '???';
        return;
      }
    }
    my $name = $p->{name} || $o->{wiki}->{var}->{page}
                               ->stringify (wiki => $o->{wiki});
    my @time = gmtime;
    my $rand = substr sprintf ('%02d%02d%04d%02d%02d%04d', @time[3,4,5,3,4,5]),
                      0, 16;
    my $host = $o->{wiki}->{input} ? 
               $o->{wiki}->{input}->meta_variable ('REMOTE_HOST') ||
               $o->{wiki}->{input}->meta_variable ('REMOTE_ADDR') :
               'unknown.invalid';
    my $md5 = new Digest::MD5;
    $md5->add (substr Digest::MD5::md5_hex ($host), -4);
    $md5->add ($name);
    $md5->add ($time[3]);
    $md5->add ($rand);
    $p->{-result} .= substr $md5->b64digest, 0, 8;

FormattingRule:
  @Category[list]:
    form-template
  @Name: bbs--2ch-trip
  @Description:
    @@@:
      Inserts 2ch style trip.  Note that algorithm generating trip
      is not exact same as that of 2ch.  Only basic latin alphabets
      should be used for compatibility.
    @@lang: en
  @Parameter:
    @@Name: source
    @@Type: ID
    @@Default: (required)
    @@Description:
      @@@@: WikiForm field in which trip key is inputed
      @@@lang: en
  @After:
    my $key = $o->{wiki}->{input}->parameter ('wikiform__'.$p->{source});
    $p->{-result} .= __FUNCPACK__->key2trip (key => $key);

FormattingRule:
  @Category[list]:
    form-template
  @Name: bbs--2ch-name
  @Description:
    @@@:
      Inserting "name" with SuikaWiki/0.9 emphasis and link,
      as well as 2ch style trip and fusianasan.
    @@lang: en
  @Parameter:
    @@Name: source
    @@Type: ID
    @@Default: "name"
    @@Description:
      @@@@: Input field name
      @@@lang: en
  @After:
    my $name = $o->{wiki}->{input}->parameter
                                      ('wikiform__'.($p->{source} || 'name'));

    my $trip;
    if ($name =~ s/\#(.*)$//g) {
      $trip = __FUNCPACK__->key2trip (key => $1);
    }

    if ($name =~ /fusianasan/) {
      my $host = $o->{wiki}->{input}->meta_variable ('REMOTE_HOST') ||
                 $o->{wiki}->{input}->meta_variable ('REMOTE_ADDR') ||
                 'unknown.invalid';
      $name =~ s/fusianasan/$host/g;
    }
    
    unless (length $name) {
      WHOLETREE:
      for (@{$o->{var}->{sw09__document_tree}->child_nodes}) {
        if ($_->node_type eq '#element' and $_->local_name eq 'head') {
          for (@{$_->child_nodes}) {
            if ($_->node_type eq '#element' and $_->local_name eq 'parameter') {
              if ($_->get_attribute_value ('name', default => '') eq
                  'default-name') {
                for (@{$_->child_nodes}) {
                  if ($_->node_type eq '#element' and
                      $_->local_name eq 'value') {
                    $name = $_->inner_text;
                    last WHOLETREE;
                  }
                }
                last WHOLETREE;
              }
            }
          }
        }
      }
    }
    unless (length $name) {
      $name = $WIKIRESOURCE->get (name => 'WikiForm:WikiComment:DefaultName',
                                  o => $o, wiki => $o->{wiki});
    }

 ## TODO: replace star and diamond
    if ($name =~ />>\d/ or $name =~ /^\d+$/) {
      $p->{-result} .= $name;
    } else {
      $p->{-result} .= "[[$name]]";
    }
    
    $p->{-result} .= ' #' . $trip if $trip;
    

Function:
  @Name: key2trip
  @Main:
    my (undef, %opt) = @_;
    my $salt = substr substr ($opt{key}, 1, 2) . 'H.', 0, 2;
    $salt =~ tr/:;<=>?\@[\\]^_`/ABCDEFGabcdefg/;
    $salt =~ s{[^./0-9A-Za-z]}{.}g;
    return substr crypt ($opt{key}, $salt), -10;


