#!/usr/bin/perl use strict; use warnings; use List::Util qw/max sum/; $|++; # produces a layout of a table used in AxPoint # input: # $table_aref - reference to an array of arrays containing the elements # of the table # %options - additional (not compulsory) named parameters: # percent_size - reference to an array containg the size of the columns # of the table (in percent of the total width) # [ will be calculated if not given ] # indent - string to use as indent for the different levels of the layout # string will be used multiple times for deeper levels # # Assumptions: # - all rows of the table have the same length (amount of columns) # - if a percent_size array reference is given, the array has the same length # as a row of the table. # # if any of these assumptions is wrong, the routine returns an empty list # # normally returns an array of lines of the layouted table sub layout_table { my ($table_aref, %options) = @_; my @option_keys = qw/indent percent_size/; my ($indent, $percent_size_aref) = @options{@option_keys}; $indent = "\t" unless defined $indent; my $row_length = @{$table_aref->[0]}; for my $key (keys %options) { warn("Unrecognized option '$key' in 'layout_table'"), return unless grep { $key eq $_ } @option_keys; } if ($percent_size_aref) { # check length of percent_size return if @$percent_size_aref != $row_length; } else { # must calculate size of each column my @max_lengths = (0) x $row_length; for my $row (@$table_aref) { my $i = 0; @max_lengths = map { max($_, length $row->[$i++]) } @max_lengths; } my $total_length = sum(@max_lengths); $percent_size_aref = [ map sprintf('%5.2f', 100*$_/$total_length), @max_lengths ]; } my @result = ( '' ); for my $row (@$table_aref) { return if $row_length != @$row; # check that all rows have same no. columns push @result, $indent . ''; for (my $i = 0; $i<$row_length; $i++) { my $p_size = $percent_size_aref->[$i]; push @result, $indent x 2 . qq//; push @result, $indent x 3 . $row->[$i]; push @result, $indent x 2 . ""; } push @result, $indent . '' } push @result, '
'; return @result; } my @data; while () { push @data, [ split ]; } local $, = "\n"; print layout_table(\@data); print layout_table(\@data, percent_size => [50, 20, 20, 10] ); print layout_table(\@data, percent_size => [50, 20, 20, 10], indent => ' ' ); print layout_table(\@data, perdent_size => [0.5, 0.2, 0.2, 0.1]); __DATA__ year income expense rest 2000 10 9 1 2001 20 13 7