File Coverage

blib/lib/Array/PrintCols/EastAsian.pm
Criterion Covered Total %
statement 114 116 98.2
branch 34 36 94.4
condition 13 15 86.6
subroutine 17 17 100.0
pod 3 3 100.0
total 181 187 96.7


line stmt bran cond sub pod time code
1             package Array::PrintCols::EastAsian;
2 8     8   275333 use 5.010;
  8         67  
  8         316  
3 8     8   46 use strict;
  8         16  
  8         327  
4 8     8   71 use warnings;
  8         19  
  8         239  
5 8     8   1066 use utf8;
  8         22  
  8         51  
6              
7 8     8   199 use Carp;
  8         12  
  8         734  
8 8     8   7336 use Encode;
  8         94580  
  8         787  
9 8     8   7301 use Data::Validator;
  8         313144  
  8         283  
10 8     8   14717 use Term::ReadKey;
  8         38560  
  8         789  
11 8     8   7398 use Text::VisualWidth::PP;
  8         225687  
  8         748  
12             $Text::VisualWidth::PP::EastAsian = 1;
13 8     8   165 use parent qw/ Exporter /;
  8         14  
  8         56  
14              
15             our $VERSION = '0.07';
16              
17             our @EXPORT = qw/ format_cols print_cols pretty_print_cols /;
18             our @EXPORT_OK = qw/ _max _min _validate _align /;
19              
20             sub _max {
21 19     19   65 my @array = @_;
22 19         83 my $max = shift @array;
23 19         41 foreach (@array) {
24 57 100       142 if ( $max < $_ ) { $max = $_; }
  11         18  
25             }
26 19         55 return $max;
27             }
28              
29             sub _min {
30 2     2   21 my @array = @_;
31 2         4 my $min = shift @array;
32 2         5 foreach (@array) {
33 10 100       26 if ( $min > $_ ) { $min = $_; }
  2         6  
34             }
35 2         14 return $min;
36             }
37              
38             sub _validate {
39 23     23   25974 my ( $array, $options ) = @_;
40 23 100       206 if ( !defined $options ) { $options = {}; }
  3         9  
41 23         186 state $rules = Data::Validator->new(
42             array => { isa => 'ArrayRef' },
43             gap => { isa => 'Int', default => 0 },
44             column => { isa => 'Int', optional => 1 },
45             width => { isa => 'Int', optional => 1 },
46             align => { isa => 'Str', default => 'left' },
47             encode => { isa => 'Str', default => 'utf-8' },
48             )->with('Sequenced');
49 23         35396 my $args = $rules->validate( $array, $options );
50 23 100       3074 if ( $args->{gap} < 0 ) { croak 'Gap option should be a integer greater than or equal 1.'; }
  1         32  
51 22 100 100     116 if ( exists $args->{column} && $args->{column} <= 0 ) { croak 'Column option should be a integer greater than 0.'; }
  2         28  
52 20 100 100     105 if ( exists $args->{width} && $args->{width} <= 0 ) { croak 'Width option should be a integer greater than 0.'; }
  2         24  
53 18 100       179 if ( !( $args->{align} =~ m/^(left|center|right)$/i ) ) {
54 1         14 croak 'Align option should be left, center, or right.';
55             }
56 17         206 return $args;
57             }
58              
59             sub _align {
60 14     14   5571 my $args = shift;
61 14         23 my @length = map { Text::VisualWidth::PP::width $_ } @{ $args->{array} };
  58         10693  
  14         58  
62 14         234 my $max_len = _max(@length);
63 14         97 my ( @formatted_array, $space );
64 14         28 for ( 0 .. $#{ $args->{array} } ) {
  14         48  
65 58         80 $space = $max_len - $length[$_];
66 58 100       220 if ( $args->{align} =~ m/^left$/i ) { push @formatted_array, $args->{array}->[$_] . q{ } x $space; }
  54         196  
67 58 100       1361 if ( $args->{align} =~ m/^right$/i ) { push @formatted_array, q{ } x $space . $args->{array}->[$_]; }
  2         9  
68 58 100       162 if ( $args->{align} =~ m/^center$/i ) {
69 2         5 my $half_space = int $space / 2;
70 2         12 push @formatted_array, q{ } x $half_space . $args->{array}->[$_] . q{ } x ( $space - $half_space );
71             }
72             }
73 14         64 return \@formatted_array;
74             }
75              
76             sub format_cols {
77 1     1 1 717 my ( $array, $options ) = @_;
78 1         7 my $args = _validate( $array, $options );
79 1         3 return _align($args);
80             }
81              
82             sub print_cols {
83 10     10 1 37520 my ( $array, $options ) = @_;
84 10         58 my $args = _validate( $array, $options );
85 10         36 my $formatted_array = _align($args);
86 10         27 my $gap = $args->{gap};
87 10         16 my $encode = $args->{encode};
88 10         14 my $column;
89 10 100       138 if ( exists $args->{column} ) { $column = $args->{column}; }
  2         4  
90 10 100       32 if ( exists $args->{width} ) {
91 4         14 my $element_width = Text::VisualWidth::PP::width $formatted_array->[0];
92 4         79 $column = _max( 1, int 1 + ( $args->{width} - $element_width ) / ( $element_width + $gap ) );
93 4 100       13 if ( exists $args->{column} ) { $column = _min( $args->{column}, $column ); }
  1         7  
94             }
95 10 100       27 if ( !$column ) { $column = $#{$formatted_array} + 1; }
  5         9  
  5         12  
96              
97 10         27 my ( $str, $encoded_str ) = q{};
98 10         14 for ( 0 .. $#{$formatted_array} ) {
  10         22  
99 50 100       95 if ( $_ % $column ) {
100 27         44 $str = $str . q{ } x $gap;
101             }
102             else {
103 23 100       47 if ($str) { $str = $str . "\n"; }
  13         20  
104             }
105 50         94 $str = $str . $formatted_array->[$_];
106             }
107 10         24 $str = $str . "\n";
108 10         70 $encoded_str = encode $encode, $str;
109 10         1125 print $encoded_str;
110 10         68 return;
111             }
112              
113             sub pretty_print_cols {
114 2     2 1 8057 my ( $array, $options ) = @_;
115 2   100     19 my $gap = $options->{gap} // 1;
116 2   100     23 my $align = $options->{align} // 'left';
117 2   100     9 my $encode = $options->{encode} // 'utf-8';
118 2         3 my $terminal_width;
119 2 50       11 if ( $^O =~ /Win32/i ) {
120 0         0 $terminal_width = ( GetTerminalSize )[0];
121             }
122             else {
123 2         12 $terminal_width = (GetTerminalSize)[0];
124             }
125 2 50 33     46841 if ( $terminal_width =~ /^\d+$/ && $terminal_width != 0 ) {
126 0         0 print_cols( $array, { 'gap' => $gap, 'width' => $terminal_width, 'align' => $align, 'encode' => $encode } );
127             }
128             else {
129 2         104 print_cols( $array, { 'gap' => $gap, 'align' => $align, 'encode' => $encode } );
130             }
131 2         41 return;
132             }
133              
134             1;
135             __END__