1 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
3 # This file is part of Cookbook.
5 # Cookbook is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation, either version 3 of the License, or (at your
8 # option) any later version.
10 # Cookbook is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Cookbook. If not, see <http://www.gnu.org/licenses/>.
18 """Hack parser for standardizing my Mom's cookbook text.
21 from .cookbook import (
22 Cookbook, Recipe, IngredientBlock, Ingredient, Amount, Directions)
25 class MomParser (object):
26 def parse(self, filename):
28 consecutive_blanks = 100
30 for line in file(filename, 'r'):
31 line = line.strip().decode('utf-8')
33 if recipe_lines != None and consecutive_blanks == 0:
34 recipe_lines.append('')
35 consecutive_blanks += 1
37 if consecutive_blanks >= 2:
38 if recipe_lines != None:
39 c.append(self._parse_recipe(recipe_lines))
42 recipe_lines.append(line)
43 consecutive_blanks = 0
46 def _parse_recipe(self, lines):
48 yield_,author,source,url,lines = self._parse_yield_line(lines)
49 ingredient_blocks,lines = self._parse_ingredient_blocks(lines)
50 directions,lines = self._parse_directions(lines)
51 assert len(lines) == 0, lines
54 ingredient_blocks=ingredient_blocks,
55 directions=directions,
61 def _parse_yield_line(self, lines):
62 while len(lines) > 0 and lines[0] == '':
64 fields = ['yield', 'from', 'source', 'url']
65 yield_ = author = source = url = None
68 if field in lines[0].lower():
71 if matching_line == True:
72 bits = lines.pop(0).split('\t')
75 if bit.lower().startswith(field+':'):
76 value = bit[len(field+':'):].strip()
78 yield_ = value.replace('Serving', 'serving')
81 elif field == 'source':
86 return (yield_, author, source, url, lines)
88 def _parse_ingredient_blocks(self, lines):
89 ingredient_blocks = []
92 while len(lines) > 0 and lines[0] == '': # scroll past blanks
95 or not (first_block == True
96 or lines[0].endswith(':'))):
98 if lines[0].endswith(':'):
100 name = line[:-1].strip()
103 block = IngredientBlock(name)
104 while len(lines) > 0 and lines[0] != '':
105 block.append(self._parse_ingredient_line(lines.pop(0)))
106 ingredient_blocks.append(block)
108 return (ingredient_blocks, lines)
110 def _parse_ingredient_line(self, line):
111 if line.lower().startswith('1 red'):
112 line = '1 # red'+line[len('1 red'):]
114 value,units,name = line.split(' ', 2)
120 elif units == 'Large':
122 elif units == 'Cloves':
124 return Ingredient(name, Amount(value, units))
126 def _parse_directions(self, lines):
127 directions = Directions()
131 if len(paragraph) > 0:
132 directions.append('\n'.join(paragraph))
135 paragraph.append(line)
136 return (directions, [])