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
Caution
Use of AI This notebook was generated with assistance from Anthropic’s Claude (via Claude Code) across several iterations and then revised by the author. The author reviewed the final content and takes responsibility for it.
Citation and Resources#
This tutorial adapts material from the official MyST quickstart guides:
mystmd team. Working with MyST in Jupyter — mystmd.org/guide/quickstart-jupyter-lab-myst
MyST-Parser docs (the Python/Sphinx flavour Jupyter Book uses) — myst-parser.readthedocs.io
MyST-NB authoring guide — myst-nb.readthedocs.io
Admonition reference — myst-parser admonitions
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 Notebook —
await 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:
Note
Module shorthand reference
mlShorthand for
module load. Used to load, unload, list, and search for tools.ml availLists all available tools and versions on the system.
ml listShows which tools are currently loaded in your session.
ml purgeUnloads all currently loaded tools, resetting your environment.
ml spider <keyword>Searches for tools matching a keyword.
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:
Tool |
Loaded with |
Typical use |
|---|---|---|
FSL |
|
Linear/non-linear registration, BET, FAST, FEAT |
ANTs |
|
N4 bias correction, advanced registration (SyN) |
SPM12 |
|
Segmentation, fMRI GLM, VBM |
AFNI |
|
3dDespike, 3dvolreg, classic AFNI workflows |
FreeSurfer |
|
Cortical surface reconstruction ( |
For quick simple tables, GitHub-style pipe tables also work:
Module system command |
Purpose |
|---|---|
|
List available tools |
|
Search for a tool |
|
Activate a tool |
|
Show what’s currently loaded |
|
Unload everything |
3.2 Figures#
The figure directive supports captions, labels, and sizing:
Fig. 1 The Neurodesk project logo.#
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:
#!/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:
ipywidgetswith 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 byjupyterlab-mystwhen 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:
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:
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}")
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:
[](#neurodesk-logo)→ The Neurodesk project logo.[](#modules-table)→ Common Neurodesk neuroimaging modules[](#bold-signal)→ (1)[](#registration-cost)→ (2)
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 |
|---|---|---|
|
Numbered figure or table |
“Fig. 1” / “Table 1” |
|
Numbered equation |
“(1)” |
|
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:
A flexible, scalable, and reproducible neuroimaging environment with 100+ research applications, available across desktop, JupyterLab, HPC, and cloud.
6.3 Grids#
Grids arrange multiple cards in a responsive layout:
Tutorials are static, step-by-step guides that walk you through analyses including the use of graphical user interfaces (GUIs).
Examples are interactive computational notebooks that you can run, modify, and experiment with.
The main Neurodesk site — installation, getting started, full module list.
Source code, issues, and contributions for all Neurodesk projects.
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 rows1 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 |
|---|---|
|
Allows raw |
|
|
|
|
|
Definition lists: |
|
GitHub-style task checkboxes: |
|
Variable substitution with |
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/andbooks/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 Editor → Document Manager → set Default Viewer for
markdownto 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_IMAGEorNEURODESKTOP_VERSIONenvironment 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