Slides
The overview below links to each definition. Function definitions show signatures with parameter and return types; variables show their declared types. Descriptions and defaults follow.
slide
Creates one logical slide command.
A logical slide is one unit of content, which may render as several physical frames once incremental steps are applied.
#mosaic.slide[
== Structure
Every slide resolves to a grid tree.
]Choosing a layout
The selection is the one positional subject, so slide("content", variant: "body")[...] and slide(layout: "content", variant: "body")[...] are the same slide.
auto: the configuredcontentlayout. The default."content","title","section": the matching entry insetup(layouts:). The name also determines numbering and the section lifecycle.- A
mosaic.layouts.*value: used directly, carrying its own semantic name. - A raw
mosaic.grids.*tree: used directly and treated as a content layout.
Supplying content
Use one of the two forms, never both on the same slide:
- Positional bodies, filling cells in depth-first layout order.
- A
cells:dictionary keyed by cell id, which is order-independent and lets a slide skip cells.
#mosaic.slide(cells: (
header: [== Named cells],
body: [Order does not matter here.],
))Planes
background: and foreground: are full-slide layers rather than grid cells, so they have parameters of their own. auto inherits the plane declared on setup, none suppresses it for this slide, and content overrides it.
#mosaic.slide(
cells: (body: [Over a photograph.]),
background: mosaic.components.image("cover.webp"),
)Layout fields
Any other named argument is a field of the selected layout, so the slide refines the configured layout rather than replacing it, and fields the theme set survive:
#mosaic.slide(layout: "title", variant: "academic")This requires layout: auto or a layout name. With an explicit mosaic.layouts.* value the constructor is already at hand, so pass the fields to it instead.
slide(
layout: auto | str | dictionary = auto,
numbered: auto | bool = auto,
invert: bool = false,
cells: dictionary = (:),
background: auto | content | none = auto,
foreground: auto | content | none = auto,
..bodies: arguments
) -> contentlayout- Type:
autoorstrordictionary - Default:
auto - Which layout resolves this slide:
autofor the configured content layout, one of the names"content","title","section", or"image", amosaic.layouts.*value, or a rawmosaic.grids.*tree. Also accepted as the leading positional argument.
- Type:
numbered- Type:
autoorbool - Default:
auto - Whether the slide contributes to logical slide numbering.
autonumbers content layouts and leaves title and section layouts unnumbered; an explicit boolean always wins.
- Type:
invert- Type:
bool - Default:
false - Whether to invert this slide’s polarity: the slide ground takes the deck’s text color, type is knocked out in the canvas color, and the muted and line colors are derived to match. Works with any layout, so an inverted title, section plate, or big-number slide are all one flag. Theme rules that pin an explicit fill other than the deck text color are not rewritten; override those on their own labels where needed.
- Type:
cells- Type:
dictionary - Default:
(:) - Cell bodies keyed by cell id. Mutually exclusive with positional bodies.
- Type:
background- Type:
autoorcontentornone - Default:
auto - Full-slide layer drawn behind the grid.
autoinherits the deck background fromsetup,nonesuppresses it.
- Type:
foreground- Type:
autoorcontentornone - Default:
auto - Full-slide layer drawn over the grid.
autoinherits the deck foreground fromsetup,nonesuppresses it.
- Type:
..bodies- Type:
arguments - Positional cell bodies in depth-first layout order, plus any named arguments forwarded as fields of the selected layout.
- Type:
info
Reads what the deck knows about itself: the metadata declared on setup, and the position of the slide being rendered. This is what a custom composition reads instead of restating the deck, and what deck chrome reads instead of counting for itself.
Returns a dictionary with six fields. Four are the deck metadata, exactly as setup received it:
title: the deck title.subtitle: the deck subtitle.authors: always an array of resolved author records, whether the deck wrote a bare name or a fulllayouts.authorrecord. Every entry carriesname,affiliations,email,orcid, andcorresponding.date: the deck date.
Two are the position of the slide being rendered, which is what makes the reader contextual:
slide: a dictionary ofnumber,total, andnumbered. The count is of logical slides rather than pages, so one incremental slide is one number however many frames it prints. Unnumbered slides (titles and sections, by default) are passed over by the count and reportnumbered: false, which is the signal deck furniture uses to quiet itself on those pages.section: a dictionary ofnumber,total, andtitle. The number is the current section’s, counting slides that use thesectionlayout, and the title is that section’s own text with any heading stripped. Before the deck’s first section slide the number is0and the title isnone.
Call it inside a context block (slide bodies, planes, and show rules already are one):
#mosaic.slide(
background: mosaic.components.image("cover.webp", scrim: black.transparentize(45%)),
)[
#context {
let deck = mosaic.info()
place(top + left, text(size: 2.2em, weight: "bold", deck.title))
place(bottom + left, deck.authors.map(author => author.name).join([, ]))
}
]The metadata half is the escape hatch for title pages the built-in variants do not draw: declare the information once on setup, and a hand-built cover reads it back instead of duplicating it. The position half is what a footline or a headline is made of, and it is the same reading components.progress does, so a theme drawing its own chrome keeps no counters of its own:
#let footline = context {
let deck = mosaic.info()
grid(
columns: (1fr, 1fr),
deck.section.title,
align(right)[#deck.slide.number\/#deck.slide.total],
)
}info() -> dictionarynote
Attaches non-rendering speaker notes to a logical slide.
Notes never appear in the slides themselves. They are collected and shown by the "speaker" and "notes" outputs of setup.
#show: mosaic.setup.with(output: "speaker")
#mosaic.slide[
== Results
#mosaic.note[Mention the confidence interval before the table.]
The estimate holds under both specifications.
]Multiple note blocks on one slide accumulate in source order. Wrap a note in steps.on, steps.reveal, or steps.replace to tie it to the same physical frames as the incremental content it belongs with, so the speaker view shows it beside the frame it describes.
note(body: content) -> contentbody- Type:
content - The note text. Ordinary content, so lists and emphasis work as usual.
- Type:
surface
Builds the transforming rule that paints a cell’s or plane’s own block.
Properties of the content inside a cell, such as text, alignment, and paragraphs, reach it through ordinary set rules on its label. The cell’s own surface cannot, because it is a block constructed before those rules apply, so it is painted by wrapping the labeled block instead. surface returns that standard wrapper, it => block(width: 100%, height: 100%, ...,, ready to use as the body of a label rule.
it)
#show label("mosaic-cell-body"): mosaic.surface(
fill: luma(240),
stroke: 0.5pt + gray,
radius: 6pt,
)What it applies to
- Any grid cell, through its
<mosaic-cell-ID>label. - The full-slide planes, which carry
<mosaic-background>and<mosaic-foreground>.
Both kinds of rule may be combined with ordinary set rules on the same label; the set rule styles the content and this one paints the block around it.
surface(
fill: none | color | gradient | tiling = none,
stroke: none | length | color | gradient | stroke | tiling | dictionary = none,
radius: relative | dictionary = 0pt,
height: auto | relative = 100%
) -> functionfill- Type:
noneorcolororgradientortiling - Default:
none - Paint behind the content, or
none.
- Type:
stroke- Type:
noneorlengthorcolororgradientorstrokeortilingordictionary - Default:
none - Border drawn around the painted block, or
none.
- Type:
radius- Type:
relativeordictionary - Default:
0pt - Corner radius of the painted block.
- Type:
height- Type:
autoorrelative - Default:
100% - Height of the painted block. Keep
100%for cells in1fror fixed tracks; passautofor a content-sized cell in anautotrack so the paint hugs the content.
- Type:
fit
Scales one block of content to the space it is given.
Mosaic never resizes body content on its own, so a slide holding more than it can show reports an overflow rather than shrinking. fit is the explicit per-block exception, for content whose size the author does not control: a wide table, a chart, a generated list, a number meant to fill the slide.
It measures the content against the region the call sits in and scales it geometrically, so proportions are preserved and the surrounding layout accounts for the new size. With no width or height it fits the whole region.
#mosaic.slide[
== A long argument
#mosaic.fit(generated-list)
]Fitting works in cells, in the background and foreground planes, and in ordinary content. Pass grow: true for display type that should fill its cell rather than merely avoid overflowing it:
#mosaic.fit(grow: true)[42%]Content that must not be re-laid out
By default the content is offered the region’s width first, so text and lists wrap into the cell and are scaled only if they are still too tall. A table, chart, or diagram would rearrange its own columns instead, which changes the composition rather than its size. Pass wrap: false to scale such a block exactly as it stands:
#mosaic.fit(wrap: false, my-wide-table)Overflow
A fitted block cannot overflow, so it emits no <mosaic-overflow-warning> record and never fails an overflow: "error" compile. A cell that fits its content therefore stops reporting how full it is.
Incremental content and speaker notes
Fitting measures its body, which means holding it inside a closure that the slide runtime cannot look into. Incremental markers and speaker notes are found by walking the slide’s content, so anything inside a fitted block would be invisible to that walk: the reveals would collapse into one frame and the notes would vanish. fit rejects such a body rather than dropping it silently. Keep pause, steps, and note outside the fitted block, or fit each revealed part on its own.
fit(
body: content,
width: auto | length | relative | fraction = auto,
height: auto | length | relative | fraction = auto,
wrap: bool = true,
grow: bool = false,
shrink: bool = true
) -> contentbody- Type:
content - The content to scale.
- Type:
width- Type:
autoorlengthorrelativeorfraction - Default:
auto - Width to fit into.
autouses the full width of the region.
- Type:
height- Type:
autoorlengthorrelativeorfraction - Default:
auto - Height to fit into.
autouses the full height of the region.
- Type:
wrap- Type:
bool - Default:
true - Let the content re-lay out at the available width before it is measured. Pass
falsefor a block whose own arrangement must be preserved.
- Type:
grow- Type:
bool - Default:
false - Scale content up when it is smaller than the space available.
- Type:
shrink- Type:
bool - Default:
true - Scale content down when it is larger than the space available.
- Type: