[ic] Contribution extension to [table-organize]

Ton Verhagen ton@verhagen.net
Sun, 26 Nov 2000 18:19:41 +0100


--=====================_24056170==_
Content-Type: text/plain; charset="us-ascii"; format=flowed

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 
--=====================_24056170==_
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.

	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
        `&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>

	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>&nbsp;</td>
            </tr>
            <tr bgcolor="#EEEEEE">
                    <td align=right>3</td>
                    <td align=center>3a</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>";
		}
		
		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


--=====================_24056170==_
Content-Type: text/plain; charset="us-ascii"; format=flowed


--=====================_24056170==_--