package Template::Plugin::ASCIITable;
use base 'Template::Plugin';
use Text::ASCIITable;
use vars qw($VERSION $AUTOLOAD);
$VERSION='0.2';
sub new {
my ($class,$context,$params)=@_;
my $self=bless {hide=>{rowline=>1}},$class;
$self->handleParms(%$params) if $params;
return $self;
}
sub draw {
my ($self,@rest)=@_;
$self->handleParms(@rest) if @rest;
my $t=Text::ASCIITable->new({$self->_globals()});
$t->setCols($self->_colnames());
for my $c ($self->_colprops()) {
$t->alignCol($c->{name},$c->{align}) if $c->{align};
$t->alignColName($c->{name},$c->{nalign}) if $c->{nalign};
$t->setColWidth($c->{name},$c->{width},$c->{widen}) if ($c->{width}||-1)>0;
}
for my $r ($self->_rows()) {
$t->addRow($r)
}
my $ret=$t->draw($self->_style());
my ($l,$r)=$self->_squeeze();
$ret=~s/^.{$l}//mg if $l;
$ret=~s/.{$r}$//mg if $r;
$ret=~s/\n$//;
return $ret;
}
my %paramSubs=(
hide => \&hide,
show => \&show,
cols => \&cols,
errors => \&errors,
reporterrors => \&errors,
allow => \&allow,
deny => \&deny,
alignheadrow => \&alignHeadRow,
rows => \&rows,
style => \&style,
);
sub handleParms {
my ($self,%params)=@_;
for my $k (keys %params) {
if (exists $paramSubs{lc($k)}) {
$paramSubs{lc($k)}->($self,$params{$k});
} else {
_die("no such parameter $k");
}
}
return;
}
sub hide {
my ($self,@what)=@_;
if (@what==1 and ref($what[0]) eq 'ARRAY') {
@what=@{$what[0]};
}
@{$self->{hide}}{grep {m{(headrow)|((head|first|last|row)line)}} map {lc $_} @what}=();
return;
}
sub show {
my ($self,@what)=@_;
if (@what==1 and ref($what[0]) eq 'ARRAY') {
@what=@{$what[0]};
}
delete @{$self->{hide}}{grep {m{(head(row|line))|((first|last|row)line)}} map {lc $_} @what};
return;
}
sub errors {
my ($self,$val)=@_;
$self->{errors}=$val;
return;
}
sub allow {
my ($self,@what)=@_;
if (@what==1 and ref($what[0]) eq 'ARRAY') {
@what=@{$what[0]};
}
@{$self->{allow}}{grep {m{ansi|html}} map {lc $_} @what}=();
return;
}
sub deny {
my ($self,@what)=@_;
if (@what==1 and ref($what[0]) eq 'ARRAY') {
@what=@{$what[0]};
}
delete @{$self->{allow}}{grep {m{ansi|html}} map {lc $_} @what};
return;
}
sub alignHeadRow {
my ($self,$val)=@_;
$self->{headrow}=$val;
return;
}
sub _handleCols {
my ($self,@colspec)=@_;
if (@colspec==1 and ref($colspec[0]) eq 'ARRAY') {
@colspec=@{$colspec[0]};
}
my %colpos=();
my @cols=();
for (@colspec) {
if (ref $_) {
push @cols,{name=>$_->[0],
align=>$_->[1],
width=>$_->[2],
widen=>$_->[3],
nalign=>$_->[4],
};
$colpos{$_->[0]}=$#cols;
} else {
push @cols,{name=>$_};
$colpos{$_}=$#cols;
}
}
return (\@cols,\%colpos)
}
sub cols {
my $self=shift;
($self->{cols},$self->{colpos})=$self->_handleCols(@_);
return;
}
sub addCols {
my $self=shift;
my ($cols,$colpos)=$self->_handleCols(@_);
push @{$self->{cols}},@$cols;
@{$self->{colpos}}{keys %$colpos}=values %$colpos;
return;
}
sub rows {
my ($self,@rows)=@_;
if (@rows==1 and ref($rows[0]) eq 'ARRAY') {
@rows=@{$rows[0]};
}
$self->{rows}=[@rows];
return;
}
sub addRows {
my ($self,@row)=@_;
if (@row==1 and ref($row[0]) eq 'ARRAY') {
@row=@{$row[0]};
}
push @{$self->{rows}},[@row];
return;
}
my %styles=(
'default'=>
{lines=>undef,
globals=>{hide=>'rowline'},
},
'rest-simple'=>
{lines=>[
['<','>','=',' '],
['<','>',' '],
['<','>','=',' '],
['<','>',' '],
['<','>','=',' '],
['<','>','-',' '],
1,1,
],
globals=>{hide=>'rowline'},
},
'rest-grid'=>
{lines=>[
['+','+','-','+'],
['|','|','|'],
['+','+','=','+'],
['|','|','|'],
['+','+','-','+'],
['+','+','-','+'],
0,0,
],
globals=>{show=>'rowline'},
},
);
sub style {
my ($self,$style)=@_;
if (ref $style eq 'ARRAY') {
if (@$style==6) {
$self->{style}=[@$style,0,0]
} elsif (@$style==5) {
$self->{style}=[@$style,[],0,0]
} elsif (@$style==8) {
$self->{style}=[@$style]
} else {
_die('Wrong style specification')
}
} elsif (exists $styles{lc $style}) {
$self->{style}=$styles{lc $style}->{lines};
$self->handleParms(%{$styles{lc $style}->{globals}});
} else {
_die("No such style $style");
}
}
sub AUTOLOAD {
return if $AUTOLOAD=~/:?DESTROY$/;
if (exists $paramSubs{lc($AUTOLOAD)}) {
goto &{$paramSubs{lc($AUTOLOAD)}};
} else {
_die("no such method $AUTOLOAD")
}
}
sub _globals {
my ($self)=@_;
my @ret=();
push @ret,'hide_HeadRow',1 if exists $self->{hide}{headrow};
push @ret,'hide_HeadLine',1 if exists $self->{hide}{headline};
push @ret,'hide_FirstLine',1 if exists $self->{hide}{firstline};
push @ret,'hide_LastLine',1 if exists $self->{hide}{lastline};
push @ret,'allowANSI',1 if exists $self->{allow}{ansi};
push @ret,'allowHTML',1 if exists $self->{allow}{html};
push @ret,'reportErrors',$self->{errors} if $self->{errors};
push @ret,'alignHeadRow',$self->{headrow} if $self->{headrow};
push @ret,'drawRowLine',1 unless exists $self->{hide}{rowline};
return @ret;
}
sub _colprops {
my ($self)=@_;
return @{$self->{cols}};
}
sub _colnames {
my ($self)=@_;
return map {$_->{name}} @{$self->{cols}};
}
sub _rows {
my ($self)=@_;
return ($self->{rows}?@{$self->{rows}}:());
}
sub _style {
my ($self)=@_;
return ($self->{style}?@{$self->{style}}[0..5]:());
}
sub _squeeze {
my ($self)=@_;
return ($self->{style}?@{$self->{style}}[6,7]:(0,0));
}
sub _die {
die (Template::Exception->new('ASCIITable',$_[0]))
}