如何在Jupyter / JupyterLab笔记本中添加目录?

201
该文档http://ipython.org/ipython-doc/stable/interactive/notebook.html说:

您可以使用不同级别的标题为整个计算文档提供概念结构;有6个级别可用,从级别1(顶级)到级别6(段落)。这些以后可以用于构建目录等。

但是,我找不到任何关于如何使用我的分层标题来创建这样的目录的说明。是否有办法做到这一点?

NB:如果存在任何其他类型的导航,我也会对使用ipython笔记本电脑标题进行跳转和查找每个部分的开头,或隐藏(折叠)整个部分内容等感兴趣。这是我的愿望清单-但任何形式的导航都将很有意义。谢谢!


1
请参考@Nikolay的答案,这是一个适用于所有网页的通用解决方案。这是一个很好的答案。 - ihightower
为了补充现有的Jupyter笔记本解决方案,我在下面添加了JupyterLab说明 - joelostblom
12个回答

165

您可以使用Markdown和HTML手动添加目录。以下是我的添加方式:

在Jupyter笔记本的顶部创建目录:

## TOC:
* [First Bullet Header](#first-bullet)
* [Second Bullet Header](#second-bullet)

在正文中添加HTML锚点:

## First Bullet Header <a class="anchor" id="first-bullet"></a>

code blocks...

## Second Bullet Header <a class="anchor" id="second-bullet"></a>

code blocks...

可能不是最好的方法,但它能够起作用。


18
这个方法对我不再起作用了,但是a类似的方法可以 - joelostblom
5
同样的“类似方法”也可以参考这个链接:https://dev59.com/KG435IYBdhLWcg3wmxXz#7335259 简而言之,使用 <a name="pookie"></a> 来创建锚点,然后在链接中使用 [pookie](#pookie) 的方式来链接到该锚点。 - michael
7
对于你的markdown文档中的所有标题,笔记本会自动添加锚点。当你将鼠标悬停在标题上时,你可以点击右侧的段落标记符号(¶),来显示浏览器地址栏中的锚点。你可以使用这个锚点而不是手动添加锚点到你的markdown的各个部分。另外最好的一点是它可以跨越多个单元格工作。 - aaruja
3
我有这个脚本 add_toc.py,它会在顶部添加一个包含目录列表的 Markdown 单元格。如果你不想安装扩展,这是一个简单易行的替代方案。 - user2148414

73

JupyterLab ToC说明

对于这个问题,已经有很多很好的答案,但它们通常需要调整才能正确地与JupyterLab中的笔记本一起使用。我写这篇答案是为了详细介绍在JupyterLab中工作并导出时包含ToC的可能方法。

作为侧边栏

jupyterlab-toc扩展程序将ToC添加为侧边栏,可以对标题进行编号、折叠部分并用于导航(请参见下面的gif演示)。此扩展程序从JupyterLab 3.0开始默认包含,在旧版本中,您可以使用以下命令进行安装。

jupyter labextension install @jupyterlab/toc

输入图像描述


在笔记本中作为单元格

目前而言,这可以手动完成,如Matt Dancho的答案中所述,也可以通过经典笔记本界面中的toc2 jupyter笔记本扩展自动完成。

首先,请将toc2作为jupyter_contrib_nbextensions捆绑包的一部分进行安装:

conda install -c conda-forge jupyter_contrib_nbextensions

然后, 启动JupyterLab, 转到Help --> Launch Classic Notebook, 并打开您想要添加ToC的笔记本。 单击工具栏中的toc2符号 弹出ToC窗口 (如果找不到,请参见下面的gif), 单击齿轮图标,选中 “Add notebook ToC cell”的框。 保存笔记本电脑,打开它时将会有ToC单元格 在JupyterLab中。 插入的单元格是一个带有html的标记单元格, 它不会自动更新。

toc2的默认选项 可以在“Nbextensions”选项卡中进行配置 在传统笔记本电脑启动页面上。 例如,您可以选择编号标题 并将ToC固定为侧边栏 (我个人认为看起来更干净)。

输入图像说明文字


在导出的HTML文件中

nbconvert可用于将笔记本导出为HTML 遵循如何格式化导出的HTML规则。 上面提到的toc2扩展添加了一个导出格式叫做html_toc, 可以直接使用nbconvert命令行进行操作 (安装了toc2扩展之后):

jupyter nbconvert file.ipynb --to html_toc
# Append `--ExtractOutputPreprocessor.enabled=False`
# to get a single html file instead of a separate directory for images

请记住,可以在笔记本单元格前面加上感叹号!将Shell命令添加到笔记本单元格中, 因此您可以将此行代码粘贴到笔记本的最后一个单元格中, 每次运行所有单元格时都会生成一个具有目录的HTML文件, 或者您可以从nbconvert获得所需的任何输出方式。 这样,您可以在工作时使用jupyterlab-toc浏览笔记本,并且仍然可以在导出的输出中获得目录,而无需使用经典笔记本界面(对于我们中的纯粹主义者)。

请注意,按照上述描述配置默认的toc2选项不会更改nbconver --to html_toc的格式。 您需要在经典笔记本界面中打开笔记本,以便将元数据写入.ipynb文件(nbconvert在导出时读取元数据)。 或者,您可以通过JupyterLab侧边栏的Notebook工具选项卡手动添加元数据,例如:

    "toc": {
        "number_sections": false,
        "sideBar": true
    }

如果你更喜欢图形用户界面的方式,你应该能够打开传统笔记本,并点击文件-->保存为HTML(带有ToC)(尽管请注意这个菜单项对我来说不可用)。


上述gif来自各自扩展的文档链接。


1
我更喜欢使用jupyter lab,但需要将TOC添加到大型笔记本HTML输出中。 这个方法完美无缺! 有一些额外的步骤来使其正常工作:1. 启用TOC2,例如conda install -c conda-forge jupyter_nbextensions_configurator,进入 http://localhost:8888/nbextensions, 取消选中“兼容性”并启用“Toc2” 2. 启动经典Notebbok,根据您的需求修改TOC设置并Add TOC to Cell(按照说明进行)。 3. 打开您的.ipynb文件并搜索“toc”,复制JSON toc配置并使用Jupyter lab的工具选项卡添加到元数据中。 - Alex
我无法在经典笔记本中使用toc2扩展来添加TOC单元。但是,使用nbconvert“--to html_toc”导出笔记本可以解决此问题。该格式非常好,并在侧边栏上添加了漂亮的TOC和标题编号。 - aimfeld
非常好!花了我一些时间才找到配置导出HTML的嵌套部分数量的字段名称,所以我在这里留下它:"toc_threshold: "6""threshold": "6",具体取决于您的版本。将其添加到“toc”部分中。 - Bastian
1
另外,为了使其与nbconvert配合使用,我不得不将其降级:conda install "nbconvert=5.6.1" - Bastian
这个也有问题,我更新了我的Jupyter Lab,然后它就可以工作了。 - Sam

64

有一个IPython nbextension,可以为笔记本构建目录。它似乎只提供导航功能,而不支持章节折叠。


谢谢,我认为这就是文档所指的内容。 - user2428107
2
对于想要在jupyter 4中安装它的人,这篇文章可能会有所帮助。 - Syrtis Major
12
更新一下:现在有一个nbextensions扩展程序,它打包了许多扩展程序,并允许您通过jupyter自身来管理它们。我认为这是获得ToC2最简单的方法。它还提供其他相关扩展程序,如章节折叠。它位于https://github.com/ipython-contrib/jupyter_contrib_nbextensions。 - user2428107

40

1
这对于与他人共享的笔记本非常有用! - rerx
2
如果您正在使用Jupyter Lab(而不是Notebook)并希望使用此JS选项,请按照此问题中的指南使其正常工作(README页面上的信息对于Lab无效):https://github.com/kmahelona/ipython_notebook_goodies/issues/6#issue-462642204 - Haskan

30

3
非常有帮助!但是一些内置功能会更加合理 - 特别是与Markdown结合使用。 - dmeu
1
我最喜欢的答案 - Code42
1
惊人的聪明! - Oleg
1
这是Firefox插件的另一种选择:https://addons.mozilla.org/zh-CN/firefox/addon/smart_toc/ - creanion

23

我最近为 Jupyter 创建了一个小扩展,名为 jupyter-navbar。它会搜索 markdown 单元格中编写的标题,并以分层方式在侧边栏中显示链接。该侧边栏可调整大小和折叠。请参见以下截图。

它易于安装,并利用“自定义”JS和CSS代码,在打开笔记本时执行,因此您不需要手动运行它。

输入图片说明


2
确实很容易安装,源代码也很友好。不错的项目! - Carson
1
谢谢!非常好的工作,这是我期待目录的最佳解决方案。我必须说,nbextensions 对我有用,直到我的笔记本变得越来越大,你的解决方案,正如我所说,是完美的,而且简单。再次感谢您出色的工作。 - pabloverd
1
哇,这太棒了,谢谢你的礼物。愿恩典照耀着你。 - clancy
太棒了。如果Jupyter内置了这样的功能就太好了。 - Bryan P
喜欢它,安装和使用非常简单。 - Pedro Alonso
太棒了!在我放弃toc2之后,成功安装了jupyter-navbar。 - trvjbr

22

nbextensions ToC使用说明

介绍

正如@Ian和@Sergey所提到的,nbextensions是一个简单的解决方案。为了详细说明他们的答案,这里提供更多信息。

什么是nbextensions?

nbextensions包含一系列扩展程序, 可为Jupyter笔记本添加功能。

例如,只列举几个扩展:

  • 目录

  • 折叠式标题

安装nbextensions

可以通过Conda或PIP进行安装。

# If conda:
conda install -c conda-forge jupyter_contrib_nbextensions
# or with pip:
pip install jupyter_contrib_nbextensions

您将在jupyter笔记本菜单中看到新标签Nbextensions。取消顶部的复选框disable configuration for nbextensions without explicit compatibility(它们可能会破坏您的笔记本环境,但对于nbextension开发很有用),然后选中Table of Contents(2)。就这样了。截图:

choice of "Table of Contents(2)" in Configurable nbextensions

复制js和css文件

要将nbextensions的javascript和css文件复制到jupyter服务器的搜索目录中,请执行以下操作:

jupyter contrib nbextension install --user

切换扩展

请注意,如果您不熟悉终端,最好安装nbextensions配置器(请参见下一节)

您可以启用/禁用所选的扩展。正如文档所提到的,通用命令是:

jupyter nbextension enable <nbextension require path>

具体来说,要启用目录(Table of Contents)扩展,请执行以下操作:

jupyter nbextension enable toc2/main

安装配置界面(可选,但有用)

如其文档所述,nbextensions_configurator为nbextensions提供了配置界面。

它的外观如下: nbextensions configurators

如果您使用conda,则可以执行以下命令进行安装:

conda install -c conda-forge jupyter_nbextensions_configurator

如果您没有安装Conda或不想通过Conda安装,则执行以下两个步骤:

pip install jupyter_nbextensions_configurator
jupyter nbextensions_configurator enable --user

2
这是一个非常好的和详细的答案。我猜启用 toc2/main 就相当于在 http://localhost:8888/tree#nbextensions_configurator 上勾选 "Table of Contents (2)"。 - flow2k

17
现在有两个包可以用来处理 Jupyter 扩展:
  1. jupyter_contrib_nbextensions 安装扩展,包括目录;

  2. jupyter_nbextensions_configurator 提供图形用户界面,用于配置哪些 nbextensions 被启用(自动为每个笔记本加载),并提供控件以配置 nbextensions 的选项。

更新:
从最新版本的 jupyter_contrib_nbextensions 开始,在使用 conda 时,您不需要安装 jupyter_nbextensions_configurator,因为它会随着这些扩展一起安装。

1
然后,在选择1)时,请确保启用扩展的使用而无需显式兼容性(取消顶部的复选框)。然后选择“目录(2)”。请参阅@KeyMaker00的答案中的详细信息。 - questionto42

14

简单的Markdown解决方案

您可以使用Markdown超链接跳转到Markdown标题,而无需定义HTML标签。无论标题中有多少个井号 #,在超链接中只需使用一个即可。标题中的任何空格都将被替换为连字符-

创建内容表

# Contents
- [Section 1](#Section-1)
- [Section 2](#Section-2)
- [Section 3](#Section-3)

创建标题

# Section 1
## Section 2

您还可以添加一个超链接返回目录。

### Section 3
[top](#Contents)

这与Matt Dancho的答案类似,但我总是觉得html锚点很棘手。


1
非常好的回答!这个很棒的脚本在编写长笔记本的目录时提供了很大的帮助!我们只需要将笔记本作为参数提供给脚本,然后打印目录,以便我们可以将其复制到一个Markdown单元格中。 - Shahrokh Bah
1
如果您将目录的某些部分设置为标题,请确保它们的名称与它们链接到的章节不同。否则,Jupyter 可能会为 TOC 链接和原始标题自动生成相同的 URL。这将是使用所接受答案中的锚标签的情况。 - Sam

5
这是我的方法,虽然有些笨拙,但可以在github上找到:
在第一个笔记本单元中添加导入单元:
from IPythonTOC import IPythonTOC

toc = IPythonTOC()

在导入单元格之后的某个位置,放置 genTOCEntry 单元格,但现在不要运行它:

''' if you called toc.genTOCMarkdownCell before running this cell, 
the title has been set in the class '''

print toc.genTOCEntry()

在genTOCEntry单元格下方,创建一个TOC单元格作为Markdown单元格:
<a id='TOC'></a>

#TOC

在编写笔记本时,在开始新的部分之前,请放置此genTOCMarkdownCell:
with open('TOCMarkdownCell.txt', 'w') as outfile:

    outfile.write(toc.genTOCMarkdownCell('Introduction'))

!cat TOCMarkdownCell.txt

!rm TOCMarkdownCell.txt

将genTOCMarkdownCell移动到笔记本中您想要开始新部分的位置,并将genTOCMarkdownCell的参数设置为您新部分的字符串标题,然后运行它。在其后添加一个markdown单元格,并将genTOCMarkdownCell的输出复制到开始新部分的markdown单元格中。然后转到笔记本顶部附近的genTOCEntry单元格并运行它。例如,如果您将genTOCMarkdownCell的参数设置为上面显示的内容并运行它,则会得到以下输出,可粘贴到新索引部分的第一个markdown单元格中:
<a id='Introduction'></a>

###Introduction

然后,当你到笔记本的顶部并运行genTocEntry时,你会得到以下输出:

[Introduction](#Introduction)

将此链接字符串复制并粘贴到目录的 markdown 单元格中,如下所示:

<a id='TOC'></a>

#TOC

[Introduction](#Introduction)

编辑文档目录(cell)并插入链接字符串后,按下shift-enter键即可在笔记本的目录(Table of Contents)中出现新章节的链接,单击该链接将导航至新章节所在位置。
需要注意的是,单击目录中的某一行会使浏览器跳至该单元格,但不会选择它。无论何时我们单击目录链接时活动单元格仍然是活动状态,所以向下、向上箭头或shift-enter操作仍指示当前活动单元格,而不是我们通过单击目录链接得到的单元格。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接