ecallen

Site Generation Findings

Overview

The blog is a static site generated with Pandoc, styled with the LaTeX CSS stylesheet (latex.now.sh). The generation process converts Markdown files into standalone HTML pages and deploys them to two targets simultaneously.

Architecture

docs/*.md (source content)
templates/*.md.tmpl (Jinja2 templates)
assets/ (shared HTML/JS fragments)
    ├── license.html
    ├── topbar.html (dark mode toggle button)
    └── dark.js (dark mode logic)
        │
        ▼
   bin/generate.sh (orchestrator)
   bin/template.py (Jinja2 renderer)
        │
        ▼
   staging/ (intermediate working dir)
        │
        ▼
  ┌─────┴──────┐
  html/        ~/Documents/GitHub/ecallen.github.io/
  (local)      (GitHub Pages deploy)

How bin/generate.sh Works (Current Version)

The script is a zsh script (the docs describe an older bash version). Here is the step-by-step flow:

  1. Clean output directories - Removes all .html files from both deploy targets (html/ and the GitHub Pages repo) and clears staging/.

  2. Stage source content - Copies all .md files from docs/ into staging/. Renames notes.md to heap.md in the process.

  3. Loop over each deploy target - The script iterates over two deploy directories and for each one:

  4. Pandoc options used:

Supporting Scripts

bin/template.py

A small Jinja2 renderer. Takes a template file and key=value pairs as CLI arguments, renders the template, and prints the result to stdout. Used to inject the correct hostname into index.md.tmpl for each deploy target. Requires the jinja2 package (managed via uv).

Deploy Targets

Directory Hostname Purpose
html/ ecallen.com Local preview / custom domain
~/Documents/GitHub/ecallen.github.io ecallen.github.io GitHub Pages

The deploy_info associative array maps each directory to its hostname so the index template gets the correct links.

Differences: Documented Version vs. Current Script

The docs/generate-site.md describes an older version of the pipeline. Key differences:

Aspect Documented (old) Current (bin/generate.sh)
Shell bash zsh
Notes handling csplit to split notes.md by headers into sections/ Copies notes.md as heap.md into staging/ (no splitting)
Index links Auto-generated from section HTML via htmlq Managed manually in index.md.tmpl
Template engine None (manual cp index.md.tmpl) Jinja2 via bin/template.py
Deploy targets Single (html/) Two (html/ + GitHub Pages repo)
Dark mode Not present topbar.html + dark.js injected
Local preview Flask server Not included in script

Potential Issues in Current Script

  1. stat variable uses ${fn} instead of ${f} - Lines 39-40 reference ${fn} which is never assigned in the current script. The loop variable is $f. This means lastUpdated and creationDate are likely empty or pulling from a stale value.

  2. stat flags are macOS-specific - The script uses stat -f %m and stat -f %c which are BSD/macOS stat flags. The documented version used stat -c (GNU/Linux). The current version is correctly targeting macOS but would break on Linux.

Workflow Summary

  1. Write markdown in drafts/.
  2. When ready, move the file to docs/.
  3. Add a link in templates/index.md.tmpl if needed.
  4. Run bin/generate.sh to build the site.
  5. Use bin/deploy.sh to push to GitHub Pages.



Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Code snippets are licensed under the MIT License.