为 nbconvert 创建自定义模板
选择模板
nbconvert的大多数导出器都是TemplateExporter的子类,使用jinja把笔记本渲染为目标格式。
可以在命令行中使用--template选项,按名称选择其他nbconvert模板。例如,通过HTML导出器使用reveal模板,可以输入:
jupyter nbconvert <path-to-notebook> --to html --template reveal
nbconvert 模板安装在哪里?
nbconvert模板是包含模板导出器所需资源的目录,例如Jinja模板和相关静态资源。模板安装在nbconvert的数据目录,即<installation prefix>/share/jupyter/nbconvert。nbconvert已经内置了若干模板。
例如,nbconvert核心为HTML导出器提供了三个HTML模板:
lab:默认HTML模板,生成与JupyterLab相同的DOM结构。
classic:采用经典Notebook样式的HTML模板。
reveal:用于生成幻灯片。
注意
运行jupyter --paths会显示所有Jupyter目录和搜索路径。
例如,在Linux上,jupyter --paths返回:
$ jupyter --paths
config:
/home/<username>/.jupyter
/<sys-prefix>/etc/jupyter
/usr/local/etc/jupyter
/etc/jupyter
data:
/home/<username>/.local/share/jupyter
/<sys-prefix>/share/jupyter
/usr/local/share/jupyter
/usr/share/jupyter
runtime:
/home/<username>/.local/share/jupyter/runtime
添加额外的模板搜索路径
要增加搜索路径,应通过TemplateExporter.extra_template_basedirs配置项指定额外的模板目录。不要覆盖TemplateExporter.template_paths,除非你确实希望替换全部路径,并且不再包含默认位置。
使用命令行时,通过--TemplateExporter.extra_template_basedirs=path/you/want/included增加模板搜索路径。
nbconvert 模板的内容
conf.json
所有nbconvert模板的根目录都包含conf.json文件,用于指定:
所继承的基础模板。
模板支持的MIME类型。
使用该模板时,需要在导出器中注册的预处理器类。
查看reveal模板的配置,可以看到它继承lab模板、导出text/html,并启用名为“100-pygments”和“500-reveal”的两个预处理器。
{
"base_template": "lab",
"mimetypes": {
"text/html": true
},
"preprocessors": {
"100-pygments": {
"type": "nbconvert.preprocessors.CSSHTMLHeaderPreprocessor",
"enabled": true
},
"500-reveal": {
"type": "nbconvert.exporters.slides._RevealMetadataPreprocessor",
"enabled": true
}
}
}
继承
nbconvert会沿着conf.json确定的继承结构向上遍历,合并已注册预处理器的字典,生成汇总配置。预处理器按名称的字典序排序,这决定了执行顺序。
除了conf.json,nbconvert模板通常还包含Jinja模板文件;派生模板也可以覆盖基础模板中的任何其他资源。
例如,查看share/jupyter/nbconvert/templates/目录中的classic模板,可以看到以下内容:classic
share/jupyter/nbconvert/templates/classic
├── static
│ └── styles.css
├── conf.json
├── index.html.j2
└── base.html.j2
classic模板导出器包含Jinja模板index.html.j2(HTML导出器的主入口)、CSS文件,以及base.html.j2基础模板。
注意
继承classic的模板会指定"base_template": "classic",并可以覆盖其中任何文件。例如,仅提供替代的styles.css,就能创建一个“classiker”模板。
Jinja 中的继承
在nbconvert中,Jinja模板可以按名称继承当前目录或基础模板目录中可用的其他Jinja模板。其他目录的Jinja模板,则可以通过相对于Jupyter数据目录的路径来引用。
例如,reveal模板中的index.html.j2继承同目录的base.html.j2,而base.html.j2继承lab/base.html.j2。这样可以使用其他模板中已有的内容,也可以在当前模板中覆盖这些内容。
一个实际示例
假设你希望修改现有Markdown模板,把每段输出包裹在围栏代码块中:
```output
(1, 2, 3)
```
先新建一个模板目录,例如mdoutput,并在其中放置以下文件:
conf.json
index.md.j2
配置文件conf.json声明此模板用于Markdown文件:
{
"mimetypes": {
"text/markdown": true
}
}
模板入口index.md.j2继承现有Markdown模板,并重新定义输出块的渲染方式:
{% extends 'markdown/index.md.j2' %}
{%- block traceback_line -%}
```output
{{ line.rstrip() | strip_ansi }}
```
{%- endblock traceback_line -%}
{%- block stream -%}
```output
{{ output.text.rstrip() }}
```
{%- endblock stream -%}
{%- block data_text scoped -%}
```output
{{ output.data['text/plain'].rstrip() }}
```
{%- endblock data_text -%}
现在可以使用新模板把笔记本转换为Markdown:
jupyter nbconvert --execute notebook.ipynb --to markdown --template=mdoutput
如果模板目录与笔记本不在同一位置,记得添加--TemplateExporter.extra_template_basedirs=path/to/template/parent。
要进一步探索模板的能力,可以查看所有模板的根模板null.j2。它位于jupyter --paths列出的某个数据路径下的./nbconvert/templates/base子目录中。











暂无评论内容