number_to_words_ru 0.2.3 → 0.3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.rdoc +68 -0
  3. data/lib/initializers/i18n.rb +1 -1
  4. data/lib/locales/numbers.en.yml +2 -3
  5. data/lib/locales/plurals.rb +24 -16
  6. data/lib/numbers_and_words/array_additions/helpers.rb +50 -0
  7. data/lib/numbers_and_words/array_additions/validations.rb +9 -0
  8. data/lib/numbers_and_words/array_additions.rb +2 -0
  9. data/lib/numbers_and_words/core_ext/array.rb +9 -0
  10. data/lib/numbers_and_words/core_ext/integer.rb +12 -0
  11. data/lib/numbers_and_words/figures_array.rb +15 -0
  12. data/lib/{number_to_words_ru → numbers_and_words}/pluralization.rb +0 -0
  13. data/lib/numbers_and_words/strategies/base.rb +11 -0
  14. data/lib/numbers_and_words/strategies/en.rb +71 -0
  15. data/lib/numbers_and_words/strategies/ru.rb +71 -0
  16. data/lib/numbers_and_words/strategies.rb +3 -0
  17. data/lib/numbers_and_words/translations_helpers/base.rb +11 -0
  18. data/lib/numbers_and_words/translations_helpers/en.rb +41 -0
  19. data/lib/numbers_and_words/translations_helpers/ru.rb +41 -0
  20. data/lib/numbers_and_words/translations_helpers.rb +3 -0
  21. data/lib/numbers_and_words/version.rb +3 -0
  22. data/lib/numbers_and_words.rb +30 -0
  23. metadata +96 -31
  24. data/lib/number_to_words_ru/array_additions/helpers.rb +0 -48
  25. data/lib/number_to_words_ru/array_additions/validations.rb +0 -7
  26. data/lib/number_to_words_ru/array_additions.rb +0 -2
  27. data/lib/number_to_words_ru/core_ext/array.rb +0 -5
  28. data/lib/number_to_words_ru/core_ext/integer.rb +0 -11
  29. data/lib/number_to_words_ru/figures_array.rb +0 -9
  30. data/lib/number_to_words_ru/strategies/base.rb +0 -10
  31. data/lib/number_to_words_ru/strategies/en.rb +0 -69
  32. data/lib/number_to_words_ru/strategies/ru.rb +0 -69
  33. data/lib/number_to_words_ru/strategies.rb +0 -3
  34. data/lib/number_to_words_ru/translations_helpers/base.rb +0 -9
  35. data/lib/number_to_words_ru/translations_helpers/en.rb +0 -37
  36. data/lib/number_to_words_ru/translations_helpers/ru.rb +0 -37
  37. data/lib/number_to_words_ru/translations_helpers.rb +0 -3
  38. data/lib/number_to_words_ru.rb +0 -26
  39. data/spec/number_to_words_ru/array/ru_spec.rb +0 -27
  40. data/spec/number_to_words_ru/integer/ru_spec.rb +0 -293
  41. data/spec/spec_helper.rb +0 -8
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2012 Kirill Lazarev
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,68 @@
1
+ == numbers_and_words {<img src="https://secure.travis-ci.org/kslazarev/numbers_and_words.png" />}[http://travis-ci.org/kslazarev/numbers_and_words]
2
+
3
+ Convert numbers to words using the I18n library.
4
+
5
+ Перевод чисел в слова при помощи библиотеки I18n.
6
+
7
+ == Supported Languages / Языки
8
+
9
+ * English
10
+ * Русский
11
+
12
+ == Examples / Примеры
13
+
14
+ I18n.with_locale(:en) { 42.to_words }
15
+ => "forty-two"
16
+
17
+ I18n.with_locale(:ru) { 42.to_words }
18
+ => "сорок два"
19
+
20
+ 21.to_words
21
+ => "twenty-one"
22
+ => "двадцать один"
23
+
24
+ 231.to_words
25
+ => "two hundred thirty-one"
26
+ => "двести тридцать один"
27
+
28
+ 4030.to_words
29
+ => "four thousand thirty"
30
+ => "четыре тысячи тридцать"
31
+
32
+ 1000100.to_words
33
+ => "one million one hundred"
34
+ => "один миллион сто"
35
+
36
+ 1000000000000000000000000000000000.to_words
37
+ => "one decillion"
38
+ => "один дециллион"
39
+
40
+ [1, 2, 3].to_words
41
+ => ["one", "two", "three"]
42
+ => ["один", "два", "три"]
43
+
44
+ [11, 22, 133].to_words
45
+ => ["eleven", "twenty-two", "one hundred thirty-three"]
46
+ => ["одиннадцать", "двадцать два", "сто тридцать три"]
47
+
48
+ == Requirements / Требования
49
+
50
+ * 1.8.7 <= Ruby (compatible with/совместимость с Ruby 1.9, JRuby and/и Rubinius);
51
+ * 0.5.0 <= I18n (earlier versions not tested/ранние версии не тестировались);
52
+
53
+ == Installation / Установка
54
+
55
+ gem install numbers_and_words
56
+
57
+ == License / Лицензия
58
+
59
+ MIT License
60
+
61
+ == Bugs and Language Support / Поправки и Новые Языки
62
+
63
+ Fork the project. Make your feature addition or bug fix with tests. Send a pull request. Bonus points for topic branches.
64
+
65
+ == Contacts / Контакты
66
+
67
+ * Kirill Lazarev (mailto:k.s.lazarev@gmail.com)
68
+ * Daniel Doubrovkine (link:http://github.com/dblock)
@@ -1,2 +1,2 @@
1
1
  require "i18n/backend/pluralization"
2
- I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
2
+ I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
@@ -1,8 +1,7 @@
1
1
  en:
2
2
  numbers:
3
- ones: [nought, one, two, three, four, five, six, seven, eight, nine]
3
+ ones: [zero, one, two, three, four, five, six, seven, eight, nine]
4
4
  teens: [ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen]
5
- tens: [nought, ten, twenty, thirty, forty, fifty, sixty, seventy, nought, ninety]
6
- union: and
5
+ tens: [zero, ten, twenty, thirty, forty, fifty, sixty, seventy, nought, ninety]
7
6
  hundreds: hundred
8
7
  mega: [ones, thousand, million, billion, trillion, quadrillion, quintillion, sextillion, septillion, octillion, nonillion, decillion]
@@ -1,22 +1,30 @@
1
- ru_rule = lambda do |count|
2
- case count
3
- when Integer
4
- case
5
- when 1 == count
6
- :one
7
- when (2..4).include?(count)
8
- :few
9
- else
10
- :many
1
+ module NumbersAndWords
2
+ module Locales
3
+ module Plurals
4
+
5
+ RU = lambda do |count|
6
+ case count
7
+ when Integer
8
+ case
9
+ when 1 == count
10
+ :one
11
+ when (2..4).include?(count)
12
+ :few
13
+ else
14
+ :many
15
+ end
16
+ else
17
+ :other
18
+ end
19
+ end
20
+
21
+ EN = lambda { |count| 1 == count ? :one : :other }
22
+
11
23
  end
12
- else
13
- :other
14
24
  end
15
25
  end
16
26
 
17
- en_rule = lambda{|count| 1 == count ? :one : :other}
18
-
19
27
  {
20
- :ru => {:i18n => {:plural => {:rule => ru_rule}}},
21
- :en => {:i18n => {:plural => {:rule => en_rule}}}
28
+ :ru => {:i18n => {:plural => {:rule => NumbersAndWords::Locales::Plurals::RU}}},
29
+ :en => {:i18n => {:plural => {:rule => NumbersAndWords::Locales::Plurals::EN}}}
22
30
  }
@@ -0,0 +1,50 @@
1
+ module NumbersAndWords
2
+ module ArrayAdditions
3
+ module Helpers
4
+ THOUSAND_CAPACITY = 1
5
+
6
+ def capacity_count
7
+ count = (self.length.to_f / 3).ceil
8
+ 1 == count ? nil : count
9
+ end
10
+
11
+ def figures_array_in_capacity capacity
12
+ self[capacity * 3, 3]
13
+ end
14
+
15
+ def number_in_capacity capacity
16
+ figures_array_in_capacity(capacity).reverse.join.to_i
17
+ end
18
+
19
+ def number_for_gender capacity
20
+ figures = figures_array_in_capacity(capacity)
21
+ teens = figures.teens
22
+ teens ? teens.join.to_i : figures.first
23
+ end
24
+
25
+ def is_a_thousand_capacity? capacity
26
+ THOUSAND_CAPACITY == capacity
27
+ end
28
+
29
+ def ones
30
+ self[0] if 0 < self[0].to_i
31
+ end
32
+
33
+ def teens
34
+ tens_with_ones if 1 == tens
35
+ end
36
+
37
+ def tens
38
+ self[1] if self[1] and 0 < self[1].to_i
39
+ end
40
+
41
+ def tens_with_ones
42
+ [ones, tens] if ones and tens
43
+ end
44
+
45
+ def hundreds
46
+ self[2] if 0 < self[2].to_i
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,9 @@
1
+ module NumbersAndWords
2
+ module ArrayAdditions
3
+ module Validations
4
+ def validate_figure_array!
5
+
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ require 'numbers_and_words/array_additions/helpers'
2
+ require 'numbers_and_words/array_additions/validations'
@@ -0,0 +1,9 @@
1
+ class Array
2
+ def to_words
3
+ map &:to_words
4
+ end
5
+
6
+ def to_figures
7
+ NumbersAndWords::FiguresArray.new self
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class Integer
2
+
3
+ def to_words
4
+ to_figures_array.to_words NumbersAndWords::Strategies::Base.factory
5
+ end
6
+
7
+ private
8
+
9
+ def to_figures_array
10
+ to_s.split(//).map(&:to_i).to_figures
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module NumbersAndWords
2
+ class FiguresArray < Array
3
+ include NumbersAndWords::ArrayAdditions::Helpers
4
+ include NumbersAndWords::ArrayAdditions::Validations
5
+
6
+ def to_words strategy, options = nil
7
+ validate_figure_array!
8
+ strategy.convert self
9
+ end
10
+
11
+ def reverse
12
+ super.to_figures
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module NumbersAndWords
2
+ module Strategies
3
+ class Base
4
+ attr_accessor :figures, :words
5
+
6
+ def self.factory
7
+ "NumbersAndWords::Strategies::#{I18n.locale.to_s.titleize}".constantize.new
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,71 @@
1
+ module NumbersAndWords
2
+ module Strategies
3
+ class En < Base
4
+ include NumbersAndWords::TranslationsHelpers::En
5
+
6
+ attr_accessor :figures_in_previous_capacity
7
+
8
+ def convert figures
9
+ @figures = figures.reverse
10
+
11
+ @words = strings
12
+ @words.empty? ? zero : @words.reverse.join(' ')
13
+ end
14
+
15
+ private
16
+
17
+ def strings
18
+ if figures.capacity_count
19
+ complex_to_words
20
+ elsif figures.hundreds
21
+ simple_hundreds_to_words
22
+ elsif figures.tens or figures.ones
23
+ simple_to_words
24
+ else
25
+ []
26
+ end
27
+ end
28
+
29
+ def complex_to_words
30
+ words = []
31
+ figures.capacity_count.times do |capacity|
32
+ number_in_capacity_by_words = save_parent_figures do |parent_figures|
33
+ @figures = parent_figures.figures_array_in_capacity(capacity)
34
+ strings
35
+ end
36
+
37
+ unless number_in_capacity_by_words.empty?
38
+ words.push translation_megs(capacity) if 0 < capacity
39
+ words += number_in_capacity_by_words
40
+ end
41
+ end
42
+ words
43
+ end
44
+
45
+ def simple_hundreds_to_words
46
+ simple_to_words + [translation_hundreds(figures.hundreds)]
47
+ end
48
+
49
+ def simple_to_words
50
+ if figures.teens
51
+ [translation_teens(figures.ones)]
52
+ elsif figures.tens
53
+ figures.ones ?
54
+ [translation_tens_with_ones(figures.tens_with_ones)] :
55
+ [translation_tens(figures.tens)]
56
+ elsif figures.ones
57
+ [translation_ones(figures.ones)]
58
+ else
59
+ []
60
+ end
61
+ end
62
+
63
+ def save_parent_figures
64
+ parent_figures = @figures
65
+ result = yield(parent_figures)
66
+ @figures = parent_figures
67
+ result
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,71 @@
1
+ module NumbersAndWords
2
+ module Strategies
3
+ class Ru < Base
4
+ include NumbersAndWords::TranslationsHelpers::Ru
5
+
6
+ def convert figures
7
+ @figures = figures.reverse
8
+ @words = strings
9
+
10
+ @words.empty? ? zero : @words.reverse.join(' ')
11
+ end
12
+
13
+ private
14
+
15
+ def strings gender = :male
16
+ if figures.capacity_count
17
+ complex_to_words
18
+ elsif figures.hundreds
19
+ simple_hundreds_to_words gender
20
+ elsif figures.tens or figures.ones
21
+ simple_to_words gender
22
+ else
23
+ []
24
+ end
25
+ end
26
+
27
+ def complex_to_words
28
+ words = []
29
+ figures.capacity_count.times do |capacity|
30
+ number_in_capacity_by_words = save_parent_figures do
31
+ @figures = figures.figures_array_in_capacity(capacity)
32
+ strings figures.is_a_thousand_capacity?(capacity) ? :female : :male
33
+ end
34
+
35
+ unless number_in_capacity_by_words.empty?
36
+ if 0 < capacity
37
+ words.push translation_megs(capacity, figures.number_for_gender(capacity))
38
+ end
39
+ words += number_in_capacity_by_words
40
+ end
41
+ end
42
+ words
43
+ end
44
+
45
+ def simple_hundreds_to_words gender
46
+ simple_to_words(gender) + [translation_hundreds(figures.hundreds)]
47
+ end
48
+
49
+ def simple_to_words gender
50
+ if figures.teens
51
+ [translation_teens(figures.ones)]
52
+ elsif figures.tens
53
+ figures.ones ?
54
+ [translation_tens_with_ones(figures.tens_with_ones, gender)] :
55
+ [translation_tens(figures.tens)]
56
+ elsif figures.ones
57
+ [translation_ones(figures.ones, gender)]
58
+ else
59
+ []
60
+ end
61
+ end
62
+
63
+ def save_parent_figures
64
+ parent_figures = @figures
65
+ result = yield
66
+ @figures = parent_figures
67
+ result
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ require 'numbers_and_words/strategies/base'
2
+ require 'numbers_and_words/strategies/ru'
3
+ require 'numbers_and_words/strategies/en'
@@ -0,0 +1,11 @@
1
+ module NumbersAndWords
2
+ module TranslationsHelpers
3
+ module Base
4
+ I18N_NAMESPACE = :numbers
5
+
6
+ def t attribute, options = {}
7
+ I18n.t attribute, options.merge(:scope => I18N_NAMESPACE)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ module NumbersAndWords
2
+ module TranslationsHelpers
3
+ module En
4
+ include NumbersAndWords::TranslationsHelpers::Base
5
+
6
+ private
7
+
8
+ def translation_teens number
9
+ t(:teens)[number]
10
+ end
11
+
12
+ def translation_tens number
13
+ t(:tens)[number]
14
+ end
15
+
16
+ def translation_ones number
17
+ t(:ones)[number]
18
+ end
19
+
20
+ def translation_tens_with_ones numbers
21
+ [translation_tens(numbers[1]), translation_ones(numbers[0])].join '-'
22
+ end
23
+
24
+ def translation_union
25
+ t :union
26
+ end
27
+
28
+ def translation_hundreds number
29
+ [t(:ones)[number], t(:hundreds)].join ' '
30
+ end
31
+
32
+ def translation_megs capacity
33
+ t(:mega)[capacity]
34
+ end
35
+
36
+ def zero
37
+ t(:ones)[0]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ module NumbersAndWords
2
+ module TranslationsHelpers
3
+ module Ru
4
+ include NumbersAndWords::TranslationsHelpers::Base
5
+
6
+ private
7
+
8
+ def translation_megs capacity, number
9
+ t translation_mega(capacity), :count => number
10
+ end
11
+
12
+ def translation_teens number
13
+ t(:teens)[number]
14
+ end
15
+
16
+ def translation_tens number
17
+ t(:tens)[number]
18
+ end
19
+
20
+ def translation_ones number, gender
21
+ t([:ones, gender].join('_'))[number]
22
+ end
23
+
24
+ def translation_tens_with_ones numbers, gender
25
+ [translation_tens(numbers[1]), translation_ones(numbers[0], gender)].join ' '
26
+ end
27
+
28
+ def translation_hundreds number
29
+ t(:hundreds)[number]
30
+ end
31
+
32
+ def translation_mega capacity
33
+ t(:mega)[capacity]
34
+ end
35
+
36
+ def zero
37
+ t(:ones_male)[0]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ require 'numbers_and_words/translations_helpers/base'
2
+ require 'numbers_and_words/translations_helpers/ru'
3
+ require 'numbers_and_words/translations_helpers/en'
@@ -0,0 +1,3 @@
1
+ module NumbersAndWords
2
+ VERSION = '0.3.0.1'
3
+ end
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'i18n'
3
+ require 'initializers/i18n'
4
+ require 'active_support/inflector'
5
+
6
+ require 'numbers_and_words/version'
7
+
8
+ require 'numbers_and_words/translations_helpers'
9
+ require 'numbers_and_words/strategies'
10
+ require 'numbers_and_words/array_additions'
11
+ require 'numbers_and_words/figures_array'
12
+
13
+ require 'numbers_and_words/core_ext/integer'
14
+ require 'numbers_and_words/core_ext/array'
15
+
16
+ module NumbersAndWords
17
+ module I18nInitialization
18
+ extend self
19
+
20
+ def init
21
+ locale_files.each { |locale_file| I18n.load_path << locale_file }
22
+ end
23
+
24
+ def locale_files
25
+ Dir[File.join(File.dirname(__FILE__), 'locales', '**/*')]
26
+ end
27
+ end
28
+ end
29
+
30
+ NumbersAndWords::I18nInitialization.init