num_words 0.2.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +20 -25
- data/lib/num_words/converter.rb +61 -55
- data/lib/num_words/version.rb +1 -1
- metadata +4 -4
- data/num_words-0.1.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcb338b276c0afbc161d4ede15bb75c6f64fd279be42066ecabb9c2c986be10c
|
4
|
+
data.tar.gz: 60b8112d1ad8729eb652d7acd893b1cd1e5aa83b5ac31a200ff8df06ca83a4a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e12980e8da746190aa011b645978741ac7c7dbc2ce5c9dc91c8fa6ebae3ca4dd57d25b81295d3d28294fc417e7ca0dc3536e45cead806363fcc62122c633442b
|
7
|
+
data.tar.gz: 42dc76855150a5c44fa7cce78d6fa401ec4e161ee6808642dfded60919d65b5ec01bee2b939b288f37ac5dd16948c556b5f79a8f7d5f9cd8af2536c58f580e5f
|
data/README.md
CHANGED
@@ -1,36 +1,31 @@
|
|
1
1
|
# NumWords
|
2
2
|
|
3
|
-
|
3
|
+
**NumWords** is a Ruby gem that converts numbers into words in multiple numbering systems, including US, European, UK, French, and Indian. It supports both integer and decimal numbers and is useful for invoices, financial documents, or any application that requires converting numeric values into readable text.
|
4
4
|
|
5
|
-
|
5
|
+
---
|
6
6
|
|
7
|
-
##
|
8
|
-
|
9
|
-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
10
|
-
|
11
|
-
Install the gem and add to the application's Gemfile by executing:
|
12
|
-
|
13
|
-
```bash
|
14
|
-
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
15
|
-
```
|
7
|
+
## Features
|
16
8
|
|
17
|
-
|
9
|
+
- Convert integers and decimals to words.
|
10
|
+
- Supports multiple country numbering systems:
|
11
|
+
- **US / American** – `thousand, million, billion`
|
12
|
+
- **European** – `thousand, million, milliard, billion`
|
13
|
+
- **UK** – `thousand, million, billion`
|
14
|
+
- **France** – `mille, million, milliard`
|
15
|
+
- **India** – `thousand, lakh, crore`
|
16
|
+
- Easy to integrate into Ruby or Rails applications.
|
17
|
+
- Supports numbers up to `duovigintillion` (10^69) in the American system.
|
18
18
|
|
19
|
-
|
20
|
-
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
21
|
-
```
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
TODO: Write usage instructions here
|
19
|
+
---
|
26
20
|
|
27
|
-
##
|
21
|
+
## Installation
|
28
22
|
|
29
|
-
|
23
|
+
### Using RubyGems
|
30
24
|
|
31
|
-
|
25
|
+
After releasing your gem to [RubyGems.org](https://rubygems.org), install it with:
|
32
26
|
|
33
|
-
|
27
|
+
```bash
|
28
|
+
# Using Bundler
|
29
|
+
bundle add num_words
|
34
30
|
|
35
|
-
|
36
|
-
# num_words
|
31
|
+
bundle add num_words
|
data/lib/num_words/converter.rb
CHANGED
@@ -2,70 +2,69 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module NumWords
|
5
|
-
|
6
|
-
|
5
|
+
# --- English words ---
|
6
|
+
ONES_EN = %w[zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
|
7
|
+
TENS_EN = %w[zero ten twenty thirty forty fifty sixty seventy eighty ninety].freeze
|
7
8
|
|
9
|
+
# --- Hindi words ---
|
10
|
+
ONES_HI = %w[शून्य एक दो तीन चार पाँच छह सात आठ नौ दस ग्यारह बारह तेरह चौदह पंद्रह सोलह सत्रह अठारह उन्नीस].freeze
|
11
|
+
TENS_HI = %w[शून्य दस बीस तीस चालीस पचास साठ सत्तर अस्सी नब्बे].freeze
|
12
|
+
INDIAN_UNITS_HI = ['', 'हज़ार', 'लाख', 'करोड़', 'अरब', 'खरब'].freeze
|
13
|
+
|
14
|
+
# --- English exponents ---
|
8
15
|
AM_EXPONENTS = {
|
9
16
|
3 => 'thousand', 6 => 'million', 9 => 'billion', 12 => 'trillion',
|
10
17
|
15 => 'quadrillion', 18 => 'quintillion', 21 => 'sexillion', 24 => 'septillion',
|
11
|
-
27 => 'octillion', 30 => 'nonillion', 33 => 'decillion', 36 => 'undecillion'
|
12
|
-
39 => 'duodecillion', 42 => 'tredecillion', 45 => 'quattuordecillion', 48 => 'quindecillion',
|
13
|
-
51 => 'sexdecillion', 54 => 'septendecillion', 57 => 'octodecillion', 60 => 'novemdecillion',
|
14
|
-
63 => 'vigintillion', 66 => 'unvigintillion', 69 => 'duovigintillion'
|
15
|
-
}.freeze
|
16
|
-
|
17
|
-
EU_EXPONENTS = {
|
18
|
-
3 => 'thousand', 6 => 'million', 9 => 'milliard', 12 => 'billion',
|
19
|
-
15 => 'billiard', 18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion',
|
20
|
-
27 => 'quadrilliard', 30 => 'quintillion', 33 => 'quintilliard', 36 => 'sextillion',
|
21
|
-
39 => 'sextilliard', 42 => 'septillion', 45 => 'septilliard', 48 => 'octillion',
|
22
|
-
51 => 'octilliard', 54 => 'noventillion', 57 => 'noventilliard', 60 => 'decillion',
|
23
|
-
63 => 'decilliard', 66 => 'undecillion', 69 => 'undecilliard'
|
18
|
+
27 => 'octillion', 30 => 'nonillion', 33 => 'decillion', 36 => 'undecillion'
|
24
19
|
}.freeze
|
25
20
|
|
26
|
-
|
27
|
-
3 => 'thousand', 6 => 'million', 12 => 'billion', 15 => 'billiard',
|
28
|
-
18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion'
|
29
|
-
}.freeze
|
30
|
-
|
31
|
-
FR_EXPONENTS = {
|
32
|
-
3 => 'mille', 6 => 'million', 9 => 'milliard', 12 => 'billion',
|
33
|
-
15 => 'billiard', 18 => 'trillion', 21 => 'trilliard'
|
34
|
-
}.freeze
|
35
|
-
|
36
|
-
INDIAN_UNITS = ['', 'thousand', 'lakh', 'crore'].freeze
|
21
|
+
INDIAN_UNITS_EN = ['', 'thousand', 'lakh', 'crore', 'arab', 'kharab'].freeze
|
37
22
|
|
38
23
|
COUNTRY_EXPONENTS = {
|
39
24
|
us: AM_EXPONENTS,
|
40
|
-
|
41
|
-
uk: UK_EXPONENTS,
|
42
|
-
fr: FR_EXPONENTS,
|
43
|
-
in: INDIAN_UNITS
|
25
|
+
in: INDIAN_UNITS_EN
|
44
26
|
}.freeze
|
45
27
|
|
46
28
|
class << self
|
47
|
-
|
48
|
-
|
29
|
+
# Main method: convert number to words
|
30
|
+
# language: :en or :hi
|
31
|
+
def to_words(number, country: :us, language: :en, include_and: true)
|
32
|
+
if [:in].include?(country) && language == :hi
|
33
|
+
return to_words_indian(number, language: language)
|
34
|
+
end
|
49
35
|
|
50
36
|
val = number.to_i.abs
|
51
37
|
return 'zero' if val.zero?
|
52
38
|
|
53
39
|
exp_hash = COUNTRY_EXPONENTS[country] || AM_EXPONENTS
|
54
|
-
|
40
|
+
ones_array = language == :hi ? ONES_HI : ONES_EN
|
41
|
+
tens_array = language == :hi ? TENS_HI : TENS_EN
|
42
|
+
units = language == :hi ? INDIAN_UNITS_HI : INDIAN_UNITS_EN
|
43
|
+
|
44
|
+
if country == :in
|
45
|
+
to_words_indian(number, language: language)
|
46
|
+
else
|
47
|
+
to_words_generic(val, exp_hash, include_and, ones_array, tens_array)
|
48
|
+
end
|
55
49
|
end
|
56
50
|
|
57
|
-
|
51
|
+
# Indian system (supports English & Hindi)
|
52
|
+
def to_words_indian(num, language: :en)
|
58
53
|
integer_part, decimal_part = num.to_s.split('.')
|
59
|
-
|
54
|
+
ones_array = language == :hi ? ONES_HI : ONES_EN
|
55
|
+
tens_array = language == :hi ? TENS_HI : TENS_EN
|
56
|
+
units = language == :hi ? INDIAN_UNITS_HI : INDIAN_UNITS_EN
|
57
|
+
|
58
|
+
integer_words = indian_units_to_words(integer_part.to_i, ones_array, tens_array, units)
|
60
59
|
return integer_words if decimal_part.nil? || decimal_part.to_i.zero?
|
61
60
|
|
62
|
-
decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i) }.join(' ')
|
61
|
+
decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i, ones_array, tens_array) }.join(' ')
|
63
62
|
"#{integer_words} and #{decimal_words}"
|
64
63
|
end
|
65
64
|
|
66
65
|
private
|
67
66
|
|
68
|
-
def to_words_generic(val, exp_hash, include_and)
|
67
|
+
def to_words_generic(val, exp_hash, include_and, ones_array, tens_array)
|
69
68
|
chunks = []
|
70
69
|
while val.positive?
|
71
70
|
chunks << val % 1000
|
@@ -75,55 +74,62 @@ module NumWords
|
|
75
74
|
result = []
|
76
75
|
chunks.each_with_index do |chunk, index|
|
77
76
|
next if chunk.zero?
|
78
|
-
words = hundreds_to_words(chunk, include_and && index.zero
|
77
|
+
words = hundreds_to_words(chunk, include_and && index.zero?, ones_array, tens_array)
|
79
78
|
result.unshift("#{words} #{exp_hash[index * 3]}".strip)
|
80
79
|
end
|
81
80
|
result.join(' ').strip
|
82
81
|
end
|
83
82
|
|
84
|
-
def hundreds_to_words(val, include_and
|
83
|
+
def hundreds_to_words(val, include_and, ones_array, tens_array)
|
85
84
|
return '' if val.zero?
|
86
85
|
|
87
86
|
words = []
|
88
87
|
if val >= 100
|
89
|
-
words << "#{
|
88
|
+
words << "#{ones_array[val / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}"
|
90
89
|
val %= 100
|
91
|
-
words << 'and' if val.positive? && include_and
|
90
|
+
words << 'and' if val.positive? && include_and && ones_array != ONES_HI
|
92
91
|
end
|
93
92
|
|
94
|
-
words <<
|
93
|
+
words << tens_array[val / 10] if val >= 20
|
95
94
|
val %= 10 if val >= 20
|
96
|
-
words <<
|
95
|
+
words << ones_array[val] if val.positive?
|
97
96
|
words.join(' ').strip
|
98
97
|
end
|
99
98
|
|
100
|
-
def indian_units_to_words(num)
|
99
|
+
def indian_units_to_words(num, ones_array, tens_array, units)
|
101
100
|
num = num.to_i
|
102
|
-
return
|
101
|
+
return ones_array[0] if num.zero?
|
102
|
+
|
103
103
|
words = []
|
104
104
|
unit_index = 0
|
105
105
|
|
106
106
|
loop do
|
107
107
|
break if num.zero?
|
108
|
-
|
109
108
|
num, remainder = unit_index.zero? ? num.divmod(1000) : num.divmod(100)
|
110
|
-
words.unshift("#{sub_thousand_to_words(remainder)} #{
|
109
|
+
words.unshift("#{sub_thousand_to_words(remainder, ones_array, tens_array)} #{units[unit_index]}".strip) if remainder.positive?
|
111
110
|
unit_index += 1
|
112
111
|
end
|
113
112
|
|
114
113
|
words.join(' ').strip
|
115
114
|
end
|
116
115
|
|
117
|
-
def sub_thousand_to_words(num)
|
118
|
-
num
|
119
|
-
return
|
120
|
-
return "#{ONES[num / 100]} hundred" if num >= 100 && (num % 100).zero?
|
116
|
+
def sub_thousand_to_words(num, ones_array, tens_array)
|
117
|
+
return ones_array[num] if num < 20
|
118
|
+
return "#{ones_array[num / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}" if num >= 100 && (num % 100).zero?
|
121
119
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
120
|
+
words = []
|
121
|
+
if num >= 100
|
122
|
+
words << "#{ones_array[num / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}"
|
123
|
+
num %= 100
|
124
|
+
end
|
125
|
+
|
126
|
+
if num >= 20
|
127
|
+
words << tens_array[num / 10]
|
128
|
+
num %= 10
|
126
129
|
end
|
130
|
+
|
131
|
+
words << ones_array[num] if num.positive?
|
132
|
+
words.join(' ').strip
|
127
133
|
end
|
128
134
|
end
|
129
135
|
end
|
data/lib/num_words/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: num_words
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mrmalvi
|
@@ -24,10 +24,10 @@ files:
|
|
24
24
|
- lib/num_words.rb
|
25
25
|
- lib/num_words/converter.rb
|
26
26
|
- lib/num_words/version.rb
|
27
|
-
- num_words-0.1.0.gem
|
28
27
|
- sig/num_words.rbs
|
29
28
|
homepage: https://github.com/mrmalvi/num_words
|
30
|
-
licenses:
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
31
|
metadata:
|
32
32
|
allowed_push_host: https://rubygems.org
|
33
33
|
homepage_uri: https://github.com/mrmalvi/num_words
|
@@ -39,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
39
|
requirements:
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 2.7.0
|
43
43
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
data/num_words-0.1.0.gem
DELETED
Binary file
|