The Garden of Thoughts blog site started as a collection of raw markdown files living in a GitHub repo. Readable on GitHub, sure — but not something you'd send someone as a link to an actual article. Today that changed.
In one session, Claude Code and I built a proper HTML publishing pipeline for Garden of Thoughts, start to finish.
A Python script that converts markdown to HTML.
All posts in garden-of-thoughts/ are written in markdown with YAML frontmatter — title, date, tags. The script reads each file, strips the frontmatter, converts the body to styled HTML, and writes out a standalone .html file that matches the site's Georgia/720px aesthetic.
The script lives at scripts/ — the conventional folder for utility scripts, distinct from src/ which is for importable package code. A small distinction, but the right one.
Incremental conversion.
Running the script a second time skips any .html that is already newer than its source .md. Only new or edited posts get processed. No unnecessary rebuilds.
A rebuilt index.
garden-of-thoughts/index.html now links to local .html files instead of github.com/... URLs. Articles are sorted newest-first, pulled directly from each file's frontmatter date.
We used uv instead of pip — a modern Python package manager written in Rust. Noticeably faster installs, and dependency management flows through pyproject.toml rather than a hand-maintained requirements.txt. If you haven't switched yet, it's worth it.
uv venv
uv add markdown pyyaml
uv run python scripts/convert_md_to_html.py
We also set up a proper .gitignore from the start:
- .venv/ and __pycache__/ — never commit these
- *.md — source files stay local; only the generated HTML ships
The posts in this garden are now real standalone blog web pages with back-navigation, date headers, tag chips, and readable typography. They can be linked directly, hosted statically, or dropped into any web server without modification.
Adding a new post is now a two-step workflow: write the markdown, run the script.
Edited and refined with assistance from Claude Code.