I recently had to split paragraphs across multiple columns. I didn't have long to do it but this solution works quite well so I present it to you ;). I knocked this together quickly so YMMV.
It takes a string of text and assumes paragraphs are on a dual carriage return boundary. It then places these into into columns.
If it helps, set DEBUG to one to see the data structure.
use HTML::Template;
use Data::Dumper;
use strict;
use warnings;
use constant DEBUG => 0;
my $parser = HTML::Template->new(
filehandle => *DATA,
die_on_bad_params => 0
);
my $columns = buildColumns(
2,
"one\n\ntwo\n\nthree\n\nfour\n\nfive\n\nsix\n\nseven\n\neight"
);
print Data::Dumper->Dump([$columns]) if DEBUG;
$parser->param(
'columns' => $columns
);
print $parser->output();
#
# Here you are.
#
sub buildColumns
{
my $nc = shift; # Number of columns
my @text = @_;
# Iterate over the text and split into a more granular array of pa
+ragraphs
my @paras;
foreach my $chunk (@text)
{
my @parts = split(/\n\n/,$chunk);
push @paras,@parts;
}
my $total = ++$#paras;
# Number of paras to go in column one:
my $num = 1;
if(($total % $nc) % 2 != 0)
{
$num = int($total/$nc) + ($total % $nc);
}
else
{
$num = ($total % $nc);
}
print "Number into column one is: ", $num, "\n\n" if DEBUG;
# Number to go into remainder
my $remainder = int($total / $nc);
print "Number into remaining columns is: ", $remainder, "\n\n" if
+DEBUG;
my @columns;
my $col = 0;
my $pushed = 1;
for(my $i = 0; $i < $total; $i++)
{
unless(defined($columns[$col]))
{
$columns[$col] = {};
$columns[$col]{'paras'} = [];
}
if($i >= $num)
{
# column two (or higher)
if($pushed > $remainder)
{
$col++;
print "We have moved to the next column: ", $col, " pu
+shed is: ", $pushed,"\n" if DEBUG;
$pushed = 1;
}
}
# push into the column
push @{$columns[$col]{'paras'}}, {'paragraph'=>$paras[$i]};
$pushed++;
print "We have pushed: ", $pushed, "\n" if DEBUG;
}
return \@columns;
}
__DATA__
<table>
<tr>
<TMPL_LOOP NAME="columns">
<td>
<TMPL_LOOP NAME="paras">
<p>
<TMPL_VAR NAME="paragraph">
<p>
</TMPL_LOOP>
</td>
</TMPL_LOOP>
</tr>
</table>