wordify 0.1.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.
- data/README.rdoc +11 -0
- data/lib/wordify.rb +38 -0
- data/lib/wordify/constructor.rb +71 -0
- data/lib/wordify/token.rb +4 -0
- data/lib/wordify/token/hundreds.rb +44 -0
- data/lib/wordify/token/tens.rb +41 -0
- data/lib/wordify/token/unit.rb +36 -0
- data/lib/wordify/tokeniser.rb +29 -0
- metadata +67 -0
data/README.rdoc
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
== Wordify
|
|
2
|
+
|
|
3
|
+
Wordify converts Numerics into words (currently only British English format).
|
|
4
|
+
|
|
5
|
+
Example:
|
|
6
|
+
|
|
7
|
+
120345.in_words #=> "one hundred and twenty thousand, three hundred and fourty five"
|
|
8
|
+
|
|
9
|
+
And in tokens...
|
|
10
|
+
|
|
11
|
+
120345.in_words(:tokens => true) #=> "one two zero three four five"
|
data/lib/wordify.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
2
|
+
module Wordify; end
|
|
3
|
+
|
|
4
|
+
require 'wordify/token'
|
|
5
|
+
require 'wordify/tokeniser'
|
|
6
|
+
require 'wordify/constructor'
|
|
7
|
+
|
|
8
|
+
module Wordify
|
|
9
|
+
class << self
|
|
10
|
+
def units; %w[zero one two three four five six seven eight nine]; end
|
|
11
|
+
def teens; %w[ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen]; end
|
|
12
|
+
def tens; %w[zero ten twenty thirty fourty fifty sixty seventy eighty ninety]; end
|
|
13
|
+
def qnts
|
|
14
|
+
%w[hundred thousand million billion trillion quadrillion quintillion] +
|
|
15
|
+
%w[sextillion septillion octillion nonillion decillion undecillion] +
|
|
16
|
+
%w[duodecillion tredecillion quattuordecillion quindecillion sexdecillion] +
|
|
17
|
+
%w[septendecillion octodecillion novemdecillion vigintillion centillion]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module Numeric
|
|
22
|
+
def in_words(options={})
|
|
23
|
+
options[:tokens] ? tokenise : construct_sentence
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def construct_sentence
|
|
29
|
+
Wordify::Constructor.new(self).to_sentence
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def tokenise
|
|
33
|
+
Wordify::Tokeniser.new(self).to_s
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Numeric; include Wordify::Numeric; end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
class Wordify::Constructor
|
|
2
|
+
attr_reader :number
|
|
3
|
+
|
|
4
|
+
def initialize(number)
|
|
5
|
+
@number = number
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def to_sentence
|
|
9
|
+
if unreadable? || out_of_range?
|
|
10
|
+
sentence = number.to_s
|
|
11
|
+
else
|
|
12
|
+
sentence = []
|
|
13
|
+
tokens_in_hundreds.each_with_index do |h, i|
|
|
14
|
+
sentence << (qnts[i] and i+1 != qnts.size ? "#{h} #{qnts[i]}" : h) if h
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
last = sentence.pop
|
|
18
|
+
prev = sentence.compact
|
|
19
|
+
sentence = if qnts.detect{ |q| last.include?(q) }
|
|
20
|
+
[prev, last].flatten.join(', ')
|
|
21
|
+
else
|
|
22
|
+
[(prev.any? ? prev.join(', ') : nil), last].compact.join(' and ')
|
|
23
|
+
end
|
|
24
|
+
sentence += ' ' + tokenised_decimals if decimals
|
|
25
|
+
end
|
|
26
|
+
sentence
|
|
27
|
+
end
|
|
28
|
+
alias_method :to_s, :to_sentence
|
|
29
|
+
|
|
30
|
+
def eql?(other)
|
|
31
|
+
to_sentence == other.to_sentence
|
|
32
|
+
end
|
|
33
|
+
alias_method :==, :eql?
|
|
34
|
+
|
|
35
|
+
def <=>(other)
|
|
36
|
+
to_sentence <=> other.to_sentence
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def out_of_range?
|
|
40
|
+
tokens.size > 23
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def unreadable?
|
|
44
|
+
number.to_s.match(/[\+\-]/) != nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def parts
|
|
48
|
+
@parts ||= number.to_s.split('.')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def tokens
|
|
52
|
+
@tokens ||= parts[0].reverse.scan(/([0-9]{1,3})/).flatten.map { |i| i.reverse }.reverse
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def tokens_in_hundreds
|
|
56
|
+
@tokens_in_hundreds ||= tokens.map { |token| Wordify::Token::Hundreds.new(token).to_s }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def decimals
|
|
60
|
+
@decimals ||= parts[1] ? ".#{parts[1]}" : nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def tokenised_decimals
|
|
64
|
+
@decimals_to_tokens ||= decimals ? Wordify::Tokeniser.new(decimals).to_s : nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def qnts
|
|
68
|
+
Wordify.qnts.first(tokens_in_hundreds.size).reverse
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class Wordify::Token::Hundreds
|
|
2
|
+
attr_reader :string, :number
|
|
3
|
+
def initialize(string)
|
|
4
|
+
@string, @number = string, string.to_i
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def raw_tokens
|
|
8
|
+
@raw_tokens ||= string.scan(/[0-9]/).map { |t| Wordify::Token::Unit.new(t) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def tokens
|
|
12
|
+
@tokens ||= ([Wordify::Token::Unit.new('0')]*(3-raw_tokens.size)) + raw_tokens
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def size
|
|
16
|
+
tokens.size
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def hundreds
|
|
20
|
+
tokens[0].zero? ? nil : "#{tokens[0].unit} hundred"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def tens
|
|
24
|
+
Wordify::Token::Tens.new(tokens[1], tokens[2]).to_s
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def group
|
|
28
|
+
@group ||= [hundreds, tens].compact
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
return nil if number.zero?
|
|
33
|
+
group.any? ? group.join(' and ') : nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def eql?(other)
|
|
37
|
+
to_s == other.to_s
|
|
38
|
+
end
|
|
39
|
+
alias_method :==, :eql?
|
|
40
|
+
|
|
41
|
+
def <=>(other)
|
|
42
|
+
to_s <=> other.to_s
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Wordify::Token::Tens
|
|
2
|
+
attr_reader :tens, :unit
|
|
3
|
+
def initialize(*unit_tokens)
|
|
4
|
+
@tens, @unit = unit_tokens
|
|
5
|
+
raise StandardError, 'Invalid tokens' unless valid?
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def ten?
|
|
9
|
+
tens.number > 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def teen?
|
|
13
|
+
tens.number == 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def valid?
|
|
17
|
+
tens.is_a?(Wordify::Token::Unit) and unit.is_a?(Wordify::Token::Unit)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_s
|
|
21
|
+
chars = []
|
|
22
|
+
if ten?
|
|
23
|
+
chars << Wordify.tens[tens.number]
|
|
24
|
+
chars << unit.unit unless unit.zero?
|
|
25
|
+
elsif teen?
|
|
26
|
+
chars << Wordify.teens[unit.number]
|
|
27
|
+
else
|
|
28
|
+
chars << unit.unit unless unit.zero?
|
|
29
|
+
end
|
|
30
|
+
chars.any? ? chars.join(' ') : nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def eql?(other)
|
|
34
|
+
to_s == other.to_s
|
|
35
|
+
end
|
|
36
|
+
alias_method :==, :eql?
|
|
37
|
+
|
|
38
|
+
def <=>(other)
|
|
39
|
+
to_s <=> other.to_s
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class Wordify::Token::Unit
|
|
2
|
+
attr_reader :character
|
|
3
|
+
def initialize(char)
|
|
4
|
+
@character = char
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def number
|
|
8
|
+
point? ? nil : character.to_i
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def point?
|
|
12
|
+
character == '.'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def unit?
|
|
16
|
+
not point?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def zero?
|
|
20
|
+
character == '0'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def unit
|
|
24
|
+
@unit ||= point? ? 'point' : Wordify.units[character.to_i]
|
|
25
|
+
end
|
|
26
|
+
alias_method :to_s, :unit
|
|
27
|
+
|
|
28
|
+
def eql?(other)
|
|
29
|
+
character == other.character
|
|
30
|
+
end
|
|
31
|
+
alias_method :==, :eql?
|
|
32
|
+
|
|
33
|
+
def <=>(other)
|
|
34
|
+
character <=> other.character
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Wordify::Tokeniser
|
|
2
|
+
attr_reader :number
|
|
3
|
+
|
|
4
|
+
def initialize(number)
|
|
5
|
+
@number = number
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def to_s
|
|
9
|
+
unreadable? ? number.to_s : tokens.map { |t| t.to_s }.join(' ')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def eql?(other)
|
|
13
|
+
to_s == other.to_s
|
|
14
|
+
end
|
|
15
|
+
alias_method :==, :eql?
|
|
16
|
+
|
|
17
|
+
def <=>(other)
|
|
18
|
+
to_s <=> other.to_s
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def unreadable?
|
|
22
|
+
number.to_s.match(/[\+\-]/) != nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def tokens
|
|
26
|
+
@tokens ||= number.to_s.scan(/(.)/).flatten.map { |char| Wordify::Token::Unit.new(char) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: wordify
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alex Neill
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-12-01 00:00:00 +00:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Covert Numerics into words
|
|
17
|
+
email: alex@featureless.co.uk
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- README.rdoc
|
|
26
|
+
- lib/wordify.rb
|
|
27
|
+
- lib/wordify/token.rb
|
|
28
|
+
- lib/wordify/token/hundreds.rb
|
|
29
|
+
- lib/wordify/token/tens.rb
|
|
30
|
+
- lib/wordify/token/unit.rb
|
|
31
|
+
- lib/wordify/constructor.rb
|
|
32
|
+
- lib/wordify/tokeniser.rb
|
|
33
|
+
has_rdoc: true
|
|
34
|
+
homepage: http://github.com/ajn/wordify
|
|
35
|
+
licenses: []
|
|
36
|
+
|
|
37
|
+
post_install_message:
|
|
38
|
+
rdoc_options:
|
|
39
|
+
- --line-numbers
|
|
40
|
+
- --inline-source
|
|
41
|
+
- --title
|
|
42
|
+
- Wordify
|
|
43
|
+
- --main
|
|
44
|
+
- README.rdoc
|
|
45
|
+
require_paths:
|
|
46
|
+
- lib
|
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: "0"
|
|
52
|
+
version:
|
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: "0"
|
|
58
|
+
version:
|
|
59
|
+
requirements: []
|
|
60
|
+
|
|
61
|
+
rubyforge_project:
|
|
62
|
+
rubygems_version: 1.3.5
|
|
63
|
+
signing_key:
|
|
64
|
+
specification_version: 3
|
|
65
|
+
summary: Covert Numerics into words
|
|
66
|
+
test_files: []
|
|
67
|
+
|