ru_propisju 1.2.0 → 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/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source :rubygems
2
+ group :development do
3
+ gem "jeweler"
4
+ gem "rake"
5
+ end
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 2.0.0 / 2011-11-15
2
+
3
+ * Добавлена поддержка украинского языка - iz65535
4
+
1
5
  === 1.2.0 / 2011-11-15
2
6
 
3
7
  * Добавлена поддержка И Еще Нескольких Валют (тм) - terraplane
data/Rakefile CHANGED
@@ -1,13 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  # -*- ruby -*-
3
+ $KCODE = 'u' if RUBY_VERSION < '1.9.0'
2
4
 
3
5
  require 'rubygems'
4
- require 'hoe'
6
+ require 'jeweler'
7
+ require './lib/ru_propisju'
5
8
 
6
- Hoe.spec 'ru_propisju' do | p |
7
- p.readme_file = 'README.rdoc'
8
- p.extra_rdoc_files = FileList['*.rdoc'] + FileList['*.txt']
9
- p.developer('Julik Tarkhanov', 'me@julik.nl')
10
- p.clean_globs += %w( *.gemspec )
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.version = RuPropisju::VERSION
11
+ gem.name = "ru_propisju"
12
+ gem.summary = "Cумма прописью"
13
+ gem.email = "me@julik.nl"
14
+ gem.homepage = "http://github.com/julik/ru_propisju"
15
+ gem.authors = ["Julik Tarkhanov"]
16
+ gem.license = 'MIT'
17
+
18
+ # Do not package invisibles
19
+ gem.files.exclude ".*"
11
20
  end
21
+ Jeweler::RubygemsDotOrgTasks.new
22
+
23
+ require 'rake/testtask'
24
+ desc "Run all tests"
25
+ Rake::TestTask.new("test") do |t|
26
+ t.libs << "test"
27
+ t.pattern = 'test/**/test_*.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ task :default => [ :test ]
12
32
 
13
33
  # vim: syntax=ruby
data/lib/ru_propisju.rb CHANGED
@@ -6,16 +6,141 @@ $KCODE = 'u' if RUBY_VERSION < '1.9.0'
6
6
  # RuPropisju.rublej(123) # "сто двадцать три рубля"
7
7
  module RuPropisju
8
8
 
9
- VERSION = '1.2.0'
9
+ VERSION = '2.0.0'
10
10
 
11
+ # http://www.xe.com/symbols.php
12
+ # (лица, приближенные форексам и всяким там валютам и курсам)
13
+ # говорят, что код валюты российского рубля - rub
14
+ CURRENCIES = {
15
+ "rur" => :rublej,
16
+ "rub" => :rublej,
17
+ "usd" => :dollarov,
18
+ "uah" => :griven,
19
+ "eur" => :evro,
20
+ }
21
+ SUPPORTED_CURRENCIES = CURRENCIES.keys.join ','
22
+
23
+ TRANSLATIONS = {
24
+ "ru" => {
25
+ 0 => "",
26
+ '0' => "ноль",
27
+ :thousands => ["тысяча", "тысячи", "тысяч"],
28
+ :millions => ["миллион", "миллиона", "миллионов"],
29
+ :billions => ["миллиард", "миллиарда", "миллиардов"],
30
+ 100 => "сто",
31
+ 200 => "двести",
32
+ 300 => "триста",
33
+ 400 => "четыреста",
34
+ 500 => "пятьсот",
35
+ 600 => "шестьсот",
36
+ 700 => "семьсот",
37
+ 800 => "восемьсот",
38
+ 900 => "девятьсот",
39
+
40
+ 10 => "десять",
41
+ 11 => "одиннадцать",
42
+ 12 => "двенадцать",
43
+ 13 => "тринадцать",
44
+ 14 => "четырнадцать",
45
+ 15 => "пятнадцать",
46
+ 16 => "шестнадцать",
47
+ 17 => "семнадцать",
48
+ 18 => "восемнадцать",
49
+ 19 => "девятнадцать",
50
+ 20 => "двадцать",
51
+ 30 => "тридцать",
52
+ 40 => "сорок",
53
+ 50 => "пятьдесят",
54
+ 60 => "шестьдесят",
55
+ 70 => "семьдесят",
56
+ 80 => "восемьдесят",
57
+ 90 => "девяносто",
58
+ # единицы, местами - c учетом рода
59
+ 1 => {1 => "один", 2 => 'одна', 3 => 'одно'},
60
+ 2 => {1 => "два", 2 => 'две', 3 => 'два'},
61
+ 3 => "три",
62
+ 4 => "четыре",
63
+ 5 => "пять",
64
+ 6 => "шесть",
65
+ 7 => "семь",
66
+ 8 => "восемь",
67
+ 9 => "девять",
68
+ :rub_integral => ["рубль", "рубля", "рублей"],
69
+ :rub_fraction => ['копейка', 'копейки', 'копеек'],
70
+ :uah_integral => ["гривна", "гривны", "гривен"],
71
+ :uah_fraction => ['копейка', 'копейки', 'копеек'],
72
+ :eur_integral => ["евро", "евро", "евро"],
73
+ # по опыту моей прошлой работы в банке
74
+ # центами называют дробную часть доллара
75
+ # а дробную часть евро называют евроцентом
76
+ :eur_fraction => ["цент", "цента", "центов"],
77
+ :usd_integral => ["доллар", "доллара", "долларов"],
78
+ :usd_fraction => ['цент', 'цента', 'центов'],
79
+ },
80
+ "ua" => {
81
+ 0 => "",
82
+ '0' => "нуль",
83
+ :thousands => ["тисяча", "тисячі", "тисяч"],
84
+ :millions => ["мільйон", "мільйона", "мільйонів"],
85
+ :billions => ["мільярд", "мільярда", "мільярдів"],
86
+ 100 => "сто",
87
+ 200 => "двісті",
88
+ 300 => "триста",
89
+ 400 => "чотиреста",
90
+ 500 => "п'ятьсот",
91
+ 600 => "шістсот",
92
+ 700 => "сімсот",
93
+ 800 => "вісімсот",
94
+ 900 => "дев'ятсот",
95
+
96
+ 10 => "десять",
97
+ 11 => "одинадцять",
98
+ 12 => "дванадцять",
99
+ 13 => "тринадцять",
100
+ 14 => "чотирнадцять",
101
+ 15 => "п'ятнадцять",
102
+ 16 => "шістнадцять",
103
+ 17 => "сімнадцять",
104
+ 18 => "вісімнадцять",
105
+ 19 => "дев'ятнадцять",
106
+ 20 => "двадцять",
107
+ 30 => "тридцять",
108
+ 40 => "сорок",
109
+ 50 => "п'ятьдесят",
110
+ 60 => "шістдесят",
111
+ 70 => "сімдесят",
112
+ 80 => "вісімдесят",
113
+ 90 => "дев'яносто",
114
+ # единицы, местами - c учетом рода
115
+ 1 => {1 => "один", 2 => 'одна', 3 => 'одне'},
116
+ 2 => {1 => "два", 2 => 'дві', 3 => 'два'},
117
+ 3 => "три",
118
+ 4 => "чотири",
119
+ 5 => "п'ять",
120
+ 6 => "шість",
121
+ 7 => "сім",
122
+ 8 => "вісім",
123
+ 9 => "дев'ять",
124
+ :rub_integral => ["рубль", "рубля", "рублів"],
125
+ :rub_fraction => ['копійка', 'копійки', 'копійок'],
126
+ :uah_integral => ["гривня", "гривні", "гривень"],
127
+ :uah_fraction => ["копійка", "копійки", "копійок"],
128
+ :eur_integral => ["євро", "євро", "євро"],
129
+ :eur_fraction => ["євроцент", "євроцента", "євроцентів"],
130
+ :usd_integral => ["долар", "долара", "доларів"],
131
+ :usd_fraction => ['цент', 'цента', 'центів'],
132
+ }
133
+ }
134
+
135
+
11
136
  # Кидается при запросе неизвестной валюты
12
137
  class UnknownCurrency < ArgumentError
13
138
  end
14
-
139
+
15
140
  # Выбирает нужный падеж существительного в зависимости от числа
16
141
  #
17
142
  # choose_plural(3, "штука", "штуки", "штук") #=> "штуки"
18
- def choose_plural(amount, *variants)
143
+ def choose_plural(amount, variants)
19
144
  mod_ten = amount % 10
20
145
  mod_hundred = amount % 100
21
146
  variant = if (mod_ten == 1 && mod_hundred != 11)
@@ -29,34 +154,39 @@ module RuPropisju
29
154
  end
30
155
  variants[variant-1]
31
156
  end
32
-
157
+
33
158
  # Выводит сумму прописью в зависимости от выбранной валюты.
34
159
  # Поддерживаемые валюты: rur, usd, uah, eur
35
160
  #
36
161
  # amount_in_words(345.2, 'rur') #=> "триста сорок пять рублей 20 копеек"
37
- def amount_in_words(amount, currency)
38
- unless CURRENCIES.has_key?(currency.to_s.downcase)
39
- raise UnknownCurrency, "Unsupported currency #{currency}, the following are supported: #{CURRENCIES.keys.join(", ")}"
162
+ def amount_in_words(amount, currency, locale = :ru)
163
+ currency = currency.to_s.downcase
164
+ unless CURRENCIES.has_key? currency
165
+ raise UnknownCurrency, "Unsupported currency #{currency}, the following are supported: #{SUPPORTED_CURRENCIES}"
40
166
  end
41
- method(CURRENCIES[currency.to_s.downcase]).call(amount)
167
+ method(CURRENCIES[currency]).call(amount, locale)
42
168
  end
43
-
169
+
44
170
  # Выводит целое или дробное число как сумму в рублях прописью
45
171
  #
46
172
  # rublej(345.2) #=> "триста сорок пять рублей 20 копеек"
47
- def rublej(amount)
173
+ def rublej(amount, locale = :ru)
48
174
  pts = []
175
+ locale_root = TRANSLATIONS[locale.to_s]
49
176
 
50
- pts << propisju_shtuk(amount.to_i, 1, "рубль", "рубля", "рублей") unless amount.to_i == 0
177
+ integrals = locale_root[:rub_integral]
178
+ fractions = locale_root[:rub_fraction]
179
+
180
+ pts << propisju_shtuk(amount.to_i, 1, integrals, locale) unless amount.to_i == 0
51
181
 
52
182
  if amount.kind_of?(Float)
53
183
  remainder = (amount.divmod(1)[1]*100).round
54
- if (remainder == 100)
55
- pts = [propisju_shtuk(amount.to_i+1, 1, 'рубль', 'рубля', 'рублей')]
184
+ if remainder == 100
185
+ pts = [propisju_shtuk(amount.to_i+1, 1, integrals, locale)]
56
186
  else
57
187
  kop = remainder.to_i
58
188
  unless kop.zero?
59
- pts << kop << choose_plural(kop, 'копейка', 'копейки', 'копеек')
189
+ pts << kop << choose_plural(kop, fractions)
60
190
  end
61
191
  end
62
192
  end
@@ -68,46 +198,53 @@ module RuPropisju
68
198
  #
69
199
  # propisju(243) => "двести сорок три"
70
200
  # propisju(221, 2) => "двести двадцать одна"
71
- def propisju(amount, gender = 1)
201
+ def propisju(amount, gender, locale = :ru)
72
202
  if amount.is_a?(Integer) || amount.is_a?(Bignum)
73
- propisju_int(amount, gender)
203
+ propisju_int(amount, gender, [], locale)
74
204
  else # также сработает для Decimal, дробные десятичные числительные в долях поэтому женского рода
75
- propisju_float(amount)
205
+ propisju_float(amount, locale)
76
206
  end
77
207
  end
78
208
 
79
209
  # Выводит целое или дробное число как сумму в гривнах прописью
80
210
  #
81
211
  # griven(32) #=> "тридцать две гривны"
82
- def griven(amount)
83
- pts = []
212
+ def griven(amount, locale = 'ru')
213
+ locale_root = TRANSLATIONS[locale.to_s]
84
214
 
85
- pts << propisju_int(amount.to_i, 2, "гривна", "гривны", "гривен") unless amount.to_i == 0
86
- if amount.kind_of?(Float)
215
+ integrals = locale_root[:uah_integral]
216
+ fractions = locale_root[:uah_fraction]
217
+
218
+ pts = []
219
+ pts << propisju_int(amount.to_i, 2, integrals, locale) unless amount.to_i == 0
220
+ if amount.kind_of? Float
87
221
  remainder = (amount.divmod(1)[1]*100).round
88
- if (remainder == 100)
89
- pts = [propisju_int(amount.to_i + 1, 2, 'гривна', 'гривны', 'гривен')]
222
+ if remainder == 100
223
+ pts = [propisju_int(amount.to_i + 1, 2, integrals, locale)]
90
224
  else
91
- pts << propisju_int(remainder.to_i, 2, 'копейка', 'копейки', 'копеек')
225
+ pts << propisju_int(remainder.to_i, 2, fractions, locale)
92
226
  end
93
227
  end
94
-
95
228
  pts.join(' ')
96
229
  end
97
230
 
98
231
  # Выводит целое или дробное число как сумму в долларах прописью
99
232
  #
100
233
  # dollarov(32) #=> "тридцать два доллара"
101
- def dollarov(amount)
234
+ def dollarov(amount, locale = 'ru')
102
235
  pts = []
236
+ locale_root = TRANSLATIONS[locale.to_s]
237
+
238
+ integrals = locale_root[:usd_integral]
239
+ fractions = locale_root[:usd_fraction]
103
240
 
104
- pts << propisju_int(amount.to_i, 1, "доллар", "доллара", "долларов") unless amount.to_i == 0
241
+ pts << propisju_int(amount.to_i, 1, integrals, locale) unless amount.to_i == 0
105
242
  if amount.kind_of?(Float)
106
243
  remainder = (amount.divmod(1)[1]*100).round
107
244
  if (remainder == 100)
108
- pts = [propisju_int(amount.to_i + 1, 1, 'доллар', 'доллара', 'долларов')]
245
+ pts = [propisju_int(amount.to_i + 1, 1, integrals, locale)]
109
246
  else
110
- pts << propisju_int(remainder.to_i, 1, 'цент', 'цента', 'центов')
247
+ pts << propisju_int(remainder.to_i, 1, fractions, locale)
111
248
  end
112
249
  end
113
250
 
@@ -117,16 +254,20 @@ module RuPropisju
117
254
  # Выводит целое или дробное число как сумму в евро прописью
118
255
  #
119
256
  # evro(32) #=> "тридцать два евро"
120
- def evro(amount)
257
+ def evro(amount, locale = 'ru')
121
258
  pts = []
259
+ locale = locale.to_sym
122
260
 
123
- pts << propisju_int(amount.to_i, 1, "евро", "евро", "евро") unless amount.to_i == 0
261
+ integrals = TRANSLATIONS[locale.to_s][:eur_integral]
262
+ fractions = TRANSLATIONS[locale.to_s][:eur_fraction]
263
+
264
+ pts << propisju_int(amount.to_i, 1, integrals, locale) unless amount.to_i == 0
124
265
  if amount.kind_of?(Float)
125
266
  remainder = (amount.divmod(1)[1]*100).round
126
267
  if (remainder == 100)
127
- pts = [propisju_int(amount.to_i + 1, 1, 'евро', 'евро', 'евро')]
268
+ pts = [propisju_int(amount.to_i + 1, 1, integrals, locale)]
128
269
  else
129
- pts << propisju_int(remainder.to_i, 1, 'цент', 'цента', 'центов')
270
+ pts << propisju_int(remainder.to_i, 1, fractions, locale)
130
271
  end
131
272
  end
132
273
 
@@ -136,19 +277,19 @@ module RuPropisju
136
277
  # Выводит сумму прописью в рублях по количеству копеек
137
278
  #
138
279
  # kopeek(343) #=> "три рубля 43 копейки"
139
- def kopeek(amount)
140
- rublej(amount / 100.0)
280
+ def kopeek(amount, locale = :ru)
281
+ rublej(amount / 100.0, locale)
141
282
  end
142
283
 
143
284
  # Выводит сумму данного существительного прописью и выбирает правильное число и падеж
144
285
  #
145
286
  # RuPropisju.propisju_shtuk(21, 3, "колесо", "колеса", "колес") #=> "двадцать одно колесо"
146
287
  # RuPropisju.propisju_shtuk(21, 1, "мужик", "мужика", "мужиков") #=> "двадцать один мужик"
147
- def propisju_shtuk(items, gender = 1, *forms)
288
+ def propisju_shtuk(items, gender, forms, locale = :ru)
148
289
  r = if items == items.to_i
149
- [propisju(items, gender), choose_plural(items, *forms)]
290
+ [propisju(items, gender, locale), choose_plural(items, forms)]
150
291
  else
151
- [propisju(items, gender), forms[1]]
292
+ [propisju(items, gender, locale), forms[1]]
152
293
  end
153
294
 
154
295
  r.join(" ")
@@ -156,128 +297,125 @@ module RuPropisju
156
297
 
157
298
  private
158
299
 
159
- def compose_ordinal(into, remaining_amount, gender, one_item='', two_items='', five_items='')
300
+ # ранее интерфейс был похож на интерфейс внешний (one_item, two_items, five_items),
301
+ # однако списковая форма строк выглядит предпочтительнее, поэтому интерфейс изменен.
302
+ # по хорошему надо менять также внешний интерфейс, но это может сломать совместимость
303
+ def compose_ordinal(into, remaining_amount, gender, item_forms=[], locale = :ru)
304
+ locale = locale.to_sym
305
+
160
306
  rest, rest1, chosen_ordinal, ones, tens, hundreds = [nil]*6
161
307
  #
162
308
  rest = remaining_amount % 1000
163
309
  remaining_amount = remaining_amount / 1000
164
- if rest == 0
310
+ if rest.zero?
165
311
  # последние три знака нулевые
166
- into = five_items + " " if into == ""
312
+ into = item_forms[2] if into.empty?
167
313
  return [into, remaining_amount]
168
314
  end
169
- #
170
- # начинаем подсчет с Rest
171
- chosen_ordinal = five_items
172
315
 
316
+ locale_root = TRANSLATIONS[locale.to_s]
317
+ # начинаем подсчет с Rest
173
318
  # сотни
174
- hundreds = case rest / 100
175
- when 0 then ""
176
- when 1 then "сто "
177
- when 2 then "двести "
178
- when 3 then "триста "
179
- when 4 then "четыреста "
180
- when 5 then "пятьсот "
181
- when 6 then "шестьсот "
182
- when 7 then "семьсот "
183
- when 8 then "восемьсот "
184
- when 9 then "девятьсот "
185
- end
319
+ hundreds = locale_root[(rest / 100).to_i * 100]
186
320
 
187
321
  # десятки
188
322
  rest = rest % 100
189
323
  rest1 = rest / 10
324
+ # единички
190
325
  ones = ""
191
- tens = case rest1
192
- when 0 then ""
193
- when 1 # особый случай
194
- case rest
195
- when 10 then "десять "
196
- when 11 then "одиннадцать "
197
- when 12 then "двенадцать "
198
- when 13 then "тринадцать "
199
- when 14 then "четырнадцать "
200
- when 15 then "пятнадцать "
201
- when 16 then "шестнадцать "
202
- when 17 then "семнадцать "
203
- when 18 then "восемнадцать "
204
- when 19 then "девятнадцать "
205
- end
206
- when 2 then "двадцать "
207
- when 3 then "тридцать "
208
- when 4 then "сорок "
209
- when 5 then "пятьдесят "
210
- when 6 then "шестьдесят "
211
- when 7 then "семьдесят "
212
- when 8 then "восемьдесят "
213
- when 9 then "девяносто "
214
- end
215
- #
216
- if rest1 < 1 or rest1 > 1 # единицы
326
+ tens = locale_root[rest1 == 1 ? rest : rest1 * 10]
327
+ # индекс выбранной формы
328
+ chosen_ordinal = 2
329
+ if rest1 < 1 || rest1 > 1 # единицы
330
+ value = locale_root[rest % 10]
331
+ # если попался хэш, делаем выбор согласно рода
332
+ value = value[gender] if value.kind_of? Hash
333
+ ones = value
217
334
  case rest % 10
218
- when 1
219
- ones = case gender
220
- when 1 then "один "
221
- when 2 then "одна "
222
- when 3 then "одно "
223
- end
224
- chosen_ordinal = one_item
225
- when 2
226
- if gender == 2
227
- ones = "две "
228
- else
229
- ones = "два "
230
- end
231
- chosen_ordinal = two_items
232
- when 3
233
- ones = "три "
234
- chosen_ordinal = two_items
235
- when 4
236
- ones = "четыре "
237
- chosen_ordinal = two_items
238
- when 5
239
- ones = "пять "
240
- when 6
241
- ones = "шесть "
242
- when 7
243
- ones = "семь "
244
- when 8
245
- ones = "восемь "
246
- when 9
247
- ones = "девять "
335
+ when 1 then chosen_ordinal = 0 # индекс формы меняется
336
+ when 2..4 then chosen_ordinal = 1 # индекс формы меняется
248
337
  end
249
338
  end
250
-
251
- plural = [hundreds, tens, ones, chosen_ordinal, " ", into].join.strip
339
+ plural = [
340
+ hundreds,
341
+ tens,
342
+ ones,
343
+ item_forms[chosen_ordinal],
344
+ into
345
+ ].compact.reject(&:empty?).join(' ').strip
252
346
  return [plural, remaining_amount]
253
347
  end
254
-
255
- DECIMALS = %w( целая десятая сотая тысячная десятитысячная стотысячная
256
- миллионная десятимиллионная стомиллионная миллиардная десятимиллиардная
257
- стомиллиардная триллионная
258
- ).map{|e| [e, e.gsub(/ая$/, "ых"), e.gsub(/ая$/, "ых"), ] }.freeze
259
-
260
- CURRENCIES = {
261
- "rur" => :rublej,
262
- "usd" => :dollarov,
263
- "uah" => :griven,
264
- "eur" => :evro,
348
+
349
+ DECIMALS = {
350
+ :ru =>{
351
+ :source_words => [
352
+ 'целая',
353
+ 'десятая',
354
+ 'сотая',
355
+ 'тысячная',
356
+ 'десятитысячная',
357
+ 'стотысячная',
358
+ 'миллионная',
359
+ 'десятимиллионная',
360
+ 'стомиллионная',
361
+ 'миллиардная',
362
+ 'десятимиллиардная',
363
+ 'стомиллиардная',
364
+ 'триллионная'
365
+ ],
366
+ :prefix => ["ая", 'ых'],
367
+ },
368
+ :ua => {
369
+ :source_words => [
370
+ 'ціла',
371
+ 'десята',
372
+ 'сота',
373
+ 'тисячна',
374
+ 'десятитисячна',
375
+ 'стотисячна',
376
+ 'мільйонна',
377
+ 'десятимільйонна',
378
+ 'стомільйонна',
379
+ 'мільярдна',
380
+ 'десятимільярдна',
381
+ 'стомільярдна',
382
+ 'трильонна'
383
+ ],
384
+ :prefix => ["а", 'их'],
385
+ },
265
386
  }
266
-
387
+
388
+
389
+ # DECIMALS = %w( целая десятая сотая тысячная десятитысячная стотысячная
390
+ # миллионная десятимиллионная стомиллионная миллиардная десятимиллиардная
391
+ # стомиллиардная триллионная
392
+ # ).map{|e| [e, e.gsub(/ая$/, "ых"), e.gsub(/ая$/, "ых"), ] }.freeze
393
+ #
394
+
267
395
  # Выдает сумму прописью с учетом дробной доли. Дробная доля округляется до миллионной, или (если
268
396
  # дробная доля оканчивается на нули) до ближайшей доли ( 500 тысячных округляется до 5 десятых).
269
397
  # Дополнительный аргумент - род существительного (1 - мужской, 2- женский, 3-средний)
270
- def propisju_float(num)
398
+ def propisju_float(num, locale = :ru)
399
+ locale_root = DECIMALS[locale.to_sym]
400
+ source_expression = locale_root[:prefix][0]
401
+ target_prefix = locale_root[:prefix][1]
402
+ words = locale_root[:source_words].map do |e|
403
+ [
404
+ e,
405
+ e.gsub(/#{source_expression}$/, target_prefix),
406
+ e.gsub(/#{source_expression}$/, target_prefix),
407
+ ]
408
+ end.freeze
271
409
 
272
410
  # Укорачиваем до триллионной доли
273
- formatted = ("%0.#{DECIMALS.length}f" % num).gsub(/0+$/, '')
411
+ formatted = ("%0.#{words.length}f" % num).gsub(/0+$/, '')
274
412
  wholes, decimals = formatted.split(/\./)
275
413
 
276
- return propisju_int(wholes.to_i) if decimals.to_i.zero?
414
+ return propisju_int(wholes.to_i, 1, [], locale) if decimals.to_i.zero?
277
415
 
278
- whole_st = propisju_shtuk(wholes.to_i, 2, *DECIMALS[0])
416
+ whole_st = propisju_shtuk(wholes.to_i, 2, words[0], locale)
279
417
 
280
- rem_st = propisju_shtuk(decimals.to_i, 2, *DECIMALS[decimals.length])
418
+ rem_st = propisju_shtuk(decimals.to_i, 2, words[decimals.length], locale)
281
419
  [whole_st, rem_st].compact.join(" ")
282
420
  end
283
421
 
@@ -291,28 +429,28 @@ module RuPropisju
291
429
  #
292
430
  # Примерно так:
293
431
  # propisju(42, 1, "сволочь", "сволочи", "сволочей") # => "сорок две сволочи"
294
- def propisju_int(amount, gender = 1, one_item = '', two_items = '', five_items = '')
432
+ def propisju_int(amount, gender = 1, item_forms = [], locale = :ru)
295
433
 
296
- return "ноль " + five_items if amount.zero?
434
+ locale_root = TRANSLATIONS[locale.to_s]
297
435
 
298
- # единицы
299
- into, remaining_amount = compose_ordinal('', amount, gender, one_item, two_items, five_items)
436
+ return locale_root['0'] + ' ' + item_forms[2] if amount.zero?
300
437
 
301
- return into if remaining_amount == 0
302
-
303
- # тысячи
304
- into, remaining_amount = compose_ordinal(into, remaining_amount, 2, "тысяча", "тысячи", "тысяч")
305
-
306
- return into if remaining_amount == 0
307
-
308
- # миллионы
309
- into, remaining_amount = compose_ordinal(into, remaining_amount, 1, "миллион", "миллиона", "миллионов")
310
-
311
- return into if remaining_amount == 0
438
+ # единицы
439
+ into, remaining_amount = compose_ordinal('', amount, gender, item_forms, locale)
440
+
441
+ return into if remaining_amount.zero?
442
+
443
+ [:thousands, :millions, :billions].each do |type|
444
+ into, remaining_amount = compose_ordinal(
445
+ into,
446
+ remaining_amount,
447
+ (type == :thousands ? 2 : 1), # пол женский только для тысяч
448
+ locale_root[type],
449
+ locale
450
+ )
451
+ return into if remaining_amount.zero?
452
+ end
312
453
 
313
- # миллиарды
314
- into, remaining_amount = compose_ordinal(into, remaining_amount, 1, "миллиард", "миллиарда", "миллиардов")
315
- return into
316
454
  end
317
455
 
318
456
  alias_method :rublja, :rublej
@@ -0,0 +1,47 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "ru_propisju"
8
+ s.version = "2.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Julik Tarkhanov"]
12
+ s.date = "2011-12-19"
13
+ s.email = "me@julik.nl"
14
+ s.extra_rdoc_files = [
15
+ "README.rdoc"
16
+ ]
17
+ s.files = [
18
+ "Gemfile",
19
+ "History.txt",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "lib/ru_propisju.rb",
23
+ "ru_propisju.gemspec",
24
+ "test/test_ru_propisju.rb"
25
+ ]
26
+ s.homepage = "http://github.com/julik/ru_propisju"
27
+ s.licenses = ["MIT"]
28
+ s.require_paths = ["lib"]
29
+ s.rubygems_version = "1.8.11"
30
+ s.summary = "C\u{443}\u{43c}\u{43c}\u{430} \u{43f}\u{440}\u{43e}\u{43f}\u{438}\u{441}\u{44c}\u{44e}"
31
+
32
+ if s.respond_to? :specification_version then
33
+ s.specification_version = 3
34
+
35
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
36
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
37
+ s.add_development_dependency(%q<rake>, [">= 0"])
38
+ else
39
+ s.add_dependency(%q<jeweler>, [">= 0"])
40
+ s.add_dependency(%q<rake>, [">= 0"])
41
+ end
42
+ else
43
+ s.add_dependency(%q<jeweler>, [">= 0"])
44
+ s.add_dependency(%q<rake>, [">= 0"])
45
+ end
46
+ end
47
+
@@ -1,67 +1,114 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8 -*-
2
2
  $KCODE = 'u' if RUBY_VERSION < '1.9.0'
3
3
 
4
4
  require "test/unit"
5
5
  require "ru_propisju"
6
6
 
7
7
  class TestRuPropisju < Test::Unit::TestCase
8
-
8
+
9
9
  def test_amount_in_words
10
10
  assert_raise(RuPropisju::UnknownCurrency) do
11
11
  RuPropisju.amount_in_words(123, "neumelix programmista")
12
12
  end
13
-
13
+
14
+ # russian locale
14
15
  assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, :rur)
16
+ assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, :rub)
15
17
  assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, "RUR")
16
18
  assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, "rur")
17
19
  assert_equal "сто двадцать три гривны", RuPropisju.amount_in_words(123, "uah")
18
20
  assert_equal "сто двадцать три евро", RuPropisju.amount_in_words(123, "eur")
19
21
  assert_equal "сто двадцать три евро четырнадцать центов", RuPropisju.amount_in_words(123.14, "eur")
20
22
  assert_equal "сто двадцать три доллара четырнадцать центов", RuPropisju.amount_in_words(123.14, "usd")
23
+
24
+ # ua locale
25
+ assert_equal "сто двадцять три рубля", RuPropisju.amount_in_words(123, :rur, :ua)
26
+ assert_equal "сто двадцять три рубля", RuPropisju.amount_in_words(123, :rub, :ua)
27
+ assert_equal "сто двадцять три рубля", RuPropisju.amount_in_words(123, "RUR", "ua")
28
+ assert_equal "сто двадцять три рубля", RuPropisju.amount_in_words(123, "rur", "ua")
29
+ assert_equal "сто двадцять три гривні", RuPropisju.amount_in_words(123, "uah", "ua")
30
+ assert_equal "сто двадцять три євро", RuPropisju.amount_in_words(123, "eur", "ua")
31
+ assert_equal "сто двадцять три євро чотирнадцять євроцентів", RuPropisju.amount_in_words(123.14, "eur", :ua)
32
+ assert_equal "сто двадцять три долара чотирнадцять центів", RuPropisju.amount_in_words(123.14, "usd", :ua)
21
33
  end
22
-
34
+
23
35
  def test_propisju_dollarov
24
36
  assert_equal "сто двадцать один доллар пятьдесят один цент", RuPropisju.dollarov(121.51)
37
+ assert_equal "сто двадцять один долар п'ятьдесят один цент", RuPropisju.dollarov(121.51, :ua)
25
38
  end
26
-
39
+
27
40
  def test_propisju_euro
28
41
  assert_equal "сто двадцать один евро четыре цента", RuPropisju.evro(121.04)
42
+ assert_equal "сто двадцять один євро чотири євроцента", RuPropisju.evro(121.04, :ua)
29
43
  end
30
-
44
+
31
45
  def test_propisju_for_ints
32
- assert_equal "пятьсот двадцать три", RuPropisju.propisju(523)
33
- assert_equal "шесть тысяч семьсот двадцать семь", RuPropisju.propisju(6727)
46
+ assert_equal "пятьсот двадцать три", RuPropisju.propisju(523, 1)
47
+ assert_equal "шесть тысяч семьсот двадцать семь", RuPropisju.propisju(6727, 1)
34
48
  assert_equal "восемь миллионов шестьсот пятьдесят два", RuPropisju.propisju(8000652, 1)
35
49
  assert_equal "восемь миллионов шестьсот пятьдесят две", RuPropisju.propisju(8000652, 2)
36
50
  assert_equal "восемь миллионов шестьсот пятьдесят два", RuPropisju.propisju(8000652, 3)
37
- assert_equal "сорок пять", RuPropisju.propisju(45)
38
- assert_equal "пять", RuPropisju.propisju(5)
39
- assert_equal "шестьсот двенадцать", RuPropisju.propisju(612)
51
+ assert_equal "сорок пять", RuPropisju.propisju(45, 1)
52
+ assert_equal "пять", RuPropisju.propisju(5, 1)
53
+ assert_equal "шестьсот двенадцать", RuPropisju.propisju(612, 1)
54
+
55
+
56
+ # ukrainian locale
57
+ assert_equal "п'ятьсот двадцять три", RuPropisju.propisju(523, 1, :ua)
58
+ assert_equal "шість тисяч сімсот двадцять сім", RuPropisju.propisju(6727, 1, :ua)
59
+ assert_equal "вісім мільйонів шістсот п'ятьдесят два", RuPropisju.propisju(8000652, 1, :ua)
60
+ assert_equal "вісім мільйонів шістсот п'ятьдесят дві", RuPropisju.propisju(8000652, 2, :ua)
61
+ assert_equal "вісім мільйонів шістсот п'ятьдесят два", RuPropisju.propisju(8000652, 3, :ua)
62
+ assert_equal "сорок п'ять", RuPropisju.propisju(45, 1, :ua)
63
+ assert_equal "п'ять", RuPropisju.propisju(5, 1, :ua)
64
+ assert_equal "шістсот дванадцять", RuPropisju.propisju(612, 1, :ua)
65
+
40
66
  end
41
-
67
+
42
68
  def test_propisju_shtuk
43
- assert_equal "шесть целых", RuPropisju.propisju_shtuk(6, 2, "целая", "целых", "целых")
44
- assert_equal "двадцать пять колес", RuPropisju.propisju_shtuk(25, 3, "колесо", "колеса", "колес")
45
- assert_equal "двадцать одна подстава", RuPropisju.propisju_shtuk(21, 2, "подстава", "подставы", "подстав")
46
- assert_equal "двести двенадцать сволочей", RuPropisju.propisju_shtuk(212.00, 2, "сволочь", "сволочи", "сволочей")
47
- assert_equal "двести двенадцать целых четыре десятых куска", RuPropisju.propisju_shtuk(212.40, 2, "кусок", "куска", "кусков")
69
+ assert_equal "шесть целых", RuPropisju.propisju_shtuk(6, 2, ["целая", "целых", "целых"])
70
+ assert_equal "двадцать пять колес", RuPropisju.propisju_shtuk(25, 3, ["колесо", "колеса", "колес"])
71
+ assert_equal "двадцать одна подстава", RuPropisju.propisju_shtuk(21, 2, ["подстава", "подставы", "подстав"])
72
+ assert_equal "двести двенадцать сволочей", RuPropisju.propisju_shtuk(212.00, 2, ["сволочь", "сволочи", "сволочей"])
73
+ assert_equal "двести двенадцать целых четыре десятых куска", RuPropisju.propisju_shtuk(212.40, 2, ["кусок", "куска", "кусков"])
74
+
75
+ # ua locale
76
+ assert_equal "шість цілих", RuPropisju.propisju_shtuk(6, 2, ["ціла", "цілих", "цілих"], :ua)
77
+ assert_equal "двадцять п'ять колес", RuPropisju.propisju_shtuk(25, 3, ["колесо", "колеса", "колес"], :ua)
78
+ assert_equal "двадцять одна підстава", RuPropisju.propisju_shtuk(21, 2, ["підстава", "підстави", "підстав"], :ua)
79
+ assert_equal "двісті дванадцять наволочів", RuPropisju.propisju_shtuk(212.00, 2, ["наволоч", "наволочі", "наволочів"], :ua)
80
+ assert_equal "двісті дванадцять цілих чотири десятих шматка", RuPropisju.propisju_shtuk(212.40, 2, ["шматок", "шматка", "шматків"], :ua)
48
81
  end
49
-
82
+
50
83
  def test_propisju_for_floats
51
- assert_equal "шесть целых пять десятых", RuPropisju.propisju(6.50)
52
- assert_equal "триста сорок одна целая девять десятых", RuPropisju.propisju(341.9)
53
- assert_equal "триста сорок одна целая двести сорок пять тысячных", RuPropisju.propisju(341.245)
54
- assert_equal "двести три целых сорок одна сотая", RuPropisju.propisju(203.41)
55
- assert_equal "четыреста сорок две целых пять десятых", RuPropisju.propisju(442.50000)
84
+ assert_equal "шесть целых пять десятых", RuPropisju.propisju(6.50, 1)
85
+ assert_equal "триста сорок одна целая девять десятых", RuPropisju.propisju(341.9, 1)
86
+ assert_equal "триста сорок одна целая двести сорок пять тысячных", RuPropisju.propisju(341.245, 1)
87
+ assert_equal "двести три целых сорок одна сотая", RuPropisju.propisju(203.41, 1)
88
+ assert_equal "четыреста сорок две целых пять десятых", RuPropisju.propisju(442.50000, 1)
89
+ # ua locale
90
+ assert_equal "шість цілих п'ять десятих", RuPropisju.propisju(6.50, 1, :ua)
91
+ assert_equal "триста сорок одна ціла дев'ять десятих", RuPropisju.propisju(341.9, 1, :ua)
92
+ assert_equal "триста сорок одна ціла двісті сорок п'ять тисячних", RuPropisju.propisju(341.245, 1, :ua)
93
+ assert_equal "двісті три цілих сорок одна сота", RuPropisju.propisju(203.41, 1, :ua)
94
+ assert_equal "чотиреста сорок дві цілих п'ять десятих", RuPropisju.propisju(442.50000, 1, :ua)
95
+
56
96
  end
57
-
97
+
58
98
  def test_choose_plural
59
- assert_equal "чемодана", RuPropisju.choose_plural(523, "чемодан", "чемодана", "чемоданов")
60
- assert_equal "партий", RuPropisju.choose_plural(6727, "партия", "партии", "партий")
61
- assert_equal "козлов", RuPropisju.choose_plural(45, "козел", "козла", "козлов")
62
- assert_equal "колес", RuPropisju.choose_plural(260, "колесо", "колеса", "колес")
99
+ assert_equal "чемодана", RuPropisju.choose_plural(523, ["чемодан", "чемодана", "чемоданов"])
100
+ assert_equal "партий", RuPropisju.choose_plural(6727, ["партия", "партии", "партий"])
101
+ assert_equal "козлов", RuPropisju.choose_plural(45, ["козел", "козла", "козлов"])
102
+ assert_equal "колес", RuPropisju.choose_plural(260, ["колесо", "колеса", "колес"])
103
+
104
+ # ua locale
105
+
106
+ assert_equal "валізи", RuPropisju.choose_plural(523, ["валіза", "валізи", "валіз"])
107
+ assert_equal "партій", RuPropisju.choose_plural(6727, ["партія", "партії", "партій"])
108
+ assert_equal "козлів", RuPropisju.choose_plural(45, ["козел", "козла", "козлів"])
109
+ assert_equal "колес", RuPropisju.choose_plural(260, ["колесо", "колеса", "колес"])
63
110
  end
64
-
111
+
65
112
  def test_rublej
66
113
  assert_equal "сто двадцать три рубля", RuPropisju.rublej(123)
67
114
  assert_equal "триста сорок три рубля 20 копеек", RuPropisju.rublej(343.20)
@@ -69,8 +116,16 @@ class TestRuPropisju < Test::Unit::TestCase
69
116
  assert_equal "триста тридцать два рубля", RuPropisju.rublej(331.995)
70
117
  assert_equal "один рубль", RuPropisju.rubl(1)
71
118
  assert_equal "три рубля 14 копеек", RuPropisju.rublja(3.14)
119
+
120
+ # ua locale
121
+ assert_equal "сто двадцять три рубля", RuPropisju.rublej(123, :ua)
122
+ assert_equal "триста сорок три рубля 20 копійок", RuPropisju.rublej(343.20, :ua)
123
+ assert_equal "42 копійки", RuPropisju.rublej(0.4187, :ua)
124
+ assert_equal "триста тридцять два рубля", RuPropisju.rublej(331.995, :ua)
125
+ assert_equal "один рубль", RuPropisju.rubl(1, :ua)
126
+ assert_equal "три рубля 14 копійок", RuPropisju.rublja(3.14, :ua)
72
127
  end
73
-
128
+
74
129
  def test_griven
75
130
  assert_equal "сто двадцать три гривны", RuPropisju.griven(123)
76
131
  assert_equal "сто двадцать четыре гривны", RuPropisju.griven(124)
@@ -79,13 +134,28 @@ class TestRuPropisju < Test::Unit::TestCase
79
134
  assert_equal "триста тридцать две гривны", RuPropisju.griven(331.995)
80
135
  assert_equal "одна гривна", RuPropisju.grivna(1)
81
136
  assert_equal "три гривны четырнадцать копеек", RuPropisju.grivny(3.14)
137
+ # ua locale
138
+ assert_equal "сто двадцять три гривні", RuPropisju.griven(123, :ua)
139
+ assert_equal "сто двадцять чотири гривні", RuPropisju.griven(124, :ua)
140
+ assert_equal "триста сорок три гривні двадцять копійок", RuPropisju.griven(343.20, :ua)
141
+ assert_equal "сорок дві копійки", RuPropisju.griven(0.4187, :ua)
142
+ assert_equal "триста тридцять дві гривні", RuPropisju.griven(331.995, :ua)
143
+ assert_equal "одна гривня", RuPropisju.grivna(1, :ua)
144
+ assert_equal "три гривні чотирнадцять копійок", RuPropisju.grivny(3.14, :ua)
145
+
82
146
  end
83
-
147
+
84
148
  def test_kopeek
85
149
  assert_equal "сто двадцать три рубля", RuPropisju.kopeek(12300)
86
150
  assert_equal "три рубля 14 копеек", RuPropisju.kopeek(314)
87
151
  assert_equal "32 копейки", RuPropisju.kopeek(32)
88
152
  assert_equal "21 копейка", RuPropisju.kopeika(21)
89
153
  assert_equal "3 копейки", RuPropisju.kopeiki(3)
154
+ # ua locale
155
+ assert_equal "сто двадцять три рубля", RuPropisju.kopeek(12300, :ua)
156
+ assert_equal "три рубля 14 копійок", RuPropisju.kopeek(314, :ua)
157
+ assert_equal "32 копійки", RuPropisju.kopeek(32, :ua)
158
+ assert_equal "21 копійка", RuPropisju.kopeika(21, :ua)
159
+ assert_equal "3 копійки", RuPropisju.kopeiki(3, :ua)
90
160
  end
91
161
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ru_propisju
3
3
  version: !ruby/object:Gem::Version
4
- version: !binary |-
5
- MS4yLjA=
4
+ version: 2.0.0
6
5
  prerelease:
7
6
  platform: ruby
8
7
  authors:
@@ -10,55 +9,49 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2011-11-15 00:00:00.000000000 Z
12
+ date: 2011-12-19 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
- name: hoe
17
- requirement: &2590690 !ruby/object:Gem::Requirement
15
+ name: jeweler
16
+ requirement: &10698430 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
- - - ~>
19
+ - - ! '>='
21
20
  - !ruby/object:Gem::Version
22
- version: '2.12'
21
+ version: '0'
23
22
  type: :development
24
23
  prerelease: false
25
- version_requirements: *2590690
26
- description: !binary |-
27
- 0JLRi9Cy0L7QtNC40YIg0YHRg9C80LzRgyDQv9GA0L7Qv9C40YHRjNGOINC4
28
- INGB0YPQvNC80Ysg0LrQvtC/0LXQtdC6LCDRgNGD0LHQu9C10Lkg0Lgg0LPR
29
- gNC40LLQtdC9LiDQn9C+0LzQvtCz0LDQtdGCINCyINCy0YvQsdC+0YDQtSDQ
30
- v9GA0LDQstC40LvRjNC90L7Qs9C+INGH0LjRgdC70LjRgtC10LvRjNC90L7Q
31
- s9C+Lg==
32
- email:
33
- - me@julik.nl
24
+ version_requirements: *10698430
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &10698180 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *10698180
36
+ description:
37
+ email: me@julik.nl
34
38
  executables: []
35
39
  extensions: []
36
40
  extra_rdoc_files:
37
- - !binary |-
38
- SGlzdG9yeS50eHQ=
39
- - !binary |-
40
- TWFuaWZlc3QudHh0
41
41
  - README.rdoc
42
42
  files:
43
- - !binary |-
44
- SGlzdG9yeS50eHQ=
45
- - !binary |-
46
- TWFuaWZlc3QudHh0
47
- - !binary |-
48
- UkVBRE1FLnJkb2M=
49
- - !binary |-
50
- UmFrZWZpbGU=
51
- - !binary |-
52
- bGliL3J1X3Byb3Bpc2p1LnJi
53
- - !binary |-
54
- dGVzdC90ZXN0X3J1X3Byb3Bpc2p1LnJi
55
- - .gemtest
43
+ - Gemfile
44
+ - History.txt
45
+ - README.rdoc
46
+ - Rakefile
47
+ - lib/ru_propisju.rb
48
+ - ru_propisju.gemspec
49
+ - test/test_ru_propisju.rb
56
50
  homepage: http://github.com/julik/ru_propisju
57
- licenses: []
51
+ licenses:
52
+ - MIT
58
53
  post_install_message:
59
- rdoc_options:
60
- - --main
61
- - README.rdoc
54
+ rdoc_options: []
62
55
  require_paths:
63
56
  - lib
64
57
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -74,13 +67,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
67
  - !ruby/object:Gem::Version
75
68
  version: '0'
76
69
  requirements: []
77
- rubyforge_project: ru_propisju
78
- rubygems_version: 1.8.5
70
+ rubyforge_project:
71
+ rubygems_version: 1.8.11
79
72
  signing_key:
80
73
  specification_version: 3
81
- summary: !binary |-
82
- 0JLRi9Cy0L7QtNC40YIg0YHRg9C80LzRgyDQv9GA0L7Qv9C40YHRjNGOINC4
83
- INGB0YPQvNC80Ysg0LrQvtC/0LXQtdC6LCDRgNGD0LHQu9C10Lkg0Lgg0LPR
84
- gNC40LLQtdC9
85
- test_files:
86
- - test/test_ru_propisju.rb
74
+ summary: Cумма прописью
75
+ test_files: []
data/.gemtest DELETED
File without changes
data/Manifest.txt DELETED
@@ -1,6 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- README.rdoc
4
- Rakefile
5
- lib/ru_propisju.rb
6
- test/test_ru_propisju.rb