table-organize — automatically organize table cells into rows or columns
Attribute | Pos. | Req. | Default | Description |
---|---|---|---|---|
cols | columns | Yes | 2 | Number of columns. | |
rows | Optional number of rows. Implies "table" parameter. | |||
columnize | Display cells in "newspaper" column order. (Rotate the table — instead of filling rows, fill columns). | |||
min_rows |
On small result sets, it can be ugly to build more than the necessary number
of columns.
This option will guarantee a minimum number of rows — columns will change
as numbers change. Formula: $num_cells % $opt->{min_rows} .
|
|||
cells | ||||
embed | Allows embedding other table elements within tables you want to organize. See more in the section called “DESCRIPTION” and examples. | |||
limit | Maximum number of cells to use. Truncates extra cells silently. | |||
table |
If specified, causes a surrounding HTML <table>
</table> to be generated with the specified attributes.
|
|||
caption |
Table <caption> container text, if any.
(Can be an array).
|
|||
tr | Attributes for table rows. (Can be an array). | |||
td | Attributes for table cells. (Can be an array). | |||
pretty | Adds newline and TAB characters to provide some reasonable indenting in the HTML source. | |||
filler |
(non-breaking space)
|
Content to automatically place in empty, "filler" cells. It could be important to provide at least minimal content in there since some browsers do not display empty cells. | ||
font |
Attributes for HTML <font> inside table cells, if any.
|
|||
joiner |
\n\t\t if pretty is
specified, none otherwise.
|
Element to use in joining cells. This is mostly used for visual layout in HTML source. | ||
interpolate | 1 | interpolate input? | ||
reparse | 1 | interpolate output? | ||
hide | 0 | Hide the tag return value? |
table-organize takes an bunch of table cells and organizes them into rows based on the specified number of columns.
If the number of cells is not on an even modulus of the number of columns, then "filler" cells will be included to keep table structure correct.
Attributes tr
, td
and
caption
can be specified as an array
(with indexes); if they are, they will alternate according to the modulus.
The td
array size should always equal the
number of columns; if it is bigger, then trailing elements are ignored. If
it is smaller, the attribute is ignored altogether.
If you will want to embed other tables inside the table you want to
organize, you'll run into an interesting problem; [table-organize]
won't know whether <td>s belong to the table you want to
arrange or to the "subtable" that should be left intact. To solve
this problem, we resort to differentiating them by lowercase
<td> and uppercase <TD>. See more in
the section called “EXAMPLES”.
Example: Advanced table-organize example
To produce a table that alternates between two row background colors and specifies custom alignment for the three columns, use:
<table> [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] </table>
(In the above example, [loop]
tag is used to produce example
data for the table cells.) The final result produced will
look like this:
<table> <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> <table>
If you also provide the columnize=1
attribute, the result
will be a "rotated" table:
<table> <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> </table>
Example: Embedding tables
To embed tables, make sure the table you want to organize uses
lowercase <td> and set attribute embed=lc
.
To invert the meaning and make uppercase <TD>s arranged
(ignoring lower- or mixed-case cells), set the
embed
attribute to any other true value
except lc
(embed=uc
will work well).
<table> [table-organize embed=lc] <td> <TABLE> <TR> <TD>something embedded</TD> </TR> </TABLE> </td> [/table-organize] </table>
or
<table> [table-organize embed=uc] <TD> <table> <tr> <td>something</td> </tr> </table> </TD> [/table-organize] </table>
Interchange 5.9.0:
Source: code/UserTag/table_organize.tag
Lines: 185
# Copyright 2002-2007 Interchange Development Group and others # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. See the LICENSE file for details. # # $Id: table_organize.tag,v 1.11 2007-11-05 20:15:27 docelic Exp $ 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 Version $Revision: 1.11 $ UserTag table-organize Routine <<EOR sub { my ($cols, $opt, $body) = @_; $cols = int($cols) || 2; $body =~ s/(.*?)(<td)\b/$2/is or return; my $out = $1; $body =~ s:(</td>)(?!.*</td>)(.*):$1:is; my $postamble = $2; my @cells; if($opt->{cells} and ref($opt->{cells}) eq 'ARRAY') { @cells = @{$opt->{cells}}; } elsif($opt->{embed}) { if($opt->{embed} eq 'lc') { push @cells, $1 while $body =~ s:(<td\b.*?</td>)::s; } else { push @cells, $1 while $body =~ s:(<TD\b.*?</TD>)::s; } } else { push @cells, $1 while $body =~ s:(<td\b.*?</td>)::is; } while ($opt->{min_rows} and ($opt->{min_rows} * ($cols - 1)) > scalar(@cells) ) { $cols--; last if $cols == 1; } 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 pre post/) { 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}; my $td_beg; my $td_end; if($opt->{font}) { $td_beg = qq{<FONT $opt->{font}>}; $td_end = qq{</FONT>}; } 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 = $opt->{joiner} || ($pretty ? "\n\t\t" : ""); while(@cells) { if ($opt->{columnize}) { my $cell_count = scalar @cells; my $row_count_ceil = POSIX::ceil($cell_count / $cols); my $row_count_floor = int($cell_count / $cols); my $remainder = $cell_count % $cols; my @tmp = splice(@cells, 0); my $index; for (my $r = 0; $r < $row_count_ceil; $r++) { for (my $c = 0; $c < $cols; $c++) { if ($c >= $remainder + 1) { $index = $r + $row_count_floor * $c + $remainder; } else { $index = $r + $row_count_ceil * $c; } push @cells, $tmp[$index]; last if $r + 1 == $row_count_ceil and $c + 1 == $remainder; } } } while (scalar(@cells) % $cols) { push @cells, "<td>$opt->{filler}</td>"; } #$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; } } @op = map { s/>/>$td_beg/; $_ } @op if $td_beg; @op = map { s/(<[^<]+)$/$td_end$1/; $_ } @op if $td_end; $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