File Coverage

blib/lib/Lingua/RU/Preposition.pm
Criterion Covered Total %
statement 66 71 92.9
branch 25 30 83.3
condition n/a
subroutine 30 33 90.9
pod 1 1 100.0
total 122 135 90.3


line stmt bran cond sub pod time code
1             package Lingua::RU::Preposition;
2              
3 4     4   99576 use warnings;
  4         10  
  4         146  
4 4     4   26 use strict;
  4         10  
  4         148  
5 4     4   1243 use utf8;
  4         28  
  4         31  
6              
7             =encoding utf8
8              
9             =head1 NAME
10              
11             Lingua::RU::Preposition - linguistic function for prepositions in Russian.
12              
13             =head1 VERSION
14              
15             Version 0.02
16              
17             =head1 DESCRIPTION
18              
19             Lingua::RU::Preposition is a perl module
20             that provides choosing proper form of varying Russian prepositions.
21              
22             =cut
23              
24              
25             BEGIN {
26 4     4   170 use Exporter ();
  4         6  
  4         896  
27 4     4   11 our ($VERSION, $DATE, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
28              
29             # set the version for version checking
30 4         9 $VERSION = 0.02;
31             # date written by hands because git does not process keywords
32 4         9 $DATE = '2014-09-16';
33              
34 4         77 @ISA = qw(Exporter);
35 4         11 @EXPORT = qw(
36             choose_preposition_by_next_word
37             );
38              
39             # exported package globals
40 4         14 @EXPORT_OK = qw(
41             bezo izo izpodo ko nado ob obo oto predo peredo podo so vo
42             );
43              
44 4         2618 %EXPORT_TAGS = (
45             'subs' => [ @EXPORT ],
46             'short' => [ @EXPORT_OK ],
47             'all' => [ @EXPORT, @EXPORT_OK ],
48             )
49              
50             }
51              
52             =head1 SYNOPSIS
53              
54             use Lingua::RU::Preposition qw/:all/;
55              
56             # Following string contains cyrillic letters
57             print ob, 'мне'; # prints 'обо' (obo)
58             print choose_preposition_by_next_word 'из', 'огня'; # prints 'из' (iz)
59              
60             =head1 TO DO
61              
62             Check rules by dictionaries and correct if needed.
63              
64             =head1 EXPORT
65              
66             Function C exported by default.
67              
68             Also you can export only short aliases for subs
69              
70             use Lingua::RU::Preposition qw/:short/;
71              
72             Or everything: subs and aliases:
73              
74             use Lingua::RU::Preposition qw/:all/; # or
75             use Lingua::RU::Preposition qw/:subs :short/;
76              
77             =head1 FUNCTIONS
78              
79             =head2 choose_preposition_by_next_word
80              
81             Chooses preposition by next word and returns chosen preposition.
82              
83             Expects 2 arguments: I and I.
84             I should be string with shortest of possible values.
85             Available values of I are:
86             C<'без'>, C<'в'>, C<'из'>, C<'из-под'>, C<'к'>, C<'над'>, C<'о'>, C<'от'>,
87             C<'пред'>, C<'перед'>, C<'под'> and C<'с'>.
88              
89             There is an aliases for calling this subroutine with common preposition:
90              
91             =head3 bezo
92              
93             C is an alias for C
94              
95             This preposition can be used with some words in both forms, they are correct.
96             Example: “без всего” (bez vsego) and “безо всего” (bezo vsego) both are correct.
97             If possible function return long form.
98              
99             =head3 izo
100              
101             C is an alias for C
102              
103             =head3 izpodo
104              
105             C is an alias for C
106              
107             =head3 ko
108              
109             C is an alias for C
110              
111             =head3 nado
112              
113             C is an alias for C
114              
115             =head3 ob and obo
116              
117             C and C are aliases for C
118              
119             =head3 oto
120              
121             C is an alias for C
122              
123             =head3 podo
124              
125             C is an alias for C
126              
127             =head3 predo
128              
129             C is an alias for C
130              
131             =head3 peredo
132              
133             C is an alias for C
134              
135             =head3 so
136              
137             C is an alias for C
138              
139             =head3 vo
140              
141             C is an alias for C
142              
143             These aliases are not exported by default. They can be expored with tags C<:short> or C<:all>.
144              
145             Example of code with these aliases:
146              
147             use Lingua::RU::Preposition qw/:short/;
148              
149             map {
150             print ob, $_;
151             } qw(
152             арбузе баране всём Елене ёлке игле йоде
153             мне многом огне паре ухе юге яблоке
154             );
155              
156             map {
157             print so, $_;
158             } qw(
159             огнём водой
160             зарёй зноем зрением зябликом
161             садом светом слоном спичками ссылкой
162             Стёпой стаканом сухарём сэром топором
163             жарой жбаном жратвой жуком
164             шаром шкафом шлангом шубой
165             );
166              
167             =cut
168              
169             sub choose_preposition_by_next_word ($$) {
170 52 50   52 1 305 my $preposition = lc shift or return undef;
171 52 50       18355 local $_ = lc shift or return undef;
172              
173             # Nested subroutine
174             local *_check_instrumental = sub {
175 13     13   19 for my $word (qw( льдом льном мной мною )) {
176 42 100       263 return $_[0] . 'о' if $word eq $_[1]
177             }
178 4         72 return $_[0]
179 52         219 }; # _check_instrumental
180              
181             # preposition => function
182             # TODO Check by dictionary
183             my %GRAMMAR = (
184             'без' => sub {
185 2     2   5 for my $word (qw( всего всей всех всякого всякой всяких )) {
186             # WARNING
187             # difficult case, both words are OK
188 7 100       50 return 'безо' if $word eq $_
189             }
190             'без'
191 1         21 },
192             'в' => sub {
193 7     7   12 for my $word (qw( все всём мне мно )) {
194 27 100       356 return 'во' if /^$word/
195             }
196             /^[вф][^аеёиоуыэюя]/
197 5 100       140 ? 'во'
198             : 'в'
199             },
200             'из' => sub {
201 3     3   8 for my $word (qw( всех льда )) {
202 4 100       64 return 'изо' if $word eq $_
203             }
204             'из'
205 1         20 },
206             'из-под' => sub {
207 0     0   0 for my $word (qw( всех льда )) {
208 0 0       0 return 'из-подо' if $word eq $_
209             }
210             'из-под'
211 0         0 },
212             'к' => sub {
213 6     6   15 for my $word (qw( всем мне мно )) {
214 12 100       313 return 'ко' if /^$word/
215             }
216             'к'
217 1         26 },
218             'о' => sub {
219 7     7   16 for my $word (qw( всех всем всём мне что )) {
220 32 100       128 return 'обо' if $word eq $_
221             }
222             return
223 5 100       168 /^[аиоуыэ]/
224             ? 'об'
225             : 'о'
226             },
227             'от' => sub {
228 3     3   7 for my $word (qw( всех )) {
229 3 100       48 return 'ото' if $word eq $_
230             }
231             'от'
232 1         23 },
233             'с' => sub {
234 11 100   11   55 return 'со' if /^мно/;
235             return
236 4 100   4   27 /^[жзсш][^аеёиоуыэюя]/i
  4         7  
  4         61  
  10         228  
237             ? 'со'
238             : 'с'
239             },
240             # Same rules:
241 3     3   9 'над' => sub { _check_instrumental('над', $_) },
242 4     4   8 'под' => sub { _check_instrumental('под', $_) },
243 3     3   8 'перед' => sub { _check_instrumental('перед', $_) },
244 3     3   9 'пред' => sub { _check_instrumental('пред', $_) },
245 52         1002 );
246              
247 52 50       172 return undef unless exists $GRAMMAR{$preposition};
248              
249 52         153 $GRAMMAR{$preposition}->($_);
250              
251             } # sub choose_preposition_by_next_word
252              
253             # Aliases
254 0     0   0 *bezo = sub { choose_preposition_by_next_word 'без', shift };
255 1     1   16 *izo = sub { choose_preposition_by_next_word 'из', shift };
256 0     0   0 *izpodo = sub { choose_preposition_by_next_word 'из-под',shift };
257 2     2   9 *ko = sub { choose_preposition_by_next_word 'к', shift };
258 1     1   4 *nado = sub { choose_preposition_by_next_word 'над', shift };
259 1     1   4 *ob = sub { choose_preposition_by_next_word 'о', shift };
260 1     1   5 *obo = sub { choose_preposition_by_next_word 'о', shift };
261 1     1   5 *oto = sub { choose_preposition_by_next_word 'от', shift };
262 1     1   3 *predo = sub { choose_preposition_by_next_word 'пред', shift };
263 1     1   4 *peredo = sub { choose_preposition_by_next_word 'перед', shift };
264 1     1   3 *podo = sub { choose_preposition_by_next_word 'под', shift };
265 1     1   4 *so = sub { choose_preposition_by_next_word 'с', shift };
266 1     1   5 *vo = sub { choose_preposition_by_next_word 'в', shift };
267              
268             =head1 AUTHOR
269              
270             Alexander Sapozhnikov, C<< >>
271              
272             =head1 BUGS
273              
274             Please report any bugs or feature requests
275             to C, or through the web interface
276             at L.
277             I will be notified, and then
278             you'll automatically be notified of progress on your bug as I make changes.
279              
280             =head1 SUPPORT
281              
282             You can find documentation for this module with the perldoc command.
283              
284             perldoc Lingua::RU::Preposition
285              
286             You can also look for information at:
287              
288             =over 4
289              
290             =item * RT: CPAN's request tracker
291              
292             L
293              
294             =item * AnnoCPAN: Annotated CPAN documentation
295              
296             L
297              
298             =item * CPAN Ratings
299              
300             L
301              
302             =item * Search CPAN
303              
304             L
305              
306             =back
307              
308             =head1 SEE ALSO
309              
310             Russian translation of this documentation available
311             at F
312              
313             =head1 COPYRIGHT & LICENSE
314              
315             Copyright 2010-2014 Alexander Sapozhnikov.
316              
317             This program is free software; you can redistribute it and/or modify it
318             under the terms of either: the GNU General Public License as published
319             by the Free Software Foundation; or the Artistic License.
320              
321             See http://dev.perl.org/licenses/ for more information.
322              
323             =cut
324              
325             1;