wordify 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"
@@ -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,4 @@
1
+ module Wordify::Token; end
2
+ require 'wordify/token/unit'
3
+ require 'wordify/token/tens'
4
+ require 'wordify/token/hundreds'
@@ -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
+