File Coverage

blib/lib/Template/Plugin/Translit/RU.pm
Criterion Covered Total %
statement 12 39 30.7
branch 0 4 0.0
condition 0 6 0.0
subroutine 4 11 36.3
pod 1 5 20.0
total 17 65 26.1


line stmt bran cond sub pod time code
1             #============================================================= -*-Perl-*-
2             #
3             # Template::Plugin::Translit::RU
4             #
5             # DESCRIPTION
6             # Filter converting cyrillic text into transliterated one.
7             #
8             # AUTHOR
9             # Igor Lobanov
10             #
11             # COPYRIGHT
12             # Copyright (C) 2004 Igor Lobanov. All Rights Reserved.
13             #
14             # This module is free software; you can redistribute it and/or
15             # modify it under the same terms as Perl itself.
16             #
17             #============================================================================
18              
19             package Template::Plugin::Translit::RU;
20 1     1   33481 use strict;
  1         3  
  1         37  
21 1     1   5 use vars qw( $VERSION );
  1         2  
  1         54  
22 1     1   870 use Template::Plugin;
  1         11750  
  1         29  
23 1     1   9 use base qw( Template::Plugin );
  1         1  
  1         1139  
24              
25             $VERSION = sprintf("%d.%02d", q$Revision: 0.05 $ =~ /(\d+)\.(\d+)/);
26              
27             my $DEFAULT_CHARSET = 'koi';
28              
29             # (en|de)code table
30             my $tab = {
31             koi => {
32             # {1} => {1}
33             single => [
34             'ÁÂ×ÇÄÅÚÉÊËÌÍÎÏÐÒÓÔÕÆØÙßáâ÷çäåúéêëìíîïðòóôõæøùÿ',
35             "abvgdezijklmnoprstuf'y\"ABVGDEZIJKLMNOPRSTUF'Y\""
36             ],
37             # + => {2,}
38             plural => [
39             # 0: re with plural-transliterated letters and special cases
40             '(ÕÛÞ|Ø[Å£ÀÑ]|Ù[Å£ÀÑÕ]|£|Ö|È|Ã|Þ|Û|Ý|Ü|À|Ñ|õûþ|ø[å³àñ]|ù[å³àñõ]|³|ö|è|ã|þ|û|ý|ü|à|ñ)',
41             # 1: table for these letters and cases [0]
42             {
43             '£' => 'yo',
44             '³' => 'Yo',
45             'Ö' => 'zh',
46             'ö' => 'Zh',
47             'È' => 'kh',
48             'è' => 'Kh',
49             'Ã' => 'tc',
50             'ã' => 'Tc',
51             'Þ' => 'ch',
52             'þ' => 'Ch',
53             'Û' => 'sh',
54             'û' => 'Sh',
55             'Ý' => 'shch',
56             'ý' => 'Shch',
57             'Ù' => 'y',
58             'ù' => 'Y',
59             'Ü' => 'ye',
60             'ü' => 'Ye',
61             'À' => 'yu',
62             'à' => 'Yu',
63             'Ñ' => 'ya',
64             'ñ' => 'Ya',
65             # {2} => {3} - could not be at the begining of the word
66             'ØÅ' => 'jie',
67             'øå' => 'JIE',
68             'Ø£' => 'jio',
69             'ø³' => 'JIO',
70             'ØÀ' => 'jiu',
71             'øà' => 'JIU',
72             'ØÑ' => 'jia',
73             'øñ' => 'JIA',
74             'ÙÅ' => 'yje',
75             'ùå' => 'YJE',
76             'Ù£' => 'yjo',
77             'ù³' => 'YJO',
78             'ÙÀ' => 'yju',
79             'ùà' => 'YJU',
80             'ÙÑ' => 'yja',
81             'ùñ' => 'YJA',
82             'ÙÕ' => 'yiu',
83             'ùõ' => 'YIU',
84             # {3} => {3,5} - could not be at the begining of the word
85             'ÕÛÞ' => 'uisch',
86             'õûþ' => 'UISCH',
87             },
88             # 3: re with special transliterated escapes
89             '(uisch|UISCH|shch|Shch|SHCH|tch|TCH|Tch|ji[eoua]|JI[EOUA]|yj[eoua]|yiu|YIU|YJ[EOUA]|yo|zh|kh|tc|ch|sh|ye|yu|ya|Y[Oo]|Z[Hh]|K[Hh]|T[Cc]|C[Hh]|S[Hh]|Y[Ee]|Y[Uu]|Y[Aa])',
90             # 4: table for special transliterated escapes [3]
91             {
92             'shch' => 'Ý',
93             'SHCH' => 'ý',
94             'Shch' => 'ý',
95             'tch' => 'ÔÞ',
96             'TCH' => 'ôþ',
97             'Tch' => 'ôÞ',
98             'jie' => 'ØÅ',
99             'jio' => 'Ø£',
100             'jiu' => 'ØÀ',
101             'jia' => 'ØÑ',
102             'JIE' => 'øå',
103             'JIO' => 'ø³',
104             'JIU' => 'øà',
105             'JIA' => 'øñ',
106             'yje' => 'ÙÅ',
107             'yjo' => 'Ù£',
108             'yju' => 'ÙÀ',
109             'yja' => 'ÙÑ',
110             'yiu' => 'ÙÕ',
111             'YJE' => 'ùå',
112             'YJO' => 'ù³',
113             'YJU' => 'ùà',
114             'YJA' => 'ùñ',
115             'YIU' => 'ùõ',
116             'yo' => '£',
117             'zh' => 'Ö',
118             'kh' => 'È',
119             'tc' => 'Ã',
120             'ch' => 'Þ',
121             'sh' => 'Û',
122             'ye' => 'Ü',
123             'yu' => 'À',
124             'ya' => 'Ñ',
125             'YO' => '³',
126             'Yo' => '³',
127             'ZH' => 'ö',
128             'Zh' => 'ö',
129             'KH' => 'è',
130             'Kh' => 'è',
131             'TC' => 'ã',
132             'Tc' => 'ã',
133             'CH' => 'þ',
134             'Ch' => 'þ',
135             'SH' => 'û',
136             'Sh' => 'û',
137             'YE' => 'ü',
138             'Ye' => 'ü',
139             'YU' => 'à',
140             'Yu' => 'à',
141             'YA' => 'ñ',
142             'Ya' => 'ñ',
143             'uisch' => 'ÕÛÞ',
144             'UISCH' => 'õûþ',
145             }
146             ]
147             },
148             win => {
149             # {1} => {1}
150             single => [
151             'àáâãäåçèéêëìíîïðñòóôüûúÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÜÛÚ',
152             "abvgdezijklmnoprstuf'y\"ABVGDEZIJKLMNOPRSTUF'Y\""
153             ],
154             # + => {2,}
155             plural => [
156             # 0: re with plural-transliterated letters and special cases
157             '(óø÷|ü[å¸þÿ]|û[å¸þÿó]|¸|æ|õ|ö|÷|ø|ù|ý|þ|ÿ|ÓØ×|Ü[ŨÞß]|Û[ŨÞßÓ]|¨|Æ|Õ|Ö|×|Ø|Ù|Ý|Þ|ß)',
158             # 1: table for these letters and cases [0]
159             {
160             '¸' => 'yo',
161             '¨' => 'Yo',
162             'æ' => 'zh',
163             'Æ' => 'Zh',
164             'õ' => 'kh',
165             'Õ' => 'Kh',
166             'ö' => 'tc',
167             'Ö' => 'Tc',
168             '÷' => 'ch',
169             '×' => 'Ch',
170             'ø' => 'sh',
171             'Ø' => 'Sh',
172             'ù' => 'shch',
173             'Ù' => 'Shch',
174             'û' => 'y',
175             'Û' => 'Y',
176             'ý' => 'ye',
177             'Ý' => 'Ye',
178             'þ' => 'yu',
179             'Þ' => 'Yu',
180             'ÿ' => 'ya',
181             'ß' => 'Ya',
182             # {2} => {3} - could not be at the begining of the word
183             'üå' => 'jie',
184             'ÜÅ' => 'JIE',
185             'ü¸' => 'jio',
186             'ܨ' => 'JIO',
187             'üþ' => 'jiu',
188             'ÜÞ' => 'JIU',
189             'üÿ' => 'jia',
190             'Üß' => 'JIA',
191             'ûå' => 'yje',
192             'ÛÅ' => 'YJE',
193             'û¸' => 'yjo',
194             'Û¨' => 'YJO',
195             'ûþ' => 'yju',
196             'ÛÞ' => 'YJU',
197             'ûÿ' => 'yja',
198             'Ûß' => 'YJA',
199             'ûó' => 'yiu',
200             'ÛÓ' => 'YIU',
201             # {3} => {3,5} - could not be at the begining of the word
202             'óø÷' => 'uisch',
203             'ÓØ×' => 'UISCH',
204             },
205             # 3: re with special transliterated escapes
206             '(uisch|UISCH|shch|Shch|SHCH|tch|TCH|Tch|ji[eoua]|JI[EOUA]|yj[eoua]|yiu|YIU|YJ[EOUA]|yo|zh|kh|tc|ch|sh|ye|yu|ya|Y[Oo]|Z[Hh]|K[Hh]|T[Cc]|C[Hh]|S[Hh]|Y[Ee]|Y[Uu]|Y[Aa])',
207             # 4: table for special transliterated escapes [3]
208             {
209             'shch' => 'ù',
210             'SHCH' => 'Ù',
211             'Shch' => 'Ù',
212             'tch' => 'ò÷',
213             'TCH' => 'Ò×',
214             'Tch' => 'Ò÷',
215             'jie' => 'üå',
216             'jio' => 'ü¸',
217             'jiu' => 'üþ',
218             'jia' => 'üÿ',
219             'JIE' => 'ÜÅ',
220             'JIO' => 'ܨ',
221             'JIU' => 'ÜÞ',
222             'JIA' => 'Üß',
223             'yje' => 'ûå',
224             'yjo' => 'û¸',
225             'yju' => 'ûþ',
226             'yja' => 'ûÿ',
227             'yiu' => 'ûó',
228             'YJE' => 'ÛÅ',
229             'YJO' => 'Û¨',
230             'YJU' => 'ÛÞ',
231             'YJA' => 'Ûß',
232             'YIU' => 'ÛÓ',
233             'yo' => '¸',
234             'zh' => 'æ',
235             'kh' => 'õ',
236             'tc' => 'ö',
237             'ch' => '÷',
238             'sh' => 'ø',
239             'ye' => 'ý',
240             'yu' => 'þ',
241             'ya' => 'ÿ',
242             'YO' => '¨',
243             'Yo' => '¨',
244             'ZH' => 'Æ',
245             'Zh' => 'Æ',
246             'KH' => 'Õ',
247             'Kh' => 'Õ',
248             'TC' => 'Ö',
249             'Tc' => 'Ö',
250             'CH' => '×',
251             'Ch' => '×',
252             'SH' => 'Ø',
253             'Sh' => 'Ø',
254             'YE' => 'Ý',
255             'Ye' => 'Ý',
256             'YU' => 'Þ',
257             'Yu' => 'Þ',
258             'YA' => 'ß',
259             'Ya' => 'ß',
260             'uisch' => 'óø÷',
261             'UISCH' => 'ÓØ×',
262             }
263             ]
264             }
265             };
266              
267             # define aliases
268             $tab->{'windows-1251'} = $tab->{'cp1251'} = $tab->{'win'};
269             $tab->{'koi8-r'} = $tab->{'koi8r'} = $tab->{'koi8'} = $tab->{'koi'};
270              
271             sub new {
272 0     0 1   my ( $class, $context, @params ) = @_;
273              
274             # init future object
275 0           my $self = {
276             _CONTEXT => $context,
277 0           _PARAMS => { map { $_ => 1 } @params },
278             };
279              
280             # check translit flag and define translit filter factory
281 0 0         if ( $self->{_PARAMS}->{translit} ) {
282 0           $context->define_filter( 'translit', [ \&translit_filter_factory, 1 ] );
283             }
284              
285             # check detranslit flag and define detranslit filter factory
286 0 0         if ( $self->{_PARAMS}->{detranslit} ) {
287 0           $context->define_filter( 'detranslit', [ \&detranslit_filter_factory, 1 ] );
288             }
289              
290 0           bless $self, $class;
291             }
292              
293             sub translit_filter_factory {
294 0     0 0   my ( $context, $charset ) = @_;
295             return sub {
296 0     0     my $text = shift;
297 0           Template::Plugin::Translit::RU->translit( $text, $charset );
298             }
299 0           }
300              
301             sub detranslit_filter_factory {
302 0     0 0   my ( $context, $charset ) = @_;
303             return sub {
304 0     0     my $text = shift;
305 0           Template::Plugin::Translit::RU->detranslit( $text, $charset );
306             }
307 0           }
308              
309             sub translit {
310 0     0 0   my ( $self, $text, $charset ) = @_;
311 0   0       $charset ||= $DEFAULT_CHARSET;
312             # replace plurals (most slow place)
313 0           $text =~ s/$tab->{$charset}->{plural}->[0]/$tab->{$charset}->{plural}->[1]->{$1}/sg;
314             # replace singles
315 0           eval "\$text =~ tr/$tab->{$charset}->{single}->[0]/$tab->{$charset}->{single}->[1]/";
316 0           return $text;
317             }
318              
319             sub detranslit {
320 0     0 0   my ( $self, $text, $charset ) = @_;
321 0   0       $charset ||= $DEFAULT_CHARSET;
322             # replace plurals (most slow place)
323 0           $text =~ s/$tab->{$charset}->{plural}->[2]/$tab->{$charset}->{plural}->[3]->{$1}/sge;
  0            
324             # replace singles
325 0           eval "\$text =~ tr/$tab->{$charset}->{single}->[1]/$tab->{$charset}->{single}->[0]/";
326 0           return $text;
327             }
328              
329             1;
330              
331             __END__