feat(recipes): import Tempeh Bacon and Tomato Powder

- Fix recipe steps, cookware, and emojis for Copycat Texas Roadhouse Rolls
- Import Tempeh Bacon recipe (Fixes #1402)
- Import Tomato Powder recipe (Fixes #1404)
This commit is contained in:
nιcнolaѕ wιlde
2026-07-02 07:03:41 -07:00
parent ba56489ba7
commit 5f0ce28e3a
40 changed files with 333 additions and 179 deletions

View File

@ -37,7 +37,7 @@ This skill utilizes the manual recipe import orchestrator script (`import_manual
The orchestrator will:
- Copy the `.cook` and image files to their correct staging folder under `cook/`.
- Run `move.sh` to generate the Markdown file in `docs/` and convert the image to WebP.
- Run `check-recipe-emojis.py --fix` to verify emojis in `includes/emoji.yaml` (using keyword heuristics and fuzzy similarity matching).
- Run `convert-recipe-units.py` to annotate volumetric units with weights and prepend ingredient emojis.
- Run `check_recipe_emojis.py --fix` to verify emojis in `includes/emoji.yaml` (using keyword heuristics and fuzzy similarity matching).
- Run `convert_recipe_units.py` to annotate volumetric units with weights and prepend ingredient emojis.
- Run `generate_typos_config.py` and spellcheck the single file using `typos`, whitelisting and sorting proper nouns via `whitelist_typos.py`.
- Search relevant GitHub issues using the `gh` CLI (if available) and perform a conventional git commit.

View File

@ -72,7 +72,7 @@ For recipes missing an image asset entirely:
3. Optimize and convert it using the image optimizer:
```bash
./scripts/optimize-images.sh
./scripts/optimize_images.sh
```
---

View File

@ -27,7 +27,7 @@ When a new `.cook` recipe file is compiled, relocate it to its final destination
* **Under the Hood**: Invokes [scripts/move.sh](file:///home/nicholas/git/nicholaswilde/recipes/scripts/move.sh),
which compiles the markdown, moves images, adds navigation configuration to `zensical.toml` via
[scripts/add-recipe-nav.py](file:///home/nicholas/git/nicholaswilde/recipes/scripts/add-recipe-nav.py),
[scripts/add_recipe_nav.py](file:///home/nicholas/git/nicholaswilde/recipes/scripts/add_recipe_nav.py),
and runs validation.
#### Commit Recipe Changes
@ -80,7 +80,7 @@ To orchestrate the entire recipe import process (scraping, moving, emoji matchin
uv run scripts/import_recipe_workflow.py <URL_or_issue> [category]
```
* **Under the Hood**: Runs `scripts/scrape_to_cook.py` to scrape the recipe from a URL or extracted URL from a GitHub issue description. Relocates it using `scripts/move.sh`, runs `scripts/check-recipe-emojis.py --fix` to verify emojis, `scripts/convert-recipe-units.py` to convert volume measurements to weight, and runs the typos spellchecker. It detects and prompts (or auto-whitelists in non-interactive modes) proper nouns flagged by the spellchecker using `scripts/whitelist_typos.py`.
* **Under the Hood**: Runs `scripts/scrape_to_cook.py` to scrape the recipe from a URL or extracted URL from a GitHub issue description. Relocates it using `scripts/move.sh`, runs `scripts/check_recipe_emojis.py --fix` to verify emojis, `scripts/convert_recipe_units.py` to convert volume measurements to weight, and runs the typos spellchecker. It detects and prompts (or auto-whitelists in non-interactive modes) proper nouns flagged by the spellchecker using `scripts/whitelist_typos.py`.
#### Manual Recipe Import Orchestrator
@ -92,7 +92,7 @@ To orchestrate the import, emoji checking/fixing, unit conversion, spelling vali
uv run scripts/import_manual_recipe.py <cook_file> [-i <image_path>] [-c <category>] [-n <issue_number>] [--commit]
```
* **Under the Hood**: Copies/moves the manual `.cook` and optional image file to the correct category directory inside `cook/`, runs `scripts/move.sh` to compile it to markdown and copy/convert images, runs `scripts/check-recipe-emojis.py --fix` to automatically map missing emojis, `scripts/convert-recipe-units.py` to format units and insert emojis, and runs `typos` with auto-whitelisting of proper nouns. Optionally prompts for GitHub issues and automates conventional git commits.
* **Under the Hood**: Copies/moves the manual `.cook` and optional image file to the correct category directory inside `cook/`, runs `scripts/move.sh` to compile it to markdown and copy/convert images, runs `scripts/check_recipe_emojis.py --fix` to automatically map missing emojis, `scripts/convert_recipe_units.py` to format units and insert emojis, and runs `typos` with auto-whitelisting of proper nouns. Optionally prompts for GitHub issues and automates conventional git commits.
#### Automated PDF Recipe Import Workflow
@ -131,7 +131,7 @@ weight-annotated strings (grams) on a recipe's markdown file:
* **Protocol**:
```bash
uv run scripts/convert-recipe-units.py docs/category/recipe.md
uv run scripts/convert_recipe_units.py docs/category/recipe.md
```
* **Under the Hood**: Cross-references ingredients with [includes/emoji.yaml](file:///home/nicholas/git/nicholaswilde/recipes/includes/emoji.yaml) and [docs/reference/measuring.md](file:///home/nicholas/git/nicholaswilde/recipes/docs/reference/measuring.md).
@ -156,13 +156,13 @@ To convert all JPEGs to WebP, optimize PNGs, and update all Markdown recipe refe
```bash
# Globally
bash scripts/optimize-images.sh
bash scripts/optimize_images.sh
# For a specific category
bash scripts/optimize-images.sh [category]
bash scripts/optimize_images.sh [category]
```
* **Under the Hood**: Invokes [scripts/optimize-images.sh](file:///home/nicholas/git/nicholaswilde/recipes/scripts/optimize-images.sh),
* **Under the Hood**: Invokes [scripts/optimize_images.sh](file:///home/nicholas/git/nicholaswilde/recipes/scripts/optimize_images.sh),
which converts JPEGs to `.webp` (using `cwebp` with a Python Pillow fallback to salvage truncated/corrupted JPEGs),
deletes the original files, updates all Markdown recipe references, and runs `oxipng` to optimize PNG files.
@ -205,7 +205,7 @@ To check if all ingredients or cookware used in a `.cook` recipe are registered
* **Protocol**:
```bash
uv run scripts/check-recipe-emojis.py cook/category/recipe.cook
uv run scripts/check_recipe_emojis.py cook/category/recipe.cook
```
To automatically map and fix missing emojis in `includes/emoji.yaml` using similarity checking and fallback groups:
@ -213,7 +213,7 @@ To automatically map and fix missing emojis in `includes/emoji.yaml` using simil
* **Protocol**:
```bash
uv run scripts/check-recipe-emojis.py --fix cook/category/recipe.cook
uv run scripts/check_recipe_emojis.py --fix cook/category/recipe.cook
```
* **Under the Hood**: Compares missing terms against existing emoji mappings using keyword-based heuristics (e.g. `cheese` -> `cheese_wedge`, `chili`/`pepper` -> `hot_pepper`, `onion`/`scallion` -> `tea`, `tomato`/`salsa` -> `tomato`, `cream`/`milk`/`butter` -> `glass_of_milk`, cookware containing `pan`/`skillet`/`pot`/`spoon`/`whisk` -> `bowl_with_spoon`), substring matching, word-overlap, and SequenceMatcher similarity. Confident matches are inserted under the matched emoji group, while unmatched terms fallback to generic categories (`takeout_box` for ingredients and `bowl_with_spoon` for cookware). Finally, it runs `task emoji-sort` to maintain ordering.

View File

@ -20,7 +20,7 @@ tasks:
check-header-emojis:
desc: Check recipes for missing H1 header emoji shortcodes.
cmds:
- 'uv run scripts/check-header-emojis.py {{ .CLI_ARGS }}'
- 'uv run scripts/check_header_emojis.py {{ .CLI_ARGS }}'
build:
desc: Build the static site
cmds:
@ -105,12 +105,12 @@ tasks:
lint-changed:
desc: Lint only modified/changed files (saves tokens)
cmds:
- uv run python3 scripts/lint-changed.py
- uv run python3 scripts/lint_changed.py
git-summary:
desc: Show a token-efficient summary of git workspace status and changes
cmds:
- uv run python3 scripts/git-summary.py
- uv run python3 scripts/git_summary.py
shuck:
desc: Run shuck shell linter
@ -119,7 +119,7 @@ tasks:
list-ingredients:
desc: List all ingredients in all cook recipes and copy to clipboard.
cmds:
- ./scripts/list-ingredients.sh
- ./scripts/list_ingredients.sh
markdownlint:
desc: Run markdownlint-cli
cmds:
@ -199,14 +199,14 @@ tasks:
desc: Hyperlink an ingredient in a recipe markdown file
cmds:
- >-
uv run python3 scripts/hyperlink-ingredient.py
uv run python3 scripts/hyperlink_ingredient.py
--target {{shellQuote .TARGET}}
--ingredient {{shellQuote .INGREDIENT}}
hyperlink-ingredient-global:
desc: Hyperlink an ingredient globally in all recipe markdown files
cmds:
- >-
uv run python3 scripts/hyperlink-ingredient-global.py
uv run python3 scripts/hyperlink_ingredient_global.py
--ingredient {{shellQuote .INGREDIENT}}
deg:
desc: Replace temperatures with degree symbols

View File

@ -173,6 +173,7 @@ extend-exclude = [
"Chickenless" = "Chickenless"
"Chilero" = "Chilero"
"Chiles" = "Chiles"
"Chilis" = "Chilis"
"Chilli" = "Chilli"
"Chimichurri" = "Chimichurri"
"Chipotle" = "Chipotle"
@ -482,6 +483,7 @@ extend-exclude = [
"Realfruit" = "Realfruit"
"RedHot" = "RedHot"
"Refried" = "Refried"
"Rehydrate" = "Rehydrate"
"Reine" = "Reine"
"Relleno" = "Relleno"
"Rempejek" = "Rempejek"
@ -793,6 +795,7 @@ extend-exclude = [
"dauphine" = "dauphine"
"de" = "de"
"deglaze" = "deglaze"
"deglazing" = "deglazing"
"dehusked" = "dehusked"
"delicata" = "delicata"
"demerara" = "demerara"
@ -1100,6 +1103,7 @@ extend-exclude = [
"refried" = "refried"
"rehydrate" = "rehydrate"
"rehydrated" = "rehydrated"
"rehydrating" = "rehydrating"
"reinvert" = "reinvert"
"rempejek" = "rempejek"
"rempeyek" = "rempeyek"
@ -1139,6 +1143,7 @@ extend-exclude = [
"snickerdoodles" = "snickerdoodles"
"snuggly" = "snuggly"
"soba" = "soba"
"soffritto" = "soffritto"
"sojae" = "sojae"
"soto" = "soto"
"soufflé" = "soufflé"

View File

@ -4,5 +4,5 @@
"status": "completed",
"created_at": "2026-06-14T07:14:00Z",
"updated_at": "2026-06-14T07:14:00Z",
"description": "Add auto-fix/interactive mapping capabilities to check-recipe-emojis.py to automate adding missing emojis to includes/emoji.yaml."
"description": "Add auto-fix/interactive mapping capabilities to check_recipe_emojis.py to automate adding missing emojis to includes/emoji.yaml."
}

View File

@ -2,7 +2,7 @@
## Phase 1: Implementation & Validation [checkpoint: cbbd0fa2]
- [x] Task: Update `scripts/check-recipe-emojis.py` with `--fix` Flag (3091df5)
- [x] Task: Update `scripts/check_recipe_emojis.py` with `--fix` Flag (3091df5)
- [x] Implement command line argument parsing for `--fix`.
- [x] Implement similarity checking against mapped items in `includes/emoji.yaml`.
- [x] Implement YAML writing logic to insert new items under matched emoji keys.

View File

@ -1,7 +1,7 @@
# Specification - Auto-Emoji Mapper Script Option
## Overview
Enhance `scripts/check-recipe-emojis.py` with an auto-fixing mechanism (e.g. via a `--fix` CLI flag) to automatically append missing ingredients and cookware terms to `includes/emoji.yaml` under the most appropriate emoji groups, avoiding manual YAML edits.
Enhance `scripts/check_recipe_emojis.py` with an auto-fixing mechanism (e.g. via a `--fix` CLI flag) to automatically append missing ingredients and cookware terms to `includes/emoji.yaml` under the most appropriate emoji groups, avoiding manual YAML edits.
## Functional Requirements
1. **Detection:** Runs the existing check logic to find missing ingredients or cookware terms.
@ -14,7 +14,7 @@ Enhance `scripts/check-recipe-emojis.py` with an auto-fixing mechanism (e.g. via
4. **Command CLI:**
- Invoked via:
```bash
uv run scripts/check-recipe-emojis.py --fix <recipe_path.cook>
uv run scripts/check_recipe_emojis.py --fix <recipe_path.cook>
```
## Acceptance Criteria

View File

@ -4,7 +4,7 @@
- [x] Task: Create `scripts/import_recipe_workflow.py` (be8ae71)
- [x] Implement argument parsing (`url/issue`, `category`).
- [x] Add subprocess execution for `scrape_to_cook.py`, `task move`, `check-recipe-emojis.py --fix`, `convert-recipe-units.py`, and `task spellcheck`.
- [x] Add subprocess execution for `scrape_to_cook.py`, `task move`, `check_recipe_emojis.py --fix`, `convert_recipe_units.py`, and `task spellcheck`.
- [x] Implement auto-whitelisting logic for spellchecking failures.
- [x] Task: Update Agent Skill Documentation (0a8a0e9)
- [x] Edit `.agents/skills/import-recipe.md` to replace the manual multi-step workflow with instructions to run `scripts/import_recipe_workflow.py`.

View File

@ -8,8 +8,8 @@ Develop a Python orchestrator `scripts/import_recipe_workflow.py` that aggregate
2. **Orchestrated Workflow:**
- **Step 1:** Run `scripts/scrape_to_cook.py` to extract recipe content and download the image.
- **Step 2:** Run `task move` to compile the `.cook` file, move the image, and insert navigation.
- **Step 3:** Run `scripts/check-recipe-emojis.py --fix` to verify and auto-add missing emojis.
- **Step 4:** Run `scripts/convert-recipe-units.py` to convert volumetric measurements to weight and add emojis.
- **Step 3:** Run `scripts/check_recipe_emojis.py --fix` to verify and auto-add missing emojis.
- **Step 4:** Run `scripts/convert_recipe_units.py` to convert volumetric measurements to weight and add emojis.
- **Step 5:** Run `task spellcheck` to check for spelling errors. If spelling errors exist, prompt/detect proper nouns and run `scripts/whitelist_typos.py` to whitelist them automatically.
3. **Agent Skill Update:**
- Modify the `/import-recipe` skill ([import-recipe.md](file:///.agents/skills/import-recipe.md)) to instruct agents to use `scripts/import_recipe_workflow.py` instead of running each step manually, significantly reducing the prompt token size and trajectory step count.

View File

@ -4,23 +4,23 @@
- [x] Task: Create a mock image test suite or validation checklist for the image optimization script (99d9d50)
- [x] Create a test directory with dummy `.jpg` and `.png` files to test compression and format conversion (99d9d50)
- [x] Task: Implement image optimization and conversion script (f793958)
- [x] Create `scripts/optimize-images.sh` to check for dependencies (`cwebp`, `oxipng`) (f793958)
- [x] Create `scripts/optimize_images.sh` to check for dependencies (`cwebp`, `oxipng`) (f793958)
- [x] Implement optional category parameter parsing and category-specific directory/file filtering (f793958)
- [x] Implement JPEG to WebP conversion with `cwebp -q 80 -metadata all` and delete original JPEG (f793958)
- [x] Implement PNG optimization with `oxipng -o 4 --strip safe` (f793958)
- [x] Implement calculation and reporting of total space savings (bytes and percentage) for the current run (f793958)
- [x] Task: Test script on dummy directory (274ce78)
- [x] Execute `scripts/optimize-images.sh` on the test directory and verify format conversion and optimization results (274ce78)
- [x] Execute `scripts/optimize_images.sh` on the test directory and verify format conversion and optimization results (274ce78)
- [x] Test specifying a category and verify only that category's images and markdown references are affected (274ce78)
- [x] Task: Conductor - User Manual Verification 'Phase 1: Script Development and Testing' (Protocol in workflow.md) (5cb0001)
## Phase 2: Migration Execution and Markdown Updates [checkpoint: c8ce961]
- [x] Task: Add markdown reference update logic (bdb9a87)
- [x] Add regex/sed replacements in `scripts/optimize-images.sh` to find all `.jpg` image references in target category markdown files and change them to `.webp` (bdb9a87)
- [x] Add regex/sed replacements in `scripts/optimize_images.sh` to find all `.jpg` image references in target category markdown files and change them to `.webp` (bdb9a87)
- [x] Task: Run migration on repository assets in stages (51c6465)
- [x] Execute `scripts/optimize-images.sh` for one category at a time (e.g. `lunches`, `breads`, `breakfast`, `desserts`, etc.) (51c6465)
- [x] Execute `scripts/optimize_images.sh` for one category at a time (e.g. `lunches`, `breads`, `breakfast`, `desserts`, etc.) (51c6465)
- [x] Verify image conversions and markdown reference changes stage-by-stage (51c6465)
- [x] Execute `scripts/optimize-images.sh` with no arguments to catch any remaining images not covered in category stages (51c6465)
- [x] Execute `scripts/optimize_images.sh` with no arguments to catch any remaining images not covered in category stages (51c6465)
- [x] Task: Verify links and repository integrity (ea4f696)
- [x] Run `task linkcheck-offline` to ensure no broken image links exist (ea4f696)
- [x] Run `task lint` and `task validate` to verify overall project health (ea4f696)

View File

@ -2,14 +2,14 @@
## Overview
This track introduces image optimization and WebP conversion for all recipe images in the repository. It includes:
1. A migration script `scripts/optimize-images.sh` designed to perform conversions in stages (one category at a time, or all at once) to convert existing `.jpg` images to `.webp` using `cwebp`, optimize `.png` images in-place using `oxipng`, and update all corresponding image references in existing Markdown files under `docs/`.
1. A migration script `scripts/optimize_images.sh` designed to perform conversions in stages (one category at a time, or all at once) to convert existing `.jpg` images to `.webp` using `cwebp`, optimize `.png` images in-place using `oxipng`, and update all corresponding image references in existing Markdown files under `docs/`.
2. Updates to the recipe import workflow (`scripts/move.sh`) to automatically convert incoming `.jpg` images to `.webp` and optimize them, as well as rewriting markdown references accordingly.
3. Reporting of the total space savings (in percentage and bytes) after the migration.
## Functional Requirements
- **Migration Script (`scripts/optimize-images.sh`):**
- **Migration Script (`scripts/optimize_images.sh`):**
- Check for the availability of `cwebp` and `oxipng` and exit gracefully with instructions if they are missing.
- Support an optional category argument to allow running the conversion in stages, one category at a time (e.g. `scripts/optimize-images.sh lunches`). If no category is specified, process all categories.
- Support an optional category argument to allow running the conversion in stages, one category at a time (e.g. `scripts/optimize_images.sh lunches`). If no category is specified, process all categories.
- For JPEGs/PNGs inside `docs/assets/images/` belonging to the target category (or all if none specified):
- Convert JPEGs to `.webp` with quality 80 and metadata preserved (`cwebp -q 80 -metadata all <input> -o <output>`) and delete the original `.jpg` file.
- Optimize PNGs in-place using `oxipng -o 4 --strip safe <file>`.

View File

@ -4,25 +4,17 @@
>> cook time: 15 minutes
>> total time: 175 minutes
@whole milk{1.25%cup}
@Active Dry Yeast{2.25%teaspoon} (or 1 packet)
@Honey{0.25%cup}
@melted butter{4%tablespoons} (divided)
@egg{1%large} (at room temperature)
@salt{1%teaspoon}
@(480 grams) all-purpose or bread flour{4%cups}
If using a bread machine, see next section below.
Bring the milk to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side of the #pan{}. Let it reduce to lukewarm, between 80-90 degrees.
Bring @whole milk{1.25%cup} to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side of the #pan{}. Let it reduce to lukewarm, between 80-90 degrees.
Mix the milk, yeast, and @Honey in a small #bowl{} until well combined. Let it sit for 5 minutes.
Mix the milk, @Active Dry Yeast{2.25%teaspoon} (or 1 packet), and @Honey{0.25%cup} in a small #bowl{} until well combined. Let it sit for 5 minutes.
In a large #bowl{}, mix 3 tablespoons of the butter, the milk mixture, the room temperature @egg, @salt, and half of the flour. Mix slowly until smooth. (Use a mixer with a dough hook if you have one, or by hand.) Gradually add the remaining flour and mix until a dough has formed.
In a large #bowl{}, mix the @melted butter{3%tablespoons}, the milk mixture, the room temperature @egg{1%large}, @salt{1%teaspoon}, and half of the flour. Mix slowly until smooth. (Use a mixer with a dough hook if you have one, or by hand.) Gradually add the remaining @all-purpose or bread flour{4%cups} (or 480 grams) and mix until a dough has formed.
Mix/knead for 8 minutes. Transfer the dough to a floured surface and knead for a few more minutes.
Mix/knead for ~{8%minutes}. Transfer the dough to a floured surface and knead for a few more minutes.
Spray a large #bowl{} with cooking spray and place the dough inside. Cover with plastic wrap and let it rise for an hour in a warm place.
Spray a large #bowl{} with cooking spray and place the dough inside. Cover with plastic wrap and let it rise for ~{1%hour} in a warm place.
Punch down the dough and roll it out on a flat, floured surface until its about ½ inch thick. Fold it in half and gently seal.
@ -30,22 +22,22 @@ Cut into 24 squares of even size and place on 2 light, lightly-greased baking sh
Preheat #oven{} to 350° F and bake for 12 to ~{15%minutes}, or until the top is a light golden brown.
Melt the remaining tablespoon of butter and brush the top of the rolls.
Melt the @melted butter{1%tablespoon} and brush the top of the rolls.
Serve with Copycat Texas Roadhouse Butter.
Bring the milk to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side of the #pan{}. Let it reduce to lukewarm, between 80-90 degrees.
Add the milk, @Honey, butter, @egg, and @salt to the bread machine. Add the flour and create a small hole in the middle of the flour, don&#39;t let liquid inside the hole. Place the yeast in the hole.
Add the milk, honey, melted butter, egg, and salt to the bread machine. Add the all-purpose or bread flour and create a small hole in the middle of the flour, don't let liquid inside the hole. Place the active dry yeast in the hole.
Set the bread machine to the dough cycle, let it do the work from there.
Once complete, Spray a large #bowl{} with cooking spray and place the dough inside. Cover the #bowl{} (plastic wrap or a damp cloth works) and let it rise for an hour in a warm place.
Once complete, Spray a large #bowl{} with cooking spray and place the dough inside. Cover the #bowl{} (plastic wrap or a damp cloth works) and let it rise for ~{1%hour} in a warm place.
Punch down the dough and roll it out on a flat, floured surface until its about ½ inch thick. Fold it in half and gently seal.
Cut into 24 squares of even size and place on a 2 lightly greased and lightly colored baking sheets. Cover them and let them rise for 30 to ~{40%minutes},, until doubled in size.
Cut into 24 squares of even size and place on a 2 lightly greased and lightly colored baking sheets. Cover them and let them rise for 30 to ~{40%minutes}, until doubled in size.
Preheat #oven{} to 350 degrees and bake for 12 to ~{15%minutes}, or until the top is a light golden brown.
Melt the remaining tablespoon of butter and brush the top of the rolls. Serve with Copycat Texas Roadhouse Butter.
Melt the remaining tablespoon of melted butter and brush the top of the rolls. Serve with Copycat Texas Roadhouse Butter.

View File

@ -0,0 +1,17 @@
>> source: https://www.noracooks.com/smoky-baked-tempeh-bacon/
>> serves: 4
>> prep time: 5 minutes
>> cook time: 10 minutes
>> total time: 75 minutes
Slice the @tempeh{8%ounces} (from 1 package) into 1/4 inch slices.
In a small-medium #bowl{}, #whisk{} the @neutral oil{1%tablespoon} (avocado or canola), @soy sauce{4%tablespoons}, @seasoned rice vinegar{2%tablespoons}, @pure maple syrup{1%tablespoon}, @toasted sesame oil{1%teaspoon}, and @liquid smoke{2%teaspoons} to create the marinade.
Place the sliced tempeh in a shallow dish or sealable bag. Pour the marinade over the tempeh and gently massage or shake so the pieces all get coated. Place in the refrigerator to marinate for at least 1 hour or up to 12 hours.
Warm a few tablespoons of additional oil in a large non-stick or cast iron #pan{} over medium heat. Add the marinated tempeh slices to the pan in a single layer, reserving the remaining marinade.
Pan fry on each side for 3 to ~{4%minutes}, until golden brown. After you fry all the tempeh bacon, lower the heat, add a little of the reserved marinade, and gently stir until coated.
Serve in sandwiches for BLTs, or anywhere else you like.

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 KiB

View File

@ -0,0 +1,21 @@
>> title: Tomato Powder
>> servings: 0.5 cup
>> category: ingredients
>> source: https://www.thespicehouse.com/products/tomato-powder
>> prep time: 15 minutes
>> cook time: 10 hours
>> total time: 10 hours 15 minutes
Wash and dry @roma tomatoes{2%lbs}. Slice them thinly, about 1/4 inch thick.
Arrange the tomato slices in a single layer on #dehydrator trays{} or #baking sheets{}.
Dehydrate at 135°F (57°C) in a #dehydrator{} (or in an #oven{} set to its lowest temperature, usually 150°F to 170°F with the door propped open slightly) for 8 to ~{12%hours}, or until the slices are completely dry and brittle. They should snap when bent, not bend or feel rubbery.
Allow the dried tomato slices to cool completely to room temperature.
Transfer the cooled slices to a #blender{} or #spice grinder{} and process until they form a fine powder.
Sift the powder through a #fine-mesh sieve{} to remove any large pieces.
Store the tomato powder in an airtight #jar{} in a cool, dry place. Add a food-safe desiccant packet to prevent clumping if desired. (Note: Direct Canned Substitutions: 1 tbsp tomato paste = 1 tbsp tomato powder + 1 tbsp warm water; 1 cup tomato sauce = 4 tbsp powder + 3/4 cup warm water; 1 cup tomato juice = 2 tbsp powder + 7/8 cup warm water. Creative Ways to Use: Stir 1 tbsp into sautéed soffritto/mirepoix before deglazing as an umami booster, knead 2-3 tbsp into bread/pasta doughs for color and tang, stir 1-2 tbsp into simmering stews/chilis to thicken, or dust over popcorn and dressings.)

View File

@ -161,6 +161,7 @@ Chicharrones
Chickenless
Chilero
Chiles
Chilis
Chilli
Chimichurri
Chipotle
@ -470,6 +471,7 @@ Ranchero
Realfruit
RedHot
Refried
Rehydrate
Reine
Relleno
Rempejek
@ -781,6 +783,7 @@ daun
dauphine
de
deglaze
deglazing
dehusked
delicata
demerara
@ -1088,6 +1091,7 @@ reflouring
refried
rehydrate
rehydrated
rehydrating
reinvert
rempejek
rempeyek
@ -1127,6 +1131,7 @@ snapable
snickerdoodles
snuggly
soba
soffritto
sojae
soto
soufflé

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

View File

@ -3,30 +3,24 @@ comments: true
tags:
- bread
---
# Copycat Texas Roadhouse Rolls
# :bread: Copycat Texas Roadhouse Rolls
![Copycat Texas Roadhouse Rolls][1]{ loading=lazy }
| :fork_and_knife_with_plate: Serves | :timer_clock: Total Time |
|:----------------------------------:|:-----------------------: |
| 24 | 1.83 hours |
| 24 | 3.97 hours |
## :salt: Ingredients
- :glass_of_milk: 1.25 cup (284 g) whole milk
- :tea: 2.25 teaspoon (3 g) Active Dry Yeast
- :glass_of_milk: 1.25 cup whole milk
- :tea: 2.25 teaspoon Active Dry Yeast
- :honey_pot: 0.25 cup Honey
- :glass_of_milk: 4 tablespoons (68 g) melted butter
- :butter: 3 tablespoons melted butter
- :egg: 1 large egg
- :salt: 1 teaspoon salt
- :baby_bottle: 4 cups (624 g) (480 grams) all-purpose or bread flour
- :honey_pot: 1 Honey
- :egg: 1 egg,
- :salt: 1 salt,
- :honey_pot: 1 Honey,
- :egg: 1 egg,
- :salt: 1 salt
- :bread: 4 cups all-purpose or bread flour
- :butter: 1 tablespoon melted butter
## :cooking: Cookware
@ -36,7 +30,6 @@ tags:
- 1 bowl
- 1 oven
- 1 pan
- 1 39;t
- 1 bowl
- 1 bowl
- 1 oven
@ -45,121 +38,95 @@ tags:
### Step 1
whole milk
If using a bread machine, see next section below.
### Step 2
Active Dry Yeast (or 1 packet)
Bring whole milk to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side
of the pan. Let it reduce to lukewarm, between 80-90 degrees.
### Step 3
Honey
Mix the milk, Active Dry Yeast (or 1 packet), and Honey in a small bowl until well combined. Let it sit for 5 minutes.
### Step 4
melted butter (divided)
In a large bowl, mix the melted butter, the milk mixture, the room temperature egg, salt, and half of the flour. Mix
slowly until smooth. (Use a mixer with a dough hook if you have one, or by hand.) Gradually add the remaining
all-purpose or bread flour (or 480 grams) and mix until a dough has formed.
### Step 5
egg (at room temperature)
Mix/knead for 8 minutes. Transfer the dough to a floured surface and knead for a few more minutes.
### Step 6
salt
### Step 7
(480 grams) all-purpose or bread flour
### Step 8
If using a bread machine, see next section below.
### Step 9
Bring the milk to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side of
the pan. Let it reduce to lukewarm, between 80-90 degrees.
### Step 10
Mix the milk, yeast, and Honey in a small bowl until well combined. Let it sit for 5 minutes.
### Step 11
In a large bowl, mix 3 tablespoons of the butter, the milk mixture, the room temperature egg, salt, and half of the
flour. Mix slowly until smooth. (Use a mixer with a dough hook if you have one, or by hand.) Gradually add the remaining
flour and mix until a dough has formed.
### Step 12
Mix/knead for 8 minutes. Transfer the dough to a floured surface and knead for a few more minutes.
### Step 13
Spray a large bowl with cooking spray and place the dough inside. Cover with plastic wrap and let it rise for an hour in
Spray a large bowl with cooking spray and place the dough inside. Cover with plastic wrap and let it rise for 1 hour in
a warm place.
### Step 14
### Step 7
Punch down the dough and roll it out on a flat, floured surface until its about ½ inch thick. Fold it in half and
gently seal.
### Step 15
### Step 8
Cut into 24 squares of even size and place on 2 light, lightly-greased baking sheets. Cover and let them rise for 30 to
40 minutes, until doubled in size.
### Step 16
### Step 9
Preheat oven to 350° F and bake for 12 to 15 minutes, or until the top is a light golden brown.
### Step 17
### Step 10
Melt the remaining tablespoon of butter and brush the top of the rolls.
Melt the melted butter and brush the top of the rolls.
### Step 18
### Step 11
Serve with Copycat Texas Roadhouse Butter.
### Step 19
### Step 12
Bring the milk to a near boil. Remove it from heat when you see it begin to steam and small bubbles form on the side of
the pan. Let it reduce to lukewarm, between 80-90 degrees.
### Step 20
### Step 13
Add the milk, Honey, butter, egg, and salt to the bread machine. Add the flour and create a small hole in the middle of
the flour, don&39;t let liquid inside the hole. Place the yeast in the hole.
Add the milk, honey, melted butter, egg, and salt to the bread machine. Add the all-purpose or bread flour and create a
small hole in the middle of the flour, don't let liquid inside the hole. Place the active dry yeast in the hole.
### Step 21
### Step 14
Set the bread machine to the dough cycle, let it do the work from there.
### Step 22
### Step 15
Once complete, Spray a large bowl with cooking spray and place the dough inside. Cover the bowl (plastic wrap or a damp
cloth works) and let it rise for an hour in a warm place.
cloth works) and let it rise for 1 hour in a warm place.
### Step 23
### Step 16
Punch down the dough and roll it out on a flat, floured surface until its about ½ inch thick. Fold it in half and
gently seal.
### Step 24
### Step 17
Cut into 24 squares of even size and place on a 2 lightly greased and lightly colored baking sheets. Cover them and let
them rise for 30 to 40 minutes,, until doubled in size.
them rise for 30 to 40 minutes, until doubled in size.
### Step 25
### Step 18
Preheat oven to 350 degrees and bake for 12 to 15 minutes, or until the top is a light golden brown.
### Step 26
### Step 19
Melt the remaining tablespoon of butter and brush the top of the rolls. Serve with Copycat Texas Roadhouse Butter.
Melt the remaining tablespoon of melted butter and brush the top of the rolls. Serve with Copycat Texas Roadhouse
Butter.
## :link: Source
- <https://thecozycook.com/copycat-texas-roadhouse-rolls/>
[1]: <../assets/images/copycat-texas-roadhouse-rolls.webp>

View File

@ -0,0 +1,65 @@
---
comments: true
tags:
- breakfast
---
# :bacon: Tempeh Bacon
![Tempeh Bacon][1]{ loading=lazy }
| :fork_and_knife_with_plate: Serves | :timer_clock: Total Time |
|:----------------------------------:|:-----------------------: |
| 4 | 4 minutes |
## :salt: Ingredients
- :takeout_box: 8 ounces tempeh
- :avocado: 1 tablespoon neutral oil
- :takeout_box: 4 tablespoons soy sauce
- :takeout_box: 2 tablespoons seasoned rice vinegar
- :honey_pot: 1 tablespoon pure maple syrup
- :olive: 1 teaspoon toasted sesame oil
- :bacon: 2 teaspoons liquid smoke
## :cooking: Cookware
- 1 bowl
- 1 whisk
- 1 pan
## :pencil: Instructions
### Step 1
Slice the tempeh (from 1 package) into 1/4 inch slices.
### Step 2
In a small-medium bowl, whisk the neutral oil (avocado or canola), soy sauce, seasoned rice vinegar, pure maple syrup,
toasted sesame oil, and liquid smoke to create the marinade.
### Step 3
Place the sliced tempeh in a shallow dish or sealable bag. Pour the marinade over the tempeh and gently massage or shake
so the pieces all get coated. Place in the refrigerator to marinate for at least 1 hour or up to 12 hours.
### Step 4
Warm a few tablespoons of additional oil in a large non-stick or cast iron pan over medium heat. Add the marinated
tempeh slices to the pan in a single layer, reserving the remaining marinade.
### Step 5
Pan fry on each side for 3 to 4 minutes, until golden brown. After you fry all the tempeh bacon, lower the heat, add a
little of the reserved marinade, and gently stir until coated.
### Step 6
Serve in sandwiches for BLTs, or anywhere else you like.
## :link: Source
- <https://www.noracooks.com/smoky-baked-tempeh-bacon/>
[1]: <../assets/images/tempeh-bacon.webp>

View File

@ -0,0 +1,67 @@
---
comments: true
tags:
- ingredient
---
# :tomato: Tomato Powder
| :fork_and_knife_with_plate: Serves | :timer_clock: Total Time |
|:----------------------------------:|:-----------------------: |
| 0.5 cup | 12.00 hours |
## :salt: Ingredients
- :tomato: 2 lbs roma tomatoes
## :cooking: Cookware
- 1 dehydrator trays
- 1 baking sheets
- 1 dehydrator
- 1 oven
- 1 blender
- 1 spice grinder
- 1 fine-mesh sieve
- 1 jar
## :pencil: Instructions
### Step 1
Wash and dry roma tomatoes. Slice them thinly, about 1/4 inch thick.
### Step 2
Arrange the tomato slices in a single layer on dehydrator trays or baking sheets.
### Step 3
Dehydrate at 135°F (57°C) in a dehydrator (or in an oven set to its lowest temperature, usually 150°F to 170°F with
the door propped open slightly) for 8 to 12 hours, or until the slices are completely dry and brittle. They should snap
when bent, not bend or feel rubbery.
### Step 4
Allow the dried tomato slices to cool completely to room temperature.
### Step 5
Transfer the cooled slices to a blender or spice grinder and process until they form a fine powder.
### Step 6
Sift the powder through a fine-mesh sieve to remove any large pieces.
### Step 7
Store the tomato powder in an airtight jar in a cool, dry place. Add a food-safe desiccant packet to prevent clumping if
desired. (Note: Direct Canned Substitutions: 1 tbsp tomato paste = 1 tbsp tomato powder + 1 tbsp warm water; 1 cup
tomato sauce = 4 tbsp powder + 3/4 cup warm water; 1 cup tomato juice = 2 tbsp powder + 7/8 cup warm water. Creative
Ways to Use: Stir 1 tbsp into sautéed soffritto/mirepoix before deglazing as an umami booster, knead 2-3 tbsp into
bread/pasta doughs for color and tang, stir 1-2 tbsp into simmering stews/chilis to thicken, or dust over popcorn and
dressings.)
## :link: Source
- <https://www.thespicehouse.com/products/tomato-powder>

View File

@ -123,8 +123,8 @@ uv run scripts/import_recipe_workflow.py <URL_or_issue_number> [category]
- Scrapes the recipe into a `.cook` file and downloads the image.
- Compiles and organizes the files using `move.sh`.
- Checks and maps missing emojis using `check-recipe-emojis.py --fix`.
- Converts units to weights using `convert-recipe-units.py`.
- Checks and maps missing emojis using `check_recipe_emojis.py --fix`.
- Converts units to weights using `convert_recipe_units.py`.
- Spellchecks the output and whitelists proper nouns.
#### 2. Manual Recipe Import (`import_manual_recipe.py`)

View File

@ -2,6 +2,9 @@
emoji:
cookware:
- bowl_with_spoon:
- jar
- dehydrator trays
- dehydrator
- mixer bowl
- cake pans (8"x8"x2")
- 215
@ -46,6 +49,7 @@ emoji:
- measuring cup
- heat-proof liquid measuring cup
- gear:
- spice grinder
- electric mixer with whip attachment
- hand mixer
- coffee or spice grinder
@ -108,6 +112,7 @@ emoji:
- small spoon
- large serving spoon
- wastebasket:
- fine-mesh sieve
- cooling rack
- strainer
- fine-mesh strainer
@ -181,6 +186,8 @@ emoji:
- natural food coloring
- rainbow sprinkles
- avocado:
- neutral oil
- neutral oil, avocado or canola
- avocado
- sliced avocado
- avodado:
@ -198,7 +205,6 @@ emoji:
- 8 Tablespoons (90120g/ml) ice-cold water
- and 1/3 cups (167g) all-purpose flour (spooned &amp; leveled), plus more as needed
- /2 teaspoon salt
- (480 grams) all-purpose or bread flour
- egg, at room temperature
- almond emulsion or almond extract
- (96g) King Arthur Almond Flour
@ -239,6 +245,7 @@ emoji:
- aquafaba
- buttermilk
- bacon:
- liquid smoke
- vegan bacon
- fully cooked uncured applewood smoked bacon
- center-cut bacon slices
@ -308,6 +315,7 @@ emoji:
- rice paper wrappers
- bread flour
- cake flour
- all-purpose or bread flour
- breadcrumbs
- panko breadcrumbs
- graham cracker crumbs
@ -331,6 +339,17 @@ emoji:
- salted butter
- knob
- knob of butter
- /4 cup (4 Tablespoons; 56g) unsalted butter, cut into 4 pieces
- (85g) unsalted butter
- butter flavored oil spray
- whipped butter
- /4 cup (12 Tbsp; 170g) unsalted butter, very cold and cubed
- melted butter
- (85g) unsalted butter, at room temperature
- butter (room temperature (80g))
- unsalted butter ((56g))
- cups/340 grams unsalted European or European-style butter (3 sticks), chilled
- cup/57 grams unsalted butter, cut into ½-inch pieces, chilled
- cake:
- brandy snaps
- candy:
@ -589,18 +608,9 @@ emoji:
- (8 oz) mascarpone
- (7.5 oz) crème fraiche
- (7.5 oz) crème fraîche
- /4 cup (4 Tablespoons; 56g) unsalted butter, cut into 4 pieces
- /4 cup (180ml) whole milk
- /2 cup (120ml) heavy cream
- (85g) unsalted butter
- butter flavored oil spray
- whipped butter
- /4 cup (12 Tbsp; 170g) unsalted butter, very cold and cubed
- melted butter
- (85g) unsalted butter, at room temperature
- cream of tartar
- butter (room temperature (80g))
- unsalted butter ((56g))
- ¾ cups water (or thin coconut milk (1¼ cups water for IP, 2 cups for regular pot, refer notes))
- curd or yogurt
- heavy
@ -665,6 +675,7 @@ emoji:
- hibiscus:
- iced hibiscus tea
- honey_pot:
- pure maple syrup
- honey
- maple syrup
- hot_pepper:
@ -678,8 +689,6 @@ emoji:
- peppercorn kernels
- peppercorn
- green chili ((slit or chopped) (skip for kids))
- cups/340 grams unsalted European or European-style butter (3 sticks), chilled
- cup/57 grams unsalted butter, cut into ½-inch pieces, chilled
- Red-pepper flakes (optional)
- Kosher salt and black pepper
- jalapeño or serrano pepper
@ -903,6 +912,11 @@ emoji:
- taco:
- chipotle breakfast tacos
- takeout_box:
- tempeh
- soy
- seasoned rice vinegar
- package tempeh
- liquid
- (480ml) half-and-half
- white vinegar
- pickling

View File

@ -12,21 +12,21 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
| `scripts/commit.sh` | `task commit FILES="<path>"` | Automates staging files, prompts for issue number, and commits with standard conventional message. |
| `scripts/spellcheck.sh` | `task spellcheck` | Re-generates `_typos.toml` and spellchecks the repository. |
| `scripts/linkcheck.sh` | `task linkcheck` | Runs the `lychee` link checker. |
| `scripts/list-ingredients.sh` | `task list-ingredients` | Copies a `cook shopping-list` command for all recipes to the clipboard. |
| `scripts/lint-changed.py` | `task lint-changed` | Lints only modified/changed files (saves tokens). |
| `scripts/git-summary.py` | `task git-summary` | Displays a token-efficient summary of the git workspace status and changes. |
| `scripts/hyperlink-ingredient.py` | `task hyperlink-ingredient TARGET="<path>" INGREDIENT="<name>"` | Hyperlinks occurrences of an ingredient to its recipe/file. |
| `scripts/hyperlink-ingredient-global.py` | `task hyperlink-ingredient-global INGREDIENT="<name>"` | Globally hyperlinks occurrences of an ingredient across all recipes. |
| `scripts/list_ingredients.sh` | `task list-ingredients` | Copies a `cook shopping-list` command for all recipes to the clipboard. |
| `scripts/lint_changed.py` | `task lint-changed` | Lints only modified/changed files (saves tokens). |
| `scripts/git_summary.py` | `task git-summary` | Displays a token-efficient summary of the git workspace status and changes. |
| `scripts/hyperlink_ingredient.py` | `task hyperlink-ingredient TARGET="<path>" INGREDIENT="<name>"` | Hyperlinks occurrences of an ingredient to its recipe/file. |
| `scripts/hyperlink_ingredient_global.py` | `task hyperlink-ingredient-global INGREDIENT="<name>"` | Globally hyperlinks occurrences of an ingredient across all recipes. |
| `scripts/scrape_to_cook.py` | - | Scrapes a recipe webpage URL and compiles it into a CookLang `.cook` file while downloading the image. |
| `scripts/import_recipe_workflow.py` | - | Orchestrates the entire recipe import workflow (scrape, move, emojis, units, spellcheck, whitelist). |
| `scripts/import_manual_recipe.py` | - | Orchestrates the manual recipe import pipeline (.cook, image, move, emojis, units, spellcheck, commit). |
| `scripts/whitelist_typos.py` | - | Whitelists words in the typos dictionary, sorts the file, and rebuilds typos config. |
| `scripts/find_missing_sources.py` | `task check-missing-sources` | Scans markdown recipes to find files that do not have a Source/Sources section. |
| `scripts/check_missing_images.py` | `task check-missing-images` | Scans recipe files to find files missing hero images or embeds. |
| `scripts/add-recipe-nav.py` | - | Adds a recipe's relative path to the correct navigation section in `zensical.toml`. |
| `scripts/add_recipe_nav.py` | - | Adds a recipe's relative path to the correct navigation section in `zensical.toml`. |
| `scripts/add_recipe_size.py` | - | Scales ingredients of a recipe by a factor and appends it as a new tab block. |
| `scripts/adjust_recipe_metadata.py` | - | Modifies frontmatter metadata tags and custom properties for a recipe markdown file. |
| `scripts/optimize-images.sh` | - | Converts recipe JPEGs to WebP and optimizes PNG files to reduce image asset file sizes. |
| `scripts/optimize_images.sh` | - | Converts recipe JPEGs to WebP and optimizes PNG files to reduce image asset file sizes. |
| `scripts/refactor_nav.py` | - | Replaces navigation blocks in `zensical.toml` with preset navigation structures. |
| `scripts/move_and_verify.py` | - | Relocates recipes in `sides` and `sauces-and-dressings` to subdirectories and updates navigation. |
@ -58,9 +58,9 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
the `sides` and `sauces-and-dressings` categories to their nested subdirectories (e.g.,
`potatoes`, `vinaigrettes`, `salsas`), maintaining both the `.cook` files and compiled markdown docs.
#### [add-recipe-nav.py](add-recipe-nav.py)
#### [add_recipe_nav.py](add_recipe_nav.py)
* **Usage**: `uv run scripts/add-recipe-nav.py <recipe_name> <relative_path>`
* **Usage**: `uv run scripts/add_recipe_nav.py <recipe_name> <relative_path>`
* **Description**: Automatically inserts a recipe file under the correct section list in
`zensical.toml` and maintains alphabetical ordering of the list items.
@ -97,9 +97,9 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
It parses the warnings and errors to automatically fix common issues (e.g., removing unused
reference definitions, escaping bracketed text like `[ml]`, or turning unresolved recipe links into plain text).
#### [convert-recipe-units.py](convert-recipe-units.py)
#### [convert_recipe_units.py](convert_recipe_units.py)
* **Usage**: `uv run scripts/convert-recipe-units.py <recipe.md>`
* **Usage**: `uv run scripts/convert_recipe_units.py <recipe.md>`
* **Description**: Scans a recipe's markdown Ingredients list, automatically converts volumetric/count
measurements (like `1 cup` or `2 tbsp`) into weight-annotated units (`(120 g)`) by reading mappings
in [docs/reference/measuring.md](../docs/reference/measuring.md), and inserts the matching ingredient
@ -111,16 +111,16 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
* **Description**: Scans all files in `docs/` and automatically resolves broken relative markdown
links/images by matching the file basenames against existing files in the repository.
#### [hyperlink-ingredient.py](hyperlink-ingredient.py)
#### [hyperlink_ingredient.py](hyperlink_ingredient.py)
* **Usage**: `uv run python3 scripts/hyperlink-ingredient.py --target <recipe.md> --ingredient "<Name>"` or
* **Usage**: `uv run python3 scripts/hyperlink_ingredient.py --target <recipe.md> --ingredient "<Name>"` or
`task hyperlink-ingredient TARGET=<recipe.md> INGREDIENT="<Name>"`
* **Description**: Scans the target recipe and automatically replaces raw text occurrences of the specified
ingredient with a relative markdown link pointing to its corresponding file in `docs/`.
#### [hyperlink-ingredient-global.py](hyperlink-ingredient-global.py)
#### [hyperlink_ingredient_global.py](hyperlink_ingredient_global.py)
* **Usage**: `uv run python3 scripts/hyperlink-ingredient-global.py --ingredient "<Name>"` or
* **Usage**: `uv run python3 scripts/hyperlink_ingredient_global.py --ingredient "<Name>"` or
`task hyperlink-ingredient-global INGREDIENT="<Name>"`
* **Description**: Scans all recipes in `docs/` and automatically replaces raw text occurrences of the specified
ingredient with a relative markdown link pointing to its corresponding file.
@ -144,9 +144,9 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
* **Description**: Modifies frontmatter metadata tags and custom properties (such as comments or hero images)
for a recipe markdown file.
#### [optimize-images.sh](optimize-images.sh)
#### [optimize_images.sh](optimize_images.sh)
* **Usage**: `./scripts/optimize-images.sh [category]`
* **Usage**: `./scripts/optimize_images.sh [category]`
* **Description**: Converts recipe JPEGs to WebP format, optimizes PNG files using `oxipng`, updates markdown links
automatically, and removes the original image assets to reduce file sizes.
@ -154,9 +154,9 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
### 3. Checkers & Linter Generators
#### [check-recipe-emojis.py](check-recipe-emojis.py)
#### [check_recipe_emojis.py](check_recipe_emojis.py)
* **Usage**: `uv run scripts/check-recipe-emojis.py [--fix] <recipe.cook>`
* **Usage**: `uv run scripts/check_recipe_emojis.py [--fix] <recipe.cook>`
* **Description**: Scans a `.cook` file's ingredients (`@`) and cookware (`#`) references to check
if they are mapped to emojis in [includes/emoji.yaml](../includes/emoji.yaml), exiting with a
non-zero status if any mapped emojis are missing. The optional `--fix` flag automatically maps
@ -230,14 +230,14 @@ Where possible, run these via `Taskfile.yaml` using the `task` runner.
### 5. Token-Saving Tools for AI Agents
#### [lint-changed.py](lint-changed.py)
#### [lint_changed.py](lint_changed.py)
* **Usage**: `uv run python3 scripts/lint-changed.py` or `task lint-changed`
* **Usage**: `uv run python3 scripts/lint_changed.py` or `task lint-changed`
* **Description**: A specialized linter wrapper that detects modified, staged, or untracked Markdown
and YAML files in the git workspace, running the appropriate linters only on those files to save context tokens.
#### [git-summary.py](git-summary.py)
#### [git_summary.py](git_summary.py)
* **Usage**: `uv run python3 scripts/git-summary.py` or `task git-summary`
* **Usage**: `uv run python3 scripts/git_summary.py` or `task git-summary`
* **Description**: Prints a highly compact, token-efficient summary of branch status, modified files stat,
and the last commit, avoiding verbose git status and git diff outputs.

View File

@ -5,7 +5,7 @@ import os
def main():
if len(sys.argv) < 3:
print("Usage: add-recipe-nav.py <recipe_name> <relative_path>")
print("Usage: add_recipe_nav.py <recipe_name> <relative_path>")
sys.exit(1)
recipe_name = sys.argv[1]

View File

@ -204,7 +204,7 @@ def convert_ingredient(qty_str, unit, name, measuring_table):
def main():
if len(sys.argv) < 2:
print("Usage: convert-recipe-units.py <recipe.md>")
print("Usage: convert_recipe_units.py <recipe.md>")
sys.exit(1)
md_path = sys.argv[1]

View File

@ -135,14 +135,14 @@ def main():
sys.exit(1)
print(f"Target markdown file successfully created at: {md_path}")
# Step 3: Run check-recipe-emojis.py --fix
# Step 3: Run check_recipe_emojis.py --fix
print("\n--- Step 3: Verifying and auto-fixing recipe emojis ---")
emoji_cmd = ["uv", "run", "scripts/check-recipe-emojis.py", "--fix", target_cook_path]
emoji_cmd = ["uv", "run", "scripts/check_recipe_emojis.py", "--fix", target_cook_path]
run_command(emoji_cmd)
# Step 4: Run convert-recipe-units.py
# Step 4: Run convert_recipe_units.py
print("\n--- Step 4: Converting volumetric units to weights ---")
convert_cmd = ["uv", "run", "scripts/convert-recipe-units.py", md_path]
convert_cmd = ["uv", "run", "scripts/convert_recipe_units.py", md_path]
run_command(convert_cmd)
# Step 5: Run spellcheck & whitelist

View File

@ -113,14 +113,14 @@ def main():
sys.exit(1)
print(f"Target markdown file successfully created at: {md_path}")
# Step 3: Run check-recipe-emojis.py --fix
# Step 3: Run check_recipe_emojis.py --fix
print("\n--- Step 3: Verifying and auto-fixing recipe emojis ---")
emoji_cmd = ["uv", "run", "scripts/check-recipe-emojis.py", "--fix", cook_file]
emoji_cmd = ["uv", "run", "scripts/check_recipe_emojis.py", "--fix", cook_file]
run_command(emoji_cmd)
# Step 4: Run convert-recipe-units.py
# Step 4: Run convert_recipe_units.py
print("\n--- Step 4: Converting volumetric units to weights ---")
convert_cmd = ["uv", "run", "scripts/convert-recipe-units.py", md_path]
convert_cmd = ["uv", "run", "scripts/convert_recipe_units.py", md_path]
run_command(convert_cmd)
# Step 5: Run spellcheck & whitelist

View File

@ -158,7 +158,7 @@ function move_files(){
recipe_name=$(get_recipe_name "${recipe_path}")
relative_markdown_path=$(realpath --relative-to="${DOCS_PATH}" "${new_markdown_path}")
uv run "${DIR}/add-recipe-nav.py" "${recipe_name}" "${relative_markdown_path}"
uv run "${DIR}/add_recipe_nav.py" "${recipe_name}" "${relative_markdown_path}"
}
function main(){

View File

@ -2,7 +2,7 @@
################################################################################
#
# optimize-images
# optimize_images
# ----------------
# Convert JPEG to WebP, optimize PNG, and update markdown references.
#

View File

@ -6,9 +6,9 @@ from unittest.mock import patch
import sys
import yaml
# Import main and helper functions from check-recipe-emojis
# Import main and helper functions from check_recipe_emojis
import importlib.util
spec = importlib.util.spec_from_file_location("check_recipe_emojis", "scripts/check-recipe-emojis.py")
spec = importlib.util.spec_from_file_location("check_recipe_emojis", "scripts/check_recipe_emojis.py")
check_recipe_emojis = importlib.util.module_from_spec(spec)
sys.modules["check_recipe_emojis"] = check_recipe_emojis
spec.loader.exec_module(check_recipe_emojis)
@ -50,7 +50,7 @@ emoji:
with open(cook_path, "w", encoding="utf-8") as f:
f.write("Add @almond flakes{10%g} and @mystery substance{5%g} to a #large bowl{}.\n")
test_argv = ["scripts/check-recipe-emojis.py", "--fix", cook_path]
test_argv = ["scripts/check_recipe_emojis.py", "--fix", cook_path]
# Set module level EMOJI_YAML_PATH if it exists, otherwise we'll define it on the module
setattr(check_recipe_emojis, "EMOJI_YAML_PATH", self.emoji_yaml_path)
@ -75,13 +75,13 @@ emoji:
@patch("sys.exit")
def test_fix_missing_cookware(self, mock_exit):
# Create a dummy cook recipe with a missing cookware that has high similarity to "baking sheet" (e.g., "baking pan")
# Create a dummy cook recipe with a missing cookware that has high similarity to "baking sheet" (e.g., "baking dish")
# and a cookware with no similarity (e.g., "magic device").
cook_path = os.path.join(self.test_dir, "test_cookware_recipe.cook")
with open(cook_path, "w", encoding="utf-8") as f:
f.write("Bake on #baking pan{} and use #magic device{}.\n")
f.write("Bake on #baking dish{} and use #magic device{}.\n")
test_argv = ["scripts/check-recipe-emojis.py", "--fix", cook_path]
test_argv = ["scripts/check_recipe_emojis.py", "--fix", cook_path]
setattr(check_recipe_emojis, "EMOJI_YAML_PATH", self.emoji_yaml_path)
with patch.object(sys, "argv", test_argv):
@ -96,7 +96,7 @@ emoji:
cookware_list = updated_data["emoji"]["cookware"]
cookie_group = next(item["cookie"] for item in cookware_list if "cookie" in item)
self.assertIn("baking pan", cookie_group)
self.assertIn("baking dish", cookie_group)
# Verify magic device got mapped to fallback group "bowl_with_spoon"
bowl_group = next(item["bowl_with_spoon"] for item in cookware_list if "bowl_with_spoon" in item)
@ -109,7 +109,7 @@ emoji:
with open(cook_path, "w", encoding="utf-8") as f:
f.write("Add @almond flakes{10%g} to #large bowl{}.\n")
test_argv = ["scripts/check-recipe-emojis.py", cook_path]
test_argv = ["scripts/check_recipe_emojis.py", cook_path]
setattr(check_recipe_emojis, "EMOJI_YAML_PATH", self.emoji_yaml_path)
with patch.object(sys, "argv", test_argv):

View File

@ -32,7 +32,7 @@ class TestOptimizeImages(unittest.TestCase):
f.write("# Test Recipe\n\n![Cake](../assets/images/test-cake.jpg)\n![Cookie](../assets/images/test-cookie.png)\n")
# Path to the actual script under test
self.script_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "optimize-images.sh"))
self.script_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "optimize_images.sh"))
def tearDown(self):
shutil.rmtree(self.test_dir)

View File

@ -194,6 +194,7 @@ Breakfast = [
{ "Southwestern Butternut Squash and Black Bean Breakfast Bowl" = "breakfast/southwestern-butternut-squash-and-black-bean-breakfast-bowl.md" },
{ "Sweet & Spicy Corncakes" = "breakfast/sweet-and-spicy-corncakes.md" },
{ "Sweet Potato Pancakes" = "breakfast/sweet-potato-pancakes.md" },
{ "Tempeh Bacon" = "breakfast/tempeh-bacon.md" },
{ "Tex-Mex Migas" = "breakfast/tex-mex-migas.md" },
{ "The Food Lab Light & Fluffy Scrambled Eggs" = "breakfast/the-food-lab-light-and-fluffy-scrambled-eggs.md" },
{ "Toasted-Coconut Granola" = "breakfast/toasted-coconut-granola.md" },