File Coverage

blib/lib/Regexp/Ethiopic.pm
Criterion Covered Total %
statement 86 130 66.1
branch 22 52 42.3
condition 6 15 40.0
subroutine 11 16 68.7
pod 4 8 50.0
total 129 221 58.3


line stmt bran cond sub pod time code
1             package Regexp::Ethiopic;
2 1     1   11 use base qw(Exporter);
  1         1  
  1         128  
3              
4 1     1   4 use utf8;
  1         2  
  1         6  
5             BEGIN
6             {
7 1     1   45 use strict;
  1         2  
  1         21  
8 1     1   3 use warnings;
  1         1  
  1         74  
9 1         707 use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS %EthiopicClasses
10             $ግዕዝ $ካዕብ $ሣልስ $ራብዕ $ኃምስ $ሳድስ $ሳብዕ
11 1     1   4 $ዘመደ_ግዕዝ $ዘመደ_ካዕብ $ዘመደ_ሣልስ $ዘመደ_ራብዕ $ዘመደ_ኃምስ);
  1         1  
12              
13              
14 1     1   4 $VERSION = "0.21";
15            
16 1         4 @EXPORT_OK = qw(%EthiopicClasses &getForm &setForm &subForm &formatForms &isFamilyOf
17             $ግዕዝ $ካዕብ $ሣልስ $ራብዕ $ኃምስ $ሳድስ $ሳብዕ
18             $ዘመደ_ግዕዝ $ዘመደ_ካዕብ $ዘመደ_ሣልስ $ዘመደ_ራብዕ $ዘመደ_ኃምስ
19             );
20 1         5 %EXPORT_TAGS = ( forms => [qw(
21             $ግዕዝ $ካዕብ $ሣልስ $ራብዕ $ኃምስ $ሳድስ $ሳብዕ
22             $ዘመደ_ግዕዝ $ዘመደ_ካዕብ $ዘመደ_ሣልስ $ዘመደ_ራብዕ $ዘመደ_ኃምስ)],
23             utils => [qw(&getForm &setForm &subForm &formatForms &isFamilyOf)]
24             );
25              
26              
27 1         39 %EthiopicClasses =(
28             1 => "ሀለሐመሠረሰሸቀቐበቨተቸኀነኘአከኸወዐዘዠየደዸጀገጘጠጨጰጸፀፈፐ",
29             2 => "ሁሉሐሙሡሩሱሹቁቑቡቩቱቹኁኑኙኡኩኹዉዑዙዡዩዱዹጁጉጙጡጩጱጹፁፉፑ",
30             3 => "ሂሊሒሚሢሪሲሺቂቒቢቪቲቺኂኒኚኢኪኺዊዒዚዢዪዲዺጂጊጚጢጪጲጺፂፊፒ",
31             4 => "ሃላሓማሣራሳሻቃቓባቫታቻኃናኛኣካኻዋዓዛዣያዳዻጃጋጛጣጫጳጻፃፋፓ",
32             5 => "ሄሌሔሜሤሬሴሼቄቔቤቬቴቼኄኔኜኤኬኼዌዔዜዤዬዴዼጄጌጜጤጬጴጼፄፌፔ",
33             6 => "ህልሕምሥርስሽቅቕብቭትችኅንኝእክኽውዕዝዥይድዽጅግጝጥጭጵጽፅፍፕ",
34             7 => "ሆሎሖሞሦሮሶሾቆቖቦቮቶቾኆኖኞኦኮኾዎዖዞዦዮዶዾጆጎጞጦጮጶጾፆፎፖ",
35             8 => "ቈቘኈኰዀጐኧ",
36             9 => "ቍቝኍኵዅጕ",
37             10 => "ቊቚኊኲዂጒ",
38             11 => "ሗሏሟሧሯሷሿቋቛቧቯቷቿኋኗኟኳዃዟዧዷዿጇጓጧጯጷጿፏፗ",
39             12 => "ቌቜኌኴዄጔ",
40             ሀ => "ሀ-ሆ",
41             ለ => "ለ-ሏ",
42             ሐ => "ሐ-ሗ",
43             መ => "መ-ሟ",
44             ሠ => "ሠ-ሧ",
45             ረ => "ረ-ሯ",
46             ሰ => "ሰ-ሷ",
47             ሸ => "ሸ-ሿ",
48             ቀ => "ቀ-ቆቈ-ቍ",
49             ቐ => "ቐ-ቖቘ-ቝ",
50             በ => "በ-ቧ",
51             ቨ => "ቨ-ቯ",
52             ተ => "ተ-ቷ",
53             ቸ => "ቸ-ቿ",
54             ኀ => "ኀ-ኆኈ-ኍ",
55             ነ => "ነ-ኗ",
56             ኘ => "ኘ-ኟ",
57             አ => "አ-ኧ",
58             ከ => "ከ-ኮኰኲ-ኵ",
59             ኸ => "ኸ-ኾዀ-ዅ",
60             ወ => "ወ-ዎ",
61             ዐ => "ዐ-ዖ",
62             ዘ => "ዘ-ዟ",
63             ዠ => "ዠ-ዧ",
64             የ => "የ-ዮ",
65             ደ => "ደ-ዷ",
66             ዸ => "ዸ-ዿ",
67             ጀ => "ጀ-ጇ",
68             ገ => "ገ-ጎጐ-ጕ",
69             ጘ => "ጘ-ጞ",
70             ጠ => "ጠ-ጧ",
71             ጨ => "ጨ-ጯ",
72             ጰ => "ጰ-ጷ",
73             ጸ => "ጸ-ጿ",
74             ፀ => "ፀ-ፆ",
75             ፈ => "ፈ-ፏ",
76             ፐ => "ፐ-ፗ",
77             አኃዝ => "፩-፼"
78             );
79              
80             $EthiopicClasses{'ግዕዝ'}
81             = $EthiopicClasses{geez}
82 1         25 = $EthiopicClasses{1}
83             ;
84             $EthiopicClasses{'ካዕብ'}
85             = $EthiopicClasses{kaib}
86 1         3 = $EthiopicClasses{2}
87             ;
88             $EthiopicClasses{'ሣልስ'}
89             = $EthiopicClasses{salis}
90 1         9 = $EthiopicClasses{3}
91             ;
92             $EthiopicClasses{'ራብዕ'}
93             = $EthiopicClasses{rabi}
94 1         1 = $EthiopicClasses{4}
95             ;
96             $EthiopicClasses{'ኃምስ'}
97             = $EthiopicClasses{hamis}
98 1         3 = $EthiopicClasses{5}
99             ;
100             $EthiopicClasses{'ሳድስ'}
101             = $EthiopicClasses{sadis}
102 1         1 = $EthiopicClasses{6}
103             ;
104             $EthiopicClasses{'ሳብዕ'}
105             = $EthiopicClasses{sabi}
106 1         1 = $EthiopicClasses{7}
107             ;
108             $EthiopicClasses{'ዘመደ፡ግዕዝ'}
109             = $EthiopicClasses{'zemede:geez'}
110 1         2 = $EthiopicClasses{8}
111             ;
112             $EthiopicClasses{'ዘመደ፡ካዕብ'}
113             = $EthiopicClasses{'zemede:kaib'}
114 1         3 = $EthiopicClasses{9}
115             ;
116             $EthiopicClasses{'ዘመደ፡ሣልስ'}
117             = $EthiopicClasses{'zemede:salis'}
118 1         1 = $EthiopicClasses{10}
119             ;
120             $EthiopicClasses{'ዘመደ፡ራብዕ'}
121             = $EthiopicClasses{'zemede:rabi'}
122 1         6 = $EthiopicClasses{11}
123             ;
124             $EthiopicClasses{'ዘመደ፡ኃምስ'}
125             = $EthiopicClasses{'zemede:hamis'}
126 1         1 = $EthiopicClasses{12}
127             ;
128             $EthiopicClasses{'ahaz'}
129 1         1 = $EthiopicClasses{'አኃዝ'}
130             ;
131              
132 1         86 ($ግዕዝ, $ካዕብ, $ሣልስ, $ራብዕ, $ኃምስ, $ሳድስ, $ሳብዕ,
133             $ዘመደ_ግዕዝ, $ዘመደ_ካዕብ, $ዘመደ_ሣልስ, $ዘመደ_ራብዕ, $ዘመደ_ኃምስ) = (1 .. 12);
134              
135             }
136              
137             sub import
138             {
139              
140 0     0   0 my @args = ( shift ); # package
141 0         0 foreach (@_) {
142 0 0       0 if ( /overload/o ) {
    0          
    0          
143 1     1   619 use overload;
  1         1515  
  1         6  
144 0         0 overload::constant 'qr' => \&getRe;
145             }
146             elsif ( /:forms/o ) {
147 0         0 Regexp::Ethiopic->export_to_level (1, $args[0], ':forms'); # this works too...
148             }
149             elsif ( /:utils/o ) {
150 0         0 Regexp::Ethiopic->export_to_level (1, $args[0], ':utils'); # this works too...
151             }
152             else {
153 0         0 push (@args, $_);
154             }
155             }
156 0 0       0 if ($#args) {
157 0         0 Regexp::Ethiopic->export_to_level (1, @args); # this works too...
158             }
159              
160             }
161              
162              
163             sub getForm
164             {
165 0     0 1 0 my ($ሆሄ) = @_;
166              
167 0         0 my $form = ord($ሆሄ)%8 + 1;
168              
169 0 0 0     0 if ( $form == 8 || $ሆሄ =~ /[ቋቛኋኳዃጓ]/o ) {
    0          
    0          
170 0         0 $form = 11;
171             }
172             elsif ( $ሆሄ =~ /[ቍቝኍኵዅጕ]/o ) {
173 0         0 $form = 9;
174             }
175             elsif ( $ሆሄ =~ /[ቈቘኈኰዀጐቊቚኊኲዂጒቌቜኌኴዄጔ]/o ) {
176 0         0 $form += 7;
177             }
178              
179 0         0 $form;
180             }
181              
182              
183             sub setForm
184             {
185 4     4 1 11 my ($ሆሄ, $form) = @_;
186              
187 4 50       15 if ( $ሆሄ =~ /[ኈ-ኍቈ-ቍቘ-ቝኰ-ኵዀ-ዅጐ-ጕ]/o ) {
188 0         0 $ሆሄ =~ s/[ኈ-ኍ]/ኅ/o;
189 0         0 $ሆሄ =~ s/[ቈ-ቍ]/ቀ/o;
190 0         0 $ሆሄ =~ s/[ቘ-ቝ]/ቐ/o;
191 0         0 $ሆሄ =~ s/[ኰ-ኵ]/ከ/o;
192 0         0 $ሆሄ =~ s/[ዀ-ዅ]/ኸ/o;
193 0         0 $ሆሄ =~ s/[ጐ-ጕ]/ገ/o;
194             }
195 4 50       8 $form = 4 if ( $ሆሄ =~ /[ቋቛኋኳዃጓ]/o );
196 4 50 33     31 $form -= 7 if ( $form == 8 || $form == 10 || $form == 12 );
      33        
197 4 50       6 $form = 8 if ( $form == 11 );
198 4 50       8 $form = 6 if ( $form == 9 );
199              
200 4         15 chr ( ord($ሆሄ) - ord($ሆሄ)%8 + $form-1 );
201             }
202              
203              
204             sub subForm
205             {
206 0     0 1 0 my ($set, $get) = @_;
207              
208             # e.g. s/([=#ሀ#=])/subForm($1, ሀ)/eg;
209 0         0 setForm ( $set, getForm ( $get ) );
210             }
211              
212              
213             sub isFamilyOf
214             {
215 0     0 0 0 my ($a,$b) = @_;
216              
217 0         0 my $gez = setForm($a,1);
218 0         0 my $re = getRe( "[#$gez#]" );
219 0         0 ( $b =~ /$re/ );
220             }
221              
222              
223             sub formatForms
224             {
225 0     0 1 0 my ($format, $string) = @_;
226              
227 0         0 my @chars = split ( //, $string );
228              
229 0 0       0 if ( @chars != ($format =~ s/%/%/g) ) {
230 0         0 $format =~ s/\p{Ethiopic}//g;
231 0         0 warn ( "\"$string\" is of different length from $format." );
232 0         0 return;
233             }
234              
235 0         0 foreach (@chars) {
236 0         0 $format =~ s/%(\d+)/setForm($_, $1)/e;
  0         0  
237             }
238              
239 0         0 $format;
240             }
241              
242              
243             sub handleChars
244             {
245 4     4 0 9 my ($chars,$form) = @_;
246              
247 4 50       7 return ( $EthiopicClasses{$form} ) if ( $chars eq "all" );
248              
249 4         5 my $re;
250              
251 4         38 $chars =~ s/(\w)(?=\w)/$1,/og;
252 4         15 my @Chars = split ( /,/, $chars );
253 4         6 foreach (@Chars) {
254 8 100       62 if ( /(\w)-(\w)/o ) {
255 4         12 my ($a,$b) = ($1,$2);
256 4         119 foreach my $char (sort keys %EthiopicClasses) {
257 300 100       400 next if ( length($char) > 1 );
258 184 100 100     401 next unless ( (ord($a) <= ord($char)) && (ord($char) <= ord($b)) );
259 12 50       26 if ( $form eq "all" ) {
260 0         0 $re .= $EthiopicClasses{$char};
261             }
262             else {
263 12         147 $EthiopicClasses{$form} =~ /([$EthiopicClasses{$char}])/;
264 12         21 $re .= $1;
265             }
266             }
267             }
268             else {
269 4         11 my $geez = setForm( $_, $ግዕዝ);
270 4 50       22 if ( $form eq "all" ) {
271 0         0 $re .= $EthiopicClasses{$geez};
272             }
273             else {
274 4         82 $EthiopicClasses{$form} =~ /([$EthiopicClasses{$geez}])/;
275 4         16 $re .= $1;
276             }
277             }
278             }
279              
280 4         14 $re;
281             }
282              
283              
284             sub setRange
285             {
286 1     1 0 8 my ($chars,$forms,$not) = @_;
287 1   33     9 $not ||= $_[3];
288              
289 1         1 my $re;
290              
291 1 50       4 if ( $forms eq "all" ) {
292 0         0 $re = handleChars ( $chars, $forms );
293             }
294             else {
295 1         7 my @Forms = split ( /,/, $forms);
296 1         6 foreach (@Forms) {
297 2 100       12 if ( /(\d)-(\d)/o ) {
298 1         3 my ($a,$b) = ($1,$2);
299 1         5 foreach my $form ($a..$b) {
300 3         6 $re .= handleChars ( $chars, $form );
301             }
302             }
303             else {
304 1         3 my $form = $_;
305 1         7 $re .= handleChars ( $chars, $form );
306             }
307             }
308             }
309              
310 1 50       14 ($re) ? ($not) ? "[$not$re]" : "[$re]" : "";
    50          
311             }
312              
313              
314             sub getRe
315             {
316 7 50   7 0 12 $_ = ($#_) ? $_[1] : $_[0];
317              
318              
319 7 50       24 s/\[:(\p{Ethiopic}+|\w+):\]/($EthiopicClasses{$1}) ? "[$EthiopicClasses{$1}]" : "[:$1:]"/eog;
  2         12  
320 7 50       18 s/\[#(\p{Ethiopic}|\d)#\]/($EthiopicClasses{$1}) ? "[$EthiopicClasses{$1}]" : ""/eog;
  1         7  
321 7         11 s/\[#(\^)?([\d,-]+)#\]/setRange("all",$2,$1)/eog;
  0         0  
322 7         16 s/\[#(\^)?([\p{Ethiopic},-]+)#\]/setRange($2,"all",$1)/eog;
  0         0  
323              
324             # print " IN: $_\n";
325              
326             #
327             # for some stupid reason the below doesn't work, so \w
328             # is used in place of \p{Ethiopic}, dangerous...
329             #
330             # test 9 in examples/overload.pl will fail
331             #
332             # s/(\p{Ethiopic})\{#([\d,-]+)#\}/setRange($1,$2)/eog;
333 7         13 s/(\w)\{#([\d,-]+)#\}/setRange($1,$2)/eog;
  0         0  
334              
335 7         21 s/\[(\^)?(\p{Ethiopic}+.*?)\]\{(\^)?#([\d,-]+)#\}/setRange($2,$4,$1,$3)/eog;
  1         6  
336              
337             # print " OUT: $_\n";
338              
339 7         1517 $_;
340             }
341              
342              
343              
344             #########################################################
345             # Do not change this, Do not put anything below this.
346             # File must return "true" value at termination
347             1;
348             ##########################################################
349              
350              
351             __END__