Slide Deck

approvedunreviewed

by Johannes Kaindl

Turn a Markdown note into a slide deck and export it to PDF or a PNG image series, with live readability checks.

โ†“ 537 downloadsUpdated 8d agoAGPL-3.0

Slide Deck

๐Ÿ‡ฌ๐Ÿ‡ง English ยท ๐Ÿ‡ฉ๐Ÿ‡ช Deutsch

Turn a Markdown note into a slide deck and export it to PDF or a PNG image series, with live readability checks.

License: AGPL-3.0 Release Docs: CC BY-SA 4.0 Platform: Desktop + Mobile

A two-column slide in the kami theme: a bullet list with inline code and KaTeX math on the left, a bar chart filling the right column

Features

  • Theme isolation โ€” slides render inside a sandboxed iframe, so the active Obsidian theme never leaks into the preview or the exports. A deck looks identical regardless of the vault theme.
  • Nine built-in themes โ€” the Nordstern set: kami ็ด™ (light, default), kogane ้ป„้‡‘ (dark), sumi ๅขจ (true-black, high-contrast), kairo ๅ›ž่ทฏ (dark, cyan), kurenai ็ด… (dark, red); plus the crimson ็ด… family in four modes (crimson-dark, crimson-dark-lc, crimson-light, crimson-light-lc), which adds a serif display face over a mono body and a faint scanline the low-contrast modes dim. Selected per deck via the theme: frontmatter key; each carries a matching code-highlight and Mermaid theme. Legacy 0.4.x keys (default, dark, serif, high-contrast) still work โ€” they resolve silently to their Nordstern successor.
  • Live theme switcher โ€” the preview toolbar has a theme dropdown for ephemeral try-on, a source label (from frontmatter / from default / โ— unsaved) that shows where the active theme comes from, and a Set button that writes theme: directly into the note's frontmatter. Frontmatter is the source of truth; the Settings default applies only to notes without a theme: key.
  • User themes โ€” drop .css files into a configurable themes folder (default Slide-Deck-Themes/); the frontmatter theme: value is the filename without the .css extension. Each file is a --sd-* token block with optional extra CSS on top of the plugin's design system (type scale, spacing, rhythm) โ€” a 7-token theme already looks finished; user themes inherit the kami theme's code-highlight and Mermaid styles unless overridden. See the theming guide. The Settings tab shows all valid theme keys live.
  • Theme import/export โ€” an Open in Finder button reveals the themes folder so you can drop files in; Export theme as .css writes any theme as an editable .css starting point; a toggle hides the themes folder in Obsidian's file explorer.
  • Twelve per-slide templates โ€” default, title, section, quote, image-focus, two-column, columns-3, stat, cover-image, agenda, threads, closing โ€” set per slide with a layout directive (an HTML comment); columns are separated by a column directive, and in multi-column templates the leading heading spans all columns. See the layout guide.
  • Combinable density modifiers โ€” add compact (tighter type) or code-heavy (smaller code) to any template in the same layout directive.
  • Smart layout inference โ€” with no explicit directive, the layout is inferred from content shape: a lone heading becomes section, a lone block quote becomes quote, a lone image or diagram becomes image-focus, and column splits pick two-column / columns-3. An explicit layout directive always wins.
  • Deck slots โ€” header:, footer:, and paginate: frontmatter keys render as floating corner slots on every slide (pagination shows n / N).
  • Media that fills and centers โ€” block images and Mermaid diagrams occupy the available space, horizontally and vertically centered and scaled to fit (object-fit: contain), for both Obsidian embeds (![[โ€ฆ]]) and standard Markdown images.
  • Sparse slides compose vertically โ€” slides with little content are vertically centered instead of clinging to the top.
  • Markdown notes โ†’ slides โ€” separate slides with a line containing only ---; YAML frontmatter controls theme, aspect ratio, and font floor per note.
  • Live preview pane โ€” renders the current note as a slide deck in a side panel, scaled to pane width, with a click-to-source link on overflow warnings.
  • Fit-or-warn readability โ€” each slide auto-scales content down to a configurable legibility floor (minFontPx); slides that would need smaller text are flagged as overflowing instead of becoming unreadable.
  • Custom CSS โ€” an optional CSS snippet in Settings is appended to the deck styles in both preview and exports, for branding or tweaks.
  • PDF export โ€” renders all slides at their native resolution; on desktop, triggers the system print dialog (choose "Save as PDF"); on mobile (iOS/iPadOS), writes a self-contained HTML file and opens it via the OS so you can print or share to PDF from there.
  • PNG image-series export โ€” captures each slide via modern-screenshot and writes numbered PNGs into a configurable export folder (Settings, default Slide-Deck-Export/); typographically accurate inter-word spacing.
  • Mobile support โ€” runs on iOS/iPadOS (Obsidian Mobile); all desktop-only APIs are platform-guarded.
  • KaTeX math โ€” inline and display math ($โ€ฆ$ / $$โ€ฆ$$) rendered by KaTeX.
  • Code highlighting โ€” fenced code blocks highlighted by highlight.js, per-theme.
  • Accessible callouts โ€” Obsidian-style > [!note], [!warning], [!danger], [!tip], [!info] blocks rendered with redundant coding: border color + geometric shape + visible label word (not color-only; satisfies WCAG 1.4.1).
  • Mermaid diagrams โ€” fenced ```mermaid ``` blocks rendered as SVG, per-theme.
  • EN/DE interface โ€” all UI strings follow Obsidian's language setting (English canonical, German supported).
  • Image slots (desktop, requires local-image-generator) โ€” a slide-image code block renders as a card with a generate button; on click it calls the neighbor plugin to produce and save an image, then replaces itself with a normal embed plus a prompt comment for re-rolling later.

Screenshots

The note and its projection. The deck renders in a side panel and carries the toolbar: theme picker, where the active theme comes from, and the two export paths.

Obsidian with the note on the left and the Slide Deck preview on the right, showing the theme picker, the from-frontmatter source label, PDF and image export buttons, and slides with a running header and page indicator

Nine built-in themes. The same slide in each โ€” only colour, type and accent change; the structure is theme-independent.

A three-by-three grid showing the same slide rendered in all nine built-in themes: kami, kogane, sumi, kairo, kurenai, crimson-dark, crimson-dark-lc, crimson-light and crimson-light-lc

Twelve per-slide templates. Set one with a layout directive, or let the layout be inferred from the slide's shape. The grid shows the nine general ones; agenda, threads and closing are in the layout guide.

A three-by-three grid of the nine slide templates: title, section, quote, image-focus, two-column, columns-3, stat, cover-image and default

Fit-or-warn. A slide that would need text below the legibility floor is flagged in the preview instead of being silently clipped.

The preview pane showing the warning: slide 1 content overflows at the legibility floor, condense this slide, above the slide marked with a red bar

Accessible callouts. Meaning is carried three ways at once โ€” border colour, geometric shape, and a visible label word.

A slide showing all five callout types (note, tip, info, warning, danger), each with a coloured border, a distinct symbol and a label word

Settings. The tab lists every valid theme: value live, including themes you drop into the themes folder yourself.

The Slide Deck settings tab, showing the default theme picker, the list of all nine valid theme keys, the legibility floor, export and themes folders, and the local AI endpoint section

Click the preview for the full-resolution image.

Requirements

  • Obsidian โ‰ฅ 1.11.4 (minAppVersion; API keys live in Obsidian's secret storage, which arrived with 1.11.4). From 1.13.0 the settings tab uses the declarative settings API; older versions get the same settings through a classic fallback.
  • Desktop + Mobile (isDesktopOnly: false) โ€” runs on desktop (Windows, macOS, Linux) and on mobile (iOS/iPadOS); desktop-only APIs are platform-guarded.
  • Desktop PDF export uses the system print dialog โ€” choose "Save as PDF" in the printer dropdown. It does not produce a PDF file directly.
  • Mobile PDF export writes a self-contained HTML file into the export folder and opens it with the OS default app; from there you can print or share to PDF. The file name is <export-folder>/<note-name>.html.
  • PNG export writes files into a configurable export folder (Settings โ†’ Slide Deck โ†’ Export folder, default Slide-Deck-Export/). PDF export on desktop goes through the system print dialog, where you choose the location.

Install

Catalog (recommended)

Via AnySource Sideloader, which installs and updates plugins from any git forge. Subscribe to the plugin catalog once under Settings โ†’ AnySource Sideloader โ†’ Catalogs โ†’ Add:

https://git.jkaindl.de/jkaindl/obsidian-catalog/raw/branch/main/catalog.json

Slide Deck then appears in the sideloader's plugin list and updates like any other plugin. Version checks go live to this repository's releases โ€” the catalog only lists what exists, it never serves the files itself. To install just this one plugin without the catalog, add its repository URL as a source instead: https://github.com/johannes-kaindl/slide-deck.

Manual

  1. Download main.js, manifest.json, and styles.css from the latest release.
  2. Create the folder .obsidian/plugins/slide-deck/ inside your vault.
  3. Copy the three files into that folder.
  4. In Obsidian: Settings โ†’ Community plugins โ†’ Installed plugins โ€” enable Slide Deck.

Build from source

git clone https://git.jkaindl.de/jkaindl/slide-deck.git
cd slide-deck
npm install
npm run build          # produces main.js
cp main.js manifest.json styles.css /path/to/vault/.obsidian/plugins/slide-deck/

Usage

  1. Open a Markdown note and separate slides with a line containing only ---.
  2. Run Open presentation preview (command palette) โ€” the deck renders in a side panel and updates as you edit. Slides that overflow are flagged there rather than silently clipped.
  3. Set theme, aspect ratio and font floor per note in the YAML frontmatter:
---
theme: kami
aspect: "16:9"
minFontPx: 24
header: My talk
paginate: true
---

# First slide

---

# Second slide
  1. Export with Export presentation to PDF or Export presentation to image series. PDF prints the isolated deck directly on desktop; on mobile a self-contained HTML file is written to your export folder and handed to the OS, where you print or share it as PDF.

Per-slide layout is chosen with a layout directive โ€” an HTML comment on its own line:

<!-- layout: two-column compact -->

# Heading spanning both columns

Left column content.

<!-- column -->

Right column content.

Omit the directive and the layout is inferred from the slide's shape. The full template and modifier reference is in the layout guide.

Image slots

Requires the local-image-generator plugin (desktop only). Run Insert image slot (command palette), pick one of six image functions (documentary, analytical, metaphorical, emotional, navigational, decorative) โ€” each steers the prompt with its own style suffix โ€” and write a prompt:

```slide-image
funktion: metaphorical

A single lantern in fog, one clear light source
```

The block renders as a card with a Generate button. Clicking it asks the neighbor plugin for an image, saves it per that plugin's own settings, and replaces the block with a plain embed plus a prompt comment (so a later re-roll has something to start from):

<!-- image: metaphorical | A single lantern in fog, one clear light source -->
![[lantern-fog.png]]

Without local-image-generator installed and enabled, the card shows an empty state instead of a button.

Configuration

Plugin settings

SettingKeyDefaultDescription
Default themedefaultThemekamiPreset used when a note has no theme frontmatter directive
Minimum body font size (px)minFontPx24Legibility floor โ€” slides that would need smaller text are flagged as overflowing
Image export scaleimageScale2Pixel multiplier for PNG export (2 = 2ร—, crisp on HiDPI screens)
Custom CSScustomCss(empty)CSS appended to the deck styles in preview and exports, for branding or tweaks
Image export folderexportFolderSlide-Deck-ExportVault folder for the PNG image-series export
Themes folderthemesFolderSlide-Deck-ThemesVault folder scanned for user .css themes
Hide themes folder in file explorerhideThemesFoldertrueHide the themes folder in Obsidian's file explorer
Image functionsimageSuffixes(built-in defaults)One editable prompt suffix per image function (blank restores the default)

Per-note frontmatter

Add a YAML frontmatter block at the top of your note to control presentation-level settings:

---
theme: kogane
aspect: 16:9
minFontPx: 24
header: My talk
footer: ACME Corp
paginate: true
---
KeyValuesDescription
themekami ยท kogane ยท sumi ยท kairo ยท kurenai ยท crimson-dark ยท crimson-dark-lc ยท crimson-light ยท crimson-light-lc ยท user-theme-key (legacy default/dark/serif/high-contrast still resolve)Visual preset name; user theme key = the .css filename without the extension
aspect16:9 (default), 4:3Canvas size: 1280ร—720 (16:9) or 960ร—720 (4:3)
minFontPxany positive numberPer-note legibility floor; overrides the plugin setting
headerany textFloating header slot shown on every slide
footerany textFloating footer slot shown on every slide
paginatetrue ยท yes ยท onShow a page indicator (n / N) on every slide

Slide layout & syntax

Twelve per-slide templates (default, title, section, quote, image-focus, two-column, columns-3, stat, cover-image, agenda, threads, closing), combinable density modifiers (compact, code-heavy), the layout and column directives, and smart layout inference are documented in the Slide layouts & syntax guide.

Slide separator

Use a line containing only --- to split slides:

---
theme: kami
aspect: 16:9
---

# Slide 1

Content here.

---

# Slide 2

More content.

Note: the --- in the YAML frontmatter block is the standard YAML delimiter and is not a slide separator.

How it works

  1. Parsing โ€” the active note's Markdown is split on --- lines into individual slide bodies. A YAML frontmatter block (if present) sets deck-level directives.
  2. Fixed canvas โ€” each slide is rendered onto a fixed canvas: 1280ร—720 px (16:9) or 960ร—720 px (4:3). The canvas size does not change with window size.
  3. Theme isolation โ€” slides render inside a sandboxed iframe with the chosen theme's styles injected directly. The active Obsidian theme does not reach inside the iframe, so the deck looks identical in preview, PDF, and PNG regardless of vault theme.
  4. Fit-or-warn โ€” each slide's content is measured in the DOM. If it exceeds the canvas, the content is scaled down uniformly. Scaling stops at minFontPx (the legibility floor). If the content would still overflow at that scale, the slide is flagged with a warning in the preview pane rather than scaled further.
  5. Export โ€” the same theme-isolated iframe artifact feeds all export paths: the print pipeline (PDF) and per-slide modern-screenshot (domToCanvas) capture (PNG). On desktop, PDF is printed via contentWindow.print(); on mobile, a self-contained HTML file is written to the vault and handed to the OS via openWithDefaultApp.

Network use (local AI)

The Generate presentation from note command sends note content to an OpenAI-compatible LLM endpoint that you configure (default http://localhost:1234, i.e. a local LM Studio). No cloud service is involved unless you point the endpoint at one โ€” the settings tab holds an ordered list of endpoints, tried in order, and each row can carry its own optional API key, so a local server and a hosted provider (e.g. OpenRouter) can sit side by side in the same list. API keys are not stored in the plugin's data.json: they go into Obsidian's secret storage (Settings โ†’ Keychain), and a plain-text key from an older version is moved there on first start.

If the LLM Endpoint Manager plugin is installed, the endpoints (and their keys) come from it instead: the settings tab then offers an endpoint and model choice, and your local list stays as a fallback for when the manager is off.

  • Reachability pings and model lists are requested when you open the generation dialog or the settings tab. These are automatic requests to the configured endpoint(s).
  • Note contents are sent only when you press "Generate". Secrets in the text (private keys, bearer tokens, API keys) are replaced by placeholders on the way out; the generated deck gets the originals back.
  • No telemetry, no analytics, no third-party services.

Server CORS

Streaming runs over XMLHttpRequest under the Obsidian origin, so the endpoint must allow cross-origin requests. LM Studio's CORS toggle must be on; Ollama needs OLLAMA_ORIGINS=app://obsidian.md (or *). If the endpoint answers the reachability ping but refuses the stream, the plugin automatically falls back to a non-streaming request (you lose the live token view, but the deck still generates).

Documentation

License

Code: AGPL-3.0-or-later โ€” a commercial license is available on request, see LICENSING.md. Documentation: CC BY-SA 4.0. Author: Johannes Kaindl โ€” https://jkaindl.de

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.