# How the Auto-Generated README Process Works in HowToCook

> Discover how the auto-generated README process works in Anduin2017/HowToCook. Learn how Node.js scripts compile markdown files for your documentation.

- Repository: [Anduin Xue/HowToCook](https://github.com/Anduin2017/HowToCook)
- Tags: how-to-guide
- Published: 2026-02-27

---

**The Anduin2017/HowToCook repository uses a Node.js build script located at [`.github/readme-generate.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/readme-generate.js) to automatically compile [`README.md`](https://github.com/Anduin2017/HowToCook/blob/main/README.md) and [`mkdocs.yml`](https://github.com/Anduin2017/HowToCook/blob/main/mkdocs.yml) from markdown files scattered across the `dishes/` and `tips/` directories.**

This automation ensures that the project documentation stays synchronized with the growing collection of recipes without manual editing. Whenever contributors add new dishes or cooking tips, running `npm run build` regenerates the table of contents, category indexes, and difficulty ratings based on the source files.

## The Build Architecture

The entry point for the auto-generated README process is defined in [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json). The `build` script executes the generator with a single command:

```bash
npm run build

```

This command runs `node ./.github/readme-generate.js`, which orchestrates the entire pipeline. The script operates as a static site generator specifically tailored for the repository's structure, processing templates and source files to produce the final documentation.

## Step-by-Step Generation Pipeline

The script follows a deterministic eight-step workflow to transform raw markdown files into structured documentation.

### Loading Templates

First, the generator loads skeleton templates that define the layout. It reads [`./.github/templates/readme_template.md`](https://github.com/Anduin2017/HowToCook/blob/main/./.github/templates/readme_template.md) and [`./.github/templates/mkdocs_template.yml`](https://github.com/Anduin2017/HowToCook/blob/main/./.github/templates/mkdocs_template.yml) into memory. These templates contain placeholders like `{{before}}`, `{{index_stars}}`, `{{main}}`, and `{{after}}` that will be replaced with generated content.

### Collecting Source Files

The `getAllMarkdown('.')` function recursively traverses the repository, skipping paths defined in `ignorePaths`. It returns an array of objects containing the `path` and `file` content for every `.md` file found. This collection includes all recipe files under `dishes/` and tip files under `tips/`.

### Categorizing Content

The main loop splits collected files into three logical buckets:

- **Tips**: General cooking advice from `tips/` (excluding `tips/advanced/`) populates the `{{before}}` and `{{after}}` sections
- **Advanced Tips**: Files in `tips/advanced/` are appended after the main content via `{{after}}`
- **Dishes**: Recipe files are grouped by their top-level directory name (e.g., `vegetable_dish`, `meat_dish`, `breakfast`)

### Building Navigation Links

For each categorized file, the generator creates formatted links. The `inlineReadmeTemplate()` function produces markdown list items like `- [鸡蛋花](dishes/vegetable_dish/鸡蛋花/鸡蛋花.md)`. Simultaneously, `inlineMkdocsTemplate()` builds corresponding navigation entries for the MkDocs configuration file.

### Generating the Difficulty Index

The `organizeByStars()` function implements a unique difficulty classification system. It scans every dish file using `countStars()` to tally the number of `★` characters. Dishes are then grouped by star count (1-5), and the generator creates dedicated files like [`starsystem/3Star.md`](https://github.com/Anduin2017/HowToCook/blob/main/starsystem/3Star.md) containing all recipes of that difficulty level. This produces the `{{index_stars}}` placeholder content.

### Assembling Final Output

Finally, the script performs template substitution. The README template receives `{{before}}`, `{{index_stars}}`, `{{main}}`, and `{{after}}`. The MkDocs template receives `{{before}}`, `{{main}}`, and `{{after}}`. The completed strings are written to [`README.md`](https://github.com/Anduin2017/HowToCook/blob/main/README.md) and [`mkdocs.yml`](https://github.com/Anduin2017/HowToCook/blob/main/mkdocs.yml) respectively.

## Key Files in the Generation Process

Understanding the file structure helps when modifying the build behavior:

| File | Purpose |
|------|---------|
| [`.github/readme-generate.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/readme-generate.js) | Core generator script containing `getAllMarkdown()`, `organizeByStars()`, and template logic |
| [`.github/templates/readme_template.md`](https://github.com/Anduin2017/HowToCook/blob/main/.github/templates/readme_template.md) | Markdown skeleton with placeholders for dynamic content |
| [`.github/templates/mkdocs_template.yml`](https://github.com/Anduin2017/HowToCook/blob/main/.github/templates/mkdocs_template.yml) | MkDocs navigation skeleton |
| [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json) | Defines the `npm run build` command |
| `dishes/**/*.md` | Recipe source files containing difficulty stars (`★`) |
| `tips/**/*.md` | Cooking tips source files |

## How to Run the Generator Locally

To regenerate the README after adding or modifying recipes:

```bash

# Install dependencies (first time only)

npm install

# Execute the build script

npm run build

# Or run the Node script directly

node ./.github/readme-generate.js

```

The command updates both [`README.md`](https://github.com/Anduin2017/HowToCook/blob/main/README.md) and [`mkdocs.yml`](https://github.com/Anduin2017/HowToCook/blob/main/mkdocs.yml) in the repository root. Commit these changes alongside your new recipe files to keep the documentation synchronized.

## Summary

- The **auto-generated README process** in HowToCook uses a Node.js script at [`.github/readme-generate.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/readme-generate.js) triggered by `npm run build`.
- The generator recursively collects markdown files from `dishes/` and `tips/`, categorizing them by directory structure and content type.
- **Difficulty ratings** are automatically calculated by counting `★` characters in recipe files and grouping them into star-based indexes.
- Templates at [`.github/templates/readme_template.md`](https://github.com/Anduin2017/HowToCook/blob/main/.github/templates/readme_template.md) and [`mkdocs_template.yml`](https://github.com/Anduin2017/HowToCook/blob/main/mkdocs_template.yml) provide the layout structure, with placeholders replaced by generated content.
- The process maintains synchronization between the raw recipe collection and the navigable documentation without manual editing.

## Frequently Asked Questions

### What triggers the auto-generated README process?

The process is triggered manually by running `npm run build` in the repository root. This executes the Node.js script [`.github/readme-generate.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/readme-generate.js). While the repository could theoretically automate this via GitHub Actions, the current implementation requires contributors to run the build command after adding or modifying recipe files.

### How does the script determine recipe difficulty?

The `organizeByStars()` function scans each dish markdown file for `★` characters using the `countStars()` helper. It tallies the total number of stars (typically 1-5) and groups recipes accordingly. The generator then creates dedicated difficulty index files (like [`starsystem/3Star.md`](https://github.com/Anduin2017/HowToCook/blob/main/starsystem/3Star.md)) and inserts navigation links into the README based on these star ratings.

### Can I modify the README template without breaking the build?

Yes, you can safely edit [`.github/templates/readme_template.md`](https://github.com/Anduin2017/HowToCook/blob/main/.github/templates/readme_template.md) as long as you preserve the placeholder variables: `{{before}}`, `{{index_stars}}`, `{{main}}`, and `{{after}}`. These placeholders are required for the script to inject the dynamic content. Removing or misspelling a placeholder will cause that section to appear blank or fail to render in the final [`README.md`](https://github.com/Anduin2017/HowToCook/blob/main/README.md).

### Is the MkDocs configuration also auto-generated?

Yes, the same build process generates [`mkdocs.yml`](https://github.com/Anduin2017/HowToCook/blob/main/mkdocs.yml) alongside [`README.md`](https://github.com/Anduin2017/HowToCook/blob/main/README.md). The script uses [`.github/templates/mkdocs_template.yml`](https://github.com/Anduin2017/HowToCook/blob/main/.github/templates/mkdocs_template.yml) as a skeleton and populates it with the same categorized navigation data derived from the `dishes/` and `tips/` directories. This ensures that the MkDocs site structure remains synchronized with the GitHub README navigation.