File Coverage

blib/lib/Text/BlockLayout.pm
Criterion Covered Total %
statement 43 43 100.0
branch 2 2 100.0
condition 7 9 77.7
subroutine 10 10 100.0
pod 1 3 33.3
total 63 67 94.0


line stmt bran cond sub pod time code
1             package Text::BlockLayout;
2              
3 1     1   18355 use 5.010;
  1         3  
  1         32  
4 1     1   4 use strict;
  1         2  
  1         30  
5 1     1   4 use warnings;
  1         5  
  1         23  
6 1     1   654 use utf8;
  1         8  
  1         4  
7 1     1   1370 use Text::Wrap ();
  1         2365  
  1         43  
8              
9             our $VERSION = '0.02';
10              
11 1     1   554 use Moo;
  1         12991  
  1         7  
12              
13             has max_width => (
14             is => 'rw',
15             required => 1,
16             );
17              
18             has line_continuation_threshold => (
19             is => 'rw',
20             default => sub { int(shift->max_width * 2 / 3 + 0.5) },
21             lazy => 1,
22             );
23             has separator => (
24             is => 'rw',
25             default => sub { ' ' },
26             );
27              
28             sub add_text {
29 5     5 0 1276 my ($self, @chunks) = @_;
30              
31 5         11 push @{$self->{chunks}}, map [0, $_], @chunks;
  5         18  
32 5         10 $self;
33             }
34              
35             sub add_line {
36 3     3 0 37 my ($self, @chunks) = @_;
37              
38 3         4 push @{$self->{chunks}}, map [1, $_], @chunks;
  3         9  
39 3         6 $self;
40             }
41              
42             sub formatted {
43 4     4 1 14 my $self = shift;
44              
45 4         5 my @lines;
46 4         4 my $last_line_separate = 0;
47 4         3 for my $chunk ( @{ $self->{chunks} }) {
  4         10  
48 8         12 my ($separate_line, $text) = @$chunk;
49 8   100     38 my $start_new_line = $last_line_separate || $separate_line || !@lines;
50 8   66     18 $start_new_line ||= length($lines[-1]) > $self->line_continuation_threshold;
51 8   66     22 $start_new_line ||= (length($lines[-1]) + length($self->separator) + length $text) > $self->max_width;
52 8 100       11 if ($start_new_line) {
53 7         15 push @lines, $self->_wrap($text);
54             }
55             else {
56 1         3 $lines[-1] .= $self->separator . $text;
57             }
58 8         841 $last_line_separate = $separate_line;
59             }
60 4         22 return join "\n", @lines, '';
61             }
62              
63             sub _wrap {
64 7     7   8 my ($self, $text) = @_;
65             # it seems Text::Wrap includes the final newline, so +1
66 7         24 local $Text::Wrap::columns = 1 + $self->max_width;
67 7         17 return split /\n/, Text::Wrap::wrap('', '', $text);
68             }
69              
70             1;
71              
72             __END__