PowerPoint export (--format pptx)
slidelang build deck.slidelang --format pptx produces an editable .pptx.
slidelang build deck.slidelang --format pptx --output ./distThe defining property of this format is that it never launches a browser. Every other rich output path can fall back to headless Chromium; PPTX has no such fallback by design, which is what makes it the format that works on a machine with no Chromium installed at all. That single constraint explains most of what follows.
What lands in the deck
Section titled “What lands in the deck”Each content block becomes one slide. Titles and subtitles use the layout’s own placeholders; body content is stacked vertically as freeform shapes.
| Element | Rendered as |
|---|---|
| Text | Text box, with inline bold/italic/code and the [x]{.token} spans resolved per segment (tokens from v2.32.4; see Inline Formatting for which of the fourteen carry formatting) |
| Bullet lists | Bulleted paragraphs, one level of nesting |
| Tables | Native PowerPoint table, including merged cells |
| Images | Embedded PNG/JPEG/GIF — local sources only |
| Quotes | Indented italic text box with an attribution line |
| Checklists | Bulleted list using ☑ / ☐ as the bullet character |
| Code | Monospaced text box, no bullet, markdown left literal |
| Charts | Rasterized PNG — see below |
Everything is a real shape, so the result stays editable in PowerPoint: you can move things, retype text, and restyle. Because the generator has no font metrics available, vertical stacking uses an estimate — if a block wraps differently than predicted, the spacing is approximate, not the content.
Checklist state lives in the bullet
Section titled “Checklist state lives in the bullet”A checked item gets ☑ and an unchecked one ☐, as the paragraph’s bullet
character rather than as text prepended to the content. That means the state
survives the reader rewriting the item’s text in PowerPoint.
Code blocks are not parsed as markdown
Section titled “Code blocks are not parsed as markdown”Inside a code block, * and ` are literal characters. They are
deliberately excluded from the inline-markdown pass that text and bullets go
through, so a snippet containing a := *ptr survives verbatim.
Charts
Section titled “Charts”Charts are rasterized to PNG by a pure-Go renderer — no browser, no network.
Native chart types: bar, line, pie, doughnut. A type without a
native mapping (radar, combo) is skipped with a warning and replaced by a
visible [Chart not rendered: <type>] marker, rather than silently vanishing.
Charts with an options: block are drawn approximately
Section titled “Charts with an options: block are drawn approximately”Chart.js configuration has no equivalent in the native renderer. Rather than
omit such charts — which in practice would mean omitting almost all of them,
since real charts nearly always carry options: — they are drawn with what the
native renderer does support, and the build logs exactly which keys were not
applied:
⚠️ PPTX: el chart "bar" se dibujó de forma aproximada — de options: plugins, responsive, scales el renderer nativo solo aplica el títuloThe chart title is recovered from options.plugins.title.text, since that is
where Chart.js expects it and where these decks normally put it. A display: false
on that title is respected, and a top-level title: takes precedence.
Legends, series names, axes and categories are drawn from the chart’s data.
What does not survive is the fine configuration: datalabel anchoring, legend
position, axis titles, beginAtZero, plugin options.
What is not exported
Section titled “What is not exported”These are skipped with an explicit warning naming the element type — never silently:
| Element | Why |
|---|---|
| Mermaid, PlantUML | Skipped by default, because --format pptx never starts Chromium. Pass --diagram-backend kroki and they are embedded: the build fetches a PNG from a Kroki server (--kroki-server points it elsewhere) and writes it into the deck as a picture. The skip warning names the flag. The only requirement is network access to that server |
| Maps | Leaflet tiles require a browser |
| Math | MathJax requires a browser |
| Special blocks, code groups, grids | Containers with their own layout, not a single shape |
Remote images (http://, https://) |
Not downloaded; replaced by a text placeholder |
Watch the build log rather than the deck — “a diagram is missing” should be a line you can read, not a mystery.
Local image confinement
Section titled “Local image confinement”Image sources come from document content, which is not trusted input. They are
confined to --asset-root, defaulting to the input file’s own directory:
slidelang build deck.slidelang --format pptx --asset-root ./assetsAn absolute path, or one escaping the root via .., is rejected and replaced by
a [Image blocked: …] placeholder. Without this, a crafted document could embed
an arbitrary local file from the machine running the build into the generated
.pptx.
Comparison with the other formats
Section titled “Comparison with the other formats”| pptx | html | ||
|---|---|---|---|
| Needs Chromium | Never | Only for offline-* render modes |
Yes |
| Editable output | Yes | — | No |
| Mermaid / PlantUML | Only with --diagram-backend kroki |
✓ | ✓ |
| Charts | Approximate | Faithful | Faithful |
| Maps, math | ✗ | ✓ | ✓ |
See Offline rendering & diagram backends for how to reduce or remove the Chromium dependency in the HTML and PDF paths.