http://www.perlmonks.org?node_id=626272

perlNinny has asked for the wisdom of the Perl Monks concerning the following question:

With your suggestions and my own peculiar madness, I was able to get most of what I wanted accomplished. Now then..
How would you make data display like text::table without using text::table? It seems I don't have it and it is a big deal to get something we don't already have.
In short, I need to display a table (no HTML) with print statements (or with whatever comes standard) like this:
TITLE DATA-A DATA-B DATA-C
How are you item1 item2 item3
item1a item2b item3c
I am fine item4 item5 item6
So, as you can see a title has at least 1 set of data but maybe more.

Da Ninny.
  • Comment on THANKS for the help...formatting followup

Replies are listed 'Best First'.
Re: THANKS for the help...formatting followup
by ikegami (Patriarch) on Jul 12, 2007 at 17:14 UTC

    It seems I don't have it and it is a big deal to get something we don't already have.

    Unless it is a big deal to install the .pl you are writting, you should have no problem also installing Text::Table. Given that Text::Table is a pure Perl module with only pure Perl dependancies, there's no difference between installing your script and installing Text::Table.

    But I wrote up an alternative anyway

    use strict; use warnings; use List::Util qw( max ); sub get_max_widths { my ($titles, $aoa) = @_; my @col_widths; foreach my $row ($titles, @$aoa) { foreach my $col_num (0..$#$row) { $col_widths[$col_num] = max( $col_widths[$col_num] || 0, length($row->[$col_num]) ); } } return \@col_widths; } sub get_formatter { my ($col_widths, $justs) = @_; if (@$col_widths > @$justs) { $justs = [ @$justs, 'L' x (@$col_widths - @$justs), ]; } my $fstr = join ' ', map { '%' . ($justs->[$_] eq 'L' ? '-' : '') . $col_widths->[$_] . 's' } 0..$#$col_widths; my $args = join ', ', map { ($justs->[$_] eq 'C' ? "center(\$_[$_], $col_widths->[$_])" : "\$_[$_]" ) } 0..$#$col_widths; return eval "sub { sprintf('$fstr', $args) }"; } sub center { my ($text, $size) = @_; $size -= length($text); return $text if $size <= 0; my $s_half = int($size / 2); my $b_half = int(($size+1) / 2); return (' ' x $s_half) . $text . (' ' x $b_half); } { my @titles = ( 'TITLE', 'DATA-A', 'DATA-B', 'DATA-C', ); # (L)eft, (R)ight or (C)enter my @title_justs = ('C') x @titles; my @justs = ('L') x @titles; my @data = ( [ 'How are you', 'item1', 'item2', 'item3' ], [ '', 'item1a', 'item2b', 'item3c' ], [ 'I am fine', 'item4', 'item5', 'item6' ], ); my $col_widths = get_max_widths(\@titles, \@data); my $title_formatter = get_formatter($col_widths, \@title_justs); my $row_formatter = get_formatter($col_widths, \@justs); print $title_formatter->(@titles), "\n"; print $row_formatter->(@$_), "\n" foreach @data; }
      GREAT. I shall enjoy studying this code! THANKS
Re: THANKS for the help...formatting followup
by Corion (Patriarch) on Jul 12, 2007 at 16:35 UTC

    Just paste the content of Text::Table and Text::Align into your script and you should be set. Alternatively, copy the two files in a private Perl library directory, say, ~/perl5-lib/Text and do use lib '~/perl5-lib/'; as the line after use strict; in your script.

    As a last resort, tell your system administrator to install the modules.