package HNS::Hnf::Command;
# $Id: Command.pm,v 1.29.2.1 2001/04/07 01:46:58 kenji Exp $
################################################################
=head1 NAME
HNS::Hnf::Command - hnf command class
=cut
use strict qw(vars subs);
use HNS::System;
use HNS::Template;
use SimpleDB::Hash;
use SimpleDB::Scalar;
use vars qw(%Entities);
use vars qw($Template $EndTemplate $NumAttr $IsOneline $AllowCommands
$CountName $OmittableEnd);
################################################################
# entity definition
# used in $AllowCommands
$Entities{'Link'} = ['LINK', 'RLINK', 'URL'];
$Entities{'Decoration'} = ['FONT', 'STRIKE', 'LSTRIKE', 'STRONG','SPAN'];
$Entities{'Image'} = ['IMG', 'LIMG', 'MARK'];
$Entities{'Replace'} = ['ALIAS'];
$Entities{'Comment'} = ['FN'];
$Entities{'Inline'} = [$Entities{'Link'}, $Entities{'Decoration'},
$Entities{'Image'}, $Entities{'Replace'},
$Entities{'Comment'}];
$Entities{'Cite'} = ['CITE', 'PRE','INCLUDE'];
$Entities{'List'} = ['UL', 'OL', 'DL'];
$Entities{'Block'} = [$Entities{'Cite'}, $Entities{'List'}, 'P', 'DIV'];
$Entities{'Flow'} = [$Entities{'Inline'}, $Entities{'Block'}];
$Entities{'New'} = ['NEW', 'LNEW', 'RLNEW'];
$Entities{'Sub'} = ['SUB', 'LSUB', 'RLSUB'];
sub new ($$)
{
my ($class, $name) = @_;
my $self = {name=>$name, # name of command
attr=>[], # array of attributes
arg_content=>undef, # content in argument
parent=>undef, # parent command
pos=>undef, # position which new command is inserted
content=>[]}; # content element(command or text)
bless $self, $class;
}
################################################################
=head2 $c->InsertCommand($elem);
insert new command at legal position
if $elem is not HNS::Hnf::Command object,
it's regarded as a command name, and insert new object
=cut
sub InsertCommand($$)
{
my ($self, $elem) = @_;
unless (ref $elem){
$elem = new HNS::Hnf::Command($elem);
}
my $pos = $self->{pos} || $self;
$pos->PushContent($elem);
$self->{pos} = $elem;
return $elem;
}
=head2 $c->PushContent(@lines);
push new command or plain text as content
=cut
sub PushContent($@)
{
my $self = shift;
for (@_){
if (ref $_){
$_->{parent} = $self;
# print "push parent:";
# print $_->{name}, "-";
# print $_->{parent}->{name} . "
";
}
push(@{$self->{content}}, $_);
}
}
=head2 $c->UnshiftContent(@lines);
@lines ¤ò unshift ¤¹¤ë
=cut
sub UnshiftContent($@)
{
my $self = shift;
for (@_){
if (ref $_){
$_->{parent} = $self;
}
unshift(@{$self->{content}}, $_);
}
}
=head2 $c->Traverse($callback);
traverse the tree-structure
=cut
sub Traverse
{
my ($self, $callback) = @_;
if (&$callback($self, 1)) {
for (@{$self->{content}}) {
if (ref $_) {
$_->Traverse($callback);
} else {
&$callback($_, 1);
}
}
&$callback($self, 0) unless $self->IsOneline;
}
$self;
}
################################################################
# access method to static variable of object class
sub get_static_variable ($$) # private
{
my ($self, $var_name) = @_;
my $full_var_name = (ref $self) . "::$var_name";
return $$full_var_name if defined $$full_var_name;
# if undefined the class, get from parent class
my $tmp = (ref $self) . "::ISA";
my @isa = @$tmp;
for my $class (@isa){
$full_var_name = "${class}::$var_name";
return $$full_var_name if defined $$full_var_name;
my $tmp = "${class}::ISA";
push(@isa, @$tmp);
}
return undef;
}
sub CountName ($)
{
return shift->get_static_variable('CountName');
}
sub OmittableEnd ($)
{
return shift->get_static_variable('OmittableEnd');
}
sub IsOneline ($)
{
return shift->get_static_variable('IsOneline');
}
sub IsBeginSection($)
{
return shift->get_static_variable('IsBeginSection');
}
# check $cmd_name is permitted as content of $self
sub allowed($$)
{
my ($self, $cmd_name) = @_;
# print "
check allowed: $cmd_name: in " . ($self->{name}) . ": ";
my $AllowCommands = $self->get_static_variable('AllowCommands');
return 1 unless defined $AllowCommands;
my @tmp = @$AllowCommands;
for (@tmp){
if (ref $_){ # entity assc array
push(@tmp, @$_);
} elsif ($cmd_name eq $_){ # command type
return 1;
}
}
return 0; # not allowed $cmd_name in $self
}
################################################################
=head2 $c->AsHTML($start, $params);
translate to HTML
=cut
sub AsHTML ($$$)
{
my ($self, $start, $params) = @_;
# my ($year, $month, $day, $newCount, $subCount, $fnCount, $cat_img) = @$params;
# print "NC:$newCount\n";
my $class = ref $self;
my $cmd_name = $self->{name};
# print "$cmd_name($start)
";
# template
my $template = sprintf("%s::%sTemplate",
$class,
($start)?'':'End');
my $comment = ($start) ? "": "";
my $templ = new HNS::Template;
$params->{content} = $self->{arg_content};
for (1..3){
$params->{$_} = $self->{attr}->[$_];
}
return $templ->Expand($$template, $params);
}
################################################################
################################################################
# derived class from HNS::Hnf::Command
# top command (implicit);
package HNS::Hnf::Command::HNF;
use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands
$CountName $OmittableEnd);
@ISA = qw(HNS::Hnf::Command);
$OmittableEnd = 1;
$AllowCommands = ['CAT','GRP'];
################################################################
# body commands:
# (*) if you want to add new command, you must account it in
# $HNS::Hnf::[A-Z][a-z]+::entity
# static variable:
# $Template [str] begin template
# $EndTemplate [str] end templte
# $NumAttr [int] number of attributes
# $IsOneline [bool] no need end command
# $IsBeginSection [bool] beginning of section (Section)
# $AllowCommands [array]commands which can be element of self class
# $CountName [str] if countable, set name for use of counter variable
# $OmittableEnd [bool] ]is end-command omittable
################################################################
package HNS::Hnf::Command::CAT;
use vars qw(@ISA $Template $ImgTemplate $EndTemplate $NumAttr $IsOneline
$AllowCommands $CountName $OmittableEnd);
#use vars qw(%DB);
$Template = qq([%var]);
$ImgTemplate = qq(%img);
@ISA = qw(HNS::Hnf::Command);
$AllowCommands = [$HNS::Hnf::Command::Entities{'New'}];
sub AsHTML() {undef}
################################################################
package HNS::Hnf::Command::GRP;
use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands
$CountName $OmittableEnd $Mark);
#use vars qw(%DB);
$Template = "";
@ISA = qw(HNS::Hnf::Command);
$IsOneline = 1;
$AllowCommands = ['CAT',$HNS::Hnf::Command::Entities{'New'}];
$Mark = "*";
sub AsHTML() {undef}
################################################################
# New Entities
package HNS::Hnf::Command::New;;
use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands
$IsBeginSection $CountName $OmittableEnd);
@ISA = qw(HNS::Hnf::Command);
$IsBeginSection = 1;
$OmittableEnd = 1;
$CountName = 'new';
$AllowCommands = [$HNS::Hnf::Command::Entities{'Sub'},
$HNS::Hnf::Command::Entities{'Flow'}];
package HNS::Hnf::Command::NEW;
use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands
$IsBeginSection $CountName $OmittableEnd);
@ISA = qw(HNS::Hnf::Command::New);
$Template = q(
\n"; $EndTemplate = "
\n"; # DIV command package HNS::Hnf::Command::DIV; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $AllowCommands = [$HNS::Hnf::Command::Entities{'Inline'}]; $OmittableEnd = 1; # or 0 $NumAttr = 1; $Template = qq("; $EndTemplate = ""; # CITE package HNS::Hnf::Command::CITE; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd $TemplateWithURI); @ISA = qw(HNS::Hnf::Command::Cite); $NumAttr = 1; $Template = qq(
\n); $TemplateWithURI = qq(\n); $EndTemplate = "\n"; $AllowCommands = [$HNS::Hnf::Command::Entities{'Flow'}]; sub AsHTML ($$$){ my ($self, $start, $params) = @_; my $uri = $self->{attr}->[1]; if ($uri) { $Template = $TemplateWithURI; } return $self->SUPER::AsHTML($start, $params); } # INCLUDE package HNS::Hnf::Command::INCLUDE; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); use vars qw($file); @ISA = qw(HNS::Hnf::Command::Cite); $IsOneline = 1; $Template = qq(\n%content\n); $NumAttr = 1; sub AsHTML($$$) { my ($self, $start, $params) = @_; my $tmp; # restrict path of file $self->{attr}->[1] =~ s/\.\.\///g; $self->{attr}->[1] =~ s/\.\.\///g; if ($self->{attr}->[1] =~ /^\//) { $self->{attr}->[1] = $HNS::System::DiaryDir . $self->{attr}->[1]; } else { $self->{attr}->[1] = "$HNS::System::IncludeDir/$self->{attr}->[1]"; } if (! -f $self->{attr}->[1]) { return &HNS::Hnf::Warning::Message('NotFound', $self->{name}, undef, $self->{attr}->[1]); } else { tie $tmp, 'SimpleDB::Scalar', "$self->{attr}->[1]", 1; my $file = $tmp; $file =~ s/&/&/g; $file =~ s/</g; $file =~ s/>/>/g; $self->{arg_content} = $file; return $self->SUPER::AsHTML($start, $params); } } # List Commands package HNS::Hnf::Command::List; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $AllowCommands = ['LI']; # UL package HNS::Hnf::Command::UL; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::List); $Template = ""; $EndTemplate = "
"; # OL package HNS::Hnf::Command::OL; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::List); $Template = ""; $EndTemplate = "
"; # LI package HNS::Hnf::Command::LI; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $Template = q(%content ); $EndTemplate = " "; $OmittableEnd = 1; $AllowCommands = [$HNS::Hnf::Command::Entities{'Flow'}]; # DL package HNS::Hnf::Command::DL; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::List); $Template = "\n"; $EndTemplate = "
\n"; $AllowCommands = ['DT', 'DD']; # DT package HNS::Hnf::Command::DT; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $Template = "%content"; $EndTemplate = " \n"; $OmittableEnd = 1; $AllowCommands = [$HNS::Hnf::Command::Entities{'Inline'}]; # DD package HNS::Hnf::Command::DD; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $Template = "%content"; $EndTemplate = " \n"; $OmittableEnd = 1; $AllowCommands = [$HNS::Hnf::Command::Entities{'Flow'}]; # HR package HNS::Hnf::Command::HR; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Block); $IsOneline = 1; $Template = q(
\n); # Comment Commands package HNS::Hnf::Command::Comment; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); @ISA = qw(HNS::Hnf::Command::Inline); # FN package HNS::Hnf::Command::FN; use vars qw(@ISA $Template $EndTemplate $NumAttr $IsOneline $AllowCommands $IsBeginSection $CountName $OmittableEnd); use vars qw($HeaderTemplate $FooterTemplate $ContentTemplate); @ISA = qw(HNS::Hnf::Command::Comment); $IsOneline = 0; $Template = qq( *%fn); $HeaderTemplate = qq(\n); $FooterTemplate = qq(