Web Presentation
Turn a Markdown file into something a team can actually read: a typeset single-page
document, or a slide deck driven live. One script, both modes, one self-contained file.
Quick usage
# themed document (default) -> ~/Downloads/<name>.html
scripts/build.py notes.md
# slide deck, one slide per `##`
scripts/build.py notes.md --mode deck
# explicit destination and owning-team label
scripts/build.py notes.md -o ~/Downloads/proposal.html -e "Platform Engineering · Draft"
Options: -m/--mode doc|deck · -o/--out · -t/--title (override the H1) ·
-e/--eyebrow (small-caps line above the title) · --theme (alternative stylesheet).
Requires pandoc on PATH. No other dependencies, no network at build or view time.
Workflow
Pick the mode. doc for something people read alone; deck for something walked
through live. Producing both from one source is normal — offer it.
Render. Run the script.
Verify before handing it over. Do not assume the transform worked — the regexes
fail silently on unexpected input. Check the counts match the source:
python3 - <<'PY'
import re; t=open('/path/to/out.html').read()
print('sections', len(re.findall(r'<span class="num">', t)),
'| toc', len(re.findall(r'<li><a href="#', t)),
'| meta', re.findall(r'<dt>(.*?)</dt>', t),
'| tables', len(re.findall(r'<div class="tw">', t)))
PY
A section count below the number of ## headings in the source means a transform
missed — see the troubleshooting section of references/authoring.md.
Report the path and what to do with it (open in a browser, print to PDF, attach).
What the renderer does with the Markdown
Beyond pandoc's defaults it recognises a few conventions and styles them:
# Title becomes the masthead or title slide
- a leading paragraph of
**Label:** value lines becomes a definition-list meta block,
with labels discovered rather than hardcoded
**The ask in one sentence:** … becomes an emphasised standfirst
## 3. Section splits the number into an accent chip
[GAP — …], [CHECK — …], [TODO …], [NOTE …], [RISK …], [OPEN …] become
status chips, or callout blocks when they stand alone
- tables get scrollable containers; YAML frontmatter is stripped
None of these are required — plain Markdown renders fine. In deck mode --- inside a
section starts a continuation slide, which is the main tool for pacing.
Read references/authoring.md for the full conventions table, deck pacing and density
guidance, keyboard shortcuts, theming via CSS custom properties, and troubleshooting.
Editing the script
If modifying scripts/build.py, two constraints are load-bearing:
- Keep
--wrap=none on the pandoc call. Pandoc otherwise wraps output at 72 columns,
splitting long opening tags and inline <strong> labels across lines. Every downstream
regex then misses those elements silently — sections vanish from the deck and the TOC
with no error.
- Match tags as
<h2\s+id=, never <h2 id=, for the same reason.
Theme changes belong in assets/theme.css (shared) and assets/deck.css (slide geometry
only); both are driven by the :root custom properties, so recolouring means editing
those properties rather than the rules.
1---2name: web-presentation3description: Render a Markdown document into a self-contained, themed HTML page or slide deck for sharing with a team — no external assets, opens offline, attachable to mail or Teams. Use when asked to share a document as a web page, publish or present notes, turn a proposal or ADR into slides, make a markdown file presentable, or produce something readable for colleagues who will not open a repo. Triggers on "share this as a webpage", "make slides from this", "present this", "publish these notes", "turn this into a deck".4---56# Web Presentation78Turn a Markdown file into something a team can actually read: a typeset single-page9document, or a slide deck driven live. One script, both modes, one self-contained file.1011## Quick usage1213```bash14# themed document (default) -> ~/Downloads/<name>.html15scripts/build.py notes.md1617# slide deck, one slide per `##`18scripts/build.py notes.md --mode deck1920# explicit destination and owning-team label21scripts/build.py notes.md -o ~/Downloads/proposal.html -e "Platform Engineering · Draft"22```2324Options: `-m/--mode doc|deck` · `-o/--out` · `-t/--title` (override the H1) ·25`-e/--eyebrow` (small-caps line above the title) · `--theme` (alternative stylesheet).2627Requires `pandoc` on PATH. No other dependencies, no network at build or view time.2829## Workflow30311. **Pick the mode.** `doc` for something people read alone; `deck` for something walked32 through live. Producing both from one source is normal — offer it.332. **Render.** Run the script.343. **Verify before handing it over.** Do not assume the transform worked — the regexes35 fail silently on unexpected input. Check the counts match the source:3637 ```bash38 python3 - <<'PY'39 import re; t=open('/path/to/out.html').read()40 print('sections', len(re.findall(r'<span class="num">', t)),41 '| toc', len(re.findall(r'<li><a href="#', t)),42 '| meta', re.findall(r'<dt>(.*?)</dt>', t),43 '| tables', len(re.findall(r'<div class="tw">', t)))44 PY45 ```4647 A section count below the number of `##` headings in the source means a transform48 missed — see the troubleshooting section of `references/authoring.md`.494. **Report the path and what to do with it** (open in a browser, print to PDF, attach).5051## What the renderer does with the Markdown5253Beyond pandoc's defaults it recognises a few conventions and styles them:5455- `# Title` becomes the masthead or title slide56- a leading paragraph of `**Label:** value` lines becomes a definition-list meta block,57 with labels discovered rather than hardcoded58- `**The ask in one sentence:** …` becomes an emphasised standfirst59- `## 3. Section` splits the number into an accent chip60- `[GAP — …]`, `[CHECK — …]`, `[TODO …]`, `[NOTE …]`, `[RISK …]`, `[OPEN …]` become61 status chips, or callout blocks when they stand alone62- tables get scrollable containers; YAML frontmatter is stripped6364None of these are required — plain Markdown renders fine. In deck mode `---` inside a65section starts a continuation slide, which is the main tool for pacing.6667**Read `references/authoring.md`** for the full conventions table, deck pacing and density68guidance, keyboard shortcuts, theming via CSS custom properties, and troubleshooting.6970## Editing the script7172If modifying `scripts/build.py`, two constraints are load-bearing:7374- **Keep `--wrap=none` on the pandoc call.** Pandoc otherwise wraps output at 72 columns,75 splitting long opening tags and inline `<strong>` labels across lines. Every downstream76 regex then misses those elements *silently* — sections vanish from the deck and the TOC77 with no error.78- **Match tags as `<h2\s+id=`**, never `<h2 id=`, for the same reason.7980Theme changes belong in `assets/theme.css` (shared) and `assets/deck.css` (slide geometry81only); both are driven by the `:root` custom properties, so recolouring means editing82those properties rather than the rules.