rutils 1.1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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\&amp\;\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