Reference

Everything the codefrag plugin does.

The complete codefrag behaviour: the options, the per-block fragment indices, the tooltip overflow fix, and the callback.

Enabling the plugin

format:
  revealjs:
    code-annotations: select
revealjs-plugins:
  - codefrag
filters:
  - codefrag

code-annotations: select is Quarto’s own option, and is what makes the annotations interactive in the first place.

The filters: entry is optional and changes nothing in the deck. It runs a check that reads the extensions.codefrag block and reports a key or a value the extension does not accept. Quarto expands a contributed filter only from a filters: entry, so revealjs-plugins: on its own leaves the check out. The check reports and never stops a render.

Options

extensions:
  codefrag:
    enabled: true
    patch-tooltip-overflow: true
Options under extensions.codefrag.
Option Default Description
enabled true Whether annotations are turned into fragments. Anything other than a boolean is read as true.
patch-tooltip-overflow true Move the tooltip up to the slide when an ancestor between the anchor and the slide clips overflow. Anything other than a boolean is read as true.
on-annotation-shown none A JavaScript function run after a tooltip is shown. Anything that is not a function is ignored.

on-annotation-shown receives { anchor, slide, targetCell, targetAnnotation, tippy }, and an exception it throws is written to the console rather than stopping navigation.

ImportantThe options block is not wired up yet

The plugin reads these three from the RevealJS deck configuration. Quarto copies a metadata key into that configuration only when the plugin entry in _extension.yml names the key in a config: block. The codefrag entry has no config: block, so nothing written under extensions.codefrag reaches the plugin and all three keep their defaults. The schema check still reads the block and still reports a key or a value it does not accept. The per-block attributes below are unaffected and work as documented.

Per-block fragment indices

A code block can say when each annotation appears, rather than taking them in order.

Attributes accepted on a code block.
Attribute Description
code-annotation-fragment-indices Comma-separated fragment indices, one per annotation, in annotation order: "2,4,6".
code-line-fragment-indices Comma-separated indices for each line-highlight step, counting the original code as step 0: "0,2,4,6". Needs code-line-numbers.

The first value of code-line-fragment-indices belongs to the original code block, which is the state the slide opens in, highlighted or not. That state needs no press, so the value is read and then ignored, and the values after it are taken by the highlight steps in order.

A token that is not a number writes a console warning and leaves that slot without an index, rather than failing the slide. A list whose length does not match the number of annotations, or of highlight steps, also writes a console warning, and the slots with no value of their own are left without an index.

RevealJS then sorts the fragments on the slide and renumbers them from zero, so the numbers you write set an order and not a position. A fragment with no index is placed after every fragment that has one, so a slot left without an index moves to the end rather than staying where it was written.

Line highlighting

A block that carries code-line-numbers as well as annotations is matched rather than sequenced, unless it also carries code-annotation-fragment-indices. That attribute turns the matching off for the block, and the annotations become plain fragments at the indices it gives.

Where the matching runs, the plugin pairs each highlight step with an annotation on the same lines, first by an exact match and then by containment, and a paired annotation takes the highlight’s step. An annotation that pairs with the state the slide opens in, which is what a code-line-numbers value with no leading | produces, is shown before the first press and takes no step. An annotation that pairs with nothing is given a step after the highest step on the slide.

Printing

pdf-separate-fragments is Quarto’s option and decides how print-pdf output is cut. It also decides whether line highlighting reaches the export, because Quarto’s own line-highlight plugin builds no highlight steps in a print view unless the option is true.

Left at its default of false, a block keeps no highlight steps, so the matching above cannot run and every annotation becomes a step of its own. The plugin then keeps the page for the first annotation and clones it for each of the rest, so every page carries one open note. A slide with three annotations becomes three pages, whatever its code-line-numbers value asks for.

Set to true, the highlight steps survive and the matching runs as it does in a live deck. RevealJS cuts a page per fragment step, starting with a page on which nothing is revealed, and the plugin only opens the right note on each page. An annotation that pairs with the state the slide opens in takes no step, so it gets no page and its note does not appear.

Markers are given a circular border under @media print, which keeps them legible once the hover styling is gone.

Layout

The stylesheet moves the copy button of an annotated block to the left, so it does not sit on top of the annotation gutter. A marker grows slightly on hover, which marks it as something to select.

Limitations

  • RevealJS only.
  • Needs a tooltip to show, which Quarto builds under code-annotations: select and under code-annotations: hover. Under code-annotations: below the annotations still become fragments and no tooltip appears, because Quarto puts the notes in a list instead. Under code-annotations: false there are no markers and the plugin does nothing.
  • The three options are not reachable from YAML, as the callout above says.
Back to top