package HNS::Hnf::Command;
# $Id: Command.pm,v 1.34 2001/08/14 21:55:38 MAKOPi 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 HNS::Diary::Template;
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','RT'];
$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(SelectTemplate($$template, %$template), $params);
}
################################################################
################################################################
# class for extension.
package HNS::Hnf::Command::ConvTemplate;
use HNS::Diary::Template;
use vars qw(@ISA);
use vars qw($BaseTemplate $NameTemplate $HrefTemplate
%BaseTemplate %NameTemplate %HrefTemplate); # HNS::Diary::Template
@ISA = qw(HNS::Diary::Template HNS::Hnf::Command);
sub AsHTML ($$$)
{
my ($self, $start, $params) = @_;
my $class = ref $self;
my $cmd_name = $self->{name};
# template
my $template = sprintf("%s::%sTemplate",
$class,
($start)?'':'End');
my $comment = ($start) ? "": "";
my $templ = new HNS::Template;
$params->{content} = $self->{arg_content};
$self->ExpandTempl($templ, $params);
for (1..3){
$params->{$_} = $self->{attr}->[$_];
}
return $templ->Expand(SelectTemplate($$template, %$template), $params);
}
package HNS::Hnf::Command::ConvUrl;
use HNS::Template;
use HNS::Diary::Template;
use vars qw (@ISA %Template);
use vars qw($BaseTemplate $NameTemplate $HrefTemplate
%BaseTemplate %NameTemplate %HrefTemplate); # HNS::Diary::Template
@ISA = qw(HNS::Diary::Template);
$HrefTemplate = "%base#%name";
$Template{mydiary} = "%href";
$Template{ISBN} = "http://www.bk1.co.jp/cgi-bin/srch/srch_result_book.cgi?idx=3&isbn=%param";
$Template{CD} = "http://www.hmv.co.jp/search/title.asp?category=CATALOGUENO&keyword=%param";
sub new($)
{
my $class = shift;
my $self = {};
bless $self, $class;
}
sub ConvUrl($;$)
{
my $self = shift;
my $attr = shift || \$self->{attr}->[1];
my $templ = new HNS::Template;
if ($$attr =~ /^#(\d{4})(\d{2})(\d{2})((\d+)(S(\d+))?)?$/ ||
$$attr =~ /^#\{(\d{4}),(\d+),(\d+)(,(\d+)(,(\d+))?)?\}$/ ||
$$attr =~ /^#{.*#(\d{4})(\d{2})(\d{2})((\d+)(S(\d+))?)?}$/) {
my ($new, $sub) = ($5, $7);
my $my_diary_params = { 'year' => $1,
'month' => sprintf("%02d", $2),
'day' => sprintf("%02d", $3),
'abc' => $3 < 11 ? 'a' : $3 < 21 ? 'b' : 'c',
'new' => $new,
'sub' => $sub};
my $tmp = new HNS::Hnf::Command::ConvUrl;
if (! $new) {
@ISA = qw(HNS::Diary);
} elsif (! $sub) {
@ISA = qw(HNS::Hnf::Command::New);
} else {
@ISA = qw(HNS::Hnf::Command::Sub);
}
$tmp->ExpandTempl($templ, $my_diary_params);
@ISA = qw(HNS::Hnf::Command);
$$attr = $templ->Expand(SelectTemplate($Template{mydiary},
%{$Template{mydiary}}),
$my_diary_params);
} elsif ($$attr =~ /^([\d\w-]+):/ && defined($Template{$1})) {
if (ref($Template{$1}) eq "CODE") {
$$attr = &{$Template{$1}}($');
} else {
$$attr = $templ->Expand(SelectTemplate($Template{$1},
%{$Template{$1}}),
{ param => $' });
}
}
}
################################################################
################################################################
# 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(%Template %ImgTemplate);
#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);
use vars qw($BaseTemplate $NameTemplate $HrefTemplate
%BaseTemplate %NameTemplate %HrefTemplate); # HNS::Diary::Template
@ISA = qw(HNS::Hnf::Command::ConvTemplate);
$IsBeginSection = 1;
$OmittableEnd = 1;
$CountName = 'new';
$AllowCommands = [$HNS::Hnf::Command::Entities{'Sub'},
$HNS::Hnf::Command::Entities{'Flow'}];
$NameTemplate = "%year%month%day%new";
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); use vars qw($BaseTemplate $NameTemplate $HrefTemplate %BaseTemplate %NameTemplate %HrefTemplate); # HNS::Diary::Template @ISA = qw(HNS::Hnf::Command::ConvTemplate HNS::Hnf::Command::Comment); $IsOneline = 0; $NameTemplate = "%year%month%day%{new}F%fn"; $Template = qq(*%fn); $HeaderTemplate = qq(\n); $FooterTemplate = qq(