https://doi.org/10.5281/zenodo.20279172

title: Working with MyST in Neurodesk subtitle: Authoring tutorials and example notebooks for NeurodeskEDU subject: MyST Quickstart Tutorial authors:

  • name: Monika Doerig orcid: 0009-0008-3617-2185 affiliations:

    • School of Electrical Engineering and Computer Science

    • The University of Queensland, Brisbane, Australia github: https://github.com/MoniDoerig license: MIT License date: 2026-05-19


Citation and Resources#

This tutorial adapts material from the official MyST quickstart guides:

1. Introduction#

NeurodeskEDU is built with Jupyter Book, which renders notebooks via MyST-Parser — an extended Markdown flavour that adds directives, roles, cross-references, math, admonitions, tabs, cards, and more.

If you’re contributing an example notebook or tutorial here, the same MyST syntax works in plain Markdwon in .ipynb. On Neurodesk, the jupyterlab-myst extension is already enabled and markdown cells render directives like :::{note} immediately.

This tutorial walks through the MyST features available in NeurodeskEDU, with examples flavoured for Neurodesk content.

2. Admonitions#

Admonitions are coloured callout boxes. They have a directive name (note, tip, warning, important, caution, etc.) that controls the colour and icon. Use :::{name} to open and ::: to close.

2.1 The standard admonition types#

The renderer ships with ten built-in types. Click through the tabs to see each:

Note

Loaded modules persist for the life of the kernel — restart to start fresh.

Tip

Pin tool versions explicitly: module load fsl/6.0.7.18, not module load fsl.

Important

Reproducibility starts with version pinning. Always specify the exact module version.

Hint

Use module spider <name> to discover available versions before loading.

Attention

Some Neurodesk tools require a graphical session — these need to be run from the Neurodesktop terminal, not the JupyterLab terminal.

Warning

SPM12 in Neurodesk is the standalone (MCR) build — no full MATLAB licence is needed, but Nipype’s SPM interface needs use_mcr=True.

Caution

Heavy jobs run on the login node will affect other users. Submit them to SLURM with sbatch.

Danger

rm -rf does not ask twice. Double-check the path, especially when scripts construct it from variables.

Error

“Module not found” usually means you forgot module load <tool> — not that the tool is missing.

See also

Get started with Neurodesk: neurodesk.org/getting-started

2.2 Custom titles#

Use :::{admonition} <title> for an arbitrary title, and add :class: <type> to keep one of the standard styles:

Which method should I use?

I want to run a quick command

Use the JupyterLab Terminal — open one from the Launcher and type ml <tool>.

I’m building an analysis pipeline

Use the Jupyter Notebookawait module.load(...) keeps your setup documented alongside your code.

I need to visualise data with a GUI tool

Use the Neurodesktop Terminal or Application Menu — both give you access to graphical applications.

I’m new to the command line

Use the Sidebar Panel or Application Menu — point-and-click, no commands needed.

This admonition combines a custom title with a definition list — the pattern of a term on one line followed by : definition on the next, enabled by the deflist extension.

2.3 Collapsible admonitions#

Add :class: dropdown to any admonition to make it collapsible. Useful for long content that would otherwise crowd the page:

2.4 Nested admonitions#

You can nest one admonition inside another by using more colons on the outer block:

Caution

Reproducibility caveat Make sure you pin tool versions in your scripts.

Note

Internally, module load <tool> without a version loads the system default — which changes when Neurodesk updates the default.

The outer block uses :::: (four colons), the inner uses ::: (three). The rule: any nested directive needs fewer colons than its parent.

3. Tables, figures, and code blocks#

3.1 Tables#

Use the list-table directive for tables that need a name (so you can cross-reference them) or alignment options:

Table 1 Common Neurodesk neuroimaging modules#

Tool

Loaded with

Typical use

FSL

module load fsl/6.0.7.18

Linear/non-linear registration, BET, FAST, FEAT

ANTs

module load ants/2.5.3

N4 bias correction, advanced registration (SyN)

SPM12

module load spm12/r7771

Segmentation, fMRI GLM, VBM

AFNI

module load afni/24.0.04

3dDespike, 3dvolreg, classic AFNI workflows

FreeSurfer

module load freesurfer/7.4.1

Cortical surface reconstruction (recon-all)

For quick simple tables, GitHub-style pipe tables also work:

Module system command

Purpose

module avail

List available tools

module spider <name>

Search for a tool

module load <tool>/<version>

Activate a tool

module list

Show what’s currently loaded

module purge

Unload everything

3.2 Figures#

The figure directive supports captions, labels, and sizing:

Common figure options:

  • :name: — label for cross-referencing

  • :alt: — alt text for accessibility

  • :width:300px, 50%, etc.

  • :height: — pixels

  • :align:left, center, right

  • :figwidth: — width of the entire figure block (caption included)

3.3 Code blocks#

Plain fenced code blocks render with syntax highlighting:

Bash:

module load fsl/6.0.7.18
flirt -ref $FSLDIR/data/standard/MNI152_T1_2mm_brain \
      -in subject_T1.nii.gz \
      -out subject_in_mni.nii.gz \
      -dof 12

Or Python:

import module
await module.load('fsl/6.0.7.18')
await module.list()

For more control (line numbers, emphasising specific lines, captions), use the code-block directive:

Listing 1 Submit a parameterised job to SLURM#
#!/bin/bash
#SBATCH --job-name=preproc
#SBATCH --time=01:00:00
#SBATCH --cpus-per-task=4

module load fsl/6.0.7.18
papermill preproc.ipynb out.ipynb --parameters_raw subject_id 02

3.4 Task lists#

The tasklist extension turns GitHub-style checkbox lists into rendered task lists — useful for tutorial steps, todo prompts, or progress overviews:

  • Load the FSL module

  • Run brain extraction

  • Register T1 to MNI152

  • Generate QC overlay

The static build doesn’t allow toggling them.

3.5 Interactive widgets#

Notebooks can include ipywidgets for interactive controls — sliders, dropdowns, file pickers, viewers (ipyniivue), and more — and they render in JupyterLab as live components. Here’s a minimal slider:

import ipywidgets as widgets

n = widgets.IntSlider(value=5, min=0, max=10, description='Subjects:')
n

The variable n bound to the slider can be referenced inside markdown via jupyterlab-myst’s {eval} role. The value below reflects the kernel’s current state at cell-render time — re-execute the cell to refresh after sliding:

Important

Slider state

Caution

Live features need a kernel The slider above and the value shown in the admonition both depend on a running Python kernel — neither will function meaningfully in the static GitHub Pages build:

  • ipywidgets with Python callbacks (observe, on_click) won’t function without a kernel. Widgets using client-side trait linking (jslink) do remain interactive.

  • {eval} inline expressions are evaluated by jupyterlab-myst when the markdown cell is rendered. In JupyterLab the value reflects the current kernel state (re-execute the cell to refresh). In the static build the value appears frozen at whatever the kernel last produced, or empty.

4. Math and equations#

The dollarmath extension is enabled in this book, so LaTeX-style math works with single dollars (inline) and double dollars (block):

  • Inline ($...$) — sits inside a sentence at text size. Example: $T_2^*$ renders as \(T_2^*\).

  • Block — wrap on its own lines with $$...$$. Add (label) after the closing $$ to make the equation cross-referenceable.
    Example with a label:

(1)#\[ S(t) = S_0 \cdot e^{-TE / T_2^*} \]

Now [](#bold-signal) or (1) becomes a link to this equation.

For multi-line equations, use the math directive. This example shows the cost function for sum-of-squared-differences image registration:

(2)#\[\hat{T} = \arg\min_{T} \; \sum_{x \in \Omega} \big(I_{\text{moving}}(T(x)) - I_{\text{fixed}}(x)\big)^2\]

4.1 Inline math via Python#

The IPython display module lets you render LaTeX from a code cell:

from IPython.display import Math
Math(r"\sigma_{\text{noise}} = \sqrt{\frac{1}{N}\sum_{i=1}^{N} (x_i - \bar{x})^2}")
\[\displaystyle \sigma_{\text{noise}} = \sqrt{\frac{1}{N}\sum_{i=1}^{N} (x_i - \bar{x})^2}\]

5. Cross-references#

Once a figure, table, equation, or section has a :name: (or label), you can link to it from anywhere in the same book.

5.1 The simple [](#label) syntax#

Modern MyST-Parser supports [](#label) as the most concise form. Empty link text means the renderer auto-fills it from the target’s caption or label:

You can also override the link text: [the Neurodesk logo](#neurodesk-logo)the Neurodesk logo.

5.2 The explicit role syntax#

Sphinx-style roles also work and let you control numbering format:

Role

Purpose

Example

{numref}`label`

Numbered figure or table

“Fig. 1” / “Table 1”

{eq}`label`

Numbered equation

“(1)”

{ref}`label`

Section heading or generic label

uses heading text

Example: see Table 1 for the modules list, equation (1) for the \(T_2^*\)-weighted signal equation.

6. Tabs, cards, and grids#

These come from the sphinx-design extension (already available in Jupyter Book) and let you build richer, screen-responsive layouts.

6.1 Tabs#

Tabs group related variants of the same content (e.g. instructions for different tools). The same tab-set directive used in §2.1 above also works as a standalone container:

bet input_T1.nii.gz output_brain.nii.gz -R
from nipype.interfaces import fsl
bet = fsl.BET(in_file='input_T1.nii.gz', robust=True)
bet.run()
import subprocess
subprocess.run(['bet', 'input_T1.nii.gz', 'output_brain.nii.gz', '-R'])

6.2 Cards#

Cards are bordered, optionally clickable boxes — useful for navigation or feature-highlight blocks:

About Neurodesk

A flexible, scalable, and reproducible neuroimaging environment with 100+ research applications, available across desktop, JupyterLab, HPC, and cloud.

https://neurodesk.org/

6.3 Grids#

Grids arrange multiple cards in a responsive layout:

Tutorials

Tutorials are static, step-by-step guides that walk you through analyses including the use of graphical user interfaces (GUIs).

https://neurodesk.org/edu/tutorials/intro.html
Examples

Examples are interactive computational notebooks that you can run, modify, and experiment with.

https://neurodesk.org/edu/examples/intro.html
Documentation

The main Neurodesk site — installation, getting started, full module list.

https://neurodesk.org/
GitHub

Source code, issues, and contributions for all Neurodesk projects.

https://github.com/NeuroDesk

The four numbers after :::::{grid} set how many columns to show at four screen sizes (small to extra-large). Examples:

  • 1 1 1 1 → 1 column at all sizes → 4 stacked rows

  • 1 1 2 2 → 2 columns on bigger screens → 2 rows of 2 (used above)

  • 1 2 3 4 → more columns the wider the screen → 1 row of 4 on desktop

7. Reference: MyST extensions enabled in this book#

Neurodeskedu’s books/_config.yml enables these MyST-Parser extensions out of the box, so anything in this tutorial works without any additional configuration on your part:

Extension

What it enables

html_image

Allows raw <img> tags in markdown with HTML attributes (e.g. style, class).

dollarmath

$inline$ and $$block$$ LaTeX math.

colon_fence

:::{directive} syntax (alternative to triple-backtick fences) for admonitions, figures, etc.

deflist

Definition lists: term \n : definition.

tasklist

GitHub-style task checkboxes: - [ ] and - [x].

substitution

Variable substitution with {{varname}} syntax — variables defined under myst_substitutions: in _config.yml get expanded inline.

Plus directives that work without extension flags:

  • figure, list-table, code-block, math, note (and other admonitions)

  • tab-set / tab-item, card, grid (from sphinx-design, included by default)

  • Cross-reference roles: {numref}, {eq}, {ref}, plus [](#label) shorthand

If you find yourself wanting an extension that isn’t enabled (e.g. linkify, attrs_inline), it can be added to _config.yml.

Where to go from here#

  • The MyST-Parser docs are the most thorough reference: myst-parser.readthedocs.io

  • The Jupyter Book guide covers book-level configuration: jupyterbook.org

  • Browse the existing notebooks in books/examples/ and books/tutorials/ for live patterns you can copy.

  • If you don’t work on Neurodesk and you need to enable MyST renderer:

    In JupyterLab, click the Settings ⚙️ → Settings EditorDocument Manager → set Default Viewer for markdown to MyST. Or just install/enable the jupyterlab-myst extension.

Happy authoring! 🧠

Dependencies in Jupyter/Python#

  • Using the package watermark to document system environment and software versions used in this notebook, alongside the Neurodesktop version extracted from the JUPYTER_IMAGE or NEURODESKTOP_VERSION environment variables.

import os

%load_ext watermark

%watermark
%watermark --iversions

neurodesktop_version = (
    os.environ.get('JUPYTER_IMAGE', '').split(':')[-1] or
    os.environ.get('NEURODESKTOP_VERSION', 'unknown')
)

print(f"Neurodesktop version: {neurodesktop_version}")
Last updated: 2026-05-19T06:05:23.872890+00:00

Python implementation: CPython
Python version       : 3.13.13
IPython version      : 9.12.0

Compiler    : GCC 14.3.0
OS          : Linux
Release     : 6.8.0-106-generic
Machine     : x86_64
Processor   : x86_64
CPU cores   : 16
Architecture: 64bit

IPython   : 9.12.0
ipywidgets: 7.8.5

Neurodesktop version: 2026-04-28