Presentation Context
The slides context is used when creating presentations. Content in this context typically appears in reveal.js slides or PowerPoint presentations.
Key Macros
Slide Creation
\newslide{title}
Creates a new slide
Args:
title: Title of the slide
\newslide{title}{attrs}
Creates a new slide with Reveal section attributes (HTML slides).
Args:
title: Title of the slide
attrs: Space-separated attributes, e.g. data-background="…" or .scrollable
\section{title}
Creates a section-divider slide (title only).
Args:
title: Section heading
\section{title}{attrs}
Section-divider slide with Reveal attributes (HTML slides).
Args:
title: Section heading
attrs: Space-separated attributes, e.g. data-background-color="…" or data-state="…"
If attrs is empty and sectionSlideBackground is defined, that default is used
(Trent decks set data-state="trent-section" for a CSS gradient backdrop).
JavaScript: content scripts vs Reveal setup
Two separate concerns (do not mix them):
Track |
Role |
Where it runs |
Authoring |
|---|---|---|---|
A — Content scripts |
Interactive widgets in figures / body |
All HTML outputs (slides, notes, notebooks) |
|
B — Reveal setup & backgrounds |
Deck chrome and full-bleed backdrops |
Reveal HTML slides only |
|
Rule of thumb: if the interaction still makes sense without Reveal, it is Track A. If it is “behind the deck” or “this slide’s backdrop,” it is Track B.
Track A — \includescript
\includescript{ballworld/ballworld.js}
Emits <script src="…/scriptsDir/…"> in HTML formats; no-op in TeX/PPTX. Prefer this over hand-written <script> tags in snippets. GPP \ifndef once-guards only accept [A-Za-z0-9_], so wrap loaders in alphanumeric defines (e.g. \ifndef{ballworldJs}), not path-shaped names.
Track B — slide_setup and backgrounds
Optional frontmatter (filename under lamd includes/):
slide_setup: slide-setup-ambient.html
When set, the slides makefile passes --include-after-body so the fragment runs after Reveal.initialize (correct place for Reveal API / ambient animation). Leave unset for most decks — default slidesheader stays for MathJax / figure-animate only.
Per-slide backgrounds use Reveal data-background* on the section:
\newslide{Title}{data-background-image="diagrams/bg.svg"}
\includeplotly{plots/myplot}{100%}{100%}
Clash policy: a slide with its own data-background* wins; deck ambient from slide_setup should yield/pause on that slide. Reference: lamd/includes/slide-setup-ambient.html.
Pitfall: YAML frontmatter background: is a layout numbering field, not a visual slide background.
Typography (font size)
Deck-wide and per-slide text size for Reveal HTML (CIP-0014). Notes / notebooks / PPTX ignore these settings in v1.
Deck-wide (parallel to talktheme):
talkfontsize: small # medium (default) | smaller/xs | small/sm | large/lg | larger/xl
Unset defaults to medium (no change from Reveal’s usual base). Lamd always attaches package CSS (slide-fonts.css + a scale override) alongside talkcss.
Per-slide (parallel to .scrollable), on \newslide / \section attrs:
\newslide{ELBO derivation}{.font-sm}
\newslide{Key takeaway}{.font-lg}
\newslide{References}{.scrollable .font-sm}
\section{Appendix}{.font-xs}
\newslide{Sparse}{\slidefont{lg}}
Class / token |
Scale vs current deck base |
|---|---|
|
0.70 |
|
0.85 |
|
1.00 |
|
1.15 |
|
1.30 |
Precedence: per-slide .font-* overrides deck talkfontsize; otherwise the deck token applies; otherwise medium. Use one size class per slide. \subsection does not take attrs in v1 — put size on \newslide or \section.
Demo: demos/cip0014-slide-fonts.html.
Content Control
\slides{content}
Specifies content that only appears in slides
Args:
content: Slide-specific content, often bullet points
Animation Control
\fragment{text}{type}
Creates animated elements in reveal.js
Args:
text: Content to animate
type: Animation type (e.g., 'fade-in', 'grow')
Presenter Notes
\speakernotes{text}
Adds notes visible only to the presenter
Args:
text: Notes for the presenter
Frame Animations (\startanimation, \newframe, \endanimation)
The frame animation system creates multi-step figure sequences in HTML slides: a range slider and previous/next buttons let the audience step through frames. Other output formats show all frames without interactive controls.
This is distinct from reveal.js \fragment{} animations (bullet-by-bullet reveal on a
single slide).
Macro reference
\startanimation{group}{start}{finish}{name}
Opens an animation sequence and renders interactive controls (HTML only).
Args:
group: Unique identifier shared by all frames in this sequence. Must match
the `name` argument of every `\newframe` in the sequence — JavaScript
uses this value as the CSS class to find frames.
start: Minimum slider value (typically 0 or 1).
finish: Maximum slider value. Should equal start + (number of frames − 1)
when using consecutive numbering.
name: Human-readable title shown beside the controls and used as the
container's ARIA label. May be empty if you use the three-argument form
via `\startslides{group}{start}{finish}`.
\newframe{contents}{name}{style}
Adds one frame to the current animation sequence.
Args:
contents: Frame content (diagrams, text, etc.).
name: CSS class for this frame — must equal `group` from `\startanimation`.
style: Optional inline CSS appended to the frame div (e.g. `margin-top:1em`).
\endanimation
Closes the animation container opened by `\startanimation`.
Worked example
The pattern below matches real talk content: eight frames numbered 0–7, all sharing the
same group class:
\startanimation{correlated_velocities}{0}{7}{Correlated velocity samples}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities000}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities001}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities002}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities003}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities004}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities005}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities006}{\width}}{correlated_velocities}{}
\newframe{\includediagram{\diagramsDir/ml/correlated_velocities007}{\width}}{correlated_velocities}{}
\endanimation
JavaScript dependency
HTML slide builds load figure-animate.js from the slides header template
(lamd/includes/slides-header.html):
<script src="https://inverseprobability.com/assets/js/figure-animate.js"></script>
<script>
/* lamdFrameIndex, lamdSetDivs, lamdPlusDivs — see slides-header.html */
</script>
Reference implementation: figure-animate.js
The library exposes showDivs(n, group) with 1-based frame indices. LaMD slide
content typically uses 0-based slider ranges (\startanimation{group}{0}{4} for five
frames). The header shim maps slider values to frame indices:
frameIndex = sliderValue - min + 1
Function |
Called from |
Purpose |
|---|---|---|
|
Init script |
Show frame n (1-based), hide others with class |
|
Range slider |
Read slider value, map to 1-based index, call |
|
Prev/next buttons |
Step slider within min/max, then call |
Initialization runs on DOMContentLoaded and calls showDivs(1, group) so the first
frame matches the slider at its minimum value.
If the script fails to load, lamd degrades gracefully: controls are hidden, the first
frame is shown, and a [lamd] figure-animate.js not loaded warning appears in the browser
console.
HTML output structure
Each animation sequence renders a container with stable attributes for styling, testing, and scripting:
Attribute / element |
Purpose |
|---|---|
|
Unique container id |
|
Shared class for all animation containers |
|
Programmatic lookup |
|
Landmark for assistive technology |
|
Wrapper around slider and buttons |
|
Per-frame identification |
Format-specific behaviour
Format |
|
|
|
|---|---|---|---|
HTML slides |
Full interactive controls + JS init |
Frame div with show/hide class |
Closes container |
Notes |
Prints |
Emits frame content |
No-op |
IPynb |
No-op (HTML macros included, then overridden) |
Emits frame content |
No-op |
TeX / PDF slides |
No-op |
Emits frame content |
No-op |
PPTX |
No-op |
Emits frame content |
No-op |
In non-HTML formats every frame appears in document order. Authors should write frames so they read sensibly when shown sequentially (e.g. with diagram captions or brief labels).
Accessibility
HTML animations follow WCAG 2.1 guidance for interactive controls:
Container:
role="region"witharia-labelset from the\startanimationtitle.Slider:
aria-label,aria-valuemin,aria-valuemax, andaria-valuenow.Buttons:
aria-label="Previous frame"/"Next frame".Frames:
role="img"witharia-labelfrom the framenameparameter.
Keyboard access uses native control behaviour: Tab to reach the slider and buttons; arrow
keys adjust the range input when it has focus. Provide a descriptive \startanimation
title so screen-reader users understand the sequence purpose.
Because every frame currently shares the same name class (and thus the same
aria-label), put the meaningful description in the visible frame content where possible.
Troubleshooting
Symptom |
Likely cause |
What to check |
|---|---|---|
Controls appear but frames do not change |
|
Use the same identifier on every frame |
Slider at left/right shows wrong frame |
0-based slider passed directly to 1-based |
Rebuild with current lamd (uses |
|
Script blocked or offline build |
Confirm |
Only first frame visible, no controls |
Expected degradation without JS |
Enable JavaScript, or rely on noscript/fallback (first frame only) |
Empty animation area |
No |
Add at least one frame between start and end |
Top slider stops before last frame (nested animations) |
|
Set |
Frames flash all at once briefly |
Race before |
Normal; init hides non-active frames once JS runs |
Additional Display Controls
\slidesmall{block}
Makes content smaller in slides only
Args:
block: Content to reduce in size
\slidenotes{slidetext}{notetext}
Different content for slides vs notes
Args:
slidetext: Content for slides
notetext: Content for notes
Example Usage
\ifndef{machineLearningIntro}
\define{machineLearningIntro}
\newslide{Introduction to Machine Learning}
\slides{
* Supervised Learning
* Unsupervised Learning
* Reinforcement Learning
}
\fragment{Deep Learning}{fade-in}
\speakernotes{
Remember to mention real-world applications for each type
}
\endif
Output Formats
reveal.js presentations (HTML)
PowerPoint (PPTX)
Tips
Keep slide content concise
Use fragments for building complex ideas
Include speaker notes for important points
Consider both HTML and PPTX output when formatting
For multi-frame diagrams, use
\startanimation/\newframe/\endanimationand repeat the samegroupclass on every frame (see Frame Animations above)Put figure widgets behind
\includescript; put Reveal chrome / ambient animation inslide_setup(see JavaScript tracks above) — do not put deck setup inslidesheader
Colored math in PPTX
PowerPoint output converts display math through pandoc’s TeX→OMML converter. That path
does not support LaTeX \color{...}{...} inside $$...$$ blocks. If color commands
reach pandoc unchanged, the build emits a warning such as:
[WARNING] Could not convert TeX math '... {\color{red}{w_0}} ...', rendering as TeX
and the equation may not render correctly in PowerPoint.
For PPTX builds, talk-macros-pptx.gpp therefore no-ops color at the gpp stage:
\color{name}{text}→text\colorred{...},\colorblue{...}, and the other\color*wrapper macros → content only
Colored math is preserved in HTML slides (MathJax), PDF/LaTeX, and notes. Authors who
need color emphasis in PowerPoint should rely on diagram colors or surrounding slide
text rather than math-mode \color.
The same no-op pattern applies when blackAndWhite is set in color-scheme.gpp for
other formats; PPTX always strips math color regardless of that flag.