File Coverage

blib/lib/Indent/Word.pm
Criterion Covered Total %
statement 82 85 96.4
branch 27 30 90.0
condition 11 12 91.6
subroutine 11 11 100.0
pod 2 2 100.0
total 133 140 95.0


line stmt bran cond sub pod time code
1             package Indent::Word;
2              
3 4     4   104158 use strict;
  4         6  
  4         107  
4 4     4   23 use warnings;
  4         6  
  4         165  
5              
6 4     4   1504 use Class::Utils qw(set_params);
  4         39906  
  4         74  
7 4     4   254 use English qw(-no_match_vars);
  4         9  
  4         17  
8 4     4   1033 use Error::Pure qw(err);
  4         9  
  4         157  
9 4     4   1485 use Indent::Utils qw(line_size_check);
  4         10  
  4         189  
10 4     4   17 use Readonly;
  4         5  
  4         3589  
11              
12             # Constants.
13             Readonly::Scalar my $EMPTY_STR => q{};
14             Readonly::Scalar my $LINE_SIZE => 79;
15              
16             our $VERSION = 0.11;
17              
18             # Constructor.
19             sub new {
20 16     16 1 457212 my ($class, @params) = @_;
21 16         29 my $self = bless {}, $class;
22              
23             # Use with ANSI sequences.
24 16         56 $self->{'ansi'} = undef;
25              
26             # Options.
27 16         27 $self->{'line_size'} = $LINE_SIZE;
28 16         22 $self->{'next_indent'} = "\t";
29              
30             # Output.
31 16         22 $self->{'output_separator'} = "\n";
32              
33             # Process params.
34 16         47 set_params($self, @params);
35              
36             # 'line_size' check.
37 14         237 line_size_check($self);
38              
39 14 100       22 if (! defined $self->{'ansi'}) {
40 1 50       4 if (exists $ENV{'NO_COLOR'}) {
    50          
41 0         0 $self->{'ansi'} = 0;
42             } elsif (defined $ENV{'COLOR'}) {
43 0         0 $self->{'ansi'} = 1;
44             } else {
45 1         2 $self->{'ansi'} = 0;
46             }
47             }
48              
49             # Check rutine for removing ANSI sequences.
50 14 100       28 if ($self->{'ansi'}) {
51 4         5 eval {
52 4         23 require Text::ANSI::Util;
53             };
54 4 50       7 if ($EVAL_ERROR) {
55 0         0 err "Cannot load 'Text::ANSI::Util' module.";
56             }
57             }
58              
59             # Object.
60 14         43 return $self;
61             }
62              
63             # Indent text by words to line_size block size.
64             sub indent {
65 16     16 1 2471 my ($self, $data, $indent, $non_indent) = @_;
66              
67             # 'indent' initialization.
68 16 100       26 if (! defined $indent) {
69 4         4 $indent = $EMPTY_STR;
70             }
71              
72             # If non_indent data, than return.
73 16 100       23 if ($non_indent) {
74 1         4 return $indent.$data;
75             }
76              
77             # Normalize whitespace: collapse all whitespace (including newlines) to single spaces.
78 15         78 $data =~ s/\s+/ /g;
79              
80             # Remove leading and trailing whitespace.
81 15         27 $data =~ s/^\s+//;
82 15         38 $data =~ s/\s+$//;
83              
84 15         31 my ($first, $second) = (undef, $indent.$data);
85 15         15 my $last_second_length = 0;
86 15         15 my @data;
87 15         14 my $one = 1;
88 15   100     25 while ($self->_length($second) >= $self->{'line_size'}
      100        
89             && $second =~ /^\s*\S+\s+/ms
90             && $last_second_length != $self->_length($second)) {
91              
92             # Last length of non-parsed part of data.
93 19         106 $last_second_length = $self->_length($second);
94              
95             # Parse to indent length.
96 19         100 ($first, my $tmp) = $self->_parse_to_indent_length($second);
97              
98             # If string is non-breakable in indent length, than parse to
99             # blank char.
100 19 100 100     43 if (! $first
      66        
101             || $self->_length($first) < $self->_length($indent)
102             || $first =~ /^$indent\s*$/ms) {
103              
104 10         517 ($first, $tmp) = $second
105             =~ /^($indent\s*[^\s]+?)\s(.*)$/msx;
106             }
107              
108             # If parsing is right.
109 19 100       99 if ($tmp) {
110              
111             # Non-parsed part of data.
112 15         17 $second = $tmp;
113              
114             # Add next_indent to string.
115 15 100       22 if ($one == 1) {
116 7         27 $indent .= $self->{'next_indent'};
117             }
118 15         16 $one = 0;
119 15         20 $second = $indent.$second;
120              
121             # Parsed part of data to @data array.
122 15         28 push @data, $first;
123             }
124             }
125              
126             # Add other data to @data array.
127 15         52 $second =~ s/\s+$//ms;
128 15 100       23 if ($second) {
129 14         17 push @data, $second;
130             }
131              
132             # Return as array or one line with output separator between its.
133 15 100       76 return wantarray ? @data : join($self->{'output_separator'}, @data);
134             }
135              
136             # Get length.
137             sub _length {
138 102     102   325 my ($self, $string) = @_;
139 102 100       121 if ($self->{'ansi'}) {
140 46         61 return length Text::ANSI::Util::ta_strip($string);
141             } else {
142 56         215 return length $string;
143             }
144             }
145              
146             # Parse to indent length.
147             sub _parse_to_indent_length {
148 19     19   21 my ($self, $string) = @_;
149 19         15 my @ret;
150 19 100       21 if ($self->{'ansi'}) {
151 9         13 my $string_wo_ansi = Text::ANSI::Util::ta_strip($string);
152              
153             # First part.
154 9         191 my ($first_wo_ansi) = $string_wo_ansi
155             =~ m/^(.{0,$self->{'line_size'}})\s+(.*)$/msx;
156 9 100       18 if (defined $first_wo_ansi) {
157 6         14 push @ret, Text::ANSI::Util::ta_trunc($string, length $first_wo_ansi);
158              
159             # Second part. (Remove first part + whitespace from string.)
160 6         1125 my $other_string_wo_ansi = Text::ANSI::Util::ta_strip(
161             Text::ANSI::Util::ta_substr($string, length $first_wo_ansi,
162             Text::ANSI::Util::ta_length($string))
163             );
164 6         1334 $other_string_wo_ansi =~ m/^(\s*)/ms;
165 6         12 my $count_of_spaces = length $1;
166 6         13 push @ret, Text::ANSI::Util::ta_substr($string, 0, (length $first_wo_ansi)
167             + $count_of_spaces, '');
168             }
169             } else {
170 10         129 @ret = $string =~ m/^(.{0,$self->{'line_size'}})\s+(.*)$/msx;
171             }
172 19         2013 return @ret;
173             }
174              
175             1;
176              
177             __END__