File Coverage

blib/lib/Text/BlockLayout.pm
Criterion Covered Total %
statement 39 39 100.0
branch 4 4 100.0
condition 10 12 83.3
subroutine 8 8 100.0
pod 1 3 33.3
total 62 66 93.9


line stmt bran cond sub pod time code
1             package Text::BlockLayout;
2              
3 1     1   16268 use 5.010;
  1         4  
  1         33  
4 1     1   3 use strict;
  1         2  
  1         27  
5 1     1   4 use warnings;
  1         5  
  1         38  
6 1     1   856 use utf8;
  1         8  
  1         4  
7              
8             our $VERSION = '0.03';
9              
10 1     1   563 use Moo;
  1         11843  
  1         5  
11              
12             has max_width => (
13             is => 'rw',
14             required => 1,
15             );
16              
17             has line_continuation_threshold => (
18             is => 'rw',
19             default => sub { int(shift->max_width * 2 / 3 + 0.5) },
20             lazy => 1,
21             );
22             has separator => (
23             is => 'rw',
24             default => sub { ' ' },
25             );
26              
27             has wrapper => (
28             is => 'rw',
29             lazy => 1,
30             default => sub {
31             return sub {
32             my ($max_width, $text) = @_;
33             require Text::Wrapper;
34             my $wrapper = Text::Wrapper->new(columns => $max_width);
35             $wrapper->wrap($text);
36             };
37             },
38             );
39              
40             has wrap_predefined_lines => (
41             is => 'rw',
42             default => sub { 1 },
43             );
44              
45             sub add_text {
46 5     5 0 41 my ($self, @chunks) = @_;
47              
48 5         6 push @{$self->{chunks}}, map [0, $_], @chunks;
  5         17  
49 5         8 $self;
50             }
51              
52             sub add_line {
53 4     4 0 28 my ($self, @chunks) = @_;
54              
55 4         4 push @{$self->{chunks}}, map [1, $_], @chunks;
  4         13  
56 4         6 $self;
57             }
58              
59             sub formatted {
60 5     5 1 15 my $self = shift;
61              
62 5         5 my @lines;
63 5         3 my $last_line_separate = 0;
64 5         4 for my $chunk ( @{ $self->{chunks} }) {
  5         11  
65 9         12 my ($separate_line, $text) = @$chunk;
66 9   100     41 my $start_new_line = $last_line_separate || $separate_line || !@lines;
67 9   66     18 $start_new_line ||= length($lines[-1]) > $self->line_continuation_threshold;
68 9   66     21 $start_new_line ||= (length($lines[-1]) + length($self->separator) + length $text) > $self->max_width;
69 9 100       13 if ($start_new_line) {
70 8 100 100     27 if (!$separate_line || $self->wrap_predefined_lines) {
71 7         126 push @lines, split /\n/, $self->wrapper->($self->max_width, $text);
72             }
73             else {
74 1         4 push @lines, split /\n/, $text;
75             }
76             }
77             else {
78 1         4 $lines[-1] .= $self->separator . $text;
79             }
80 9         446 $last_line_separate = $separate_line;
81             }
82 5         26 return join "\n", @lines, '';
83             }
84              
85              
86             1;
87              
88             __END__