number_to 0.7.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 +7 -0
- data/lib/modules/alphabetics.rb +23 -0
- data/lib/modules/number_words.rb +168 -0
- data/lib/modules/ordinals.rb +20 -0
- data/lib/modules/roman_numerals.rb +33 -0
- data/lib/number_to/fixnum.rb +24 -0
- data/lib/number_to.rb +11 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c0a68f0393aaa50be1a3f8252373cae857d42068
|
4
|
+
data.tar.gz: 1966aa6f80a2de113df09b88b3361b21ce90366a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 257dd29a7ab46c33499bd7577f4580266c6d40fa2cad09ea75cf4bffe85e3ac6feb23a182899f8ae41384f7a2bc5ea73d6020ccb98fd5d623ee92858ad4ad0e4
|
7
|
+
data.tar.gz: ef633b1dbf356e0164cd5e63b55f41e59bc1731e621c32a9b220824cd1bb9a4e8de2703fe5f0248ca680c9fbe114c6110743c6f532db2ccda8768e64284b035d
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Alphabetics
|
2
|
+
def to_upper_alpha(num)
|
3
|
+
to_lower_alpha(num).upcase
|
4
|
+
end
|
5
|
+
|
6
|
+
def to_lower_alpha(num)
|
7
|
+
num_to_alph(num)
|
8
|
+
end
|
9
|
+
|
10
|
+
ALPH = ("a" .. "z").to_a
|
11
|
+
|
12
|
+
def num_to_alph(num)
|
13
|
+
num = num.to_i
|
14
|
+
repetition = num > 26 ? calc_repetition(num) : 1
|
15
|
+
real_num = num > 26 ? num % 26 : num
|
16
|
+
real_num = 26 if real_num == 0
|
17
|
+
ALPH[real_num - 1] * repetition
|
18
|
+
end
|
19
|
+
|
20
|
+
def calc_repetition(num)
|
21
|
+
num % 26 == 0 ? num / 26 : (num / 26) + 1
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module NumberWords
|
2
|
+
|
3
|
+
WORDS = {
|
4
|
+
'0' => 'zero',
|
5
|
+
'1' => 'one',
|
6
|
+
'2' => 'two',
|
7
|
+
'3' => 'three',
|
8
|
+
'4' => 'four',
|
9
|
+
'5' => 'five',
|
10
|
+
'6' => 'six',
|
11
|
+
'7' => 'seven',
|
12
|
+
'8' => 'eight',
|
13
|
+
'9' => 'nine',
|
14
|
+
'10' => 'ten',
|
15
|
+
'11' => 'eleven',
|
16
|
+
'12' => 'twelve',
|
17
|
+
'13' => 'thirteen',
|
18
|
+
'14' => 'fourteen',
|
19
|
+
'15' => 'fifteen',
|
20
|
+
'16' => 'sixteen',
|
21
|
+
'17' => 'seventeen',
|
22
|
+
'18' => 'eighteen',
|
23
|
+
'19' => 'nineteen',
|
24
|
+
'20' => 'twenty',
|
25
|
+
'30' => 'thirty',
|
26
|
+
'40' => 'forty',
|
27
|
+
'50' => 'fifty',
|
28
|
+
'60' => 'sixty',
|
29
|
+
'70' => 'seventy',
|
30
|
+
'80' => 'eighty',
|
31
|
+
'90' => 'ninety'
|
32
|
+
}
|
33
|
+
LARGE_NUMS = {
|
34
|
+
1 => 'thousand',
|
35
|
+
2 => 'million',
|
36
|
+
3 => 'billion',
|
37
|
+
4 => 'trillion'
|
38
|
+
}
|
39
|
+
ORDINALS = {
|
40
|
+
'one' => 'first',
|
41
|
+
'two' => 'second',
|
42
|
+
'three' => 'third',
|
43
|
+
'four' => 'fourth',
|
44
|
+
'five' => 'fifth',
|
45
|
+
'six' => 'sixth',
|
46
|
+
'seven' => 'seventh',
|
47
|
+
'eight' => 'eighth',
|
48
|
+
'nine' => 'ninth',
|
49
|
+
'One' => 'First',
|
50
|
+
'Two' => 'Second',
|
51
|
+
'Three' => 'Third',
|
52
|
+
'Four' => 'Fourth',
|
53
|
+
'Five' => 'Fifth',
|
54
|
+
'Six' => 'Sixth',
|
55
|
+
'Seven' => 'Seventh',
|
56
|
+
'Eight' => 'Eighth',
|
57
|
+
'Nine' => 'Ninth'
|
58
|
+
}
|
59
|
+
|
60
|
+
def to_words(num, options = {})
|
61
|
+
NumbersToWords.new(num, options).to_words
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_word_ordinal(num, options = {})
|
65
|
+
text = NumbersToWords.new(num, options).to_words
|
66
|
+
change_last_word(text)
|
67
|
+
end
|
68
|
+
|
69
|
+
def change_last_word(text)
|
70
|
+
words = text.split(/(\W)/)
|
71
|
+
last = words[words.size - 1]
|
72
|
+
new_last = ordinal_word(last)
|
73
|
+
words[words.size - 1] = new_last
|
74
|
+
words.join
|
75
|
+
end
|
76
|
+
|
77
|
+
def ordinal_word(word)
|
78
|
+
ORDINALS[word] || word += 'th'
|
79
|
+
end
|
80
|
+
|
81
|
+
class NumbersToWords
|
82
|
+
attr_reader :num, :options
|
83
|
+
attr_reader :hundred, :large_nums
|
84
|
+
DEFAULTS = {styled: false, case: 'lower', space: ' '}
|
85
|
+
|
86
|
+
def initialize(num, options = {})
|
87
|
+
@num = num.to_s
|
88
|
+
@options = DEFAULTS.merge(options)
|
89
|
+
set_style_opts
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_style_opts
|
93
|
+
@hundred = options[:styled] ? 'hundred and' : 'hundred'
|
94
|
+
@large_nums = options[:styled] ? large_nums_with_commas : LARGE_NUMS
|
95
|
+
end
|
96
|
+
|
97
|
+
def large_nums_with_commas
|
98
|
+
large_nums = LARGE_NUMS.dup
|
99
|
+
large_nums.each { |k,v| large_nums[k] = "#{v}," }
|
100
|
+
large_nums
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_words
|
104
|
+
arr = num.each_char.to_a
|
105
|
+
groups = arr.reverse.each_slice(3).to_a
|
106
|
+
collector = words_for_groups(groups)
|
107
|
+
formatted_words(collector)
|
108
|
+
end
|
109
|
+
|
110
|
+
def formatted_words(collector)
|
111
|
+
words = collector.reverse.join(options[:space]).gsub(/,$/,'')
|
112
|
+
return words unless options[:case] == 'upper'
|
113
|
+
words.split(/(\W)/).map(&:capitalize).join.gsub(/ and/i, ' and')
|
114
|
+
end
|
115
|
+
|
116
|
+
def words_for_groups(groups)
|
117
|
+
collector = []
|
118
|
+
groups.each_with_index do |group, i|
|
119
|
+
next if group.all? { |e| e == '0' }
|
120
|
+
rearrange_group(group)
|
121
|
+
words = word_group(group, i)
|
122
|
+
collector << words
|
123
|
+
end
|
124
|
+
collector
|
125
|
+
end
|
126
|
+
|
127
|
+
def rearrange_group(group)
|
128
|
+
group.reverse!
|
129
|
+
group.shift while group.first == '0'
|
130
|
+
end
|
131
|
+
|
132
|
+
def word_group(group, i)
|
133
|
+
words = basic_word_group(group)
|
134
|
+
words += options[:space] + large_nums[i] if large_nums[i]
|
135
|
+
words
|
136
|
+
end
|
137
|
+
|
138
|
+
def basic_word_group(group)
|
139
|
+
case group.size
|
140
|
+
when 0; ''
|
141
|
+
when 1; WORDS[group[0]]
|
142
|
+
when 2; tenner(group[0], group[1])
|
143
|
+
when 3; hundreder(group)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def hundreder(group)
|
148
|
+
tens = tenner(group[1], group[2])
|
149
|
+
hundred_joiner = tens.empty? ? 'hundred' : hundred
|
150
|
+
[WORDS[group[0]],
|
151
|
+
hundred_joiner,
|
152
|
+
tens
|
153
|
+
].reject { |n| n.empty? }.join(options[:space])
|
154
|
+
end
|
155
|
+
|
156
|
+
def tenner(first, second)
|
157
|
+
return '' if first == '0' and second == '0'
|
158
|
+
return WORDS[second] if first == '0' and second != '0'
|
159
|
+
return WORDS[first + second] if first == '1' or second == '0'
|
160
|
+
joined_tenner(first, second)
|
161
|
+
end
|
162
|
+
|
163
|
+
def joined_tenner(first, second)
|
164
|
+
joiner = options[:styled] ? '-' : options[:space]
|
165
|
+
WORDS[first + '0'] + joiner + WORDS[second]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# taken straight from activesupport/lib/active_support/inflector/methods.rb
|
2
|
+
module Ordinals
|
3
|
+
def to_ordinal(num)
|
4
|
+
"#{num}#{ordinal(num)}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def ordinal(number)
|
8
|
+
abs_number = number.to_i.abs
|
9
|
+
if (11..13).include?(abs_number % 100)
|
10
|
+
"th"
|
11
|
+
else
|
12
|
+
case abs_number % 10
|
13
|
+
when 1; "st"
|
14
|
+
when 2; "nd"
|
15
|
+
when 3; "rd"
|
16
|
+
else "th"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# adapted without any substanial changes from https://github.com/AndrewVos/roman-numerals
|
2
|
+
module RomanNumerals
|
3
|
+
BASE_DIGITS = {
|
4
|
+
1 => 'I',
|
5
|
+
4 => 'IV',
|
6
|
+
5 => 'V',
|
7
|
+
9 => 'IX',
|
8
|
+
10 => 'X',
|
9
|
+
40 => 'XL',
|
10
|
+
50 => 'L',
|
11
|
+
90 => 'XC',
|
12
|
+
100 => 'C',
|
13
|
+
400 => 'CD',
|
14
|
+
500 => 'D',
|
15
|
+
900 => 'CM',
|
16
|
+
1000 => 'M'
|
17
|
+
}
|
18
|
+
|
19
|
+
def to_upper_roman(value)
|
20
|
+
result = ''
|
21
|
+
BASE_DIGITS.keys.reverse.each do |decimal|
|
22
|
+
while value >= decimal
|
23
|
+
value -= decimal
|
24
|
+
result += BASE_DIGITS[decimal]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_lower_roman(value)
|
31
|
+
to_upper_roman(value).downcase
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Fixnum
|
2
|
+
def to_upper_roman
|
3
|
+
NumberTo.to_upper_roman(self)
|
4
|
+
end
|
5
|
+
def to_lower_roman
|
6
|
+
NumberTo.to_lower_roman(self)
|
7
|
+
end
|
8
|
+
def to_upper_alpha
|
9
|
+
NumberTo.to_upper_alpha(self)
|
10
|
+
end
|
11
|
+
def to_lower_alpha
|
12
|
+
NumberTo.to_lower_alpha(self)
|
13
|
+
end
|
14
|
+
def to_ordinal
|
15
|
+
NumberTo.to_ordinal(self)
|
16
|
+
end
|
17
|
+
def to_words(options = {})
|
18
|
+
NumberTo.to_words(self, options)
|
19
|
+
end
|
20
|
+
def to_word_ordinal(options = {})
|
21
|
+
NumberTo.to_word_ordinal(self, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
data/lib/number_to.rb
ADDED
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: number_to
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Corrigan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>'
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.0.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>'
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.0.0
|
69
|
+
description: Convenience methods for converting fixnums to various string equivalents.
|
70
|
+
(Alphabetic, roman numerals, ordinals, words.)
|
71
|
+
email: dcorrigan@scribenet.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/number_to.rb
|
77
|
+
- lib/modules/roman_numerals.rb
|
78
|
+
- lib/modules/number_words.rb
|
79
|
+
- lib/modules/ordinals.rb
|
80
|
+
- lib/modules/alphabetics.rb
|
81
|
+
- lib/number_to/fixnum.rb
|
82
|
+
homepage: http://www.scribenet.com
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.0.14
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Convenience methods for converting fixnums to various string equivalents.
|
107
|
+
test_files: []
|