ru_propisju 1.1.0 → 1.2.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/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.2.0 / 2011-11-15
2
+
3
+ * Добавлена поддержка И Еще Нескольких Валют (тм) - terraplane
4
+
1
5
  === 1.1.0 / 2011-04-09
2
6
 
3
7
  * На самом деле количество копеек пишется цифрами
data/Rakefile CHANGED
@@ -6,8 +6,8 @@ require 'hoe'
6
6
  Hoe.spec 'ru_propisju' do | p |
7
7
  p.readme_file = 'README.rdoc'
8
8
  p.extra_rdoc_files = FileList['*.rdoc'] + FileList['*.txt']
9
-
10
9
  p.developer('Julik Tarkhanov', 'me@julik.nl')
10
+ p.clean_globs += %w( *.gemspec )
11
11
  end
12
12
 
13
13
  # vim: syntax=ruby
data/lib/ru_propisju.rb CHANGED
@@ -1,12 +1,16 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8 -*-
2
2
  $KCODE = 'u' if RUBY_VERSION < '1.9.0'
3
3
 
4
4
  # Самый лучший, прекрасный, кривой и неотразимый суперпечататель суммы прописью для Ruby.
5
5
  #
6
6
  # RuPropisju.rublej(123) # "сто двадцать три рубля"
7
7
  module RuPropisju
8
+
9
+ VERSION = '1.2.0'
8
10
 
9
- VERSION = '1.1.0'
11
+ # Кидается при запросе неизвестной валюты
12
+ class UnknownCurrency < ArgumentError
13
+ end
10
14
 
11
15
  # Выбирает нужный падеж существительного в зависимости от числа
12
16
  #
@@ -14,7 +18,7 @@ module RuPropisju
14
18
  def choose_plural(amount, *variants)
15
19
  mod_ten = amount % 10
16
20
  mod_hundred = amount % 100
17
- variant = if (mod_ten == 1 && mod_hundred != 11)
21
+ variant = if (mod_ten == 1 && mod_hundred != 11)
18
22
  1
19
23
  else
20
24
  if mod_ten >= 2 && mod_ten <= 4 && (mod_hundred <10 || mod_hundred % 100>=20)
@@ -26,15 +30,25 @@ module RuPropisju
26
30
  variants[variant-1]
27
31
  end
28
32
 
33
+ # Выводит сумму прописью в зависимости от выбранной валюты.
34
+ # Поддерживаемые валюты: rur, usd, uah, eur
35
+ #
36
+ # 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(", ")}"
40
+ end
41
+ method(CURRENCIES[currency.to_s.downcase]).call(amount)
42
+ end
29
43
 
30
44
  # Выводит целое или дробное число как сумму в рублях прописью
31
45
  #
32
46
  # rublej(345.2) #=> "триста сорок пять рублей 20 копеек"
33
47
  def rublej(amount)
34
48
  pts = []
35
-
49
+
36
50
  pts << propisju_shtuk(amount.to_i, 1, "рубль", "рубля", "рублей") unless amount.to_i == 0
37
-
51
+
38
52
  if amount.kind_of?(Float)
39
53
  remainder = (amount.divmod(1)[1]*100).round
40
54
  if (remainder == 100)
@@ -46,10 +60,10 @@ module RuPropisju
46
60
  end
47
61
  end
48
62
  end
49
-
63
+
50
64
  pts.join(' ')
51
65
  end
52
-
66
+
53
67
  # Выбирает корректный вариант числительного в зависимости от рода и числа и оформляет сумму прописью
54
68
  #
55
69
  # propisju(243) => "двести сорок три"
@@ -61,7 +75,7 @@ module RuPropisju
61
75
  propisju_float(amount)
62
76
  end
63
77
  end
64
-
78
+
65
79
  # Выводит целое или дробное число как сумму в гривнах прописью
66
80
  #
67
81
  # griven(32) #=> "тридцать две гривны"
@@ -77,10 +91,48 @@ module RuPropisju
77
91
  pts << propisju_int(remainder.to_i, 2, 'копейка', 'копейки', 'копеек')
78
92
  end
79
93
  end
80
-
94
+
81
95
  pts.join(' ')
82
96
  end
83
-
97
+
98
+ # Выводит целое или дробное число как сумму в долларах прописью
99
+ #
100
+ # dollarov(32) #=> "тридцать два доллара"
101
+ def dollarov(amount)
102
+ pts = []
103
+
104
+ pts << propisju_int(amount.to_i, 1, "доллар", "доллара", "долларов") unless amount.to_i == 0
105
+ if amount.kind_of?(Float)
106
+ remainder = (amount.divmod(1)[1]*100).round
107
+ if (remainder == 100)
108
+ pts = [propisju_int(amount.to_i + 1, 1, 'доллар', 'доллара', 'долларов')]
109
+ else
110
+ pts << propisju_int(remainder.to_i, 1, 'цент', 'цента', 'центов')
111
+ end
112
+ end
113
+
114
+ pts.join(' ')
115
+ end
116
+
117
+ # Выводит целое или дробное число как сумму в евро прописью
118
+ #
119
+ # evro(32) #=> "тридцать два евро"
120
+ def evro(amount)
121
+ pts = []
122
+
123
+ pts << propisju_int(amount.to_i, 1, "евро", "евро", "евро") unless amount.to_i == 0
124
+ if amount.kind_of?(Float)
125
+ remainder = (amount.divmod(1)[1]*100).round
126
+ if (remainder == 100)
127
+ pts = [propisju_int(amount.to_i + 1, 1, 'евро', 'евро', 'евро')]
128
+ else
129
+ pts << propisju_int(remainder.to_i, 1, 'цент', 'цента', 'центов')
130
+ end
131
+ end
132
+
133
+ pts.join(' ')
134
+ end
135
+
84
136
  # Выводит сумму прописью в рублях по количеству копеек
85
137
  #
86
138
  # kopeek(343) #=> "три рубля 43 копейки"
@@ -98,26 +150,26 @@ module RuPropisju
98
150
  else
99
151
  [propisju(items, gender), forms[1]]
100
152
  end
101
-
153
+
102
154
  r.join(" ")
103
155
  end
104
-
156
+
105
157
  private
106
-
158
+
107
159
  def compose_ordinal(into, remaining_amount, gender, one_item='', two_items='', five_items='')
108
160
  rest, rest1, chosen_ordinal, ones, tens, hundreds = [nil]*6
109
161
  #
110
162
  rest = remaining_amount % 1000
111
163
  remaining_amount = remaining_amount / 1000
112
- if rest == 0
113
- # последние три знака нулевые
164
+ if rest == 0
165
+ # последние три знака нулевые
114
166
  into = five_items + " " if into == ""
115
167
  return [into, remaining_amount]
116
168
  end
117
169
  #
118
170
  # начинаем подсчет с Rest
119
171
  chosen_ordinal = five_items
120
-
172
+
121
173
  # сотни
122
174
  hundreds = case rest / 100
123
175
  when 0 then ""
@@ -174,8 +226,8 @@ module RuPropisju
174
226
  if gender == 2
175
227
  ones = "две "
176
228
  else
177
- ones = "два "
178
- end
229
+ ones = "два "
230
+ end
179
231
  chosen_ordinal = two_items
180
232
  when 3
181
233
  ones = "три "
@@ -195,33 +247,40 @@ module RuPropisju
195
247
  ones = "девять "
196
248
  end
197
249
  end
198
-
199
- plural = [hundreds, tens, ones, chosen_ordinal, " ", into].join.strip
200
- return [plural, remaining_amount]
250
+
251
+ plural = [hundreds, tens, ones, chosen_ordinal, " ", into].join.strip
252
+ return [plural, remaining_amount]
201
253
  end
202
254
 
203
255
  DECIMALS = %w( целая десятая сотая тысячная десятитысячная стотысячная
204
- миллионная десятимиллионная стомиллионная миллиардная десятимиллиардная
256
+ миллионная десятимиллионная стомиллионная миллиардная десятимиллиардная
205
257
  стомиллиардная триллионная
206
258
  ).map{|e| [e, e.gsub(/ая$/, "ых"), e.gsub(/ая$/, "ых"), ] }.freeze
207
259
 
260
+ CURRENCIES = {
261
+ "rur" => :rublej,
262
+ "usd" => :dollarov,
263
+ "uah" => :griven,
264
+ "eur" => :evro,
265
+ }
266
+
208
267
  # Выдает сумму прописью с учетом дробной доли. Дробная доля округляется до миллионной, или (если
209
268
  # дробная доля оканчивается на нули) до ближайшей доли ( 500 тысячных округляется до 5 десятых).
210
269
  # Дополнительный аргумент - род существительного (1 - мужской, 2- женский, 3-средний)
211
270
  def propisju_float(num)
212
-
271
+
213
272
  # Укорачиваем до триллионной доли
214
273
  formatted = ("%0.#{DECIMALS.length}f" % num).gsub(/0+$/, '')
215
274
  wholes, decimals = formatted.split(/\./)
216
-
275
+
217
276
  return propisju_int(wholes.to_i) if decimals.to_i.zero?
218
-
277
+
219
278
  whole_st = propisju_shtuk(wholes.to_i, 2, *DECIMALS[0])
220
-
279
+
221
280
  rem_st = propisju_shtuk(decimals.to_i, 2, *DECIMALS[decimals.length])
222
281
  [whole_st, rem_st].compact.join(" ")
223
282
  end
224
-
283
+
225
284
  # Выполняет преобразование числа из цифрого вида в символьное
226
285
  #
227
286
  # amount - числительное
@@ -229,44 +288,46 @@ module RuPropisju
229
288
  # one_item - именительный падеж единственного числа (= 1)
230
289
  # two_items - родительный падеж единственного числа (= 2-4)
231
290
  # five_items - родительный падеж множественного числа ( = 5-10)
232
- #
291
+ #
233
292
  # Примерно так:
234
293
  # propisju(42, 1, "сволочь", "сволочи", "сволочей") # => "сорок две сволочи"
235
294
  def propisju_int(amount, gender = 1, one_item = '', two_items = '', five_items = '')
236
-
295
+
237
296
  return "ноль " + five_items if amount.zero?
238
-
297
+
239
298
  # единицы
240
299
  into, remaining_amount = compose_ordinal('', amount, gender, one_item, two_items, five_items)
241
-
300
+
242
301
  return into if remaining_amount == 0
243
-
302
+
244
303
  # тысячи
245
- into, remaining_amount = compose_ordinal(into, remaining_amount, 2, "тысяча", "тысячи", "тысяч")
246
-
304
+ into, remaining_amount = compose_ordinal(into, remaining_amount, 2, "тысяча", "тысячи", "тысяч")
305
+
247
306
  return into if remaining_amount == 0
248
-
307
+
249
308
  # миллионы
250
309
  into, remaining_amount = compose_ordinal(into, remaining_amount, 1, "миллион", "миллиона", "миллионов")
251
-
310
+
252
311
  return into if remaining_amount == 0
253
-
312
+
254
313
  # миллиарды
255
314
  into, remaining_amount = compose_ordinal(into, remaining_amount, 1, "миллиард", "миллиарда", "миллиардов")
256
315
  return into
257
316
  end
258
-
317
+
259
318
  alias_method :rublja, :rublej
260
319
  alias_method :rubl, :rublej
261
-
320
+
262
321
  alias_method :kopeika, :kopeek
263
322
  alias_method :kopeiki, :kopeek
264
-
323
+
265
324
  alias_method :grivna, :griven
266
325
  alias_method :grivny, :griven
267
-
268
-
326
+
327
+ alias_method :dollar, :dollarov
328
+ alias_method :dollary, :dollarov
329
+
269
330
  public_instance_methods(true).map{|m| module_function(m) }
270
-
331
+
271
332
  module_function :propisju_int, :propisju_float, :compose_ordinal
272
- end
333
+ end
@@ -5,7 +5,29 @@ require "test/unit"
5
5
  require "ru_propisju"
6
6
 
7
7
  class TestRuPropisju < Test::Unit::TestCase
8
-
8
+
9
+ def test_amount_in_words
10
+ assert_raise(RuPropisju::UnknownCurrency) do
11
+ RuPropisju.amount_in_words(123, "neumelix programmista")
12
+ end
13
+
14
+ assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, :rur)
15
+ assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, "RUR")
16
+ assert_equal "сто двадцать три рубля", RuPropisju.amount_in_words(123, "rur")
17
+ assert_equal "сто двадцать три гривны", RuPropisju.amount_in_words(123, "uah")
18
+ assert_equal "сто двадцать три евро", RuPropisju.amount_in_words(123, "eur")
19
+ assert_equal "сто двадцать три евро четырнадцать центов", RuPropisju.amount_in_words(123.14, "eur")
20
+ assert_equal "сто двадцать три доллара четырнадцать центов", RuPropisju.amount_in_words(123.14, "usd")
21
+ end
22
+
23
+ def test_propisju_dollarov
24
+ assert_equal "сто двадцать один доллар пятьдесят один цент", RuPropisju.dollarov(121.51)
25
+ end
26
+
27
+ def test_propisju_euro
28
+ assert_equal "сто двадцать один евро четыре цента", RuPropisju.evro(121.04)
29
+ end
30
+
9
31
  def test_propisju_for_ints
10
32
  assert_equal "пятьсот двадцать три", RuPropisju.propisju(523)
11
33
  assert_equal "шесть тысяч семьсот двадцать семь", RuPropisju.propisju(6727)
metadata CHANGED
@@ -1,92 +1,86 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ru_propisju
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: !binary |-
5
+ MS4yLjA=
5
6
  prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 0
10
- version: 1.1.0
11
7
  platform: ruby
12
- authors:
8
+ authors:
13
9
  - Julik Tarkhanov
14
10
  autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2011-04-08 00:00:00 +02:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2011-11-15 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: hoe
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &2590690 !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 41
30
- segments:
31
- - 2
32
- - 9
33
- - 1
34
- version: 2.9.1
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '2.12'
35
23
  type: :development
36
- version_requirements: *id001
37
- description: "\xD0\x92\xD1\x8B\xD0\xB2\xD0\xBE\xD0\xB4\xD0\xB8\xD1\x82 \xD1\x81\xD1\x83\xD0\xBC\xD0\xBC\xD1\x83 \xD0\xBF\xD1\x80\xD0\xBE\xD0\xBF\xD0\xB8\xD1\x81\xD1\x8C\xD1\x8E \xD0\xB8 \xD1\x81\xD1\x83\xD0\xBC\xD0\xBC\xD1\x8B \xD0\xBA\xD0\xBE\xD0\xBF\xD0\xB5\xD0\xB5\xD0\xBA, \xD1\x80\xD1\x83\xD0\xB1\xD0\xBB\xD0\xB5\xD0\xB9 \xD0\xB8 \xD0\xB3\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD0\xBD. \xD0\x9F\xD0\xBE\xD0\xBC\xD0\xBE\xD0\xB3\xD0\xB0\xD0\xB5\xD1\x82 \xD0\xB2 \xD0\xB2\xD1\x8B\xD0\xB1\xD0\xBE\xD1\x80\xD0\xB5 \xD0\xBF\xD1\x80\xD0\xB0\xD0\xB2\xD0\xB8\xD0\xBB\xD1\x8C\xD0\xBD\xD0\xBE\xD0\xB3\xD0\xBE \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xB8\xD1\x82\xD0\xB5\xD0\xBB\xD1\x8C\xD0\xBD\xD0\xBE\xD0\xB3\xD0\xBE."
38
- email:
24
+ 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:
39
33
  - me@julik.nl
40
34
  executables: []
41
-
42
35
  extensions: []
43
-
44
- extra_rdoc_files:
45
- - History.txt
46
- - Manifest.txt
36
+ extra_rdoc_files:
37
+ - !binary |-
38
+ SGlzdG9yeS50eHQ=
39
+ - !binary |-
40
+ TWFuaWZlc3QudHh0
47
41
  - README.rdoc
48
- files:
49
- - History.txt
50
- - Manifest.txt
51
- - README.rdoc
52
- - Rakefile
53
- - lib/ru_propisju.rb
54
- - test/test_ru_propisju.rb
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
55
  - .gemtest
56
- has_rdoc: true
57
56
  homepage: http://github.com/julik/ru_propisju
58
57
  licenses: []
59
-
60
58
  post_install_message:
61
- rdoc_options:
59
+ rdoc_options:
62
60
  - --main
63
61
  - README.rdoc
64
- require_paths:
62
+ require_paths:
65
63
  - lib
66
- required_ruby_version: !ruby/object:Gem::Requirement
64
+ required_ruby_version: !ruby/object:Gem::Requirement
67
65
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
75
- required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
71
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- hash: 3
81
- segments:
82
- - 0
83
- version: "0"
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
84
76
  requirements: []
85
-
86
77
  rubyforge_project: ru_propisju
87
- rubygems_version: 1.4.1
78
+ rubygems_version: 1.8.5
88
79
  signing_key:
89
80
  specification_version: 3
90
- summary: "\xD0\x92\xD1\x8B\xD0\xB2\xD0\xBE\xD0\xB4\xD0\xB8\xD1\x82 \xD1\x81\xD1\x83\xD0\xBC\xD0\xBC\xD1\x83 \xD0\xBF\xD1\x80\xD0\xBE\xD0\xBF\xD0\xB8\xD1\x81\xD1\x8C\xD1\x8E \xD0\xB8 \xD1\x81\xD1\x83\xD0\xBC\xD0\xBC\xD1\x8B \xD0\xBA\xD0\xBE\xD0\xBF\xD0\xB5\xD0\xB5\xD0\xBA, \xD1\x80\xD1\x83\xD0\xB1\xD0\xBB\xD0\xB5\xD0\xB9 \xD0\xB8 \xD0\xB3\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD0\xBD"
91
- test_files:
81
+ summary: !binary |-
82
+ 0JLRi9Cy0L7QtNC40YIg0YHRg9C80LzRgyDQv9GA0L7Qv9C40YHRjNGOINC4
83
+ INGB0YPQvNC80Ysg0LrQvtC/0LXQtdC6LCDRgNGD0LHQu9C10Lkg0Lgg0LPR
84
+ gNC40LLQtdC9
85
+ test_files:
92
86
  - test/test_ru_propisju.rb