trange_frange 0.1.0 → 0.1.1
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/ChangeLog.md +5 -1
- data/README.md +5 -13
- data/lib/trange_frange.rb +14 -330
- data/lib/trange_frange/version.rb +3 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/trange_frange_spec.rb +0 -1
- metadata +3 -3
data/ChangeLog.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# trange_frange #
|
2
|
-
The tool spells out numbers (amounts) in words. It supports serbian language.
|
2
|
+
The tool spells out numbers (amounts) in words. It supports serbian language and amounts up to 999 bilions.
|
3
3
|
> 12345.67 => 'dvanaest hiljada tri stotine četrdeset pet i 67/100'
|
4
4
|
|
5
5
|
## Install ##
|
@@ -14,31 +14,23 @@ amount = TrangeFrange::Amount.new(16345.67)
|
|
14
14
|
amount.spell!
|
15
15
|
=> "šesnaest hiljada tri stotine četrdeset pet"
|
16
16
|
```
|
17
|
-
|
17
|
+
including a fraction
|
18
18
|
```ruby
|
19
|
-
require 'trange_frange'
|
20
|
-
amount = TrangeFrange::Amount.new(16345.67)
|
21
19
|
amount.spell! show_fraction: true
|
22
20
|
=> 'šesnaest hiljada tri stotine četrdeset pet i 67/100'
|
23
21
|
```
|
24
|
-
|
22
|
+
disabling spacing between words
|
25
23
|
```ruby
|
26
|
-
require 'trange_frange'
|
27
|
-
amount = TrangeFrange::Amount.new(16345.67)
|
28
24
|
amount.spell! squeeze: true
|
29
25
|
=> 'šesnaesthiljadatristotinečetrdesetpet'
|
30
26
|
```
|
31
|
-
|
27
|
+
disabling accented lating characters
|
32
28
|
```ruby
|
33
|
-
require 'trange_frange'
|
34
|
-
amount = TrangeFrange::Amount.new(16345.67)
|
35
29
|
amount.spell! bald: true
|
36
30
|
=> 'sesnaest hiljada tri stotine cetrdeset pet'
|
37
31
|
```
|
38
|
-
|
32
|
+
combined options
|
39
33
|
```ruby
|
40
|
-
require 'trange_frange'
|
41
|
-
amount = TrangeFrange::Amount.new(16345.67)
|
42
34
|
amount.spell! show_fraction: true, squeeze: true, bald: true
|
43
35
|
=> 'sesnaesthiljadatristotinecetrdesetpet i 67/100'
|
44
36
|
```
|
data/lib/trange_frange.rb
CHANGED
@@ -1,333 +1,17 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'trange_frange/version'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
class OrderCondition
|
21
|
-
def initialize
|
22
|
-
@conditions = []
|
23
|
-
end
|
24
|
-
|
25
|
-
def add
|
26
|
-
@conditions << Proc.new
|
27
|
-
end
|
28
|
-
|
29
|
-
def match!
|
30
|
-
@conditions.map(&:call).map do |condition|
|
31
|
-
return condition if condition
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
attr_reader :conditions
|
37
|
-
end
|
38
|
-
|
39
|
-
class Base < Struct.new :base
|
40
|
-
# range [10-19]
|
41
|
-
def teen?
|
42
|
-
member.ten == '1'
|
43
|
-
end
|
44
|
-
|
45
|
-
def gender?
|
46
|
-
%w[1 2].include? member.one
|
47
|
-
end
|
48
|
-
|
49
|
-
def member
|
50
|
-
@member ||= TrangeFrange::Member.new base
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class Suffix < Struct.new :base
|
55
|
-
def gender?
|
56
|
-
('2'..'4').include? suffix_base.member.one
|
57
|
-
end
|
58
|
-
|
59
|
-
def one?
|
60
|
-
suffix_base.member.one == '1'
|
61
|
-
end
|
62
|
-
|
63
|
-
def suffix_base
|
64
|
-
@suffix_base ||= TrangeFrange::Base.new base
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class One < Struct.new :base, :magnitude
|
69
|
-
ONES = {
|
70
|
-
'0' => '', # not printed
|
71
|
-
'1' => {
|
72
|
-
:m => 'jedan', # male gender
|
73
|
-
:f => 'jedna' # female gender
|
74
|
-
},
|
75
|
-
'2' => {
|
76
|
-
:m => 'dva',
|
77
|
-
:f => 'dve'
|
78
|
-
},
|
79
|
-
'3' => 'tri',
|
80
|
-
'4' => 'četiri',
|
81
|
-
'5' => 'pet',
|
82
|
-
'6' => 'šest',
|
83
|
-
'7' => 'sedam',
|
84
|
-
'8' => 'osam',
|
85
|
-
'9' => 'devet'
|
86
|
-
}
|
87
|
-
|
88
|
-
def word
|
89
|
-
order_condition.add { String.new if one_base.teen? }
|
90
|
-
order_condition.add { ONES[one_base.member.one][gender] if one_base.gender? }
|
91
|
-
order_condition.add { ONES[one_base.member.one] }
|
92
|
-
order_condition.match!
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def one_base
|
98
|
-
@one_base ||= TrangeFrange::Base.new base
|
99
|
-
end
|
100
|
-
|
101
|
-
def order_condition
|
102
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
103
|
-
end
|
104
|
-
|
105
|
-
def gender
|
106
|
-
magnitude.odd? ? :f : :m
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
class Ten < Struct.new :base
|
111
|
-
TENS = {
|
112
|
-
'0' => '',
|
113
|
-
'10' => 'deset',
|
114
|
-
'11' => 'jedanaest',
|
115
|
-
'12' => 'dvanaest',
|
116
|
-
'13' => 'trinaest',
|
117
|
-
'14' => 'četrnaest',
|
118
|
-
'15' => 'petnaest',
|
119
|
-
'16' => 'šesnaest',
|
120
|
-
'17' => 'sedamnaest',
|
121
|
-
'18' => 'osamnaest',
|
122
|
-
'19' => 'devetnaest',
|
123
|
-
'2' => 'dvadeset',
|
124
|
-
'3' => 'trideset',
|
125
|
-
'4' => 'četrdeset',
|
126
|
-
'5' => 'pedeset',
|
127
|
-
'6' => 'šezdeset',
|
128
|
-
'7' => 'sedamdeset',
|
129
|
-
'8' => 'osamdeset',
|
130
|
-
'9' => 'devedeset'
|
131
|
-
}
|
132
|
-
|
133
|
-
def word
|
134
|
-
order_condition.add { TENS[teen_base_member] if ten_base.teen? }
|
135
|
-
order_condition.add { TENS[ten_base.member.ten] }
|
136
|
-
order_condition.match!
|
137
|
-
end
|
138
|
-
|
139
|
-
private
|
140
|
-
|
141
|
-
def ten_base
|
142
|
-
@ten_base ||= TrangeFrange::Base.new base
|
143
|
-
end
|
144
|
-
|
145
|
-
def order_condition
|
146
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
147
|
-
end
|
148
|
-
|
149
|
-
def teen_base_member
|
150
|
-
ten_base.member.ten + ten_base.member.one
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
class Hundred < Struct.new :base
|
155
|
-
HUNDREDS = {
|
156
|
-
'0' => '',
|
157
|
-
'1' => 'jedna stotina',
|
158
|
-
'2' => 'dve stotine',
|
159
|
-
'3' => 'tri stotine',
|
160
|
-
'4' => 'četiri stotine',
|
161
|
-
'5' => 'pet stotina',
|
162
|
-
'6' => 'šest stotina',
|
163
|
-
'7' => 'sedam stotina',
|
164
|
-
'8' => 'osam stotina',
|
165
|
-
'9' => 'devet stotina'
|
166
|
-
}
|
167
|
-
|
168
|
-
def word
|
169
|
-
order_condition.add { HUNDREDS[hundred_base.member.hundred] }
|
170
|
-
order_condition.match!
|
171
|
-
end
|
172
|
-
|
173
|
-
private
|
174
|
-
|
175
|
-
def hundred_base
|
176
|
-
@hundred_base ||= TrangeFrange::Base.new base
|
177
|
-
end
|
178
|
-
|
179
|
-
def order_condition
|
180
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
class Thousand < Struct.new :base
|
185
|
-
THOUSANDS = %w[hiljada hiljade]
|
186
|
-
|
187
|
-
def word
|
188
|
-
order_condition.add { THOUSANDS[1] if suffix.gender? and !suffix.suffix_base.teen? }
|
189
|
-
order_condition.add { THOUSANDS[0] }
|
190
|
-
order_condition.match!
|
191
|
-
end
|
192
|
-
|
193
|
-
private
|
194
|
-
|
195
|
-
def suffix
|
196
|
-
@suffix ||= TrangeFrange::Suffix.new base
|
197
|
-
end
|
198
|
-
|
199
|
-
def order_condition
|
200
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
class Milion < Struct.new :base
|
205
|
-
MILIONS = %w[milion miliona]
|
206
|
-
|
207
|
-
def word
|
208
|
-
order_condition.add { MILIONS[0] if suffix.one? and !suffix.suffix_base.teen? }
|
209
|
-
order_condition.add { MILIONS[1] }
|
210
|
-
order_condition.match!
|
211
|
-
end
|
212
|
-
|
213
|
-
private
|
214
|
-
|
215
|
-
def suffix
|
216
|
-
@suffix ||= TrangeFrange::Suffix.new base
|
217
|
-
end
|
218
|
-
|
219
|
-
def order_condition
|
220
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
class Bilion < Struct.new :base
|
225
|
-
BILIONS = %w[milijarda milijarde milijardi]
|
226
|
-
|
227
|
-
def word
|
228
|
-
order_condition.add { BILIONS[0] if suffix.one? and !suffix.suffix_base.teen? }
|
229
|
-
order_condition.add { BILIONS[1] if suffix.gender? and !suffix.suffix_base.teen? }
|
230
|
-
order_condition.add { BILIONS[2] }
|
231
|
-
order_condition.match!
|
232
|
-
end
|
233
|
-
|
234
|
-
private
|
235
|
-
|
236
|
-
def suffix
|
237
|
-
@suffix ||= TrangeFrange::Suffix.new base
|
238
|
-
end
|
239
|
-
|
240
|
-
def order_condition
|
241
|
-
@order_condition ||= TrangeFrange::OrderCondition.new
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
class Shaper < Struct.new :words, :fraction, :options
|
246
|
-
OPTIONS = [:bald, :squeeze, :show_fraction]
|
247
|
-
|
248
|
-
def shape!
|
249
|
-
OPTIONS.each { |option| send(option) if options[option] } and return words
|
250
|
-
end
|
251
|
-
|
252
|
-
private
|
253
|
-
|
254
|
-
def show_fraction
|
255
|
-
words << " i #{fraction}/100"
|
256
|
-
end
|
257
|
-
|
258
|
-
def squeeze
|
259
|
-
words.delete!(' ')
|
260
|
-
end
|
261
|
-
|
262
|
-
def bald
|
263
|
-
words.tr!('čćšđž', 'ccsdz')
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
class Amount
|
268
|
-
attr_reader :amount
|
269
|
-
|
270
|
-
MAX_AMOUNT_SIZE = 12
|
271
|
-
BASES = [Hundred, Ten, One]
|
272
|
-
SUFFIXES = [Thousand, Milion, Bilion]
|
273
|
-
|
274
|
-
def initialize(amount)
|
275
|
-
unless amount.is_a?(Fixnum) || amount.is_a?(Float)
|
276
|
-
raise TypeError, 'Amount must be of type Fixnum or Float.'
|
277
|
-
end
|
278
|
-
|
279
|
-
if max_amount_size?(amount)
|
280
|
-
raise NotImplementedError, 'I can only work with amounts up to 999 bilions.'
|
281
|
-
end
|
282
|
-
|
283
|
-
@amount = amount
|
284
|
-
end
|
285
|
-
|
286
|
-
def spell!(options={})
|
287
|
-
TrangeFrange::Shaper.new(generate_words!, fraction, options).shape!
|
288
|
-
end
|
289
|
-
|
290
|
-
private
|
291
|
-
|
292
|
-
def max_amount_size?(amount)
|
293
|
-
amount.to_s.split('.')[0].size > MAX_AMOUNT_SIZE
|
294
|
-
end
|
295
|
-
|
296
|
-
def split!
|
297
|
-
@splitted ||= ('%.2f' % amount).split('.')
|
298
|
-
end
|
299
|
-
|
300
|
-
def whole_number
|
301
|
-
@whole_number ||= split![0]
|
302
|
-
end
|
303
|
-
|
304
|
-
def fraction
|
305
|
-
@fraction ||= split![1]
|
306
|
-
end
|
307
|
-
|
308
|
-
def members
|
309
|
-
@members ||= whole_number.reverse.scan(/.{1,3}/).reverse.map(&:reverse)
|
310
|
-
end
|
311
|
-
|
312
|
-
def generate_base!(member, magnitude)
|
313
|
-
BASES.map do |base|
|
314
|
-
base == One ? base.new(member, magnitude).word : base.new(member).word
|
315
|
-
end.join(' ').strip.squeeze
|
316
|
-
end
|
317
|
-
|
318
|
-
def generate_suffix!(member, magnitude)
|
319
|
-
magnitude > 0 ? SUFFIXES[magnitude.pred].new(member).word : String.new
|
320
|
-
end
|
321
|
-
|
322
|
-
def generate_words!
|
323
|
-
magnitude = members.size.pred
|
324
|
-
Array.new.tap do |words|
|
325
|
-
members.map do |member|
|
326
|
-
words << generate_base!(member, magnitude)
|
327
|
-
words << generate_suffix!(member, magnitude) unless words.last.empty?
|
328
|
-
magnitude -= 1
|
329
|
-
end
|
330
|
-
end.join(' ').strip.squeeze
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
4
|
+
require 'trange_frange/member'
|
5
|
+
require 'trange_frange/base'
|
6
|
+
require 'trange_frange/suffix'
|
7
|
+
require 'trange_frange/order_condition'
|
8
|
+
require 'trange_frange/base_helper'
|
9
|
+
require 'trange_frange/suffix_helper'
|
10
|
+
require 'trange_frange/one'
|
11
|
+
require 'trange_frange/ten'
|
12
|
+
require 'trange_frange/hundred'
|
13
|
+
require 'trange_frange/thousand'
|
14
|
+
require 'trange_frange/milion'
|
15
|
+
require 'trange_frange/bilion'
|
16
|
+
require 'trange_frange/shaper'
|
17
|
+
require 'trange_frange/amount'
|
data/spec/spec_helper.rb
CHANGED
data/spec/trange_frange_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trange_frange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
version: '0'
|
99
99
|
requirements: []
|
100
100
|
rubyforge_project:
|
101
|
-
rubygems_version: 1.8.
|
101
|
+
rubygems_version: 1.8.25
|
102
102
|
signing_key:
|
103
103
|
specification_version: 3
|
104
104
|
summary: Tool for spelling amounts
|