1

我有一个 Python jupyter notebook,我可以通过命令行成功地将它导出为带有目录的HTML:

$ jupyter nbconvert nb.ipynb --template toc2

我该如何做同样的事情,但以编程方式(通过 API)?

这是我到目前为止所取得的成就:

import os
import nbformat
from nbconvert import HTMLExporter
from nbconvert.preprocessors import ExecutePreprocessor

nb_path = './nb.ipynb'
with open(nb_path) as f:
    nb = nbformat.read(f, as_version=4)

ep = ExecutePreprocessor(kernel_name='python3')
ep.preprocess(nb)
exporter = HTMLExporter()
html, _ = exporter.from_notebook_node(nb)

output_html_file = f"./nb.html"
with open(output_html_file, "w") as f:
    f.write(html)
    f.close()
print(f"Result HTML file: {output_html_file}")

它确实成功导出了 HTML;但是没有目录。我不知道如何--template toc2通过 API 设置。

4

2 回答 2

2

我找到了两种方法来做到这一点:

最忠实再现的方式$ jupyter nbconvert nb.ipynb --template toc2 涉及使用模板文件设置HTMLExporter().template_file属性。toc2.tpl

  • 主要技巧是找到此文件在您的系统上的位置。对我来说是<base filepath>/Anaconda3/Lib/site-packages/jupyter_contrib_nbextensions/templates/toc2.tpl
  • 完整代码如下:
from nbconvert import HTMLExporter
from nbconvert.writers import FilesWriter
import nbformat
from pathlib import Path

input_notebook = "My_notebook.ipynb"
output_html ="My_notebook"
toc2_tpl_path = "<base filepath>/Anaconda3/Lib/site-packages/jupyter_contrib_nbextensions/templates/toc2.tpl"

notebook_node = nbformat.read(input_notebook, as_version=4)

exporter = HTMLExporter()
exporter.template_file = toc2_tpl_path # THIS IS THE CRITICAL LINE

(body, resources) = exporter.from_notebook_node(notebook_node)

write_file = FilesWriter()
write_file.write(
    output=body,
    resources=resources,
    notebook_name=output_html
)

另一种方法是使用模块TocExporter中的类nbconvert_support,而不是HTMLExporter.

  • 但是,这模仿了命令行表达式jupyter nbconvert --to html_toc nb.ipynb,而不是设置标准 HTML 导出方法的模板
  • 这种方法的主要问题是似乎没有办法用这种方法嵌入图形,这是上面基于模板的方法的默认值
  • 但是,如果图形嵌入无关紧要,则此解决方案在不同系统之间更加灵活,因为您不必跟踪不同的文件路径toc2.tpl
  • 下面是一个例子:
from nbconvert import HTMLExporter
from nbconvert.writers import FilesWriter
import nbformat
from pathlib import Path
from jupyter_contrib_nbextensions.nbconvert_support import TocExporter # CRITICAL MODULE

input_notebook = "My_notebook.ipynb"
output_html ="My_notebook"

notebook_node = nbformat.read(input_notebook, as_version=4)

exporter = TocExporter() # CRITICAL LINE

(body, resources) = exporter.from_notebook_node(notebook_node)

write_file = FilesWriter()
write_file.write(
    output=body,
    resources=resources,
    notebook_name=output_html
)

作为最后一点,我想向遇到此答案的其他人提及我这样做的动机。我使用的其中一台机器使用 Windows,因此要让命令提示符运行 jupyter 命令需要对 Windows PATH 环境进行一些处理,这让我很头疼。我可以通过使用 Anaconda 提示符来解决这个问题,但这需要打开提示符并每次都输入完整的命令。我可以尝试使用 编写脚本os.system(),但这会调用默认命令行(Windows 命令提示符)而不是 Anaconda 提示符。上面的方法允许我通过在任何笔记本中运行一个简单的 python 脚本,将 Jupyter 笔记本转换为带有 TOC 和嵌入式图形的 HTML。

于 2020-10-17T19:49:35.843 回答
0

这在文档中并不清楚,但是该类的构造函数TemplateExporter提到了以下内容:

template_file : str (optional, kw arg)
导出时使用的模板。

经过测试,我可以确认您需要做的就是将文件路径添加到此参数下的模板文件中为您的导出器。

HTMLExporter(template_file=path_to_template_file)
于 2020-07-09T13:34:14.797 回答