Examples

The source behind the deck.

Each cascade behaviour, with the source that produces it and the slides it becomes in the RevealJS preview.

This page is HTML, and the filter only splits slides, so the demonstration is the RevealJS preview built by this same site. Each section below gives the source and says what the deck does with it. The Reference holds the rules, the options, and the defaults.

Repeating the chain

## Results

### Experiment A

Each `---` starts a new slide.

---

Written with no headings at all.

In the deck this is two slides, and both carry ## Results and ### Experiment A.

A heading at the same level starts a new chain under the same parent:

---

### Experiment B

A new chain under the same section.

The slide after it carries ## Results and ### Experiment B.

A rule followed by a deeper heading

A --- followed by a heading repeats the headings above that level only. A --- followed by anything else repeats the whole chain, as far as the depth allows.

## Results

### Experiment A

#### First measurement

Body of the first slide.

---

#### Second measurement

Body of the second slide.

---

Body of the third slide.

The second slide carries ## Results, ### Experiment A, and the #### Second measurement written under the rule. The second --- is followed by body text, so the third slide carries all three headings, #### Second measurement included.

Where the chain is collected

The Reference states the collection rule. The short of it is that a heading joins the chain only where it follows the slide heading, another heading, or an absorbed --- directly.

## Results

A sentence written before the subsection heading.

### Experiment A

Body of the first slide.

---

Body of the second slide.

The second slide carries ## Results alone, because the sentence stands between the two headings. Write the subsection heading directly under the slide heading to have it repeated:

## Results

### Experiment A

A sentence written after the subsection heading.

---

Body of the second slide.

The second slide now carries ## Results and ### Experiment A.

Limiting the depth

## Limiting the depth {cascade-depth="1"}

### A subsection

---

Only the slide-level heading is repeated here.

The continuation slide carries ## Limiting the depth and nothing below it.

The same limit can be set for a whole document instead:

extensions:
  cascade:
    depth: 1

An attribute on a heading overrides that for the chain beginning there, and the document setting resumes at the next heading at or above slide level.

Counting the levels

A depth counts heading levels from the slide level down. RevealJS makes a slide at level 2 unless the document says otherwise, so depth: 2 repeats ## and ###, and drops ####.

extensions:
  cascade:
    depth: 2

A depth of zero

The filter replaces each --- with the headings it repeats, and the repeated slide-level heading is what starts the new slide. A depth of 0 repeats no heading, so the first --- starts no slide and the text under it stays on the slide above. Both examples below are for a document that sets it:

extensions:
  cascade:
    depth: 0
## Results

### Experiment A

Body of the slide.

---

This text stays on the slide above.

cascade-depth="0" does the same for the chain that starts at the heading carrying it.

A second --- under the same heading behaves differently, because the chain is empty by then and the filter passes over a rule it has nothing to repeat for:

## Results

Body of the slide.

---

This text stays on the slide above.

---

This text starts a slide with no heading on it.

Opting a heading out

## Results

### An aside {.no-cascade}

Body of the first slide.

---

Body of the second slide.

The aside keeps its own place in the slide and is never carried forward, so the second slide carries ## Results alone.

A slide-level heading that opts out

A slide-level heading marked .no-cascade leaves the chain with no heading at slide level. Nothing then starts a new slide, and the rest of the chain is repeated in place, on the slide above. That needs a rest of the chain to repeat. Mark a slide-level heading .no-cascade with no other heading under it, and in a deck with no # section heading above it, and the chain is empty, so the --- stays in the document and starts a slide with no heading on it. Put a # section heading above it and the chain holds that heading instead, so the --- is taken out and nothing starts a new slide.

## Opting a heading out {.no-cascade}

### A subsection

Body of the slide.

---

This text stays on the slide above, under a second copy of `### A subsection`.

Write the next ## heading yourself where the next slide has to start.

Splitting inside a div

## Inside a div

::: {.callout-note}

A note, first part.

---

Second part, on a new slide, still in the callout.

:::

The div is closed, the chain repeated, and an identical div reopened around what follows, so both slides carry the same callout. Two rules in one div make three slides, and each slide that holds content carries the div.

A callout with a title

## Inside a div

::: {.callout-tip}

## Remember this

First part.

---

Second part.

:::

A title written as a heading at the top of the div is repeated inside every reopened div. Both slides therefore show the callout under the title Remember this, rather than the generic name of its type.

Identifiers on a div that splits

Each reopened div is a copy of the first with its identifier removed. A div written with an #id keeps it on the first slide only, so the anchor stays unique.

Divs the filter leaves alone

An identifier that starts with letters and a hyphen marks a cross-reference target, such as #tbl-results or #fig-plot. The filter leaves such a div alone, and the rule inside it is drawn rather than split. An ordinary identifier of the same shape is left alone as well:

::: {#side-note .column-margin}

First part.

---

Second part.

:::

Both parts stay on one slide, with a rule drawn between them. Write the identifier without the hyphen, as #sidenote, to have the div split.

A .panel-tabset is left alone as well, because reopening it would break the tabs.

A rule at the top of a div

A --- written as the first thing inside a div splits off a fragment that holds nothing. The slide before it then carries the heading chain alone:

## Leading rule

::: {.column-margin}

---

Only part.

:::

This is two slides: ## Leading rule with nothing under it, then ## Leading rule with the div.

Shifted heading levels

Quarto applies shift-heading-level-by after the filter has run, and passes it to no filter. A document that sets it has to declare the same value again:

format:
  revealjs:
    shift-heading-level-by: -1

extensions:
  cascade:
    shift: -1

With both values set, the slide level in the source is 3:

# Part one

## Results

### Experiment A

Body of the first slide.

---

Body of the second slide.

The second slide carries ### Experiment A alone. ## Results is above the slide level, so it keeps its own section slide and is not repeated. shift-heading-level-by: -1 moves # Part one to level 0, which Pandoc reads as the document title, so it names the deck instead of starting a slide. Only a # written at the top of the document does that. Write a second # later and the shift leaves it below level 1, where Pandoc writes it as a plain paragraph and it starts no slide at all.

Leave shift out and the filter reads the slide level as 2. It then treats ## Results as a slide heading and repeats it, so the --- produces a duplicate section slide before the continuation.

A different slide level

The filter follows the RevealJS slide-level.

format:
  revealjs:
    slide-level: 1
# Results

## Experiment A

Body of the first slide.

---

Body of the second slide.

The second slide carries # Results and ## Experiment A.

Rules that are not breaks

A --- inside a fenced code block never reaches the filter, because Pandoc reads it as content:

```
---
```

A --- row in a pipe table is a column separator, and is left alone.

A rule with no chain yet

A --- written before any heading has no chain to repeat. The filter leaves the rule in place, and RevealJS starts a new slide at it with no heading on it.

What the extension reports

Each of these is written to the render log, and none of them stops the render. The extension writes the [cascade] tag and the message, and Quarto writes the (W) or (E) in front of it.

A chain that skips a heading level usually points at an accidental gap in the source:

## Results

#### Deep detail

Body of the first slide.

---

Body of the second slide.
(W) [cascade] Heading chain skips from level 2 ("Results") to level 4 ("Deep detail") on a continuation slide; intermediate level(s) are missing.

A depth the extension cannot use is reported twice, once by the schema check and once by the filter. The block below carries a second, unrelated mistake as well, a dept typo, which the schema check reports on its own:

extensions:
  cascade:
    depth: "lots"
    dept: 2
(W) [cascade] dept: is not a recognised key and was ignored.
(E) [cascade] depth: must be of type "integer", got "string".
(W) [cascade] Ignoring "depth" option "lots": expected a whole number of zero or more. Repeating the whole chain.

The schema check names the key it does not know and the type it expected. The filter then says what it does with the value it was given.

A shift that moves the slide level out of range is reported and ignored:

extensions:
  cascade:
    shift: 5
(W) [cascade] Ignoring "shift" option 5: it puts the slide level at -3, outside the range 1 to 6, which would repeat no heading at all.

Outside RevealJS

There are no slides to split in HTML, PDF, or Word, so the filter takes every --- out of them. A rule written inside a div is removed as well. A document that uses --- as an ordinary rule as well as a slide break asks for it back:

extensions:
  cascade:
    keep-hrule: true

This site sets it, which is why a --- written in one of these pages would be drawn rather than dropped. Only the literal false turns it off again.

Source

The repository ships a short, standalone starting point you can copy: example.qmd.

Back to top