humanize_fraction 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/README.md +37 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +3 -0
- data/humanize_fraction.gemspec +33 -0
- data/lib/core_extensions/string/humanize_fraction.rb +9 -0
- data/lib/humanize_fraction/humanizer.rb +105 -0
- data/lib/humanize_fraction/version.rb +3 -0
- data/lib/humanize_fraction.rb +10 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e0beddb356fa1d63e5658dd2e25fb4916414fbd0
|
4
|
+
data.tar.gz: 520506910e547967f3f5f485c51c8d8bb75fe6eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07e78cdf965891de22a42f8b92b41e366ac6f18dd58dccadd8783b8ec46b9b2114a1d1cb9fd68429c526d711eebd74f58232ba45ab2f8cbde533c4cc48c79198
|
7
|
+
data.tar.gz: 8b4c46ebc18c7ae1f57c26a748c7599769fb82c05336c8bd553667cd6d4c16a8a5dd236fa8aac23a021ead71d4f1a790c58fc7ac773e4cce4de9f7979f58cda9
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# humanize_fraction [](https://circleci.com/gh/6/humanize_fraction)
|
2
|
+
|
3
|
+
Rubygem to convert fraction to words, like 1 ⅓ => one and a third. Examples:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
"1/8".humanize_fraction
|
7
|
+
#=> "one eighth"
|
8
|
+
"1/8".humanize_fraction(shorthand: true)
|
9
|
+
#=> "an eighth"
|
10
|
+
"2 3/4".humanize_fraction
|
11
|
+
#=> "two and three fourths"
|
12
|
+
"2 3/4".humanize_fraction(quarter: true)
|
13
|
+
#=> "two and three quarters"
|
14
|
+
"1/1000000".humanize_fraction(shorthand: true)
|
15
|
+
#=> "a millionth"
|
16
|
+
"222/333".humanize_fraction
|
17
|
+
#=> "two hundred and twenty-two three hundred thirty-thirds"
|
18
|
+
```
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile and execute `bundle` to install:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'humanize_fraction'
|
26
|
+
```
|
27
|
+
|
28
|
+
If you wish to use the monkey-patched `String#humanize_fraction`, add the following into an initializer/config:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'humanize_fraction'
|
32
|
+
String.include(CoreExtensions::String::HumanizeFraction)
|
33
|
+
```
|
34
|
+
|
35
|
+
## Development
|
36
|
+
|
37
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "humanize_fraction"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/circle.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "humanize_fraction/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "humanize_fraction"
|
8
|
+
spec.version = HumanizeFraction::VERSION
|
9
|
+
spec.authors = ["Peter Graham"]
|
10
|
+
spec.email = ["peterghm@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Convert fractions to words, 3/5 => three fifths.}
|
13
|
+
spec.description = %q{Convert fractions to words, such as 3/5 to three fifths.}
|
14
|
+
spec.homepage = "https://github.com/6/humanize_fraction"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.license = "MIT"
|
23
|
+
spec.required_ruby_version = ">= 2.3.0"
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "activesupport", ">= 4"
|
26
|
+
spec.add_runtime_dependency "humanize", "~> 1.4"
|
27
|
+
spec.add_runtime_dependency "twitter_cldr", "~> 4.4"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
spec.add_development_dependency "rspec-its", "~> 1.2"
|
33
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module HumanizeFraction
|
2
|
+
class Humanizer
|
3
|
+
# From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
|
4
|
+
SINGLE_FRACTION = /^\s*(\-?\d+)\/(\-?\d+)\s*$/
|
5
|
+
MIXED_FRACTION = /^\s*(\-?\d*)\s+(\d+)\/(\d+)\s*$/
|
6
|
+
|
7
|
+
attr_reader :numerator, :denominator, :integer_part, :quarter, :shorthand
|
8
|
+
|
9
|
+
def initialize(numerator:, denominator:, integer_part: nil, shorthand: false, quarter: false)
|
10
|
+
[numerator, denominator].each do |number|
|
11
|
+
if !number.is_a?(Integer)
|
12
|
+
raise ArgumentError, "Expected Integers for numerator/denominator but got #{number.class.name}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if !integer_part.nil? && !integer_part.is_a?(Integer)
|
16
|
+
raise ArgumentError, "Expected Integer or NilClass for integer_part but got #{integer_part.class.name}"
|
17
|
+
end
|
18
|
+
@integer_part = integer_part
|
19
|
+
@numerator = numerator
|
20
|
+
@denominator = denominator
|
21
|
+
@shorthand = shorthand
|
22
|
+
@quarter = quarter
|
23
|
+
end
|
24
|
+
alias_method :quarter?, :quarter
|
25
|
+
alias_method :shorthand?, :shorthand
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
words = []
|
29
|
+
words << humanize_integer_part if !integer_part.nil?
|
30
|
+
words << humanize_numerator
|
31
|
+
words << humanize_denominator
|
32
|
+
words.join(" ")
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.from_string(string, options = {})
|
36
|
+
if !string.is_a?(String)
|
37
|
+
raise ArgumentError, "Expected String but got #{string.class.name}"
|
38
|
+
end
|
39
|
+
if string_is_mixed_fraction?(string)
|
40
|
+
whole, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
|
41
|
+
new(integer_part: whole, numerator: numerator, denominator: denominator, **options)
|
42
|
+
elsif string_is_single_fraction?(string)
|
43
|
+
numerator, denominator = string.split("/").map(&:to_i)
|
44
|
+
new(numerator: numerator, denominator: denominator, **options)
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Unable to extract fraction from string #{string}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def humanize_integer_part
|
53
|
+
"#{integer_part.humanize} and"
|
54
|
+
end
|
55
|
+
|
56
|
+
def humanize_numerator
|
57
|
+
number = if numerator == 1 && shorthand?
|
58
|
+
# 8 is the only(?) case where you want to prefix with `an` instead of `a`.
|
59
|
+
first_digit(denominator) == 8 ? "an" : "a"
|
60
|
+
else
|
61
|
+
numerator.humanize
|
62
|
+
end
|
63
|
+
number
|
64
|
+
end
|
65
|
+
|
66
|
+
def humanize_denominator
|
67
|
+
number = case denominator
|
68
|
+
when 2
|
69
|
+
"half"
|
70
|
+
when 4
|
71
|
+
quarter? ? "quarter" : "fourth"
|
72
|
+
else
|
73
|
+
denominator.localize(:en).to_rbnf_s("SpelloutRules", "spellout-ordinal")
|
74
|
+
end
|
75
|
+
# Handle case of `a millionth`, `a thousandth`, etc.
|
76
|
+
if shorthand? && denominator >= 100 &&
|
77
|
+
first_digit(denominator) == 1 && remaining_digits_zeros?(denominator)
|
78
|
+
number.sub!(/\Aone\s/, "")
|
79
|
+
end
|
80
|
+
if numerator != 1
|
81
|
+
number = ActiveSupport::Inflector.pluralize(number)
|
82
|
+
end
|
83
|
+
number
|
84
|
+
end
|
85
|
+
|
86
|
+
def first_digit(number)
|
87
|
+
number.to_s.split("").first.to_i
|
88
|
+
end
|
89
|
+
|
90
|
+
# Checks if everything after first digit are zeros.
|
91
|
+
def remaining_digits_zeros?(number)
|
92
|
+
numbers = number.to_s.split("")
|
93
|
+
numbers.shift
|
94
|
+
numbers.size > 0 && numbers.map(&:to_i).all?(&:zero?)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.string_is_mixed_fraction?(value)
|
98
|
+
value&.match(MIXED_FRACTION)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.string_is_single_fraction?(value)
|
102
|
+
value&.match(SINGLE_FRACTION)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: humanize_fraction
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Graham
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: humanize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: twitter_cldr
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.14'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-its
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.2'
|
111
|
+
description: Convert fractions to words, such as 3/5 to three fifths.
|
112
|
+
email:
|
113
|
+
- peterghm@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- Gemfile
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- bin/console
|
124
|
+
- bin/setup
|
125
|
+
- circle.yml
|
126
|
+
- humanize_fraction.gemspec
|
127
|
+
- lib/core_extensions/string/humanize_fraction.rb
|
128
|
+
- lib/humanize_fraction.rb
|
129
|
+
- lib/humanize_fraction/humanizer.rb
|
130
|
+
- lib/humanize_fraction/version.rb
|
131
|
+
homepage: https://github.com/6/humanize_fraction
|
132
|
+
licenses:
|
133
|
+
- MIT
|
134
|
+
metadata: {}
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 2.3.0
|
144
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
requirements: []
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 2.5.1
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Convert fractions to words, 3/5 => three fifths.
|
155
|
+
test_files: []
|