sub cell {
# $tab is a number.
# $type is either 'h' for heading or 'd' for data.
# $contents is the text in the cell.
# $opt is all of the available options to be adding inside the opening tag.
my ($tab,$type,$contents,$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};
push @attributes, qq(colspan="$opt->{colspan}") if $opt->{colspan};
push @attributes, qq(rowspan="$opt->{rowspan}") if $opt->{rowspan};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $open = $type.$format;
line($tab,qq());
# Lists are treated specially in cells. The list subroutine is below.
if ($contents =~ /list/i) {
if (ref($opt->{list}[1]) eq 'HASH') {
list($tab + 1,$opt->{list}->[0],$opt->{list}->[1]);
}
else {
list($tab + 1,$opt->{list});
}
}
else {
line($tab + 1,$contents);
}
line($tab,qq());
}
####
sub row {
# $tab is a number.
# $type is one of the keys from the %types table below.
# $cells is an array ref list of the cells in the row.
my ($tab,$type,$cells) = @_;
my %types = (
header => 'h',
data => 'd',
whead => 'd'
);
line($tab,qq());
# Rows which start with a header need to have the first cell
# shifted off to receive the th tag.
if ($type eq 'whead') {
my $cell = shift @{$cells};
cell($tab + 1,'h',ucfirst $cell, { class => 'row_header' });
}
# Most cells do not need anything special so the contents can be passed
# as $value, however if the cell needs formatting or other attributes,
# it can be passed as an array ref [$contents, { ... options ... }].
my $cell_type = $types{$type};
for my $cell (@{$cells}) {
if (ref($cell) eq 'ARRAY') {
cell($tab + 1,$cell_type,$cell->[0],$cell->[1]);
}
else {
cell($tab + 1,$cell_type,$cell);
}
}
line($tab,q(
));
}
####
sub table {
# $tab is again a number.
# Everything else is optional.
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>));
# If a caption is wanted set caption => "Caption"
line($tab + 1,qq($opt->{caption})) if $opt->{caption};
# Set headings to the same array ref as you would if you were setting the row.
row($tab + 1,'header',$opt->{headings}) if $opt->{headings};
# In most tables, the data rows would come next. For this array ref
# you would push all the array refs you would use for row above.
# (I hope that makes sense.)
if ($opt->{data}) {
row($tab + 1,'data',$_) for @{$opt->{data}};
}
# In most tables, there could be final rows which contain totals.
# For this array ref you would push all the array refs you would
# use for row above. Some tables have a header row and rows with
# their own headings.
# (I hope that makes sense.)
if ($opt->{whead}) {
row($tab + 1,'whead',$_) for @{$opt->{whead}};
}
line($tab,q());
}
####
sub list {
# And again, $tab is a number.
# $list is an array ref of values.
# $opt is the few available options for lists.
my ($tab,$list,$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 = 'ul'.$format;
line($tab,qq(<$tag>));
line($tab + 1,qq($_)) for @{$list};
line($tab,q());
}
####
sub col {
my ($tab,$opt) = @_;
my @attributes;
push @attributes, qq(class="$opt->{class}") if $opt->{class};
push @attributes, qq(span="$opt->{span}") if $opt->{span};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $tag = 'col'.$format;
line($tab,qq(<$tag>));
}
sub cols {
my ($tab,$cols) = @_;
col($tab,$_) for @{$cols};
}
####
sub sline {
my ($tab,$line) = @_;
return qq(\t) x $tab.qq($line\n);
}
sub line {
print sline(@_);
}
####
package Base::HTML::Elements;
use strict;
use warnings;
use base 'Exporter';
our @EXPORT_OK = qw(table cols col row cell list);
use Base::Nifty qw(line);
sub list {
my ($tab,$list,$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 = 'ul'.$format;
line($tab,qq(<$tag>));
line($tab + 1,qq($_)) for @{$list};
line($tab,q());
}
sub cell {
my ($tab,$type,$contents,$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};
push @attributes, qq(colspan="$opt->{colspan}") if $opt->{colspan};
push @attributes, qq(rowspan="$opt->{rowspan}") if $opt->{rowspan};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $open = $type.$format;
line($tab,qq());
if ($contents =~ /list/i) {
if (ref($opt->{list}[1]) eq 'HASH') {
list($tab + 1,$opt->{list}->[0],$opt->{list}->[1]);
}
else {
list($tab + 1,$opt->{list});
}
}
else {
line($tab + 1,$contents);
}
line($tab,qq());
}
sub row {
my ($tab,$type,$cells) = @_;
my %types = (
header => 'h',
data => 'd',
whead => 'd'
);
line($tab,qq());
if ($type eq 'whead') {
my $cell = shift @{$cells};
cell($tab + 1,'h',ucfirst $cell, { class => 'row_header' });
}
my $cell_type = $types{$type};
for my $cell (@{$cells}) {
if (ref($cell) eq 'ARRAY') {
cell($tab + 1,$cell_type,$cell->[0],$cell->[1]);
}
else {
cell($tab + 1,$cell_type,$cell);
}
}
line($tab,q(
));
}
sub col {
my ($tab,$opt) = @_;
my @attributes;
push @attributes, qq(class="$opt->{class}") if $opt->{class};
push @attributes, qq(span="$opt->{span}") if $opt->{span};
my $format = @attributes > 0 ? ' '.join(' ',@attributes) : '';
my $tag = 'col'.$format;
line($tab,qq(<$tag>));
}
sub cols {
my ($tab,$cols) = @_;
col($tab,$_) for @{$cols};
}
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};
if ($opt->{data}) {
row($tab + 1,'data',$_) for @{$opt->{data}};
}
if ($opt->{whead}) {
row($tab + 1,'whead',$_) for @{$opt->{whead}};
}
line($tab,q());
}
1;