From 9671a90726d93ee47ac855c6b7cfe9aa343800df Mon Sep 17 00:00:00 2001 From: Spencer Brower <6729162+sbrow@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:34:52 -0400 Subject: [PATCH] refactor: Improved the way sites are loaded. --- AGENTS.md | 119 +++++++++++++++++++++++++++ TODOS.md | 3 +- config.odin | 68 ---------------- feed.odin | 70 ++++++++-------- main.odin | 43 ++-------- mustache_test.odin | 48 ++++++----- render.odin | 147 ++++++++++++++++++++-------------- site.odin | 108 ++++++++++++++++++++++++- site_test.odin | 196 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 573 insertions(+), 229 deletions(-) create mode 100644 AGENTS.md delete mode 100644 config.odin create mode 100644 site_test.odin diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8318c25 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,119 @@ +# Thor — Odin Static Site Generator + +Thor is a static site generator written in [Odin](https://odin-lang.org), replacing Hugo for the `sbrow.github.io` blog. It lives at `./thor/` as a git subtree with its own `flake.nix`. + +## Architecture + +``` +thor.json ← site config (title, base_url, social, author) +content/ ← markdown and HTML content files +layouts/ ← Mustache templates +assets/ ← CSS (TailwindCSS source) and JS +public/ ← build output (generated) +``` + +### Source files + +| File | Responsibility | +|---|---| +| `main.odin` | Entry point. Calls `init_site`, `walk_content`, `render_site` | +| `site.odin` | `Site` struct (config + arena), `init_site`, `load_site_config`, `site_merge`, `site_allocator`, `destroy_site` | +| `frontmatter.odin` | JSON frontmatter parser (`{ }` delimited) | +| `content.odin` | `Page` struct, content walker, page loader, cmark integration, footnote/alert/emoji pipeline | +| `footnotes.odin` | Footnote definition stripping (pre-cmark) + sidenote injection (post-cmark) | +| `alerts.odin` | GitHub alert post-processor (`> [!CAUTION]` → styled blockquote) | +| `emoji.odin` | Emoji shortcode expander (`:shrug:` → `¯\_(ツ)_/¯`) | +| `render.odin` | Mustache template rendering, all page types, RSS, sitemap, robots.txt | +| `feed.odin` | RSS feed + sitemap XML generation | +| `icons.odin` | Inline SVG icon constants (home, github, rss, chevron-up, star) | +| `mustache/` | Vendored [odin-mustache](https://github.com/benjamindblock/odin-mustache) library | + +### Data flow + +``` +thor.json → init_site → Site (config + Dynamic_Arena) + ↓ +content/ → walk_content → []Page (with body_html from cmark pipeline) + ↓ +layouts/*.html → render_site (Mustache render_in_layout) → public/ +``` + +### Markdown pipeline (in content.odin `load_page`) + +``` +raw markdown + → expand_emoji (pre-cmark: :shortcode: → unicode) + → strip_definitions (pre-cmark: extract [^id]: definitions) + → cmark markdown_to_html (Unsafe mode for HTML passthrough) + → inject_sidenotes (post-cmark: [^id] →