File Coverage

blib/lib/Text/WrapProp.pm
Criterion Covered Total %
statement 34 34 100.0
branch 9 10 90.0
condition 3 3 100.0
subroutine 3 3 100.0
pod 0 1 0.0
total 49 51 96.0


line stmt bran cond sub pod time code
1             package Text::WrapProp;
2              
3 1     1   168097 use strict;
  1         1  
  1         36  
4 1     1   4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         316  
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.04';
17              
18             1;
19              
20             sub wrap_prop {
21 1     1 0 36 my ($text, $width, $ref_width_table) = @_;
22              
23 1         2 my @width_table = @{$ref_width_table};
  1         19  
24              
25 1 50       5 return '' if $text eq '';
26              
27             # simplify whitespace, including newlines
28 1         17 $text =~ s/\s+/ /gs;
29              
30 1         3 my $cursor = 0; # width so far of line
31 1         1 my $c; # current character
32             my $out; # output buffer
33 1         2 my $nextline = '';
34              
35 1         2 my $i=0;
36              
37 1         2 my $ltext = length $text;
38              
39             # In 1998, regex scanning, but 50% slower than C-style char processing. eg. while ($text =~ /(.)/gcs) {
40             # In 2014, they're equally fast. See eg/NOTES.
41              
42 1         4 while ($i < $ltext) {
43             # pop off next character
44 314         257 $c = substr($text,$i++,1);
45            
46             # don't need leading spaces at start of line
47 314 100 100     503 next if $nextline eq '' and $c eq ' ';
48              
49             # see if character will fit on line - but don't include if too long
50 312 100       349 if ($cursor + $width_table[ord $c] <= $width) {
51             # another character fits
52 297         209 $nextline .= $c;
53 297         408 $cursor += $width_table[ord $c];
54             }
55             else {
56             # find where we can wrap by checking backwards for separator
57 15         14 my $j = length($nextline);
58 15         43 foreach (split '', reverse $nextline) { # find separator
59 123         79 $j--;
60 123 100       239 last if /( |:|;|,|\.|-|\(|\)|\/)/o; # separator characters
61             }
62              
63             # see if no separator found
64 15 100       29 if (!$j) { # no separator, so just truncate line right here
65 3         3 $i--; # rerun on $c
66 3         4 $out .= $nextline."\n";
67             }
68             #
69             else { # separator found, so break line at separator
70 12         11 $i -= length($nextline) - $j; # rerun characters after separator
71 12         18 $out .= substr($nextline, 0, $j+1)."\n";
72             }
73              
74 15         15 $nextline = '';
75 15         23 $cursor = 0;
76             }
77             }
78              
79 1         9 $out.$nextline;
80             }
81              
82             __END__