ru_propisju 1.2.0 → 2.0.0

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