Roles and Directives#

Roles and directives provide a way to extend the syntax of MyST in an unbound manner, by interpreting a chuck of text as a specific type of markup, according to its name.

Mostly all docutils roles, docutils directives, Sphinx roles, or Sphinx directives can be used in MyST.

1.  Syntax#

1.1.  Directives - a block-level extension point#

Directives syntax is defined with triple-backticks and curly-brackets. It is effectively a Markdown code fence with curly brackets around the language, and a directive name in place of a language name. Here is the basic structure:

MyST

reStructuredText

```{directivename} arguments
:key1: val1
:key2: val2

This is
directive content
```
.. directivename:: arguments
   :key1: val1
   :key2: val2

   This is
   directive content

For example:

```{admonition} This is my admonition
This is my note
```

This is my admonition

This is my note

Parameterizing directives (options)#

Many directives can take key/value pairs, in an optional option block at the start of the directive.

The option block starts on the first line of the directive body and is defined by a set of lines prefixed with :.

The block then follows a YAML-like mapping syntax, where the key (string) and value (string) are separated by a colon (:):

```{code-block} python
:lineno-start: 10
:emphasize-lines: 1, 3

a = 2
print('my 1st line')
print(f'my {a}nd line')
```
10a = 2
11print('my 1st line')
12print(f'my {a}nd line')

Comments, starting #, are also allowed in between options or at the end of values, and are ignored. The values can be enclosed in quotes (" or ') and span multiple lines. Newline behaviour can be controlled by starting the value with | (preserve newlines) or > (collapse newlines):

```{code-block} python
:lineno-start: 10  # this is a comment
: # this is also a comment
:emphasize-lines: "1, 3"
:caption: |
:    This is my
:    multi-line caption. It is *pretty nifty* ;-)

a = 2
print('my 1st line')
print(f'my {a}nd line')
```
This is my multi-line caption. It is pretty nifty ;-)#
10a = 2
11print('my 1st line')
12print(f'my {a}nd line')
Old-style options block

Option blocks can also be enclosed by ---, with no : prefix, for example:

```{code-block} python
---
lineno-start: 10
emphasize-lines: 1, 3
caption: |
    This is my
    multi-line caption. It is *pretty nifty* ;-)
---
a = 2
print('my 1st line')
print(f'my {a}nd line')
```
This is my multi-line caption. It is pretty nifty ;-)#
10a = 2
11print('my 1st line')
12print(f'my {a}nd line')

How directives parse content#

Some directives parse the content that is in their content block. MyST parses this content as Markdown.

This means that MyST markdown can be written in the content areas of any directives written in MyST markdown. For example:

```{admonition} My markdown link
Here is [markdown link syntax](https://jupyter.org)
```

As a short-hand for directives that require no arguments, and when no parameter options are used (see below), you may start the content directly after the directive name.

```{note} Notes require **no** arguments, so content can start here.
```

Note

Notes require no arguments, so content can start here.

For special cases, MySt also offers the eval-rst directive. This will parse the content as ReStructuredText:

```{eval-rst}
.. figure:: img/fun-fish.png
  :width: 100px
  :name: rst-fun-fish

  Party time!

A reference from inside: :ref:`rst-fun-fish`

A reference from outside: :ref:`syntax/directives/parsing`
```
../_images/fun-fish.png

Party time!#

A reference from inside: Party time!

A reference from outside: How directives parse content

Note how the text is integrated into the rest of the document, so we can also reference party fish anywhere else in the documentation.

Nesting directives#

You can nest directives by ensuring that the tick-lines corresponding to the outermost directive are longer than the tick-lines for the inner directives. For example, nest a warning inside a note block like so:

````{note}
The next info should be nested
```{warning}
Here's my warning
```
````

Note

The next info should be nested

Warning

Here’s my warning

You can indent inner-code fences, so long as they aren’t indented by more than 3 spaces. Otherwise, they will be rendered as “raw code” blocks:

````{note}
The warning block will be properly-parsed

   ```{warning}
   Here's my warning
   ```

But the next block will be parsed as raw text

    ```{warning}
    Here's my raw text warning that isn't parsed...
    ```
````

Note

The warning block will be properly-parsed

Warning

Here’s my warning

But the next block will be parsed as raw text

```{warning}
Here's my raw text warning that isn't parsed...
```

This can really be abused if you’d like ;-)

``````{note}
The next info should be nested
`````{warning}
Here's my warning
````{admonition} Yep another admonition
```python
# All this fuss was about this boring python?!
print('yep!')
```
````
`````
``````

Note

The next info should be nested

Warning

Here’s my warning

Yep another admonition

# All this fuss was about this boring python?!
print('yep!')

Markdown-friendly directives#

Want to use syntax that renders correctly in standard Markdown editors? See the extended syntax option.

:::{note}
This text is **standard** *Markdown*
:::

Note

This text is standard Markdown

1.2.  Roles - an in-line extension point#

Roles are similar to directives - they allow you to define arbitrary new functionality, but they are used in-line. To define an in-line role, use the following form:

MyST

reStructuredText

{role-name}`role content`
:role-name:`role content`

For example:

Since Pythagoras, we know that {math}`a^2 + b^2 = c^2`

Since Pythagoras, we know that \(a^2 + b^2 = c^2\)

You can use roles to do things like reference equations and other items in your book. For example:

```{math} e^{i\pi} + 1 = 0
:label: euler
```

Euler's identity, equation {math:numref}`euler`, was elected one of the
most beautiful mathematical formulas.
(1)#\[e^{i\pi} + 1 = 0\]

Euler’s identity, equation (1), was elected one of the most beautiful mathematical formulas.

Euler’s identity, equation (1), was elected one of the most beautiful mathematical formulas.

How roles parse content#

The content of roles is parsed differently depending on the role that you’ve used. Some roles expect inputs that will be used to change functionality. For example, the ref role will assume that input content is a reference to some other part of the site. However, other roles may use the MyST parser to parse the input as content.

Some roles also extend their functionality depending on the content that you pass. For example, following the ref example above, if you pass a string like this: Content to display <myref>, then the ref will display Content to display and use myref as the reference to look up.

How roles parse this content depends on the author that created the role.

2.  MyST only roles#

This section contains information about special roles and directives that come bundled with the MyST Parser Sphinx extension.

2.1.  Insert the date and reading time#

New in version 0.14.0: The sub-ref role and word counting.

You may insert the “last updated” date and estimated reading time into your document via substitution definitions, which can be accessed via the sub-ref role.

For example:

> {sub-ref}`today` | {sub-ref}`wordcount-words` words | {sub-ref}`wordcount-minutes` min read

Mar 26, 2024 | 768 words | 4 min read

today is replaced by either the date on which the document is parsed, with the format set by today_fmt, or the today variable if set in the configuration file.

The reading speed is computed using the myst_words_per_minute configuration (see the Sphinx configuration options).