Field Notes

meta

Build and rendering pipeline

The wiki is a filesystem-first collection of Markdown notes that gets rendered into a static site. The source of truth is src/; the build produces dist/; and bin/wiki.py is the single tool that does both.

The source tree

src/
  *.md              -- maintained wiki notes (the source of truth)
  sources/          -- immutable evidence artifacts
  .obsidian/        -- minimal Obsidian portability layer

Top-level src/*.md files are maintained wiki notes. Everything else under src/ is either evidence or configuration.

The build: bin/wiki.py

wiki.py is a single-file Python tool that handles every wiki operation: creating notes, linting, building, serving, deploying, querying, searching, renaming, and importing sources.

The build converts src/ into a static site in dist/:

  1. Parse YAML frontmatter from every .md file.
  2. Convert Markdown to HTML using the markdown library.
  3. Apply a bounded Obsidian-compatible syntax subset: wikilinks, callouts, tasks, Mermaid fences, Vega-Lite fences, inline and block math.
  4. Render the graph-marker directives (wiki-graph, tag-graph, tag-cloud) into interactive force-directed graphs.
  5. Apply a note template with navigation chrome (breadcrumbs, prev/next links, backlinks).
  6. Write the output to dist/.

Incremental builds

The build tracks a stamp file. just build skips the rebuild when nothing is newer than the last build stamp. just rebuild forces a full rebuild by passing --force.

Rendering constraints

Only a bounded Obsidian subset renders. The following break the build and are rejected by lint:

  • Embeds (page embeds using the exclamation-mark-bracket syntax)
  • Block references
  • Dataview queries
  • Templater syntax
  • Inline tags
  • Obsidian comment markers
  • Highlights (double-equals syntax)
  • Extended task states (custom checkbox symbols beyond the standard three)

The rationale is renderer compatibility: the static build and the Obsidian editor must produce the same output, so the wiki restricts itself to the intersection of what both support.

Math rendering

Inline math (single-dollar delimiters) and block math (double-dollar delimiters) are converted to MathML at build time. The conversion uses latex2mathml and emits a plain MathML element: there is no MathJax or KaTeX script loaded at view time. A note with math renders identically whether served from dist/ or opened from file://.

Obsidian renders the same source with its own MathJax-based math engine, so the two environments may differ in layout for complex multi-row environments. The build therefore prefers flat expressions with \text{} labels over aligned or array environments.

Mermaid and Vega-Lite

Mermaid diagrams render in the browser at view time. The static build emits <pre><code class="language-mermaid"> blocks; a Mermaid script in the page template converts them to SVG.

Vega and Vega-Lite charts similarly render client-side. The build emits <pre><code class="language-vega-lite"> blocks with inline JSON specifications.

Both are fenced code blocks in the Markdown source:

```mermaid
flowchart LR
  A --> B
```

```vega-lite
{"data": {"values": [...]}, "mark": "bar"}
```

The serve command

just serve dynamically renders src/ in a read-only local server. It applies the same rendering pipeline as build but serves from memory, useful for previewing changes before committing.

just preview builds first and then serves the exact dist/ artifact, useful for testing the production output locally.

The dist/ directory

dist/ is generated output. Never edit it by hand and never treat it as canonical. The deploy command uploads dist/ to Cloudflare Pages after copying _redirects and _headers from share/cloudflare/.

The template

The note template at share/templates/note.md defines the HTML structure that wraps every rendered note. It provides:

  • A breadcrumb trail from the Index.
  • The note’s rendered body.
  • A backlinks section showing which other notes link to this one.
  • Prev/next navigation links.

The template is applied during the build; editing it changes the structure of every rendered page.

This note cites no sources of its own.

Working out connections…