I am using the CPAN Text::Table module. I have a table in my script and some values are multi-line strings. I am also using a rule to print this table.
My code is as follows:
#!/usr/bin/perl5.14.1
use FindBin;
use lib "$FindBin::Bin/mylib/Text-Aligner-0.12/lib/";
use lib "$FindBin::Bin/mylib/Text-Table-1.130/lib/";
use Text::Table;
my $tb = Text::Table->new(\'| ', "", \' | ', "Field ", \'| ', "Length ", \'| ', "Comment ", \' |');
my @AoA = (
[ 1, "Foo", "20", "Foo" ],
[ 2, "Bar", "35", "Bar\nBar" ],
[ 3, "Tze", "10", "Tze\nTze" ],
);
$tb->load(@AoA);
my $rule = $tb->rule(qw/- /);
my @arr = $tb->body;
print $rule, $tb->title, $rule;
for (@arr) {
print $_ . $rule;
}
However when I run this I get the following:
|---|-------|--------|----------|
| | Field | Length | Comment |
|---|-------|--------|----------|
| 1 | Foo | 20 | Foo |
|---|-------|--------|----------|
| 2 | Bar | 35 | Bar |
|---|-------|--------|----------|
| | | | Bar |
|---|-------|--------|----------|
| 3 | Tze | 10 | Tze |
|---|-------|--------|----------|
| | | | Tze |
|---|-------|--------|----------|
Is there a way to not print separate lines in the case of multi-line strings?
I want to display my table as follows:
|---|-------|--------|----------|
| | Field | Length | Comment |
|---|-------|--------|----------|
| 1 | Foo | 20 | Foo |
|---|-------|--------|----------|
| 2 | Bar | 35 | Bar |
| | | | Bar |
|---|-------|--------|----------|
| 3 | Tze | 10 | Tze |
| | | | Tze |
|---|-------|--------|----------|
The Text::Table
code calls split( /\n/ )
on each row of your data and puts the results into their own rows. You can work around this by calculating which rows actually correspond to multi-line data and only printing a rule at the appropriate boundaries:
use strict;
use warnings;
use List::Util qw(max);
use Text::Table;
my $sep = \'|';
my @col_spec = ($sep, '', $sep, 'Field', $sep, 'Length', $sep, 'Comment', $sep);
my $tb = Text::Table->new(@col_spec);
my @data = (
[ 1, "Foo", "20", "Foo" ],
[ 2, "Bar\nBaz\nQux", "35", "Bar\nBar" ],
[ 3, "Tze", "10", "Tze\nTze" ]
);
# Track which rows should be preceded by rules. A key of 'n' indicates that a
# rule should be printed before the nth row (zero-indexed).
my %indexes = (
0 => 1, # Before header row
1 => 1 # After header row
);
# Calculate body rows for which rules should be printed
my $count = 1;
foreach my $row (@data) {
# Greatest number of newlines in row
my $newlines = max map { tr/\n// } @$row;
# One newline corresponds to two rows
$count += $newlines + 1;
$indexes{$count} = 1;
}
$tb->load(@data);
my $rule = $tb->rule('-', '+');
foreach my $i (0 .. $tb->height) {
print $rule if exists $indexes{$i};
print $tb->table($i);
}
+-+-----+------+-------+
| |Field|Length|Comment|
+-+-----+------+-------+
|1|Foo |20 |Foo |
+-+-----+------+-------+
|2|Bar |35 |Bar |
| |Baz | |Bar |
| |Qux | | |
+-+-----+------+-------+
|3|Tze |10 |Tze |
| | | |Tze |
+-+-----+------+-------+