Format code outputs
Contents
Format 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.
stdout and stderr¶
Remove stdout or 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 aremove-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.
Group stdout and stderr into single streams¶
Cells may print multiple things to stdout
and stderr
.
For example, if a cell prints status updates throughout its execution, each of these is often printed to stdout
.
By default, these outputs may be split across multiple items, and will be rendered as separate “chunks” in your built documentation.
If you’d like each of the outputs in stderr
and stdout
to be merged into a single stream for each, use the following configuration:
nb_merge_streams = True
This will ensure that all stderr
and stdout
outputs are merged into a single group.
This also makes cell outputs more deterministic.
Normally, slight differences in timing may result in different orders of stderr
and stdout
in the cell output, while this setting will sort them properly.
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")
```
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-wide.svg)'))
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"