File Coverage

blib/lib/Lingua/ZH/CEDICT.pm
Criterion Covered Total %
statement 44 144 30.5
branch 4 18 22.2
condition 12 37 32.4
subroutine 11 26 42.3
pod 21 21 100.0
total 92 246 37.4


line stmt bran cond sub pod time code
1             package Lingua::ZH::CEDICT;
2              
3             # Copyright (c) 2002-2005 Christian Renz
4             # This module is free software; you can redistribute it and/or modify
5             # it under the same terms as Perl itself.
6              
7             # $Id: CEDICT.pm,v 1.5 2002/08/13 19:06:07 crenz Exp $
8              
9 4     4   76722 use 5.006;
  4         16  
  4         186  
10 4     4   3917 use bytes;
  4         35  
  4         22  
11 4     4   127 use strict;
  4         8  
  4         143  
12 4     4   24 use warnings;
  4         7  
  4         249  
13 4     4   125 use vars qw($VERSION @ISA);
  4         8  
  4         13004  
14              
15             $VERSION = '0.04';
16             @ISA = ();
17              
18             sub new {
19 5     5 1 12756 my $class = shift;
20 5         24 my $self = +{@_};
21              
22 5   100     43 $self->{source} ||= 'Storable';
23              
24             # load data interface module
25 5         23 my $if = "$class\::$self->{source}";
26 5         38 (my $file = $if) =~ s|::|/|g;
27 5         4379 require "$file.pm";
28              
29             # let others do the blessing
30 5         17 return $if->new(%{$self});
  5         48  
31             }
32              
33             sub exportData {
34 0     0 1 0 my ($self) = @_;
35 0         0 my $data;
36              
37 0         0 foreach (qw(version entry keysZh keysPinyin keysEn)) {
38 0         0 $data->{$_} = $self->{$_};
39             }
40              
41 0         0 return $data;
42             }
43              
44             sub numEntries {
45 7328     7328 1 8524 my ($self) = @_;
46              
47 7328         6762 return scalar @{$self->{entry}};
  7328         18565  
48             }
49              
50             sub version {
51 0     0 1 0 my ($self) = @_;
52              
53 0         0 return $self->{version};
54             }
55              
56             sub generateKeywords {
57 0     0 1 0 my ($self) = @_;
58              
59 0         0 $self->{keysZh} = {};
60 0         0 $self->{keysPinyin} = {};
61 0         0 $self->{keysEn} = {};
62              
63 0         0 my ($zh, $p, $en);
64              
65 0         0 foreach (0..($self->numEntries - 1)) {
66 0         0 my $e = $self->{entry}->[$_];
67 0         0 push @{$self->{keysZh}->{$e->[0]}}, $_; $zh++;
  0         0  
  0         0  
68 0 0 0     0 if (defined($e->[1]) && ($e->[1])) {
69 0         0 push @{$self->{keysZh}->{$e->[1]}}, $_;
  0         0  
70 0         0 $zh++;
71             }
72 0         0 push @{$self->{keysPinyin}->{$e->[3]}}, $_; $p++;
  0         0  
  0         0  
73              
74 0         0 foreach my $k ($self->englishToKeywords($e->[4])) {
75 0         0 push @{$self->{keysEn}->{$k}}, $_;
  0         0  
76 0         0 $en++;
77             }
78             }
79             }
80              
81             sub applyPinyinFormat {
82 0     0 1 0 my ($self, $sub) = @_;
83              
84 0   0     0 $sub ||= \&utf8Pinyin;
85              
86 0         0 foreach (0..($self->numEntries - 1)) {
87 0         0 $self->{entry}->[$_]->[2] =
88             &$sub($self->{entry}->[$_]->[2]);
89             }
90             }
91              
92             sub applyEnglishFormat {
93 0     0 1 0 my ($self, $sub) = @_;
94              
95 0   0     0 $sub ||= \&formatEnglish;
96              
97 0         0 foreach (0..($self->numEntries - 1)) {
98 0         0 $self->{entry}->[$_]->[4] =
99             &$sub($self->{entry}->[$_]->[4]);
100             }
101             }
102              
103             sub addSimpChar {
104 0     0 1 0 my ($self) = @_;
105              
106 0   0     0 $self->{HanConvert} ||= "Lingua::ZH::CEDICT::HanConvert";
107 0         0 (my $filename = $self->{HanConvert} . ".pm") =~ s|::|/|g;
108 0         0 my $lib = $self->{HanConvert};
109              
110 0         0 require $filename;
111 0         0 import $lib 'simple';
112              
113              
114 0         0 foreach (@{$self->{entry}}) {
  0         0  
115 0         0 my $s = simple($_->[0]);
116 0 0       0 $_->[1] = $s unless ($s eq $_->[0]);
117             }
118             }
119              
120             # just for completeness' sake, should not really be necessary
121             sub addTradChar {
122 0     0 1 0 my ($self) = @_;
123              
124 0   0     0 $self->{HanConvert} ||= "Lingua::ZH::HanConvert";
125 0         0 (my $filename = $self->{HanConvert} . ".pm") =~ s|::|/|g;
126 0         0 my $lib = $self->{HanConvert};
127              
128 0         0 require $filename;
129 0         0 import $lib 'trad';
130              
131 0         0 foreach (@{$self->{entry}}) {
  0         0  
132 0         0 my $t = trad($_->[0]);
133 0 0       0 if ($t ne $_->[0]) {
134 0         0 $_->[1] = $_->[0];
135 0         0 $_->[0] = $t;
136             }
137             }
138             }
139              
140             # Functions for accessing the dictionary ************************************
141              
142             sub entry {
143 0     0 1 0 my ($self, $num) = @_;
144 0         0 return $self->{entry}->[$num];
145             }
146              
147             sub keysEn {
148 0     0 1 0 my ($self) = @_;
149              
150 0         0 return $self->{keysEn};
151             }
152              
153             sub keysZh {
154 0     0 1 0 my ($self) = @_;
155              
156 0         0 return $self->{keysZh};
157             }
158              
159             sub keysPinyin {
160 0     0 1 0 my ($self) = @_;
161              
162 0         0 return $self->{keysPinyin};
163             }
164              
165             sub startMatch {
166 1     1 1 515 my ($self, $term) = @_;
167              
168 1         5 $self->{_matchPos} = 0;
169 1         3 $self->{_matchTerm} = $term;
170             }
171              
172             # returns a reference to the first/following entry that matches
173             sub match {
174 1     1 1 8 my ($self) = @_;
175 1         3 my $term = $self->{_matchTerm};
176              
177 1         46 while ($self->{_matchPos} < $self->numEntries) {
178 616         845 $self->{_matchPos}++;
179 616         997 my $e = $self->{entry}->[$self->{_matchPos} - 1];
180 616 100 33     11533 return $e
      33        
      33        
      66        
181             if (($e->[0] =~ /$term/) or
182             ($e->[1] =~ /$term/) or
183             ($e->[2] =~ /\b$term\b/i) or
184             ($e->[3] =~ /\b$term\b/i) or
185             ($e->[4] =~ /\b$term\b/i));
186             }
187              
188             # nothing found
189 0         0 return undef;
190             }
191              
192             sub startFind {
193 1     1 1 504 my ($self, $term) = @_;
194              
195 1         5 $self->{_findPos} = 0;
196 1         3 $self->{_findTerm} = $term;
197             }
198              
199             # returns a reference to the first/following entry that matches
200             sub find {
201 2     2 1 513 my ($self) = @_;
202 2         6 my $term = $self->{_findTerm};
203              
204 2         34 while ($self->{_findPos} < $self->numEntries) {
205 6712         8986 $self->{_findPos}++;
206 6712         11779 my $e = $self->{entry}->[$self->{_findPos} - 1];
207 6712 100 33     99681 return $e
      33        
      33        
      66        
208             if (($e->[0] eq $term) or
209             ($e->[1] eq $term) or
210             ($e->[2] =~ /^$term$/i) or
211             ($e->[3] =~ /^$term$/i) or
212             ($e->[4] =~ /^$term$/i));
213             }
214              
215             # nothing found
216 0           return undef;
217             }
218              
219             # Formatting ****************************************************************
220              
221             my %xlat =
222             (a1 => "ā", e1 => "ē", i1 => "ī",
223             o1 => "ō", u1 => "ū", 'v1' => "ǖ",
224             a2 => "á", e2 => "é", i2 => "í",
225             o2 => "ó", u2 => "ú", 'v2' => "ǘ",
226             a3 => "ǎ", e3 => "ě", i3 => "ǐ",
227             o3 => "ǒ", u3 => "ǔ", 'v3' => "ǚ",
228             a4 => "à", e4 => "è", i4 => "ì",
229             o4 => "ò", u4 => "ù", 'v4' => "ǜ",
230             a5 => 'a', e5 => 'e', i5 => 'i',
231             o5 => 'o', u5 => 'u', 'v5' => 'ü');
232              
233             sub utf8Pinyin {
234 0     0 1   my ($self, $p) = @_;
235 0 0         $p = $self unless ref($self);
236              
237             # normalize u: and v to v
238 0           $p =~ s/u:/v/g;
239              
240 0           $p =~ s/([iuv]?)([aeiouv])([a-z]*)([1-5])/$1$xlat{"$2$4"}$3/g;
241 0           return $p;
242             }
243              
244             sub formatEnglish {
245 0     0 1   my ($self, $en) = @_;
246 0 0         $en = $self unless ref($self);
247              
248 0           my $separator = " · ";
249             # my $separator = "/";
250              
251             # $en =~ s|/|$separator|g;
252             # return $en;
253              
254 0           my @terms = split m|/|, $en;
255              
256 0           foreach (0..$#terms) {
257 0           $terms[$_] =~ s|\(([^(]+)\)$|$1|;
258             }
259              
260 0           return join($separator, @terms);
261             }
262              
263             sub removePinyinTones {
264 0     0 1   my ($self, $p) = @_;
265              
266 0           $p =~ s/[12345]//g;
267 0           $p =~ s/(u:|v)/u/g;
268              
269 0           return $p;
270             }
271              
272             sub englishToKeywords {
273 0     0 1   my ($self, $en) = @_;
274 0           my @kw;
275              
276 0           foreach (split(m|/|, $en)) {
277 0 0         next if /^\([^()]+\)$/;
278              
279             # remove trailing explanation in brackets
280 0           s/\s+\([^(]+\)$//;
281 0           s/^\(?(to|the|a|an|to be)\)?\s+//i;
282              
283             # remove characters we don't like in keywords
284 0           s|[^-a-zA-Z0-9 /.]||g;
285 0           s|^\.+||;
286             # s!(\w|\d|\s|-|/)!!g;
287              
288             # remove leading and trailing and multiple whitespace
289 0           s/^\s+//;
290 0           s/\s+$//;
291 0           s/\s\s+/ /g;
292              
293             # definitions like "(a sense of) uncertainty"
294 0 0         if (/^\((.+?)\)\s+(.+)$/) {
295 0           push @kw, uc($2);
296 0           push @kw, uc("$1 $2");
297             } else {
298 0           push @kw, uc($_);
299             }
300             }
301              
302             # return non-empty keywords
303 0           return grep /\w/, @kw;
304             }
305              
306             1;
307             __END__