| 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__ |