main

vincent.demeester.fr

Personal website and activity stream.

Architecture

org files (Emacs)
     │
     ▼
ox-tufte export ──→ site/*.html (bare HTML)
                         │
                    soupault (plugins: CSS/JS injection, heading slugs,
                         │    callouts, tag pills, theme toggle, nav, footer)
                         ▼
                    build/*.html (processed)
                         │
flux generate ──────→ build/flux/ (stream, feeds, tag pages)
     │                   │
     │              static assets (images/, articles/data/)
     │                   │
     ▼                   ▼
entries.json        rsync → carthage.vpn:/var/www/vincent.demeester.fr/

Content sources

Source Location What
Articles & pages *.html at repo root Org-exported digital garden pages
Posts posts/*.html Blog posts (2012–2020)
TIL ~/desktop/org/til.org Short learnings, C-c o c ii
Bookmarks ~/desktop/org/bookmarks.org Links worth keeping, C-c o c lk

Flux — Activity stream

A Go CLI tool (cmd/flux/) that aggregates activity into a unified feed at /flux/.

Sources:

  • GitHub merged PRs + opened issues (search API, last year)
  • GitHub releases (tektoncd + vdemeester orgs, skip drafts/prereleases)
  • Git log (new/modified content pages in this repo)
  • TIL entries from til.org
  • Bookmarks from bookmarks.org

Output:

  • /flux/index.html — latest 50 entries
  • /flux/2026.html, /flux/2025.html — year archives
  • /flux/tags/ — tag index + per-tag pages
  • /flux/feed.json, /flux/feed.xml — full feeds (JSON Feed + Atom)
  • /flux/content.json, /flux/content.xml — content-only feeds (pages, TIL, bookmarks — no GitHub)
  • /flux/home-snippet.html — injected into homepage

Workflow

Writing a new page

  1. Write in org-mode (Emacs)
  2. Export with ox-tufte: C-c C-e T h → produces *.html at repo root
  3. Build and deploy:
    make deploy
    

Adding a TIL

  1. C-c o c ii → prompts title + tags, adds date
  2. Writes to ~/desktop/org/til.org (most recent first)
  3. Re-export TIL page: C-c C-e T h from til.orgsite/til.html
  4. make deploy

Adding a bookmark

  1. From browser: org-protocol bookmarklet → C-c o c lk
  2. From Emacs: C-c o c lk, paste URL
  3. Prompts for tags, adds date, optional note
  4. Writes to ~/desktop/org/bookmarks.org
  5. Re-export: C-c C-e T h from bookmarks.orgsite/bookmarks.html
  6. make deploy

Manual flux update (local)

make deploy          # full pipeline: flux generate → soupault → rsync
make build           # build only (no deploy)
make deploy-dry-run  # preview what would change

Flux CLI

./bin/flux generate -v          # fetch all sources, render
./bin/flux generate --dry-run   # preview without writing
./bin/flux list                 # show cached entries
./bin/flux list --source til    # filter by source
./bin/flux version

Build pipeline (make build)

  1. flux generate — fetch GitHub/git/TIL/bookmarks → flux/entries.json → render HTML + feeds
  2. populate-site — copy root HTML content → site/ for soupault
  3. inject-snippet — insert flux/home-snippet.html into site/index.html
  4. soupault — process site/build/ (inject CSS/JS, strip old CSS, heading slugs, callouts, nav, footer)
  5. static assets — copy images/, articles/data/, style.css, flux.jsbuild/
  6. flux output — copy flux/*.html, feeds, tags → build/flux/

Soupault plugins

Plugin What
strip-old-css Remove old tufte/2022 stylesheet links
inject-css/js/viewport Add style.css, flux.js, viewport meta
theme-toggle Dark/light toggle button in .site-controls
site-nav Navigation links (⌘ ≋ ☉) in floating pill
site-footer Consistent footer on all pages
callouts #+begin_note/tip/warning/danger → styled callouts
heading-slugs Replace org IDs with readable slugs + § anchors
tag-pills Org heading tags → clickable pill links
link-timestamps Org timestamps → year archive links
inject-time Hidden <time> element from page dates

Automated deployment (carthage)

scripts/flux-generate.sh — runs via systemd timer (hourly):

  1. Pulls latest from git
  2. Builds flux binary (via nix-shell -p go)3 . Generates flux entries
  3. Runs soupault (via nix-shell -p soupault)
  4. Copies static assets
  5. Deploys to /var/www/vincent.demeester.fr/
  6. Commits updated entries.json back to git

See scripts/nixos-service.nix for the systemd unit.

Key files

cmd/flux/main.go              CLI entry point
internal/flux/
├── entry.go                  Entry type, Store (load/save/merge/sort/filter)
├── source.go                 Source interface
├── github.go                 GitHub PRs, issues, releases
├── gitlog.go                 Git history scanner
├── til.go                    TIL org parser
├── bookmarks.go              Bookmarks org parser
└── render.go                 JSON Feed, Atom, HTML renderers

site/index.html               Homepage (with FLUX_SNIPPET placeholder)
site/about.html               About page
site/sandbox.html              Design system showcase
site/posts/index.html          Posts listing
soupault.toml                  Soupault config
plugins/                       Soupault Lua plugins
style.css                      Design system CSS
flux.js                        Theme toggle + accent picker JS
Makefile                       Build + deploy pipeline
scripts/flux-generate.sh       Automated build script (nix-shell shebang)
scripts/nixos-service.nix      NixOS systemd timer config

Design

  • Typography: Serif body (Palatino), sans headings (Seravek), mono code
  • Syntax: Tonsky 4-color (strings green bg, comments warm bg, definitions blue bg, constants purple)
  • Theme: Light/dark toggle, system default respected
  • Navigation: Floating pill with ⌘ (index) ≋ (flux) ☉ (about) + ☀️/🌙 toggle
  • Feeds: Full (all activity) + content-only (pages, TIL, bookmarks)