Incremental steps

The contents below link to each definition. Function entries show the signature, then a description, then the parameters with their types and defaults; variable entries show the declared type.

Shows a grid node or content only over a step range.

on(
  range,
  before: "hidden",
  after: "hidden",
  body
) -> content | dictionary
Description

This is the explicit form of incremental control: the range says exactly which frames the body appears on, independent of source order.

#mosaic.slide[
  == Findings
  #mosaic.steps.on(1)[First, in isolation.]
  #mosaic.steps.on("2-")[Then, for the rest of the slide.]
  #mosaic.steps.on("2-3", after: "dimmed")[A passing remark.]
]

Ranges

States

before and after say what happens outside the range:

The body may be content or a Mosaic grid node, so whole regions of a layout can appear and disappear, not just text.

Arguments
rangeint | str
Which steps show the body: an integer, "N-" for open-ended, or "N-M" for a closed range.
beforestr
How the body renders before the range: "hidden", "visible", or "dimmed".
afterstr
How the body renders after the range: "hidden", "visible", or "dimmed".
bodycontent | dictionary
Content or Mosaic grid node controlled by the range.

Reveals content or grid nodes one step at a time.

reveal(
  start: 1,
  before: "hidden",
  after: "visible",
  ..items
) -> content | array
Description

Where on sets one range by hand, reveal assigns consecutive steps for you, which is what a bulleted build usually wants.

#mosaic.steps.reveal[
  - Collect the data
  - Fit the model
  - Report the interval
]

What counts as an item

#mosaic.steps.reveal(start: 2, after: "dimmed",
  [First claim], [Second claim], [Third claim],
)
Arguments
startint
Step on which the first item appears. Later items follow one step apart.
beforestr
How an item renders before its own step: "hidden", "visible", or "dimmed".
afterstr
How an item renders after its own step: "visible" keeps it on screen, "dimmed" mutes it as the build moves on, and "hidden" removes it.
..itemsarguments
The items: content blocks or Mosaic grid nodes, but not both. At least one is required.

Replaces one content block with the next on successive steps.

replace(start: 1, align: top + left, ..bodies) -> content
Description

Exactly one body is on screen at a time, and every body occupies the same space, so surrounding content does not shift as the slide advances. That makes it the tool for an equation that rewrites itself or a diagram that gains an annotation.

#mosaic.steps.replace(
  align: center + horizon,
  $ a^2 + b^2 $,
  $ a^2 + b^2 = c^2 $,
)

This accepts content only. To swap structure, keep the grid stable and replace the content inside a cell.

Arguments
startint
Step on which the first body appears. Each later body replaces it one step further on.
alignalignment
Alignment applied to every body inside the shared area they occupy.
..bodiesarguments
The content blocks, shown one per step in order. At least one is required.

Teaches Mosaic to step through a drawing library’s own command values.

drawing(
  render: none,
  hide: none,
  dim: none,
  ..args
) -> content
Description

on and reveal work on content, which a drawing package such as CETZ or Fletcher does not produce: its nodes and edges are opaque command values that only mean something to its own renderer. drawing bridges the two. Mosaic resolves the step ranges, drops what this frame does not show, passes what remains through hide or dim, and hands the surviving array to render.

The usual shape is to bind the three functions once, then call the result like the library’s own renderer.

#import "@preview/fletcher:0.5.8" as fletcher

#let diagram = mosaic.steps.drawing.with(
  render: fletcher.diagram,
  hide: fletcher.hide,
)

#diagram(
  spacing: 4em,
  fletcher.node((0, 0), `reading`),
  mosaic.steps.on("2-", (
    fletcher.edge(`read()`, "-|>"),
    fletcher.node((1, 0), `eof`),
  )),
)

Positional arguments are the commands, each of which may be wrapped in on or reveal, alone or as an array. Named arguments are forwarded untouched to render, which is how spacing: above reaches fletcher.diagram.

Arguments
renderfunction
Draws the frame. Called as render(..named, commands) with the named arguments given here and the array of commands this frame keeps. Usually the library’s own top-level renderer.
hidefunction
Turns one command into its invisible counterpart, so it still reserves space and the drawing does not shift between frames. Usually the library’s own hide.
dimfunction | none
Turns one command into its muted counterpart. Required only if some step range uses the "dimmed" state; omitting it makes that an error.
..argsarguments
Positionally, the drawing commands, optionally wrapped in on or reveal. By name, arguments forwarded unchanged to render.

Advances subsequent content to the next physical frame.

Description

content

This is the least ceremonious way to build a slide: drop a marker where the pause belongs, and everything after it moves to the following frame. Everything before it stays on screen, so the slide accumulates.

#mosaic.slide[
  == Argument
  The premise.
  #mosaic.steps.pause
  The consequence.
  #mosaic.steps.pause
  The objection.
]

A pause is a value rather than a function, so it takes no arguments and no body. Compare steps.on and steps.reveal, which name their steps explicitly and can therefore reach frames out of source order.

Empty leading, trailing, or consecutive pauses produce no blank frames.