humanize_fraction 0.1.1 → 0.1.2
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 +4 -4
- data/humanize_fraction.gemspec +1 -0
- data/lib/humanize_fraction.rb +2 -0
- data/lib/humanize_fraction/fraction_string_parser.rb +57 -0
- data/lib/humanize_fraction/humanizer.rb +4 -32
- data/lib/humanize_fraction/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48b87152720622914c2118dd643e7ae53757892a
|
|
4
|
+
data.tar.gz: f4a156d8e3f0c5274544d7dc6c84b9f96c6aa22b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bec3257ee12d4158d8b61de48500614486f6685224299e21101701fbad654c165a9beee9b465ad87c835c3994a238b325a4f510c7ea90b7b4571b4f8962a3a5
|
|
7
|
+
data.tar.gz: 25155b9bd6c6c63df47e2cd205c1e126e40464a0c082c00c909b81df270fc1b9caa80bc44d2ad846b32136fe5d0bbd7d115b389901ad45881b2b3300e48301ff
|
data/README.md
CHANGED
|
@@ -7,10 +7,10 @@ Rubygem to convert fraction to words, like 1 ⅓ => one and a third. Examples:
|
|
|
7
7
|
#=> "one eighth"
|
|
8
8
|
"1/8".humanize_fraction(shorthand: true)
|
|
9
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"
|
|
10
|
+
"-2 3/4".humanize_fraction
|
|
11
|
+
#=> "negative two and three fourths"
|
|
12
|
+
"-2 3/4".humanize_fraction(quarter: true)
|
|
13
|
+
#=> "negative two and three quarters"
|
|
14
14
|
"1/1000000".humanize_fraction(shorthand: true)
|
|
15
15
|
#=> "a millionth"
|
|
16
16
|
"222/333".humanize_fraction
|
data/humanize_fraction.gemspec
CHANGED
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.add_runtime_dependency "activesupport", ">= 4"
|
|
26
26
|
spec.add_runtime_dependency "humanize", "~> 1.4"
|
|
27
27
|
spec.add_runtime_dependency "numbers_and_words", "~> 0.11"
|
|
28
|
+
spec.add_runtime_dependency "sig", "~> 1.0"
|
|
28
29
|
|
|
29
30
|
spec.add_development_dependency "bundler", "~> 1.14"
|
|
30
31
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/humanize_fraction.rb
CHANGED
|
@@ -2,8 +2,10 @@ 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
4
|
require "numbers_and_words"
|
|
5
|
+
require "sig"
|
|
5
6
|
|
|
6
7
|
require "humanize_fraction/humanizer"
|
|
8
|
+
require "humanize_fraction/fraction_string_parser"
|
|
7
9
|
require "humanize_fraction/version"
|
|
8
10
|
require "core_extensions/string/humanize_fraction"
|
|
9
11
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# This class takes a fraction string (e.g. "1 3/4") and parses it into the
|
|
2
|
+
# individual fraction components of whole_part, numerator, and denominator.
|
|
3
|
+
module HumanizeFraction
|
|
4
|
+
class FractionStringParser
|
|
5
|
+
# From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
|
|
6
|
+
SINGLE_FRACTION = /\A\s*(\-?\d+)\s*\/\s*(\-?\d+)\s*\z/
|
|
7
|
+
MIXED_FRACTION = /\A\s*(\-?\d*)\s+(\d+)\s*\/\s*(\d+)\s*\z/
|
|
8
|
+
|
|
9
|
+
attr_reader :string
|
|
10
|
+
sig String,
|
|
11
|
+
def initialize(string)
|
|
12
|
+
@string = string
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fraction_components
|
|
16
|
+
@fraction_components ||= begin
|
|
17
|
+
if string_is_mixed_fraction?
|
|
18
|
+
mixed_fraction_components
|
|
19
|
+
elsif string_is_single_fraction?
|
|
20
|
+
single_fraction_components
|
|
21
|
+
else
|
|
22
|
+
raise ArgumentError, "Unable to extract fraction from string #{string}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def mixed_fraction_components
|
|
30
|
+
whole_part, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
|
|
31
|
+
components = {whole_part: whole_part, numerator: numerator, denominator: denominator}
|
|
32
|
+
validate_fraction_components(components)
|
|
33
|
+
components
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def single_fraction_components
|
|
37
|
+
numerator, denominator = string.split("/").map(&:to_i)
|
|
38
|
+
components = {whole_part: nil, numerator: numerator, denominator: denominator}
|
|
39
|
+
validate_fraction_components(components)
|
|
40
|
+
components
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def string_is_mixed_fraction?
|
|
44
|
+
string.match(MIXED_FRACTION)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def string_is_single_fraction?
|
|
48
|
+
string.match(SINGLE_FRACTION)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def validate_fraction_components(components)
|
|
52
|
+
if components[:denominator].zero?
|
|
53
|
+
raise ArgumentError, "Unable to parse fraction with zero denominator"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
module HumanizeFraction
|
|
2
2
|
class Humanizer
|
|
3
|
-
# From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
|
|
4
|
-
SINGLE_FRACTION = /\A\s*(\-?\d+)\/(\-?\d+)\s*\z/
|
|
5
|
-
MIXED_FRACTION = /\A\s*(\-?\d*)\s+(\d+)\/(\d+)\s*\z/
|
|
6
|
-
|
|
7
3
|
# Numbers that should be prefixed with `a` instead of `an` even though they
|
|
8
4
|
# start with a vowel.
|
|
9
5
|
NUMBERS_STARTING_WITH_SILENT_VOWEL = [
|
|
@@ -12,15 +8,8 @@ module HumanizeFraction
|
|
|
12
8
|
|
|
13
9
|
attr_reader :numerator, :denominator, :whole_part
|
|
14
10
|
|
|
11
|
+
sig [{numerator: Integer, denominator: Integer, whole_part: [NilClass, Integer]}],
|
|
15
12
|
def initialize(numerator:, denominator:, whole_part: nil)
|
|
16
|
-
[numerator, denominator].each do |number|
|
|
17
|
-
if !number.is_a?(Integer)
|
|
18
|
-
raise ArgumentError, "Expected Integers for numerator/denominator but got #{number.class.name}"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
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}"
|
|
23
|
-
end
|
|
24
13
|
@whole_part = whole_part
|
|
25
14
|
@numerator = numerator
|
|
26
15
|
@denominator = denominator
|
|
@@ -35,19 +24,10 @@ module HumanizeFraction
|
|
|
35
24
|
words.join(" ")
|
|
36
25
|
end
|
|
37
26
|
|
|
27
|
+
sig_self [String, Hash],
|
|
38
28
|
def self.from_string(string, options = {})
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
if string_is_mixed_fraction?(string)
|
|
43
|
-
whole, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
|
|
44
|
-
new(whole_part: whole, numerator: numerator, denominator: denominator, **options)
|
|
45
|
-
elsif string_is_single_fraction?(string)
|
|
46
|
-
numerator, denominator = string.split("/").map(&:to_i)
|
|
47
|
-
new(numerator: numerator, denominator: denominator, **options)
|
|
48
|
-
else
|
|
49
|
-
raise ArgumentError, "Unable to extract fraction from string #{string}"
|
|
50
|
-
end
|
|
29
|
+
parser = FractionStringParser.new(string)
|
|
30
|
+
new(**parser.fraction_components, **options)
|
|
51
31
|
end
|
|
52
32
|
|
|
53
33
|
private
|
|
@@ -100,13 +80,5 @@ module HumanizeFraction
|
|
|
100
80
|
"a"
|
|
101
81
|
end
|
|
102
82
|
end
|
|
103
|
-
|
|
104
|
-
def self.string_is_mixed_fraction?(value)
|
|
105
|
-
value&.match(MIXED_FRACTION)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def self.string_is_single_fraction?(value)
|
|
109
|
-
value&.match(SINGLE_FRACTION)
|
|
110
|
-
end
|
|
111
83
|
end
|
|
112
84
|
end
|
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.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Graham
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0.11'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: sig
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: bundler
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -126,6 +140,7 @@ files:
|
|
|
126
140
|
- humanize_fraction.gemspec
|
|
127
141
|
- lib/core_extensions/string/humanize_fraction.rb
|
|
128
142
|
- lib/humanize_fraction.rb
|
|
143
|
+
- lib/humanize_fraction/fraction_string_parser.rb
|
|
129
144
|
- lib/humanize_fraction/humanizer.rb
|
|
130
145
|
- lib/humanize_fraction/version.rb
|
|
131
146
|
homepage: https://github.com/6/humanize_fraction
|