Formatting code outputs

Render priority

When Jupyter executes a code cell it can produce multiple outputs, and each of these outputs can contain multiple MIME media types, for use by different output formats (like HTML or LaTeX).

MyST-NB stores a default priority dictionary for most of the common Sphinx builders, which you can be also update in your conf.py. For example, this is the default priority list for HTML:

nb_render_priority = {
  "html": (
            "application/vnd.jupyter.widget-view+json",
            "application/javascript",
            "text/html",
            "image/svg+xml",
            "image/png",
            "image/jpeg",
            "text/markdown",
            "text/latex",
            "text/plain",
        )
}

See also

Customise the render process, for a more advanced means of customisation.

Removing stdout and stderr

In some cases you may not wish to display stdout/stderr outputs in your final documentation, for example, if they are only for debugging purposes.

You can tell MyST-NB to remove these outputs, per cell, using the remove-stdout and remove-stderr cell tags, like so:

```{code-cell} ipython3
:tags: [remove-input,remove-stdout,remove-stderr]

import pandas, sys
print("this is some stdout")
print("this is some stderr", file=sys.stderr)
# but what I really want to show is:
pandas.DataFrame({"column 1": [1, 2, 3]})
```
column 1
0 1
1 2
2 3

Alternatively, you can configure how stdout is dealt with at a global configuration level, using the nb_output_stderr configuration value. This can be set to:

  • "show" (default): show all stderr (unless a remove-stderr tag is present)

  • "remove": remove all stderr

  • "remove-warn": remove all stderr, but log a warning to sphinx if any found

  • "warn", "error" or "severe": log to sphinx, at a certain level, if any found.

Images

With the default renderer, for any image types output by the code, we can apply formatting via cell metadata. The top-level metadata key can be set using nb_render_key in your conf.py, and is set to render by default. Then for the image we can apply all the variables of the standard image directive:

  • width: length or percentage (%) of the current line width

  • height: length

  • scale: integer percentage (the “%” symbol is optional)

  • align: “top”, “middle”, “bottom”, “left”, “center”, or “right”

  • classes: space separated strings

  • alt: string

Units of length are: ‘em’, ‘ex’, ‘px’, ‘in’, ‘cm’, ‘mm’, ‘pt’, ‘pc’

We can also set a caption (which is rendered as CommonMark) and name, by which to reference the figure:

```{code-cell} ipython3
---
render:
  image:
    width: 200px
    alt: fun-fish
    classes: shadow bg-primary
  figure:
    caption: |
      Hey everyone its **party** time!
    name: fun-fish
---
from IPython.display import Image
Image("images/fun-fish.png")
```
from IPython.display import Image
Image("images/fun-fish.png")
fun-fish

Hey everyone its party time!

Now we can link to the image from anywhere in our documentation: swim to the fish

Markdown

Markdown output is parsed by MyST-Parser, currently with the configuration set to myst_commonmark_only=True (see MyST configuration options).

The parsed Markdown is integrated into the wider documentation, and so it is possible, for example, to include internal references:

from IPython.display import display, Markdown
display(Markdown('**_some_ markdown** and an [internal reference](use/format/markdown)!'))

some markdown and an internal reference!

and even internal images can be rendered!

display(Markdown('![figure](../_static/logo.png)'))

figure

ANSI Outputs

By default, the standard output/error streams and text/plain MIME outputs may contain ANSI escape sequences to change the text and background colors.

import sys
print("BEWARE: \x1b[1;33;41mugly colors\x1b[m!", file=sys.stderr)
print("AB\x1b[43mCD\x1b[35mEF\x1b[1mGH\x1b[4mIJ\x1b[7m"
      "KL\x1b[49mMN\x1b[39mOP\x1b[22mQR\x1b[24mST\x1b[27mUV")
ABCDEFGHIJKLMNOPQRSTUV
BEWARE: ugly colors!

This uses the built-in AnsiColorLexer pygments lexer. You can change the lexer used in the conf.py, for example to turn off lexing:

nb_render_text_lexer = "none"

The following code1 shows the 8 basic ANSI colors it is based on. Each of the 8 colors has an “intense” variation, which is used for bold text.

text = " XYZ "
formatstring = "\x1b[{}m" + text + "\x1b[m"

print(
    " " * 6
    + " " * len(text)
    + "".join("{:^{}}".format(bg, len(text)) for bg in range(40, 48))
)
for fg in range(30, 38):
    for bold in False, True:
        fg_code = ("1;" if bold else "") + str(fg)
        print(
            " {:>4} ".format(fg_code)
            + formatstring.format(fg_code)
            + "".join(
                formatstring.format(fg_code + ";" + str(bg)) for bg in range(40, 48)
            )
        )
            40   41   42   43   44   45   46   47  
   30  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;30  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   31  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;31  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   32  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;32  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   33  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;33  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   34  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;34  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   35  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;35  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   36  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;36  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
   37  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 
 1;37  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ  XYZ 

Note

ANSI also supports a set of 256 indexed colors. This is currently not supported, but we hope to introduce it at a later date (raise an issue on the repository if you require it!).

Customise the render process

The render process is goverened by subclasses of myst_nb.render_outputs.CellOutputRendererBase, which dictate how to create the docutils AST nodes for a particular MIME type. the default implementation is CellOutputRenderer.

Implementations are loaded via Python entry points, in the myst_nb.mime_render group. So it is possible to inject your own subclass to handle rendering.

For example, the renderers loaded in this package are:

entry_points={
    "myst_nb.mime_render": [
        "default = myst_nb.render_outputs:CellOutputRenderer",
        "inline = myst_nb.render_outputs:CellOutputRendererInline",
    ],
}

You can then select the renderer plugin in your conf.py:

nb_render_plugin = "default"

1

Borrowed from nbsphinx!