File Coverage

blib/lib/Indent/Block.pm
Criterion Covered Total %
statement 55 70 78.5
branch 14 22 63.6
condition 4 12 33.3
subroutine 8 8 100.0
pod 2 2 100.0
total 83 114 72.8


line stmt bran cond sub pod time code
1             package Indent::Block;
2              
3 4     4   178879 use strict;
  4         6  
  4         128  
4 4     4   28 use warnings;
  4         5  
  4         202  
5              
6 4     4   1880 use Class::Utils qw(set_params);
  4         53860  
  4         84  
7 4     4   2558 use Indent::Utils qw(line_size_check string_len);
  4         16  
  4         293  
8 4     4   27 use Readonly;
  4         8  
  4         3473  
9              
10             # Constants.
11             Readonly::Scalar my $EMPTY_STR => q{};
12             Readonly::Scalar my $LINE_SIZE => 79;
13              
14             our $VERSION = 0.09;
15              
16             # Constructor.
17             sub new {
18 5     5 1 700658 my ($class, @params) = @_;
19 5         18 my $self = bless {}, $class;
20              
21             # Line size.
22 5         21 $self->{'line_size'} = $LINE_SIZE;
23              
24             # Next indent.
25 5         30 $self->{'next_indent'} = "\t";
26              
27             # Output.
28 5         11 $self->{'output_separator'} = "\n";
29              
30             # Strict mode - without white space optimalization.
31 5         11 $self->{'strict'} = 1;
32              
33             # Process params.
34 5         28 set_params($self, @params);
35              
36             # 'line_size' check.
37 3         54 line_size_check($self);
38              
39             # Save current piece.
40 3         9 $self->{'_current'} = $EMPTY_STR;
41              
42             # Object.
43 3         19 return $self;
44             }
45              
46             # Parses tag to indented data.
47             sub indent {
48 5     5 1 3047 my ($self, $data_ar, $act_indent, $non_indent) = @_;
49              
50             # Undef indent.
51 5 100       16 if (! $act_indent) {
52 4         7 $act_indent = $EMPTY_STR;
53             }
54              
55             # Input data.
56 5         10 my @input = @{$data_ar};
  5         14  
57              
58             # If non_indent data, than return.
59 5 100       15 if ($non_indent) {
60 1         7 return $act_indent.join($EMPTY_STR, @input);
61             }
62              
63             # Indent.
64 4         8 my @data = ();
65 4         7 my ($first, $second);
66 4         9 $first = shift @input;
67 4         8 my $tmp_indent = $act_indent;
68 4         13 while (@input) {
69 4         6 $second = shift @input;
70 4 100       13 if ($self->_compare($first, $second, $tmp_indent)) {
71 2         5 push @data, $self->{'_current'};
72 2         5 $first = $second;
73 2         4 $second = $EMPTY_STR;
74 2         29 $tmp_indent = $act_indent.$self->{'next_indent'};
75             } else {
76 2         8 $first .= $second;
77             }
78             }
79              
80             # Add other data to @data array.
81 4 50       12 if ($first) {
82              
83             # White space optimalization.
84 4 50       13 if (! $self->{'strict'}) {
85 0         0 $first =~ s/^\s*//ms;
86 0         0 $first =~ s/\s*$//ms;
87             }
88 4 50       10 if ($first ne $EMPTY_STR) {
89 4         12 push @data, $tmp_indent.$first;
90             }
91             }
92              
93             # Return as array or one line with output separator between its.
94 4 100       23 return wantarray ? @data : join($self->{'output_separator'}, @data);
95             }
96              
97             # Compare strings with 'line_size' and save right current string.
98             sub _compare {
99 4     4   12 my ($self, $first, $second, $act_indent) = @_;
100              
101             # Without optimalization.
102 4 50       14 if ($self->{'strict'}) {
103 4 100 66     27 if (length $first > 0
      66        
104             && (string_len($act_indent.$first)
105             >= $self->{'line_size'}
106             || string_len($act_indent.$first.$second)
107             > $self->{'line_size'})) {
108              
109 2         6 $self->{'_current'} = $act_indent.$first;
110 2         7 return 1;
111             } else {
112 2         8 return 0;
113             }
114              
115             # With optimalizaton.
116             # TODO Rewrite.
117             } else {
118 0           my $tmp1 = $first;
119 0           $tmp1 =~ s/^\s*//ms;
120 0           $tmp1 =~ s/\s*$//ms;
121 0 0 0       if (length $tmp1 > 0
122             && string_len($act_indent.$tmp1)
123             >= $self->{'line_size'}) {
124              
125 0           $self->{'_current'} = $act_indent.$tmp1;
126 0           return 1;
127             } else {
128 0           my $tmp2 = $first.$second;
129 0           $tmp2 =~ s/^\s*//ms;
130 0           $tmp2 =~ s/\s*$//ms;
131 0 0 0       if (length $tmp1 > 0
132             && string_len($act_indent.$tmp2)
133             > $self->{'line_size'}) {
134              
135 0           $self->{'_current'} = $act_indent.$tmp1;
136 0           return 1;
137             } else {
138 0           return 0;
139             }
140             }
141             }
142             }
143              
144             1;
145              
146             __END__
147              
148             =pod
149              
150             =encoding utf8
151              
152             =head1 NAME
153              
154             Indent::Block - Class for block indenting.
155              
156             =head1 SYNOPSIS
157              
158             use Indent::Block;
159              
160             my $obj = Indent::Block->new(%parameters);
161             my $string = $obj->indent($data, [$act_indent, $non_indent]);
162             my @data = $obj->indent($data, [$act_indent, $non_indent]);
163              
164             =head1 METHODS
165              
166             =head2 C<new>
167              
168             my $obj = Indent::Block->new(%parameters);
169              
170             Constructor.
171              
172             Returns instance of object.
173              
174             =over 8
175              
176             =item * C<line_size>
177              
178             Sets indent line size value.
179             Default value is 'line_size' => 79.
180              
181             =item * C<next_indent>
182              
183             Sets next indent string.
184             Default value is 'next_indent' => "\t" (tabelator).
185              
186             =item * C<output_separator>
187              
188             Sets output separator between indented datas for string context.
189             Default value is 'output_separator' => "\n" (new line).
190              
191             =item * C<strict>
192              
193             Sets or unsets strict mode.
194             Unset strict mode means whitespace optimalization.
195             Default value is 'strict' => 1.
196              
197             =back
198              
199             =head2 C<indent>
200              
201             my $string = $obj->indent($data, [$act_indent, $non_indent]);
202              
203             or
204              
205             my @data = $obj->indent($data, [$act_indent, $non_indent]);
206              
207             Indent method.
208              
209             - C<$data_ar> - Reference to array with strings to indent.
210             - C<$act_indent> - String to actual indent.
211             - C<$non_indent> - Flag, that says 'no-indent' for current time.
212              
213             Returns string to print or array of data to print.
214              
215             =head1 ERRORS
216              
217             new():
218             From Class::Utils::set_params():
219             Unknown parameter '%s'.
220             From Indent::Utils::line_size_check():
221             'line_size' parameter must be a positive number.
222             line_size => %s
223              
224             =head1 EXAMPLE
225              
226             use strict;
227             use warnings;
228              
229             use Indent::Block;
230              
231             # Object.
232             my $i = Indent::Block->new(
233             'line_size' => 2,
234             'next_indent' => '',
235             );
236              
237             # Print in scalar context.
238             print $i->indent(['text', 'text', 'text'])."\n";
239              
240             # Output:
241             # text
242             # text
243             # text
244              
245             =head1 DEPENDENCIES
246              
247             L<Class::Utils>,
248             L<Indent::Utils>,
249             L<Readonly>.
250              
251             =head1 SEE ALSO
252              
253             =over
254              
255             =item L<Indent>
256              
257             Class for indent handling.
258              
259             =item L<Indent::Data>
260              
261             Class for data indenting.
262              
263             =item L<Indent::String>
264              
265             Class for text indenting.
266              
267             =item L<Indent::Utils>
268              
269             Utilities for Indent classes.
270              
271             =item L<Indent::Word>
272              
273             Class for word indenting.
274              
275             =back
276              
277             =head1 REPOSITORY
278              
279             L<https://github.com/michal-josef-spacek/Indent>
280              
281             =head1 AUTHOR
282              
283             Michal Josef Špaček L<mailto:skim@cpan.org>
284              
285             L<http://skim.cz>
286              
287             =head1 LICENSE AND COPYRIGHT
288              
289             © 2005-2024 Michal Josef Špaček
290              
291             BSD 2-Clause License
292              
293             =head1 VERSION
294              
295             0.09
296              
297             =cut