File Coverage

blib/lib/Text/VisualWidth/PP.pm
Criterion Covered Total %
statement 47 48 97.9
branch 13 14 92.8
condition n/a
subroutine 14 15 93.3
pod 0 9 0.0
total 74 86 86.0


line stmt bran cond sub pod time code
1             package Text::VisualWidth::PP;
2 9     9   1243281 use strict;
  9         25  
  9         412  
3 9     9   72 use warnings;
  9         51  
  9         656  
4 9     9   218 use 5.008001;
  9         35  
5 9     9   4721 use parent qw(Exporter);
  9         3281  
  9         87  
6             our $VERSION = '0.08';
7 9     9   4594 use Unicode::EastAsianWidth;
  9         10458  
  9         1377  
8              
9             our @EXPORT_OK = qw(vwidth vtrim);
10              
11             our $EastAsian = $Unicode::EastAsianWidth::EastAsian;
12              
13             if ($^V lt v5.32) {
14 9     9   70 no strict 'refs';
  9         22  
  9         5321  
15             *{"utf8::Is_Emoji_Modifier"} = sub { "1F3FB\t1F3FF\n" };
16             };
17              
18             sub Spacing {
19 55     55 0 135249 $_[0] . <
20             -utf8::Nonspacing_Mark
21             -utf8::Enclosing_Mark
22             -utf8::Default_Ignorable_Code_Point
23             -utf8::Is_Emoji_Modifier
24             END
25             }
26              
27             sub InVWPP1Fullwidth() {
28 15     15 0 86 Spacing
29             InEastAsianFullwidth() . InEastAsianWide() . InEastAsianAmbiguous()
30             }
31             sub InVWPP0Fullwidth() {
32 23     23 0 156 Spacing
33             InEastAsianFullwidth() . InEastAsianWide()
34             }
35             sub InVWPP1Halfwidth() {
36 3     3 0 20 Spacing
37             InEastAsianHalfwidth().
38             InEastAsianNarrow().
39             InEastAsianNeutral()
40             }
41             sub InVWPP0Halfwidth() {
42 14     14 0 88 Spacing
43             InEastAsianHalfwidth().
44             InEastAsianNarrow().
45             InEastAsianNeutral().
46             InEastAsianAmbiguous()
47             }
48              
49 6     6 0 239628 sub vwidth { width(@_) }
50 0     0 0 0 sub vtrim { trim(@_) }
51              
52             # E_Modifier not following E_Base has full-width visual representation
53             my $EM = $^V ge v5.28 ? '(?>(?
54             : '(?!)' ;
55             $EM = qr/$EM/; # to avoid error on v5.24
56              
57             sub width {
58 55     55 0 1516387 my $str = shift;
59              
60 55         105 my $ret = 0;
61 55 100       179 if ($EastAsian) {
62 3         318 while ($str =~ /((?:$EM|(?
63             |((?: (?
64 3 50       197 $ret += $1 ? length($1) * 2 : length($2)
65             }
66             } else {
67 52         3389 while ($str =~ /((?:$EM|(?
68             |((?: (?
69 51 100       2683 $ret += $1 ? length($1) * 2 : length($2)
70             }
71             }
72 55         430 $ret;
73             }
74              
75             sub trim {
76 24     24 0 1015 my ($str, $limit) = @_;
77              
78 24         47 my $cnt = 0;
79 24         81 my $ret = '';
80 24 100       118 my $fullwidth = $EastAsian ? qr/\p{InVWPP1Fullwidth}/ : qr/\p{InVWPP0Fullwidth}/;
81 24         198 while ($str =~ /\G(\X)/g) {
82 100         229 my $ch = $1;
83 100         173 my $w = do {
84 100 100       757 if ($ch =~ /\A$fullwidth\z/) {
    100          
85 17         30 2;
86             } elsif (length($ch) == 1) {
87 56         100 1;
88             } else {
89 27         71 width($ch);
90             }
91             };
92 100 100       216 if ($cnt+$w <= $limit) {
93 80         172 $ret .= $ch;
94 80         318 $cnt += $w;
95             } else {
96 20         116 last;
97             }
98             }
99 24         191 $ret;
100             }
101              
102             1;
103             __END__