blib/lib/Biblio/Thesaurus.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 338 | 784 | 43.1 |
branch | 118 | 334 | 35.3 |
condition | 16 | 92 | 17.3 |
subroutine | 40 | 80 | 50.0 |
pod | 45 | 45 | 100.0 |
total | 557 | 1335 | 41.7 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | # -*- Mode: Perl; tab-width: 2; -*- | ||||||
2 | package Biblio::Thesaurus; | ||||||
3 | 7 | 7 | 262572 | use 5.010; | |||
7 | 30 | ||||||
7 | 326 | ||||||
4 | 7 | 7 | 46 | use strict; | |||
7 | 14 | ||||||
7 | 277 | ||||||
5 | 7 | 7 | 37 | use warnings; | |||
7 | 17 | ||||||
7 | 328 | ||||||
6 | require Exporter; | ||||||
7 | 7 | 7 | 23729 | use Storable; | |||
7 | 45615 | ||||||
7 | 702 | ||||||
8 | 7 | 7 | 58670 | use CGI qw/:standard/; | |||
7 | 154339 | ||||||
7 | 58 | ||||||
9 | |||||||
10 | 7 | 7 | 29574 | use Data::Dumper; | |||
7 | 18037 | ||||||
7 | 105568 | ||||||
11 | |||||||
12 | # Version | ||||||
13 | our $VERSION = '0.43'; | ||||||
14 | |||||||
15 | # Module Stuff | ||||||
16 | our @ISA = qw(Exporter); | ||||||
17 | our %EXPORT_TAGS = ( 'all' => [ qw() ] ); | ||||||
18 | our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); | ||||||
19 | |||||||
20 | # We are working with an object oriented interface. This means, we only | ||||||
21 | # need to export constructors. | ||||||
22 | # | ||||||
23 | # The last three variables are used to down-translation sub (downtr) | ||||||
24 | our @EXPORT = qw( | ||||||
25 | &thesaurusLoad | ||||||
26 | &thesaurusLoadM | ||||||
27 | &thesaurusNew | ||||||
28 | &thesaurusRetrieve | ||||||
29 | &thesaurusMultiLoad | ||||||
30 | @terms $term $rel); | ||||||
31 | |||||||
32 | our ($casesen,$rel,@terms,$term); | ||||||
33 | |||||||
34 | |||||||
35 | ## | ||||||
36 | # | ||||||
37 | # | ||||||
38 | 0 | 0 | 1 | 0 | sub top_name { topName(@_) } | ||
39 | |||||||
40 | sub topName { | ||||||
41 | 1 | 1 | 1 | 2 | my ($self, $name) = @_; | ||
42 | 1 | 50 | 3 | if($name){ $self->{name} = $name;} | |||
0 | 0 | ||||||
43 | 1 | 4 | else { return $self->{name};} | ||||
44 | } | ||||||
45 | |||||||
46 | sub order { | ||||||
47 | 0 | 0 | 1 | 0 | my ($self,@names) = @_; | ||
48 | 0 | 0 | 0 | if(@names){ $self->{order} = [@names] ; } | |||
0 | 0 | ||||||
49 | 0 | 0 | 0 | else { defined $self->{order} ? (@{$self->{order}}) : () } | |||
0 | 0 | ||||||
50 | } | ||||||
51 | |||||||
52 | sub isLanguage{ | ||||||
53 | 0 | 0 | 1 | 0 | my ($self,$l) = @_; | ||
54 | 0 | 0 | return defined $self->{languages}{$l} | ||||
55 | } | ||||||
56 | |||||||
57 | sub languages{ | ||||||
58 | 0 | 0 | 1 | 0 | my ($self,@names) = @_; | ||
59 | 0 | 0 | 0 | if(@names){ for (@names) { $self->{languages}{$_} = 1; }} | |||
0 | 0 | ||||||
0 | 0 | ||||||
60 | 0 | 0 | else { keys (%{$self->{languages}}) } | ||||
0 | 0 | ||||||
61 | } | ||||||
62 | |||||||
63 | sub baselang { | ||||||
64 | 0 | 0 | 1 | 0 | my ($self,$name) = @_; | ||
65 | 0 | 0 | 0 | if($name){ $self->{$name} = $self->{$self->{baselang}}; | |||
0 | 0 | ||||||
0 | 0 | ||||||
66 | 0 | 0 | delete $self->{$self->{baselang}}; | ||||
67 | 0 | 0 | $self->{baselang} = $name;} | ||||
68 | else {return $self->{baselang};} | ||||||
69 | } | ||||||
70 | |||||||
71 | ## | ||||||
72 | # | ||||||
73 | # | ||||||
74 | sub terms { | ||||||
75 | 28 | 28 | 1 | 337 | my ($self, $term, @rels) = @_; | ||
76 | 28 | 55 | my $base = $self->{baselang}; | ||||
77 | 28 | 50 | 63 | return () unless $self->isDefined($term); | |||
78 | 28 | 76 | $term = $self->_definition($term); | ||||
79 | |||||||
80 | 28 | 58 | @rels = map { uc $_ } @rels; | ||||
29 | 89 | ||||||
81 | |||||||
82 | return (map { | ||||||
83 | 28 | 100 | 56 | if (defined($self->{$base}{$term}{$_})) { | |||
29 | 92 | ||||||
84 | 11 | 50 | 45 | if (ref($self->{$base}{$term}{$_}) eq "ARRAY") { | |||
85 | 11 | 15 | @{$self->{$base}{$term}{$_}} | ||||
11 | 73 | ||||||
86 | } else { | ||||||
87 | 0 | 0 | ($self->{$base}{$term}{$_}) | ||||
88 | } | ||||||
89 | } else { | ||||||
90 | () | ||||||
91 | 18 | 44 | } | ||||
92 | } @rels); | ||||||
93 | } | ||||||
94 | |||||||
95 | ## | ||||||
96 | # Parece-me que não está a ser usada. | ||||||
97 | # | ||||||
98 | # sub external { | ||||||
99 | # my ($self,$term,$external) = @_; | ||||||
100 | # $external = uc($external); | ||||||
101 | # $term = $self->definition($term); | ||||||
102 | # return $self->{$self->{baselang}}{$term}{$external}; | ||||||
103 | # } | ||||||
104 | |||||||
105 | ### | ||||||
106 | # | ||||||
107 | # | ||||||
108 | 0 | 0 | 1 | 0 | sub all_terms { allTerms(@_) } | ||
109 | |||||||
110 | sub allTerms { | ||||||
111 | 5 | 5 | 1 | 826 | my $self = shift; | ||
112 | 5 | 7 | return sort keys %{$self->{$self->{baselang}}}; | ||||
5 | 46 | ||||||
113 | } | ||||||
114 | |||||||
115 | ### | ||||||
116 | # | ||||||
117 | # | ||||||
118 | sub depth_first { | ||||||
119 | 43 | 43 | 1 | 985 | my ($self,$term,$niveis,@relat) = @_; | ||
120 | 43 | 56 | my %st=(); | ||||
121 | |||||||
122 | 43 | 100 | 93 | if ($niveis>=1) { | |||
29 | 50 | 100 | |||||
123 | 14 | 35 | for ($self->terms($term,@relat)) { | ||||
124 | 38 | 86 | $st{$_}=depth_first($self,$_,$niveis-1,@relat); | ||||
125 | } | ||||||
126 | 14 | 51 | \%st; } | ||||
127 | 0 | 0 | elsif($niveis == 0) {1} | ||||
128 | else {1} | ||||||
129 | } | ||||||
130 | |||||||
131 | ### | ||||||
132 | # | ||||||
133 | # | ||||||
134 | sub _default_norelations { | ||||||
135 | return { | ||||||
136 | 12 | 12 | 89 | 'URL'=> 1, | |||
137 | 'SN' => 1 | ||||||
138 | }; | ||||||
139 | } | ||||||
140 | |||||||
141 | ### | ||||||
142 | # | ||||||
143 | # | ||||||
144 | sub _default_inversions { | ||||||
145 | 12 | 12 | 115 | +{ NT => 'BT', BT => 'NT', RT => 'RT', USE => 'UF', UF => 'USE' }; | |||
146 | } | ||||||
147 | |||||||
148 | ### | ||||||
149 | # | ||||||
150 | # | ||||||
151 | sub _translateTerm { | ||||||
152 | 0 | 0 | 0 | my ($self,$term,$lang,$dic) = @_; | |||
153 | 0 | 0 | 0 | $dic = {} unless $dic; | |||
154 | |||||||
155 | 0 | 0 | $lang = uc($lang); | ||||
156 | # Se foi $lang definido como linguagem | ||||||
157 | 0 | 0 | 0 | if (defined($self->{languages}{$lang})) { | |||
158 | 0 | 0 | my $trad; | ||||
159 | # Se existe a tradução | ||||||
160 | 0 | 0 | 0 | if (defined($trad = $self->{$self->{baselang}}{$term}{$lang})) { | |||
161 | 0 | 0 | return $trad; | ||||
162 | } | ||||||
163 | } | ||||||
164 | |||||||
165 | 0 | 0 | 0 | if(defined $dic->{$term}) {return $dic->{ $term}} | |||
0 | 0 | ||||||
166 | 0 | 0 | 0 | if(defined $dic->{lcfirst($term)}) {return ucfirst($dic->{lcfirst($term)})} | |||
0 | 0 | ||||||
167 | 0 | 0 | 0 | if(defined $dic->{lc($term)}) {return uc($dic->{ lc($term)})} | |||
0 | 0 | ||||||
168 | |||||||
169 | 0 | 0 | return "[$self->{baselang}-$lang:".$self->getdefinition($term)."]"; | ||||
170 | } | ||||||
171 | |||||||
172 | |||||||
173 | ### | ||||||
174 | # | ||||||
175 | # | ||||||
176 | sub appendThesaurus { | ||||||
177 | 2 | 2 | 1 | 7 | my ($self,$other) = @_; | ||
178 | |||||||
179 | # This way we handle full thesaurus objects or simple filename | ||||||
180 | 2 | 50 | 9 | unless (ref($other)) { | |||
181 | 2 | 6 | $other = thesaurusLoad($other); | ||||
182 | } | ||||||
183 | |||||||
184 | 2 | 4 | my $new; | ||||
185 | |||||||
186 | # Check if baselang is the same, or if some of them is undefined | ||||||
187 | 2 | 100 | 13 | if ($self->{baselang} eq $other->{baselang}) { | |||
50 | |||||||
50 | |||||||
188 | 1 | 4 | $new->{baselang} = $self->{baselang} | ||||
189 | |||||||
190 | } elsif ($self->{baselang} eq "_") { | ||||||
191 | 0 | 0 | $new->{baselang} = $other->{baselang} | ||||
192 | |||||||
193 | } elsif ($other->{baselang} eq "_") { | ||||||
194 | 1 | 3 | $new->{baselang} = $self->{baselang} | ||||
195 | |||||||
196 | } else { | ||||||
197 | 0 | 0 | return undef; | ||||
198 | } | ||||||
199 | |||||||
200 | # If some of the top is _top_, the other is choosed. If | ||||||
201 | # there are two different tops, use the first ($self) one | ||||||
202 | 2 | 100 | 12 | if ($other->{name} eq $self->{name}) { | |||
50 | |||||||
50 | |||||||
203 | 1 | 2 | $new->{name} = $self->{name} | ||||
204 | |||||||
205 | } elsif ($other->{name} eq "_top_") { | ||||||
206 | 0 | 0 | $new->{name} = $self->{name} | ||||
207 | |||||||
208 | } elsif ($self->{name} eq "_top_") { | ||||||
209 | 1 | 3 | $new->{name} = $other->{name} | ||||
210 | |||||||
211 | } else { | ||||||
212 | 0 | 0 | $new->{name} = $self->{name} | ||||
213 | } | ||||||
214 | |||||||
215 | # VERSION: current module version | ||||||
216 | 2 | 6 | $new->{version} = $VERSION; | ||||
217 | |||||||
218 | sub _ffjoin { | ||||||
219 | # key, hash1ref, hash2ref | ||||||
220 | 8 | 8 | 18 | my ($c,$a,$b) = @_; | |||
221 | 8 | 50 | 33 | 44 | if (exists($a->{$c}) && exists($b->{$c})) { | ||
0 | |||||||
0 | |||||||
222 | 8 | 11 | return {%{$a->{$c}},%{$b->{$c}}}; | ||||
8 | 33 | ||||||
8 | 56 | ||||||
223 | } elsif (exists($a->{$c})) { | ||||||
224 | 0 | 0 | return {%{$a->{$c}}} | ||||
0 | 0 | ||||||
225 | } elsif (exists($b->{$c})) { | ||||||
226 | 0 | 0 | return {%{$b->{$c}}} | ||||
0 | 0 | ||||||
227 | } else { | ||||||
228 | return {} | ||||||
229 | 0 | 0 | } | ||||
230 | } | ||||||
231 | |||||||
232 | # Inverses: join hash tables... in conflict, $self is used | ||||||
233 | 2 | 7 | $new->{inverses} = _ffjoin("inverses",$other,$self); | ||||
234 | |||||||
235 | # Descriptions: in conflict, $self is used | ||||||
236 | 2 | 11 | $new->{descriptions} = _ffjoin("descriptions",$other,$self); | ||||
237 | |||||||
238 | # Externals: union | ||||||
239 | 2 | 9 | $new->{externals} = _ffjoin("externals",$self,$other); | ||||
240 | |||||||
241 | # Languages: union | ||||||
242 | 2 | 15 | $new->{languages} = _ffjoin("languages",$self,$other); | ||||
243 | # delete($new->{languages}{"_"}) if ($new->{baselang} ne "_"); | ||||||
244 | |||||||
245 | # Get terms for the new thesaurus | ||||||
246 | 2 | 10 | my @terms = _set_of(keys %{$self ->{$self ->{baselang}}}, | ||||
2 | 12 | ||||||
247 | 2 | 13 | keys %{$other->{$other->{baselang}}}); | ||||
248 | |||||||
249 | # Para cada termo do thesaurus... | ||||||
250 | 2 | 8 | for my $term (@terms) { | ||||
251 | |||||||
252 | # existe em ambos... | ||||||
253 | 20 | 100 | 100 | 44 | if ($self->isDefined($term) && $other->isDefined($term)) { | ||
100 | |||||||
254 | 6 | 17 | my ($a_def,$b_def) = ($self->_definition($term), | ||||
255 | $other->_definition($term)); | ||||||
256 | 6 | 12 | my $def = $a_def; | ||||
257 | |||||||
258 | 6 | 19 | $new->{defined}{lc($def)} = $def; | ||||
259 | |||||||
260 | 6 | 18 | my @class = _set_of(keys %{$self ->{$self ->{baselang}}{$a_def}}, | ||||
6 | 23 | ||||||
261 | 6 | 9 | keys %{$other->{$other->{baselang}}{$b_def}}); | ||||
262 | |||||||
263 | # para cada uma das suas relações... | ||||||
264 | 6 | 13 | for my $class (@class) { | ||||
265 | 16 | 100 | 56 | if ($class eq "_NAME_") { | |||
100 | |||||||
50 | |||||||
266 | |||||||
267 | # print STDERR Dumper($new->{$new->{baselang}}{$def}); | ||||||
268 | # optar pela forma do thesaurus A | ||||||
269 | 6 | 24 | $new->{$new->{baselang}}{$def}{_NAME_} = $def; | ||||
270 | |||||||
271 | } elsif ($new->{externals}{$class}) { | ||||||
272 | 1 | 50 | 5 | if (exists($self->{$self->{baselang}}{$a_def}{$class})) { | |||
273 | 1 | 9 | push @{$new->{$new->{baselang}}{$def}{$class}}, | ||||
1 | 4 | ||||||
274 | 1 | 2 | @{$self->{$self->{baselang}}{$a_def}{$class}}; | ||||
275 | } | ||||||
276 | 1 | 50 | 4 | if (exists($other->{$other->{baselang}}{$b_def}{$class})) { | |||
277 | 0 | 0 | push @{$new->{$new->{baselang}}{$def}{$class}}, | ||||
0 | 0 | ||||||
278 | 0 | 0 | @{$other->{$other->{baselang}}{$b_def}{$class}}; | ||||
279 | } | ||||||
280 | |||||||
281 | } elsif ($new->{languages}{$class}) { | ||||||
282 | 0 | 0 | $new->{$new->{baselang}}{$def}{$class} = "_"; | ||||
283 | |||||||
284 | } else { | ||||||
285 | 9 | 100 | 100 | 61 | if (exists($self ->{$self ->{baselang}}{$a_def}{$class}) && | ||
100 | |||||||
286 | exists($other->{$other->{baselang}}{$b_def}{$class})) { | ||||||
287 | |||||||
288 | # Join lists | ||||||
289 | 6 | 10 | my %there; | ||||
290 | 6 | 19 | @there{@{$self->{$self->{baselang}}{$a_def}{$class}}} = | ||||
6 | 19 | ||||||
291 | 6 | 8 | 1 x @{$self->{$self->{baselang}}{$a_def}{$class}}; | ||||
292 | |||||||
293 | 6 | 8 | push @{$new->{$new->{baselang}}{$def}{$class}}, keys %there; | ||||
6 | 23 | ||||||
294 | |||||||
295 | 6 | 11 | for (@{$other->{$other->{baselang}}{$b_def}{$class}}) { | ||||
6 | 17 | ||||||
296 | 7 | 100 | 56 | unless ($there{$_}) { | |||
297 | 5 | 8 | push @{$new->{$new->{baselang}}{$def}{$class}}, $_; | ||||
5 | 13 | ||||||
298 | } | ||||||
299 | 7 | 24 | $there{$_} = 1; | ||||
300 | } | ||||||
301 | |||||||
302 | } elsif (exists($self->{$self->{baselang}}{$a_def}{$class})) { | ||||||
303 | 2 | 13 | $new->{$new->{baselang}}{$def}{$class} = | ||||
304 | $self->{$self->{baselang}}{$a_def}{$class}; | ||||||
305 | } else { ## other->b_def->class | ||||||
306 | 1 | 12 | $new->{$new->{baselang}}{$def}{$class} = | ||||
307 | $other->{$other->{baselang}}{$b_def}{$class}; | ||||||
308 | } | ||||||
309 | } | ||||||
310 | } | ||||||
311 | |||||||
312 | } elsif ($self->isDefined($term)) { | ||||||
313 | 9 | 17 | $new->{defined}{lc($term)} = $self->_definition($term); | ||||
314 | 9 | 41 | $new->{$new->{baselang}}{$term} = $self->{$self->{baselang}}{$term}; | ||||
315 | } else { ### $other->isDefined($term) | ||||||
316 | 5 | 12 | $new->{defined}{lc($term)} = $other->_definition($term); | ||||
317 | 5 | 72 | $new->{$new->{baselang}}{$term} = $other->{$other->{baselang}}{$term}; | ||||
318 | } | ||||||
319 | } | ||||||
320 | |||||||
321 | 2 | 57 | return bless($new); | ||||
322 | } | ||||||
323 | |||||||
324 | |||||||
325 | ### | ||||||
326 | # | ||||||
327 | # | ||||||
328 | sub thesaurusMultiLoad { | ||||||
329 | 1 | 1 | 1 | 813 | my @files = @_; | ||
330 | |||||||
331 | 1 | 6 | my $self = thesaurusLoad(shift @files); | ||||
332 | 1 | 4 | while(@files) { | ||||
333 | 1 | 5 | $self->appendThesaurus(shift @files); | ||||
334 | } | ||||||
335 | |||||||
336 | 1 | 5 | return $self; | ||||
337 | } | ||||||
338 | |||||||
339 | ### | ||||||
340 | # | ||||||
341 | # | ||||||
342 | sub top { | ||||||
343 | 0 | 0 | 1 | 0 | my $self = shift; | ||
344 | 0 | 0 | my $script = shift; | ||||
345 | 0 | 0 | return "
|
||||
346 | 0 | 0 | map {" |
||||
347 | 0 | 0 | @{$self->{$self->{baselang}}->{$self->{name}}->{NT}}). ""; | ||||
348 | } | ||||||
349 | |||||||
350 | ### | ||||||
351 | # | ||||||
352 | # | ||||||
353 | sub _default_descriptions { | ||||||
354 | return { | ||||||
355 | 12 | 12 | 99 | 'RT' => q/Related term/, | |||
356 | 'TT' => q/Top term/, | ||||||
357 | 'NT' => q/Narrower term/, | ||||||
358 | 'BT' => q/Broader term/, | ||||||
359 | 'USE' => q/Synonym/, | ||||||
360 | 'UF' => q/Quasi synonym/, | ||||||
361 | 'SN' => q/Scope note/, | ||||||
362 | }; | ||||||
363 | } | ||||||
364 | |||||||
365 | sub setExternal { | ||||||
366 | 0 | 0 | 1 | 0 | my ($self,@rels) = @_; | ||
367 | 0 | 0 | for (@rels) { | ||||
368 | 0 | 0 | $self->{externals}{uc($_)} = 1; | ||||
369 | } | ||||||
370 | 0 | 0 | return $self; | ||||
371 | } | ||||||
372 | |||||||
373 | sub isExternal { | ||||||
374 | 0 | 0 | 1 | 0 | my ($self,$ext) = @_; | ||
375 | 0 | 0 | 0 | return (defined($self->{externals}{uc($ext)}) && | |||
376 | defined($self->{externals}{uc($ext)}) == 1); | ||||||
377 | } | ||||||
378 | |||||||
379 | ### | ||||||
380 | # | ||||||
381 | # | ||||||
382 | sub thesaurusNew { | ||||||
383 | 2 | 2 | 1 | 456 | my $obj = { | ||
384 | # thesaurus => {}, | ||||||
385 | inverses => _default_inversions(), | ||||||
386 | descriptions => _default_descriptions(), | ||||||
387 | externals => _default_norelations(), | ||||||
388 | name => '_top_', | ||||||
389 | baselang => '?', | ||||||
390 | languages => {}, | ||||||
391 | version => $VERSION, | ||||||
392 | prefix => "", | ||||||
393 | }; | ||||||
394 | |||||||
395 | # bless and return it! Amen! | ||||||
396 | 2 | 9 | return bless($obj); | ||||
397 | } | ||||||
398 | |||||||
399 | ### | ||||||
400 | # | ||||||
401 | # | ||||||
402 | sub storeOn { | ||||||
403 | 1 | 1 | 1 | 31 | store(@_); | ||
404 | } | ||||||
405 | |||||||
406 | ### | ||||||
407 | # | ||||||
408 | # | ||||||
409 | sub thesaurusRetrieve { | ||||||
410 | 1 | 1 | 1 | 783899 | my $file = shift; | ||
411 | 1 | 11 | my $obj = retrieve($file); | ||||
412 | 1 | 50 | 378053 | if (defined($obj->{version})) { | |||
413 | 1 | 12 | return $obj; | ||||
414 | } else { | ||||||
415 | 0 | 0 | die("Rebuild your thesaurus with a recent Biblio::Thesaurus version"); | ||||
416 | } | ||||||
417 | } | ||||||
418 | |||||||
419 | ### | ||||||
420 | # | ||||||
421 | # | ||||||
422 | sub _trurl { | ||||||
423 | 0 | 0 | 0 | my $t = shift; | |||
424 | 0 | 0 | $t =~ s/\s/+/g; | ||||
425 | 0 | 0 | return $t; | ||||
426 | } | ||||||
427 | |||||||
428 | ### | ||||||
429 | # | ||||||
430 | # | ||||||
431 | sub getHTMLTop { | ||||||
432 | 0 | 0 | 1 | 0 | my $self = shift; | ||
433 | 0 | 0 | 0 | my $script = shift || $ENV{SCRIPT_NAME}; | |||
434 | 0 | 0 | my $t = "
|
||||
435 | 0 | 0 | $t.=join("\n", | ||||
436 | 0 | 0 | map { " |
||||
437 | 0 | 0 | @{$self->{$self->{baselang}}->{$self->{name}}->{NT}}); | ||||
438 | 0 | 0 | $t .= ""; | ||||
439 | 0 | 0 | return $t; | ||||
440 | } | ||||||
441 | |||||||
442 | ### | ||||||
443 | # | ||||||
444 | # | ||||||
445 | sub thesaurusLoad { | ||||||
446 | |||||||
447 | 10 | 10 | 1 | 2182 | my %opt =(); | ||
448 | # completed => 1 | ||||||
449 | 10 | 50 | 48 | if(ref($_[0]) eq "HASH") {%opt = (%opt , %{shift(@_)}) } ; | |||
0 | 0 | ||||||
0 | 0 | ||||||
450 | |||||||
451 | 10 | 22 | my ($file,$self) = @_; | ||||
452 | 10 | 18 | my %thesaurus; | ||||
453 | |||||||
454 | 10 | 50 | 37 | unless($self){ | |||
455 | 10 | 37 | $self->{inverses} = _default_inversions(); | ||||
456 | 10 | 34 | $self->{descriptions} = _default_descriptions(); | ||||
457 | 10 | 34 | $self->{externals} = _default_norelations(); | ||||
458 | 10 | 26 | $self->{name} = "_top_"; | ||||
459 | 10 | 25 | $self->{baselang} = "_"; | ||||
460 | 10 | 30 | $self->{languages} = {}; | ||||
461 | 10 | 21 | $self->{defined} = {}; | ||||
462 | 10 | 39 | $self->{version} = $VERSION; } | ||||
463 | else { | ||||||
464 | 0 | 0 | $self->{defined} = {}; | ||||
465 | } | ||||||
466 | |||||||
467 | # Open the thesaurus file to load | ||||||
468 | 10 | 50 | 531 | open ISO, $file or die (q/Can't open thesaurus file/); | |||
469 | ### binmode(ISO,"$opt{encoding}:") if($opt{encoding}); | ||||||
470 | |||||||
471 | # While we have commands or comments or empty lines, continue... | ||||||
472 | 10 | 368 | while(($_ = |
||||
473 | 104 | 14851 | chomp; | ||||
474 | |||||||
475 | 104 | 100 | 1078 | if (/^%\s*inv(?:erse)?\s+(\S+)\s+(\S+)/) { | |||
100 | |||||||
50 | |||||||
50 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
50 | |||||||
476 | |||||||
477 | # Treat the inv*erse command | ||||||
478 | 17 | 55 | $self->{inverses}{uc($1)} = uc($2); | ||||
479 | 17 | 99 | $self->{inverses}{uc($2)} = uc($1); | ||||
480 | |||||||
481 | } elsif (/^%\s*enc(oding)?\s+(\S+)/) { | ||||||
482 | |||||||
483 | 1 | 6 | $self->{encoding} = lc $2; | ||||
484 | 1 | 5 | $self->{encoding} =~ s/_/-/g; | ||||
485 | 1 | 1 | 9 | binmode ISO, ":encoding($self->{encoding})"; | |||
1 | 2 | ||||||
1 | 10 | ||||||
1 | 38 | ||||||
486 | |||||||
487 | } elsif (/^%\s*tit(le)?\s+(.+)/) { | ||||||
488 | 0 | 0 | $self->{title} = $2; | ||||
489 | |||||||
490 | } elsif (/^%\s*aut(hor)?\s+(.+)/) { | ||||||
491 | 0 | 0 | $self->{author} = $2; | ||||
492 | |||||||
493 | } elsif (/^%\s*desc(ription)?\[(\S+)\]\s+(\S+)\s+(.*)$/) { | ||||||
494 | |||||||
495 | # Treat the desc*cription [lang] command.... 'RT EN' | ||||||
496 | 2 | 22 | $self->{descriptions}{uc($3)." ".uc($2)} = $3; | ||||
497 | |||||||
498 | } elsif (/^%\s*desc(ription)?\s+(\S+)\s+(.*)$/) { | ||||||
499 | |||||||
500 | # Treat the desc*cription command | ||||||
501 | 30 | 237 | $self->{descriptions}{uc($2)} = $3; | ||||
502 | |||||||
503 | } elsif (/^%\s*ext(ernals?)?\s+(.*)$/) { | ||||||
504 | |||||||
505 | # Treat the ext*ernals command | ||||||
506 | 4 | 15 | chomp(my $classes = uc($2)); | ||||
507 | 4 | 18 | for (split /\s+/, $classes) { | ||||
508 | 8 | 46 | $self->{externals}{$_} = 1; | ||||
509 | } | ||||||
510 | |||||||
511 | } elsif (/^%\s*lang(uages?)?\s+(.*)$/) { | ||||||
512 | |||||||
513 | # Treat the lang*uages command | ||||||
514 | 4 | 12 | chomp(my $classes = uc($2)); | ||||
515 | 4 | 15 | for (split /\s+/, $classes) { | ||||
516 | 4 | 32 | $self->{languages}{$_} = 1; | ||||
517 | } | ||||||
518 | |||||||
519 | } elsif (/^%\s*top\s+(.*)$/) { | ||||||
520 | |||||||
521 | 5 | 36 | $self->{name} = $1; | ||||
522 | |||||||
523 | } elsif (/^%\s*baselang(uage)?\s+(\S+)/) { | ||||||
524 | |||||||
525 | 8 | 116 | $self->{baselang} = uc($2); | ||||
526 | |||||||
527 | } elsif (/^%/) { | ||||||
528 | |||||||
529 | 0 | 0 | print STDERR "Unknown command: '$_'\n\n"; | ||||
530 | |||||||
531 | } else { | ||||||
532 | # It's a comment or an empty line: do nothing | ||||||
533 | } | ||||||
534 | } | ||||||
535 | |||||||
536 | # Redefine the record separator | ||||||
537 | 10 | 27 | my $old_sep = $/; | ||||
538 | 10 | 26 | $/ = ""; | ||||
539 | |||||||
540 | # The last line wasn't a comment, a command or an empty line, so use it! | ||||||
541 | 10 | 37 | $_ .= |
||||
542 | |||||||
543 | 10 | 55 | my $ncommands = $.-1; | ||||
544 | |||||||
545 | # While there are definitions... | ||||||
546 | 10 | 16 | do { | ||||
547 | # define local variables | ||||||
548 | 148 | 160 | my ($class,$term,$relations); | ||||
549 | |||||||
550 | ## Concat lines that continue back in one | ||||||
551 | 148 | 474 | s/\n[ \t]+/ /g; # Can't use \s because "\n" =~ m!\s! | ||||
552 | |||||||
553 | # The first line contains the term to be defined | ||||||
554 | 148 | 773 | /(.+)(?:\n((.|\n)+)|\n?$)/; | ||||
555 | 148 | 281 | $term = $1; | ||||
556 | 148 | 100 | 417 | $relations = $2 || ""; | |||
557 | |||||||
558 | # If the term is all spaces, go back... | ||||||
559 | 148 | 50 | 458 | if ($term =~ /^\s+$/) { | |||
560 | 0 | 0 | print STDERR "Term with only spaces ignored at block term ",$.-$ncommands,"\n\n"; | ||||
561 | 0 | 0 | $term = '#zbr'; # This makes the next loop think this is a comment and ignore it | ||||
562 | } | ||||||
563 | |||||||
564 | # Let's see if the term is commented... | ||||||
565 | 148 | 50 | 299 | unless ($term =~ /^#/) { | |||
566 | 148 | 240 | $term = _term_normalize($term); | ||||
567 | |||||||
568 | 148 | 50 | 448 | $term = $self->{defined}{lc($term)} if ($self->{defined}{lc($term)}); | |||
569 | 148 | 557 | $thesaurus{$term}{_NAME_} = $term; | ||||
570 | 148 | 320 | $self->{defined}{lc($term)} = $term; | ||||
571 | |||||||
572 | # The remaining are relations | ||||||
573 | 148 | 250 | $_ = $relations; | ||||
574 | |||||||
575 | # OK! The term is *not* commented... | ||||||
576 | # For each definition line... | ||||||
577 | 148 | 100 | 471 | $_.="\n" unless /\n$/; | |||
578 | 148 | 639 | while (/((([^#\s]+)|#)[ \t]*(.*)\n)/g) { | ||||
579 | 253 | 100 | 618 | next unless $4; | |||
580 | # Is it commented? | ||||||
581 | 250 | 50 | 636 | unless ($2 eq "#") { | |||
582 | # it seems not... set the relation class | ||||||
583 | 250 | 368 | $class = uc($2); # || $class;... now multiline are handled before this | ||||
584 | |||||||
585 | 250 | 50 | 423 | print STDERR "** WARNING **: '$1'\n" unless $class; | |||
586 | |||||||
587 | # See if $class has a description | ||||||
588 | 250 | 100 | 593 | $self->{descriptions}{$class} = ucfirst(lc($class)) unless defined $self->{descriptions}{$class}; | |||
589 | ## $descs->{$class}= ucfirst(lc($class)) unless(defined($descs->{$class})); | ||||||
590 | |||||||
591 | # divide the relation terms by comma unless it is a language or extern relation | ||||||
592 | 250 | 100 | 66 | 1137 | if ( exists($self->{externals}{$class}) && defined($self->{externals}{$class}) ) { | ||
100 | 66 | ||||||
593 | ## $thesaurus{$term}{$class}.= ($2?"$4":" $4"); | ||||||
594 | ## $thesaurus{$term}{$class}.= ($thesaurus{$term}{$class}?" $4":"$4"); | ||||||
595 | 22 | 23 | push @{$thesaurus{$term}{$class}}, $4; | ||||
22 | 202 | ||||||
596 | } elsif (exists($self->{languages}{$class}) && defined($self->{languages}{$class})) { | ||||||
597 | # $translations->{$class}->{_term_normalize($4)}.=$term; | ||||||
598 | 5 | 21 | $self->{$class}{$4}.=$term; | ||||
599 | 5 | 16 | $self->{defined}{_term_normalize(lc($4))} = $term; | ||||
600 | 5 | 31 | $thesaurus{$term}{$class} = $4; | ||||
601 | } else { | ||||||
602 | 223 | 1310 | push(@{$thesaurus{$term}{$class}}, map { | ||||
481 | 712 | ||||||
603 | 223 | 218 | _term_normalize($_) | ||||
604 | } split(/\s*,\s*/, $4)); | ||||||
605 | } | ||||||
606 | } | ||||||
607 | } | ||||||
608 | } | ||||||
609 | } while( |
||||||
610 | |||||||
611 | # Close the ISO thesaurus file | ||||||
612 | 10 | 137 | close ISO; | ||||
613 | |||||||
614 | # revert to the old record separator. Not needed, but beautifer. | ||||||
615 | 10 | 28 | $/ = $old_sep; | ||||
616 | |||||||
617 | 10 | 37 | $self->{$self->{baselang}} = \%thesaurus; | ||||
618 | 10 | 32 | $self->{languages}{$self->{baselang}} = 1; | ||||
619 | |||||||
620 | # bless and return the thesaurus! Amen! | ||||||
621 | 10 | 50 | 33 | 54 | if (exists($opt{completed}) && $opt{completed}) { | ||
622 | 0 | 0 | return bless($self); | ||||
623 | } else { | ||||||
624 | 10 | 42 | return complete(bless($self)); | ||||
625 | } | ||||||
626 | } | ||||||
627 | |||||||
628 | sub _lc{ | ||||||
629 | 0 | 0 | 0 | 0 | if($casesen){$_[0]} | ||
0 | 0 | ||||||
0 | 0 | ||||||
630 | else {lc($_[0])} | ||||||
631 | } | ||||||
632 | |||||||
633 | sub thesaurusLoadM { | ||||||
634 | 0 | 0 | 1 | 0 | my $file = shift; | ||
635 | 0 | 0 | my ($t,$rs)= _treatMetas1(thesaurusLoad($file)); | ||||
636 | 0 | 0 | 0 | if(@$rs){ | |||
0 | 0 | ||||||
637 | 0 | 0 | undef $t->{$t->{baselang}}; | ||||
638 | 0 | 0 | undef $t->{defined}; | ||||
639 | 0 | 0 | _treatMetas2(thesaurusLoad($file,$t),$rs);} | ||||
640 | else{$t} | ||||||
641 | } | ||||||
642 | |||||||
643 | sub _treatMetas1 { | ||||||
644 | 0 | 0 | 0 | my $t = shift; | |||
645 | 0 | 0 | my @ts=(); | ||||
646 | 0 | 0 | my %r=(); | ||||
647 | |||||||
648 | 0 | 0 | 0 | if(@ts=$t->terms("_order_","NT")) { $t->order(@ts); | |||
0 | 0 | ||||||
649 | 0 | 0 | @r{@ts,"_order_"}=(@ts,1) } | ||||
650 | 0 | 0 | 0 | if(@ts=$t->terms("_external_","NT")){ $t->setExternal(@ts); | |||
0 | 0 | ||||||
651 | 0 | 0 | @r{@ts,"_external_"}=(@ts,1) } | ||||
652 | 0 | 0 | 0 | if(@ts=$t->terms("_top_","NT")) { $t->topName($ts[0]); | |||
0 | 0 | ||||||
653 | 0 | 0 | $r{"_top_"}=1 } | ||||
654 | 0 | 0 | 0 | if(@ts=$t->terms("baselang_","NT")){ $t->baselang($ts[0]); | |||
0 | 0 | ||||||
655 | 0 | 0 | @r{@ts,"baselang_"}=(@ts,1) } | ||||
656 | 0 | 0 | 0 | if(@ts=$t->terms("_language_","NT")){ $t->languages(@ts); | |||
0 | 0 | ||||||
657 | 0 | 0 | @r{@ts,"_language_"}=(@ts,1) } | ||||
658 | 0 | 0 | 0 | if(@ts=$t->terms("_symmetric_","NT")){ for(@ts){ $t->addInverse($_,$_);} | |||
0 | 0 | ||||||
0 | 0 | ||||||
659 | 0 | 0 | @r{@ts,"_symmetric_"}=(@ts,1) } | ||||
660 | |||||||
661 | # for each new relation describe it, add Invers and remove it as Term | ||||||
662 | 0 | 0 | 0 | if(@ts=$t->terms("_relation_","NT")){ | |||
663 | 0 | 0 | $r{"_relation_"}=1 ; | ||||
664 | $t->downtr( | ||||||
665 | 0 | 0 | 0 | { SN => sub{ $t->describe({rel => $term, desc=>$terms[0]}) }, ## FALTA A LINGUA | |||
666 | 0 | 0 | 0 | INV => sub{ $t->addInverse($term,$terms[0])}, | |||
667 | 0 | 0 | 0 | RANG => sub{ $t->setExternal($term)}, | |||
668 | -order => ["SN","INV"], | ||||||
669 | 0 | 0 | 0 | -eachTerm => sub{ $r{$term}=$term }, | |||
670 | 0 | 0 | }, @ts); | ||||
671 | } | ||||||
672 | 0 | 0 | ($t,[(keys %r)]); | ||||
673 | } | ||||||
674 | |||||||
675 | sub _treatMetas2{ | ||||||
676 | 0 | 0 | 0 | my ($t,$rs)= @_; | |||
677 | 0 | 0 | for (@$rs){ $t->deleteTerm($_)} | ||||
0 | 0 | ||||||
678 | 0 | 0 | $t; | ||||
679 | } | ||||||
680 | |||||||
681 | ### | ||||||
682 | # | ||||||
683 | # | ||||||
684 | sub getDescription { | ||||||
685 | 0 | 0 | 1 | 0 | my ($obj, $rel, $lang) = @_; | ||
686 | 0 | 0 | 0 | if (defined($lang)) { | |||
687 | 0 | 0 | my $x = uc($rel)." ".uc($lang); | ||||
688 | 0 | 0 | 0 | return exists($obj->{descriptions}->{$x})?$obj->{descriptions}->{$x}:"..."; | |||
689 | } else { | ||||||
690 | 0 | 0 | my $x = uc($rel)." ".uc($obj->{baselang}); | ||||
691 | 0 | 0 | 0 | if (exists($obj->{descriptions}->{$x})) { | |||
0 | |||||||
692 | 0 | 0 | return $obj->{descriptions}->{$x}; | ||||
693 | } elsif (exists($obj->{descriptions}->{$rel})) { | ||||||
694 | 0 | 0 | return $obj->{descriptions}->{$rel}; | ||||
695 | } else { | ||||||
696 | 0 | 0 | return "..."; | ||||
697 | } | ||||||
698 | } | ||||||
699 | } | ||||||
700 | |||||||
701 | ### | ||||||
702 | # | ||||||
703 | # | ||||||
704 | sub describe { | ||||||
705 | 0 | 0 | 1 | 0 | my ($obj, $conf) = @_; | ||
706 | 0 | 0 | my ($class, $desc, $lang); | ||||
707 | 0 | 0 | 0 | return unless ($class = uc($conf->{rel})); | |||
708 | 0 | 0 | 0 | return unless ($desc = $conf->{desc}); | |||
709 | 0 | 0 | 0 | if ($conf->{lang}) { | |||
710 | 0 | 0 | $lang = " ".uc($conf->{lang}); | ||||
711 | } else { | ||||||
712 | 0 | 0 | $lang = ""; | ||||
713 | } | ||||||
714 | |||||||
715 | 0 | 0 | $obj->{descriptions}->{$class.$lang}=$desc; | ||||
716 | } | ||||||
717 | |||||||
718 | ### | ||||||
719 | # | ||||||
720 | # | ||||||
721 | sub addInverse { | ||||||
722 | 0 | 0 | 1 | 0 | my ($obj,$a,$b) = @_; | ||
723 | 0 | 0 | $a = uc($a); | ||||
724 | 0 | 0 | $b = uc($b); | ||||
725 | 0 | 0 | 0 | $obj->{descriptions}{$a}="..." unless(defined($obj->{descriptions}{$a})); | |||
726 | 0 | 0 | 0 | $obj->{descriptions}{$b}="..." unless(defined($obj->{descriptions}{$b})); | |||
727 | |||||||
728 | 0 | 0 | for (keys %{$obj->{inverses}}) { | ||||
0 | 0 | ||||||
729 | 0 | 0 | 0 | 0 | delete($obj->{inverses}{$_}) if (($obj->{inverses}{$_} eq $a) || | ||
730 | ($obj->{inverses}{$_} eq $b)); | ||||||
731 | } | ||||||
732 | 0 | 0 | $obj->{inverses}{$a}=$b; | ||||
733 | 0 | 0 | $obj->{inverses}{$b}=$a; | ||||
734 | } | ||||||
735 | |||||||
736 | ### | ||||||
737 | # | ||||||
738 | # | ||||||
739 | sub meta2str { | ||||||
740 | 0 | 0 | 1 | 0 | my $obj = shift; | ||
741 | 0 | 0 | my $term; | ||||
742 | 0 | 0 | my %inverses = %{$obj->{inverses}}; | ||||
0 | 0 | ||||||
743 | 0 | 0 | my %descs = %{$obj->{descriptions}}; | ||||
0 | 0 | ||||||
744 | |||||||
745 | 0 | 0 | my $t = ""; | ||||
746 | |||||||
747 | # Save the 'encoding' command | ||||||
748 | # | ||||||
749 | 0 | 0 | 0 | $t.="\%encoding $obj->{encoding}\n\n" if defined $obj->{encoding} ; | |||
750 | |||||||
751 | # Save the 'title' command | ||||||
752 | # | ||||||
753 | 0 | 0 | 0 | $t.="\%title $obj->{title}\n\n" if defined $obj->{title}; | |||
754 | |||||||
755 | # Save the 'author' command | ||||||
756 | # | ||||||
757 | 0 | 0 | 0 | $t.="\%author $obj->{author}\n\n" if defined $obj->{author}; | |||
758 | |||||||
759 | # Save the externals commands | ||||||
760 | # | ||||||
761 | 0 | 0 | $t.= "\%externals " . join(" ",keys %{$obj->{externals}}); | ||||
0 | 0 | ||||||
762 | 0 | 0 | $t.="\n\n"; | ||||
763 | |||||||
764 | # Save the languages commands | ||||||
765 | # | ||||||
766 | 0 | 0 | $t.= "\%languages " . join(" ",keys %{$obj->{languages}}); | ||||
0 | 0 | ||||||
767 | 0 | 0 | $t.="\n\n"; | ||||
768 | |||||||
769 | # Save the 'top' command | ||||||
770 | # | ||||||
771 | 0 | 0 | 0 | $t.="\%top $obj->{name}\n\n" if $obj->{name} ne "_top_"; | |||
772 | |||||||
773 | # Save the 'baselanguage' command | ||||||
774 | # | ||||||
775 | 0 | 0 | 0 | $t.="\%baselanguage $obj->{baselang}\n\n" if $obj->{baselang} ne "_"; | |||
776 | |||||||
777 | # Save the inverses commands | ||||||
778 | # | ||||||
779 | 0 | 0 | for $term (keys %inverses) { | ||||
780 | 0 | 0 | $t.= "\%inverse $term $inverses{$term}\n"; | ||||
781 | } | ||||||
782 | 0 | 0 | $t.="\n\n"; | ||||
783 | |||||||
784 | # Save the descriptions commands | ||||||
785 | # | ||||||
786 | 0 | 0 | for $term (keys %descs) { | ||||
787 | 0 | 0 | 0 | if ( $term =~ /^(\w+)\s+(\w+)$/ ) { | |||
788 | 0 | 0 | $t.= "\%description[$2] $1 $descs{$term}\n"; | ||||
789 | } else { | ||||||
790 | 0 | 0 | $t.= "\%description $term $descs{$term}\n"; | ||||
791 | } | ||||||
792 | } | ||||||
793 | 0 | 0 | $t.="\n\n"; | ||||
794 | 0 | 0 | $t; | ||||
795 | } | ||||||
796 | |||||||
797 | ## | ||||||
798 | # | ||||||
799 | # | ||||||
800 | sub save { | ||||||
801 | 0 | 0 | 1 | 0 | my $obj = shift; | ||
802 | 0 | 0 | my $file = shift; | ||||
803 | 0 | 0 | my ($term,$class); | ||||
804 | 0 | 0 | my %thesaurus = %{$obj->{$obj->{baselang}}}; | ||||
0 | 0 | ||||||
805 | 0 | 0 | my $t = meta2str($obj); #save the metadata | ||||
806 | |||||||
807 | # Save the thesaurus | ||||||
808 | # | ||||||
809 | 0 | 0 | for $term (keys %thesaurus) { | ||||
810 | 0 | 0 | $t.= "\n$thesaurus{$term}{_NAME_}\n"; | ||||
811 | 0 | 0 | for $class ( keys %{$thesaurus{$term}} ) { | ||||
0 | 0 | ||||||
812 | 0 | 0 | 0 | next if $class eq "_NAME_"; | |||
813 | 0 | 0 | 0 | if(defined $obj->{languages}{$class}) { | |||
814 | 0 | 0 | $t.= "$class\t$thesaurus{$term}->{$class}\n"; | ||||
815 | } else { | ||||||
816 | # if save_compact, juntar por ',' as relacoes nao external | ||||||
817 | 0 | 0 | $t.= "$class\t$_\n" for (@{$thesaurus{$term}{$class}}); | ||||
0 | 0 | ||||||
818 | } | ||||||
819 | } | ||||||
820 | } | ||||||
821 | |||||||
822 | 0 | 0 | 0 | open F, ">$file" or return 0; | |||
823 | 0 | 0 | 0 | if (defined $obj->{encoding}) { | |||
824 | 0 | 0 | $obj->{encoding} = lc($obj->{encoding}); | ||||
825 | 0 | 0 | $obj->{encoding} =~ s/_/-/g; | ||||
826 | 0 | 0 | binmode(F,":encoding($obj->{encoding})") ; | ||||
827 | } | ||||||
828 | 0 | 0 | print F $t; | ||||
829 | 0 | 0 | close F; | ||||
830 | 0 | 0 | return 1; | ||||
831 | } | ||||||
832 | |||||||
833 | ### | ||||||
834 | # | ||||||
835 | # | ||||||
836 | sub navigate { | ||||||
837 | # The first element is the object reference | ||||||
838 | 0 | 0 | 1 | 0 | my $obj = shift; | ||
839 | # This is the script name | ||||||
840 | 0 | 0 | 0 | my $script = $ENV{SCRIPT_NAME} || ""; | |||
841 | |||||||
842 | # Get the configuration hash | ||||||
843 | 0 | 0 | my $conf = {}; | ||||
844 | 0 | 0 | 0 | if (ref($_[0])) { $conf = shift } | |||
0 | 0 | ||||||
845 | |||||||
846 | 0 | 0 | 0 | my $expander = $conf->{expand} || []; | |||
847 | 0 | 0 | my @tmp = map {$obj->{inverses}{$_}} @$expander; | ||||
0 | 0 | ||||||
848 | 0 | 0 | 0 | my $language = $conf->{lang} || undef; | |||
849 | 0 | 0 | 0 | my $second_level_limit = $conf->{level2size} || 0; | |||
850 | 0 | 0 | 0 | my $hide_on_first_level = $conf->{level1hide} || []; | |||
851 | 0 | 0 | 0 | my $hide_on_second_level = $conf->{level2hide} || \@tmp; | |||
852 | 0 | 0 | 0 | my $capitalize = $conf->{capitalize} || 0; | |||
853 | 0 | 0 | 0 | my $topic = $conf->{topic_name} || "t"; | |||
854 | |||||||
855 | 0 | 0 | my %hide; | ||||
856 | 0 | 0 | @hide{@$hide_on_first_level} = @$hide_on_first_level; | ||||
857 | |||||||
858 | 0 | 0 | 0 | $script = $conf->{scriptname} if (exists($conf->{scriptname})); | |||
859 | 0 | 0 | my %param = @_; | ||||
860 | |||||||
861 | 0 | 0 | my $term; | ||||
862 | 0 | 0 | my $show_title = 1; | ||||
863 | 0 | 0 | 0 | if (exists($param{$topic})) { | |||
864 | 0 | 0 | $param{$topic} =~ s/\+/ /g; | ||||
865 | 0 | 0 | $term = $obj->getdefinition($param{$topic}); | ||||
866 | } else { | ||||||
867 | 0 | 0 | 0 | 0 | $show_title = 0 if exists($conf->{title}) && $conf->{title} eq "no"; | ||
868 | 0 | 0 | 0 | if ($obj->isDefined($obj->{name})) { | |||
869 | 0 | 0 | $term = $obj->{defined}{lc($obj->{name})}; | ||||
870 | } else { | ||||||
871 | 0 | 0 | $term = '_top_'; | ||||
872 | } | ||||||
873 | } | ||||||
874 | |||||||
875 | 0 | 0 | my (@terms,$html); | ||||
876 | |||||||
877 | # If we don't have the term, return only the title | ||||||
878 | 0 | 0 | 0 | return h2($term) unless ($obj->isDefined($term)); | |||
879 | |||||||
880 | # Make the page title | ||||||
881 | 0 | 0 | 0 | $html = h2(capitalize($capitalize, $obj->_translateTerm($term,$language))) if $show_title; | |||
882 | |||||||
883 | # Get the external relations | ||||||
884 | 0 | 0 | my %norel = %{$obj->{externals}}; | ||||
0 | 0 | ||||||
885 | |||||||
886 | # Now print the relations | ||||||
887 | 0 | 0 | my $rel; | ||||
888 | 0 | 0 | for $rel (keys %{$obj->{$obj->{baselang}}{$term}}) { | ||||
0 | 0 | ||||||
889 | # next iteraction if the relation is the _NAME_ | ||||||
890 | 0 | 0 | 0 | next if ($rel eq "_NAME_"); | |||
891 | |||||||
892 | # Next if we want to hide it | ||||||
893 | 0 | 0 | 0 | next if exists $hide{$rel}; | |||
894 | |||||||
895 | # This block jumps if it is an expansion relation | ||||||
896 | 0 | 0 | 0 | next if grep {$_ eq uc($rel)} @{$expander}; | |||
0 | 0 | ||||||
0 | 0 | ||||||
897 | |||||||
898 | # The externs exceptions... | ||||||
899 | 0 | 0 | 0 | if (exists($norel{$rel})) { | |||
0 | |||||||
900 | # It's an external, so... | ||||||
901 | # | ||||||
902 | # Its description is "..."? | ||||||
903 | 0 | 0 | my $desc = $obj->getDescription($rel, $language); | ||||
904 | |||||||
905 | 0 | 0 | $html .= join(" \n", map { b($desc)." $_" } @{$obj->{$obj->{baselang}}{$term}{$rel}}); |
||||
0 | 0 | ||||||
0 | 0 | ||||||
906 | 0 | 0 | $html .= " ".br; | ||||
907 | } elsif (exists($obj->{languages}{$rel})) { | ||||||
908 | ## This empty block is used for languages translations | ||||||
909 | |||||||
910 | } else { | ||||||
911 | ## OK! It's a simple relation | ||||||
912 | |||||||
913 | # There is a translation for the *relation* description? | ||||||
914 | 0 | 0 | my $desc = $obj->getDescription($rel, $language); | ||||
915 | 0 | 0 | 0 | if ($desc eq "...") { | |||
916 | 0 | 0 | $html .= b($rel)." "; | ||||
917 | } else { | ||||||
918 | 0 | 0 | $html.= b($desc)." "; | ||||
919 | } | ||||||
920 | |||||||
921 | # Now, write each term with a thesaurus link | ||||||
922 | 0 | 0 | $html.= join(", ", map { | ||||
923 | 0 | 0 | my $term = $_; | ||||
924 | 0 | 0 | my $link = $term; | ||||
925 | 0 | 0 | $link =~ s/\s/+/g; | ||||
926 | 0 | 0 | $term = $obj->_translateTerm($term, $language); | ||||
927 | 0 | 0 | a({ href=>"$script?$topic=$link"},$term) | ||||
928 | 0 | 0 | } sort {lc($a)cmp lc($b)} @{$obj->{$obj->{baselang}}{$term}{$rel}}); | ||||
0 | 0 | ||||||
929 | |||||||
930 | 0 | 0 | $html.= br; | ||||
931 | } | ||||||
932 | } | ||||||
933 | |||||||
934 | # Now, treat the expansion relations | ||||||
935 | 0 | 0 | for $rel (@{$expander}) { | ||||
0 | 0 | ||||||
936 | 0 | 0 | $rel = uc($rel); | ||||
937 | 0 | 0 | 0 | if (exists($obj->{$obj->{baselang}}{$term}{$rel})) { | |||
938 | 0 | 0 | @terms = sort {lc($a)cmp lc($b)} @{$obj->{$obj->{baselang}}{$term}{$rel}}; | ||||
0 | 0 | ||||||
0 | 0 | ||||||
939 | 0 | 0 | $html.= ul(li([map { | ||||
940 | 0 | 0 | 0 | _thesaurusGetHTMLTerm($_, $obj, $script, $language, | |||
941 | $second_level_limit, $hide_on_second_level); | ||||||
942 | } @terms])) if (@terms); | ||||||
943 | } | ||||||
944 | } | ||||||
945 | 0 | 0 | return $html; | ||||
946 | } | ||||||
947 | |||||||
948 | ### | ||||||
949 | # | ||||||
950 | # | ||||||
951 | sub toTex{ | ||||||
952 | 0 | 0 | 1 | 0 | my $self = shift; | ||
953 | 0 | 0 | 0 | my $_corres = shift || {}; | |||
954 | 0 | 0 | 0 | my $mydt = shift || {}; | |||
955 | # my $a; | ||||||
956 | |||||||
957 | 0 | 0 | my %descs = %{$self->{descriptions}}; | ||||
0 | 0 | ||||||
958 | |||||||
959 | my $procgr= sub { | ||||||
960 | 0 | 0 | 0 | my $r="";# my $a; | |||
961 | 0 | 0 | 0 | my $auxrel = $descs{$rel} || $rel; | |||
962 | 0 | 0 | $auxrel =~ s/_/ /g; | ||||
963 | 0 | 0 | $auxrel = ucfirst(lc($auxrel)); | ||||
964 | 0 | 0 | 0 | my $ki = $_corres->{$rel}->[0] || "\\\\\\emph{$auxrel} -- " ; | |||
965 | 0 | 0 | 0 | my $kf = $_corres->{$rel}->[1] || "\n"; | |||
966 | 0 | 0 | $r = "\\item[$ki]" . | ||||
967 | 0 | 0 | 0 | join(' $\diamondsuit$ ',(sort {lc($a) cmp lc($b)} @terms)) if @terms; | |||
968 | 0 | 0 | }; | ||||
969 | |||||||
970 | 0 | 0 | 0 | $self->downtr( | |||
971 | { '-default' => $procgr, | ||||||
972 | '-end' => sub{s/_/\\_/g; | ||||||
973 | 0 | 0 | "\\begin{description}\n$_\\end{description}\n"}, | ||||
974 | 0 | 0 | 0 | '-eachTerm' => | |||
975 | sub{"\n\\item[$term]~\\begin{description}\n$_\\end{description}\n"}, | ||||||
976 | 0 | 0 | 0 | (defined $self->{order}?(-order => $self->{order}):()), | |||
977 | (%$mydt) } | ||||||
978 | ); | ||||||
979 | } | ||||||
980 | |||||||
981 | sub toXml{ | ||||||
982 | 0 | 0 | 1 | 0 | my $self = shift; | ||
983 | 0 | 0 | 0 | my $_corres = shift || {}; | |||
984 | 0 | 0 | 0 | my $mydt = shift || {}; | |||
985 | 0 | 0 | my $a; | ||||
986 | |||||||
987 | my $proc= sub { | ||||||
988 | 0 | 0 | 0 | my $r=""; my $a; | |||
0 | 0 | ||||||
989 | 0 | 0 | 0 | my $ki = $_corres->{$rel}->[0] || "$rel" ; | |||
990 | 0 | 0 | 0 | my $kf = $_corres->{$rel}->[1] || "/$rel"; | |||
991 | 0 | 0 | for $a (@terms){ $r .= " <$ki>$a<$kf>\n";}; | ||||
0 | 0 | ||||||
992 | 0 | 0 | $r; | ||||
993 | 0 | 0 | }; | ||||
994 | |||||||
995 | 0 | 0 | 0 | $self->downtr({ | |||
996 | '-default' => $proc, | ||||||
997 | '-eachTerm' => | ||||||
998 | sub{" |
||||||
999 | 0 | 0 | 0 | '-end' => sub{" |
|||
1000 | 0 | 0 | (%$mydt) | ||||
1001 | }); | ||||||
1002 | } | ||||||
1003 | |||||||
1004 | ### | ||||||
1005 | # | ||||||
1006 | # | ||||||
1007 | sub dumpHTML { | ||||||
1008 | 0 | 0 | 1 | 0 | my $obj = shift; | ||
1009 | 0 | 0 | my %thesaurus = %{$obj->{$obj->{baselang}}}; | ||||
0 | 0 | ||||||
1010 | 0 | 0 | my $t = ""; | ||||
1011 | 0 | 0 | for (keys %thesaurus) { | ||||
1012 | 0 | 0 | $t.=_thesaurusGetHTMLTerm($_,$obj,"",$obj->{baselang}); | ||||
1013 | } | ||||||
1014 | 0 | 0 | return $t; | ||||
1015 | } | ||||||
1016 | |||||||
1017 | ### | ||||||
1018 | # | ||||||
1019 | # | ||||||
1020 | sub relations { | ||||||
1021 | 1 | 1 | 1 | 3 | my ($self,$term) = @_; | ||
1022 | |||||||
1023 | 1 | 2 | return sort grep { $_ !~ /^_/ } keys %{$self->{$self->{baselang}}->{$term}} | ||||
2 | 10 | ||||||
1 | 6 | ||||||
1024 | } | ||||||
1025 | |||||||
1026 | |||||||
1027 | ### | ||||||
1028 | # | ||||||
1029 | # Given a term, return it's information (second level for navigate) | ||||||
1030 | sub _thesaurusGetHTMLTerm { | ||||||
1031 | 0 | 0 | 0 | my ($term,$obj,$script,$language,$limit,$hide) = @_; | |||
1032 | |||||||
1033 | 0 | 0 | 0 | my @rels2hide = map {uc} (defined($hide))?@$hide:(); | |||
0 | 0 | ||||||
1034 | 0 | 0 | my %rels2hide; | ||||
1035 | 0 | 0 | @rels2hide{@rels2hide}=1; | ||||
1036 | |||||||
1037 | # Put thesaurus and descriptions on handy variables | ||||||
1038 | 0 | 0 | my %thesaurus = %{$obj->{$obj->{baselang}}}; | ||||
0 | 0 | ||||||
1039 | 0 | 0 | my %descs = %{$obj->{descriptions}}; | ||||
0 | 0 | ||||||
1040 | |||||||
1041 | # Check if the term exists in the thesaurus | ||||||
1042 | 0 | 0 | 0 | if ($obj->isDefined($term)) { | |||
1043 | 0 | 0 | $term = $obj->{defined}{lc($term)}; | ||||
1044 | 0 | 0 | my ($c,$t,$tterm); | ||||
1045 | 0 | 0 | my $link = $term; | ||||
1046 | |||||||
1047 | 0 | 0 | $link =~ s/\s/+/g; | ||||
1048 | 0 | 0 | $tterm = $obj->_translateTerm($term,$language); | ||||
1049 | 0 | 0 | $t = b(a({href=>"$script?t=$link"},$tterm)). br . "
|
||||
1050 | |||||||
1051 | 0 | 0 | for $c (sort keys %{$thesaurus{$term}}) { | ||||
0 | 0 | ||||||
1052 | 0 | 0 | $c = uc($c); | ||||
1053 | 0 | 0 | 0 | next if exists($rels2hide{$c}); | |||
1054 | # jump if it is the name relation :) | ||||||
1055 | 0 | 0 | 0 | next if ($c eq "_NAME_"); | |||
1056 | |||||||
1057 | 0 | 0 | 0 | if (exists($obj->{externals}{$c})) { | |||
0 | |||||||
1058 | # put an external relation | ||||||
1059 | 0 | 0 | my $desc = $obj->getDescription($c,$language); | ||||
1060 | 0 | 0 | 0 | if ($desc eq "...") { | |||
1061 | 0 | 0 | $t .= join(" \n", map { div($_) } @{$thesaurus{$term}{$c}}); |
||||
0 | 0 | ||||||
0 | 0 | ||||||
1062 | } else { | ||||||
1063 | 0 | 0 | $t .= join(" \n", map { b($desc)." $_" } @{$thesaurus{$term}{$c}}); |
||||
0 | 0 | ||||||
0 | 0 | ||||||
1064 | } | ||||||
1065 | } elsif (exists($obj->{languages}{$c})) { | ||||||
1066 | # Jump the language relations | ||||||
1067 | } else { | ||||||
1068 | 0 | 0 | my $desc = $obj->getDescription($c,$language); | ||||
1069 | 0 | 0 | 0 | if ($desc eq "...") { | |||
1070 | 0 | 0 | $t.= b($c)." "; | ||||
1071 | } else { | ||||||
1072 | 0 | 0 | $t.= b($desc)." "; | ||||
1073 | } | ||||||
1074 | 0 | 0 | my @termos = sort {lc($a)cmp lc($b)} ( @{$thesaurus{$term}{$c}} ); | ||||
0 | 0 | ||||||
0 | 0 | ||||||
1075 | 0 | 0 | 0 | 0 | if (defined($limit) && $limit!=0 && @termos > $limit) { | ||
0 | |||||||
1076 | 0 | 0 | while(@termos > $limit) { pop @termos; } | ||||
0 | 0 | ||||||
1077 | 0 | 0 | push @termos, "..."; | ||||
1078 | } | ||||||
1079 | 0 | 0 | 0 | if (defined($script)) { | |||
1080 | 0 | 0 | @termos = map {my $link = $_; | ||||
0 | 0 | ||||||
1081 | 0 | 0 | 0 | if ($link eq "...") { | |||
1082 | 0 | 0 | $link | ||||
1083 | } else { | ||||||
1084 | 0 | 0 | 0 | $_ = $obj->_translateTerm($_,$language) || $_; | |||
1085 | 0 | 0 | $link =~s/\s/+/g; | ||||
1086 | 0 | 0 | a({href=>"$script?t=$link"},$_) | ||||
1087 | } | ||||||
1088 | } @termos; | ||||||
1089 | } | ||||||
1090 | 0 | 0 | $t.= join(", ", @termos) . br."\n"; | ||||
1091 | } | ||||||
1092 | } | ||||||
1093 | 0 | 0 | $t.= "\n"; | ||||
1094 | 0 | 0 | return $t; | ||||
1095 | } else { | ||||||
1096 | 0 | 0 | print STDERR "Can't find term '$term'\n"; | ||||
1097 | 0 | 0 | return qq/Term $term is not defined\n/; | ||||
1098 | } | ||||||
1099 | } | ||||||
1100 | |||||||
1101 | 11 | 11 | 1 | 1096 | sub getdefinition { getDefinition(@_) } | ||
1102 | sub getDefinition { | ||||||
1103 | 11 | 11 | 1 | 12 | my $self = shift; | ||
1104 | 11 | 25 | my $term = _term_normalize(lc(shift)); | ||||
1105 | 11 | 50 | 23 | if ($self->isDefined($term)) { | |||
1106 | 11 | 37 | return $self->{defined}{$term}; | ||||
1107 | } else { | ||||||
1108 | 0 | 0 | return $term; | ||||
1109 | } | ||||||
1110 | } | ||||||
1111 | |||||||
1112 | ### | ||||||
1113 | # | ||||||
1114 | # | ||||||
1115 | sub isDefined { | ||||||
1116 | 101063 | 101063 | 1 | 675616 | my $obj = shift; | ||
1117 | 101063 | 208592 | my $term = _term_normalize(lc(shift)); | ||||
1118 | 101063 | 386861 | return defined($obj->{defined}{$term}); | ||||
1119 | } | ||||||
1120 | |||||||
1121 | ### | ||||||
1122 | # | ||||||
1123 | # | ||||||
1124 | sub _definition { | ||||||
1125 | 267 | 267 | 362 | my ($self,$term) = @_; | |||
1126 | 267 | 643 | return $self->{defined}{_term_normalize(lc($term))}; | ||||
1127 | } | ||||||
1128 | |||||||
1129 | ### | ||||||
1130 | # | ||||||
1131 | # | ||||||
1132 | sub complete { | ||||||
1133 | 12 | 12 | 1 | 21 | my $obj = shift; | ||
1134 | 12 | 83 | my $thesaurus = $obj->{$obj->{baselang}}; | ||||
1135 | 12 | 25 | my %inverses = %{$obj->{inverses}}; | ||||
12 | 106 | ||||||
1136 | 12 | 30 | my ($termo,$classe); | ||||
1137 | |||||||
1138 | # para cada termo | ||||||
1139 | 12 | 58 | for $termo (keys %$thesaurus) { | ||||
1140 | # $obj->{defined}{lc($termo)} = $termo; | ||||||
1141 | # e para cada classe, | ||||||
1142 | 164 | 172 | for $classe (keys %{$thesaurus->{$termo}}) { | ||||
164 | 560 | ||||||
1143 | # verificar se existem duplicados... | ||||||
1144 | 429 | 100 | 1210 | if (ref($thesaurus->{$termo}{$classe}) eq "ARRAY") { | |||
1145 | 260 | 258 | my %h; | ||||
1146 | 260 | 267 | @h{@{$thesaurus->{$termo}{$classe}}} = @{$thesaurus->{$termo}{$classe}}; | ||||
260 | 1236 | ||||||
260 | 450 | ||||||
1147 | 260 | 838 | $thesaurus->{$termo}{$classe} = [ keys %h ]; | ||||
1148 | |||||||
1149 | # se tiver inverso, | ||||||
1150 | 260 | 100 | 785 | if (defined($inverses{$classe})) { | |||
1151 | # completar cada um dos termos relacionados | ||||||
1152 | 233 | 238 | for (@{$thesaurus->{$termo}{$classe}}) { | ||||
233 | 560 | ||||||
1153 | # %thesaurus = _completa($obj,$_,$inverses{$classe},$termo,%thesaurus); | ||||||
1154 | 556 | 1108 | _completa($obj,$_,$inverses{$classe},$termo,$thesaurus); | ||||
1155 | } | ||||||
1156 | } | ||||||
1157 | } | ||||||
1158 | } | ||||||
1159 | } | ||||||
1160 | |||||||
1161 | 12 | 44 | $obj -> {$obj->{baselang}} = $thesaurus; | ||||
1162 | |||||||
1163 | 12 | 75 | return $obj; | ||||
1164 | } | ||||||
1165 | |||||||
1166 | ### | ||||||
1167 | # | ||||||
1168 | # | ||||||
1169 | sub _completa { | ||||||
1170 | ## Yeah, obj and thesaurus can be redundanct, but it's better this way... | ||||||
1171 | 556 | 556 | 927 | my ($obj,$palavra,$classe,$termo,$thesaurus) = @_; | |||
1172 | 556 | 519 | my $t; | ||||
1173 | |||||||
1174 | # Ver se existe a palavra e a classe no thesaurus | ||||||
1175 | 556 | 100 | 1015 | if ($obj->isDefined($palavra)) { | |||
1176 | 286 | 675 | $t = $obj->{defined}{lc($palavra)}; | ||||
1177 | 286 | 100 | 684 | if (defined($thesaurus->{$t}{$classe})) { | |||
1178 | # se existe, o array palavras fica com os termos (para ver se ja' existe) | ||||||
1179 | 121 | 173 | my @palavras = @{$thesaurus->{$t}{$classe}}; | ||||
121 | 363 | ||||||
1180 | # ver se ja' existe | ||||||
1181 | 121 | 196 | for (@palavras) { | ||||
1182 | 288 | 100 | 1000 | return $thesaurus if (lc eq lc($termo)); | |||
1183 | } | ||||||
1184 | } | ||||||
1185 | # nao existe: aumentar | ||||||
1186 | 192 | 207 | push @{$thesaurus->{$t}{$classe}}, $obj->{defined}{lc($termo)}; | ||||
192 | 783 | ||||||
1187 | } else { | ||||||
1188 | # nao existe: aumentar | ||||||
1189 | 270 | 50 | 33 | 1095 | $thesaurus->{$palavra}{_NAME_} = $palavra unless | ||
1190 | defined($thesaurus->{$palavra}) && defined($thesaurus->{$palavra}{_NAME_}); | ||||||
1191 | 270 | 586 | $obj->{defined}{lc($palavra)} = $palavra; | ||||
1192 | 270 | 293 | push @{$thesaurus->{$palavra}{$classe}}, $obj->{defined}{lc($termo)}; | ||||
270 | 876 | ||||||
1193 | } | ||||||
1194 | 462 | 1402 | return $thesaurus; | ||||
1195 | } | ||||||
1196 | |||||||
1197 | ### | ||||||
1198 | # | ||||||
1199 | # | ||||||
1200 | sub addTerm { | ||||||
1201 | 100011 | 100011 | 1 | 660883 | my $obj = shift; | ||
1202 | 100011 | 194317 | my $term = _term_normalize(shift); | ||||
1203 | |||||||
1204 | 100011 | 653927 | $obj->{$obj->{baselang}}{$term}{_NAME_} = $term; | ||||
1205 | 100011 | 419556 | $obj->{defined}{lc($term)} = $term; | ||||
1206 | } | ||||||
1207 | |||||||
1208 | sub hasRelation { | ||||||
1209 | 15 | 15 | 1 | 784 | my ($obj, $term, $rel, $rterm) = @_; | ||
1210 | 15 | 27 | $rel = uc($rel); | ||||
1211 | |||||||
1212 | 15 | 50 | 30 | return 0 unless $obj->isDefined($term); # Check if term exists | |||
1213 | 15 | 36 | $term = $obj->_definition($term); | ||||
1214 | |||||||
1215 | 15 | 22 | my $has = 0; | ||||
1216 | 15 | 100 | 29 | if ($rterm) { | |||
1217 | 13 | 50 | 33 | if (exists($obj->{externals}{$rel})) { | |||
1218 | 0 | 0 | 0 | $has = 1 if (grep { $_ eq $rterm } @{$obj->{$obj->{baselang}}{$term}{$rel}}); | |||
0 | 0 | ||||||
0 | 0 | ||||||
1219 | } else { | ||||||
1220 | 13 | 20 | $rterm = _term_normalize($rterm); | ||||
1221 | 13 | 100 | 15 | $has = 1 if (grep { $_ eq $rterm} @{$obj->{$obj->{baselang}}{$term}{$rel}}); | |||
22 | 51 | ||||||
13 | 50 | ||||||
1222 | } | ||||||
1223 | } else { | ||||||
1224 | 2 | 100 | 9 | $has = 1 if exists($obj->{$obj->{baselang}}{$term}{$rel}); | |||
1225 | } | ||||||
1226 | 15 | 70 | return $has; | ||||
1227 | } | ||||||
1228 | |||||||
1229 | ### | ||||||
1230 | # | ||||||
1231 | # | ||||||
1232 | sub addRelation { | ||||||
1233 | 4 | 4 | 1 | 1355 | my ($obj, $term, $rel, @terms) = @_; | ||
1234 | 4 | 7 | $rel = uc($rel); | ||||
1235 | |||||||
1236 | 4 | 50 | 19 | $obj->{descriptions}{$rel} = "..." | |||
1237 | unless defined($obj->{descriptions}{$rel}); | ||||||
1238 | |||||||
1239 | 4 | 50 | 9 | unless ($obj->isDefined($term)) { | |||
1240 | 0 | 0 | $obj->{defined}{lc(_term_normalize($term))} = _term_normalize($term); | ||||
1241 | } | ||||||
1242 | |||||||
1243 | 4 | 11 | $term = $obj->_definition($term); | ||||
1244 | |||||||
1245 | 4 | 100 | 15 | if (exists($obj->{externals}{$rel})) { | |||
1246 | 1 | 4 | push @{$obj->{$obj->{baselang}}{$term}{$rel}}, @terms; | ||||
1 | 6 | ||||||
1247 | |||||||
1248 | } else { | ||||||
1249 | 3 | 12 | push @{$obj->{$obj->{baselang}}{$term}{$rel}}, | ||||
7 | 10 | ||||||
1250 | 3 | 3 | map {_term_normalize($_)} @terms; | ||||
1251 | 3 | 6 | for (@terms) { | ||||
1252 | 7 | 50 | 22 | $obj->addTerm($_) unless $obj->isDefined($_); | |||
1253 | } | ||||||
1254 | } | ||||||
1255 | |||||||
1256 | } | ||||||
1257 | |||||||
1258 | ### | ||||||
1259 | # | ||||||
1260 | # | ||||||
1261 | sub deleteRelation { | ||||||
1262 | 6 | 6 | 1 | 835 | my ($self, $term, $rel, @terms) = @_; | ||
1263 | 6 | 13 | $rel = uc($rel); | ||||
1264 | |||||||
1265 | 6 | 100 | 15 | if (@terms) { | |||
1266 | 3 | 6 | for my $oterm (@terms) { | ||||
1267 | 4 | 13 | $self->_deleteRelation($term, $rel, $oterm); | ||||
1268 | ## Se existe inversa, do the same shit | ||||||
1269 | 4 | 50 | 16 | if (exists $self->{inverses}{$rel}) { | |||
1270 | 4 | 11 | $self->_deleteRelation($oterm, $self->{inverses}{$rel}, $term); | ||||
1271 | } | ||||||
1272 | } | ||||||
1273 | } else { | ||||||
1274 | 3 | 100 | 12 | if (exists($self->{externals}{$rel})) { | |||
1275 | 1 | 4 | $self->_deleteRelation($term, $rel); | ||||
1276 | } else { | ||||||
1277 | 2 | 20 | @terms = $self->terms($term,$rel); | ||||
1278 | 2 | 100 | 7 | return unless @terms; | |||
1279 | 1 | 6 | $self->deleteRelation($term, $rel, @terms); | ||||
1280 | } | ||||||
1281 | } | ||||||
1282 | } | ||||||
1283 | |||||||
1284 | ### | ||||||
1285 | # | ||||||
1286 | # | ||||||
1287 | sub _deleteRelation { | ||||||
1288 | 9 | 9 | 20 | my ($obj, $term, $rel, $oterm) = @_; | |||
1289 | |||||||
1290 | # return if the term is not defined | ||||||
1291 | 9 | 50 | 19 | return unless $obj->isDefined($term); | |||
1292 | |||||||
1293 | 9 | 22 | $term = $obj->_definition($term); | ||||
1294 | 9 | 100 | 23 | if ($oterm) { | |||
1295 | # if we have a full relation (term,rel,term), then it is not an external relation | ||||||
1296 | 8 | 50 | 26 | return if exists($obj->{externals}{$rel}); | |||
1297 | |||||||
1298 | 8 | 24 | $oterm = _term_normalize($oterm); | ||||
1299 | 8 | 11 | $obj->{$obj->{baselang}}{$term}{$rel} = [ grep { $_ ne $oterm } @{$obj->{$obj->{baselang}}{$term}{$rel}}]; | ||||
11 | 43 | ||||||
8 | 33 | ||||||
1300 | } else { | ||||||
1301 | 1 | 6 | delete($obj->{$obj->{baselang}}{$term}{$rel}); | ||||
1302 | } | ||||||
1303 | } | ||||||
1304 | |||||||
1305 | ### | ||||||
1306 | # | ||||||
1307 | # | ||||||
1308 | sub deleteTerm { | ||||||
1309 | 1 | 1 | 1 | 2 | my $obj = shift; | ||
1310 | 1 | 5 | my $term = _term_normalize(shift); | ||||
1311 | 1 | 2 | my $t2=$term; | ||||
1312 | 1 | 4 | $term = $obj->_definition($term); | ||||
1313 | 1 | 2 | my ($t,$c); | ||||
1314 | |||||||
1315 | 1 | 50 | 0 | 28 | warn("'$t2' => '$term'\n") && return unless defined($term); | ||
1316 | |||||||
1317 | 1 | 50 | 5 | if (defined($obj->{$obj->{baselang}}{$term})){ | |||
0 | 0 | ||||||
1318 | 1 | 4 | delete($obj->{$obj->{baselang}}{$term}); | ||||
1319 | 1 | 4 | delete($obj->{defined}{lc($term)}); | ||||
1320 | } | ||||||
1321 | else {warn ("'$term' not found...\n");} | ||||||
1322 | |||||||
1323 | 1 | 1 | foreach $t (keys %{$obj->{$obj->{baselang}}}) { | ||||
1 | 5 | ||||||
1324 | 1 | 1 | foreach $c (keys %{$obj->{$obj->{baselang}}{$t}}) { | ||||
1 | 4 | ||||||
1325 | 1 | 3 | my @a = (); | ||||
1326 | 1 | 50 | 8 | if ( ref($obj->{$obj->{baselang}}{$t}{$c}) eq "ARRAY") { | |||
1327 | 0 | 0 | foreach (@{$obj->{$obj->{baselang}}{$t}{$c}}) { | ||||
0 | 0 | ||||||
1328 | 0 | 0 | 0 | push(@a,$_) unless($_ eq $term); | |||
1329 | } | ||||||
1330 | 0 | 0 | $obj->{$obj->{baselang}}{$t}{$c}=\@a; | ||||
1331 | } | ||||||
1332 | } | ||||||
1333 | } | ||||||
1334 | } | ||||||
1335 | |||||||
1336 | ### | ||||||
1337 | # | ||||||
1338 | # | ||||||
1339 | sub downtr { | ||||||
1340 | 0 | 0 | 1 | 0 | my $self = shift; | ||
1341 | 0 | 0 | my $handler = shift; | ||||
1342 | 0 | 0 | 0 | die("bad use of downtr method; args should be: hashRef, termlist") | |||
1343 | unless(ref($handler) eq "HASH"); | ||||||
1344 | 0 | 0 | my @tl = @_ ; #lc(shift); | ||||
1345 | 0 | 0 | @tl = (sort | ||||
1346 | 0 | 0 | {lc($a) cmp lc($b)} | ||||
1347 | 0 | 0 | 0 | keys %{$self->{$self->{baselang}}}) unless (@tl); | |||
1348 | 0 | 0 | my $r2 = ""; #final result | ||||
1349 | 0 | 0 | my $c; | ||||
1350 | 0 | 0 | for my $t (@tl){ | ||||
1351 | 0 | 0 | my $r = ""; | ||||
1352 | 0 | 0 | $term = $t; | ||||
1353 | 0 | 0 | 0 | if (defined( $handler->{"_NAME_"})){ | |||
1354 | 0 | 0 | $r .= &{$handler->{"_NAME_"}}; | ||||
0 | 0 | ||||||
1355 | } | ||||||
1356 | |||||||
1357 | 0 | 0 | my @rels = (keys %{$self->{$self->{baselang}}->{$t}}); | ||||
0 | 0 | ||||||
1358 | 0 | 0 | my %rels = (); | ||||
1359 | 0 | 0 | @rels{@rels} = @rels; | ||||
1360 | 0 | 0 | 0 | my $order = defined $handler->{-order} ? $handler->{-order} : | |||
0 | |||||||
1361 | ( defined $self->{order} ? $self->{order} : []); | ||||||
1362 | 0 | 0 | delete(@rels{@$order}); | ||||
1363 | 0 | 0 | @rels = ( @{$order}, (sort keys(%rels) )); | ||||
0 | 0 | ||||||
1364 | |||||||
1365 | 0 | 0 | for $c (@rels) { | ||||
1366 | 0 | 0 | 0 | next unless $self->{$self->{baselang}}{$t}{$c}; | |||
1367 | 0 | 0 | 0 | next if ($c eq "_NAME_"); | |||
1368 | |||||||
1369 | # Set environment variables to downtr function | ||||||
1370 | # | ||||||
1371 | # rel... | ||||||
1372 | # | ||||||
1373 | 0 | 0 | $rel = $c; | ||||
1374 | # | ||||||
1375 | # List of terms... | ||||||
1376 | # | ||||||
1377 | 0 | 0 | 0 | if ($self->{languages}->{$rel}) { | |||
1378 | 0 | 0 | @terms = ( $self->{$self->{baselang}}{$t}{$rel} ); | ||||
1379 | } else { | ||||||
1380 | 0 | 0 | @terms = @{$self->{$self->{baselang}}{$t}{$rel}}; | ||||
0 | 0 | ||||||
1381 | } | ||||||
1382 | |||||||
1383 | # | ||||||
1384 | # Current term... | ||||||
1385 | # | ||||||
1386 | 0 | 0 | $term = $t; | ||||
1387 | |||||||
1388 | 0 | 0 | 0 | if (exists($handler->{$rel})) { | |||
0 | |||||||
1389 | 0 | 0 | 0 | $r .= &{$handler->{$rel}} // ""; | |||
0 | 0 | ||||||
1390 | } elsif (exists($handler->{-default})) { | ||||||
1391 | 0 | 0 | 0 | $r .= &{$handler->{-default}} // ""; | |||
0 | 0 | ||||||
1392 | } else { | ||||||
1393 | 0 | 0 | $r .= "\n$rel\t".join(", ",@terms); | ||||
1394 | } | ||||||
1395 | } | ||||||
1396 | 0 | 0 | for($r){ | ||||
1397 | 0 | 0 | 0 | if (exists($handler->{'-eachTerm'})) { | |||
1398 | 0 | 0 | my $ans = &{$handler->{'-eachTerm'}}; | ||||
0 | 0 | ||||||
1399 | 0 | 0 | 0 | $r2 .= ($ans)?$ans:""; | |||
1400 | } else { | ||||||
1401 | 0 | 0 | $r2 .= $_; | ||||
1402 | } | ||||||
1403 | } | ||||||
1404 | } | ||||||
1405 | 0 | 0 | 0 | if (defined($handler->{-end})) { | |||
1406 | 0 | 0 | for($r2){ | ||||
1407 | 0 | 0 | $_ = &{$handler->{'-end'}} | ||||
0 | 0 | ||||||
1408 | } | ||||||
1409 | } | ||||||
1410 | 0 | 0 | $r2; | ||||
1411 | } | ||||||
1412 | |||||||
1413 | ### | ||||||
1414 | # | ||||||
1415 | # | ||||||
1416 | sub tc{ | ||||||
1417 | 1 | 1 | 1 | 11 | my ($self,$term,@relations) = @_; | ||
1418 | 1 | 6 | my %x = _tc_aux($self, $term, {}, @relations); | ||||
1419 | 1 | 11 | return (keys %x); | ||||
1420 | } | ||||||
1421 | |||||||
1422 | |||||||
1423 | ### | ||||||
1424 | # | ||||||
1425 | # | ||||||
1426 | sub toHash { | ||||||
1427 | 1 | 1 | 1 | 16 | my ($self, $rel) = @_; | ||
1428 | 1 | 50 | 3 | $rel //= "NT"; | |||
1429 | 1 | 50 | 12 | $rel = [$rel] unless ref($rel); | |||
1430 | 1 | 6 | my $top = $self->topName; | ||||
1431 | 1 | 7 | return +{ $top => $self->_toHash($top, $rel, [$top]) }; | ||||
1432 | } | ||||||
1433 | |||||||
1434 | sub _toHash { | ||||||
1435 | 4 | 4 | 7 | my ($self, $term, $rel, $stack) = @_; | |||
1436 | 4 | 12 | my $h = $self->depth_first($term, 1, @$rel); | ||||
1437 | 4 | 100 | 12 | if (keys %$h) { | |||
1438 | 1 | 3 | for (keys %$h) { | ||||
1439 | 3 | 13 | $h->{$_} = $self->_toHash($_, $rel, [@$stack, $_]); | ||||
1440 | } | ||||||
1441 | } else { | ||||||
1442 | 3 | 7 | $h = join("::", @$stack); | ||||
1443 | } | ||||||
1444 | 4 | 17 | return $h; | ||||
1445 | } | ||||||
1446 | |||||||
1447 | ## | ||||||
1448 | # | ||||||
1449 | # | ||||||
1450 | sub toJson { | ||||||
1451 | 0 | 0 | 1 | 0 | my ($self, $rel) = @_; | ||
1452 | 0 | 0 | 0 | $rel //= "NT"; | |||
1453 | 0 | 0 | 0 | $rel = [$rel] unless ref($rel); | |||
1454 | 0 | 0 | my $top = $self->topName; | ||||
1455 | 0 | 0 | $self->_toJson($top, $rel); | ||||
1456 | } | ||||||
1457 | |||||||
1458 | sub _toJson { | ||||||
1459 | 0 | 0 | 0 | my ($self, $term, $rel) = @_; | |||
1460 | 0 | 0 | my $h = $self->depth_first($term, 1, @$rel); | ||||
1461 | 0 | 0 | my $json = "{ \"data\": \"$term\", \"attr\":{id:\"$term\"}"; | ||||
1462 | 0 | 0 | 0 | if (keys %$h) { | |||
1463 | 0 | 0 | $json .= ", \"children\": ["; | ||||
1464 | 0 | 0 | $json .= join(", ", map { $self->_toJson($_, $rel) } keys %$h); | ||||
0 | 0 | ||||||
1465 | 0 | 0 | $json .= "]" | ||||
1466 | } | ||||||
1467 | 0 | 0 | $json .= "}"; | ||||
1468 | } | ||||||
1469 | |||||||
1470 | ### | ||||||
1471 | # | ||||||
1472 | # | ||||||
1473 | sub _tc_aux { | ||||||
1474 | 10 | 10 | 16 | my ($self,$term,$vis,@relat) = @_; | |||
1475 | 10 | 24 | $term = $self->getdefinition($term); | ||||
1476 | 10 | 21 | my %r = ( $term => 1 ); | ||||
1477 | 10 | 24 | for ($self->terms($term,@relat)) { | ||||
1478 | 9 | 50 | 20 | next if exists $vis->{$_}; | |||
1479 | 9 | 14 | $vis->{$_}++; | ||||
1480 | 9 | 50 | 40 | %r = (%r, $_ => 1, _tc_aux($self,$_,@relat)) unless $r{$_}; | |||
1481 | } | ||||||
1482 | 10 | 78 | return %r; | ||||
1483 | } | ||||||
1484 | |||||||
1485 | ### | ||||||
1486 | # | ||||||
1487 | # | ||||||
1488 | sub _term_normalize { | ||||||
1489 | 202015 | 202015 | 238051 | my $t = shift; | |||
1490 | 202015 | 1126942 | $t =~ s/^\s*(.*?)\s*$/$1/; | ||||
1491 | 202015 | 344821 | $t =~ s/\s\s+/ /g; | ||||
1492 | 202015 | 404054 | return $t; | ||||
1493 | } | ||||||
1494 | |||||||
1495 | sub capitalize { | ||||||
1496 | 0 | 0 | 1 | 0 | my $op = shift; | ||
1497 | 0 | 0 | my $text = shift; | ||||
1498 | 0 | 0 | 0 | if ($op) { | |||
1499 | 0 | 0 | $text = join(" ",map {ucfirst} split /\s+/, $text); | ||||
0 | 0 | ||||||
1500 | } | ||||||
1501 | 0 | 0 | return $text; | ||||
1502 | } | ||||||
1503 | |||||||
1504 | # remove duplicados de uma lista | ||||||
1505 | sub _set_of { | ||||||
1506 | 8 | 8 | 15 | my %set = (); | |||
1507 | 8 | 51 | $set{$_} = 1 for @_; | ||||
1508 | 8 | 46 | return keys %set; | ||||
1509 | } | ||||||
1510 | |||||||
1511 | 1; | ||||||
1512 | __END__ |