File Coverage

blib/lib/Text/WrapProp.pm
Criterion Covered Total %
statement 40 40 100.0
branch 16 16 100.0
condition 12 12 100.0
subroutine 3 3 100.0
pod 0 1 0.0
total 71 72 98.6


line stmt bran cond sub pod time code
1             package Text::WrapProp;
2              
3 1     1   168137 use strict;
  1         2  
  1         37  
4 1     1   4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         1  
  1         363  
5              
6             require Exporter;
7              
8             @ISA = qw(Exporter AutoLoader);
9             # Items to export into callers namespace by default. Note: do not export
10             # names by default without a very good reason. Use EXPORT_OK instead.
11             # Do not simply export all your public functions/methods/constants.
12              
13             @EXPORT_OK = qw( wrap_prop );
14             @EXPORT = qw();
15              
16             $VERSION = '0.05';
17              
18             1;
19              
20             sub wrap_prop {
21 14     14 0 5318 my ($text, $width, $ref_width_table) = @_;
22              
23 14 100 100     113 if (not defined $text) {
    100 100        
    100 100        
    100          
24 1         4 return('', 1);
25             }
26 8         35 elsif (not defined $width or $width < 0.0000001) {
27 3         9 return('', 2);
28             }
29             elsif (not defined $ref_width_table or ref($ref_width_table) ne 'ARRAY' or scalar(@{$ref_width_table}) <= 1) {
30 3         8 return('', 3);
31             }
32             elsif ($text eq '') {
33 1         3 return('', 0);
34             }
35              
36 6         7 my @width_table = @{$ref_width_table};
  6         90  
37              
38             # simplify whitespace, including newlines
39 6         29 $text =~ s/\s+/ /gs;
40              
41 6         6 my $c; # current character
42 6         8 my $ltext = length $text;
43 6         6 my $cursor = 0; # width so far of line
44 6         7 my $out = ''; # output buffer
45 6         4 my $nextline = '';
46              
47 6         7 my $i=0;
48              
49 6         12 while ($i < $ltext) {
50             # pop off next character
51 443         379 $c = substr($text, $i++, 1);
52            
53             # don't need leading spaces at start of line
54 443 100 100     669 next if $nextline eq '' and $c eq ' ';
55              
56             # see if character will fit on line - but don't include if too long
57 442 100       550 if ($cursor + $width_table[ord $c] < $width + 0.0000001) {
58             # another character fits
59 423         282 $nextline .= $c;
60 423         604 $cursor += $width_table[ord $c];
61             }
62             else {
63             # find where we can wrap by checking backwards for separator
64 19         16 my $j = length($nextline);
65 19         70 for (split //, reverse $nextline) { # find separator
66 196         105 $j--;
67             # last if /( |:|;|,|\.|-|\(|\)|\/)/o; # separator characters
68 196 100       308 last if /[ :;,.()\\\/-]/; # separator characters
69             }
70              
71             # see if no separator found
72 19 100       39 if (!$j) { # no separator, so just truncate line right here
73 6         5 $i--; # rerun on $c
74 6         9 $out .= $nextline."\n";
75             }
76             #
77             else { # separator found, so break line at separator
78 13         14 $i -= length($nextline) - $j; # rerun characters after separator
79 13         19 $out .= substr($nextline, 0, $j+1)."\n";
80             }
81              
82 19         17 $nextline = '';
83 19         27 $cursor = 0;
84             }
85             # print "i=$i, ltext=$ltext, cursor=$cursor, out=$out\n\n";
86             }
87              
88 6         47 return($out.$nextline, 0);
89             }
90              
91             __END__