[ic] Possibly useful [table-organize]

Mike Heins mikeh@minivend.com
Wed, 22 Nov 2000 13:18:20 -0500


--M9NhX3UHpAaciwkO
Content-Type: text/plain; charset=us-ascii

While I was looking at the [PREFIX-alternate] stuff when writing the
Tips & Tricks about optimization, I thought it might be nice to be able
to do that without having to noodle it out every time. So I did the
attached UserTag.

Hope it helps.

-- 
Akopia, Inc., 131 Willow Lane, Floor 2, Oxford, OH  45056
phone +1.513.523.7621 fax 7501 <heins@akopia.com>

Friends don't let friends use Outlook. -- Bob Blaylock

--M9NhX3UHpAaciwkO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=to

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.

    pretty
        Adds newline and tab characters to provide some reasonable
        indenting.

    filler
        Contents to place in empty cells put on as filler. Defaults to
        `&nbsp;'.

    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>&nbsp;</td>
                    <td align=left>&nbsp;</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} = '&nbsp;' 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>";
		}

		#$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


--M9NhX3UHpAaciwkO--