+++ /dev/null
-# Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
-#
-# This file is part of Cookbook.
-#
-# Cookbook is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# Cookbook is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Cookbook. If not, see <http://www.gnu.org/licenses/>.
-
-"""Hack parser for standardizing my Mom's cookbook text.
-"""
-
-from .cookbook import (
- Cookbook, Recipe, IngredientBlock, Ingredient, Amount, Directions)
-
-
-class MomParser (object):
- def parse(self, filename):
- c = Cookbook()
- consecutive_blanks = 100
- recipe_lines = None
- for line in file(filename, 'r'):
- line = line.strip().decode('utf-8')
- if line == '':
- if recipe_lines != None and consecutive_blanks == 0:
- recipe_lines.append('')
- consecutive_blanks += 1
- continue
- if consecutive_blanks >= 2:
- if recipe_lines != None:
- c.append(self._parse_recipe(recipe_lines))
- recipe_lines = [line]
- else:
- recipe_lines.append(line)
- consecutive_blanks = 0
- return c
-
- def _parse_recipe(self, lines):
- name = lines.pop(0)
- yield_,author,source,url,lines = self._parse_yield_line(lines)
- ingredient_blocks,lines = self._parse_ingredient_blocks(lines)
- directions,lines = self._parse_directions(lines)
- assert len(lines) == 0, lines
- return Recipe(
- name=name,
- ingredient_blocks=ingredient_blocks,
- directions=directions,
- yield_=yield_,
- author=author,
- source=source,
- url=url)
-
- def _parse_yield_line(self, lines):
- while len(lines) > 0 and lines[0] == '':
- lines.pop(0)
- fields = ['yield', 'from', 'source', 'url']
- yield_ = author = source = url = None
- matching_line = False
- for field in fields:
- if field in lines[0].lower():
- matching_line = True
- break
- if matching_line == True:
- bits = lines.pop(0).split('\t')
- for bit in bits:
- for field in fields:
- if bit.lower().startswith(field+':'):
- value = bit[len(field+':'):].strip()
- if field == 'yield':
- yield_ = value.replace('Serving', 'serving')
- elif field == 'from':
- author = value
- elif field == 'source':
- source = value
- elif field == 'url':
- url = value
- break
- return (yield_, author, source, url, lines)
-
- def _parse_ingredient_blocks(self, lines):
- ingredient_blocks = []
- first_block = True
- while True:
- while len(lines) > 0 and lines[0] == '': # scroll past blanks
- lines.pop(0)
- if (len(lines) == 0
- or not (first_block == True
- or lines[0].endswith(':'))):
- break
- if lines[0].endswith(':'):
- line = lines.pop(0)
- name = line[:-1].strip()
- else:
- name = None
- block = IngredientBlock(name)
- while len(lines) > 0 and lines[0] != '':
- block.append(self._parse_ingredient_line(lines.pop(0)))
- ingredient_blocks.append(block)
- first_block = False
- return (ingredient_blocks, lines)
-
- def _parse_ingredient_line(self, line):
- if line.lower().startswith('1 red'):
- line = '1 # red'+line[len('1 red'):]
- try:
- value,units,name = line.split(' ', 2)
- except ValueError:
- print line,
- raise
- if units == '#':
- units = None
- elif units == 'Large':
- units = 'large'
- elif units == 'Cloves':
- units = 'cloves'
- return Ingredient(name, Amount(value, units))
-
- def _parse_directions(self, lines):
- directions = Directions()
- paragraph = []
- for line in lines:
- if line == '':
- if len(paragraph) > 0:
- directions.append('\n'.join(paragraph))
- paragraph = []
- else:
- paragraph.append(line)
- return (directions, [])