diff --git a/recipe.py b/recipe.py index dfd4faa..e204d3f 100644 --- a/recipe.py +++ b/recipe.py @@ -4,122 +4,150 @@ from anytree.importer import DictImporter from sys import argv -def build_table_depth_first(node, rows=None): +class TableCell: + def __init__(self, name, rowspan="", colspan="", description="", is_header=False): + self.name = name + self.rowspan = rowspan + self.colspan = colspan + self.description = description + self.is_header = is_header - if rows is None: - rows = [] - - for child in sorted(node.children, key=lambda x: x.height, reverse=True): - rows = build_table_depth_first(child, rows) - - colspan = 0 - if node.siblings: - max_sibling_height = max([s.height for s in node.siblings]) - - if max_sibling_height > node.height: - colspan = max_sibling_height - node.height + 1 - - if node.is_leaf: - rows.append([f'{node.name}']) - - if colspan > 1: - rows[-1].append(f'') - - else: - child_leaves = len(node.leaves) - cur_row = len(rows) - child_leaves - rows[cur_row].append(f"{node.name}") - - return rows - - -def generate_steps_depth_first(node, steps=[]): - for child in sorted(node.children, key=lambda x: x.height, reverse=True): - steps = generate_steps_depth_first(child, steps) - - if not node.is_leaf: - steps.append(node.description if node.description else node.name) - - return steps - - -if len(argv) < 2: - print(f"usage: {argv[0]} ") - exit() - -with open(argv[1], 'r') as f: - recipe = json.loads(f.read()) - -recipe_name = recipe.get("name") -recipe_desc = recipe.get("description") -importer = DictImporter() -sub_recipes = [importer.import_(data) for data in recipe["sub_recipes"]] - -print("") -print("") -print(f"{recipe_name}") -print("") -print("") -print("") -print("") - -print("
") -print("
") -print(f"

{recipe_name}

") -print("
") - -print("
") -print(f"

{recipe_desc}

") -print("
") -print("
") - -print("
") -print("
") -print("

Needs

") -print("
    ") - -for sub_recipe in sub_recipes: - for ingredient in sub_recipe.leaves: - if ingredient.description: - print(f"
  • {ingredient.name} -- {ingredient.description}
  • ") + def to_html(self): + if self.is_header: + html = f"{self.name}" + elif not self.name: + html = f'' else: - print(f"
  • {ingredient.name}
  • ") + html = f"{self.name}" -print("
") -print("
") + return html -print("
") -print("

Preparation

") -print("
    ") -for sub_recipe in sub_recipes: - tasks = generate_steps_depth_first(sub_recipe, steps=[]) - for task in tasks: - print(f"
  1. {task}
  2. ") +class Recipe: + def __init__(self, json_filename: str): + with open(json_filename, 'r') as f: + recipe_dict = json.loads(f.read()) -print("
") -print("
") -print("
") + self.name = recipe_dict.get("name") + self.desc = recipe_dict.get("description") + importer = DictImporter() + self.sub_recipes = [importer.import_(data) for data in recipe_dict["sub_recipes"]] -print("") -print("

Tabular Layout

") + def generate_ingredient_list(self): + ingredients = [] -for sub_recipe in sub_recipes: - print("

") - print("") + for sub_recipe in self.sub_recipes: + for ingredient in sub_recipe.leaves: + if ingredient.description: + ingredients.append(f"{ingredient.name} -- {ingredient.description}") + else: + ingredients.append(ingredient.name) - output_rows = build_table_depth_first(sub_recipe) + return ingredients - for row in output_rows: - print("") - for cell in row: - print(f" {cell}") - print("") + def generate_task_list(self): + tasks = [] - print("
") - print("

") + for sub_recipe in self.sub_recipes: + tasks.extend(self.generate_steps_depth_first(sub_recipe, steps=[])) -print("
") + return tasks + + def generate_steps_depth_first(self, node, steps=[]): + for child in sorted(node.children, key=lambda x: x.height, reverse=True): + steps = self.generate_steps_depth_first(child, steps) + + if not node.is_leaf: + steps.append(node.description if node.description else node.name) + + return steps + + def generate_tables(self): + tables = [] + + for sub_recipe in self.sub_recipes: + tables.append(self.build_table_rows_depth_first(sub_recipe)) + + return tables + + def build_table_rows_depth_first(self, node, rows=None): + if rows is None: + rows = [] + + for child in sorted(node.children, key=lambda x: x.height, reverse=True): + rows = self.build_table_rows_depth_first(child, rows) + + colspan = 0 + if node.siblings: + max_sibling_height = max([s.height for s in node.siblings]) + + if max_sibling_height > node.height: + colspan = max_sibling_height - node.height + 1 + + if node.is_leaf: + rows.append([TableCell(node.name, description=node.description, is_header=True)]) + + if colspan > 1: + rows[-1].append(TableCell("", colspan=colspan-1)) + + else: + child_leaves = len(node.leaves) + cur_row = len(rows) - child_leaves + rows[cur_row].append(TableCell(node.name, rowspan=child_leaves, colspan=colspan, description=node.description)) + + return rows + + def to_html(self): + return f""" + +{self.name} + + + + + +
+ +

{self.name}

+

{self.desc}

+
+ +
+
+

Needs

+
    +{"\n".join([f"
  • {ingredient}
  • " for ingredient in self.generate_ingredient_list()])} +
+
+ +
+

Preparation

+
    +{"\n".join([f"
  1. {task}
  2. " for task in self.generate_task_list()])} +
+
+
+ + +

Tabular Layout

+{"\n".join( + [f"\n{"".join( + [f"\n{"".join( + [f" {cell.to_html()}\n" for cell in row] + )}\n" for row in table] + )}
" for table in self.generate_tables()] +)} +
+ + + +""" + + +if __name__ == "__main__": + if len(argv) < 2: + print(f"usage: {argv[0]} ") + exit(1) + + print(Recipe(argv[1]).to_html()) -print("") -print("")