[Date Prev][Date Next][Thread Prev][Thread Next][Minivend by date
][Minivend by thread
]
[ic] Contribution extension to [table-organize]
Hello All,
I have added a little code to the [table-organize] usertag.
When columnize=1 is present, the resulting table will be layed out in
newspaper columns.
Hope you'll find the addition useful.
Ton Verhagen
UserTag table-organize Order cols
UserTag table-organize attrAlias columns cols
UserTag table-organize Interpolate
UserTag table-organize addAttr
UserTag table-organize hasEndTag
UserTag table-organize Documentation <<EOD
table-organize
usage: [table-organize <options>] [loop ....] <td> [loop-tags] </td>
[/loop] [/table-organize]
Takes an unorganized set of table cells and organizes them into rows
based on the number of columns; it will also break them into separate
tables.
If the number of cells are not on an even modulus of the number of
columns, then "filler" cells are pushed on.
Parameters:
cols (or columns)
Number of columns. This argument defaults to 2 if not present.
rows
Optional number of rows. Implies "table" parameter.
table
If present, will cause a surrounding <TABLE > </TABLE> pair with the
attributes specified in this option.
caption
Table <CAPTION> container text, if any. Can be an array.
td Attributes for table cells. Can be an array.
tr Attributes for table rows. Can be an array.
columnize
Will display cells in (newspaper) column order.
pretty
Adds newline and tab characters to provide some reasonable
indenting.
filler
Contents to place in empty cells put on as filler. Defaults to
` '.
limit
Maximum number of cells to use. Truncates extra cells silently.
The `tr', `td', and `caption' attributes can be specified with indexes;
if they are, then they will alternate according to the modulus.
The `td' option array size should probably always equal the number of
columns; if it is bigger, then trailing elements are ignored. If it is
smaller, no attribute is used.
For example, to produce a table that 1) alternates rows with background
colors `#EEEEEE' and `#FFFFFF', and 2) aligns the columns RIGHT CENTER
LEFT, do:
[table-organize
cols=3
pretty=1
tr.0='bgcolor="#EEEEEE"'
tr.1='bgcolor="#FFFFFF"'
td.0='align=right'
td.1='align=center'
td.2='align=left'
]
[loop list="1 2 3 1a 2a 3a 1b"] <td> [loop-code] </td> [/loop]
[/table-organize]
which will produce:
<tr bgcolor="#EEEEEE">
<td align=right>1</td>
<td align=center>2</td>
<td align=left>3</td>
</tr>
<tr bgcolor="#FFFFFF">
<td align=right>1a</td>
<td align=center>2a</td>
<td align=left>3a</td>
</tr>
<tr bgcolor="#EEEEEE">
<td align=right>1b</td>
<td align=center> </td>
<td align=left> </td>
</tr>
If the attribute columnize=1 is present, the result will look like:
<tr bgcolor="#EEEEEE">
<td align=right>1</td>
<td align=center>1a</td>
<td align=left>1b</td>
</tr>
<tr bgcolor="#FFFFFF">
<td align=right>2</td>
<td align=center>2a</td>
<td align=left> </td>
</tr>
<tr bgcolor="#EEEEEE">
<td align=right>3</td>
<td align=center>3a</td>
<td align=left> </td>
</tr>
See the source for more ideas on how to extend this tag.
EOD
UserTag table-organize Routine <<EOR
sub {
my ($cols, $opt, $body) = @_;
$cols = int($cols) || 2;
$body =~ s/(.*?)(<td)\b/$2/is;
my $out = $1;
$body =~ s:(</td>)(?!.*</td>)(.*):$1:is;
my $postamble = $2;
my @cells;
push @cells, $1 while $body =~ s:(<td\b.*?</td>)::is;
if(int($opt->{limit}) and $opt->{limit} < scalar(@cells) ) {
splice(@cells, $opt->{limit});
}
for(qw/ table/) {
$opt->{$_} = defined $opt->{$_} ? " $opt->{$_}" : '';
}
my @td;
if(! $opt->{td}) {
@td = '' x $cols;
}
elsif (ref $opt->{td} ) {
@td = @{$opt->{td}};
push @td, '' while scalar(@td) < $cols;
}
else {
@td = " $opt->{td}" x $cols;
}
my %attr;
for(qw/caption tr/) {
if( ! $opt->{$_} ) {
#do nothing
}
elsif (ref $opt->{$_}) {
$attr{$_} = $opt->{$_};
}
else {
$attr{$_} = [$opt->{$_}];
}
}
my $pretty = $opt->{pretty};
$opt->{td} =~ s/^(\S)/ $1/;
$opt->{tr} =~ s/^(\S)/ $1/;
my @rest;
my $rows;
my $rmod;
my $tmod = 0;
my $total_mod;
$opt->{filler} = ' ' if ! defined $opt->{filler};
if($rows = int($opt->{rows}) ) {
$total_mod = $rows * $cols;
@rest = splice(@cells, $total_mod)
if $total_mod < @cells;
$opt->{table} = ' ' if ! $opt->{table};
}
my $joiner = $pretty ? "\n\t\t" : "";
while(@cells) {
while (scalar(@cells) % $cols) {
push @cells, "<td>$opt->{filler}</td>";
}
if( $opt->{columnize}) {
my $nr_of_rows = scalar(@cells) / $cols;
my @tmp = splice(@cells,0);
my $index;
my $r = 0;
while ($r < $nr_of_rows) {
my $c = 0;
while ($c < $cols) {
$index = $r + $nr_of_rows * $c;
push @cells, $tmp[$index];
$c++;
}
$r++;
}
}
#$out .= "<!-- starting table tmod=$tmod -->";
if($opt->{table}) {
$out .= "<table$opt->{table}>";
$out .= "\n" if $pretty;
if($opt->{caption}) {
my $idx = $tmod % scalar(@{$attr{caption}});
#$out .= "<!-- caption index $idx -->";
$out .= "\n" if $pretty;
$out .= "<CAPTION>" . $attr{caption}[$idx] . "</CAPTION>";
$out .= "\n" if $pretty;
}
}
$rmod = 0;
while(@cells) {
$out .= "\t" if $pretty;
$out .= "<tr";
if($opt->{tr}) {
my $idx = $rmod % scalar(@{$attr{tr}});
$out .= " " . $attr{tr}[$idx];
}
$out .= ">";
$out .= "\n\t\t" if $pretty;
my @op = splice (@cells, 0, $cols);
if($opt->{td}) {
for ( my $i = 0; $i < $cols; $i++) {
$op[$i] =~ s/(<td)/$1 $td[$i]/i;
}
}
$out .= join($joiner, @op);
$out .= "\n\t" if $pretty;
$out .= "</tr>";
$out .= "\n" if $pretty;
$rmod++;
}
if($opt->{table}) {
$out .= "</table>";
$out .= "\n" if $pretty;
}
if(@rest) {
my $num = $total_mod < scalar(@rest) ? $total_mod : scalar(@rest);
@cells = splice(@rest, 0, $num);
}
$tmod++;
}
return $out . $postamble;
}
EOR