Skip to content

Commit

Permalink
Merge pull request #28 from balvig/fractions
Browse files Browse the repository at this point in the history
Provide option for preserving amounts
  • Loading branch information
iancanderson committed Aug 19, 2016
2 parents effe7b2 + fa545c2 commit 246a7e3
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 27 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ print result.ingredient
#=> "sucre"
```

### Handling amounts

By default, Ingreedy will convert all amounts to a rational number:

```ruby
result = Ingreedy.parse("1 1/2 cups flour")
print result.amount
#=> 3/2
```

However, setting `Ingreedy.preverse_amounts = true`, will allow amounts
to be detected and returned as originally input:

```ruby
Ingreedy.preserve_amounts = true

result = Ingreedy.parse("1 1/2 cups flour")
print result.amount
#=> 1 1/2
```

[Live demo](http://hangryingreedytest.herokuapp.com/)

# Pieces of Flair
Expand Down
8 changes: 2 additions & 6 deletions lib/ingreedy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@
module Ingreedy
ParseFailed = Class.new(StandardError)

def self.locale
@locale ||= nil
end

def self.locale=(locale)
@locale = locale
class << self
attr_accessor :locale, :preserve_amounts
end

def self.parse(query)
Expand Down
48 changes: 27 additions & 21 deletions lib/ingreedy/rationalizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,43 @@ def initialize(options)
end

def rationalize
if @word
result = rationalize_word
elsif @fraction
result = rationalize_fraction
if @integer
result += @integer.to_i
end
elsif @integer
result = @integer.to_r
elsif @float
result = @float.tr(",", ".").to_r
if Ingreedy.preserve_amounts
(normalized_word || compound_fraction || @float || @integer)
else
(normalized_word || rationalized_fraction || rationalized_float || @integer).to_r
end

result
end

private

def rationalize_fraction
vulgar_fractions.each do |char, amount|
@fraction.gsub!(char, amount.to_s)
def normalized_word
return unless @word
Ingreedy.dictionaries.current.numbers[@word.downcase]
end

def normalized_fraction
@fraction.tap do |fraction|
Ingreedy.dictionaries.current.vulgar_fractions.each do |char, amount|
fraction.gsub!(char, amount.to_s)
end
end
@fraction.to_r
end

def vulgar_fractions
Ingreedy.dictionaries.current.vulgar_fractions
def rationalized_fraction
return unless @fraction
result = normalized_fraction
result = result.to_r + @integer.to_i
result
end

def rationalize_word
Ingreedy.dictionaries.current.numbers[@word.downcase]
def compound_fraction
return unless @fraction
"#{@integer} #{normalized_fraction}".strip
end

def rationalized_float
return unless @float
@float.tr(",", ".")
end
end
end
26 changes: 26 additions & 0 deletions spec/ingreedy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@
end
end

describe Ingreedy, "amount parsing preserving original value" do
around do |example|
Ingreedy.preserve_amounts = true
example.run
Ingreedy.preserve_amounts = false
end

{
"1 cup flour" => "1",
"2 cups flour" => "2",
"1 1/2 cups flour" => "1 1/2",
"¼ cups flour" => "1/4",
"1 ½ cups flour" => "1 1/2",
"1½ cups flour" => "1 1/2",
"1.0 cup flour" => "1.0",
"1.5 cups flour" => "1.5",
"1,5 cups flour" => "1,5",
"1/2 cups flour" => "1/2",
".25 cups flour" => ".25",
}.each do |query, expected|
it "parses the correct amount" do
expect(Ingreedy.parse(query).amount).to eq(expected)
end
end
end

describe Ingreedy, "english units" do
context "abbreviated" do
{
Expand Down

0 comments on commit 246a7e3

Please sign in to comment.