File Coverage

blib/lib/Text/Language/Guess.pm
Criterion Covered Total %
statement 83 85 97.6
branch 10 14 71.4
condition 4 6 66.6
subroutine 16 16 100.0
pod 5 8 62.5
total 118 129 91.4


line stmt bran cond sub pod time code
1             ###########################################
2             # Text::Language::Guess
3             # 2005, Mike Schilli
4             ###########################################
5              
6             ###########################################
7             package Text::Language::Guess;
8             ###########################################
9              
10 1     1   33782 use strict;
  1         3  
  1         47  
11 1     1   6 use warnings;
  1         2  
  1         45  
12 1     1   6 use vars qw(%STOPMAPS $VERSION);
  1         7  
  1         232  
13              
14 1     1   1836 use Log::Log4perl qw(:easy);
  1         59626  
  1         9  
15 1     1   1500 use Text::ExtractWords;
  1         2987  
  1         125  
16 1     1   881 use Lingua::StopWords;
  1         335  
  1         41  
17 1     1   5 use File::Spec;
  1         2  
  1         20  
18 1     1   5 use File::Basename;
  1         2  
  1         993  
19              
20             %STOPMAPS = ();
21             $VERSION = "0.02";
22              
23             ###########################################
24             sub new {
25             ###########################################
26 2     2 1 429 my($class, @options) = @_;
27              
28 2         8 my $self = {
29             languages => languages(),
30             @options,
31             };
32              
33 2         19 bless $self, $class;
34              
35             # To avoid re-initializing the stopmap (which is fairly expensive)
36             # on every new(), hold all stopmaps for pre-computed language
37             # combinations in a class variable.
38 2 50       7 if(exists $STOPMAPS{"@{$self->{languages}}"}) {
  2         31  
39 0         0 $self->{stopmap} = $STOPMAPS{"@{$self->{languages}}"};
  0         0  
40             } else {
41 2         11 $self->{stopmap} = $self->stopwords();
42 2         5 $STOPMAPS{"@{$self->{languages}}"} = $self->{stopmap};
  2         11  
43             }
44              
45 2         8 return $self;
46             }
47              
48             ###########################################
49             sub scores {
50             ###########################################
51 2     2 1 375 my($self, $file) = @_;
52              
53 2         5 return $self->scores_string(slurp($file));
54             }
55              
56             ###########################################
57             sub scores_string {
58             ###########################################
59 10     10 1 23 my($self, $data) = @_;
60              
61 10         16 my @words = ();
62 10         20 my %scores = ();
63              
64 10 50 33     43 LOGDIE "Cannot score empty/undefined document" if
65             !defined $data or !length $data;
66              
67 10         231 words_list(\@words, $data, {});
68            
69 10         21 for my $word (@words) {
70 300         483 my $langs = $self->{stopmap}->{$word};
71            
72 300 100       495 if(! defined $langs) {
73 184         444 DEBUG "$word doesn't match any language";
74 184         1027 next;
75             }
76            
77 116         145 for my $lang (@$langs) {
78 197         663 DEBUG "Scoring for $lang";
79 197         1172 $scores{$lang}++;
80             }
81             }
82              
83 10         49 return \%scores;
84             }
85            
86             ###########################################
87             sub language_guess {
88             ###########################################
89 4     4 1 25 my($self, $file) = @_;
90            
91 4         12 return $self->language_guess_string(slurp($file));
92             }
93              
94             ###########################################
95             sub language_guess_string {
96             ###########################################
97 6     6 1 16 my($self, $data) = @_;
98              
99 6         15 my $scores = $self->scores_string($data);
100              
101 6         9 my $best_lang;
102             my $max_score;
103            
104 6         19 for my $lang (keys %$scores) {
105 31 100 100     163 if(!defined $max_score or
106             $max_score < $scores->{$lang}) {
107 10         13 $best_lang = $lang;
108 10         17 $max_score = $scores->{$lang};
109             }
110             }
111            
112 6         56 return $best_lang;
113             }
114              
115             ###########################################
116             sub stopwords {
117             ###########################################
118 2     2 0 5 my($self) = @_;
119              
120             # Fetch all stopword lists from all supported languages
121              
122 2         6 my $stopmap = {};
123              
124 2         5 for my $lang (@{$self->{languages}}) {
  2         8  
125            
126 15         69 DEBUG "Loading language $lang";
127              
128 15         136 my $stopwords = Lingua::StopWords::getStopWords($lang);
129              
130 15         34426 for my $stopword (keys %$stopwords) {
131 2612         7458 DEBUG "Pushing $stopword => $lang";
132 2612         15471 push @{$stopmap->{$stopword}}, $lang;
  2612         8704  
133             }
134             }
135              
136 2         8 return $stopmap;
137             }
138            
139             ###########################################
140             sub languages {
141             ###########################################
142              
143             # Check which languages are supported by Lingua::StopWords
144              
145 2     2 0 6 for my $dir (@INC) {
146 16 100       477 if(-f File::Spec->catfile($dir, "Lingua/StopWords.pm")) {
147 2         2330 return [map { s/\.pm$//; lc basename($_); }
  26         103  
  26         910  
148             <$dir/Lingua/StopWords/*.pm>];
149             }
150             }
151             }
152              
153             ###########################################
154             sub slurp {
155             ###########################################
156 10     10 0 754 my($file) = @_;
157              
158 10 50       4268 LOGDIE "$file not a file" unless -f $file;
159              
160 10         229 local $/ = undef;
161              
162 10         12 my $data;
163              
164 10 50       1032 open FILE, "<$file" or LOGDIE "Cannot open $file ($!)";
165 10         1920 $data = ;
166 10         91 close FILE;
167 10         51 return $data;
168             }
169              
170             1;
171              
172             __END__