A deck is an ordinary Clojure value, so the same source renders as a live presentation, as a standalone HTML file, and as an assertion in a test suite.
Slides become programs without becoming a JavaScript project.
(deck/deck
{:title "My talk"
:slides [(deck/slide :intro
[:h1 "Hello"]
{:background-image "hero.jpg"
:notes "Speaker-only"})
(deck/stack :details
[(deck/slide :one [:p "First"])
(deck/slide :two [:p "Second"])])]})Nothing is registered, mounted or configured. deck/deck validates the tree and throws rather than rendering something wrong.
Images, GIFs, video with poster and sources, audio, iframes.
Bullets, ordered lists, tables, quotations, callouts, kickers.
Language-tagged blocks with stepped line highlighting.
Columns, card grids, groups and Reveal fragments.
(defmethod content/render :timeline [{:keys [events]}]
(into [:ol.acme-timeline]
(map (fn [e] [:li (:label e)]))
events))
(defn timeline [events]
{:plato/type :timeline :events events})defmethod. No edit to the deck model, the browser shell, or the HTML exporter.---
title: My talk
---
# Hello
Revenue and the *three bets*.
Note: ninety seconds.#+TITLE: My talk
* Hello
Revenue and the /three bets/.
:NOTES:
Ninety seconds.
:END:(ns talk.latex
(:require [plato.source :as source]))
(defn ->deck [text]
...)
(source/register-extensions! :latex ["tex"])
(defmethod source/->deck :latex [_ text]
(->deck text))Markdown, Org and EDN ship this way. plato.cli does not know their names.
| Browser | Static export | |
|---|---|---|
| Runtime | Reagent + Reveal.js | JVM or a native binary |
| Scenes | Live, scrub-able SVG | Final frame, same SVG code |
| Slide attributes | plato.deck/section-attrs | plato.deck/section-attrs |
| Output | A running page | One self-contained .html |
{:meta {:prefix "plato" :reveal-theme "night"}
:color {:bg "#0b0e13" :accent "#f0ac5f"}
:scene {:palette [:teal :gold] :background :bg}
:rules
[[:.reveal {:background [:token :bg]}
[:.plato-kicker {:color [:token :accent]}]]]}A :root custom property per token, then the theme's own rules.
The tokens as data — the scene palette is derived from it.
A language-neutral manifest, value and variable per token.
A theme may :extends another and state only what differs. Scene colours and CSS colours cannot drift, because they are the same token.
# any registered format, one command
plato build talk.md -o dist/talk.html --assets public
plato build talk.org -o dist/talk.html
plato build deck.edn -o dist/talk.html
# tokens in, stylesheet out
plato theme theme/acme.tokens.edn -o css/acme.cssOn the JVM, or as a self-contained native binary built with ClojureWasm — no JVM at run time.
A deck is an ordinary Clojure value.