This extension provides a filter to render pseudocode blocks in Typst output documents. It uses the lovelace Typst package to typeset algorithms with automatic indentation and bold keywords.
From a directory with an existing Quarto file or project, run:
quarto add christopherkenny/pseudocodeThis will install the extension under the _extensions subdirectory. If you're using version control, you will want to check in this directory.
Add the following to your document metadata after installing as above.
filters:
- quarto
- pseudocodePlacing quarto before pseudocode ensures Quarto's built-in processing (including cross-reference resolution) runs before this filter, which is required for @alg-* references to resolve correctly.
Then write pseudocode in a fenced code block with the pseudocode class:
```pseudocode
+ initialize parameters θ randomly
+ *while* not converged
+ *for* each data point $x_i$
+ compute posterior $Q(z_i) = P(z_i \mid x_i, \theta)$
+ *end*
+ *end*
+ return $\theta$
```Each + item becomes one line of pseudocode. Nested lists create indented blocks. Bold keywords like *while*, *for*, *if*, *then*, *else*, and *end* are written with *...*. Inline math uses standard LaTeX notation with $...$. Line comments use //.
The filter only activates for format: typst output and does nothing for other formats.
Options are passed as code block attributes. All options are optional.
| Option | Type | Default | Description |
|---|---|---|---|
title |
string | — | Title shown in the algorithm header |
line-numbering |
string or none |
— | Line number format, e.g. "1" or "a" |
booktabs |
true/false |
false |
Decorative top/bottom rules |
stroke |
Typst stroke | 1pt + gray |
Indentation guide style |
hooks |
Typst length | 0pt |
Indentation guide hook length |
indentation |
Typst length | 1em |
Width of each indentation level |
line-gap |
Typst length | .8em |
Vertical space between lines |
booktabs-stroke |
Typst stroke | 2pt + text.fill |
Style for booktabs rules |
title-inset |
Typst length | 0.8em |
Padding around the title |
line-number-supplement |
string | "Line" |
Label used in line references |
line-number-alignment |
Typst alignment | horizon + right |
Position of line numbers |
For example:
```{.pseudocode title="EM Algorithm" line-numbering="1" booktabs="true"}
+ initialize parameters θ randomly
+ *while* not converged
+ ...
+ *end*
```Length and stroke values (e.g. stroke, indentation) are passed directly as raw Typst, so write them in Typst syntax: stroke="0.5pt + blue", indentation="1.5em".
To make an algorithm referenceable, add a #alg-* identifier and a cap attribute.
The filter wraps the block in a Typst #figure(kind: "algorithm", ...), which gives it an "Algorithm N" counter.
Add a crossref block to your document metadata and use filters: [quarto, pseudocode] so the filter runs after Quarto's crossref pass and can rewrite unresolved @alg-* references to native Typst #ref().
crossref:
custom:
- kind: float
key: alg
reference-prefix: Algorithm```{.pseudocode #alg-sort title="Bubble Sort" cap="Bubble sort in-place."}
+ *for* $i = 1$ *to* $n - 1$
+ ...
+ *end*
```Then reference it with standard Quarto syntax:
@alg-sort shows bubble sort.Note: Quarto will emit a
WARNING: Unable to resolve crossref @alg-*message during rendering. This is a false positive. The algorithm label lives inside a raw Typst block, Quarto's crossref pass cannot see it. The filter intercepts the resulting broken reference and rewrites it to a native Typst#ref()call, so the output is correct.
Here is the source code for a minimal example: example.qmd.
MIT License. See the license file for further details.
