File Coverage

blib/lib/Text/Elide.pm
Criterion Covered Total %
statement 21 41 51.2
branch 0 18 0.0
condition 0 6 0.0
subroutine 7 8 87.5
pod 1 1 100.0
total 29 74 39.1


line stmt bran cond sub pod time code
1             package Text::Elide;
2              
3 1     1   26018 use version; $VERSION = qv('0.0.3');
  1         3024  
  1         6  
4              
5 1     1   75 use warnings;
  1         2  
  1         30  
6 1     1   5 use strict;
  1         6  
  1         25  
7 1     1   5 use Carp;
  1         2  
  1         118  
8              
9 1     1   4 use base qw( Exporter );
  1         2  
  1         143  
10             our @EXPORT_OK = qw( elide );
11              
12             # use Smart::Comments;
13 1     1   1023 use Readonly;
  1         3365  
  1         54  
14 1     1   6 use List::Util qw( min );
  1         2  
  1         441  
15              
16             Readonly my $default_elipsis => " ...";
17              
18             # Module implementation here
19              
20             sub elide
21             {
22 0 0   0 1   defined( my $string = shift ) || die "no string argument\n";
23 0 0         defined( my $length = shift ) || die "no length argument\n";
24 0 0         croak "length must be a positive integer\n" unless $length > 0;
25 0   0       my $elipsis = shift || $default_elipsis;
26             # trivial case where string is already less than length
27 0 0         return $string if length( $string ) <= $length;
28             ### require: length( $string ) > $length
29             # to check if we have broken in the middle of a word ...
30 0   0       my $broken_word =
31             substr( $string, $length-1, 1 ) =~ /\S/ &&
32             substr( $string, $length, 1 ) =~ /\S/
33             ;
34             # crudely truncate ...
35 0           $string = substr( $string, 0, $length );
36             ### require: length( $string ) == $length
37             # strip trailing whitespace
38 0           $string =~ s/\s*$//;
39             ### require: $string =~ /\S$/
40             # return truncated string if only one word / part of word (no whitespace) -
41             # ( ... but possibly with leading whitespace)
42 0 0         return $string if $string =~ /^\s*\S+$/;
43             ### require: $string =~ /\S\s+\S/
44 0 0         croak "elipsis string ($elipsis) is longer than length ($length)\n"
45             if length( $elipsis ) > $length
46             ;
47             ### require: length( $elipsis ) <= $length
48 0 0         if ( $broken_word )
49             {
50             # remove partial word if crude truncation split mid-word
51 0           $string =~ s/\s+\S+$//;
52             ### require: $string =~ /\S$/
53             }
54             # if there is only one word ...
55 0 0         unless ( $string =~ /\S\s+\S/ )
56             {
57             # check if room for elipsis ...
58 0 0         if ( length( $string ) + length( $elipsis ) <= $length )
59             {
60 0           return $string . $elipsis;
61             }
62             # ... else return string without elipsis
63 0           return $string;
64             }
65             ### require: $string =~ /\s+\S+$/
66             # recursively remove "words" until there is room for the elipsis string
67 0           while ( length( $string ) + length( $elipsis ) > $length )
68             {
69             ### require: length( $string ) + length( $elipsis ) > $length
70             ### require: $string =~ /\s+\S+/
71 0           $string =~ s/\s+\S+$//;
72             ### require: length( $string ) > 0
73             }
74             ### require: length( $string ) + length( $elipsis ) <= $length
75 0           $string = $string . $elipsis;
76 0           return $string;
77             }
78              
79             1; # Magic true value required at end of module
80             __END__