Skip to content

Instantly share code, notes, and snippets.

@alexkrolick
Last active March 26, 2025 01:47
Show Gist options
  • Save alexkrolick/11beb8d72c6584c6ba6ea8a1866aa53d to your computer and use it in GitHub Desktop.
Save alexkrolick/11beb8d72c6584c6ba6ea8a1866aa53d to your computer and use it in GitHub Desktop.
Recipe Parser
#!/usr/bin/env node
// Requires Node 14+
const fs = require('fs/promises');
const yaml = require('yaml');
const markdown = require('micromark');
async function main () {
const recipeFiles = await fs.readdir('./recipes');
let recipesByCategory = {};
for (const filepath of recipeFiles) {
if (filepath.endsWith('.yml')) {
const recipeStr = await fs.readFile('./recipes/' + filepath, 'utf8');
let recipeObj = yaml.parse(recipeStr);
recipeObj.html = await recipe2html(recipeObj);
// console.log(recipeObj.html)
const category = recipeObj.category || 'Other';
recipesByCategory[category] = (recipesByCategory[category] || [])
.concat(recipeObj);
}
}
const byPublishedDate = (i, j) => {
return (i.published_at > j.published_at) ? -1
: (i.published_at < j.published_at) ? 1
: 0;
}
const contentsHtml = `
<ul id="recipe-list" class="note">
${Object.entries(recipesByCategory).map(([category, recipes]) => {
return `\
<li>${category}
<ul>
${recipes.sort(byPublishedDate).map(recipe => {
return `\
<li><a href="#${recipe.id}">${recipe.title}</a></li>`;
}).join('\n')}
</ul>
</li>`;
}).join('\n')}
</ul>
`;
const recipesHtml = `
<div id="recipes">
${Object.entries(recipesByCategory).map(([category, recipes]) => {
return `\
<h2>${category}</h2>
${recipes.sort(byPublishedDate).map(recipe => recipe.html).join('\n')}
`
}).join('\n')}
</div>
`;
await fs.writeFile('../_contents.html', contentsHtml);
await fs.writeFile('../_recipes.html', recipesHtml);
}
async function recipe2html(r) {
// console.log(JSON.stringify(r, null, 2))
const html = `
<article itemscope itemtype="http://schema.org/Recipe" id="${r.id}">
<h3 itemprop="name">${r.title}</h3>
<p class="author">
By <span itemprop="author">${r.author}</span>
</p>
<p>
<meta itemprop="datePublished" content="${r.published_at}" />
<strong>${new Date(r.published_at).toLocaleDateString()}</strong>
<em>${r.category}</em>
</p>
<div itemprop="description">
${markdown(r.description)}
</div>
<section>
<h4>Prep Time</h4>
<ul class="prep">
<li>
Prep Time: <meta itemprop="prepTime" content="PT${r.prep_time}" />
${r.prep_time}
</li>
<li>
Cook time: <meta itemprop="cookTime" content="PT${r.cook_time}" />
${r.cook_time}
</li>
<li>
Yield: <span itemprop="recipeYield">${r.yield}</span>
</li>
</ul>
</section>
<section>
<h4>Ingredients</h4>
<ul class="ingredients">
${r.ingredients.map(i => {
// TODO: parse quantities to allow scaling recipe
return `\
<li itemprop="recipeIngredient">
${i}
</li>`;
}).join('\n')}
</ul>
</section>
<section>
<h4>Instructions</h4>
<ul itemprop="recipeInstructions">
${r.steps.map(step => {
return `\
<li itemprop="step">
${markdown(step)}
</li>`;
}).join('\n')}
</ul>
</section>
</article>
`;
return html;
}
main();
id: banana-bread
title: Banana Bread w/Sweet Potato and Pecans
author: Alex Krolick
published_at: 2020-06-10
category: Bakery
prep_time: 20M
cook_time: 1H
yield: 8 servings
description: |
Based on this recipe: [Best Banana Bread](https://cookpad.com/us/recipes/4042250-best-banana-bread)
Substitute 1 banana (use 3 instead of 4) with about 1/3 cup cooked +
mashed sweet potato insides. Add some chopped roasted pecans to the mix,
and sprinkle some more on top.
I baked it more than an hour (1H15M) since it was in one big loaf pan instead of
the standard banana bread size (small) tins.
ingredients:
- 1 1/2 cup all-purpose flour
- 3 soft bananas with lots of brown spots
- 1/3 cup sweet potato, cooked and mashed
- 1/4 cup roast pecans, chopped
- 1/3 cup butter
- 2/3 cups white sugar
- 2 tbsp turbinado or brown sugar
- 1 egg
- 1 teaspoon vanilla extract
- 1 tsp baking soda
- 1 pinch salt
- 1/4 teaspoon ground cinnamon
- 1 pinch ground nutmeg
steps:
- Preheat oven to 350F.
- Melt butter in a pan. When it starts to turn brown, remove from heat and
let cool while you do the next steps.
- >
Mash together 3 bananas and 1/3 cup sweet potato in a mixing bowl. I used
about half of a baked sweet potato: bake at 400F for 1 hour with slashes
cut across the top, then scoop out insides.
- Add butter, 1 egg, spices, and 1 tsp baking soda to the bowl
- Mix in 2/3 cup sugar, then 1 1/2 cup flour to the bowl
- Mix in 1/3 cup chopped pecans
- Lightly grease 2 small baking pans, or 1 larger one
- Pour in banana bread mix.
- Sprinkle 2 tbsp brown sugar and more chopped pecans on top.
- Bake for 1 hour if using small pans or about 1:15 if using a single pan.
A toothpick poked into the loaf should come out clean.
- Remove from oven and let cool in the pan for about 15 min before dumping
it out onto a rack. Let it cool before serving.
{
"dependencies": {
"yaml": "*",
"micromark": "*",
}
}
id:
title:
author:
published_at:
category:
prep_time:
cook_time:
yield:
description: |
ingredients:
-
steps:
-
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment