ada_numbers 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 687cb405cfb56c733e1f7744a14999e22bc15ef11ae93c3163522c2a1dbe2e0f
4
+ data.tar.gz: 6324a7fe749ed13b5589ce8c180758ff46415f1427981ea10ac49c3a12506e6e
5
+ SHA512:
6
+ metadata.gz: a3be0a5c634712132d807f58524629ce698a74447745394380ff082aec034cb95cb1466859f62b826068a971e583fe941046d0ddec091b9a1ebcf1570ec3299d
7
+ data.tar.gz: 9b6d9d02c84bd66f179bdf6002c65fd8bcb21d8cf816034ddb74fb91c4f7544062f63b655b5e8430fb90c6dd383bc6338a72c93ff451062f607b15c9122071fc
data/.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
6
+ <component name="NewModuleRootManager">
7
+ <content url="file://$MODULE_DIR$">
8
+ <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
9
+ <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
10
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
+ </content>
12
+ <orderEntry type="jdk" jdkName="rbenv: 2.7.7" jdkType="RUBY_SDK" />
13
+ <orderEntry type="sourceFolder" forTests="false" />
14
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, rbenv: 2.7.7) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.18.0, rbenv: 2.7.7) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="rake (v12.3.3, rbenv: 2.7.7) [gem]" level="application" />
17
+ </component>
18
+ <component name="RakeTasksCache">
19
+ <option name="myRootTask">
20
+ <RakeTaskImpl id="rake">
21
+ <subtasks>
22
+ <RakeTaskImpl description="Build ada_numbers-0.1.0.gem into the pkg directory" fullCommand="build" id="build" />
23
+ <RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
24
+ <RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
25
+ <RakeTaskImpl description="Build and install ada_numbers-0.1.0.gem into system gems" fullCommand="install" id="install" />
26
+ <RakeTaskImpl id="install">
27
+ <subtasks>
28
+ <RakeTaskImpl description="Build and install ada_numbers-0.1.0.gem into system gems without network access" fullCommand="install:local" id="local" />
29
+ </subtasks>
30
+ </RakeTaskImpl>
31
+ <RakeTaskImpl description="Create tag v0.1.0 and build and push ada_numbers-0.1.0.gem to rubygems.org" fullCommand="release[remote]" id="release[remote]" />
32
+ <RakeTaskImpl description="Run tests" fullCommand="test" id="test" />
33
+ <RakeTaskImpl description="" fullCommand="default" id="default" />
34
+ <RakeTaskImpl description="" fullCommand="release" id="release" />
35
+ <RakeTaskImpl id="release">
36
+ <subtasks>
37
+ <RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
38
+ <RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
39
+ <RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
40
+ </subtasks>
41
+ </RakeTaskImpl>
42
+ </subtasks>
43
+ </RakeTaskImpl>
44
+ </option>
45
+ </component>
46
+ </module>
data/.idea/modules.xml ADDED
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/ada_numbers.iml" filepath="$PROJECT_DIR$/.idea/ada_numbers.iml" />
6
+ <module fileurl="file://$PROJECT_DIR$/../.idea/ada_numbers_gem.iml" filepath="$PROJECT_DIR$/../.idea/ada_numbers_gem.iml" />
7
+ </modules>
8
+ </component>
9
+ </project>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
5
+ </component>
6
+ </project>
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ada_numbers.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "minitest", "~> 5.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ada_numbers (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.18.0)
10
+ rake (12.3.3)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ ada_numbers!
17
+ minitest (~> 5.0)
18
+ rake (~> 12.0)
19
+
20
+ BUNDLED WITH
21
+ 2.1.4
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,30 @@
1
+ require_relative 'lib/ada_numbers/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "ada_numbers"
5
+ spec.version = AdaNumbers::VERSION
6
+ spec.authors = ["Roberto W. P. Ribeiro"]
7
+ spec.email = ["rober.will@hotmail.com"]
8
+
9
+ spec.summary = %q{It converts a number to its equivalent in written words,
10
+ i.e. 123 to "cento e vinte três" or to "one hundred and twenty-three", and vice versa.}
11
+ spec.description = %q{It converts a number to its equivalent in written words,
12
+ i.e. 123 to "cento e vinte três" or to "one hundred and twenty-three", and vice versa.}
13
+ spec.homepage = "https://github.com/roberwil/ada_numbers_gem"
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/roberwil/ada_numbers_gem"
18
+ spec.metadata["changelog_uri"] = "https://github.com/roberwil/ada_numbers_gem/blob/main/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+ spec.license = "MIT"
30
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ada_numbers"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ module AdaNumbers
2
+ module Separator
3
+ class En
4
+ NUMBERS_SEPARATOR = "And"
5
+ DECIMAL_SEPARATOR = "Point"
6
+ DECIMAL_SEPARATOR_ALTERNATIVE = "Comma"
7
+ COMMA = ","
8
+ DASH = "-"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,113 @@
1
+ module AdaNumbers
2
+ module WrittenNumber
3
+ class En
4
+ ZERO = "Zero"
5
+ ONE = "One"
6
+ TWO = "Two"
7
+ THREE = "Three"
8
+ FOUR = "Four"
9
+ FIVE = "Five"
10
+ SIX = "Six"
11
+ SEVEN = "Seven"
12
+ EIGHT = "Eight"
13
+ NINE = "Nine"
14
+ TEN = "Ten"
15
+ ELEVEN = "Eleven"
16
+ TWELVE = "Twelve"
17
+ THIRTEEN = "Thirteen"
18
+ FOURTEEN = "Fourteen"
19
+ FIFTEEN = "Fifteen"
20
+ SIXTEEN = "Sixteen"
21
+ SEVENTEEN = "Seventeen"
22
+ EIGHTEEN = "Eighteen"
23
+ NINETEEN = "Nineteen"
24
+ TWENTY = "Twenty"
25
+ THIRTY = "Thirty"
26
+ FORTY = "Forty"
27
+ FIFTY = "Fifty"
28
+ SIXTY = "Sixty"
29
+ SEVENTY = "Seventy"
30
+ EIGHTY = "Eighty"
31
+ NINETY = "Ninety"
32
+ HUNDRED = "Hundred"
33
+ THOUSAND = "Thousand"
34
+ MILLION = "Million"
35
+ THOUSAND_MILLION = "Thousand Million"
36
+ BILLION = "Billion"
37
+ TRILLION = "Trillion"
38
+
39
+ @@numbers_that_ignore_separator = [
40
+ HUNDRED, THOUSAND, MILLION,
41
+ THOUSAND_MILLION, BILLION, TRILLION
42
+ ]
43
+
44
+ def self.numbers_that_ignore_separator; @@numbers_that_ignore_separator; end
45
+
46
+ @@unities_that_combine_with_separator = [
47
+ TWENTY, THIRTY, FORTY, FIFTY,
48
+ SIXTY, SEVENTY, EIGHTY, NINETY
49
+ ]
50
+
51
+ def self.unities_that_combine_with_separator; @@unities_that_combine_with_separator; end
52
+
53
+ @@words_to_number_map = {
54
+ ZERO => 0, ONE => 1, TWO => 2, THREE => 3, FOUR => 4,
55
+ FIVE => 5, SIX => 6, SEVEN => 7, EIGHT => 8, NINE => 9,
56
+ TEN => 10, ELEVEN => 11, TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14,
57
+ FIFTEEN => 15, SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
58
+ TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50, SIXTY => 60,
59
+ SEVENTY => 70, EIGHTY => 80, NINETY => 90, HUNDRED => 100, THOUSAND => 1e3.to_i,
60
+ MILLION => 1e6.to_i
61
+ }
62
+
63
+ def self.words_to_number_map; @@words_to_number_map; end
64
+
65
+ @@words_to_number_unities_and_tens_map = {
66
+ ZERO => 0, ONE => 1, TWO => 2, THREE => 3, FOUR => 4,
67
+ FIVE => 5, SIX => 6, SEVEN => 7, EIGHT => 8, NINE => 9,
68
+ TEN => 10, ELEVEN => 11, TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14,
69
+ FIFTEEN => 15, SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
70
+ TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50, SIXTY => 60,
71
+ SEVENTY => 70, EIGHTY => 80, NINETY => 90
72
+ }
73
+
74
+ def self.words_to_number_unities_and_tens_map; @@words_to_number_unities_and_tens_map; end
75
+
76
+ @@words_to_number_map_long_scale = {
77
+ THOUSAND_MILLION => 1e9.to_i,
78
+ BILLION => 1e12.to_i
79
+ }
80
+
81
+ def self.words_to_number_map_long_scale; @@words_to_number_map_long_scale; end
82
+
83
+ @@words_to_number_map_short_scale = {
84
+ BILLION => 1e9.to_i,
85
+ TRILLION => 1e12.to_i
86
+ }
87
+
88
+ def self.words_to_number_map_short_scale; @@words_to_number_map_short_scale; end
89
+
90
+ @@not_to_combine_with_thousand = [
91
+ MILLION, BILLION, TRILLION
92
+ ]
93
+
94
+ def self.not_to_combine_with_thousand; @@not_to_combine_with_thousand; end
95
+
96
+ @@numbers_to_words_map_unities = {
97
+ 0 => ZERO, 1 => ONE, 2 => TWO , 3 => THREE, 4 => FOUR,
98
+ 5 => FIVE, 6 => SIX, 7 => SEVEN, 8 => EIGHT, 9 => NINE
99
+ }
100
+
101
+ def self.numbers_to_words_map_unities; @@numbers_to_words_map_unities; end
102
+
103
+ @@numbers_to_words_map_tens = {
104
+ 10 => TEN , 11 => ELEVEN , 12 => TWELVE , 13 => THIRTEEN, 14 => FOURTEEN,
105
+ 15 => FIFTEEN, 16 => SIXTEEN, 17 => SEVENTEEN, 18 => EIGHTEEN, 19 => NINETEEN,
106
+ 20 => TWENTY , 30 => THIRTY , 40 => FORTY , 50 => FIFTY , 60 => SIXTY ,
107
+ 70 => SEVENTY, 80 => EIGHTY , 90 => NINETY
108
+ }
109
+
110
+ def self.numbers_to_words_map_tens; @@numbers_to_words_map_tens; end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AdaNumbers
4
+ class Message
5
+ UNSUPPORTED = "Unsupported"
6
+ INVALID_NUMBER = "Invalid Number"
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module AdaNumbers
2
+ module Separator
3
+ class Pt
4
+ NUMBERS_SEPARATOR = "E"
5
+ DECIMAL_SEPARATOR = "Vírgula"
6
+ DECIMAL_SEPARATOR_ALTERNATIVE = "Ponto"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,116 @@
1
+ module AdaNumbers
2
+ module WrittenNumber
3
+ class Pt
4
+ ZERO = "Zero"
5
+ ONE = "Um"
6
+ TWO = "Dois"
7
+ THREE = "Três"
8
+ FOUR = "Quatro"
9
+ FIVE = "Cinco"
10
+ SIX = "Seis"
11
+ SEVEN = "Sete"
12
+ EIGHT = "Oito"
13
+ NINE = "Nove"
14
+ TEN = "Dez"
15
+ ELEVEN = "Onze"
16
+ TWELVE = "Doze"
17
+ THIRTEEN = "Treze"
18
+ FOURTEEN = "Catorze"
19
+ FIFTEEN = "Quinze"
20
+ SIXTEEN = "Dezasseis"
21
+ SEVENTEEN = "Dezassete"
22
+ EIGHTEEN = "Dezoito"
23
+ NINETEEN = "Dezanove"
24
+ TWENTY = "Vinte"
25
+ THIRTY = "Trinta"
26
+ FORTY = "Quarenta"
27
+ FIFTY = "Cinquenta"
28
+ SIXTY = "Sessenta"
29
+ SEVENTY = "Setenta"
30
+ EIGHTY = "Oitenta"
31
+ NINETY = "Noventa"
32
+ ONE_HUNDRED_SINGLE = "Cem"
33
+ ONE_HUNDRED = "Cento"
34
+ TWO_HUNDRED = "Duzentos"
35
+ THREE_HUNDRED = "Trezentos"
36
+ FOUR_HUNDRED = "Quatrocentos"
37
+ FIVE_HUNDRED = "Quinhentos"
38
+ SIX_HUNDRED = "Seiscentos"
39
+ SEVEN_HUNDRED = "Setecentos"
40
+ EIGHT_HUNDRED = "Oitocentos"
41
+ NINE_HUNDRED = "Novecentos"
42
+ THOUSAND = "Mil"
43
+ MILLION_SINGULAR = "Um Milhão"
44
+ MILLION_PLURAL = "Milhões"
45
+ THOUSAND_MILLION = "Mil Milhões"
46
+ BILLION_SINGULAR = "Um Bilião"
47
+ BILLION_PLURAL = "Biliões"
48
+ TRILLION_SINGULAR = "Um Trilião"
49
+ TRILLION_PLURAL = "Triliões"
50
+
51
+ @@numbers_that_ignore_separator = [
52
+ ONE_HUNDRED, TWO_HUNDRED, THREE_HUNDRED, FOUR_HUNDRED, FIVE_HUNDRED,
53
+ SIX_HUNDRED, SEVEN_HUNDRED, EIGHT_HUNDRED, NINE_HUNDRED, THOUSAND,
54
+ MILLION_SINGULAR, MILLION_PLURAL, THOUSAND_MILLION, BILLION_SINGULAR,
55
+ BILLION_PLURAL, TRILLION_SINGULAR, TRILLION_PLURAL
56
+ ]
57
+
58
+ def self.numbers_that_ignore_separator; @@numbers_that_ignore_separator; end
59
+
60
+ @@words_to_number_map = {
61
+ ZERO => 0, ONE => 1, TWO => 2, THREE => 3,
62
+ FOUR => 4, FIVE => 5, SIX => 6, SEVEN => 7,
63
+ EIGHT => 8, NINE => 9, TEN => 10, ELEVEN => 11,
64
+ TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14, FIFTEEN => 15,
65
+ SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
66
+ TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50,
67
+ SIXTY => 60, SEVENTY => 70, EIGHTY => 80, NINETY => 90,
68
+ ONE_HUNDRED => 100, ONE_HUNDRED_SINGLE => 100, TWO_HUNDRED => 200, THREE_HUNDRED => 300,
69
+ FOUR_HUNDRED => 400, FIVE_HUNDRED => 500, SIX_HUNDRED => 600, SEVEN_HUNDRED => 700,
70
+ EIGHT_HUNDRED => 800, NINE_HUNDRED => 900, THOUSAND => 1e3.to_i, MILLION_SINGULAR => 1e6.to_i,
71
+ MILLION_PLURAL => 1e6.to_i
72
+ }
73
+
74
+ def self.words_to_number_map; @@words_to_number_map; end
75
+
76
+ @@words_to_number_map_long_scale = {
77
+ THOUSAND_MILLION => 1e9.to_i,
78
+ BILLION_SINGULAR => 1e12.to_i,
79
+ BILLION_PLURAL => 1e12.to_i
80
+ }
81
+
82
+ def self.words_to_number_map_long_scale; @@words_to_number_map_long_scale; end
83
+
84
+ @@words_to_number_map_short_scale = {
85
+ BILLION_SINGULAR => 1e9.to_i,
86
+ BILLION_PLURAL => 1e9.to_i,
87
+ TRILLION_SINGULAR => 1e12.to_i,
88
+ TRILLION_PLURAL => 1e12.to_i
89
+ }
90
+
91
+ def self.words_to_number_map_short_scale; @@words_to_number_map_short_scale; end
92
+
93
+ @@not_to_combine_with_thousand = [
94
+ MILLION_SINGULAR, BILLION_PLURAL, TRILLION_PLURAL
95
+ ]
96
+
97
+ def self.not_to_combine_with_thousand; @@not_to_combine_with_thousand; end
98
+
99
+ @@numbers_to_words_map_unities = {
100
+ 0 => ZERO, 1 => ONE, 2 => TWO , 3 => THREE, 4 => FOUR,
101
+ 5 => FIVE, 6 => SIX, 7 => SEVEN, 8 => EIGHT, 9 => NINE
102
+ }
103
+
104
+ def self.numbers_to_words_map_unities; @@numbers_to_words_map_unities; end
105
+
106
+ @@numbers_to_words_map_tens = {
107
+ 10 => TEN , 11 => ELEVEN , 12 => TWELVE , 13 => THIRTEEN, 14 => FOURTEEN,
108
+ 15 => FIFTEEN, 16 => SIXTEEN, 17 => SEVENTEEN, 18 => EIGHTEEN, 19 => NINETEEN,
109
+ 20 => TWENTY , 30 => THIRTY , 40 => FORTY , 50 => FIFTY , 60 => SIXTY ,
110
+ 70 => SEVENTY, 80 => EIGHTY , 90 => NINETY
111
+ }
112
+
113
+ def self.numbers_to_words_map_tens; @@numbers_to_words_map_tens; end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,185 @@
1
+ require_relative '../../utilities/integer_extensions'
2
+ require_relative '../../utilities/hash_extensions'
3
+ require_relative '../../utilities/settings'
4
+ require_relative '../../utilities/number_category'
5
+
6
+ require_relative '../../constants/en/written_numbers'
7
+ require_relative '../../constants/en/separators'
8
+ require_relative '../../constants/message'
9
+
10
+ module AdaNumbers
11
+ module NumberToWordsConverter
12
+ class En
13
+ @@use_short_scale = false
14
+ @@number_tokens = []
15
+
16
+ def self.convert(number)
17
+ return convert_integer(number) if number.class == Integer
18
+ return convert_float(number)
19
+ end
20
+
21
+ private
22
+
23
+ def self.convert_integer(number)
24
+ return Message::UNSUPPORTED if number.number_of_digits > Settings::Parameters::DIGITS_LIMIT
25
+
26
+ select_scale
27
+ @@number_tokens.clear
28
+ return resolve_number number
29
+ end
30
+
31
+ def self.convert_float(number)
32
+ select_scale
33
+
34
+ str_number = number.to_s.split '.'
35
+
36
+ str_integer_part = str_number.first
37
+ str_decimal_part = str_number.size == 1 ? "0" : str_number.last
38
+
39
+ return Message::UNSUPPORTED if str_integer_part.size > Settings::Parameters::DIGITS_LIMIT || str_decimal_part.size > Settings::Parameters::DIGITS_LIMIT
40
+
41
+ whole_part = str_integer_part.to_i
42
+ decimal_part = str_decimal_part.to_i
43
+
44
+ @@number_tokens.clear
45
+ result = resolve_number whole_part
46
+
47
+ return result if decimal_part == 0
48
+
49
+ result += " #{Separator::En::DECIMAL_SEPARATOR.downcase} "
50
+ # just aggregating the zeros
51
+ result += str_decimal_part.split('').
52
+ take_while { |c| c == "0" }.
53
+ collect { |c| WrittenNumber::En::ZERO }.
54
+ join ' '
55
+
56
+ @@number_tokens.clear
57
+ result += result[-1] == ' ' ? resolve_number(decimal_part) :
58
+ " #{resolve_number(decimal_part)}"
59
+
60
+ return result
61
+ end
62
+
63
+ def self.select_scale
64
+ @@use_short_scale = Settings.scale == Settings::Parameters::SCALES[:short]
65
+ end
66
+
67
+ def self.resolve_number(number)
68
+ result = ''
69
+ number_category = number.category
70
+
71
+ case number_category
72
+ when NumberCategory::UNITY
73
+ result = unities number
74
+ when NumberCategory::TEN
75
+ result = tens number
76
+ when NumberCategory::HUNDRED
77
+ result = hundreds number
78
+ when NumberCategory::THOUSAND
79
+ result = thousands number
80
+ when NumberCategory::MILLION
81
+ result = millions number
82
+ when NumberCategory::THOUSAND_MILLIONS
83
+ result = thousand_millions number
84
+ when NumberCategory::BILLION
85
+ result = billions number
86
+ end
87
+
88
+ if result.empty?
89
+ str_number = number.to_s
90
+ bridge = number.bridge
91
+
92
+ first_digits = (str_number[0...bridge] + '0' * number_category).to_i
93
+ other_digits = (str_number[bridge..-1]).to_i
94
+
95
+ resolve_number first_digits
96
+ resolve_number other_digits
97
+ else
98
+ @@number_tokens << result
99
+ end
100
+
101
+ add_separators_to_number @@number_tokens
102
+ end
103
+
104
+ def self.unity_or_ten?(number)
105
+ result = !WrittenNumber::En.words_to_number_unities_and_tens_map.resolve(number).nil?
106
+ result ? result : number.include?(Separator::En::DASH)
107
+ end
108
+
109
+ def self.add_separators_to_number(number_tokens)
110
+ result = number_tokens.first
111
+
112
+ (1...number_tokens.size).each do |cursor|
113
+ current_token = number_tokens[cursor]
114
+
115
+ is_hundred = cursor + 1 < number_tokens.size && unity_or_ten?(current_token) &&
116
+ (number_tokens[cursor + 1] == WrittenNumber::En::HUNDRED ||
117
+ number_tokens[cursor + 1] == WrittenNumber::En::THOUSAND ||
118
+ number_tokens[cursor + 1] == WrittenNumber::En::MILLION ||
119
+ number_tokens[cursor + 1] == WrittenNumber::En::THOUSAND_MILLION ||
120
+ number_tokens[cursor + 1] == WrittenNumber::En::BILLION ||
121
+ number_tokens[cursor + 1] == WrittenNumber::En::TRILLION)
122
+
123
+ add_comma = cursor > 1 && is_hundred
124
+ no_separator = WrittenNumber::En.numbers_that_ignore_separator.include?(current_token) || is_hundred
125
+
126
+ if (add_comma)
127
+ result += "#{Separator::En::COMMA} #{current_token}"
128
+ elsif no_separator
129
+ result += " #{current_token}"
130
+ else
131
+ result += " #{Separator::En::NUMBERS_SEPARATOR.downcase} #{current_token}"
132
+ end
133
+ end
134
+
135
+ return result
136
+ end
137
+
138
+ def self.unities(number)
139
+ WrittenNumber::En.numbers_to_words_map_unities.resolve number
140
+ end
141
+
142
+ def self.tens(number)
143
+ result = WrittenNumber::En.numbers_to_words_map_tens.resolve number
144
+ return result if result != ''
145
+
146
+ bridge = number.bridge
147
+ ten = number.to_s[0...bridge].to_i * 10
148
+ unity = number.to_s[bridge..-1].to_i
149
+
150
+ result = "#{tens(ten)}#{Separator::En::DASH}#{unities(unity).downcase}"
151
+ result
152
+ end
153
+
154
+ def self.hundreds(number)
155
+ evaluate_hundreds_and_over number, 1e2.to_i, WrittenNumber::En::HUNDRED
156
+ end
157
+
158
+ def self.thousands(number)
159
+ evaluate_hundreds_and_over number, 1e3.to_i, WrittenNumber::En::THOUSAND
160
+ end
161
+
162
+ def self.millions(number)
163
+ evaluate_hundreds_and_over number, 1e6.to_i, WrittenNumber::En::MILLION
164
+ end
165
+
166
+ def self.thousand_millions(number)
167
+ qualifier = (@@use_short_scale ? WrittenNumber::En::BILLION : WrittenNumber::En::THOUSAND_MILLION)
168
+ evaluate_hundreds_and_over number, 1e9.to_i, qualifier
169
+ end
170
+
171
+ def self.billions(number)
172
+ qualifier = (@@use_short_scale ? WrittenNumber::En::TRILLION : WrittenNumber::En::BILLION)
173
+ evaluate_hundreds_and_over number, 1e12.to_i, qualifier
174
+ end
175
+
176
+ def self.evaluate_hundreds_and_over(number, category_identifier, qualifier)
177
+ return '' if number % category_identifier != 0
178
+
179
+ partial_number = number.to_s[0...number.bridge].to_i
180
+ resolve_number partial_number
181
+ return qualifier
182
+ end
183
+ end
184
+ end
185
+ end