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.
@@ -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
+