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/), ], });