package HTML::TableTiler ; $VERSION = 1.21 ; use strict ; # This file uses the "Perlish" coding style # please read http://perl.4pro.net/perlish_coding_style.html ; use 5.005 ; use Carp ; use HTML::PullParser 1.0 ; use IO::Util 1.2 ; require Exporter ; @HTML::TableTiler::ISA = qw| Exporter | ; @HTML::TableTiler::EXPORT_OK = qw| tile_table | ; BEGIN { *PULL = sub () { 'PULL' } ; *TILE = sub () { 'TILE' } ; *TRIM = sub () { 'TRIM' } ; *TRUE = sub () { 1 } ; *FALSE = sub () { 0 } ; *RESET = sub () { 0 } } ; sub new { my $c = shift ; my $t = shift || \ '
' ; $t = IO::Util::slurp($t) unless ref $t eq 'SCALAR' ; $$t or croak 'The tile content is empty' ; my $s = _parse_table($t) ; bless $s, $c } ; sub _parse_table { my ( $content ) = shift ; my ( $start , $Hrows , $end ) = $$content =~ m| ^ (.*?) # start ( ]*?> .* ) # Hrows (.*) # end $ |xsi ; my ( $p , $rows , $ignore ) ; $Hrows or croak 'The tile does not contain any "..." area' ; eval { local $SIG{__DIE__} ; $p = HTML::PullParser->new( doc => $Hrows , start => 'tag, text', , end => 'tag, text' ) } ; if ($@) { croak "Problem with the HTML parser: $@" } ; ( my $ri = my $di = my $td = my $in_tr = my $in_td = RESET ) ; my $err = sub { croak "Unespected HTML tag $_[0] found in the tile" } ; while ( my $tok = $p->get_token ) { my ( $tag, $text ) = @$tok ; if ( $tag eq 'tr' ) { ( not $in_tr and not $in_td ) or $err->($text) ; $$rows[$ri]{Srow} = $text ; $in_tr = TRUE } elsif ( $tag eq '/tr') { ( $in_tr and not $in_td) or $err->($text) ; $$rows[$ri++]{Erow} = $text ; $in_tr = FALSE ; $di = FALSE } elsif ( $tag eq 'td' ) { ($in_tr and not $in_td) or $err->($text) ; $$rows[$ri]{cells}[$di]{Scell} = $text ; $in_td = TRUE } elsif ( $tag eq '/td' ) { ($in_tr and $in_td) or $err->($text) ; $$rows[$ri]{cells}[$di++]{Ecell} .= $text ; $in_td = FALSE ; $td++ } elsif ( $tag !~ m|^/| ) { ($in_tr and $in_td) or $err->($text) ; $$rows[$ri]{cells}[$di]{Scell} .= $text if $in_td } elsif ( $tag =~ m|^/| ) { ( $in_tr and $in_td ) or $err->($text) ; $$rows[$ri]{cells}[$di]{Ecell} .= $text if $in_td } } ; $td or croak 'The tile does not contain any "..." area' ; return { start => $start , rows => $rows , end => $end } } ; sub is_matrix { my ($data_matrix) = shift # bi-dimensional array check ; foreach my $dr ( @$data_matrix ) { if ( ref $dr eq 'ARRAY' ) { foreach my $d ( @$dr ) { return 0 if ref $d } } else { return 0 } } ; return 1 } ; sub tile_table { my ( $s , $data_matrix , $tile , $mode , $checked ) ; if ( length(ref $_[0]) # blessed obj && eval { $_[0]->isa(ref $_[0]) } ) { ( $s, $data_matrix, $mode, $checked) = @_ } else { ( $data_matrix, $tile, $mode, $checked ) = @_ ; $s = __PACKAGE__->new($tile) ; undef $tile } ; $mode ||= 'H_PULL V_PULL' ; $checked || is_matrix($data_matrix) || croak 'Wrong data matrix content' # set Hmode and Vmode ; my $m = qr/(PULL|TILE|TRIM)/ ; my ($Hmode) = $mode =~ /\b H_ $m \b/x ; $Hmode ||= PULL ; my ($Vmode) = $mode =~ /\b V_ $m \b/x ; $Vmode ||= PULL # spread table ; my $out = "\n" ; ROW: for ( ( my $dmi = my $tmi = RESET ) ; $dmi <= $#$data_matrix ; ( $dmi ++ , $tmi ++ ) ) { if ( $tmi > $#{$s->{rows}} ) { if ( $Vmode eq PULL ) { $tmi = $#{$s->{rows}} } elsif ( $Vmode eq TILE ) { $tmi = RESET } elsif ( $Vmode eq TRIM ) { last ROW } } ; $out .= $s->{rows}[$tmi]{Srow} . "\n" ; my $data_cells = $$data_matrix[$dmi] ; my $html_cells = $$s{rows}[$tmi]{cells} ; CELL: for ( ( my $di = my $ti = RESET ) ; $di <= $#$data_cells ; ( $di ++ , $ti ++ ) ) { if ( $ti > $#$html_cells ) { if ( $Hmode eq PULL ) { $ti = $#$html_cells } elsif ( $Hmode eq TILE ) { $ti = RESET } elsif ( $Hmode eq TRIM ) { last CELL } } ; $out .= "\t" . $$html_cells[$ti]{Scell} . $$data_cells[$di] . $$html_cells[$ti]{Ecell} . "\n" } ; $out .= $$s{rows}[$tmi]{Erow} . "\n" } ; return $$s{start} . $out . $$s{end} } ; 1 __END__ =pod =head1 NAME HTML::TableTiler - easily generates complex graphic styled HTML tables =head1 VERSION 1.21 The latest versions changes are reported in the F file in this distribution. =head1 INSTALLATION =over =item Prerequisites HTML::PullParser >= 1.0 IO::Util >= 1.2 =item CPAN perl -MCPAN -e 'install HTML::TableTiler' =item Standard installation From the directory where this file is located, type: perl Makefile.PL make make test make install =back =head1 SYNOPSIS =over =item the tile
a optional placeholder another optional placeholder
=item the code $matrix=[ [ 'Balls', 'A470', 250, 2.75 ], [ 'Cubes', 'A520', 378, 3.25 ], [ 'Cones', 'A665', 186, 2.85 ] ]; Object-Oriented interface: use HTML::TableTiler; $tt = HTML::TableTiler->new(\$tile); print $tt->tile_table($matrix); Function-Oriented interface use HTML::TableTiler qw(tile_table); print tile_table($matrix, \$tile); =item the tiled table
Balls A470 250 2.75
Cubes A520 378 3.25
Cones A665 186 2.85
=back =head1 DESCRIPTION HTML::TableTiler uses a minimum HTML table as a tile to generate a complete HTML table from a bidimensional array of data. It can easily produce simple or complex graphic styled tables with minimum effort and maximum speed. Think about the table tile as a sort of tile that automatically expands itself to contain the whole data. You can control the final look of a table by choosing either the HORIZONTAL and the VERTICAL tiling mode among: PULL, TILE and TRIM. The main advantages to use it are: =over =item * automatic table generation Pass only a bidimensional array of data to generate a complete HTML table. No worry to decide in advance the quantity of cells (or rows) in the table. =item * complex graphic patterns generation without coding Just prepare a simple table tile in your preferred WYSIWYG HTML editor and let the module do the job for you. =item * simple to maintain You can indipendently change the table tile or the code, and everything will go as you would expect. =back =head1 HTML Examples Below this paragraph you should see several HTML examples. If you don't see any example, please take a look at the F file included in this distribution: an image is worth thousands of words (expecially with HTML)! =for html

All the examples use the code below:

common code for all the examples
01
02
03
04
05
06
07
08
09
10

$matrix=[
          [ 'Descr.', 'Item', 'Quant.','Cost', 'Price' ],
          [ 'Balls',  'A001', '101',   '2.75', '4.95'  ],
          [ 'Cubes',  'A002', '102',   '3.75', '5.95'  ],
          [ 'Cones',  'A003', '103',   '4.75', '6.75'  ],
          [ 'Tubes',  'A004', '104',   '5.75', '7.95'  ]
        ];

use HTML::TableTiler qw(tile_table);
print tile_table($matrix, $tile, $modes);

See tile and modes in each example to understand how both work in combination.
Placeholders are optional, but very useful to preview the final result.


Example #1

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile: undef (default: '<table><tr><td></td></tr></table>')

Modes: not allowed with default tile


Example #2

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder
placeholder

Modes: undef (default: H_PULL V_PULL)


Example #3

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder
placeholder

Modes: V_TILE (default: H_PULL)


Example #4

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder placeholder

Modes: undef (default: H_PULL V_PULL)


Example #5

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder placeholder

Modes: H_TILE (default: V_PULL)


Example #6

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder placeholder
placeholder placeholder

Modes: H_TILE V_TILE


Example #7

Descr. Item Quant. Cost Price
Balls A001 101 2.75 4.95
Cubes A002 102 3.75 5.95
Cones A003 103 4.75 6.75
Tubes A004 104 5.75 7.95

Tile:

placeholder placeholder
placeholder placeholder

Modes: undef (default: H_PULL V_PULL)

=head1 METHODS =over =item new ( [tile] ) The constructor method generate a HTML::TableTiler object. It accepts one optional I parameter that can be a reference to a SCALAR content, a path to a file or a filehandle. If you don't pass any I to the constructor method, a plain I will be used internally to generate a plain HTML table. A I must be a valid HTML chunk containing at least one " ... " area. See L<"HTML Examples"> or the F file in order to know more useful details about table tiles. Examples of constructors: $tt = HTML::TableTiler->new( \$tile_scalar ); $tt = HTML::TableTiler->new( '/path/to/table_tile_file' ); $tt = HTML::TableTiler->new( *TABLE_TILE_FILEHANDLER ); $tt = HTML::TableTiler->new(); # default \'
' =item is_matrix( array_reference ) This method checks if the passed I is a matrix (i.e. an array of arrays). It returns C<1> on success and C<0> on failure. It is called automatically by the C method unless you pass a true value as tird argument. =item tile_table ( matrix [, mode ] [, checked] ) This method generates a tiled table including the data contained in I. The I parameter must be a reference to a bidimensional array: $matrix=[ [ 'Balls', 'A470', '250', '2.75' ], [ 'Cubes', 'A520', '378', '3.25' ], [ 'Cones', 'A665', '186', '2.85' ] ]; The I parameter must be scalar containing one or two literal words representing ROW and COLUMN tiling mode. These are the accepted modes: =over =item H_PULL The grafic style of each rightmost CELL in the tile will be rightward replicated. This is the default HORIZONTAL tiling mode, so if you don't explicitly assign any other H_* mode, this mode will be used by default. =item H_TILE The grafic style of each ROW in the tile will be rightward replicated. =item H_TRIM The table ROW will be trimmed to the tile ROW, and the surplus data in I will be ignored. =item V_PULL The grafic style of each bottommost CELL in the tile will be downward replicated. This is the default VERTICAL tiling mode, so if you don't explicitly assign any other V_* mode, this mode will be used by default. =item V_TILE The grafic style of each COLUMN in the tile will be downward replicated. =item V_TRIM The table COLUMN will be trimmed to the tile COLUMN, and the surplus data in I will be ignored. =back Examples: $tt->TableTiler( \@matrix, "V_TRIM H_TILE" ); $tt->TableTiler( \@matrix, "V_TILE" ); # default "H_PULL" $tt->TableTiler( \@matrix ); # default "H_PULL V_PULL" Different combinations of I and I can easily produce complex tiled tables. (See L<"HTML Examples"> or the F file for details.) A true I argument avoid the C method to be internally called. =back =head1 FUNCTIONS =over =item tile_table ( matrix [, tile [, mode ]] ) If you prefer a function-oriented programming style, you can import or directly use the C function: use HTML::TableTiler qw( tile_table ); print tile_table( \@matrix, \$tile, "V_TILE" ); print tile_table( \@matrix ); # or use HTML::TableTiler; print HTML::TableTiler::tile_table( \@matrix, \$tile, "V_TILE" ); print HTML::TableTiler::tile_table( \@matrix); Note that you have to pass the I as the optional second parameter, and the I as the optional third parameter. (See method C for details). =back =head1 SEE ALSO L, that supplies an extended and transparent interface to this module. =head1 SUPPORT and FEEDBACK If you need support or if you want just to send me some feedback or request, please use this link: http://perl.4pro.net/?HTML::TableTiler. =head1 AUTHOR and COPYRIGHT © 2002-2004 by Domizio Demichelis. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as perl itself. =cut