rutils 1.1.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gemtest +0 -0
- data/History.txt +10 -0
- data/Manifest.txt +4 -8
- data/README.txt +20 -172
- data/Rakefile.rb +5 -11
- data/init.rb +3 -3
- data/lib/{gilenson/gilenson_stub.rb → gilenson_stub.rb} +0 -6
- data/lib/integration/integration.rb +1 -1
- data/lib/integration/rails_date_helper_override.rb +4 -4
- data/lib/pluralizer.rb +101 -0
- data/lib/rudates.rb +85 -0
- data/lib/rutils.rb +13 -7
- data/lib/transliteration.rb +30 -0
- data/lib/version.rb +1 -1
- data/test/extras/integration_rails_filter.rb +1 -1
- data/test/extras/integration_rails_gilenson_helpers.rb +1 -1
- data/test/extras/integration_rails_helpers.rb +1 -1
- data/test/run_tests.rb +1 -1
- data/test/test_datetime.rb +16 -7
- data/test/test_integration.rb +1 -1
- data/test/test_integration_flag.rb +1 -1
- data/test/test_pluralize.rb +1 -1
- data/test/test_rutils_base.rb +1 -1
- data/test/test_transliteration.rb +1 -32
- metadata +45 -32
- data/bin/rutilize +0 -38
- data/lib/countries/countries.rb +0 -1773
- data/lib/datetime/datetime.rb +0 -83
- data/lib/pluralizer/pluralizer.rb +0 -288
- data/lib/transliteration/bidi.rb +0 -21
- data/lib/transliteration/simple.rb +0 -75
- data/lib/transliteration/transliteration.rb +0 -79
data/lib/datetime/datetime.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
module RuTils
|
3
|
-
module DateTime
|
4
|
-
|
5
|
-
def self.distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, absolute = false) #nodoc
|
6
|
-
from_time = from_time.to_time if from_time.respond_to?(:to_time)
|
7
|
-
to_time = to_time.to_time if to_time.respond_to?(:to_time)
|
8
|
-
distance_in_minutes = (((to_time - from_time).abs)/60).round
|
9
|
-
distance_in_seconds = ((to_time - from_time).abs).round
|
10
|
-
|
11
|
-
case distance_in_minutes
|
12
|
-
when 0..1
|
13
|
-
return (distance_in_minutes==0) ? 'меньше минуты' : '1 минуту' unless include_seconds
|
14
|
-
|
15
|
-
case distance_in_seconds
|
16
|
-
when 0..5 then 'менее 5 секунд'
|
17
|
-
when 6..10 then 'менее 10 секунд'
|
18
|
-
when 11..20 then 'менее 20 секунд'
|
19
|
-
when 21..40 then 'пол-минуты'
|
20
|
-
when 41..59 then 'меньше минуты'
|
21
|
-
else '1 минуту'
|
22
|
-
end
|
23
|
-
|
24
|
-
when 2..45 then distance_in_minutes.to_s +
|
25
|
-
" " + distance_in_minutes.items("минута", "минуты", "минут")
|
26
|
-
when 46..90 then 'около часа'
|
27
|
-
# исключение, сдвигаем на один влево чтобы соответствовать падежу
|
28
|
-
when 90..1440 then "около " + (distance_in_minutes.to_f / 60.0).round.to_s +
|
29
|
-
" " + (distance_in_minutes.to_f / 60.0).round.items("часа", 'часов', 'часов')
|
30
|
-
when 1441..2880 then '1 день'
|
31
|
-
else (distance_in_minutes / 1440).round.to_s +
|
32
|
-
" " + (distance_in_minutes / 1440).round.items("день", "дня", "дней")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.ru_strftime(time, format_str='%d.%m.%Y')
|
37
|
-
clean_fmt = format_str.to_s.gsub(/%{2}/, RuTils::SUBSTITUTION_MARKER).
|
38
|
-
gsub(/%a/, Date::RU_ABBR_DAYNAMES[time.wday]).
|
39
|
-
gsub(/%A/, Date::RU_DAYNAMES[time.wday]).
|
40
|
-
gsub(/%b/, Date::RU_ABBR_MONTHNAMES[time.mon]).
|
41
|
-
gsub(/%d(\s)*%B/, '%02d' % time.day + '\1' + Date::RU_INFLECTED_MONTHNAMES[time.mon]).
|
42
|
-
gsub(/%e(\s)*%B/, '%d' % time.day + '\1' + Date::RU_INFLECTED_MONTHNAMES[time.mon]).
|
43
|
-
gsub(/%B/, Date::RU_MONTHNAMES[time.mon]).
|
44
|
-
gsub(/#{RuTils::SUBSTITUTION_MARKER}/, '%%')
|
45
|
-
|
46
|
-
# Теперь когда все нужные нам маркеры заменены можно отдать это стандартному strftime
|
47
|
-
time.respond_to?(:strftime_norutils) ? time.strftime_norutils(clean_fmt) : time.to_time.strftime_norutils(clean_fmt)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Date
|
53
|
-
RU_MONTHNAMES = [nil] + %w{ январь февраль март апрель май июнь июль август сентябрь октябрь ноябрь декабрь }
|
54
|
-
RU_DAYNAMES = %w(воскресенье понедельник вторник среда четверг пятница суббота)
|
55
|
-
RU_ABBR_MONTHNAMES = [nil] + %w{ янв фев мар апр май июн июл авг сен окт ноя дек }
|
56
|
-
RU_ABBR_DAYNAMES = %w(вск пн вт ср чт пт сб)
|
57
|
-
RU_INFLECTED_MONTHNAMES = [nil] + %w{ января февраля марта апреля мая июня июля августа сентября октября ноября декабря }
|
58
|
-
RU_DAYNAMES_E = [nil] + %w{первое второе третье четвёртое пятое шестое седьмое восьмое девятое десятое одиннадцатое двенадцатое тринадцатое четырнадцатое пятнадцатое шестнадцатое семнадцатое восемнадцатое девятнадцатое двадцатое двадцать тридцатое тридцатьпервое}
|
59
|
-
end
|
60
|
-
|
61
|
-
class Time
|
62
|
-
alias_method :strftime_norutils, :strftime
|
63
|
-
|
64
|
-
def strftime(fmt)
|
65
|
-
RuTils::overrides_enabled? ? RuTils::DateTime::ru_strftime(self, fmt) : strftime_norutils(fmt)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class Date
|
70
|
-
# Inside rails we have date formatting
|
71
|
-
if self.instance_methods.include?('strftime')
|
72
|
-
alias_method :strftime_norutils, :strftime
|
73
|
-
def strftime(fmt='%F')
|
74
|
-
RuTils::overrides_enabled? ? RuTils::DateTime::ru_strftime(self, fmt) : strftime_norutils(fmt)
|
75
|
-
end
|
76
|
-
|
77
|
-
else
|
78
|
-
def strftime(fmt='%F')
|
79
|
-
RuTils::overrides_enabled? ? RuTils::DateTime::ru_strftime(self, fmt) : to_time.strftime(fmt)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
@@ -1,288 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
module RuTils
|
3
|
-
module Pluralization #:nodoc:
|
4
|
-
# Выбирает нужный падеж существительного в зависимости от числа
|
5
|
-
def self.choose_plural(amount, *variants)
|
6
|
-
variant = (amount%10==1 && amount%100!=11 ? 1 : amount%10>=2 && amount%10<=4 && (amount%100<10 || amount%100>=20) ? 2 : 3)
|
7
|
-
variants[variant-1]
|
8
|
-
end
|
9
|
-
|
10
|
-
# Выводит целое или дробное число как сумму в рублях прописью
|
11
|
-
def self.rublej(amount)
|
12
|
-
pts = []
|
13
|
-
|
14
|
-
pts << RuTils::Pluralization::sum_string(amount.to_i, 1, "рубль", "рубля", "рублей") unless amount.to_i == 0
|
15
|
-
if amount.kind_of?(Float)
|
16
|
-
remainder = (amount.divmod(1)[1]*100).round
|
17
|
-
if (remainder == 100)
|
18
|
-
pts = [RuTils::Pluralization::sum_string(amount.to_i+1, 1, 'рубль', 'рубля', 'рублей')]
|
19
|
-
else
|
20
|
-
pts << RuTils::Pluralization::sum_string(remainder.to_i, 2, 'копейка', 'копейки', 'копеек')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
pts.join(' ')
|
25
|
-
end
|
26
|
-
|
27
|
-
# Выводит целое или дробное число как сумму в гривнах прописью
|
28
|
-
def self.griven(amount)
|
29
|
-
pts = []
|
30
|
-
|
31
|
-
pts << RuTils::Pluralization::sum_string(amount.to_i, 2, "гривна", "гривны", "гривен") unless amount.to_i == 0
|
32
|
-
if amount.kind_of?(Float)
|
33
|
-
remainder = (amount.divmod(1)[1]*100).round
|
34
|
-
if (remainder == 100)
|
35
|
-
pts = [RuTils::Pluralization::sum_string(amount.to_i+1, 2, 'гривна', 'гривны', 'гривен')]
|
36
|
-
else
|
37
|
-
pts << RuTils::Pluralization::sum_string(remainder.to_i, 2, 'копейка', 'копейки', 'копеек')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
pts.join(' ')
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.kopeek(amount)
|
45
|
-
pts = []
|
46
|
-
r, k = (amount/100.0).floor, (amount - ((amount/100.0).floor * 100)).to_i
|
47
|
-
pts << RuTils::Pluralization::sum_string(r, 1, "рубль", "рубля", "рублей") unless r.zero?
|
48
|
-
pts << RuTils::Pluralization::sum_string(k, 2, 'копейка', 'копейки', 'копеек') unless k.zero?
|
49
|
-
pts.join(' ')
|
50
|
-
end
|
51
|
-
|
52
|
-
# Выполняет преобразование числа из цифрого вида в символьное
|
53
|
-
# amount - числительное
|
54
|
-
# gender = 1 - мужской, = 2 - женский, = 3 - средний
|
55
|
-
# one_item - именительный падеж единственного числа (= 1)
|
56
|
-
# two_items - родительный падеж единственного числа (= 2-4)
|
57
|
-
# five_items - родительный падеж множественного числа ( = 5-10)
|
58
|
-
def self.sum_string(amount, gender, one_item='', two_items='', five_items='')
|
59
|
-
into = ''
|
60
|
-
tmp_val ||= 0
|
61
|
-
|
62
|
-
return "ноль " + five_items if amount == 0
|
63
|
-
|
64
|
-
tmp_val = amount
|
65
|
-
|
66
|
-
# единицы
|
67
|
-
into, tmp_val = sum_string_fn(into, tmp_val, gender, one_item, two_items, five_items)
|
68
|
-
|
69
|
-
return into if tmp_val == 0
|
70
|
-
|
71
|
-
# тысячи
|
72
|
-
into, tmp_val = sum_string_fn(into, tmp_val, 2, "тысяча", "тысячи", "тысяч")
|
73
|
-
|
74
|
-
return into if tmp_val == 0
|
75
|
-
|
76
|
-
# миллионы
|
77
|
-
into, tmp_val = sum_string_fn(into, tmp_val, 1, "миллион", "миллиона", "миллионов")
|
78
|
-
|
79
|
-
return into if tmp_val == 0
|
80
|
-
|
81
|
-
# миллиардов
|
82
|
-
into, tmp_val = sum_string_fn(into, tmp_val, 1, "миллиард", "миллиарда", "миллиардов")
|
83
|
-
return into
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
def self.sum_string_fn(into, tmp_val, gender, one_item='', two_items='', five_items='')
|
88
|
-
rest, rest1, end_word, ones, tens, hundreds = [nil]*6
|
89
|
-
#
|
90
|
-
rest = tmp_val % 1000
|
91
|
-
tmp_val = tmp_val / 1000
|
92
|
-
if rest == 0
|
93
|
-
# последние три знака нулевые
|
94
|
-
into = five_items + " " if into == ""
|
95
|
-
return [into, tmp_val]
|
96
|
-
end
|
97
|
-
#
|
98
|
-
# начинаем подсчет с Rest
|
99
|
-
end_word = five_items
|
100
|
-
# сотни
|
101
|
-
hundreds = case rest / 100
|
102
|
-
when 0 then ""
|
103
|
-
when 1 then "сто "
|
104
|
-
when 2 then "двести "
|
105
|
-
when 3 then "триста "
|
106
|
-
when 4 then "четыреста "
|
107
|
-
when 5 then "пятьсот "
|
108
|
-
when 6 then "шестьсот "
|
109
|
-
when 7 then "семьсот "
|
110
|
-
when 8 then "восемьсот "
|
111
|
-
when 9 then "девятьсот "
|
112
|
-
end
|
113
|
-
|
114
|
-
# десятки
|
115
|
-
rest = rest % 100
|
116
|
-
rest1 = rest / 10
|
117
|
-
ones = ""
|
118
|
-
tens = case rest1
|
119
|
-
when 0 then ""
|
120
|
-
when 1 # особый случай
|
121
|
-
case rest
|
122
|
-
when 10 then "десять "
|
123
|
-
when 11 then "одиннадцать "
|
124
|
-
when 12 then "двенадцать "
|
125
|
-
when 13 then "тринадцать "
|
126
|
-
when 14 then "четырнадцать "
|
127
|
-
when 15 then "пятнадцать "
|
128
|
-
when 16 then "шестнадцать "
|
129
|
-
when 17 then "семнадцать "
|
130
|
-
when 18 then "восемнадцать "
|
131
|
-
when 19 then "девятнадцать "
|
132
|
-
end
|
133
|
-
when 2 then "двадцать "
|
134
|
-
when 3 then "тридцать "
|
135
|
-
when 4 then "сорок "
|
136
|
-
when 5 then "пятьдесят "
|
137
|
-
when 6 then "шестьдесят "
|
138
|
-
when 7 then "семьдесят "
|
139
|
-
when 8 then "восемьдесят "
|
140
|
-
when 9 then "девяносто "
|
141
|
-
end
|
142
|
-
#
|
143
|
-
if rest1 < 1 or rest1 > 1 # единицы
|
144
|
-
case rest % 10
|
145
|
-
when 1
|
146
|
-
ones = case gender
|
147
|
-
when 1 then "один "
|
148
|
-
when 2 then "одна "
|
149
|
-
when 3 then "одно "
|
150
|
-
end
|
151
|
-
end_word = one_item
|
152
|
-
when 2
|
153
|
-
if gender == 2
|
154
|
-
ones = "две "
|
155
|
-
else
|
156
|
-
ones = "два "
|
157
|
-
end
|
158
|
-
end_word = two_items
|
159
|
-
when 3
|
160
|
-
ones = "три " if end_word = two_items # TODO - WTF?
|
161
|
-
when 4
|
162
|
-
ones = "четыре " if end_word = two_items # TODO - WTF?
|
163
|
-
when 5
|
164
|
-
ones = "пять "
|
165
|
-
when 6
|
166
|
-
ones = "шесть "
|
167
|
-
when 7
|
168
|
-
ones = "семь "
|
169
|
-
when 8
|
170
|
-
ones = "восемь "
|
171
|
-
when 9
|
172
|
-
ones = "девять "
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# сборка строки
|
177
|
-
plural = [hundreds, tens, ones, end_word, " ", into].join.strip
|
178
|
-
return [plural, tmp_val]
|
179
|
-
end
|
180
|
-
|
181
|
-
# Реализует вывод прописью любого объекта, реализующего Float
|
182
|
-
module FloatFormatting
|
183
|
-
|
184
|
-
# Выдает сумму прописью с учетом дробной доли. Дробная доля округляется до миллионной, или (если
|
185
|
-
# дробная доля оканчивается на нули) до ближайшей доли ( 500 тысячных округляется до 5 десятых).
|
186
|
-
# Дополнительный аргумент - род существительного (1 - мужской, 2- женский, 3-средний)
|
187
|
-
def propisju(gender = 2)
|
188
|
-
raise "Это не число!" if self.nan?
|
189
|
-
|
190
|
-
st = RuTils::Pluralization::sum_string(self.to_i, gender, "целая", "целых", "целых")
|
191
|
-
|
192
|
-
remainder = self.to_s.match(/\.(\d+)/)[1]
|
193
|
-
|
194
|
-
signs = remainder.to_s.size- 1
|
195
|
-
|
196
|
-
it = [["десятая", "десятых"]]
|
197
|
-
it << ["сотая", "сотых"]
|
198
|
-
it << ["тысячная", "тысячных"]
|
199
|
-
it << ["десятитысячная", "десятитысячных"]
|
200
|
-
it << ["стотысячная", "стотысячных"]
|
201
|
-
it << ["миллионная", "милллионных"]
|
202
|
-
it << ["десятимиллионная", "десятимилллионных", "десятимиллионных"]
|
203
|
-
it << ["стомиллионная", "стомилллионных", "стомиллионных"]
|
204
|
-
it << ["миллиардная", "миллиардных", "миллиардных"]
|
205
|
-
it << ["десятимиллиардная", "десятимиллиардных", "десятимиллиардных"]
|
206
|
-
it << ["стомиллиардная", "стомиллиардных", "стомиллиардных"]
|
207
|
-
it << ["триллионная", "триллионных", "триллионных"]
|
208
|
-
|
209
|
-
while it[signs].nil?
|
210
|
-
remainder = (remainder/10).round
|
211
|
-
signs = remainder.to_s.size- 1
|
212
|
-
end
|
213
|
-
|
214
|
-
suf1, suf2, suf3 = it[signs][0], it[signs][1], it[signs][2]
|
215
|
-
st + " " + RuTils::Pluralization::sum_string(remainder.to_i, 2, suf1, suf2, suf2)
|
216
|
-
end
|
217
|
-
|
218
|
-
def propisju_items(gender=1, *forms)
|
219
|
-
if self == self.to_i
|
220
|
-
return self.to_i.propisju_items(gender, *forms)
|
221
|
-
else
|
222
|
-
self.propisju(gender) + " " + forms[1]
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
# Реализует вывод прописью любого объекта, реализующего Numeric
|
229
|
-
module NumericFormatting
|
230
|
-
# Выбирает корректный вариант числительного в зависимости от рода и числа и оформляет сумму прописью
|
231
|
-
# 234.propisju => "двести сорок три"
|
232
|
-
# 221.propisju(2) => "двести двадцать одна"
|
233
|
-
def propisju(gender = 1)
|
234
|
-
RuTils::Pluralization::sum_string(self, gender, "")
|
235
|
-
end
|
236
|
-
|
237
|
-
def propisju_items(gender=1, *forms)
|
238
|
-
self.propisju(gender) + " " + RuTils::Pluralization::choose_plural(self.to_i, *forms)
|
239
|
-
end
|
240
|
-
|
241
|
-
# Выбирает корректный вариант числительного в зависимости от рода и числа. Например:
|
242
|
-
# * 4.items("колесо", "колеса", "колес") => "колеса"
|
243
|
-
def items(one_item, two_items, five_items)
|
244
|
-
RuTils::Pluralization::choose_plural(self, one_item, two_items, five_items)
|
245
|
-
end
|
246
|
-
|
247
|
-
# Выводит сумму в рублях прописью. Например:
|
248
|
-
# * (15.4).rublej => "пятнадцать рублей сорок копеек"
|
249
|
-
# * 1.rubl => "один рубль"
|
250
|
-
# * (3.14).rublja => "три рубля четырнадцать копеек"
|
251
|
-
def rublej
|
252
|
-
RuTils::Pluralization::rublej(self)
|
253
|
-
end
|
254
|
-
alias :rubl :rublej
|
255
|
-
alias :rublja :rublej
|
256
|
-
|
257
|
-
# Выводит сумму в гривнах прописью. Например:
|
258
|
-
# * (15.4).griven => "пятнадцать гривен сорок копеек"
|
259
|
-
# * 1.grivna => "одна гривна"
|
260
|
-
# * (3.14).grivny => "три гривны четырнадцать копеек"
|
261
|
-
def griven
|
262
|
-
RuTils::Pluralization::griven(self)
|
263
|
-
end
|
264
|
-
alias :grivna :griven
|
265
|
-
alias :grivny :griven
|
266
|
-
end
|
267
|
-
|
268
|
-
module FixnumFormatting
|
269
|
-
def kopeek
|
270
|
-
RuTils::Pluralization.kopeek(self)
|
271
|
-
end
|
272
|
-
alias :kopeika :kopeek
|
273
|
-
alias :kopeiki :kopeek
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
class Object::Numeric
|
279
|
-
include RuTils::Pluralization::NumericFormatting
|
280
|
-
end
|
281
|
-
|
282
|
-
class Object::Fixnum
|
283
|
-
include RuTils::Pluralization::FixnumFormatting
|
284
|
-
end
|
285
|
-
|
286
|
-
class Object::Float
|
287
|
-
include RuTils::Pluralization::FloatFormatting
|
288
|
-
end
|
data/lib/transliteration/bidi.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
# ++DEPRECATED++ Этот модуль удален и присутствует только для выдачи сообщения об ошибке.
|
3
|
-
module RuTils::Transliteration::BiDi
|
4
|
-
ERR = "Equivalent bidirectional transliteration for URLs is malpractice. BiDi translit has been removed from RuTils"
|
5
|
-
|
6
|
-
extend self
|
7
|
-
|
8
|
-
# ++DEPRECATED++
|
9
|
-
def translify(str, allow_slashes = true)
|
10
|
-
bail!
|
11
|
-
end
|
12
|
-
|
13
|
-
# ++DEPRECATED++
|
14
|
-
def detranslify(str, allow_slashes = true)
|
15
|
-
bail!
|
16
|
-
end
|
17
|
-
|
18
|
-
def bail! #:nodoc:
|
19
|
-
raise RuTils::RemovedFeature, ERR
|
20
|
-
end
|
21
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
# Реализует простейшую транслитерацию
|
3
|
-
# "вот мы и здесь".translify => "vot my i zdes"
|
4
|
-
# "vot my i zdes".detranslify => "вот мы и здесь"
|
5
|
-
module RuTils::Transliteration::Simple
|
6
|
-
TABLE_LOWER = {
|
7
|
-
"і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e",
|
8
|
-
"ї"=>"yi","а"=>"a","б"=>"b",
|
9
|
-
"в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
|
10
|
-
"з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
|
11
|
-
"м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
|
12
|
-
"с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
|
13
|
-
"ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'",
|
14
|
-
"ы"=>"yi","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya"
|
15
|
-
}.sort do | one, two|
|
16
|
-
two[1].size <=> one[1].size
|
17
|
-
end
|
18
|
-
|
19
|
-
TABLE_UPPER = {
|
20
|
-
"Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I",
|
21
|
-
"А"=>"A","Б"=>"B","В"=>"V","Г"=>"G",
|
22
|
-
"Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I",
|
23
|
-
"Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
|
24
|
-
"О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T",
|
25
|
-
"У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH",
|
26
|
-
"Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"YI","Ь"=>"",
|
27
|
-
"Э"=>"E","Ю"=>"YU","Я"=>"YA",
|
28
|
-
}.sort do | one, two|
|
29
|
-
two[1].size <=> one[1].size
|
30
|
-
end
|
31
|
-
|
32
|
-
TABLE = TABLE_UPPER + TABLE_LOWER
|
33
|
-
|
34
|
-
# Заменяет кириллицу в строке на латиницу. Немного специфично потому что поддерживает
|
35
|
-
# комби-регистр (Щука -> Shuka)
|
36
|
-
def self.translify(str)
|
37
|
-
chars = str.split(//)
|
38
|
-
|
39
|
-
lowers = TABLE_LOWER.map{|e| e[0] }
|
40
|
-
uppers = TABLE_UPPER.map{|e| e[0] }
|
41
|
-
|
42
|
-
hashtable = {}
|
43
|
-
TABLE.each do | item |
|
44
|
-
next unless item[0] && item[1]
|
45
|
-
hashtable[item[0]] = item[1]
|
46
|
-
end
|
47
|
-
|
48
|
-
result = ''
|
49
|
-
chars.each_with_index do | char, index |
|
50
|
-
if uppers.include?(char) && lowers.include?(chars[index+1])
|
51
|
-
# Combined case. Here we deal with Latin letters so there is no problem to use
|
52
|
-
# Ruby's builtin upcase_downcase
|
53
|
-
ch = hashtable[char].downcase.capitalize
|
54
|
-
result << ch
|
55
|
-
elsif uppers.include?(char)
|
56
|
-
result << hashtable[char]
|
57
|
-
elsif lowers.include?(char)
|
58
|
-
result << hashtable[char]
|
59
|
-
else
|
60
|
-
result << char
|
61
|
-
end
|
62
|
-
end
|
63
|
-
return result
|
64
|
-
end
|
65
|
-
|
66
|
-
# Транслитерирует строку, делая ее пригодной для применения как имя директории или URL
|
67
|
-
def self.dirify(string)
|
68
|
-
st = self.translify(string)
|
69
|
-
st.gsub!(/(\s\&\s)|(\s\&\;\s)/, ' and ') # convert & to "and"
|
70
|
-
st.gsub!(/\W/, ' ') #replace non-chars
|
71
|
-
st.gsub!(/(_)$/, '') #trailing underscores
|
72
|
-
st.gsub!(/^(_)/, '') #leading unders
|
73
|
-
st.strip.translify.gsub(/(\s)/,'-').downcase.squeeze('-')
|
74
|
-
end
|
75
|
-
end
|