Skip to content

Deck fixes, image layout, Mermaid diagrams and frameless images - #8

Merged
chris-colinsky merged 16 commits into
mainfrom
feature/image-frame
Sep 23, 2026
Merged

chris-colinsky merged 16 commits into
mainfrom
feature/image-frame

Conversation

@chris-colinsky

Copy link
Copy Markdown
Member

Addresses the open issues from deck-building feedback, plus three new features.

Fixes

  • blockquote line length is too short #5 The > lead wrapped at 24ch, about half the width of the bullets. It is now 42ch, which wraps close to where a bullet does.
  • page title on slides with images #7 On split slides the kicker was pinned to the top of the slide, away from its heading. It now sits in the text column, just above the heading, as on the other layouts.
  • deep linking #6 The URL hash tracks the current slide. deck.html#4 opens slide 4, and a reload after a rebuild stays on the same slide. Slide steps use replaceState, so Back still leaves the deck.
  • deck building challenges #3, in three parts:
    • When a layout rejects content, the error now lists what that layout takes, e.g. a paragraph isn't used by the table layout, which takes a ## heading and a | table.
    • A line starting with // is an author note. It is dropped wherever it sits, never reaches the page, and doesn't split lists or shift error line numbers.
    • A split slide with no image: line builds with a dashed placeholder. A misspelled image path still stops the build.

New

  • image layout. A slide that is only an image: it fills the slide, centered, with the kicker at the top left. It takes image, image-alt, image-max and image-frame, and shows the placeholder when there is no image yet.
  • Mermaid diagrams. image: flow.mmd is drawn to SVG at build time with the Mermaid CLI (mmdc), so the page stays self-contained. mmdc is optional. Without it, or on a Mermaid syntax error, the build stops with a message that says what to do.
  • image-frame: no. Set it in the config block or on one slide to drop the white panel behind images. A Mermaid diagram with no frame is drawn in the deck theme's colors.

Docs (syntax.md, how-it-works.md, speaker-notes.md, README), the demo deck and its notes, and the changelog are updated to match.

Notes for review

  • The fixes were built on separate branches and merged here, so the history has merge commits. The only conflicts were in CHANGELOG.md and two test files, and both sides were kept.
  • One test does a real mmdc render. It is skipped when mmdc isn't installed; the other Mermaid tests stand in a fake mmdc.
  • Chromium-based browsers are the target for Mermaid output, since its labels use <foreignObject>.

Testing

  • uv run pytest: 104 pass, including the real Mermaid render.
  • uv run ruff check . && uv run ruff format --check . and uv run pyright: clean.
  • Checked by screenshot in headless Chrome, in both themes: the lead width, the split kicker, hash navigation, placeholders, the image layout with tall and wide images, and Mermaid diagrams with and without a frame.

The lead was capped at 24ch, so it wrapped at about half the width
of the bullet points below it. At 42ch it wraps close to where a
60ch bullet does, since the lead's font is about 1.4 times larger.

Fixes #5
The kicker was rendered above the split grid, which fills the slide,
so it sat pinned to the top while the heading sat mid-column. It now
renders in the text column, just above the heading, as on the other
layouts.

Fixes #7
The deck opens on the slide named in the hash and writes the number
back on every move, so a link can point at a slide and a reload after
a rebuild stays put. replaceState keeps slide steps out of the
browser history, so Back still leaves the deck.

Fixes #6
The layouts accept different blocks, and the rules are hard to hold
in your head. When a slide holds content its layout doesn't use, the
error now ends with the blocks that layout does take, built from the
same table the parser checks against.

Part of #3
Authors had nowhere to leave a reminder next to a slide: ((dimmed))
text still renders in front of the audience. A line starting with //
is now dropped wherever it sits. Content around it parses as if it
weren't there, error line numbers stay right, and a chunk holding
only notes is skipped so it can stub a future slide.

Part of #3
A slide that needs a diagram that doesn't exist yet had to sit in the
wrong layout, because split required an image: line. It now builds
without one and shows a dashed box where the image will go. An
image: that names a missing file still stops the build.

Fixes #3
# Conflicts:
#	CHANGELOG.md
#	tests/test_parse.py
#	tests/test_render.py
Some slides are a diagram and nothing else, and split forces a
heading column beside it. The image layout fills the slide with the
image, centered, and keeps the kicker at the top left. The image keys
now apply to both split and image, and a missing image: line shows
the same placeholder as split.
Diagrams written in Mermaid had to be rendered by hand before they
could go on a slide. image: flow.mmd now runs the Mermaid CLI (mmdc)
and embeds the SVG, so the page stays self-contained. mmdc is an
optional install; without it, or on a Mermaid syntax error, the build
stops with a message that says what to do. The SVG gets a pixel size
from its viewBox, since Mermaid's width="100%" leaves an <img> with no
natural size.
Every image sat on a white panel, so a Mermaid diagram showed as a
white box on a dark slide. image-frame: no, set for the deck or on
one slide, puts the image straight on the slide. An unframed Mermaid
diagram is drawn in the theme's colors, read from its tokens, with
Mermaid's dark mode set from the brightness of --bg. Framed diagrams
keep Mermaid's default look, which reads well on white.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Theme token extraction can misparse valid CSS comments and break builds or Mermaid colors.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Adds image-focused layouts, Mermaid rendering, author notes, deep linking, and several presentation fixes.

Changes:

  • Adds image layouts, placeholders, frameless images, and Mermaid support.
  • Improves parsing errors, author notes, split-slide kickers, and lead width.
  • Adds hash navigation, tests, examples, and documentation.
File Description
src/​akceo/​parse.py Adds image layout, frame settings, notes, and clearer validation.
src/​akceo/​render.py Renders image layouts, placeholders, frames, and themed Mermaid images.
src/​akceo/​images.py Converts Mermaid diagrams to embedded SVG.
src/​akceo/​themes.py Extracts theme token values.
src/​akceo/​assets/​deck.js Adds hash-based slide navigation.
src/​akceo/​assets/​base.css Updates lead, image, and placeholder styling.
tests/​test_parse.py Covers new parsing behavior.
tests/​test_render.py Covers image and split rendering.
tests/​test_images.py Covers Mermaid rendering and configuration.
tests/​test_themes.py Covers token extraction.
tests/​test_cli.py Updates end-to-end build coverage.
README.md Documents Mermaid and deep linking.
docs/​syntax.md Documents the expanded deck syntax.
docs/​how-it-works.md Updates architecture and pipeline details.
docs/​speaker-notes.md Updates the demo slide count.
examples/​demo/​deck.md Demonstrates author notes and image layout.
examples/​demo/​speaker-notes.md Adds notes for the new slide.
CHANGELOG.md Records the new features and fixes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/akceo/themes.py
Comment thread docs/how-it-works.md Outdated
A --token: written inside a /* comment */ was read as a real
declaration. It could overwrite a token's value and swallow the next
declaration, so build() raised KeyError for any deck using that
theme, and a token set only in a comment passed the token check.
Comments are now removed before both the check and the value read.

Also note in the pipeline diagram that a slide with no image: line
skips data_uri and gets the placeholder.
@chris-colinsky
chris-colinsky merged commit d9a854f into main Sep 23, 2026
1 check passed
@chris-colinsky
chris-colinsky deleted the feature/image-frame branch September 23, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants