File Coverage

blib/lib/Regexp/Cherokee.pm
Criterion Covered Total %
statement 77 121 63.6
branch 18 42 42.8
condition 4 6 66.6
subroutine 11 16 68.7
pod 4 7 57.1
total 114 192 59.3


line stmt bran cond sub pod time code
1             package Regexp::Cherokee;
2 1     1   118960 use base qw(Exporter);
  1         3  
  1         154  
3              
4 1     1   14 use utf8;
  1         2  
  1         7  
5             BEGIN
6             {
7 1     1   89 use strict;
  1         2  
  1         34  
8 1     1   5 use warnings;
  1         3  
  1         80  
9 1     1   6 use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS %CherokeeClasses %CherokeeEquivalence $pseudoMatrix);
  1         2  
  1         453  
10              
11 1     1   5 $VERSION = "0.07";
12            
13 1         11 @EXPORT_OK = qw(%CherokeeClasses %CherokeeEquivalence &getForm &setForm &subForm &formatForms);
14 1         11 %EXPORT_TAGS = ( utils => [qw(&getForm &setForm &subForm &formatForms)] );
15              
16              
17 1         28 %CherokeeClasses =(
18             1 => "ᎠᎦᎧᎭᎳᎹᎾᎿᏀᏆᏌᏍᏓᏔᏜᏝᏣᏩᏯ",
19             2 => "ᎡᎨᎮᎴᎺᏁᏇᏎᏕᏖᏞᏤᏪᏰ",
20             3 => "ᎢᎩᎯᎵᎻᏂᏈᏏᏗᏘᏟᏥᏫᏱ",
21             4 => "ᎣᎪᎰᎶᎼᏃᏉᏐᏙᏠᏦᏬᏲ",
22             5 => "ᎤᎫᎱᎷᎽᏄᏊᏑᏚᏡᏧᏭᏳ",
23             6 => "ᎥᎬᎲᎸᏅᏋᏒᏛᏢᏨᏮᏴ",
24             Ꭰ => "Ꭰ-Ꭵ",
25             Ꭶ => "Ꭶ-Ꭼ",
26             Ꭽ => "Ꭽ-Ꮂ",
27             Ꮃ => "Ꮃ-Ꮈ",
28             Ꮉ => "Ꮉ-Ꮍ",
29             Ꮎ => "Ꮎ-Ꮕ",
30             Ꮖ => "Ꮖ-Ꮛ",
31             Ꮜ => "Ꮜ-Ꮢ",
32             Ꮣ => "Ꮣ-Ꮫ",
33             Ꮬ => "Ꮬ-Ꮲ",
34             Ꮳ => "Ꮳ-Ꮸ",
35             Ꮹ => "Ꮹ-Ꮾ",
36             Ꮿ => "Ꮿ-Ᏼ"
37             );
38              
39             #
40             # Cherokee Rules Orthography Equivalence
41             #
42 1         4 %CherokeeEquivalence =(
43             Ꭶ => "ᎦᎧ",
44             Ꮎ => "ᎾᎿᏀ",
45             Ꮜ => "ᏌᏍ",
46             Ꮣ => "ᏓᏔ",
47             Ꮥ => "ᏕᏖ",
48             Ꮧ => "ᏗᏘ",
49             Ꮬ => "ᏜᏝ"
50             );
51             $CherokeeEquivalence{'Ꭷ'}
52 1         2 = $CherokeeEquivalence{'Ꭶ'}
53             ;
54             $CherokeeEquivalence{'Ꮏ'}
55             = $CherokeeEquivalence{'Ꮐ'}
56 1         2 = $CherokeeEquivalence{'Ꮎ'}
57             ;
58             $CherokeeEquivalence{'Ꮝ'}
59 1         1 = $CherokeeEquivalence{'Ꮜ'}
60             ;
61             $CherokeeEquivalence{'Ꮤ'}
62 1         2 = $CherokeeEquivalence{'Ꮣ'}
63             ;
64             $CherokeeEquivalence{'Ꮦ'}
65 1         1 = $CherokeeEquivalence{'Ꮥ'}
66             ;
67             $CherokeeEquivalence{'Ꮨ'}
68 1         4 = $CherokeeEquivalence{'Ꮧ'}
69             ;
70             $CherokeeEquivalence{'Ꮭ'}
71 1         2 = $CherokeeEquivalence{'Ꮬ'}
72             ;
73              
74             # use a long string as a pseudo matrix
75             # get index in pseudo matrix, then find in index+form combination position in matrix
76              
77             # 6x13 matrix
78              
79             # Form 1: "ᎠᎦᎭᎳᎹᎾᏆᏌᏓᏜᏣᏩᏯ",
80             # Form 2: "ᎡᎨᎮᎴᎺᏁᏇᏎᏕᏞᏤᏪᏰ",
81             # Form 3: "ᎢᎩᎯᎵᎻᏂᏈᏏᏗᏟᏥᏫᏱ",
82             # Form 4: "ᎣᎪᎰᎶᎼᏃᏉᏐᏙᏠᏦᏬᏲ",
83             # Form 5: "ᎤᎫᎱᎷᎽᏄᏊᏑᏚᏡᏧᏭᏳ",
84             # Form 6: "ᎥᎬᎲᎸXᏅᏋᏒᏛᏢᏨᏮᏴ",
85              
86 1         65 $pseudoMatrix = "ᎠᎦᎭᎳᎹᎾᏆᏌᏓᏜᏣᏩᏯᎡᎨᎮᎴᎺᏁᏇᏎᏕᏞᏤᏪᏰᎢᎩᎯᎵᎻᏂᏈᏏᏗᏟᏥᏫᏱᎣᎪᎰᎶᎼᏃᏉᏐᏙᏠᏦᏬᏲᎤᎫᎱᎷᎽᏄᏊᏑᏚᏡᏧᏭᏳᎥᎬᎲᎸXᏅᏋᏒᏛᏢᏨᏮᏴ";
87              
88             }
89              
90             sub import
91             {
92              
93 1     1   11 my @args = ( shift ); # package
94 1         4 foreach (@_) {
95 1 50       6 if ( /overload/o ) {
    0          
    0          
96 1     1   590 use overload;
  1         1579  
  1         8  
97 1         5 overload::constant 'qr' => \&getRe;
98             }
99             elsif ( /:forms/o ) {
100 0         0 Regexp::Cherokee->export_to_level (1, $args[0], ':forms'); # this works too...
101             }
102             elsif ( /:utils/o ) {
103 0         0 Regexp::Cherokee->export_to_level (1, $args[0], ':utils'); # this works too...
104             }
105             else {
106 0         0 push (@args, $_);
107             }
108             }
109 1 50       138 if ($#args) {
110 0         0 Regexp::Cherokee->export_to_level (1, @args); # this works too...
111             }
112              
113             }
114              
115              
116             sub getForm
117             {
118 0     0 1 0 my ($letter) = @_;
119              
120              
121 0         0 foreach my $form (1..6) {
122 0 0       0 return $form if ( $CherokeeClasses{$form} =~ $letter );
123             }
124             }
125              
126              
127             #
128             # unfortunately the index function in Perl 5.8.0 is broken for some
129             # Unicode sequences: http://rt.perl.org/rt2/Ticket/Display.html?id=22375
130             #
131             sub _index
132             {
133 0     0   0 my ( $haystack, $needle ) = @_;
134              
135 0         0 my $pos = my $found = 0;
136 0         0 foreach (split (//, $haystack) ) {
137 0 0       0 $found = 1 if ( /$needle/ );
138 0 0       0 $pos++ unless ( $found );
139             }
140              
141 0         0 $pos;
142             }
143              
144              
145             sub setForm
146             {
147 0     0 1 0 my ($letter, $form) = @_;
148              
149              
150 0         0 $form--;
151             #
152             # simplify
153             #
154 0         0 $letter =~ s/Ꭷ/Ꭶ/;
155 0         0 $letter =~ s/[ᎿᏀ]/Ꮎ/;
156 0         0 $letter =~ s/Ꮝ/Ꮜ/;
157 0         0 $letter =~ s/Ꮤ/Ꮣ/;
158 0         0 $letter =~ s/Ꮦ/Ꮥ/;
159 0         0 $letter =~ s/Ꮨ/Ꮧ/;
160 0         0 $letter =~ s/Ꮭ/Ꮬ/;
161              
162             # print "letter = $letter / form = $form\n
";
163 0         0 my $index = _index ( $pseudoMatrix, $letter );
164             # print "index = $index
\n";
165              
166 0         0 my $offset = ( ($index%13) + $form*13 );
167 0         0 substr ( $pseudoMatrix, $offset, 1 );
168              
169             }
170              
171              
172             sub subForm
173             {
174 0     0 1 0 my ($set, $get) = @_;
175              
176 0         0 setForm ( $set, getForm ( $get ) );
177             }
178              
179              
180             sub formatForms
181             {
182 0     0 1 0 my ($format, $string) = @_;
183              
184 0         0 my @chars = split ( //, $string );
185              
186 0 0       0 if ( @chars != ($format =~ s/%/%/g) ) {
187 0         0 $format =~ s/\p{Cherokee}//g;
188 0         0 warn ( "\"$string\" is of different length from $format." );
189 0         0 return;
190             }
191              
192 0         0 foreach (@chars) {
193 0         0 $format =~ s/%(\d+)/setForm($_, $1)/e;
  0         0  
194             }
195              
196 0         0 $format;
197             }
198              
199              
200             sub handleChars
201             {
202 4     4 0 6 my ($chars,$form) = @_;
203              
204 4 50       9 return ( $CherokeeClasses{$form} ) if ( $chars eq "all" );
205              
206 4         17 my $re;
207              
208 4         23 $chars =~ s/(\w)(?=\w)/$1,/og;
209 4         10 my @Chars = split ( /,/, $chars );
210 4         7 foreach (@Chars) {
211 8 100       46 if ( /(\w)-(\w)/o ) {
212 4         6 my ($a,$b) = ($1,$2);
213 4         29 foreach my $char (sort keys %CherokeeClasses) {
214 76 50       112 next if ( length($char) > 1 );
215 76 100 100     125 next unless ( (ord($a) <= ord($char)) && (ord($char) <= ord($b)) );
216 16 50       18 if ( $form eq "all" ) {
217 0         0 $re .= $CherokeeClasses{$char};
218             }
219             else {
220 16         157 $CherokeeClasses{$form} =~ /([$CherokeeClasses{$char}])/;
221 16         25 $re .= $1;
222             }
223             }
224             }
225             else {
226 4 50       7 if ( $form eq "all" ) {
227 0         0 $re .= $CherokeeClasses{$_};
228             }
229             else {
230 4         34 $CherokeeClasses{$form} =~ /([$CherokeeClasses{$_}])/;
231 4         8 $re .= $1;
232             }
233             }
234             }
235              
236 4         11 $re;
237             }
238              
239              
240             sub setRange
241             {
242 1     1 0 11 my ($chars,$forms,$not) = @_;
243 1   33     7 $not ||= $_[3];
244              
245 1         1 my $re;
246              
247 1 50       3 if ( $forms eq "all" ) {
248 0         0 $re = handleChars ( $chars, $forms );
249             }
250             else {
251 1         4 my @Forms = split ( /,/, $forms);
252             #
253             # next time, put @Chars loop on the outside and set
254             # up character ranges with -
255             #
256 1         2 foreach (@Forms) {
257 2 100       7 if ( /(\d)-(\d)/o ) {
258 1         3 my ($a,$b) = ($1,$2);
259 1         4 foreach my $form ($a..$b) {
260 3         12 $re .= handleChars ( $chars, $form );
261             }
262             }
263             else {
264 1         2 my $form = $_;
265 1         3 $re .= handleChars ( $chars, $form );
266             }
267             }
268             }
269              
270 1 50       5 ($re) ? ($not) ? "[$not$re]" : "[$re]" : "";
    50          
271             }
272              
273              
274             sub getRe
275             {
276 7 100   7 0 155805 $_ = ($#_) ? $_[1] : $_[0];
277              
278              
279 7 0       17 s/\[=(\p{Cherokee})=\]/($CherokeeEquivalence{$1}) ? "[$CherokeeEquivalence{$1}]" : $1/eog;
  0         0  
280 7 50       42 s/\[#(\p{Cherokee}|\d)#\]/($CherokeeClasses{$1}) ? "[$CherokeeClasses{$1}]" : ""/eog;
  21         116  
281 7         18 s/\[#(\^)?([\d,-]+)#\]/setRange("all",$2,$1)/eog;
  0         0  
282 7         18 s/\[#(\^)?([\p{Cherokee},-]+)#\]/setRange($2,"all",$1)/eog;
  0         0  
283              
284             #
285             # for some stupid reason the below doesn't work, so \w
286             # is used in place of \p{Cherokee}, dangerous...
287             #
288             # s/(\p{Cherokee})\{%([\d,-]+)\}/setRange($1,$2)/eog;
289 7         14 s/(\w)\{#([\d,-]+)#\}/setRange($1,$2)/eog;
  0         0  
290              
291 7         20 s/\[(\^)?(\p{Cherokee}+.*?)\]\{(\^)?#([\d,-]+)#\}/setRange($2,$4,$1,$3)/eog;
  1         5  
292              
293 7         2266 $_;
294             }
295              
296              
297              
298             #########################################################
299             # Do not change this, Do not put anything below this.
300             # File must return "true" value at termination
301             1;
302             ##########################################################
303              
304              
305             __END__