File Coverage

blib/lib/Lingua/StarDict/Gen.pm
Criterion Covered Total %
statement 30 183 16.3
branch 0 64 0.0
condition 0 19 0.0
subroutine 10 21 47.6
pod 6 6 100.0
total 46 293 15.7


line stmt bran cond sub pod time code
1             package Lingua::StarDict::Gen;
2              
3 1     1   26036 use warnings;
  1         2  
  1         40  
4 1     1   6 use strict;
  1         2  
  1         35  
5 1     1   9537 use Data::Dumper;
  1         59736  
  1         86  
6 1     1   1003 use locale;
  1         228  
  1         6  
7 1     1   1511 use Encode;
  1         20965  
  1         520  
8 1     1   1378 use utf8;
  1         12  
  1         7  
9 1     1   1177 use File::Spec::Functions;
  1         1142  
  1         1410  
10             #use POSIX qw(locale_h);
11             #setlocale(LC_ALL,"C");
12              
13             $Data::Dumper::Indent=1;
14             $Data::Dumper::Terse=1;
15              
16             our $VERSION = '0.10';
17              
18             my $nome; my %dic;
19              
20 0     0 1   sub carregaDic { &loadDict; }
21              
22             sub loadDict {
23 0     0 1   my %opt =(type=> "default");
24 0           local $/;
25 0 0         if(ref($_[0]) eq "HASH") {%opt = (%opt , %{shift(@_)}) } ;
  0            
  0            
26              
27 0 0         if ($opt{type} eq "default"){ $/ = "\n"; }
  0            
28 0 0         if ($opt{type} eq "term") { $/ = ""; }
  0            
29              
30 0           my $file = shift;
31 0           my %dic;
32 0 0         open IN,"<$file" or die "Can load $file\n";
33 0           while () {
34 0           chomp;
35 0 0 0       if (m!^%enc(oding)?\s+([a-zA-Z0-9-]+)!) {
    0          
    0          
36 0           binmode IN, ":$2";
37             next
38 0           } elsif ($opt{type} eq "term") {
39 0 0 0       $opt{lang} = $1 if(!$opt{lang} && m((\w+)));
40              
41 0           my $inf={};
42 0           my @ls = split (/\n(?=\S)/,$_);
43 0           for (@ls){
44 0 0         if(/(\w+)\s+(.*)/s){ push( @{$inf->{$1}}, split (/\s*[;,]\s*/,$2));}
  0            
  0            
45             }
46 0           for(@{$inf->{$opt{lang}}}){
  0            
47 0           $dic{$_} = $inf;
48             }
49             } elsif ($opt{type} eq "default" && /(.*?)\s*\{\s*(.*?)\s*\}/) {
50 0           my @palavras = split (/\s*;\s*/,$2);
51 0           $dic{$1} = [@palavras];
52             }
53             }
54 0           close IN;
55 0           \%dic
56             }
57              
58 0     0 1   sub mostraDic { &showDict; }
59              
60             sub showDict {
61 0     0 1   $nome = shift;
62 0           %dic = %{$nome};
  0            
63 0           for my $chave (sort (keys %dic)) {
64 0           for (@{$dic{$chave}}) {
  0            
65 0           print "$chave -> $_\n";
66             }
67             }
68             }
69              
70 0     0 1   sub escreveDic { &writeDict; }
71              
72              
73             sub writeDict {
74 0     0 1   my $hash= shift;
75 0           my $dic = shift;
76 0           my $dirpath=shift;
77 0           my $d ; ## install dic directory
78 0           my $s='/';
79 0 0         if( $^O eq "linux") {$d= "/usr/share/stardict/dic/" }
  0 0          
  0 0          
80 0           elsif( $^O eq "darwin") {$d= "/opt/gtk/share/stardict/dic/" }
81 0           elsif( $^O eq "MSWin32"){$d= "$ENV{ProgramFiles}\\stardict\\dic\\";$s="\\"}
82 0   0       $dirpath ||= "";
83 0 0 0       $dirpath ||= $d if -d $d;
84 0 0 0       $dirpath ||= "/usr/local/share/stardict/dic/" if -d "/usr/local/share/stardict/dic/";
85 0           my $finalpath= catfile($dirpath,$dic);
86 0 0         unless(-d $finalpath){
87 0 0         mkdir($finalpath,0755) or die "Cant create directory $finalpath\n";
88             }
89 0           my $finalpath2= catfile($finalpath,$dic);
90              
91 0 0         open DICT,">:raw:utf8","$finalpath2.dict" or die ("Cant create $dic.dict\n");
92 0 0         open IDX, ">:raw" ,"$finalpath2.idx" or die ("Cant create $dic.idx\n");
93 0 0         open IFO, ">:raw" ,"$finalpath2.ifo" or die ("Cant create $dic.ifo\n");
94              
95 0           my $byteCount = 0;
96 0           my @keys =();
97             ### { no locale; @keys = sort (keys %{$hash}); }
98 0           @keys = sort {_stardict_strcmp($a,$b)} (keys %{$hash});
  0            
  0            
99 0           for my $chave (@keys) {
100 0           my $posInicial = $byteCount;
101 0           my $word8 = $chave;
102 0 0         $word8 = encode_utf8($word8) unless utf8::is_utf8($chave);
103 1     1   9 { use bytes; print IDX pack('a*x',$word8); }
  1         2  
  1         7  
  0            
  0            
104              
105 0           print IDX pack('N',$byteCount);
106             ### print "$chave \@ $byteCount\n";
107 0           print DICT "$word8\n";
108 0           $byteCount += (bytes::length($word8) + 1);
109              
110 0 0         if(ref($hash->{$chave}) eq "ARRAY"){
    0          
111 0           for (@{$hash->{$chave}}) {
  0            
112 0           my $b=$_;
113 0 0         if(ref $_){ $b= _dumperpp(Dumper($b)); }
  0            
114 0           print DICT "\t$b\n";
115 0           $byteCount += (_len2($b) + 2);
116             } }
117             elsif(ref($hash->{$chave})) {
118 0           my $a= _dumperpp(Dumper($hash->{$chave}));
119             ### print "DEBUG: $chave\n";
120 0           print DICT " $a\n";
121 0           $byteCount += (_len2($a) +3); }
122             else {
123 0           my $a=$hash->{$chave};
124 0           $a =~ s/\s*$//;
125 0           $a =~ s/\n/\n\t/g;
126             ### print "DEBUG: $chave\n\t$a\n";
127 0           print DICT "\t$a\n";
128 0           $byteCount += (_len2($a) +2);
129             }
130 0           print DICT "\n\n";
131 0           $byteCount +=2;
132 0           print IDX pack('N',$byteCount-$posInicial);
133             ### print "length: ",($byteCount-$posInicial),"\n";
134             }
135 0           my $nword = scalar (keys %{$hash});
  0            
136 0           my @t= gmtime(time);
137 0           print IFO "StarDict's dict ifo file\n";
138 0           print IFO "version=2.4.2\n";
139 0           print IFO "wordcount=$nword\n";
140 0           print IFO "bookname=$dic\n";
141             ## print IFO "dictfilesize=$byteCount\n";
142 0           print IFO "idxfilesize=", tell(IDX),"\n";
143 0           print IFO "date=", 1900+$t[5], "-" , $t[4]+1 , "-" , $t[3],"\n";
144 0 0         if($^O eq "MSWin32"){ print IFO "sametypesequence=m\n";}
  0            
145 0           else { print IFO "sametypesequence=x\n";}
146 0           close(IFO);
147 0           close(DICT);
148 0           close(IDX);
149             }
150              
151             sub _len2{
152 0     0     my $string = shift;
153 0 0         $string = encode_utf8($string) unless utf8::is_utf8($string);
154 0           bytes::length($string) ;
155             }
156             #sub len2{ do { length($_[0]) } }
157              
158             sub _dumperpp{
159 0     0     my $a = shift;
160 0           $a =~ s/.*'_NAME_' .*\n// ;
161             # $a =~ s/\$VAR\d*\s*=(\s|[\{\[])*//;
162 0           $a =~ s/^(\s|[\{\[])*//;
163 0           $a =~ s/[\}\]]?\s*$//;
164             ## $a =~ s/\n /\n\t/g;
165 0           $a =~ s/\s*(\[|\]|\{|\}),?\s*\n/\n/g;
166 0           $a =~ s/\\x\{(.*?)\}/chr(hex("$1"))/ge;
  0            
167 0           $a =~ s/'(.*?)'/$1/g;
168 0           $a =~ s/"(.*?)"/$1/g;
169 0           $a;
170             }
171              
172             sub _g_ascii_strcasecmp { # pure perl re-implementation of g_ascii_strcasecmp
173 0     0     my $s1 = shift;
174 0           my $s2 = shift;
175 1     1   1217 no locale;
  1         3  
  1         10  
176 0           $s1=~s/([A-Z])/lc($1)/ge;
  0            
177 0           $s2=~s/([A-Z])/lc($1)/ge;
  0            
178 0   0       while (length($s1) || length($s2))
179             {
180 0 0         return -1 if length($s1)==0;
181 0 0         return 1 if length($s2)==0;
182 0           $s1=~s/^(.)//;
183 0           my $c1 = $1;
184 0           $s2=~s/^(.)//;
185 0           my $c2 = $1;
186 0 0         return ord($c1)-ord($c2) if $c1 ne $c2;
187             }
188 0           return 0;
189             }
190              
191             sub _strcmp { # pure perl re-implementation of strcmp
192 0     0     my $s1 = shift;
193 0           my $s2 = shift;
194 1     1   390 no locale;
  1         2  
  1         14  
195 0   0       while (length($s1) || length($s2)) {
196 0 0         return -1 if length($s1)==0;
197 0 0         return 1 if length($s2)==0;
198 0           $s1=~s/^(.)//;
199 0           my $c1 = $1;
200 0           $s2=~s/^(.)//;
201 0           my $c2 = $1;
202 0 0         return ord($c1)-ord($c2) if $c1 ne $c2;
203             }
204 0           return 0;
205             }
206              
207             sub _stardict_strcmp { # pure perl re-implementation of stardict_strcmp
208 0     0     my $s1 = shift;
209 0           my $s2 = shift;
210            
211 0           my $i = _g_ascii_strcasecmp($s1, $s2);
212 0 0         return $i if $i;
213 0           return _strcmp($s1,$s2);
214             }
215              
216              
217             1;
218              
219             =encoding utf8
220              
221             =head1 NAME
222              
223             Lingua::StarDict::Gen - Stardict dictionary generator
224              
225             =head1 SYNOPSIS
226              
227             use Lingua::StarDict::Gen;
228              
229             $dic = { word1 => ...
230             word2 => ...
231             }
232              
233             Lingua::StarDict::Gen::writeDict($dic,"dicname" [,"dirpath"]);
234             Lingua::StarDict::Gen::escreveDic($dic,"dicname" [,"dirpath"]);
235              
236             $dic=Lingua::StarDict::Gen::loadDict("file");
237             $dic=Lingua::StarDict::Gen::carregaDic("file");
238              
239             =head1 DESCRIPTION
240              
241             This module generates StarDict dictionaries from HASH references (function C).
242              
243             This module also imports a simple dictionary (lines with C)(function
244             C).
245              
246              
247             =head1 ABSTRACT
248              
249             C is a perl module for building Stardict
250             dictionaries from perl Hash.
251              
252             Also included perl script for making stardicts form term-format and
253             thesaurus-format.
254              
255             =head1 FUNCTIONS
256              
257             =head2 writeDict
258              
259             =head2 escreveDic
260              
261             Lingua::StarDict::Gen::writeDict($dic,"dicname");
262             Lingua::StarDict::Gen::writeDict($dic,"dicname", dir);
263              
264             Write the necessary files StarDict files for dictionary in $dic HASH reference.
265              
266             C is the directory where the StarDict files are written.
267              
268             If no C is provided, Lingua::StarDict::Gen will try to write it in
269             C (the default path for StarDict dictionaries).
270             In this case the dictionary will be automatically installed.
271              
272              
273             =head2 loadDict
274              
275             =head2 carregaDic
276              
277             This function loads a simple dictionary to a HASH reference.
278              
279             $dic=Lingua::StarDict::Gen::loadDict("file");
280              
281             Where file has the following sintax:
282              
283             word{def 1; def 2;... ;def n}
284              
285             Example (default format):
286              
287             %encoding utf8
288             cat{gato; tareco; animal com quatros patas e mia}
289             dog{...}
290              
291             Example2 (terminology format):
292              
293             %encoding utf8
294              
295             EN cat ; feline
296             PT gato ; tareco
297             DEF animal com 4 patas e que mia
298              
299             EN house; building; appartment
300             PT house
301             FR maison
302             ...
303              
304             In this case we must say the type used:
305              
306             $dic=Lingua::StarDict::Gen::loadDict({type=>"term"},"file");
307              
308             or even specify the language:
309              
310             $dic=Lingua::StarDict::Gen::loadDict(
311             {type=>"term", lang=>"PT"},"file");
312              
313             See also the script C in the destribution.
314              
315             =head2 mostraDic
316              
317             =head2 showDict
318              
319             showDict($hash);
320              
321             Prints to stdio the information in the hash in the form
322              
323             word -> definition
324              
325             =head1 Authors
326              
327             José João Almeida
328              
329             Alberto Simões
330              
331             Paulo Silva
332              
333             Paulo Soares
334              
335             Nicolav Shaplov
336              
337             =head1 SEE ALSO
338              
339             stardict
340              
341             perl
342              
343             wiktionary-export/trunk/StarDict
344              
345             =head1 COPYRIGHT & LICENSE
346              
347             Copyright 2008 J.Joao, All Rights Reserved.
348              
349             This program is free software; you can redistribute it and/or modify it
350             under the same terms as Perl itself.
351              
352             =cut
353              
354             1; # End of Lingua::StarDict::Gen