Notebook filters & render scripts

Accessible tools that allow you to customize and extend Quarto.

Hamel Husain

Parlance Labs

Different ways to customize Quarto

Pandoc Required

Do not need Pandoc

We will cover the last two.

What are notebook filters?

See the docs

  • Modify notebooks programatically before they are rendered
  • A quick way to customize Quarto.
  • Add special directives:
    • #|hide to hide cells
    • delete sensitive information

Read from stdin and write to stdout.

Hello-World Filter

The filter

filter.py
import sys
import nbformat

# read notebook from stdin
nb = nbformat.reads(sys.stdin.read(), as_version = 4)

# prepend a comment to the source of each cell
for index, cell in enumerate(nb.cells):
  if cell.cell_type == 'code':
     if "#|hide" in cell.source:
        # delete cell
        del nb.cells[index]
        
# write notebook to stdout 
nbformat.write(nb, sys.stdout)


The project config:

_quarto.yml
ipynb-filters:
  - 6_filter/filter.py

Deubgging Notebook Filters

From this repo:

cd 6_filter/
cat filter_demo.ipynb | python filter.py

Does the notebook look like you expect? Prototype on a minimal notebook first!

Save the notebook:

cat filter_demo.ipynb | python filter.py > test.ipynb

Open the notebook in JupyterLab or VSCode.

Let me show you live!

Set breakpoints

It is useful to put breakpoints in your filter script to learn the nbformat API.

Let’s try it

quarto preview filter_demo.ipynb

Notebook filter tips

  • Search the Quarto docs before reaching for a filter
  • I’ve needed them less and less as Quarto has matured
  • I currently use them to handle edge cases that you are likely not going to encounter.

Let’s see how other people are using them. I found this.

Render Scripts

These are not like notebook filters, but they are a way to run arbitrary code before a project is rendered.

See this documentation.

I don’t use these personally! But let’s see what other people are doing.

This example is interesting.

Pandoc Filters (Lua)

  • Background on Pandoc
  • This is advanced; not going to cover it except for mentioning some references.
  • Lua filters have the upshot that the runtime is included with Quarto, so it’s easier to distribute.

Resources:

Exercise

  1. Create a notebook filter that deletes all cell outputs that contain phone numbers (use a regex).
  2. Create a pre-render script that warns you if a notebook does not contain a front matter (raw cell) as its first cell.