File Coverage

blib/lib/Text/Fy/Utils.pm
Criterion Covered Total %
statement 58 58 100.0
branch 13 14 92.8
condition 2 2 100.0
subroutine 14 14 100.0
pod 0 6 0.0
total 87 94 92.5


line stmt bran cond sub pod time code
1             package Text::Fy::Utils;
2             $Text::Fy::Utils::VERSION = '0.10';
3 1     1   621 use 5.020;
  1         3  
  1         67  
4 1     1   4 use warnings;
  1         1  
  1         28  
5              
6 1     1   10 use Carp;
  1         1  
  1         58  
7 1     1   243725 use Unicode::Normalize;
  1         2667  
  1         91  
8 1     1   663 use Encode qw(encode decode);
  1         9430  
  1         870  
9              
10             require Exporter;
11             our @ISA = qw(Exporter);
12             our @EXPORT = qw();
13             our @EXPORT_OK = qw(asciify isoify simplify commify cv_to_win cv_from_win);
14              
15             my %cp1252_to_uni;
16              
17             for (128..159) {
18             $cp1252_to_uni{chr($_)} = decode('cp1252', chr($_));
19             }
20              
21             my %uni_to_ascii = (
22             "\x{20ac}" => q{E},
23             "\x{201a}" => q{,},
24             "\x{0192}" => q{f},
25             "\x{2026}" => q{_},
26             "\x{2020}" => q{+},
27             "\x{02c6}" => q{^},
28             "\x{2030}" => q{%},
29             # "\x{0160}" => q{S},
30             "\x{2039}" => q{<},
31             "\x{0152}" => q{O},
32             # "\x{017d}" => q{Z},
33             "\x{2022}" => q{.},
34             "\x{20dc}" => q{~},
35             # "\x{0161}" => q{s},
36             "\x{203a}" => q{>},
37             "\x{203a}" => q{>},
38             "\x{0153}" => q{o},
39             # "\x{017e}" => q{z},
40             # "\x{017e}" => q{Y},
41             "\x{0080}" => q{e},
42             "\x{0082}" => q{,},
43             "\x{0083}" => q{f},
44             "\x{0085}" => q{_},
45             "\x{0088}" => q{^},
46             "\x{0089}" => q{%},
47             "\x{008b}" => q{<},
48             "\x{008c}" => q{O},
49             "\x{0095}" => q{.},
50             "\x{0098}" => q{~},
51             "\x{0099}" => q{T},
52             "\x{009b}" => q{>},
53             "\x{009c}" => q{o},
54             "\x{00a1}" => q{!},
55             "\x{00a2}" => q{c},
56             "\x{00a3}" => q{L},
57             "\x{00a5}" => q{Y},
58             "\x{00a6}" => q{|},
59             "\x{00a9}" => q{C},
60             "\x{00aa}" => q{a},
61             "\x{00ae}" => q{R},
62             "\x{00b2}" => q{2},
63             "\x{00b3}" => q{3},
64             "\x{00b7}" => q{.},
65             "\x{00b9}" => q{1},
66             "\x{00ba}" => q{0},
67             "\x{00bf}" => q{?},
68             "\x{00c6}" => q{A},
69             "\x{00d7}" => q{x},
70             "\x{00d8}" => q{O},
71             "\x{00df}" => q{s},
72             "\x{00e6}" => q{a},
73             "\x{00f0}" => q{d},
74             "\x{00f8}" => q{o},
75             );
76              
77             my %uni_to_iso = (
78             "\x{201c}" => q{"},
79             "\x{201d}" => q{"},
80             "\x{201e}" => q{"},
81              
82             "\x{2018}" => q{'},
83             "\x{2019}" => q{'},
84              
85             "\x{2013}" => q{-},
86             "\x{2014}" => q{-},
87             );
88              
89             my %iso_to_ascii = (
90             "\x{008a}" => q{S},
91             "\x{008e}" => q{Z},
92             "\x{009a}" => q{s},
93             "\x{009e}" => q{z},
94             "\x{009f}" => q{Y},
95             "\x{00ba}" => q{o},
96              
97             "\x{0084}" => q{"},
98             "\x{0093}" => q{"},
99             "\x{0094}" => q{"},
100             "\x{00ab}" => q{"},
101             "\x{00bb}" => q{"},
102              
103             "\x{0091}" => q{'},
104             "\x{0092}" => q{'},
105             "\x{00b4}" => q{'},
106              
107             "\x{0096}" => q{-},
108             "\x{0097}" => q{-},
109             "\x{00ac}" => q{-},
110             "\x{00ad}" => q{-},
111             );
112              
113             my $convert_c2u = _make_tr(\%cp1252_to_uni);
114             my $convert_u2c = _make_tr(\%cp1252_to_uni, 'R');
115             my $convert_u2a = _make_tr(\%uni_to_ascii);
116             my $convert_u2i = _make_tr(\%uni_to_iso);
117             my $convert_i2a = _make_tr(\%iso_to_ascii);
118              
119             sub _make_tr {
120 5     5   10 my ($href, $rev) = @_;
121              
122 5         70 my $from = join '', map { sprintf '\x{%04x}', ord($_) } sort keys %$href;
  136         283  
123 5         68 my $to = join '', map { sprintf '\x{%04x}', ord($href->{$_}) } sort keys %$href;
  136         305  
124              
125 5 100       52 my $code = 'sub { $_[0] =~ '.($rev ? "tr/$to/$from/" : "tr/$from/$to/").'; }';
126              
127 5 50       423 eval $code or die "Can't compile >$code< because $@";
128             }
129              
130             sub asciify {
131 1     1 0 6 _aconvert($_[0], 0, 0);
132             }
133              
134             sub isoify {
135 1     1 0 5 _aconvert($_[0], 1, 0);
136             }
137              
138             sub simplify {
139 1     1 0 7 _aconvert($_[0], 2, 0);
140             }
141              
142             sub _aconvert {
143 9     9   679 my ($text, $loc_m, $loc_w) = @_;
144              
145 9         318 $convert_u2i->($text);
146              
147 9 100       28 if ($loc_w) { # windows cp1252
148 3         97 $convert_c2u->($text);
149             }
150              
151 9 100       25 if ($loc_m == 1) { # iso
152 1     1   521 $text = NFC($text) =~ s{\p{Diacriticals}}''xmsgr;
  1         8  
  1         11  
  3         89  
153              
154 3 100       10 if ($loc_w) { # windows cp1252
155 1         33 $convert_u2c->($text);
156             }
157              
158 3         27 $text =~ s{([^\x00-\xff])}{NFD($1)}xmsge;
  29         124  
159              
160 3         47 $text =~ s{\p{Diacriticals}}''xmsg;
161              
162 3         14 $text = encode('iso-8859-1', $text);
163             }
164             else { # pure or brutal
165 6         184 $convert_i2a->($text);
166 6 100       98 $convert_u2a->($text) if $loc_m == 2; # brutal
167              
168 6         210 $text = encode('iso-8859-1', NFD($text) =~ s{\p{Diacriticals}}''xmsgr);
169 6         228 $text =~ s{\P{ASCII}}'?'xmsg;
170             }
171              
172 9         141 return $text;
173             }
174              
175             sub cv_from_win {
176 1     1 0 3 my ($buf) = @_;
177              
178 1         38 $convert_c2u->($buf);
179              
180 1         5 return $buf;
181             }
182              
183             sub cv_to_win {
184 1     1 0 4 my ($buf) = @_;
185              
186 1         42 $convert_u2c->($buf);
187              
188 1         6 return $buf;
189             }
190              
191             sub commify {
192 2     2 0 6 local $_ = shift;
193 2         6 my ($sep) = @_;
194              
195 2   100     12 $sep //= '_';
196              
197 2         5 my $len = length($_);
198 2         8 for my $i (1..$len) {
199 6 100       52 last unless s/^([-+]?\d+)(\d{3})/$1$sep$2/;
200             }
201              
202 2         14 return $_;
203             }
204              
205             1;
206              
207             __END__