格式化代码单元格#

代码单元格的渲染行为可以通过全局、文件或单元格级别的配置进行控制,如 配置部分 所述。

请参阅以下部分,了解这些配置选项及其效果的描述。

为源代码行编号#

您可以通过全局设置 nb_number_source_lines = True、在笔记本元数据中设置 number_source_lines 或在单元格元数据中设置 number_source_lines 来控制是否为代码单元格显示源代码行号。例如:

```{code-cell} ipython3
---
mystnb:
  number_source_lines: true
---
a = 1
b = 2
c = 1
```
1a = 1
2b = 2
3c = 1

标准输出和标准错误输出#

移除标准输出或标准错误#

在某些情况下,您可能不希望最终文档中显示标准输出/标准错误输出,例如,如果它们仅用于调试目的。

您可以通过使用 remove-stdoutremove-stderr 单元格标签 来告诉 MyST-NB 移除这些输出,例如:

```{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

或者,您可以在全局配置级别配置如何处理标准输出,使用 nb_output_stderr 配置值。这可以设置为:

  • "show"(默认):显示所有标准错误(除非存在 remove-stderr 标签)

  • "remove":移除所有标准错误

  • "remove-warn":移除所有标准错误,但如果发现任何标准错误,则向 sphinx 记录警告

  • "warn""error""severe":如果发现任何标准错误,则以特定级别记录到 sphinx。

合并为单一流#

单元格可能会多次向 stdoutstderr 打印内容。例如,如果单元格在执行过程中打印状态更新,这些内容通常会打印到 stdout。默认情况下,这些输出可能会被分成多个项目,并在构建的文档中呈现为单独的“块”。

如果您希望将 stderrstdout 中的每个输出合并为单一流,请使用以下配置:

nb_merge_streams = True

这将确保所有 stderrstdout 输出合并为一个组。这也使单元格输出更加确定。通常,时间上的微小差异可能会导致 stderrstdout 在单元格输出中的顺序不同,而此设置将正确地对它们进行排序。

输出 MIME 优先级#

当 Jupyter 执行代码单元格时,它可以生成多个输出,每个输出可以包含多个 MIME 媒体类型,用于不同的输出格式(如 HTML 或 LaTeX)。

MyST-NB 为大多数常见的 Sphinx 构建器名称 存储了基本优先级字典,将 MIME 类型映射到优先级数字(数字越小,优先级越高):

import yaml
from myst_nb.core.render import base_render_priority
print(yaml.dump(base_render_priority()))
Hide code cell output
applehelp:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 50
  image/jp2: 80
  image/jpeg: 60
  image/png: 40
  image/svg+xml: 90
  image/tiff: 70
  text/html: 30
  text/latex: 110
  text/markdown: 100
  text/plain: 120
changes:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
devhelp:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 50
  image/jpeg: 60
  image/png: 40
  text/html: 30
  text/latex: 80
  text/markdown: 70
  text/plain: 90
dirhtml:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
dummy:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
epub:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
gettext:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
html:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
htmlhelp:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 50
  image/jpeg: 60
  image/png: 40
  text/html: 30
  text/latex: 80
  text/markdown: 70
  text/plain: 90
json:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
latex:
  application/pdf: 10
  image/jpeg: 30
  image/png: 20
  text/latex: 40
  text/markdown: 50
  text/plain: 60
linkcheck:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
man:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
pickle:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
pseudoxml:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
qthelp:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
readthedocs:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
readthedocsdirhtml:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
readthedocssinglehtml:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
readthedocssinglehtmllocalmedia:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
singlehtml:
  application/javascript: 20
  application/vnd.jupyter.widget-view+json: 10
  image/gif: 60
  image/jpeg: 70
  image/png: 50
  image/svg+xml: 40
  text/html: 30
  text/latex: 90
  text/markdown: 80
  text/plain: 100
texinfo:
  image/gif: 30
  image/jpeg: 20
  image/png: 10
  text/latex: 40
  text/markdown: 50
  text/plain: 60
text:
  text/latex: 10
  text/markdown: 20
  text/plain: 30
xml:
  text/latex: 10
  text/markdown: 20
  text/plain: 30

您可以在 conf.py 中使用 nb_mime_priority_overrides 配置选项覆盖此字典中的项目。例如,以下配置按顺序应用:

  • text/plain 设置为 html 输出的最高优先级。

  • 禁用 latex 输出的 image/jpeg

  • 为所有构建器添加自定义 MIME 类型 customtype* 适用于所有构建器)

nb_mime_priority_overrides = [
  ('html', 'text/plain', 0),
  ('latex', 'image/jpeg', None),
  ('*', 'customtype', 20)
]

在 0.14.0 版本发生变更: nb_mime_priority_overrides 替换 nb_render_priority

参见

自定义渲染过程,用于更高级的自定义方法。

图像和图表#

使用默认渲染器,对于代码输出的任何图像类型,我们可以通过单元格元数据应用格式化。顶层元数据键可以在 conf.py 中使用 nb_cell_metadata_key 设置,默认设置为 mystnb。然后,对于图像,可以应用标准 图像指令 的所有变量:

  • width:当前行宽度的长度或百分比(%)

  • height:长度

  • scale:整数百分比(“%”符号可选)

  • align:"top"、"middle"、"bottom"、"left"、"center" 或 "right"

  • classes: 空格分隔的字符串

  • alt: string

长度单位包括:'em'、'ex'、'px'、'in'、'cm'、'mm'、'pt'、'pc'

您还可以将输出包装在 figure 中,其中可以包括:

  • align: "left", "center", or "right"

  • caption:字符串,必须包含一个段落,并呈现为 MyST Markdown(后续段落将作为图例添加)

  • caption_before:布尔值,如果为 true,则标题在图表之前呈现(默认为 false)

  • name:用于引用图表的名称

  • classes: 空格分隔的字符串

```{code-cell} ipython3
---
mystnb:
  image:
    width: 300px
    alt: fun-fish
    classes: shadow bg-primary
  figure:
    caption: |
      Hey everyone its **party** time!

      (and I'm a legend)
    name: fun-fish-ref
---
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!#

(and I'm a legend)

现在可以从文档的任何位置链接到该图像:游向鱼

您可以为任何 MIME 输出创建图表,包括表格:

```{code-cell} ipython3
---
mystnb:
  figure:
    align: center
    caption_before: true
    caption: This is my table caption, above the table
---
import pandas
df = pandas.DataFrame({"column 1": [1, 2, 3]})
df = df.style.set_table_attributes('class="dataframe align-center"')
df
```
import pandas
df = pandas.DataFrame({"column 1": [1, 2, 3]})
df = df.style.set_table_attributes('class="dataframe align-center"')
df

This is my table caption, above the table#

  column 1
0 1
1 2
2 3

Markdown#

text/markdown 输出的格式可以通过 render_markdown_format 配置指定:

CommonMark 格式化将输出基本的 Markdown 语法:

from IPython.display import display, Markdown
display(Markdown('**_some_ markdown** and an [a reference](https://example.com)!'))

some markdown and an a reference!

甚至内部图像也可以渲染!

display(Markdown('![figure](../_static/logo-wide.svg)'))

figure

但将 Markdown 格式设置为 myst 将允许更高级的格式化,例如包含内部引用、表格甚至其他指令,可以使用:

  • conf.py 中使用 myst_render_markdown_format = "myst" 进行全局设置,或者

  • 在单元格元数据中使用 markdown_format 进行每单元格设置。

````{code-cell} ipython3
---
mystnb:
  markdown_format: myst
---
display(Markdown('**_some_ markdown** and an [internal reference](render/output/markdown)!'))
display(Markdown("""
| a | b | c |
|---|---|---|
| 1 | 2 | 3 |
"""))
display(Markdown("""
```{note}
A note admonition!
```
"""))
````

解析后的 Markdown 被集成到更广泛的文档中,因此可以包含内部引用,例如:

display(Markdown('**_some_ markdown** and an [internal reference](render/output/markdown)!'))
display(Markdown("""
| a | b | c |
|---|---|---|
| 1 | 2 | 3 |
"""))
display(Markdown("""
```{note}
A note admonition!
```
"""))

some markdown and an internal reference!

a

b

c

1

2

3

备注

A note admonition!

ANSI 输出#

默认情况下,标准输出/错误流和 text/plain MIME 输出可能包含 ANSI 转义序列,以更改文本和背景颜色。

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!

这使用了内置的 AnsiColorLexer pygments 词法分析器。您可以在 conf.py 中更改使用的词法分析器,例如关闭词法分析:

nb_render_text_lexer = "none"

以下代码[1] 显示了它所基于的 8 种基本 ANSI 颜色。每种颜色都有“强烈”变体,用于粗体文本。

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 

备注

ANSI 还支持一组 256 种索引颜色。目前不支持此功能,但希望在以后引入它(如果您需要,请在存储库上提出问题!)。

自定义渲染过程#

渲染过程由 NbElementRenderer 的子类控制,这些子类规定了如何为笔记本元素创建 docutils AST 节点。

实现通过 Python 入口点 加载,位于 myst_nb.renderers 组中。因此,可以注入您自己的子类以完全覆盖渲染。

例如,此包中加载的渲染器是:

[project.entry-points."myst_nb.renderers"]
default = "myst_nb.core.render:NbElementRenderer"

然后,您可以在 conf.py 中选择渲染器插件:

nb_render_plugin = "default"

插件还可以覆盖特定输出 MIME 类型的渲染,使用 myst_nb.mime_renderers 入口点组来提供具有签名的函数:MimeRenderPlugin

例如 myst_nb.core.render.ExampleMimeRenderPlugin,在此包中加载:

[project.entry-points."myst_nb.mime_renderers"]
example = "myst_nb.core.render:ExampleMimeRenderPlugin"

这意味着现在可以在所有输出格式中渲染 custommimetype

from IPython.display import display
display({"custommimetype": "Some text"}, raw=True)

This is a custom mime type, with content: 'Some text'