sub table { my ($tab,$opt) = @_; my @attributes; push @attributes, qq(id="$opt->{id}") if $opt->{id}; push @attributes, qq(class="$opt->{class}") if $opt->{class}; push @attributes, qq(style="$opt->{style}") if $opt->{style}; my $format = @attributes > 0 ? ' '.join(' ',@attributes) : ''; my $tag = 'table'.$format; line($tab,qq(<$tag>)); line($tab + 1,qq(
##
sub table {
my ($tab,$opt) = @_;
my @attributes;
push @attributes, qq(id="$opt->{id}") if $opt->{id};
push @attributes, qq(class="$opt->{class}") if $opt->{class};
push @attributes, qq(style="$opt->{style}") if $opt->{style};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $tag = 'table'.$format;
line($tab,qq(<$tag>));
line($tab + 1,qq($opt->{caption} )) if $opt->{caption};
row($tab + 1,'header',$opt->{headings}) if $opt->{headings};
for (@{$opt->{rows} || []}) {
row($tab + 1, $_->isa("MyRow::WithHead")?"whead":"data", $_);
}
line($tab,q());
}
sub data { bless \@_, "MyRow" }
sub whead { bless \@_, "MyRow::WithHead" }
table(1, {
id => 't1',
headings => [qw/NAME STRENGTH COMMENT/],
rows => [
whead(qw/1 2 no/),
data( qw/2 3 yes/),
whead(qw/10 20 another/),
data( qw/100 200 comment/),
],
});
####
sub table {
my ($tab,$opt) = @_;
my @attributes;
push @attributes, qq(id="$opt->{id}") if $opt->{id};
push @attributes, qq(class="$opt->{class}") if $opt->{class};
push @attributes, qq(style="$opt->{style}") if $opt->{style};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $tag = 'table'.$format;
line($tab,qq(<$tag>));
line($tab + 1,qq($opt->{caption} )) if $opt->{caption};
row($tab + 1,'header',$opt->{headings}) if $opt->{headings};
$_->output($tab+1) for @{$opt->{rows} || []};
line($tab,q());
}
{
package MyCell;
sub output {
my $self = shift;
my ($tab) = @_;
::line($tab, qq(@$self ));
}
}
{
package MyCell::Header;
use base "MyCell";
sub output {
my $self = shift;
my ($tab) = @_;
::line($tab, qq(@$self ));
}
}
{
package MyRow;
sub cells {
my $self = shift;
return map { bless [$_], "MyCell" } @$self;
}
sub output {
my $self = shift;
my ($tab) = @_;
::line($tab,qq());
$_->output($tab + 1) for $self->cells;
::line($tab,qq( ));
}
}
{
package MyRow::WithHead;
use base "MyRow";
sub cells {
my $self = shift;
my @cells = $self->SUPER::cells;
bless $cells[0], "MyCell::Header";
return @cells;
}
}
sub data { bless \@_, "MyRow" }
sub whead { bless \@_, "MyRow::WithHead" }
table(1, {
id => 't1',
headings => [qw/NAME STRENGTH COMMENT/],
rows => [
whead(qw/1 2 no/),
data( qw/2 3 yes/),
whead(qw/10 20 another/),
data( qw/100 200 comment/),
],
});
####
use strict;
use warnings;
{
package MyElem;
sub _line {
shift;
my $t = shift;
print(("\t" x $t), @_, "\n");
}
}
{
package MyCell;
use base "MyElem";
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, qq(@$self ));
}
}
{
package MyCell::Header;
use base "MyCell";
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, qq(@$self ));
}
}
{
package MyRow;
use base "MyElem";
sub cells {
my $self = shift;
return map { bless [$_], "MyCell" } @$self;
}
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab,qq());
$_->output($tab + 1) for $self->cells;
$self->_line($tab,qq( ));
}
}
{
package MyRow::WithHead;
use base "MyRow";
sub cells {
my $self = shift;
my @cells = $self->SUPER::cells;
bless $cells[0], "MyCell::Header";
return @cells;
}
}
{
package MyRow::AllHeads;
use base "MyRow";
sub cells {
my $self = shift;
return map { bless [$_], "MyCell::Header" } @$self;
}
}
{
package MyTable;
use base "MyElem";
sub output {
my $self = shift;
my ($tab) = @_;
my @attributes;
push @attributes, qq(id="$self->{id}") if $self->{id};
push @attributes, qq(class="$self->{class}") if $self->{class};
push @attributes, qq(style="$self->{style}") if $self->{style};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $tag = 'table'.$format;
$self->_line($tab, qq(<$tag>));
$self->_line($tab + 1,qq($self->{caption} )) if $self->{caption};
$self->{headings}->output($tab+1) if $self->{headings};
$_->output($tab+1) for @{$self->{rows} || []};
$self->_line($tab,q());
}
}
sub data { bless \@_, "MyRow" }
sub whead { bless \@_, "MyRow::WithHead" }
sub headings { bless \@_, "MyRow::AllHeads" }
sub table { bless {@_}, "MyTable" }
my $table = table(
id => 't1',
headings => headings(qw/NAME STRENGTH COMMENT/),
rows => [
whead(qw/1 2 no/),
data (qw/2 3 yes/),
whead(qw/10 20 another/),
data (qw/100 200 comment/),
],
);
$table->output(1);
####
use strict;
use warnings;
{
package MyElem;
sub new {
my $class = shift;
my %opts = @_;
my $self = bless \%opts, $class;
$self->_init;
return $self;
}
sub _init {
my $self = shift;
}
sub _tagname {
shift;
return "span";
}
sub id { shift->{id} }
sub class { shift->{class} }
sub style { shift->{style} }
sub title { shift->{title} }
sub _start_tag {
my $self = shift;
my $tag =
join " ", $self->_tagname,
map { sprintf '%s="%s"', $_, $self->$_ }
grep { defined $self->$_ }
qw(id class style title);
return "<$tag>";
}
sub _end_tag {
my $self = shift;
my $tag = $self->_tagname;
return "$tag>";
}
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, $self->_start_tag, $self->value, $self->_end_tag);
}
sub _line {
shift;
my $t = shift;
print(("\t" x $t), @_, "\n");
}
}
{
package MyCell;
use base "MyElem";
sub value {
shift->{value};
}
sub _tagname {
return "td";
}
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, $self->_start_tag, $self->value, $self->_end_tag);
}
}
{
package MyCell::Header;
use base "MyCell";
sub _tagname {
return "th";
}
}
{
package MyRow;
use base "MyElem";
use Scalar::Util qw(blessed);
sub _init {
my $self = shift;
@{$self->{cells}} = map {
blessed($_) ? $_ : "MyCell"->new(value => $_)
} @{$self->{cells}||[]};
$self->SUPER::_init;
}
sub cells {
@{shift->{cells}};
}
sub _tagname {
return "tr";
}
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, $self->_start_tag);
$_->output($tab + 1) for $self->cells;
$self->_line($tab, $self->_end_tag);
}
}
{
package MyRow::WithHead;
use base "MyRow";
use Scalar::Util qw(blessed);
sub _init {
my $self = shift;
$self->{cells}[0] = "MyCell::Header"->new(value => $self->{cells}[0])
unless blessed($self->{cells}[0]);
$self->SUPER::_init;
}
}
{
package MyRow::AllHeads;
use base "MyRow";
use Scalar::Util qw(blessed);
sub _init {
my $self = shift;
@{$self->{cells}} = map {
blessed($_) ? $_ : "MyCell::Header"->new(value => $_)
} @{$self->{cells}||[]};
$self->SUPER::_init;
}
}
{
package MyTable;
use base "MyElem";
use Scalar::Util qw(blessed);
sub _init {
my $self = shift;
@{$self->{rows}} = map {
blessed($_) ? $_ : "MyRow"->new(cells => $_)
} @{$self->{rows}||[]};
$self->SUPER::_init;
}
sub rows {
@{shift->{rows}};
}
sub _tagname {
return "table";
}
sub output {
my $self = shift;
my ($tab) = @_;
$self->_line($tab, $self->_start_tag);
$self->_line($tab + 1,qq($self->{caption} )) if $self->{caption};
$_->output($tab+1) for $self->rows;
$self->_line($tab, $self->_end_tag);
}
}
sub data { my @args = @_; "MyRow"->new(cells => \@args) }
sub whead { my @args = @_; "MyRow::WithHead"->new(cells => \@args) }
sub headings { my @args = @_; "MyRow::AllHeads"->new(cells => \@args) }
my $table = "MyTable"->new(
id => 't1',
rows => [
headings (qw/NAME STRENGTH COMMENT/),
whead (qw/1 2 no/),
data (qw/2 3 yes/),
whead (qw/10 20 another/),
data (qw/100 200 comment/),
data (1000, "MyCell"->new(value => 2000, style=>"color:red"), "again"),
],
);
$table->output(1);