mdeck 3.10.1 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +13 -2
  3. package/assets/base.css +4 -1
  4. package/docs/reference/authoring.md +65 -4
  5. package/docs/site/assets/site.css +2 -0
  6. package/docs/site/content/commands.md +3 -1
  7. package/docs/site/content/drawing.md +1 -1
  8. package/docs/site/content/install.md +47 -0
  9. package/docs/site/content/media.md +20 -1
  10. package/docs/site/content/presenting.md +39 -2
  11. package/docs/site/content/sharing.md +1 -0
  12. package/docs/site/content/welcome.md +21 -1
  13. package/docs/site/images/features/hotspots.webp +0 -0
  14. package/docs/site/images/features/languages.webp +0 -0
  15. package/docs/site/pages.js +1 -0
  16. package/examples/custom-layouts/slides.md +21 -9
  17. package/examples/showcase/refs.bib +21 -0
  18. package/examples/showcase/slides.ar.drawings.json +11 -0
  19. package/examples/showcase/slides.ar.md +567 -0
  20. package/examples/showcase/slides.de.drawings.json +11 -0
  21. package/examples/showcase/slides.de.md +567 -0
  22. package/examples/showcase/slides.en.drawings.json +11 -0
  23. package/examples/showcase/{slides.md → slides.en.md} +112 -5
  24. package/package.json +1 -1
  25. package/skills/write-slides/SKILL.md +10 -1
  26. package/src/build/check.js +7 -1
  27. package/src/build/config.js +2 -0
  28. package/src/build/slidesPlugin.js +6 -6
  29. package/src/build/svgCheck.js +65 -0
  30. package/src/build/timingPlugin.js +80 -0
  31. package/src/cli/args.js +4 -3
  32. package/src/cli/index.js +34 -11
  33. package/src/components/VideoPlayer.jsx +6 -1
  34. package/src/core/editDeck.js +44 -7
  35. package/src/core/icons.js +3 -0
  36. package/src/core/labels.js +75 -0
  37. package/src/core/parseSlides.js +3 -3
  38. package/src/core/timing.js +83 -0
  39. package/src/core/validateDeck.js +5 -0
  40. package/src/editor/components/DeckSettings.jsx +1 -0
  41. package/src/editor/components/MetaFields.jsx +1 -0
  42. package/src/home/Home.jsx +1 -0
  43. package/src/layouts/layoutApi.jsx +51 -8
  44. package/src/runtime/RehearsalSummary.jsx +129 -0
  45. package/src/runtime/component.js +27 -0
  46. package/src/runtime/deck-stage.js +49 -20
  47. package/src/runtime/ink/bus.js +13 -5
  48. package/src/runtime/ink/outbox.js +27 -0
  49. package/src/runtime/ink/room.js +31 -6
  50. package/src/runtime/ink/segments.js +21 -0
  51. package/src/runtime/main.jsx +157 -28
  52. package/src/runtime/shared.js +77 -0
  53. package/src/runtime/steps.js +36 -0
  54. package/src/runtime/useTalkTimer.js +65 -0
  55. package/examples/citations/refs.bib +0 -30
  56. package/examples/citations/refs.yml +0 -21
  57. package/examples/citations/slides.md +0 -43
  58. package/examples/citations/slides.pdf +0 -0
  59. package/examples/poll/slides.md +0 -127
  60. package/examples/showcase/slides.drawings.json +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.11.0 — 2026-10-12
4
+
5
+ - Time your talk. `time: 2m` in a slide's settings is how long to spend on it, `time: 20m` in the deck's the length of the talk; slides without a time share what is left. The presenter view counts down the time left on the slide and shows whether you are ahead of or behind the plan. `mdeck rehearse` (or **Rehearse** in the presenter view and on the launch page) times each slide as you go through the talk; at the end a table offers the times rounded to 15 seconds, to change in 15-second steps, and **Save to deck** writes them into the slides' settings without reloading the open windows. The editor has a Time field for each slide and a Length for the deck, and `mdeck check` reports a time it cannot read.
6
+ - Under `mdeck run`, the presenter view has a button back to the launch page.
7
+ - The presenter view's timer reads the clock instead of counting seconds, so it no longer falls behind, and carries on through a reload. **T** starts and pauses it.
8
+ - mdeck's own words come in Arabic too: with `lang: ar`, or a file named `talk.ar.md`, the reader view, the control bar, polls, the phones' answer page and callout titles are Arabic.
9
+ - Fixed on slides set from right to left: a palette-coloured drawing (an SVG mdeck places in the page) had its text run out of its box, and a citation in Latin script, such as (Roediger & Karpicke, 2006), was jumbled where it met Arabic text. Drawings now keep their own direction, and citations and references read in theirs.
10
+ - The tour comes in English, German and Arabic (`examples/showcase/slides.en.md`, `.de.md`, `.ar.md`), each with its drawings in place; `mdeck run slides.en.md` switches between them with **L**. It now also shows citations and a word cloud for the room; the poll and citations examples it replaces are gone.
11
+ - Fixed: on a slide with several areas (`:::slot`), a code block in one area turned the next area into code: its citations and footnotes showed as written, while those inside the code block were filled in. Citations and footnotes now leave code blocks and `inline code` alone, and the areas after one are prose again.
12
+ - Deck components can share state across slides and windows: `import { useShared, useView } from 'mdeck/component'`. `useShared('count', 0)` works like `useState`, but every slide, the presenter's slide, the audience window, other windows in the browser and a paired iPad see the same value, and a window opened later gets it. `useView()` says which window a component is in. `mdeck/component` is the first part of mdeck that components may rely on; the authoring reference says what it promises and what stays mdeck's own.
13
+ - A drawing that uses the palette (an SVG with `var(--…)`) builds up in the order its parts are numbered: `data-step="1"`, `data-step="2"` … reveal one press at a time, parts with the same number together, whatever their order in the file, which is also the order they are drawn in. Bare `data-step` parts still appear in document order. With hotspots on, `data-hotspot` on a part makes it a hotspot once it is shown.
14
+ - Fixed: a drawing on two slides lost its arrowheads, gradients and `<use>` copies on the second, because `url(#…)` found the copy on the hidden first slide. Each copy in the page now gets ids of its own.
15
+ - `mdeck check` looks at the deck's SVG drawings: palette names without a fallback, fixed colours that stay the same in every palette and in dark mode, style rules that reach the rest of the page, numbered and bare steps in one drawing, and `data-step` or `data-hotspot` in a drawing that uses no palette colour and so is shown as a picture.
16
+ - The slide-writing skill draws diagrams as SVG in the palette's colours, builds them up with numbered steps and checks them in light and dark.
17
+ - A deck shared in part, with `--slide` or `--no-polls`, keeps the time its slides were planned to take as its `time:`, so the presenter view's countdown fits the part. The note that slides with polls were left out now appears only when one of the chosen slides had a poll.
18
+ - Fixed: a YouTube video in `<videoplayer>` showed "This video is unavailable" on a device that opened the deck through a server, such as a paired iPad. Such pages send no referrer, which YouTube requires of embedded players; the player now sends the deck's origin (never its path).
19
+ - Fixed: in a deck with polls, every slide change in the presenter view read the whole deck several times over to find out whether it has any. On an iPad presenting a large deck, slides changed noticeably slower than in the audience window. The answer is now kept until the deck changes.
20
+ - `--slide 3,5-7` for `mdeck send`, `mdeck build` and `mdeck pdf` keeps only these slides, for example the part of a deck shown in one lecture, with their drawings. The numbers count the slides as written, like `mdeck snapshot --slide` and `mdeck check --render`. A `<style>` written on a slide that is left out moves to the first slide kept, since it styles the whole deck; the same now holds for slides left out with `--no-polls`.
21
+ - Fixed: a stroke or laser trail drawn on a paired iPad could stop short in the audience window. Two batches of ink could be on their way at once and arrive in the other order, and a batch lost to the network was gone; the window then dropped that piece and everything after it. Batches now go one after another, a lost one is sent again, and a piece that arrives early waits for the one before it. While the network or the server is gone, the iPad tries again less and less often, up to every five seconds, and keeps only the laser's and the zoom's last position.
22
+ - Ink and the laser drawn on a paired iPad reach the audience window sooner: about 60 ms after the pen instead of 100 to 150 ms.
23
+ - The laser's trail stays on the screen as long as the pen is down, also in the audience window and on paired devices, so a circle or an underline can be shown while you talk about it. Lifted, it retracts as before.
24
+ - The presenter view's slide number is a field: type a number and press Enter (Go on an iPad) to jump to that slide, in the iPad's slide-only layout beside the arrows and in the speaker layout. The audience window and paired devices follow.
25
+
3
26
  ## 3.10.1 — 2026-10-11
4
27
 
5
28
  - Theme settings can be text: `type = "text"` for words a theme shows, such as Terminal's prompt. Authors write them as they should appear (`prompt: "~/demo $ "`), spaces included, and mdeck quotes them for the stylesheet; the editor shows a text box with the theme's own words. Before, such words could only be fixed in the theme.
package/README.md CHANGED
@@ -31,6 +31,18 @@ Polls, scales, word clouds, open questions and numbers to guess. People scan the
31
31
  </tr>
32
32
  <tr>
33
33
  <td width="50%" valign="top">
34
+ <a href="docs/site/images/features/hotspots.webp"><img src="docs/site/images/features/hotspots.webp" alt="The projector zoomed in on a table, and in front of it the presenter view showing the same slide with numbered keys on its code, table and formula"></a>
35
+ <p><b><a href="https://gh.tschieber.de/mdeck/presenting.html#zoom-in-on-part-of-a-slide">Zoom into a chart, a table or a line of code</a></b><br>
36
+ Turn on hotspots, and the presenter view puts a number on each picture, table, formula and code block. Press it, and the slide glides in until that part fills the projector; press it again to see the whole slide. The audience never sees the numbers.</p>
37
+ </td>
38
+ <td width="50%" valign="top">
39
+ <a href="docs/site/images/features/languages.webp"><img src="docs/site/images/features/languages.webp" alt="The same slide with a Python example in English, German, Hindi and Farsi, the Farsi one running right to left"></a>
40
+ <p><b><a href="https://gh.tschieber.de/mdeck/presenting.html#one-talk-in-several-languages">Give the talk in the room's language</a></b><br>
41
+ Keep <code>talk.en.md</code> beside <code>talk.de.md</code>, and press <b>L</b> to switch languages in the middle of the talk: slides, notes and every screen change at once, and you stay on the same slide. Farsi, Arabic and Hebrew run right to left.</p>
42
+ </td>
43
+ </tr>
44
+ <tr>
45
+ <td width="50%" valign="top">
34
46
  <a href="docs/site/images/features/citations.webp"><img src="docs/site/images/features/citations.webp" alt="A slide with author–year citations and the full references at its foot, over a slide that lists all references"></a>
35
47
  <p><b><a href="https://gh.tschieber.de/mdeck/more-content.html#cite-a-source">Cite your sources properly</a></b><br>
36
48
  Cite as in a paper, <code>[@knuth1984, p. 97]</code>, from the BibTeX, CSL-JSON or Hayagriva file you already keep. Each slide lists what it cites at its foot, in APA, Vancouver, Harvard or any CSL style.</p>
@@ -188,9 +200,8 @@ complete folder.
188
200
 
189
201
  | Example | Theme | What it demonstrates |
190
202
  |---|---|---|
191
- | [Tour](examples/showcase/slides.md) | Glass | Start here: each slide shows the Markdown beside what it becomes, from headings to layouts, live code, notes, drawing, zooming into a part, a poll and sharing |
203
+ | [Tour](examples/showcase/slides.en.md) | Neue | Start here: each slide shows the Markdown beside what it becomes, from headings to layouts, live code, citations, notes, drawing, zooming into a part, timing the talk, a poll and a word cloud for the room, and sharing; in English, [German](examples/showcase/slides.de.md) and [Arabic](examples/showcase/slides.ar.md) |
192
204
  | [Python](examples/python/slides.en.md) | Academic | A real lesson: live code to try out, points revealed step by step, notes on every slide, a poll to check understanding; in English, [German](examples/python/slides.de.md), [Hindi](examples/python/slides.hi.md) and [Farsi](examples/python/slides.fa.md), switched in the presenter view |
193
- | [Poll](examples/poll/slides.md) | Neue | A join slide, then a poll, a scale, a word cloud and open questions; start it with `mdeck run slides.md --network` |
194
205
  | [Custom layouts](examples/custom-layouts/slides.md) | Neue | A deck-local comparison design and named regions |
195
206
 
196
207
  The docs home page embeds a short talk, and the screenshots above show Neue.
package/assets/base.css CHANGED
@@ -183,7 +183,10 @@ deck-stage[data-ink-hidden] .slide-ink { display: none; }
183
183
  /* ── Code blocks ─────────────────────────────────────────────────────────── */
184
184
  .code-block { white-space: pre-wrap; overflow-x: hidden; }
185
185
  /* Code and maths read from left to right, also on a right-to-left slide. */
186
- .slide[dir="rtl"] :is(pre, code, kbd, samp, .katex, .code-block-wrapper) { direction: ltr; unicode-bidi: isolate; }
186
+ .slide[dir="rtl"] :is(pre, code, kbd, samp, .katex, .code-block-wrapper, .themed-picture) { direction: ltr; unicode-bidi: isolate; }
187
+ /* A citation and a reference read in their own direction: Latin names stay in
188
+ order beside Arabic text, and a reference list in Latin script stays left aligned. */
189
+ .slide[dir="rtl"] .citation, .slide[dir="rtl"] .slide-citations .csl-entry { unicode-bidi: plaintext; }
187
190
  /* A bullet that points along the line points the other way. */
188
191
  .slide[dir="rtl"] .slide-body ul > li::before { scale: -1 1; }
189
192
 
@@ -67,6 +67,7 @@ Each `---` line starts a new slide. Frontmatter is only needed when you want a s
67
67
  | `csl` | `apa` | Citation style: `apa`, `vancouver`, `harvard1`, or a `.csl` file |
68
68
  | `nocite` | — | References to list without citing them; `['*']` lists the whole file |
69
69
  | `show.citations` | `true` | `false` leaves out each slide's own references above the footer |
70
+ | `time` | — | How long the talk takes, such as `20m`: slides without their own `time` share what is left (see [Time your talk](../site/content/presenting.md#time-your-talk)) |
70
71
  | `hotspots` | `off` | Number keys zoom in on parts of a slide while presenting: `auto` (pictures, code, tables, formulas, videos, callouts, columns, polls and `data-hotspot` elements), `marked` (only `data-hotspot` elements) or `off` (1–9 go to slides) |
71
72
 
72
73
  ### Theme params
@@ -172,6 +173,7 @@ description: A short description shown under the title.
172
173
  | `section` | Section label shown in the slide header (auto-propagated — see below) |
173
174
  | `title` | Name in the outline and reader navigation, for slides without a heading (not shown on the slide) |
174
175
  | `hotspots` | This slide's own hotspots: `auto`, `marked`, `off` or `false` (see the deck field) |
176
+ | `time` | How long to spend on the slide: `90s`, `2m`, `1m30s` or `1.5m`. The presenter view counts it down; `mdeck rehearse` measures and saves it |
175
177
 
176
178
  ### Section labels
177
179
 
@@ -543,7 +545,7 @@ A title written after the type on the `:::` line still wins over both.
543
545
 
544
546
  ## Language
545
547
 
546
- `lang` is the language of the whole deck. The page is marked with it, so screen readers pronounce the slides correctly and browsers hyphenate them. It also picks the words mdeck itself shows the audience: the reader view's buttons, the deck's control bar, polls on the slide and on phones, and callout titles. German (`de`) and English (`en`) are built in; for any other language the words stay English. A regional code such as `de-CH` uses the German words.
548
+ `lang` is the language of the whole deck. The page is marked with it, so screen readers pronounce the slides correctly and browsers hyphenate them. It also picks the words mdeck itself shows the audience: the reader view's buttons, the deck's control bar, polls on the slide and on phones, and callout titles. English (`en`), German (`de`) and Arabic (`ar`) are built in; for any other language the words stay English. A regional code such as `de-CH` uses the German words.
547
549
 
548
550
  The presenter view, the launch page and the editor are tools for the author and always stay English.
549
551
 
@@ -709,9 +711,33 @@ palette's custom properties (`--bg`, `--surface`, `--ink`, `--ink-soft`,
709
711
  `--muted`, `--rule`, `--accent`, `--accent-2`, `--accent-3`, `--on-accent`) and follows the
710
712
  theme, palette and appearance. Give each a fallback (`var(--accent, #1f3fd1)`)
711
713
  for places that show the file on its own, set `fit: contain` to keep the whole
712
- drawing, prefix class names in its `<style>` because inline styles apply to the
713
- page, and avoid `id`s, since a slide can be shown more than once. Such SVGs stay
714
- files in single-file builds and travel inside the deck's code instead.
714
+ drawing, and start every rule in its `<style>` with a class of the drawing's
715
+ own (`.flow-box`), because inline styles apply to the page. Each copy in the
716
+ page gets ids of its own, and `url(#…)` and `href="#…"` inside it follow them,
717
+ so markers, gradients and `<use>` work on every slide that shows the drawing;
718
+ `#id` selectors in its `<style>` do not. Such SVGs stay files in single-file
719
+ builds and travel inside the deck's code instead.
720
+
721
+ Being part of the slide, such a drawing can build up: `data-step` on its parts
722
+ reveals them one press at a time. Numbered parts (`data-step="1"`,
723
+ `data-step="2"` …) appear in the order of their numbers, and parts with the
724
+ same number together, whatever their order in the file, which is also the order
725
+ they are drawn in; the drawing's steps come where its first step is in the
726
+ slide. Bare `data-step` parts appear in document order. With hotspots on,
727
+ `data-hotspot` on a part makes it a hotspot once it is shown.
728
+
729
+ ```svg
730
+ <g data-step="1" data-hotspot>…input…</g>
731
+ <g data-step="1">…output…</g>
732
+ <g data-step="2">…the arrow, drawn under both…</g>
733
+ ```
734
+
735
+ `mdeck check` warns about a palette name without a fallback (`svg-fallback`),
736
+ fixed colours that do not follow the palette or dark mode (`svg-fixed-colour`),
737
+ style rules that reach beyond the drawing (`svg-style`), numbered and bare steps
738
+ in one drawing (`svg-steps`), and `data-step` or `data-hotspot` in an SVG that
739
+ uses no palette colour, which is shown as a picture and so cannot build up
740
+ (`svg-not-inline`).
715
741
 
716
742
  A normal build copies referenced local images, video, and audio next to the HTML
717
743
  while preserving their deck-relative paths. This is the recommended distribution
@@ -822,6 +848,8 @@ While `mdeck run` runs, the answers are kept beside the deck in `<slides>.result
822
848
 
823
849
  `--no-polls` leaves slides with an activity or a join code (`<qrcode join />`) out of `mdeck send`, `mdeck build --reader` and `mdeck pdf`; without it they show as a record of the talk. Saved drawings follow the remaining slides.
824
850
 
851
+ `--slide 3,5-7` keeps only these slides in `mdeck send`, `mdeck build` and `mdeck pdf`, numbered by their place in the deck as written. Drawings follow their slides, and `<style>` elements on the slides left out move to the first slide kept, since they style the whole deck.
852
+
825
853
  Rooms run inside `mdeck run` (add `--network` so phones can reach it) or on a server started with `mdeck server`, set in the deck:
826
854
 
827
855
  ```yaml
@@ -909,6 +937,39 @@ stays out of every other deck's bundle. Install such dependencies in a
909
937
  > hooks from `preact/hooks`. The build resolves those imports back to the
910
938
  > framework's own Preact, so the deck folder needs no Preact install.
911
939
 
940
+ ### Shared state across slides and windows
941
+
942
+ A component can keep a value that every slide and every window of the talk
943
+ share: the presenter's slide, the audience window, other deck windows in the
944
+ same browser, and a paired iPad. Import it from `mdeck/component`:
945
+
946
+ ```jsx
947
+ import { h } from 'preact'
948
+ import { useShared, useView } from 'mdeck/component'
949
+
950
+ export default function Counter() {
951
+ const [count, setCount] = useShared('count', 0)
952
+ return <button onClick={() => setCount(n => n + 1)}>{count}</button>
953
+ }
954
+ ```
955
+
956
+ - `useShared(name, initial)` returns the value and a function to set it, like
957
+ `useState`. `initial` stands in until a window sets one. Values must survive
958
+ JSON (numbers, text, lists, plain objects). The latest change wins.
959
+ - A window opened later, or reloaded, gets the current values from the others.
960
+ Nothing is saved: when every window of the talk is closed, the values are gone.
961
+ - `useView()` says which window the component is in: `presenter` (the
962
+ presenter view's slide), `audience`, `deck`, `follow` (a phone following the
963
+ talk), `preview` (the next-slide preview and the editor) or `reader`.
964
+ Previews, followers and the reader see shared values but do not change them.
965
+ - Choose names that belong to your component, such as `countdown` or
966
+ `quiz:round`: every component in the deck shares one set of names.
967
+
968
+ `mdeck/component` is the part of mdeck that components may rely on; it is
969
+ kept stable across versions. A component renders inside its slide. Anything
970
+ else it reaches, such as the page outside its slide, the `<deck-stage>`, mdeck's
971
+ events or the presenter view, is not part of it and may change without notice.
972
+
912
973
  ---
913
974
 
914
975
  ## Inline HTML
@@ -68,6 +68,8 @@ h1 { font-size: clamp(32px, 3vw, 46px); margin: 0 0 24px; max-width: 23ch; }
68
68
  .welcome h1 { font-size: clamp(40px, 4.5vw, 63px); line-height: 1.08; max-width: 14ch; letter-spacing: -.055em; }
69
69
  .welcome article > p:first-of-type { font-size: 20px; line-height: 1.55; color: var(--secondary); max-width: 53ch; }
70
70
  .welcome article > p:nth-of-type(3) > a { display: inline-block; background: var(--blue); color: white; text-decoration: none; padding: 10px 19px; border-radius: 5px; font-size: 15px; font-weight: 600; }
71
+ .welcome article > p:nth-of-type(3) { display: flex; flex-wrap: wrap; gap: 8px; }
72
+ .welcome article > p:nth-of-type(3) > a + a { background: none; color: var(--blue); box-shadow: inset 0 0 0 1.5px var(--blue); }
71
73
  .welcome article { max-width: 820px; }
72
74
  .welcome article > :not(.features) { max-width: 76ch; }
73
75
  .features { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 36px 32px; margin: 24px 0 32px; }
@@ -11,6 +11,7 @@ For how the commands, the views and the servers fit together, see [Views, comman
11
11
  | `mdeck skill --install claude` | Teach your AI assistant to write mdeck slides ([details](claude-skill.html)) |
12
12
  | `mdeck new` | Make a presentation with guided questions |
13
13
  | `mdeck run my-talk.md` | Open the launch page: present, edit, check and send from one place; slides reload when you save |
14
+ | `mdeck rehearse my-talk.md` | Rehearse the talk: each slide is timed, and the times can be saved into the deck ([details](presenting.html#rehearse)) |
14
15
  | `mdeck edit my-talk.md` | Edit slides, colors and themes in the browser; saves to the file |
15
16
  | `mdeck themes search`, `install <theme>`, `remove`, `update`, `list` | Themes: install more (each with its palette), remove the ones you do not use; see [Install, remove or share a theme](theme-repository.html) |
16
17
  | `mdeck palettes search`, `install <palette>`, … | The same for palettes |
@@ -32,7 +33,7 @@ For how the commands, the views and the servers fit together, see [Views, comman
32
33
  `mdeck run my-talk.md` opens a page on your own computer with everything for this talk. It is what the preview's plain address, such as `http://localhost:5173/`, shows; the slides themselves are at `?view=deck`.
33
34
 
34
35
  - **Preview:** a small live copy of the deck to flip through; click it to open the audience window at that slide.
35
- - **Present:** the presenter view, audience window and reader view, each in a new tab. The presenter view has notes, drawing controls, a timer and next-slide preview; switch to its slide-only layout for a single screen. The audience window shows slides without notes. Fullscreen is a control inside either view, not a separate view.
36
+ - **Present:** the presenter view, audience window and reader view, each in a new tab. The presenter view has notes, drawing controls, a timer and next-slide preview; **Rehearse** opens it timing each slide; switch to its slide-only layout for a single screen. The audience window shows slides without notes. Fullscreen is a control inside either view, not a separate view.
36
37
  - **Write and learn:** the visual editor, the theme editor (themes and palettes on a sample deck, see [Install, remove or share a theme](theme-repository.html)) and these guides. Each starts the first time you click it.
37
38
  - **Send:** buttons that make the `dist` folder, one file to send, or a PDF, next to your slide file, and show them in your file manager.
38
39
  - **Polls:** for a deck with polls: the server (built in, or the `server` setting and whether it answers), the join link and session code for phones, and for a server of your own the key that lets your browser move the phones along and reset polls (see below).
@@ -94,6 +95,7 @@ The design page shows themes and palettes on a sample deck with every kind of sl
94
95
  | `mdeck send my-talk.md` | One file for readers: the reader view, speaker notes removed, a PDF inside |
95
96
  | `mdeck send my-talk.md --notes` | The same, keeping the speaker notes |
96
97
  | `mdeck send my-talk.md --no-polls` | The same, leaving out the slides with polls and their join codes |
98
+ | `mdeck send my-talk.md --slide 12-30` | The same with only slides 12 to 30 and their drawings; also for `build` and `pdf` |
97
99
  | `mdeck send my-talk.md --no-pdf` | The same, without rendering the PDF |
98
100
  | `mdeck pdf my-talk.md -o talk.pdf` | Render the slides to a PDF file (`--no-polls` leaves out the slides with polls) |
99
101
  | `--no-drawings` | Leave out the drawings from `my-talk.drawings.json`, for `build`, `send` and `pdf` |
@@ -11,7 +11,7 @@ Press **D** in standalone slides or in the presenter view, or use the pen button
11
11
  | Pen | Thin to thick with the pencil's pressure. Kept. |
12
12
  | Highlighter | A wide, see-through stroke in its own colours, always below the pen's strokes. Kept. |
13
13
  | Select and move | Draw a loop around strokes, or tap one, to select it; a finger's tap on a stroke selects it with any tool. Drag inside the dashed box with the pen to move it; a straight line shows handles at its ends, which the pen moves. **Delete** (or the toolbar's bin) removes the selection. |
14
- | Laser pointer | A red dot with a white core and a short trail that disappears by itself, for pointing at something. With a pencil that can hover, the dot follows it without touching. Never kept. |
14
+ | Laser pointer | A red dot with a white core and a trail that stays as long as the pen or finger is down and disappears by itself once it is lifted, for pointing at something or circling it. With a pencil that can hover, the dot follows it without touching. Never kept. |
15
15
  | Eraser | Removes whole strokes you touch. |
16
16
 
17
17
  **Zoom**: two fingers zoom into the slide and move around it, one finger moves a zoomed slide, and Ctrl + scroll (a trackpad pinch) zooms on a laptop. Only the slide grows; the bars and the toolbar keep their size. The audience window shows the same part of the slide. **1:1** at the top left shows the whole slide again, as does the next slide. To zoom straight to a picture or a table with a number key, see [hotspots](presenting.html#zoom-in-on-part-of-a-slide).
@@ -0,0 +1,47 @@
1
+ # Install mdeck
2
+
3
+ Three commands in a terminal, a few minutes in all. mdeck is published on npm, the package registry for JavaScript tools, as [mdeck](https://www.npmjs.com/package/mdeck).
4
+
5
+ ## 1. Install Node.js
6
+
7
+ mdeck runs on [Node.js](https://nodejs.org) 22 or newer, which brings npm along. Check whether you have it:
8
+
9
+ ```sh
10
+ node --version
11
+ ```
12
+
13
+ A number of 22 or higher is enough. If the command is not found or the number is lower, install the LTS version from [nodejs.org](https://nodejs.org).
14
+
15
+ ## 2. Install mdeck
16
+
17
+ ```sh
18
+ npm install -g mdeck
19
+ ```
20
+
21
+ Check that it is ready:
22
+
23
+ ```sh
24
+ mdeck --help
25
+ ```
26
+
27
+ ## 3. Teach your AI assistant
28
+
29
+ ```sh
30
+ mdeck skill --install claude
31
+ ```
32
+
33
+ Write `codex`, `cursor`, `copilot` or `gemini` instead of `claude` for those assistants. [Work with an AI assistant](claude-skill.html) says more.
34
+
35
+ Then [make your first presentation](getting-started.html).
36
+
37
+ ## Update, check or remove
38
+
39
+ | To | Run |
40
+ |---|---|
41
+ | Update to the newest version | `npm install -g mdeck` |
42
+ | See which version you have | `npm list -g mdeck` |
43
+ | Remove mdeck | `npm uninstall -g mdeck` |
44
+
45
+ What each version brings is in the [changelog](https://github.com/tilman-schieber/mdeck/blob/main/CHANGELOG.md) and the [releases](https://github.com/tilman-schieber/mdeck/releases). After an update, run `mdeck skill --install claude` again, so your assistant knows the new features.
46
+
47
+ If `npm` or `mdeck` is not found, see [When something goes wrong](troubleshooting.html#the-command-is-not-recognized).
@@ -59,7 +59,7 @@ For a cropped picture, use `fit: cover`. You can add `position: "left center"` o
59
59
 
60
60
  ## Pictures that follow the theme
61
61
 
62
- An SVG drawing can take its colours from the theme, so it matches every theme, palette, and light or dark. Colour it with the palette's names instead of fixed colours, for example `fill: var(--accent, #1f3fd1)`; the colour after the comma is used wherever the picture is shown on its own. The names are `--bg`, `--surface`, `--ink`, `--ink-soft`, `--muted`, `--rule`, `--accent`, `--accent-2` and `--on-accent`.
62
+ An SVG drawing can take its colours from the theme, so it matches every theme, palette, and light or dark. Colour it with the palette's names instead of fixed colours, for example `fill: var(--accent, #1f3fd1)`; the colour after the comma is used wherever the picture is shown on its own. The names are `--bg`, `--surface`, `--ink`, `--ink-soft`, `--muted`, `--rule`, `--accent`, `--accent-2`, `--accent-3` and `--on-accent`.
63
63
 
64
64
  It works wherever a picture goes: in the slide text (`![…](./img/drawing.svg)`) or as the `image` of a layout. In a layout, add `fit: contain` so the whole drawing shows. The tour example's title picture, `examples/showcase/img/mdeck.svg`, works this way. An AI assistant can draw one for you:
65
65
 
@@ -68,6 +68,25 @@ Draw an SVG title picture for this talk that uses the palette's
68
68
  colours, with a transparent background, and put it on the title slide.
69
69
  ```
70
70
 
71
+ ### A drawing that builds up
72
+
73
+ Such a drawing is part of the slide, so its parts can appear one at a time, like the points of a list. Put each part in a group and number it with `data-step`: the parts appear in the order of their numbers, and parts with the same number appear together.
74
+
75
+ ```html
76
+ <g data-step="1">…the first box…</g>
77
+ <g data-step="1">…the second box…</g>
78
+ <g data-step="2">…the arrow between them…</g>
79
+ ```
80
+
81
+ The numbers decide the order, not where a part is in the file, so an arrow can be drawn under the boxes and still appear after them. With hotspots on (see [Zoom in on part of a slide](presenting.html#zoom-in-on-part-of-a-slide)), `data-hotspot` on a group gives it a key of its own. The same drawing can be on several slides; each copy keeps its arrowheads and gradients.
82
+
83
+ `mdeck check` looks at these drawings: it names colours that stay fixed in dark mode, palette names without a colour after the comma, and styles that would reach the rest of the slide. An assistant can do all of it for you:
84
+
85
+ ```prompt
86
+ Draw the three stages of the pipeline as an SVG in the palette's colours
87
+ that builds up one stage at a time, and make each stage a hotspot.
88
+ ```
89
+
71
90
  ## Add a video file
72
91
 
73
92
  Paste this line into a normal slide, or into one side of a split slide:
@@ -65,10 +65,45 @@ To let people answer a question on their phones, put a poll on a slide. See [Ask
65
65
  | 1–9 | Zoom in on a part of the slide, with hotspots on (see below); without them, go to slide 1–9 |
66
66
  | 0 or Escape | Show the whole slide again |
67
67
  | H | Turn hotspots on or off for this talk, in the presenter view |
68
+ | T | Start or pause the timer, in the presenter view |
69
+
70
+ To jump to a slide, tap or click the slide number in the presenter view (beside the arrows on an iPad, at the top of the speaker layout), type the number and press Enter, or Go on an iPad's keyboard. Escape keeps the current slide.
68
71
 
69
72
  Click the slide area if your keys are not controlling it. Keys behave normally while you are typing in a text field.
70
73
 
71
- The timer is for your own reference; you can start, pause, and reset it in the presenter view.
74
+ The timer is for your own reference; you can start, pause (**T**), and reset it in the presenter view. It keeps running through a reload of the page.
75
+
76
+ ## Time your talk
77
+
78
+ Give a slide the time you want to spend on it with `time:` in its settings, and the whole talk a length with `time:` in the deck's settings:
79
+
80
+ ```markdown
81
+ ---
82
+ time: 20m
83
+ ---
84
+
85
+ ---
86
+ :::meta
87
+ time: 2m
88
+ :::
89
+ # The results
90
+ ```
91
+
92
+ Write times as `90s`, `2m`, `1m30s` or `1.5m`. Slides without a time share what the deck's time leaves over; without a deck time, they get none.
93
+
94
+ Once the deck has times, the presenter view shows under the timer how much time is left on the slide (amber in its last 15 seconds, red once it is over), the length of the talk, and whether you are ahead of or behind your plan. In the slide-only layout the time left on the slide sits beside the timer.
95
+
96
+ ### Rehearse
97
+
98
+ You do not have to guess the times. Rehearse the talk and mdeck measures them:
99
+
100
+ ```bash
101
+ mdeck rehearse my-talk.md
102
+ ```
103
+
104
+ This opens the presenter view rehearsing: the timer starts, and every second on a slide counts towards it, including when you come back to it. **Rehearse** in the presenter view, and the tile on the launch page, start a rehearsal too. Press **Finish**, or go on past the last slide, and a table shows for each slide the time it has, the time you spent and the new time, rounded to 15 seconds. Change a new time in 15-second steps with **−** and **+** (or **↑** and **↓** on its row), put back the time the slide had, or take the slide's time out. **Save to deck** writes the new times into the slides' settings, so you can see them in the file and change them like any other setting. The open windows do not reload, and the deck is copied to `.mdeck-backups/` first.
105
+
106
+ Saving needs `mdeck run` or `mdeck rehearse`. A deck you built can still rehearse; **Copy** gives you the times to paste in yourself.
72
107
 
73
108
  ## Zoom in on part of a slide
74
109
 
@@ -96,6 +131,8 @@ A slide can have its own setting in its frontmatter, such as `hotspots: false` f
96
131
  The rate is <span data-hotspot>**2.4 %** a year</span>, for now.
97
132
  ```
98
133
 
134
+ In a drawing that takes its colours from the theme, `data-hotspot` on a group makes that part of the drawing a hotspot.
135
+
99
136
  Parts that nearly fill the slide, or its whole width, get no key, since there is nothing to zoom; what is inside them may. A part inside another one shares its key: a column with a formula and a tip in it is one part. The keys follow reading order, up to nine on a slide. In the editor, the deck's settings and each slide's details have a **Hotspots** choice too. **H**, or the button beside **Draw**, turns hotspots on or off for the rest of the talk without changing the deck; a slide set to `false` stays without them.
100
137
 
101
138
  ## One talk in several languages
@@ -125,7 +162,7 @@ Wrap a list in a steps block:
125
162
  :::
126
163
  ```
127
164
 
128
- Each press of the next key reveals one point. Once all points are visible, the next press moves to the following slide. Printed slides show all the points.
165
+ Each press of the next key reveals one point. Once all points are visible, the next press moves to the following slide. Printed slides show all the points. A drawing can build up the same way; see [A drawing that builds up](media.html#a-drawing-that-builds-up).
129
166
 
130
167
  ## Before the talk
131
168
 
@@ -21,6 +21,7 @@ Send `my-talk.html` by email. It opens in a **reader view**: an outline of all s
21
21
  - Drawings from `my-talk.drawings.json` are part of every build and PDF; `--no-drawings` leaves them out. Readers can hide them with the **Drawings** button in the reader view. See [Draw on your slides](drawing.html).
22
22
  - Your speaker notes are removed. Add `--notes` to keep them in the file, for example when you also present from the same file. Readers only see notes if you put `reader:` with `notes: true` in the settings at the top of your slide file.
23
23
  - Slides with a poll, question, word cloud or scale stay as a record of the talk: the question and its options, marked as answered live. Add `--no-polls` to leave them out of the file and its PDF, together with slides showing the join code (`<qrcode join />`).
24
+ - `--slide 12-30` sends only some slides, for example the part of a deck shown in today's lecture. The numbers are the slides' places in the deck, as `mdeck check --render` and `mdeck snapshot` count them, and may be listed, `3,5-7`. Drawings stay on their slides, and a `<style>` written on a slide that is left out still applies. A deck `time:` shrinks to what the kept slides were planned to take.
24
25
  - The PDF is made while sending, using Chrome or Chromium on your computer. If neither is found, the button offers the browser's own "Save as PDF" dialog instead. Set `MDECK_CHROME` to the browser's path if it is installed somewhere unusual. `--no-pdf` skips it.
25
26
  - `-o` chooses the name: `mdeck send my-talk.md -o handout.html`.
26
27
  - The file keeps your theme and colours; readers can only switch between light and dark. To keep that fixed too, put `reader:` with `themes: false` in the settings at the top of your slide file.
@@ -4,7 +4,7 @@ Bring what you already have: old PowerPoint slides, a PDF, a Word document, a pa
4
4
 
5
5
  The content stays yours. The assistant works from your material, not from its own idea of the topic: it chooses layouts, tidies wording, moves detail into speaker notes and checks the file. You do not need to know how to program. The slides are a plain text file, so you can read every word, change any of it yourself, or ask for something different.
6
6
 
7
- [Make your first presentation](getting-started.html)
7
+ [Make your first presentation](getting-started.html) [Install mdeck](install.html)
8
8
 
9
9
  ## What you can do with it
10
10
 
@@ -32,6 +32,26 @@ Polls, scales, word clouds, open questions and numbers to guess. People scan the
32
32
 
33
33
  <section>
34
34
 
35
+ [![The projector zoomed in on a table, and in front of it the presenter view showing the same slide with numbered keys on its code, table and formula](images/features/hotspots.webp)](images/features/hotspots.webp)
36
+
37
+ ### Zoom into a chart, a table or a line of code
38
+
39
+ Turn on hotspots, and the presenter view puts a number on each picture, table, formula and code block. Press it, or tap it on an iPad, and the slide glides in until that part fills the projector; press it again to see the whole slide. Phones following the talk zoom along, and the audience never sees the numbers. [Zoom in on part of a slide](presenting.html#zoom-in-on-part-of-a-slide)
40
+
41
+ </section>
42
+
43
+ <section>
44
+
45
+ [![The same slide with a Python example in English, German, Hindi and Farsi, the Farsi one running right to left](images/features/languages.webp)](images/features/languages.webp)
46
+
47
+ ### Give the talk in the room's language
48
+
49
+ Keep the talk once per language, `talk.en.md` beside `talk.de.md`, and press **L** to switch in the middle of it: the slides, your notes and every screen change at once, and you stay on the same slide and step. Farsi, Arabic and Hebrew run right to left, with code and formulas left to right. [One talk in several languages](presenting.html#one-talk-in-several-languages)
50
+
51
+ </section>
52
+
53
+ <section>
54
+
35
55
  [![A slide with author–year citations and the full references at its foot, next to a slide that lists all references](images/features/citations.webp)](images/features/citations.webp)
36
56
 
37
57
  ### Cite your sources properly
@@ -1,5 +1,6 @@
1
1
  export const pages = [
2
2
  { slug: 'index', title: 'Welcome to mdeck', group: 'Start here', file: 'welcome.md', description: 'Turn your existing slides, documents and notes into a deck with an AI assistant, then present and share it.', preview: 'first-talk' },
3
+ { slug: 'install', title: 'Install mdeck', group: 'Start here', file: 'install.md', description: 'Install Node.js and mdeck from npm, teach your AI assistant, and keep mdeck up to date.' },
3
4
  { slug: 'getting-started', title: 'Make your first presentation', group: 'Start here', file: 'getting-started.md', description: 'Set up mdeck and your AI assistant, hand over your material, and open the deck it makes.' },
4
5
  { slug: 'claude-skill', title: 'Work with an AI assistant', group: 'Start here', source: '../reference/claude-skill.md', description: 'Set up Claude Code, Codex, Cursor, Copilot or Gemini, turn PowerPoint, PDF, Word or notes into a deck, and change it by asking.' },
5
6
  { slug: 'writing', title: 'Read and adjust your slides', group: 'Make your presentation', file: 'writing.md', description: 'The simple marks in a slide file, so you can read what your assistant wrote and fix small things.' },
@@ -25,7 +25,7 @@ props:
25
25
  ## Single HTML file
26
26
 
27
27
  :::tip
28
- Useful when transferring one file is operationally important.
28
+ Handy when one file is easier to pass on than a folder.
29
29
  :::
30
30
 
31
31
  - All local assets embedded
@@ -33,7 +33,7 @@ Useful when transferring one file is operationally important.
33
33
  :::
34
34
 
35
35
  :::notes
36
- This layout is loaded from extensions/comparison beside this deck.
36
+ This layout is not built into mdeck: it comes from `extensions/comparison/` beside this deck. `ratio` sets the widths of the two sides, `emphasis` which one stands out.
37
37
  :::
38
38
 
39
39
  ---
@@ -41,20 +41,32 @@ This layout is loaded from extensions/comparison beside this deck.
41
41
  layout: split
42
42
  id: built-in-regions
43
43
  props:
44
- ratio: [1, 2]
44
+ ratio: [1, 1]
45
45
  :::
46
- # Built-in layouts use the same region model
46
+ # A layout of your own
47
47
 
48
48
  :::slot left
49
- ```js
50
- const template = 'comparison'
49
+ ```markdown
50
+ :::meta
51
+ layout: comparison
52
+ props:
53
+ emphasis: right
54
+ :::
55
+ # Deployment options
56
+ :::slot left
57
+ ## Directory bundle
58
+ :::
51
59
  ```
52
60
  :::
53
61
 
54
62
  :::slot right
55
63
  :::steps
56
- - Define a manifest.
57
- - Write a Preact layout.
58
- - Use it from Markdown.
64
+ - `extension.toml` names the layout, its areas and its settings.
65
+ - `layout.jsx` places the areas, `styles.css` styles them.
66
+ - A slide chooses it with `layout: comparison`.
59
67
  :::
60
68
  :::
69
+
70
+ :::notes
71
+ All three files are in `extensions/comparison/`. `mdeck list layouts` shows the deck's own layouts beside mdeck's, and `mdeck starter comparison` prints a slide to start from. To use the layout in other decks, install it once for all of them; the guide "Reusable layouts" shows how.
72
+ :::
@@ -0,0 +1,21 @@
1
+ @article{roediger2006,
2
+ author = {Roediger, Henry L. and Karpicke, Jeffrey D.},
3
+ title = {Test-Enhanced Learning: Taking Memory Tests Improves Long-Term Retention},
4
+ journal = {Psychological Science},
5
+ year = {2006},
6
+ volume = {17},
7
+ number = {3},
8
+ pages = {249--255},
9
+ doi = {10.1111/j.1467-9280.2006.01693.x}
10
+ }
11
+
12
+ @article{freeman2014,
13
+ author = {Freeman, Scott and Eddy, Sarah L. and McDonough, Miles and Smith, Michelle K. and Okoroafor, Nnadozie and Jordt, Hannah and Wenderoth, Mary Pat},
14
+ title = {Active Learning Increases Student Performance in Science, Engineering, and Mathematics},
15
+ journal = {Proceedings of the National Academy of Sciences},
16
+ year = {2014},
17
+ volume = {111},
18
+ number = {23},
19
+ pages = {8410--8415},
20
+ doi = {10.1073/pnas.1319030111}
21
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 1,
3
+ "width": 1920,
4
+ "height": 1080,
5
+ "slides": {
6
+ "draw-on-any-slide": [
7
+ {"id":"tour:underline","tool":"pen","color":"#e11d48","size":7,"points":[[1253,489,0.45],[1267,491,0.48],[1280,493,0.52],[1293,494,0.55],[1307,495,0.58],[1320,496,0.61],[1333,496,0.64],[1347,495,0.66],[1360,494,0.68],[1373,492,0.7],[1387,491,0.72],[1400,489,0.73],[1413,487,0.74],[1427,486,0.75],[1440,485,0.75],[1453,485,0.75],[1467,486,0.74],[1480,487,0.73],[1493,488,0.72],[1507,490,0.71],[1520,492,0.69],[1533,494,0.67],[1547,496,0.64],[1560,497,0.62],[1573,498,0.59],[1587,499,0.56],[1600,499,0.53],[1613,498,0.49],[1627,497,0.46],[1640,495,0.43],[1653,494,0.39],[1667,492,0.36],[1680,491,0.33],[1693,489,0.3],[1707,489,0.27],[1720,488,0.25],[1733,489,0.22],[1747,489,0.2],[1760,491,0.19],[1773,493,0.17],[1787,495,0.16]]},
8
+ {"id":"tour:circle","tool":"pen","color":"#e11d48","size":6,"points":[[1690,520,0.5],[1694,520,0.54],[1699,520,0.57],[1703,521,0.6],[1707,523,0.64],[1711,526,0.66],[1714,529,0.69],[1716,533,0.71],[1718,537,0.73],[1719,541,0.74],[1720,545,0.75],[1719,549,0.75],[1718,553,0.75],[1716,557,0.74],[1714,561,0.73],[1711,563,0.71],[1708,566,0.69],[1704,568,0.66],[1701,570,0.63],[1697,571,0.6],[1693,572,0.57],[1689,572,0.54],[1685,572,0.5],[1681,572,0.46],[1677,570,0.43],[1673,569,0.4],[1670,567,0.36],[1667,564,0.34],[1664,560,0.31],[1662,557,0.29],[1660,552,0.27],[1660,548,0.26],[1660,544,0.25],[1661,539,0.25],[1663,535,0.25],[1665,532,0.26],[1668,529,0.27],[1671,526,0.29],[1675,524,0.31],[1679,523,0.34],[1683,522,0.37],[1687,522,0.4],[1691,522,0.43],[1695,522,0.47],[1699,524,0.5],[1703,525,0.54]]}
9
+ ]
10
+ }
11
+ }