softprops-nuwords 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 softprops
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ lib/nuwords.rb
2
+ LICENSE
3
+ Rakefile
4
+ README.rdoc
5
+ test/nuwords_test.rb
6
+ test/test_helper.rb
7
+ VERSION
8
+ Manifest
@@ -0,0 +1,9 @@
1
+ = nuwords
2
+
3
+ Numeric words
4
+
5
+ 42.in_words #=> "fourty-two"
6
+
7
+ == Copyright
8
+
9
+ Copyright (c) 2009 softprops. See LICENSE for details.
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "nuwords"
8
+ gem.summary = %Q{numeric words}
9
+ gem.email = "d.tangren@gmail.com"
10
+ gem.homepage = "http://github.com/softprops/nuwords"
11
+ gem.authors = ["softprops"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "nuwords #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
57
+ require 'echoe'
58
+ Echoe.new('nuwords','0.1.0') do |g|
59
+ g.description = 'convert numbers to words'
60
+ g.url = 'http://github.com/softprops/nuwords'
61
+ g.author = 'softprops'
62
+ g.email = 'd.tangren@gmail.com'
63
+ g.ignore_pattern = ['tmp/*','script/*']
64
+ g.development_dependencies =[]
65
+ end
66
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,146 @@
1
+ #
2
+ # A Simple library for converting numeric values into words. Supports values
3
+ # up to #MAX (999,999,999,999,999). I could support more but it's not really that useful at
4
+ # that point. I draw the line at
5
+ # 'nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million
6
+ # nine hundred ninety-nine thousand nine hundred ninety-nine'!
7
+ # simple usage:
8
+ # 0.in_words # => 'zero'
9
+ # 1234013.in_words # => 'one million two hundred thirty-four thousand thirteen'
10
+ #
11
+ # custom language usage:
12
+ # 3.in_words :in => 'Mandarin' # => 'san'
13
+ #
14
+ # custom translator usage:
15
+ # 142.in_words :translator => CustomTranslator # => result of CustomTranslator.translate(142)
16
+ #
17
+ # @author softprops
18
+ #
19
+ module Nuwords
20
+ # the maxiumum supported number
21
+ MAX = 999_999_999_999_999
22
+
23
+ # Translates a numeric value to words
24
+ # This method takes an optional hash of options which include
25
+ # :translator => The class responsible for translation behavior
26
+ # :in => The language Dictionary that the number should be translated into
27
+ # If the Dictionary for the language cannot be found an UnsupportedLanguageException will be raised
28
+ def in_words(opts = {})
29
+ translator = opts.delete(:translator) || Translator.new
30
+ raise InvalidTranslatorException unless translator.respond_to?(:translate)
31
+ translator.translate(self, opts)
32
+ end
33
+
34
+ alias_method :to_w, :in_words
35
+
36
+ protected
37
+
38
+ class InvalidTranslatorException < Exception; end
39
+ class NumberNotSupportedException < Exception; end
40
+
41
+ # Responsible for translating a given number into
42
+ # words. To extend override #parse with your impl
43
+ class Translator
44
+
45
+ # The interface for performing actual translation
46
+ def translate(number, opts = {})
47
+ @dictionary = dictionary_for(opts[:in] || 'En')
48
+ @dashed = opts[:dashed].nil? ? true : opts[:dashed]
49
+ parse(number, false)
50
+ end
51
+
52
+ protected
53
+
54
+ # Handles the core logic of interpreting
55
+ # the given number in words
56
+ # The language is dependent on the Dictionary provided with the
57
+ #:in option which defaults to En (English)
58
+ def parse(number, ignore_zero = true)
59
+ word = ''
60
+ case number
61
+ when 0
62
+ word << @dictionary.zero! if !ignore_zero
63
+ when 1..9
64
+ word << @dictionary.ones![number - 1]
65
+ when 11..19
66
+ word << @dictionary.teens![(number - 10) - 1]
67
+ when 10 || 20..99
68
+ word << @dictionary.tens![(number / 10) - 1] if(number/10 > 0)
69
+ word << (@dashed ? '-' : '') << parse(number % 10) if(number % 10 > 0)
70
+ when 100..999
71
+ word << parse(number/100) << " #{@dictionary.bigs![0]} " if (number/100 > 0)
72
+ word << parse(number%100) if (number%100 > 0)
73
+ when 1_000..999_999
74
+ word << parse((number/1000)) << " #{@dictionary.bigs![1]} " if (number/1_000>0)
75
+ word << parse(number%1000) if (number%1_000>0)
76
+ when 1_000_000..999_999_999
77
+ word << parse(number/1_000_000) << " #{@dictionary.bigs![2]} " if(number/1_000_000>0)
78
+ word << parse(number%1_000_000) if(number%1_000_000>0)
79
+ when 1_000_000_000..999_999_999_999
80
+ word << parse(number/1_000_000_000) << " #{@dictionary.bigs![3]} " if(number/1_000_000_000>0)
81
+ word << parse(number%1_000_000_000) if(number%1_000_000_000>0)
82
+ when 1_000_000_000_000..999_999_999_999_999
83
+ word << parse(number/1_000_000_000_000) <<" #{@dictionary.bigs![4]} " if(number/1_000_000_000_000>0)
84
+ word << parse(number%1_000_000_000_000) if(number%1_000_000_000_000>0)
85
+ else
86
+ raise NumberNotSupportedException.new("Number #{number} not supported")
87
+ end
88
+ word.strip
89
+ end
90
+
91
+ private
92
+
93
+ # Fetchs the Library of words for the given
94
+ # language
95
+ def dictionary_for(lang)
96
+ Dictionaries.find(lang.to_s)
97
+ end
98
+ end
99
+
100
+ # =Language Dictionaries
101
+ # to use your own, include Numords::Dictionaries::Dictionary
102
+ # in a class that defines class methods #zero, #ones, #teens, #tens, #bigs
103
+ # and invoke via 1.in_words(:in => CustomLanguage)
104
+ module Dictionaries
105
+
106
+ class UnsupportedLanguageException < Exception; end
107
+
108
+ class << self
109
+ # look up a dictionary for a given lan
110
+ def find(lang)
111
+ return Dictionaries.const_get(lang) if lang.kind_of?(String)
112
+ lang
113
+ rescue Exception => e; raise UnsupportedLanguageException.new("#{e} - unsupported language #{lang}")
114
+ end
115
+ end
116
+
117
+ # Base behavior of Dictionary. Defines the definition
118
+ # of accessor methods for %w( zero ones teens tens bigs )
119
+ module Dictionary
120
+ def self.included(klass)
121
+ %w( zero ones teens tens bigs ).each do |classification|
122
+ klass.class_eval %Q{
123
+ def self.#{classification}(values)
124
+ @@#{classification}=values
125
+ end
126
+
127
+ def self.#{classification}!
128
+ @@#{classification}
129
+ end
130
+ }
131
+ end
132
+ end
133
+ end # end Dictionary
134
+
135
+ # English library (default)
136
+ class En
137
+ include Dictionary
138
+ zero 'zero'
139
+ ones %w( one two three four five six seven eight nine )
140
+ teens %w( eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen )
141
+ tens %w( ten twenty thirty fourty fifty sixty seventy eighty ninety )
142
+ bigs %w( hundred thousand million billion trillion )
143
+ end # end En
144
+ end # end Dictionaries
145
+ end
146
+ Numeric.send :include, Nuwords # include in Numeric class for use
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{nuwords}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["softprops"]
9
+ s.date = %q{2009-05-17}
10
+ s.description = %q{convert numbers to words}
11
+ s.email = %q{d.tangren@gmail.com}
12
+ s.extra_rdoc_files = ["lib/nuwords.rb", "LICENSE", "README.rdoc"]
13
+ s.files = ["lib/nuwords.rb", "LICENSE", "Rakefile", "README.rdoc", "test/nuwords_test.rb", "test/test_helper.rb", "VERSION", "Manifest", "nuwords.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/softprops/nuwords}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Nuwords", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{nuwords}
19
+ s.rubygems_version = %q{1.3.2}
20
+ s.summary = %q{convert numbers to words}
21
+ s.test_files = ["test/nuwords_test.rb", "test/test_helper.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+
3
+ # English library (default)
4
+ class AnotherLanguage
5
+ include Nuwords::Dictionaries::Dictionary
6
+ zero 'zero'
7
+ ones %w( blah meh nom si wu liu chi ba nine )
8
+ teens %w( eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen )
9
+ tens %w( bacon twenty thirty fourty fifty sixty seventy eighty ninety )
10
+ bigs %w( hundred thousand million billion trillion )
11
+ end
12
+
13
+ class NuwordsTest < Test::Unit::TestCase
14
+
15
+ context "the library" do
16
+ should "provide the maxiumum supported value" do
17
+ assert true, Nuwords.const_defined?(:MAX)
18
+ end
19
+ context "when given a bogus translator" do
20
+ should "raise a InvalidTranslatorException" do
21
+ assert_raise Nuwords::InvalidTranslatorException do
22
+ 1.in_words(:translator => Hash)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ context "a numberic value" do
29
+ context "less than one" do
30
+ should "translate to zero" do
31
+ assert_equal "zero", 0.in_words
32
+ end
33
+ end
34
+
35
+ context "that is greater than ten and less than on hundred" do
36
+ should "be delimited by a dash if not devisible evenly by ten" do
37
+ assert_equal "twenty-five", 25.in_words
38
+ end
39
+
40
+ context "when requested not to have dashes" do
41
+ should "not be delimited by a dash if not devisible evenly by ten" do
42
+ assert_equal "twentyfive", 25.in_words(:dashed => false)
43
+ end
44
+ end
45
+ end
46
+
47
+ context "that is translated to a custom language" do
48
+ should "translate numeric values accordingly" do
49
+ assert_equal 'bacon', 10.in_words(:in => AnotherLanguage)
50
+ end
51
+ end
52
+
53
+ context "that is translated to a bogus language" do
54
+ should "raise an UnsupportedLanguageException" do
55
+ assert_raise Nuwords::Dictionaries::UnsupportedLanguageException do
56
+ 10.in_words(:in => "asdf")
57
+ end
58
+ end
59
+ end
60
+
61
+ context "that is less or equal to 999,999,999,999,999" do
62
+ should "not raise a NumberNotSupportedException" do
63
+ assert_nothing_raised do
64
+ # 0.upto(999_999_999_999_999) works but takes a good while to run
65
+ (999_999_999_999_999 - 1).in_words
66
+ 999_999_999_999_999.in_words
67
+ end
68
+ end
69
+ end
70
+
71
+ context "that is greater than 999,999,999,999,999" do
72
+ should "raise a NumberNotSupportedException" do
73
+ assert_raise Nuwords::NumberNotSupportedException do
74
+ 999_999_999_999_999.next.in_words
75
+ end
76
+ end
77
+ end
78
+
79
+ should "respond to aliased method #to_w" do
80
+ assert true, 1.respond_to?(:to_w)
81
+ end
82
+
83
+ should "return the same value when #to_w is called as with #in_words" do
84
+ assert_equal 1.to_w, 1.in_words
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'nuwords'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: softprops-nuwords
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - softprops
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-17 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: convert numbers to words
17
+ email: d.tangren@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/nuwords.rb
24
+ - LICENSE
25
+ - README.rdoc
26
+ files:
27
+ - lib/nuwords.rb
28
+ - LICENSE
29
+ - Rakefile
30
+ - README.rdoc
31
+ - test/nuwords_test.rb
32
+ - test/test_helper.rb
33
+ - VERSION
34
+ - Manifest
35
+ - nuwords.gemspec
36
+ has_rdoc: true
37
+ homepage: http://github.com/softprops/nuwords
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --line-numbers
41
+ - --inline-source
42
+ - --title
43
+ - Nuwords
44
+ - --main
45
+ - README.rdoc
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "1.2"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project: nuwords
63
+ rubygems_version: 1.2.0
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: convert numbers to words
67
+ test_files:
68
+ - test/nuwords_test.rb
69
+ - test/test_helper.rb