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