From b3be5fa90d9d9f5057a5257d9607377d9ebed0b1 Mon Sep 17 00:00:00 2001
From: gamerdonkey
Date: Sat, 13 Sep 2025 03:12:28 +0000
Subject: [PATCH] Update recipe converter into an object.
---
recipe.py | 240 ++++++++++++++++++++++++++++++------------------------
1 file changed, 134 insertions(+), 106 deletions(-)
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("")
-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" - {task}
")
+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}
+
+
+
+
+
+
+
+
+
+
Needs
+
+{"\n".join([f" - {ingredient}
" for ingredient in self.generate_ingredient_list()])}
+
+
+
+
+
Preparation
+
+{"\n".join([f" - {task}
" 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("")