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