| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Term::FormatColumns; |
|
2
|
|
|
|
|
|
|
# ABSTRACT: Format lists of data into columns across the terminal's width |
|
3
|
|
|
|
|
|
|
$Term::FormatColumns::VERSION = '0.006'; |
|
4
|
2
|
|
|
2
|
|
25111
|
use strict; |
|
|
2
|
|
|
|
|
13
|
|
|
|
2
|
|
|
|
|
95
|
|
|
5
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
133
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
2
|
|
|
|
|
15
|
use Sub::Exporter -setup => [ |
|
8
|
|
|
|
|
|
|
exports => ( |
|
9
|
|
|
|
|
|
|
qw/format_columns format_columns_for_fh format_columns_for_width/, |
|
10
|
|
|
|
|
|
|
), |
|
11
|
2
|
|
|
2
|
|
1260
|
]; |
|
|
2
|
|
|
|
|
24897
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
2
|
|
|
2
|
|
1759
|
use Term::ReadKey qw( GetTerminalSize ); |
|
|
2
|
|
|
|
|
6665
|
|
|
|
2
|
|
|
|
|
119
|
|
|
14
|
2
|
|
|
2
|
|
10
|
use List::Util qw( max ); |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
191
|
|
|
15
|
2
|
|
|
2
|
|
1359
|
use List::MoreUtils qw( part each_arrayref ); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use POSIX qw( ceil ); |
|
17
|
|
|
|
|
|
|
use Symbol qw(qualify_to_ref); |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Find the length of a string as displayed on the terminal, ignoring any ANSI |
|
20
|
|
|
|
|
|
|
# escape sequences. |
|
21
|
|
|
|
|
|
|
sub _term_length { |
|
22
|
|
|
|
|
|
|
my ( $str ) = @_; |
|
23
|
|
|
|
|
|
|
$str =~ s/\x1b\[[0-9;]+m//g; |
|
24
|
|
|
|
|
|
|
return length $str; |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub format_columns { |
|
29
|
|
|
|
|
|
|
return format_columns_for_fh( \*STDOUT, @_ ); |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub format_columns_for_fh(*@) { |
|
34
|
|
|
|
|
|
|
my $fh = qualify_to_ref( shift, caller ); |
|
35
|
|
|
|
|
|
|
my @data = @_; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# If we're not attached to a terminal, one column, seperated by newlines |
|
38
|
|
|
|
|
|
|
if ( !-t $fh ) { |
|
39
|
|
|
|
|
|
|
return join "\n", @data, ''; |
|
40
|
|
|
|
|
|
|
} |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# We're attached to a terminal, print column-wise alphabetically to fit the |
|
43
|
|
|
|
|
|
|
# terminal width |
|
44
|
|
|
|
|
|
|
my ( $term_width, undef, undef, undef ) = GetTerminalSize(); |
|
45
|
|
|
|
|
|
|
return format_columns_for_width( $term_width, @data ); |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub format_columns_for_width { |
|
50
|
|
|
|
|
|
|
my ( $term_width, @data ) = @_; |
|
51
|
|
|
|
|
|
|
my $max_width = max map { _term_length( $_ ) } @data; |
|
52
|
|
|
|
|
|
|
$max_width += 2; # make sure at least two spaces between data values |
|
53
|
|
|
|
|
|
|
my $columns = int( $term_width / $max_width ); |
|
54
|
|
|
|
|
|
|
if ( $columns <= 1 ) { |
|
55
|
|
|
|
|
|
|
# Only one column, let the terminal handle things |
|
56
|
|
|
|
|
|
|
return join "\n", @data, ''; # Add a \n to the end |
|
57
|
|
|
|
|
|
|
} |
|
58
|
|
|
|
|
|
|
my $output = ''; |
|
59
|
|
|
|
|
|
|
my $column_width = int( $term_width / $columns ); |
|
60
|
|
|
|
|
|
|
my $rows = ceil( @data / $columns ); |
|
61
|
|
|
|
|
|
|
push @data, ('') x ($rows * $columns - @data); # Pad data with empty strings |
|
62
|
|
|
|
|
|
|
my @index = part { int( $_ / $rows ) } 0..$#data; |
|
63
|
|
|
|
|
|
|
my $iter = each_arrayref @index; |
|
64
|
|
|
|
|
|
|
while ( my @row_vals = $iter->() ) { |
|
65
|
|
|
|
|
|
|
my @cells = map { $data[$_] } @row_vals; |
|
66
|
|
|
|
|
|
|
my $last_cell = pop @cells; |
|
67
|
|
|
|
|
|
|
for (@cells) { |
|
68
|
|
|
|
|
|
|
my $length = _term_length( $_ ); |
|
69
|
|
|
|
|
|
|
$output .= $_; |
|
70
|
|
|
|
|
|
|
$output .= ' ' x ($column_width - $length); |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
$output .= $last_cell . "\n"; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
return $output; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
1; |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
__END__ |