File Coverage

blib/lib/Indent/Word.pm
Criterion Covered Total %
statement 78 81 96.3
branch 25 28 89.2
condition 11 12 91.6
subroutine 11 11 100.0
pod 2 2 100.0
total 127 134 94.7


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