humanize_fraction 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +23 -1
- data/humanize_fraction.gemspec +1 -1
- data/lib/core_extensions/string/humanize_fraction.rb +1 -1
- data/lib/humanize_fraction/humanizer.rb +41 -34
- data/lib/humanize_fraction/version.rb +1 -1
- data/lib/humanize_fraction.rb +2 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71e2420b7a27230601ab8ae89e38f3097908f13f
|
4
|
+
data.tar.gz: 80455bea8b7ae37f41a686570ced33c3ffa78914
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47ecefd1c758ef9de3c81505d16f6312ff3d339f42929feb7c5f4a992c4056ff430d05c30f599b7b85bc784a9bab666fd75250306ee77d624f75c71b119bf942
|
7
|
+
data.tar.gz: 8a3d6b9e0fd2337dadbf331ad8d17f386d46adc450ca0c4bee112810e458b2acc497fce5cbc300dc47a2b7d4fe50cce8166979283b065bcf218a073aab5ae9da
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# humanize_fraction [](https://circleci.com/gh/6/humanize_fraction)
|
1
|
+
# humanize_fraction [](https://circleci.com/gh/6/humanize_fraction) [](https://rubygems.org/gems/humanize_fraction)
|
2
2
|
|
3
3
|
Rubygem to convert fraction to words, like 1 ⅓ => one and a third. Examples:
|
4
4
|
|
@@ -15,6 +15,28 @@ Rubygem to convert fraction to words, like 1 ⅓ => one and a third. Examples:
|
|
15
15
|
#=> "a millionth"
|
16
16
|
"222/333".humanize_fraction
|
17
17
|
#=> "two hundred and twenty-two three hundred thirty-thirds"
|
18
|
+
"1/1000000000000000000000000000".humanize_fraction(shorthand: true)
|
19
|
+
#=> "an octillionth"
|
20
|
+
```
|
21
|
+
|
22
|
+
If you don't want to monkey patch `String`, you can also use the Humanizer class directly:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# From a string:
|
26
|
+
fraction = HumanizeFraction::Humanizer.from_string("2 1/4")
|
27
|
+
|
28
|
+
# From integers:
|
29
|
+
fraction = HumanizeFraction::Humanizer.new(
|
30
|
+
whole_part: 2,
|
31
|
+
numerator: 1,
|
32
|
+
denominator: 4,
|
33
|
+
)
|
34
|
+
|
35
|
+
fraction.to_s
|
36
|
+
# => "two and one fourth"
|
37
|
+
|
38
|
+
fraction.to_s(shorthand: true, quarter: true)
|
39
|
+
# => "two and a quarter"
|
18
40
|
```
|
19
41
|
|
20
42
|
## Installation
|
data/humanize_fraction.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_runtime_dependency "activesupport", ">= 4"
|
26
26
|
spec.add_runtime_dependency "humanize", "~> 1.4"
|
27
|
-
spec.add_runtime_dependency "
|
27
|
+
spec.add_runtime_dependency "numbers_and_words", "~> 0.11"
|
28
28
|
|
29
29
|
spec.add_development_dependency "bundler", "~> 1.14"
|
30
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -1,34 +1,37 @@
|
|
1
1
|
module HumanizeFraction
|
2
2
|
class Humanizer
|
3
3
|
# From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
|
4
|
-
SINGLE_FRACTION =
|
5
|
-
MIXED_FRACTION =
|
4
|
+
SINGLE_FRACTION = /\A\s*(\-?\d+)\/(\-?\d+)\s*\z/
|
5
|
+
MIXED_FRACTION = /\A\s*(\-?\d*)\s+(\d+)\/(\d+)\s*\z/
|
6
6
|
|
7
|
-
|
7
|
+
# Numbers that should be prefixed with `a` instead of `an` even though they
|
8
|
+
# start with a vowel.
|
9
|
+
NUMBERS_STARTING_WITH_SILENT_VOWEL = [
|
10
|
+
"one",
|
11
|
+
]
|
8
12
|
|
9
|
-
|
13
|
+
attr_reader :numerator, :denominator, :whole_part
|
14
|
+
|
15
|
+
def initialize(numerator:, denominator:, whole_part: nil)
|
10
16
|
[numerator, denominator].each do |number|
|
11
17
|
if !number.is_a?(Integer)
|
12
18
|
raise ArgumentError, "Expected Integers for numerator/denominator but got #{number.class.name}"
|
13
19
|
end
|
14
20
|
end
|
15
|
-
if !
|
16
|
-
raise ArgumentError, "Expected Integer or NilClass for
|
21
|
+
if !whole_part.nil? && !whole_part.is_a?(Integer)
|
22
|
+
raise ArgumentError, "Expected Integer or NilClass for whole_part but got #{whole_part.class.name}"
|
17
23
|
end
|
18
|
-
@
|
24
|
+
@whole_part = whole_part
|
19
25
|
@numerator = numerator
|
20
26
|
@denominator = denominator
|
21
|
-
@shorthand = shorthand
|
22
|
-
@quarter = quarter
|
23
27
|
end
|
24
|
-
alias_method :quarter?, :quarter
|
25
|
-
alias_method :shorthand?, :shorthand
|
26
28
|
|
27
|
-
def to_s
|
29
|
+
def to_s(shorthand: false, quarter: false)
|
30
|
+
humanized_denominator = humanize_denominator(shorthand: shorthand, quarter: quarter)
|
28
31
|
words = []
|
29
|
-
words <<
|
30
|
-
words << humanize_numerator
|
31
|
-
words <<
|
32
|
+
words << humanize_whole_part if !whole_part.nil?
|
33
|
+
words << humanize_numerator(humanized_denominator, shorthand: shorthand)
|
34
|
+
words << humanized_denominator
|
32
35
|
words.join(" ")
|
33
36
|
end
|
34
37
|
|
@@ -38,7 +41,7 @@ module HumanizeFraction
|
|
38
41
|
end
|
39
42
|
if string_is_mixed_fraction?(string)
|
40
43
|
whole, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
|
41
|
-
new(
|
44
|
+
new(whole_part: whole, numerator: numerator, denominator: denominator, **options)
|
42
45
|
elsif string_is_single_fraction?(string)
|
43
46
|
numerator, denominator = string.split("/").map(&:to_i)
|
44
47
|
new(numerator: numerator, denominator: denominator, **options)
|
@@ -49,32 +52,31 @@ module HumanizeFraction
|
|
49
52
|
|
50
53
|
private
|
51
54
|
|
52
|
-
def
|
53
|
-
"#{
|
55
|
+
def humanize_whole_part
|
56
|
+
"#{whole_part.humanize} and"
|
54
57
|
end
|
55
58
|
|
56
|
-
def humanize_numerator
|
57
|
-
number = if numerator == 1 && shorthand
|
58
|
-
|
59
|
-
|
59
|
+
def humanize_numerator(humanized_denominator, shorthand:)
|
60
|
+
number = if numerator == 1 && shorthand
|
61
|
+
first_number = humanized_denominator.split(" ").first
|
62
|
+
indefinite_article(first_number)
|
60
63
|
else
|
61
64
|
numerator.humanize
|
62
65
|
end
|
63
66
|
number
|
64
67
|
end
|
65
68
|
|
66
|
-
def humanize_denominator
|
69
|
+
def humanize_denominator(shorthand:, quarter:)
|
67
70
|
number = case denominator
|
68
71
|
when 2
|
69
72
|
"half"
|
70
73
|
when 4
|
71
|
-
quarter
|
74
|
+
quarter ? "quarter" : "fourth"
|
72
75
|
else
|
73
|
-
|
76
|
+
I18n.with_locale(:en) { denominator.to_words(ordinal: true) }
|
74
77
|
end
|
75
78
|
# Handle case of `a millionth`, `a thousandth`, etc.
|
76
|
-
if shorthand
|
77
|
-
first_digit(denominator) == 1 && remaining_digits_zeros?(denominator)
|
79
|
+
if shorthand && denominator >= 100 && one_followed_by_zeros?(denominator)
|
78
80
|
number.sub!(/\Aone\s/, "")
|
79
81
|
end
|
80
82
|
if numerator != 1
|
@@ -83,15 +85,20 @@ module HumanizeFraction
|
|
83
85
|
number
|
84
86
|
end
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
+
# Checks number is a 1 followed by only zeros, e.g. 10 or 10000000
|
89
|
+
def one_followed_by_zeros?(number)
|
90
|
+
digits = number.to_s.split("")
|
91
|
+
first_digit = digits.shift
|
92
|
+
first_digit.to_i == 1 && digits.size > 0 && digits.map(&:to_i).all?(&:zero?)
|
88
93
|
end
|
89
94
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
+
def indefinite_article(humanized_number)
|
96
|
+
if humanized_number.match(/\A[aeiou]/) &&
|
97
|
+
!NUMBERS_STARTING_WITH_SILENT_VOWEL.include?(humanized_number)
|
98
|
+
"an"
|
99
|
+
else
|
100
|
+
"a"
|
101
|
+
end
|
95
102
|
end
|
96
103
|
|
97
104
|
def self.string_is_mixed_fraction?(value)
|
data/lib/humanize_fraction.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "active_support/inflector"
|
2
2
|
require "humanize"
|
3
|
-
|
3
|
+
# TODO: figure out how to use this library without the monkey patching it does.
|
4
|
+
require "numbers_and_words"
|
4
5
|
|
5
6
|
require "humanize_fraction/humanizer"
|
6
7
|
require "humanize_fraction/version"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: humanize_fraction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Graham
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: numbers_and_words
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0.11'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0.11'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|