65 Slides
This chapter documents the public slide modules. It describes implemented operations, not proposed syntax. For a first lesson, see Make a slide and give it time. For short examples, see Slide recipes.
Unless stated otherwise, lengths are world units and durations are seconds. Numbers used for positions and times must be finite. IDs are nonempty interned symbols. Descriptions are immutable; preparation and rendering are explicit. Private struct fields and wire-format records are not public constructors.
65.1 Slide descriptions and content
syntax
(slide option ... [slot-name slot-option ... content] ...)
procedure
(make-slide [ #:id id #:layout chosen-layout #:slots slots #:theme theme #:notes notes]) → slide? id : symbol? = 'slide chosen-layout : (or/c symbol? layout?) = 'blank slots : (or/c hash? list?) = (hash) theme : (or/c #f slide-theme?) = #f notes : string? = ""
procedure
(slot-content content [ #:key key #:align align #:valign valign #:fit fit]) → any/c content : any/c key : (or/c #f symbol?) = #f align : (or/c #f 'left 'center 'right) = #f valign : (or/c #f 'top 'center 'bottom) = #f fit : (or/c #f 'contain 'cover 'natural) = #f
procedure
(paragraph-content text [ #:role role #:align align]) → content? text : (or/c string? text-content? tex-span?) role : (or/c #f symbol?) = #f align : (or/c #f 'left 'center 'right) = #f
syntax
(bullets option ... [item-name content] ...)
procedure
(make-bullets entries [#:ordered? ordered?]) → content?
entries : list? ordered? : boolean? = #f
65.2 Inline TeX text content
| (require animate/text-content) | package: animate |
The normal slide text surfaces accept mixed ordinary prose and TeX mathematics. This module also provides explicit immutable content values for programmatic authoring. It is pure: parsing a string does not load a Pict renderer, invoke TeX, or create a file.
In an ordinary slot string, $...$ and \(...\) create inline mathematics. $$...$$ and \[...\] create display mathematics on a line of their own. Write \$ for a literal dollar sign. A bare or mismatched delimiter, nested delimiters, and empty mathematics are errors; use literal-text for code, currency, or other content that must remain literal. TeX comments inside a mathematical fragment are respected while the closing delimiter is found.
Racket and markup escaping are separate. For example, "As $h\\to0$" supplies one runtime TeX backslash, while "Price: \\$5; position: $x_0$" keeps the price literal and typesets the position. Formula source is trusted TeX input; the native preparation adapter invokes the configured TeX backend and is not a sandbox.
procedure
(literal-text source [#:plain plain]) → text-content?
source : string? plain : (or/c #f string?) = #f
procedure
(inline-text [#:plain plain] piece ...) → text-content?
plain : (or/c #f string?) = #f piece : (or/c string? tex-span? text-content?)
procedure
(text-content? value) → boolean?
value : any/c
procedure
(tex-span-source value) → string?
value : tex-span?
procedure
(tex-span-plain value) → (or/c #f string?)
value : tex-span?
procedure
(parse-inline-text source) → text-content?
source : string?
procedure
(normalize-text-content value) → text-content?
value : (or/c string? tex-span? text-content?)
procedure
(text-content-runs value) → list?
value : text-content?
procedure
(text-content-source value) → (or/c #f string?)
value : text-content?
procedure
(text-content->plain value) → string?
value : text-content?
procedure
(text-run-kind run) → symbol?
run : text-run?
procedure
(text-run-content run) → string?
run : text-run?
procedure
(text-run-plain run) → string?
run : text-run?
procedure
run : text-run?
procedure
run : text-run?
procedure
(exn:fail:inline-tex? value) → boolean?
value : any/c
procedure
(exn:fail:inline-tex-code value) → symbol?
value : exn:fail:inline-tex?
procedure
(exn:fail:inline-tex-start value) → exact-nonnegative-integer?
value : exn:fail:inline-tex?
procedure
(exn:fail:inline-tex-end value) → exact-nonnegative-integer?
value : exn:fail:inline-tex?
Mixed text is measured and typeset only by prepare-slide! or prepare-storyboard!. Calling a conversion that has not prepared TeX-bearing text reports 'preparation-required. Prepared prose and formula runs share line baselines; a fraction or radical can increase line height, but cannot be split or silently scaled to fit. An atom wider than its line is a measured overflow error. Theme role, foreground, width, alignment, and line spacing are part of preparation, so later reveal, replacement, and Scene sampling replay fixed geometry without TeX calls or reflow. Raw draw-text calls, speaker notes, and SRT/WebVTT text remain literal.
65.2.1 Pict and image content
procedure
(pict-content picture-or-factory [#:fit fit]) → content?
picture-or-factory : any/c fit : (or/c 'contain 'cover 'natural) = 'contain
syntax
(image-content path option ...)
65.3 Themes and formats
procedure
(slide-format #:id id #:width width #:height height) → slide-format? id : symbol? width : real? height : real?
value
value
value
value
procedure
(slide-theme #:id id [ #:extends parent #:colors colors #:typography typography #:spacing spacing #:decorations decorations]) → slide-theme? id : symbol? parent : (or/c #f slide-theme?) = #f colors : (or/c #f color-theme?) = #f typography : (or/c #f typography-theme?) = #f spacing : hash? = (hash) decorations : hash? = (hash)
value
value
procedure
(theme-spacing theme key-or-number) → real?
theme : slide-theme? key-or-number : (or/c symbol? real?)
procedure
(role-style theme role) → text-style?
theme : slide-theme? role : symbol?
Default spacing includes safe-x = 0.65, safe-y = 0.50, section-gap = 0.35, column-gap = 0.60, bullet-gap = 0.23, paragraph-gap = 0.25, footer-height = 0.35, subtitle-height = 0.85, title-band = 1.20, caption-band = 0.85, and math-minimum-scale = 0.70. Band tokens do not force built-in text to a fixed height; text is measured. Custom nonnegative numeric spacing tokens are allowed. The minimum math scale must lie in [0,1].
Decoration keys are title-rule? and footer-rule?, both false by default. Other decoration keys are errors. The slide lecture typography differs from the core native typography theme; use its actual roles rather than copying a native font-size table.
65.4 Layouts and regions
procedure
(layout-names) → list?
procedure
(layout-ref name-or-layout) → layout?
name-or-layout : (or/c symbol? layout?)
Layout |
| Required |
| Optional |
title |
| title |
| subtitle |
section |
| title |
| subtitle |
title+body |
| title, body |
| none |
title+two-column |
| title, left, right |
| none |
title+figure |
| title, figure |
| body |
figure+caption |
| figure |
| caption |
figure-full |
| figure |
| none |
equation-focus |
| equation |
| annotation |
equation+explanation |
| equation, body |
| title |
theorem |
| title, statement |
| body |
quote |
| quote |
| attribution |
blank |
| none |
| content |
All built-ins also permit a footer. Hidden content retains its region. An omitted body in title+figure releases room to the figure. Portrait two-column text stacks at natural heights with a section gap. equation-focus groups its equation and annotation into one centered block.
procedure
(slot-spec name [ #:required? required? #:role role]) → slot-spec? name : symbol? required? : boolean? = #f role : symbol? = 'body
procedure
(layout #:id id #:slots slots #:arrange wide-tree [ #:standard standard-tree #:portrait portrait-tree #:fallback fallback]) → layout? id : symbol? slots : (listof slot-spec?) wide-tree : any/c standard-tree : any/c = #f portrait-tree : any/c = #f fallback : (or/c #f 'wide) = #f
procedure
(region name [ #:basis basis #:grow grow #:align align #:valign valign #:padding padding #:min minimum #:max maximum]) → any/c name : symbol? basis : (or/c real? 'content) = 0 grow : real? = 0 align : (or/c 'left 'center 'right) = 'left valign : (or/c 'top 'center 'bottom) = 'top padding : real? = 0 minimum : real? = 0 maximum : real? = +inf.0
procedure
(hbox [ #:basis basis #:grow grow #:gap gap #:padding padding #:min minimum #:max maximum] child ...) → any/c basis : (or/c real? 'content) = 0 grow : real? = 0 gap : (or/c real? symbol?) = 'column-gap padding : real? = 0 minimum : real? = 0 maximum : real? = +inf.0 child : any/c
procedure
(vbox [ #:basis basis #:grow grow #:gap gap #:padding padding #:min minimum #:max maximum] child ...) → any/c basis : (or/c real? 'content) = 0 grow : real? = 0 gap : (or/c real? symbol?) = 'section-gap padding : real? = 0 minimum : real? = 0 maximum : real? = +inf.0 child : any/c
65.5 Clips, beats, and narration
procedure
(build-slide slide [ #:initial initial #:poster poster #:motion motion] beat ...) → slide-clip? slide : slide? initial : any/c = 'visible poster : any/c = 'end motion : (or/c #f 'normal 'reduced) = #f beat : beat?
procedure
(hold-slide slide #:duration duration) → slide-clip?
slide : slide? duration : real?
procedure
(beat name [ #:duration duration #:narration voice #:tail-hold tail-hold] action ...) → beat? name : symbol? duration : (or/c #f real?) = #f voice : (or/c #f narration?) = #f tail-hold : real? = 0 action : slide-action?
A clip poster can be 'start, 'end, a nonnegative time, or a named beat boundary such as '(explain end). Visibility changes persist; emphasis returns to the base scale. Overlapping writes to the same property, including conflicting parent/child visibility, are errors.
syntax
(narration text option ...)
procedure
(make-narration text [ #:audio audio #:draft-duration draft-duration #:at at #:source-start source-start #:duration duration #:captions captions #:asset-base asset-base]) → narration? text : string? audio : (or/c #f path-string?) = #f draft-duration : (or/c #f real?) = #f at : real? = 0 source-start : real? = 0 duration : (or/c #f real?) = #f captions : any/c = #f asset-base : (or/c #f path-string?) = #f
Captions are an ordered, nonoverlapping list of (list start end text) relative to the selected recording interval. False derives captions from the text; an empty list suppresses them. Captions must fit their interval. Relative paths used by the procedure need an explicit base.
65.6 Slot actions
Selectors are a slot symbol or a nonempty symbol path, such as '(body check). They are resolved against the prepared content. Times and durations below are finite and nonnegative.
procedure
(reveal-slot selector [ #:at at #:duration duration #:effect effect]) → slide-action? selector : any/c at : real? = 0 duration : real? = 0.4 effect : (or/c 'fade 'instant) = 'fade
procedure
(conceal-slot selector [ #:at at #:duration duration #:effect effect]) → slide-action? selector : any/c at : real? = 0 duration : real? = 0.4 effect : (or/c 'fade 'instant) = 'fade
procedure
(emphasize-slot selector [ #:at at #:duration duration #:scale scale]) → slide-action? selector : any/c at : real? = 0 duration : real? = 0.8 scale : real? = 1.08
procedure
(replace-content slot content [ #:at at #:duration duration #:effect effect]) → slide-action? slot : any/c content : any/c at : real? = 0 duration : real? = 0.4 effect : (or/c 'crossfade 'instant) = 'crossfade
procedure
(play-content slot [ #:at at #:from from #:to to #:duration duration #:retime retime]) → slide-action? slot : any/c at : real? = 0 from : any/c = #f to : any/c = 'end duration : (or/c #f real?) = #f retime : (or/c #f 'stretch) = #f
65.7 Storyboards and transitions
procedure
(storyboard [ #:id id #:theme theme #:format format #:motion motion #:subtitles? subtitles?] entry ...) → storyboard? id : symbol? = 'storyboard theme : slide-theme? = lecture-light format : slide-format? = widescreen motion : (or/c 'normal 'reduced) = 'normal subtitles? : boolean? = #t entry : any/c
procedure
(storyboard-shot occurrence-id clip) → any/c
occurrence-id : symbol? clip : slide-clip?
procedure
procedure
(slide-transition [ #:effect effect #:duration duration #:keys keys #:direction direction #:easing easing #:scale scale #:color color #:depth depth]) → slide-transition? effect : symbol? = 'crossfade duration : real? = 0.6 keys : (listof symbol?) = '() direction : (or/c #f 'left 'right 'up 'down) = #f easing : symbol? = 'linear scale : (or/c #f real?) = #f color : (or/c #f color-spec?) = #f depth : (or/c #f 'auto 'slot 'semantic) = #f
Effect |
| Behavior |
crossfade |
| Fade the outgoing content out and incoming content in. |
match |
| Match selected keys; other content crossfades. |
push |
| Move both compositions by one canvas extent. |
wipe |
| Keep both stationary and move a reveal boundary. |
cover |
| Move the destination over the stationary source. |
uncover |
| Move the source away from the stationary destination. |
zoom |
| Grow source and destination with a crossfade. |
fade-through |
| Fade to an opaque intermediate color, then from it. |
Direction applies only to push, wipe, cover, and uncover; its default is left. Leftward travel brings the incoming composition from the right. These four effects require opaque endpoint backgrounds. They include backgrounds, decorations, and existing crops, not only content leaves.
Easing is one of 'linear, 'smooth (cubic smoothstep), 'ease-in, 'ease-out, or 'ease-in-out (quadratic). These are symbols for the slide API. They are not core rate-function constructors: native scene-play may instead take (smooth).
Scale applies only to zoom and lies strictly between 0 and 1; default 0.85. The source grows from 1 to its reciprocal; the destination grows from scale to 1. Color applies only to fade-through; default black. It resolves under the destination theme and must be opaque. The solid intermediate frame occurs at eased progress one half, not necessarily halfway in clock time.
Keys and depth apply to match. Missing, ambiguous, or wholly invisible keyed endpoints fail. Auto depth uses named-part matching or supported checkpoint replay where available, then falls back to compatible whole-asset matching or crossfade. Slot depth disables the recursive/replay mechanisms. Semantic depth requires supported correspondence for the requested keys and rejects unsupported domain relationships. It still permits defined create/remove/replacement behavior within a supported named group.
Clip clocks stay at the outgoing endpoint and incoming start. A matched pair of compatible content-state values deliberately replays its child interval through the bridge. This is the exception, not automatic playback of both clips.
Reduced storyboard motion replaces match, push, wipe, cover, uncover, and zoom with same-duration/easing crossfades. Cuts and fade-through retain their behavior. Per-clip reduced motion separately suppresses emphasis scaling and uses instant slot visibility changes without changing beat intervals. It does not replace arbitrary embedded animation choreography.
65.8 Named children and frozen checkpoints
procedure
(semantic-part id content [ #:x x #:y y] #:width width #:height height [ #:align align #:valign valign #:fit fit]) → semantic-part? id : symbol? content : any/c x : real? = 0 y : real? = 0 width : real? height : real? align : (or/c 'left 'center 'right) = 'center valign : (or/c 'top 'center 'bottom) = 'center fit : (or/c 'contain 'natural) = 'contain
procedure
(semantic-group #:width width #:height height part ...) → semantic-group? width : real? height : real? part : semantic-part?
Matched child placements compose with the matched parent placement. Surviving names move, changed appearances crossfade within their moving rectangle, and created/removed children fade. This is not a general text or geometry morph.
procedure
(content-state content #:at at [ #:viewport viewport]) → content-state? content : content? at : any/c viewport : list? = '(16 9)
A poster chooses how ordinary content is previewed; a content state fixes what that content shows. Those are different operations. State replay is visual-only: imported media is rejected rather than duplicated or stretched. Narrate outside that replay or author media explicitly in the parent. Unrelated formulas and independently realized constructions do not establish a replay interval merely because their slot keys agree.
65.9 Pict and Scene conversion
65.9.1 Pict output
procedure
(slide->pict source [ #:at at #:theme theme #:format format #:size size #:fit fit #:debug debug]) → pict? source : any/c at : any/c = #f theme : (or/c #f slide-theme?) = #f format : (or/c #f slide-format?) = #f size : any/c = #f fit : (or/c 'error 'letterbox) = 'error debug : list? = '()
procedure
(storyboard->pict source [ #:at at #:size size #:fit fit #:debug debug]) → pict? source : any/c at : any/c = 'end size : any/c = #f fit : (or/c 'error 'letterbox) = 'error debug : list? = '()
procedure
(storyboard->picts source [ #:size size #:fit fit #:debug debug]) → (listof pict?) source : any/c size : any/c = #f fit : (or/c 'error 'letterbox) = 'error debug : list? = '()
procedure
(content-width value) → real?
value : any/c (content-height value) → real? value : any/c (content-theme value) → slide-theme? value : any/c (content-format value) → slide-format? value : any/c
procedure
(content-color context role) → any/c
context : any/c role : symbol?
Size is false or a list of two positive exact pixel counts. False uses 80 pixels per world unit. An aspect mismatch is an error unless letterbox is explicit. Debug flags are slots, safe-area, and baselines. Ordinary output excludes the separate narration-subtitle track. In-memory content can resolve automatically; content needing file/tool effects requires explicit preparation first.
65.9.2 Scene and timeline output
procedure
(slide->scene source [ #:theme theme #:format format #:size size #:fit fit]) → scene? source : any/c theme : (or/c #f slide-theme?) = #f format : (or/c #f slide-format?) = #f size : any/c = #f fit : (or/c 'error 'letterbox) = 'error
procedure
(storyboard->scene source [ #:size size #:fit fit]) → scene? source : any/c size : any/c = #f fit : (or/c 'error 'letterbox) = 'error
procedure
(storyboard->timeline source [ #:size size #:fit fit]) → authored-timeline? source : any/c size : any/c = #f fit : (or/c 'error 'letterbox) = 'error
procedure
(scene-slot-id selector) → symbol?
selector : any/c
procedure
(scene-slot-ref scene selector [#:at at]) → visual?
scene : scene? selector : any/c at : real? = (scene-duration scene)
65.10 Native, mathematical, and geometry content
65.10.1 Native Scene content
procedure
(scene-content source [ #:fit fit #:poster poster #:media media #:background? background?]) → content? source : (or/c scene? authored-timeline?) fit : (or/c 'contain 'cover 'natural) = 'contain poster : any/c = 'end media : (or/c #f 'visual-only 'import) = #f background? : boolean? = #f
procedure
(visual-content visual [ #:fit fit #:width width #:height height]) → content? visual : visual? fit : (or/c 'contain 'cover 'natural) = 'contain width : (or/c #f real?) = #f height : (or/c #f real?) = #f
Imported media runs only while its child clock advances. Audio must use bounded cues. Partial trimming through faded cue envelopes and overlapping parent/child subtitles are rejected instead of silently changing their meaning.
65.10.2 Mathematical content
procedure
(math-content plan [ #:poster poster #:fit fit #:aspect aspect]) → content? plan : any/c poster : any/c = 'end fit : (or/c 'contain 'natural) = 'contain aspect : real? = 16/9
Step cues can be (step-name start) or (step-name end); qualify with a segment index when names repeat. Existing domain context headings and working-row margins remain inside the viewport. Mathematical foreground/background colors must resolve to opaque colors. Fitting below the theme’s minimum math scale fails.
65.10.3 Geometry content
procedure
(geometry-content program-or-timeline [ #:poster poster #:fit fit #:aspect aspect]) → content? program-or-timeline : any/c poster : any/c = 'end fit : (or/c 'contain 'natural) = 'contain aspect : real? = 16/9
Geometry supports the module-backed worker route. Workers reconstruct samplers from parent-prepared data without realizing the construction or placing labels again. Explicit realization in module-level user code can still repeat when that module is loaded in workers; the adapter cannot remove arbitrary source effects.
65.11 Preparation and inspection
65.11.1 Preparation
procedure
(prepare-slide! source [ #:theme theme #:format format #:asset-base asset-base]) → any/c source : any/c theme : (or/c #f slide-theme?) = #f format : (or/c #f slide-format?) = #f asset-base : (or/c #f path-string?) = #f
procedure
(prepare-storyboard! source [ #:asset-base asset-base]) → prepared-storyboard? source : any/c asset-base : (or/c #f path-string?) = #f
procedure
(prepared-duration source) → real?
source : any/c
procedure
(storyboard-match-report source) → list?
source : any/c
procedure
(prepared-slide? value) → boolean?
value : any/c (prepared-slide-clip? value) → boolean? value : any/c (prepared-storyboard? value) → boolean? value : any/c
65.11.2 Inspection helpers
procedure
(storyboard-ref source occurrence-id) → any/c
source : any/c occurrence-id : symbol?
procedure
(storyboard-with-theme board theme) → storyboard?
board : storyboard? theme : slide-theme?
procedure
(storyboard-with-format board format) → storyboard?
board : storyboard? format : slide-format?
procedure
(check-storyboard source) → list?
source : any/c
Slide exceptions expose a code, semantic path, and details. Domain exceptions retain their own types. No automatic font-fallback or effective-resolution advisories are supplied; absence of a diagnostic is not evidence of good type.
65.12 Project sources
syntax
(storyboard-source module-path binding option ...)
procedure
(make-storyboard-source module-path binding [ #:asset-base asset-base #:seed seed]) → any/c module-path : path-string? binding : symbol? asset-base : (or/c #f path-string?) = #f seed : exact-integer? = 0
Prepared artifacts are data, not a promise of persistent frame-cache reuse. Workers need compatible source, Racket, and fonts. No font binaries are transferred. Arbitrary renderer factories and arbitrary closures are not made portable by this API. slides/render-example.rkt configures the ordinary runner from an exported film; it avoids duplicating those theme settings.
65.13 Gallery catalogue
value
value
procedure
(select-slide-gallery-entries [ #:entries entries #:category category]) → list? entries : (or/c #f list?) = #f category : (or/c #f symbol?) = #f
procedure
(make-slide-gallery [ #:entries entries #:category category #:theme theme #:format format #:motion motion]) → storyboard? entries : (or/c #f list?) = #f category : (or/c #f symbol?) = #f theme : slide-theme? = lecture-light format : slide-format? = widescreen motion : (or/c 'normal 'reduced) = 'normal
procedure
(slide-gallery-entry? value) → boolean?
value : any/c
procedure
(slide-gallery-entry-id value) → symbol?
value : slide-gallery-entry? (slide-gallery-entry-category value) → symbol? value : slide-gallery-entry? (slide-gallery-entry-title value) → string? value : slide-gallery-entry? (slide-gallery-entry-description value) → string? value : slide-gallery-entry? (slide-gallery-entry-requirements value) → list? value : slide-gallery-entry? (slide-gallery-entry-example value) → string? value : slide-gallery-entry? (slide-gallery-entry-source value) → string? value : slide-gallery-entry?
65.14 Core predicates and read-only accessors
These operations inspect values; they do not prepare or render them.
procedure
value : any/c (content? value) → boolean? value : any/c (slide-format? value) → boolean? value : any/c (slide-theme? value) → boolean? value : any/c (layout? value) → boolean? value : any/c (slot-spec? value) → boolean? value : any/c (slide-clip? value) → boolean? value : any/c (beat? value) → boolean? value : any/c (slide-action? value) → boolean? value : any/c (narration? value) → boolean? value : any/c (storyboard? value) → boolean? value : any/c (slide-transition? value) → boolean? value : any/c (semantic-group? value) → boolean? value : any/c (semantic-part? value) → boolean? value : any/c (content-state? value) → boolean? value : any/c (diagnostic? value) → boolean? value : any/c (exn:fail:slides? value) → boolean? value : any/c