Jupyter Notebook Tools for Sphinx

nbsphinx is a Sphinx extension that provides a source parser for *.ipynb files. Custom Sphinx directives are used to show Jupyter Notebook code cells (and of course their results) in both HTML and LaTeX output. Un-evaluated notebooks – i.e. notebooks without stored output cells – will be automatically executed during the Sphinx build process.

Quick Start:
  1. Install nbsphinx

  2. Edit your conf.py and add 'nbsphinx' to extensions.

  3. Edit your index.rst and add the names of your *.ipynb files to the toctree.

  4. Run Sphinx!

Online documentation (and example of use):

http://nbsphinx.readthedocs.io/

Source code repository (and issue tracker):

https://github.com/spatialaudio/nbsphinx/

License:

MIT – see the file LICENSE for details.

All content shown below – except for the sections Normal reStructuredText Files, Contributing and Version History – was generated from Jupyter notebooks.

This page was generated from doc/installation.ipynb. Interactive online version: Binder badge.

Installation

Note that some packages may be out of date. You can always get the newest nbsphinx release from PyPI (using pip). If you want to try the latest development version, have a look at the section Contributing.

nbsphinx Packages

Anaconda Badge

If you are using the conda package manager (e.g. with Anaconda for Linux/macOS/Windows), you can install nbsphinx from the conda-forge channel:

conda install -c conda-forge nbsphinx

If you are using Linux, there are packages available for many distributions.

Packaging status

PyPI version

On any platform, you can also install nbsphinx with pip, Python’s own package manager:

python3 -m pip install nbsphinx --user

If you want to install it system-wide for all users (assuming you have the necessary rights), just drop the --user flag.

To upgrade an existing nbsphinx installation to the newest release, use the --upgrade flag:

python3 -m pip install nbsphinx --upgrade --user

If you suddenly change your mind, you can un-install it with:

python3 -m pip uninstall nbsphinx

Depending on your Python installation, you may have to use python instead of python3.

nbsphinx Prerequisites

Some of the aforementioned packages will install some of these prerequisites automatically, some of the things may be already installed on your computer anyway.

Python

Of course you’ll need Python, because both Sphinx and nbsphinx are implemented in Python. There are many ways to get Python. If you don’t know which one is best for you, you can try Anaconda.

Sphinx

You’ll need Sphinx as well, because nbsphinx is just a Sphinx extension and doesn’t do anything on its own.

If you use conda, you can get Sphinx from the conda-forge channel:

conda install -c conda-forge sphinx

Alternatively, you can install it with pip (see below):

python3 -m pip install Sphinx --user

pip

Recent versions of Python already come with pip pre-installed. If you don’t have it, you can install it manually.

pandoc

The stand-alone program pandoc is used to convert Markdown content to something Sphinx can understand. You have to install this program separately, ideally with your package manager. If you are using conda, you can install pandoc from the conda-forge channel:

conda install -c conda-forge pandoc

If that doesn’t work out for you, have a look at pandoc’s installation instructions.

Note

The use of pandoc in nbsphinx is temporary, but will likely stay that way for a long time, see issue #36.

Pygments Lexer for Syntax Highlighting

To get proper syntax highlighting in code cells, you’ll need an appropriate Pygments lexer. This of course depends on the programming language of your Jupyter notebooks (more specifically, the pygments_lexer metadata of your notebooks).

For example, if you use Python in your notebooks, you’ll have to have the IPython package installed, e.g. with

conda install -c conda-forge ipython

or

python3 -m pip install IPython --user

Note

If you are using Anaconda with the default channel and syntax highlighting in code cells doesn’t seem to work, you can try to install IPython from the conda-forge channel or directly with pip, or as a work-around, add 'IPython.sphinxext.ipython_console_highlighting' to extensions in your conf.py.

For details, see Anaconda issue #1430 and nbsphinx issue #24.

Jupyter Kernel

If you want to execute your notebooks during the Sphinx build process (see Controlling Notebook Execution), you need an appropriate Jupyter kernel installed.

For example, if you use Python, you should install the ipykernel package, e.g. with

conda install -c conda-forge ipykernel

or

python3 -m pip install ipykernel --user

If you created your notebooks yourself with Jupyter, it’s very likely that you have the right kernel installed already.

This page was generated from doc/usage.ipynb. Interactive online version: Binder badge.

Usage

Sphinx Setup

In the directory with your notebook files, run this command (assuming you have Sphinx installed already):

python3 -m sphinx.cmd.quickstart

Answer the questions that appear on the screen. In case of doubt, just press the <Return> key repeatedly to take the default values.

After that, there will be a few brand-new files in the current directory. You’ll have to make a few changes to the file named conf.py. You should at least check if this variable contains the right things:

extensions = [
    'nbsphinx',
    'sphinx.ext.mathjax',
]

For an example, see this project’s conf.py file.

Once your conf.py is in place, edit the file named index.rst and add the file names of your notebooks (without the .ipynb extension) to the toctree directive. For an example, see this project’s doc/index.rst file.

Alternatively, you can delete the file index.rst and replace it with your own notebook called index.ipynb which will serve as main page. In this case you can create the main toctree in index.ipynb.

Sphinx Configuration Values

All configuration values are described in the Sphinx documentation, here we mention only the ones which may be relevant in combination with nbsphinx.

exclude_patterns

Sphinx builds all potential source files (reST files, Jupyter notebooks, …) that are in the source directory (including any sub-directories), whether you want to use them or not. If you want certain source files not to be built, specify them in exclude_patterns. For example, you might want to ignore source files in your build directory:

exclude_patterns = ['_build']

Note that the directory .ipynb_checkpoints is automatically added to exclude_patterns by nbsphinx.

extensions

This is the only required value. You have to add 'nbsphinx' to the list of extensions, otherwise it won’t work.

Other interesting extensions are:

highlight_language

Default language for syntax highlighting in reST and Markdown cells, when no language is specified explicitly.

By default, this is 'python3', while Jupyter doesn’t have a default language. Set highlight_language to 'none' to get the same behavior as in Jupyter:

highlight_language = 'none'

See also nbsphinx_codecell_lexer.

html_css_files

See Custom CSS and html_css_files.

latex_additional_files

latex_additional_files can be useful if you are using BibTeX files, see References.

mathjax_config

The configuration value mathjax_config can be useful to enable Automatic Equation Numbering.

suppress_warnings

Warnings can be really helpful to detect small mistakes, and you should consider invoking Sphinx with the -W option, which turns warnings into errors. However, warnings can also be annoying, especially if you are fully aware of the “problem”, but you simply don’t care about it for some reason. In this case, you can use suppress_warnings to silence specific types of warnings.

If you want to suppress all warnings from nbsphinx, use this:

suppress_warnings = [
    'nbsphinx',
]

You can also be more specific:

suppress_warnings = [
    'nbsphinx.localfile',
    'nbsphinx.gallery',
    'nbsphinx.thumbnail',
    'nbsphinx.notebooktitle',
    'nbsphinx.ipywidgets',
]

nbsphinx Configuration Values

nbsphinx_allow_errors

If True, the build process is continued even if an exception occurs.

See Ignoring Errors.

nbsphinx_codecell_lexer

Default Pygments lexer for syntax highlighting in code cells. If available, this information is taken from the notebook metadata instead.

Please note that this is not the same as highlight_language, which is used for formatting code in Markdown cells!

nbsphinx_custom_formats

See Custom Notebook Formats.

nbsphinx_epilog

See Prolog and Epilog.

nbsphinx_execute

Whether to execute notebooks before conversion or not. Possible values: 'always', 'never', 'auto' (default).

See Explicitly Dis-/Enabling Notebook Execution.

nbsphinx_execute_arguments

Kernel arguments used when executing notebooks.

If you use Matplotlib for plots, this setting is recommended:

nbsphinx_execute_arguments = [
    "--InlineBackend.figure_formats={'svg', 'pdf'}",
    "--InlineBackend.rc={'figure.dpi': 96}",
]

If you don’t use LaTeX/PDF output, you can drop the 'pdf' figure format.

See Configuring the Kernels.

nbsphinx_input_prompt

Input prompt for code cells. %s is replaced by the execution count.

To get a prompt similar to the Classic Notebook, use

nbsphinx_input_prompt = 'In [%s]:'
nbsphinx_kernel_name

Use a different kernel than stored in the notebook metadata, e.g.:

nbsphinx_kernel_name = 'python3'

See Configuring the Kernels.

nbsphinx_output_prompt

Output prompt for code cells. %s is replaced by the execution count.

To get a prompt similar to the Classic Notebook, use

nbsphinx_output_prompt = 'Out[%s]:'
nbsphinx_prolog

See Prolog and Epilog.

nbsphinx_prompt_width

Width of input/output prompts (HTML only).

If a prompt is wider than that, it protrudes into the left margin.

Any CSS length can be specified.

nbsphinx_requirejs_options

Options for loading RequireJS. See nbsphinx_requirejs_path.

nbsphinx_requirejs_path

URL or local path to override the default URL for RequireJS.

If you use a local file, it should be located in a directory listed in html_static_path.

Set to empty string to disable loading RequireJS.

nbsphinx_responsive_width

If the browser window is narrower than this, input/output prompts are on separate lines (HTML only).

Any CSS length can be specified.

nbsphinx_thumbnails

A dictionary mapping from a document name (i.e. source file without suffix but with subdirectories) – optionally containing wildcards – to a thumbnail path to be used in a thumbnail gallery.

See Specifying Thumbnails.

nbsphinx_timeout

Controls when a cell will time out. The timeout is given in seconds. Given -1, cells will never time out, which is also the default.

See Cell Execution Timeout.

nbsphinx_widgets_options

Options for loading Jupyter widgets resources. See nbsphinx_widgets_path.

nbsphinx_widgets_path

URL or local path to override the default URL for Jupyter widgets resources. See Interactive Widgets (HTML only).

If you use a local file, it should be located in a directory listed in html_static_path.

For loading the widgets resources, RequireJS is needed, see nbsphinx_requirejs_path.

If nbsphinx_widgets_path is not specified, widgets resources are only loaded if at least one notebook actually uses widgets. If you are loading the relevant JavaScript code by some other means already, you can set this option to the empty string to avoid loading it a second time.

Running Sphinx

To create the HTML pages, use this command:

python3 -m sphinx <source-dir> <build-dir>

If you have many notebooks, you can do a parallel build by using the -j option:

python3 -m sphinx <source-dir> <build-dir> -j<number-of-processes>

For example, if your source files are in the current directory and you have 4 CPU cores, you can run this:

python3 -m sphinx . _build -j4

Afterwards, you can find the main HTML file in _build/index.html.

Subsequent builds will be faster, because only those source files which have changed will be re-built. To force re-building all source files, use the -E option.

Note

By default, notebooks will be executed during the Sphinx build process only if they do not have any output cells stored. See Controlling Notebook Execution.

To create LaTeX output, use:

python3 -m sphinx <source-dir> <build-dir> -b latex

If you don’t know how to create a PDF file from the LaTeX output, you should have a look at Latexmk (see also this tutorial).

Sphinx can automatically check if the links you are using are still valid. Just invoke it like this:

python3 -m sphinx <source-dir> <build-dir> -b linkcheck

Watching for Changes with sphinx-autobuild

If you think it’s tedious to run the Sphinx build command again and again while you make changes to your notebooks, you’ll be happy to hear that there is a way to avoid that: sphinx-autobuild!

It can be installed with

python3 -m pip install sphinx-autobuild --user

You can start auto-building your files with

python3 -m sphinx_autobuild <source-dir> <build-dir>

This will start a local webserver which will serve the generated HTML pages at http://localhost:8000/. Whenever you save changes in one of your notebooks, the appropriate HTML page(s) will be re-built and when finished, your browser view will be refreshed automagically. Neat!

You can also abuse this to auto-build the LaTeX output:

python3 -m sphinx_autobuild <source-dir> <build-dir> -b latex

However, to auto-build the final PDF file as well, you’ll need an additional tool. Again, you can use latexmk for this (see above). Change to the build directory and run

latexmk -pdf -pvc

If your PDF viewer isn’t opened because of LaTeX build errors, you can use the command line flag -f to force creating a PDF file.

Automatic Creation of HTML and PDF output on readthedocs.org

There are two different methods, both of which are described below.

In both cases, you’ll first have to create an account on https://readthedocs.org/ and connect your GitLab/Github/Bitbucket/… account. Instead of connecting, you can also manually add any publicly available Git/Subversion/Mercurial/Bazaar/… repository.

After doing the steps described below, you only have to “push” to your repository, and the HTML pages and the PDF file of your stuff are automagically created on readthedocs.org. Awesome!

You can even have different versions of your stuff, just use Git tags and branches and select in the readthedocs.org settings which of those should be created.

Note

If you want to execute notebooks (see Controlling Notebook Execution), you’ll need to install the appropriate Jupyter kernel. In the examples below, the IPython kernel is installed from the packet ipykernel.

Using requirements.txt

  1. Create a file named .readthedocs.yml in the main directory of your repository with the following contents:

    version: 2
    formats: all
    python:
      version: 3
      install:
        - requirements: doc/requirements.txt
      system_packages: true
    

    For further options see https://docs.readthedocs.io/en/latest/config-file/.

  2. Create a file named doc/requirements.txt (or whatever you chose in the previous step) containing the required pip packages:

    ipykernel
    nbsphinx
    

    You can also install directly from Github et al., using a specific branch/tag/commit, e.g.

    git+https://github.com/spatialaudio/nbsphinx.git@master
    

Using conda

  1. Create a file named .readthedocs.yml in the main directory of your repository with the following contents:

    version: 2
    formats: all
    conda:
      file: doc/environment.yml
    

    For further options see https://docs.readthedocs.io/en/latest/config-file/.

  2. Create a file named doc/environment.yml (or whatever you chose in the previous step) describing a conda environment like this:

    channels:
      - conda-forge
    dependencies:
      - python>=3
      - pandoc
      - ipykernel
      - pip
      - pip:
        - nbsphinx
    

    It is up to you if you want to install nbsphinx with conda or with pip (but note that the conda package might be outdated). And you can of course add further conda and pip packages. You can also install packages directly from Github et al., using a specific branch/tag/commit, e.g.

    - pip:
      - git+https://github.com/spatialaudio/nbsphinx.git@master
    

Note

The specification of the conda-forge channel is recommended because it tends to have more recent package versions than the default channel.

HTML Themes

The nbsphinx extension does not provide its own theme, you can use any of the available themes or create a custom one, if you feel like it.

The following (incomplete) list of themes contains up to three links for each theme:

  1. The documentation (or the official sample page) of this theme (if available; see also the documentation of the built-in Sphinx themes)

  2. How the nbsphinx documentation looks when using this theme

  3. How to enable this theme using either requirements.txt or readthedocs.yml and theme-specific settings (in some cases)

Sphinx’s Built-In Themes

Using Notebooks with Git

Git is extremely useful for managing source code and it can and should also be used for managing Jupyter notebooks. There is one caveat, however: Notebooks can contain output cells with rich media like images, plots, sounds, HTML, JavaScript and many other types of bulky machine-created content. This can make it hard to work with Git efficiently, because changes in those bulky contents can completely obscure the more interesting human-made changes in text and source code. Working with multiple collaborators on a notebook can become very tedious because of this.

It is therefore highly recommended that you remove all outputs from your notebooks before committing changes to a Git repository (except for the reasons mentioned in Pre-Executing Notebooks).

If there are no output cells in a notebook, nbsphinx will by default execute the notebook, and the pages generated by Sphinx will therefore contain all the output cells. See Controlling Notebook Execution for how this behavior can be customized.

In the Jupyter Notebook application, you can manually clear all outputs by selecting “Cell” \(\to\) “All Output” \(\to\) “Clear” from the menu. In JupyterLab, the menu items are “Edit” \(\to\) “Clear All Outputs”.

There are several tools available to remove outputs from multiple files at once without having to open them separately. You can even include such a tool as “clean/smudge filters” into your Git workflow, which will strip the output cells automatically whenever a Git command is executed. For details, have a look at those links:

This page was generated from doc/markdown-cells.ipynb. Interactive online version: Binder badge.

Markdown Cells

We can use emphasis, boldface, preformatted text.

It looks like strike-out text is not supported: [STRIKEOUT:strikethrough].

  • Red

  • Green

  • Blue


  1. One

  2. Two

  3. Three

Arbitrary Unicode characters should be supported, e.g. łßō. Note, however, that this only works if your HTML browser and your LaTeX processor provide the appropriate fonts.

Equations

Inline equations like \(\text{e}^{i\pi} = -1\) can be created by putting a LaTeX expression between two dollar signs, like this: $\text{e}^{i\pi} = -1$.

Note

Avoid leading and trailing spaces around math expressions, otherwise errors like the following will occur when Sphinx is running:

ERROR: Unknown interpreted text role "raw-latex".

See also the pandoc docs:

Anything between two $ characters will be treated as TeX math. The opening $ must have a non-space character immediately to its right, while the closing $ must have a non-space character immediately to its left, and must not be followed immediately by a digit.

Equations can also be displayed on their own line like this:

\begin{equation} \int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0). \end{equation}

This can be done by simply using one of the LaTeX math environments, like so:

\begin{equation}
\int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)
\end{equation}

Note

For equations to be shown in HTML output, you have to specify a math extension in your extensions setting, e.g.:

extensions = [
    'nbsphinx',
    'sphinx.ext.mathjax',
    # ... other useful extensions ...
]

Automatic Equation Numbering

This is not automatically enabled in Jupyter notebooks, but you can install a notebook extension in order to enable equation numbering: https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/equation-numbering/readme.html.

Automatic Equation Numbering is enabled on https://nbviewer.jupyter.org/, see e.g. the latest version of this very notebook at the link https://nbviewer.jupyter.org/github/spatialaudio/nbsphinx/blob/master/doc/markdown-cells.ipynb#Automatic-Equation-Numbering.

When using nbsphinx, you can use the following mathjax_config setting in your conf.py file to enable automatic equation numbering in HTML output. In LaTeX output, the equations are numbered by default.

mathjax_config = {
    'TeX': {'equationNumbers': {'autoNumber': 'AMS', 'useLabelIds': True}},
}

You can use \label{...} to give a unique label to an equation:

\begin{equation} \phi = \frac{1 + \sqrt{5}}{2} \label{golden-mean} \end{equation}
\begin{equation}
\phi = \frac{1 + \sqrt{5}}{2}
\label{golden-mean}
\end{equation}

If automatic equation numbering is enabled, you can later reference that equation using its label. You can use \eqref{golden-mean} for a reference with parentheses: \eqref{golden-mean}, or \ref{golden-mean} for a reference without them: \ref{golden-mean}.

In HTML output, these equation references only work for equations within a single HTML page. In LaTeX output, equations from other notebooks can be referenced, e.g. \eqref{fibonacci-recurrence}.

Manual Equation Numbering

If you prefer to assign equation numbers (or some kind of names) manually, you can do so with \tag{...}:

\begin{equation} a^2 + b^2 = c^2 \tag{99.4} \label{pythagoras} \end{equation}
\begin{equation}
a^2 + b^2 = c^2
\tag{99.4}
\label{pythagoras}
\end{equation}

The above equation has the number \ref{pythagoras}.

Citations

According to https://nbconvert.readthedocs.io/en/latest/latex_citations.html, nbconvert supports citations using a special HTML-based syntax. nbsphinx supports the same syntax.

Example: [KRKP+16].

<cite data-cite="kluyver2016jupyter">Kluyver et al. (2016)</cite>

You don’t actually have to use <cite>, any inline HTML tag can be used, e.g. <strong>: [PGH11].

<strong data-cite="perez2011python">Python: An Ecosystem for Scientific Computing</strong>

You’ll also have to define a list of references, see the section about references.

There is also a Notebook extension which may or may not be useful: https://github.com/takluyver/cite2c.

Code

We can also write code with nice syntax highlighting:

print("Hello, world!")

Tables

A

B

A and B

False

False

False

True

False

False

False

True

False

True

True

True

Images

Local image: Jupyter notebook icon

![Jupyter notebook icon](images/notebook_icon.png)

Remote image: Python logo (remote)

![Python logo (remote)](https://www.python.org/static/img/python-logo-large.png)

Using the HTML <img> tag

The aforementioned Markdown syntax for including images doesn’t allow specifying the image size.

If you want to control the size of the included image, you can use the HTML <img> element with the width attribute like this:

<img src="images/notebook_icon.png" alt="Jupyter notebook icon" width="300">

Jupyter notebook icon

In addition to the src, alt, width and height attributes, you can also use the class attribute, which is simply forwarded to the HTML output (and ignored in LaTeX output). All other attributes are ignored.

SVG support for LaTeX

LaTeX doesn’t support SVG images, but there are Sphinx extensions that can be used for automatically converting SVG images for inclusion in LaTeX output.

Just include one of the following options in the list of extensions in your conf.py file.

If one of those extensions is installed, SVG images can be used even for LaTeX output:

Python logo

![Python logo](images/python_logo.svg)

Remote SVG images can also be used (and will be shown in the LaTeX output):

Jupyter logo

![Jupyter logo](https://jupyter.org/assets/main-logo.svg)

Cell Attachments

Images can also be embedded in the notebook itself. Just drag an image file into the Markdown cell you are just editing or copy and paste some image data from an image editor/viewer.

The generated Markdown code will look just like a “normal” image link, except that it will have an attachment: prefix:

![a stick figure](attachment:stickfigure.png)

This is a cell attachment: a stick figure

In the Jupyter Notebook, there is a speciall “Attachments” cell toolbar which you can use to see all attachments of a cell and delete them, if needed.

HTML Elements (HTML only)

It is allowed to use plain HTML elements within Markdown cells. Those elements are passed through to the HTML output and are ignored for the LaTeX output. Below are a few examples.

HTML5 audio elements can be created like this:

<audio src="https://example.org/audio.ogg" controls>alternative text</audio>

Example:

HTML5 video elements can be created like this:

<video src="https://example.org/video.ogv" controls>alternative text</video>

Example:

The alternative text is shown in browsers that don’t support those elements. The same text is also shown in Sphinx’s LaTeX output.

Note: You can also use local files for the <audio> and <video> elements, but you have to create a link to the source file somewhere, because only then are the local files copied to the HTML output directory! You should do that anyway to make the audio/video file accessible to browsers that don’t support the <audio> and <video> elements.

Info/Warning Boxes

Warning

This is an experimental feature! Its usage will probably change in the future or it might be removed completely!

Until there is an info/warning extension for Markdown/CommonMark (see this issue), such boxes can be created by using HTML <div> elements like this:

<div class="alert alert-info">

Note

This is a note!

</div>

For this to work reliably, you should obey the following guidelines:

  • The class attribute has to be either "alert alert-info" or "alert alert-warning", other values will not be converted correctly.

  • No further attributes are allowed.

  • For compatibility with CommonMark, you should add an empty line between the <div> start tag and the beginning of the content.

Note

The text can contain further Markdown formatting. It is even possible to have nested boxes:

… but please don’t overuse this!

This page was generated from doc/code-cells.ipynb. Interactive online version: Binder badge.

Code Cells

Code, Output, Streams

An empty code cell:

[ ]:

Two empty lines:

[ ]:


Leading/trailing empty lines:

[1]:


# 2 empty lines before, 1 after

A simple output:

[2]:
6 * 7
[2]:
42

The standard output stream:

[3]:
print('Hello, world!')
Hello, world!

Normal output + standard output

[4]:
print('Hello, world!')
6 * 7
Hello, world!
[4]:
42

The standard error stream is highlighted and displayed just below the code cell. The standard output stream comes afterwards (with no special highlighting). Finally, the “normal” output is displayed.

[5]:
import sys

print("I'll appear on the standard error stream", file=sys.stderr)
print("I'll appear on the standard output stream")
"I'm the 'normal' output"
I'll appear on the standard output stream
I'll appear on the standard error stream
[5]:
"I'm the 'normal' output"

Note

Using the IPython kernel, the order is actually mixed up, see https://github.com/ipython/ipykernel/issues/280.

Cell Magics

IPython can handle code in other languages by means of cell magics:

[6]:
%%bash
for i in 1 2 3
do
    echo $i
done
1
2
3

Special Display Formats

See IPython example notebook.

Local Image Files

[7]:
from IPython.display import Image
i = Image(filename='images/notebook_icon.png')
i
[7]:
_images/code-cells_20_0.png
[8]:
display(i)
_images/code-cells_21_0.png

See also SVG support for LaTeX.

[9]:
from IPython.display import SVG
SVG(filename='images/python_logo.svg')
[9]:
_images/code-cells_23_0.svg

Image URLs

[10]:
Image(url='https://www.python.org/static/img/python-logo-large.png')
[10]:
[11]:
Image(url='https://www.python.org/static/img/python-logo-large.png', embed=True)
[11]:
_images/code-cells_26_0.png
[12]:
Image(url='https://jupyter.org/assets/nav_logo.svg')
[12]:

Math

[13]:
from IPython.display import Math
eq = Math(r'\int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)')
eq
[13]:
$\displaystyle \int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)$
[14]:
display(eq)
$\displaystyle \int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)$
[15]:
from IPython.display import Latex
Latex(r'This is a \LaTeX{} equation: $a^2 + b^2 = c^2$')
[15]:
This is a \LaTeX{} equation: $a^2 + b^2 = c^2$
[16]:
%%latex
\begin{equation}
\int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)
\end{equation}
\begin{equation} \int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0) \end{equation}

Plots

The output formats for Matplotlib plots can be customized. You’ll need separate settings for the Jupyter Notebook application and for nbsphinx.

If you want to use SVG images for Matplotlib plots, add this line to your IPython configuration file:

c.InlineBackend.figure_formats = {'svg'}

If you want SVG images, but also want nice plots when exporting to LaTeX/PDF, you can select:

c.InlineBackend.figure_formats = {'svg', 'pdf'}

If you want to use the default PNG plots or HiDPI plots using 'png2x' (a.k.a. 'retina'), make sure to set this:

c.InlineBackend.rc = {'figure.dpi': 96}

This is needed because the default 'figure.dpi' value of 72 is only valid for the Qt Console.

If you are planning to store your SVG plots as part of your notebooks, you should also have a look at the 'svg.hashsalt' setting.

For more details on these and other settings, have a look at Default Values for Matplotlib’s “inline” Backend.

The configuration file ipython_kernel_config.py can be either in the directory where your notebook is located (see the ipython_kernel_config.py in this directory), or in your profile directory (typically ~/.ipython/profile_default/ipython_kernel_config.py). To find out your IPython profile directory, use this command:

python3 -m IPython profile locate

A local ipython_kernel_config.py in the notebook directory also works on https://mybinder.org/. Alternatively, you can create a file with those settings in a file named .ipython/profile_default/ipython_kernel_config.py in your repository.

To get SVG and PDF plots for nbsphinx, use something like this in your conf.py file:

nbsphinx_execute_arguments = [
    "--InlineBackend.figure_formats={'svg', 'pdf'}",
    "--InlineBackend.rc={'figure.dpi': 96}",
]

In the following example, nbsphinx should use an SVG image in the HTML output and a PDF image for LaTeX/PDF output.

[17]:
import matplotlib.pyplot as plt
[18]:
fig, ax = plt.subplots(figsize=[6, 3])
ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);
_images/code-cells_35_0.svg

Alternatively, the figure format(s) can also be chosen directly in the notebook (which overrides the setting in nbsphinx_execute_arguments and in the IPython configuration):

[19]:
%config InlineBackend.figure_formats = ['png']
[20]:
fig
[20]:
_images/code-cells_38_0.png

If you want to use PNG images, but with HiDPI resolution, use the special 'png2x' (a.k.a. 'retina') format (which also looks nice in the LaTeX output):

[21]:
%config InlineBackend.figure_formats = ['png2x']
[22]:
fig
[22]:
_images/code-cells_41_0.png

Pandas Dataframes

Pandas dataframes should be displayed as nicely formatted HTML tables (if you are using HTML output).

[23]:
import numpy as np
import pandas as pd
[24]:
df = pd.DataFrame(np.random.randint(0, 100, size=[5, 4]),
                  columns=['a', 'b', 'c', 'd'])
df
[24]:
a b c d
0 80 46 59 68
1 24 86 35 0
2 10 52 89 99
3 13 99 17 20
4 96 56 21 30

For LaTeX output, however, the plain text output is used by default.

To get nice LaTeX tables, a few settings have to be changed:

[25]:
pd.set_option('display.latex.repr', True)

This is not enabled by default because of Pandas issue #12182.

The generated LaTeX tables utilize the booktabs package, so you have to make sure that package is loaded in the preamble with:

\usepackage{booktabs}

In order to allow page breaks within tables, you should use:

[26]:
pd.set_option('display.latex.longtable', True)

The longtable package is already used by Sphinx, so you don’t have to manually load it in the preamble.

Finally, if you want to use LaTeX math expressions in your dataframe, you’ll have to disable escaping:

[27]:
pd.set_option('display.latex.escape', False)

The above settings should have no influence on the HTML output, but the LaTeX output should now look nicer:

[28]:
df = pd.DataFrame(np.random.randint(0, 100, size=[10, 4]),
                  columns=[r'$\alpha$', r'$\beta$', r'$\gamma$', r'$\delta$'])
df
[28]:
$\alpha$ $\beta$ $\gamma$ $\delta$
0 30 6 36 82
1 74 95 0 73
2 81 43 50 18
3 18 23 1 94
4 37 58 2 65
5 56 47 38 97
6 20 11 25 61
7 9 73 96 13
8 67 48 8 70
9 51 85 12 10

YouTube Videos

[29]:
from IPython.display import YouTubeVideo
YouTubeVideo('WAikxUGbomY')
[29]:

Interactive Widgets (HTML only)

The basic widget infrastructure is provided by the ipywidgets module. More advanced widgets are available in separate packages, see for example https://jupyter.org/widgets.

The JavaScript code which is needed to display Jupyter widgets is loaded automatically (using RequireJS). If you want to use non-default URLs or local files, you can use the nbsphinx_widgets_path and nbsphinx_requirejs_path settings.

[30]:
import ipywidgets as w
[31]:
slider = w.IntSlider()
slider.value = 42
slider

A widget typically consists of a so-called “model” and a “view” into that model.

If you display a widget multiple times, all instances act as a “view” into the same “model”. That means that their state is synchronized. You can move either one of these sliders to try this out:

[32]:
slider

You can also link different widgets.

Widgets can be linked via the kernel (which of course only works while a kernel is running) or directly in the client (which even works in the rendered HTML pages).

Widgets can be linked uni- or bi-directionally.

Examples for all 4 combinations are shown here:

[33]:
link = w.IntSlider(description='link')
w.link((slider, 'value'), (link, 'value'))
jslink = w.IntSlider(description='jslink')
w.jslink((slider, 'value'), (jslink, 'value'))
dlink = w.IntSlider(description='dlink')
w.dlink((slider, 'value'), (dlink, 'value'))
jsdlink = w.IntSlider(description='jsdlink')
w.jsdlink((slider, 'value'), (jsdlink, 'value'))
w.VBox([link, jslink, dlink, jsdlink])

Other Languages

The examples shown here are using Python, but the widget technology can also be used with different Jupyter kernels (i.e. with different programming languages).

Arbitrary JavaScript Output (HTML only)

[34]:
%%javascript

var text = document.createTextNode("Hello, I was generated with JavaScript!");
// Content appended to "element" will be visible in the output area:
element.appendChild(text);

Unsupported Output Types

If a code cell produces data with an unsupported MIME type, the Jupyter Notebook doesn’t generate any output. nbsphinx, however, shows a warning message.

[35]:
display({
    'text/x-python': 'print("Hello, world!")',
    'text/x-haskell': 'main = putStrLn "Hello, world!"',
}, raw=True)

Data type cannot be displayed: text/x-python, text/x-haskell

ANSI Colors

The standard output and standard error streams may contain ANSI escape sequences to change the text and background colors.

[36]:
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!

The following code showing the 8 basic ANSI colors is based on http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html. Each of the 8 colors has an “intense” variation, which is used for bold text.

[37]:
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 also supports a set of 256 indexed colors. The following code showing all of them is based on http://bitmote.com/index.php?post/2012/11/19/Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt-on-Linux.

[38]:
formatstring = '\x1b[38;5;{0};48;5;{0}mX\x1b[1mX\x1b[m'

print('  + ' + ''.join('{:2}'.format(i) for i in range(36)))
print('  0 ' + ''.join(formatstring.format(i) for i in range(16)))
for i in range(7):
    i = i * 36 + 16
    print('{:3} '.format(i) + ''.join(formatstring.format(i + j)
                                      for j in range(36) if i + j < 256))
  +  0 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435
  0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 16 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 52 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 88 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
124 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
160 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
196 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
232 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

You can even use 24-bit RGB colors:

[39]:
start = 255, 0, 0
end = 0, 0, 255
length = 79
out = []

for i in range(length):
    rgb = [start[c] + int(i * (end[c] - start[c]) / length) for c in range(3)]
    out.append('\x1b['
               '38;2;{rgb[2]};{rgb[1]};{rgb[0]};'
               '48;2;{rgb[0]};{rgb[1]};{rgb[2]}mX\x1b[m'.format(rgb=rgb))
print(''.join(out))
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
This page was generated from doc/raw-cells.ipynb. Interactive online version: Binder badge.

Raw Cells

The “Raw NBConvert” cell type can be used to render different code formats into HTML or LaTeX by Sphinx. This information is stored in the notebook metadata and converted appropriately.

Usage

To select a desired format from within Jupyter, select the cell containing your special code and choose options from the following dropdown menus:

  1. Select “Raw NBConvert”

  2. Switch the Cell Toolbar to “Raw Cell Format”

  3. Chose the appropriate “Raw NBConvert Format” within the cell

Steps for converting cells to Raw formats in Jupyter

Available Raw Cell Formats

The following examples show how different Jupyter cell formats are rendered by Sphinx.

None

By default (if no cell format is selected), the cell content is included (without any conversion) in both the HTML and LaTeX output. This is typically not useful at all.

"I'm a raw cell with no format."

reST

Raw cells in “reST” format are interpreted as reStructuredText and parsed by Sphinx. The result is visible in both HTML and LaTeX output.

I’m a raw cell in reST format.”

Markdown

Raw cells in “Markdown” format are interpreted as Markdown, and the result is included in both HTML and LaTeX output. Since the Jupyter Notebook also supports normal Markdown cells, this might not be useful at all.

I’m a raw cell in Markdown format.”

HTML

Raw cells in “HTML” format are only visible in HTML output. This option might not be very useful, since raw HTML code is also allowed within normal Markdown cells.

I’m a raw cell in HTML format.”

LaTeX

Raw cells in “LaTeX” format are only visible in LaTeX output.

Python

Raw cells in “Python” format are not visible at all (nor executed in any way).

This page was generated from doc/hidden-cells.ipynb. Interactive online version: Binder badge.

Hidden Cells

You can remove cells from the HTML/LaTeX output by adding this to the cell metadata:

"nbsphinx": "hidden"

Hidden cells are still executed but removed afterwards.

For example, the following hidden cell defines the variable answer.

This is the cell after the hidden cell. Although the previous cell is not visible, its result is still available:

[2]:
answer
[2]:
42

Don’t overuse this, because it may make it harder to follow what’s going on in your notebook.

Also Markdown cells can be hidden. The following cell is hidden.

This is the cell after the hidden cell.

This page was generated from doc/executing-notebooks.ipynb. Interactive online version: Binder badge.

Controlling Notebook Execution

Notebooks with no outputs are automatically executed during the Sphinx build process. If, however, there is at least one output cell present, the notebook is not evaluated and included as is.

The following notebooks show how this default behavior can be used and customized.

This page was generated from doc/pre-executed.ipynb. Interactive online version: Binder badge.

Pre-Executing Notebooks

Automatically executing notebooks during the Sphinx build process is an important feature of nbsphinx. However, there are a few use cases where pre-executing a notebook and storing the outputs might be preferable. Storing any output will, by default, stop nbsphinx from executing the notebook.

Long-Running Cells

If you are doing some very time-consuming computations, it might not be feasible to re-execute the notebook every time you build your Sphinx documentation.

So just do it once – when you happen to have the time – and then just keep the output.

[1]:
import time
[2]:
%time time.sleep(60 * 60)
6 * 7
CPU times: user 160 ms, sys: 56 ms, total: 216 ms
Wall time: 1h 1s
[2]:
42

Rare Libraries

You might have created results with a library that’s hard to install and therefore you have only managed to install it on one very old computer in the basement, so you probably cannot run this whenever you build your Sphinx docs.

[3]:
from a_very_rare_library import calculate_the_answer
[4]:
calculate_the_answer()
[4]:
42

Exceptions

If an exception is raised during the Sphinx build process, it is stopped (the build process, not the exception!). If you want to show to your audience how an exception looks like, you have two choices:

  1. Allow errors – either generally or on a per-notebook or per-cell basis – see Ignoring Errors (per cell).

  2. Execute the notebook beforehand and save the results, like it’s done in this example notebook:

[5]:
1 / 0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-5-b710d87c980c> in <module>()
----> 1 1 / 0

ZeroDivisionError: division by zero

Client-specific Outputs

When nbsphinx executes notebooks, it uses the nbconvert module to do so. Certain Jupyter clients might produce output that differs from what nbconvert would produce. To preserve those original outputs, the notebook has to be executed and saved before running Sphinx.

For example, the JupyterLab help system shows the help text as cell outputs, while executing with nbconvert doesn’t produce any output.

[6]:
sorted?
Signature: sorted(iterable, /, *, key=None, reverse=False)
Docstring:
Return a new list containing all items from the iterable in ascending order.

A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
Type:      builtin_function_or_method

This page was generated from doc/never-execute.ipynb. Interactive online version: Binder badge.

Explicitly Dis-/Enabling Notebook Execution

If you want to include a notebook without outputs and yet don’t want nbsphinx to execute it for you, you can explicitly disable this feature.

You can do this globally by setting the following option in conf.py:

nbsphinx_execute = 'never'

Or on a per-notebook basis by adding this to the notebook’s JSON metadata:

"nbsphinx": {
  "execute": "never"
},

There are three possible settings, "always", "auto" and "never". By default (= "auto"), notebooks with no outputs are executed and notebooks with at least one output are not. As always, per-notebook settings take precedence over the settings in conf.py.

This very notebook has its metadata set to "never", therefore the following cell is not executed:

[ ]:
6 * 7
This page was generated from doc/allow-errors.ipynb. Interactive online version: Binder badge.

Ignoring Errors

Normally, if an exception is raised while executing a notebook, the Sphinx build process is stopped immediately.

If a notebook contains errors on purpose (or if you are too lazy to fix them right now), you have four options:

  1. Manually execute the notebook in question and save the results, see the pre-executed example notebook.

  2. Allow errors in all notebooks by setting this option in conf.py: nbsphinx_allow_errors = True

  3. Allow errors on a per-notebook basis by adding this to the notebook’s JSON metadata: "nbsphinx": {  "allow_errors": true    },

  4. Allow errors on a per-cell basis using the raises-exception tag, see Ignoring Errors on a Cell-by-Cell Basis.

This very notebook is an example for the third option. The results of the following code cells are not stored within the notebook, therefore it is executed during the Sphinx build process. Since the above-mentioned allow_errors flag is set in this notebook’s metadata, all cells are executed although most of them cause an exception.

[1]:
nonsense
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-7dd4c0df649c> in <module>
----> 1 nonsense

NameError: name 'nonsense' is not defined
[2]:
42 / 0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-52cebea8b64f> in <module>
----> 1 42 / 0

ZeroDivisionError: division by zero
[3]:
print 'Hello, world!'
  File "<ipython-input-3-653b30cd70a8>", line 1
    print 'Hello, world!'
                        ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Hello, world!')?

[4]:
6 ~ 7
  File "<ipython-input-4-8300b2622db3>", line 1
    6 ~ 7
      ^
SyntaxError: invalid syntax

[5]:
6 * 7
[5]:
42
This page was generated from doc/allow-errors-per-cell.ipynb. Interactive online version: Binder badge.

Ignoring Errors on a Per-Cell Basis

Instead of ignoring errors for all notebooks or for some selected notebooks (see the previous notebook), you can be more fine-grained and just allow errors on certain code cells by tagging them with the raises-exception tag.

[1]:
'no problem'
[1]:
'no problem'

The following code cell has the raises-exception tag.

[2]:
problem
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-526ab3a89ffc> in <module>
----> 1 problem

NameError: name 'problem' is not defined

The following code cell is executed even though the previous cell raised an exception.

[3]:
'no problem'
[3]:
'no problem'

Note

The behavior of the raises-exception tag doesn’t match its name. While it does allow exceptions, it does not check if an exception is actually raised!

This will hopefully be fixed at some point, see https://github.com/jupyter/nbconvert/issues/730.

This page was generated from doc/configuring-kernels.ipynb. Interactive online version: Binder badge.

Configuring the Kernels

Kernel Name

If we have multiple kernels installed, we can choose to override the kernel saved in the notebook using nbsphinx_kernel_name:

nbsphinx_kernel_name = 'python-upstream-dev'

which uses the kernel named python-upstream-dev instead of the kernel name stored in the notebook.

Kernel Arguments

We can also pass options to the kernel by setting nbsphinx_execute_arguments in conf.py. These work the same way as ipython_kernel_config.py. For example, using

nbsphinx_execute_arguments = [
    "--InlineBackend.rc={'figure.dpi': 96}",
]

to set plot options is the same as writing:

c.InlineBackend.rc = {'figure.dpi': 96}

in ipython_kernel_config.py or using:

%config InlineBackend.rc={'figure.dpi': 96}

at the top of a notebook:

[1]:
get_ipython().config.InlineBackend.rc
[1]:
{'figure.dpi': 96}

Environment Variables

The contents of os.environ after the execution of conf.py will be passed as environment variables to the kernel. As an example, MY_DUMMY_VARIABLE has been set in conf.py like this:

import os
os.environ['MY_DUMMY_VARIABLE'] = 'Hello from conf.py!'

… and it can be checked in the notebook like this:

[2]:
import os
os.environ['MY_DUMMY_VARIABLE']
[2]:
'Hello from conf.py!'

This is useful if we want to edit PYTHONPATH in order to compile the documentation without installing the project:

import os

src = os.path.abspath('../src')
os.environ['PYTHONPATH'] = src

If you are using https://mybinder.org/ and you want to define environment variables, you should create a file .binder/start in your repository (see Binder docs) containing definitions like this:

#!/bin/bash
export MY_DUMMY_VARIABLE="Hello from .binder/start!"
exec "$@"
This page was generated from doc/timeout.ipynb. Interactive online version: Binder badge.

Cell Execution Timeout

By default, code cells will be executed until they are finished, even if that takes a very long time. In some cases they might never finish.

If you would like to only use a finite amount of time per cell, you can choose a timeout length for all notebooks by setting the following option in conf.py:

nbsphinx_timeout = 60

Or change the timeout length on a per-notebook basis by adding this to the notebook’s JSON metadata:

"nbsphinx": {
  "timeout": 60
},

The timeout is given in seconds, use -1 to disable the timeout (which is the default).

Alternatively, you can manually execute the notebook in question and save the results, see the pre-executed example notebook.

This page was generated from doc/prolog-and-epilog.ipynb. Interactive online version: Binder badge.

Prolog and Epilog

When including notebooks in your Sphinx documentation, you can choose to add some generic content before and after each notebook. This can be done with the configuration values nbsphinx_prolog and nbsphinx_epilog in the file conf.py.

The prolog and epilog strings can hold arbitrary reST markup. Particularly, the only and raw directives can be used to have different content for HTML and LaTeX output.

Those strings are also processed by the Jinja2 templating engine. This means you can run Python-like code within those strings. You have access to the current Sphinx build environment via the variable env. Most notably, you can get the file name of the current notebook with

{{ env.doc2path(env.docname, base=None) }}

Have a look at the Jinja2 template documentation for more information.

Warning

If you use invalid syntax, you might get an error like this:

jinja2.exceptions.TemplateSyntaxError: expected token ':', got '}'

This is especially prone to happen when using raw LaTeX, with its abundance of braces. To avoid clashing braces you can try to insert additional spaces or LaTeX macros that don’t have a visible effect, like e.g. \strut{}. For example, you can avoid three consecutive opening braces with something like that:

\texttt{\strut{}{{ env.doc2path(env.docname, base=None) }}}

NB: The three consecutive closing braces in this example are not problematic.

An alternative work-around would be to surround LaTeX braces with Jinja braces like this:

{{ '{' }}

The string within will not be touched by Jinja.

Another special Jinja syntax is {%, which is also often used in fancy TeX/LaTeX code. A work-around for this situation would be to use

{{ '{%' }}

Examples

You can include a simple static string, using reST markup if you like:

nbsphinx_epilog = """
----

Generated by nbsphinx_ from a Jupyter_ notebook.

.. _nbsphinx: https://nbsphinx.readthedocs.io/
.. _Jupyter: https://jupyter.org/
"""

Using some additional Jinja2 markup and the information from the env variable, you can create URLs that point to the current notebook file, but located on some other server:

nbsphinx_prolog = """
Go there: https://example.org/notebooks/{{ env.doc2path(env.docname, base=None) }}

----
"""

You can also use separate content for HTML and LaTeX output, e.g.:

nbsphinx_prolog = r"""
{% set docname = env.doc2path(env.docname, base=None) %}

.. only:: html

    Go there: https://example.org/notebooks/{{ docname }}

.. raw:: latex

    \nbsphinxstartnotebook{The following section was created from
    \texttt{\strut{}{{ docname }}}:}
"""

nbsphinx_epilog = r"""
.. raw:: latex

    \nbsphinxstopnotebook{\hfill End of notebook.}
"""

Note the use of the \nbsphinxstartnotebook and \nbsphinxstopnotebook commands. Those make sure there is not too much space between the “prolog” and the beginning of the notebook and, respectively, between the end of the notebook and the “epilog”. They also avoid page breaks, in order for the “prolog”/”epilog” not to end up on the page before/after the notebook.

For a more involved example for different HTML and LaTeX versions, see the file conf.py of the nbsphinx documentation.

This page was generated from doc/custom-formats.pct.py. Interactive online version: Binder badge.

Custom Notebook Formats

By default, Jupyter notebooks are stored in files with the suffix .ipynb, which use the JSON format for storage.

However, there are libraries available which allow storing notebooks in different formats, using different file suffixes.

To use a custom notebook format in nbsphinx, you can specify the nbsphinx_custom_formats option in your conf.py file. You have to provide the file extension and a conversion function that takes the contents of a file (as a string) and returns a Jupyter notebook object.

nbsphinx_custom_formats = {
    '.mysuffix': 'mylibrary.converter_function',
}

The converter function can be given as a string (recommended) or as a function object.

If a conversion function takes more than a single string argument, you can specify the function name plus a dictionary with keyword arguments which will be passed to the conversion function in addition to the file contents.

nbsphinx_custom_formats = {
    '.mysuffix': ['mylibrary.converter_function', {'some_arg': 42}],
}

You can of course use multiple formats by specifying multiple conversion functions.

Example: Jupytext

One example for a library which provides a custom conversion function is jupytext, which allows storing the contents of Jupyter notebooks in Markdown and R-Markdown, as well as plain Julia, Python and R files.

Since its conversion function takes more than a single string argument, we have to pass a keyword argument, e.g.:

nbsphinx_custom_formats = {
    '.Rmd': ['jupytext.reads', {'fmt': 'Rmd'}],
}

This very page is an example of a notebook stored in the py:percent format (see docs):

[1]:
!head -20 custom-formats.pct.py
# %% [markdown]
# # Custom Notebook Formats
#
# By default, Jupyter notebooks are stored in files with the suffix `.ipynb`,
# which use the JSON format for storage.
#
# However, there are libraries available which allow storing notebooks
# in different formats, using different file suffixes.
#
# To use a custom notebook format in `nbsphinx`, you can specify the
# `nbsphinx_custom_formats` option in your `conf.py` file.
# You have to provide the file extension
# and a conversion function that takes the contents of a file (as a string)
# and returns a Jupyter notebook object.
#
# ```python
# nbsphinx_custom_formats = {
#     '.mysuffix': 'mylibrary.converter_function',
# }
# ```

To select a suitable conversion function, we use the following setting in conf.py:

nbsphinx_custom_formats = {
    '.pct.py': ['jupytext.reads', {'fmt': 'py:percent'}],
}

Another example is this gallery example page.

This page was generated from doc/subdir/a-notebook-in-a-subdir.ipynb. Interactive online version: Binder badge.

Notebooks in Sub-Directories

You can organize your notebooks in subdirectories and nbsphinx will take care that relative links to other notebooks, images and other files still work.

Let’s see if links to local images work: Jupyter notebook icon

[1]:
from IPython.display import Image
Image(filename='../images/notebook_icon.png')
[1]:
_images/subdir_a-notebook-in-a-subdir_2_0.png

Warning

There may be problems with images in output cells if your source directory contains symbolic links, see issue #49.

A link to a notebook in the same sub-directory: link.

A link to a notebook in the parent directory: link.

A link to a local file: link.

A random equation:

\begin{equation} F_n = F_{n-1} + F_{n-2} \tag{08.15} \label{fibonacci-recurrence} \end{equation}

A Sub-Section

This is just for testing inter-notebook links, see this section.

This page was generated from doc/subdir/gallery.ipynb. Interactive online version: Binder badge.

Creating Thumbnail Galleries

Inspired by Sphinx-Gallery, you can create thumbnail galleries from a list of Jupyter notebooks (or other Sphinx source files).

nbsphinx does not provide any gallery styles, but you can easily use the styles from Sphinx-Gallery by installing it:

python3 -m pip install sphinx-gallery --user

… and loading the styles in your conf.py with:

extensions = [
    'nbsphinx',
    'sphinx_gallery.load_style',
    # more extensions, if needed ...
]

You’ll need Sphinx-Gallery version 0.6 or higher.

However, you can also create your own CSS styles if you prefer (then you don’t need to install Sphinx-Gallery). You can load your CSS files with html_css_files.

You can create Thumbnail Galleries in reST Files and you can create galleries by adding the "nbsphinx-gallery" cell tag or metadata to notebooks, which is used just like the “nbsphinx-toctree” cell tag/metadata.

For possible options, see the toctree notebook.

Note

In LaTeX output this behaves just like toctree, i.e. no thumbnail gallery is shown, but the linked files are included in the document.

Like with toctree you should avoid adding content after a gallery (except other toctrees and galleries) because this content would appear in the LaTeX output after the content of all included source files, which is probably not what you want.

The following cell has the "nbsphinx-gallery" tag, which creates a thumbnail gallery. The first section title in that cell (if available) is used as "caption" (unless it’s given in the metadata).

The notebooks in the following gallery describe different ways how to select which images are used as thumbnails.

This page was generated from doc/gallery/cell-tag.ipynb. Interactive online version: Binder badge.

Using a Cell Tag to Select a Thumbnail

You can select any code cell (with appropriate output) by tagging it with the nbsphinx-thumbnail tag.

If there are multiple outputs in the selected cell, the last one is used. See Choosing from Multiple Outputs for how to select a specific output. If you want to show a tooltip, have a look at Using Cell Metadata to Select a Thumbnail.

[1]:
import matplotlib.pyplot as plt

The following cell has the nbsphinx-thumbnail tag:

[2]:
fig, ax = plt.subplots(figsize=[6, 3])
ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8])
[2]:
[<matplotlib.lines.Line2D at 0x7f168791fb00>]
_images/gallery_cell-tag_4_1.svg
This page was generated from doc/gallery/cell-metadata.ipynb. Interactive online version: Binder badge.

Using Cell Metadata to Select a Thumbnail

If the nbsphinx-thumbnail cell tag is not enough, you can use cell metadata to specify more options.

The last cell in this notebook has this metadata:

{
    "nbsphinx-thumbnail": {
        "tooltip": "This tooltip message was defined in cell metadata"
    }
}

If there are multiple outputs in the selected cell, the last one is used. See Choosing from Multiple Outputs for how to select a specific output.

[1]:
import matplotlib.pyplot as plt
import numpy as np
[2]:
plt.rcParams['image.cmap'] = 'coolwarm'
plt.rcParams['image.origin'] = 'lower'

Some example data stolen from https://matplotlib.org/examples/pylab_examples/pcolor_demo.html:

[3]:
x, y = np.meshgrid(np.arange(-3, 3, 0.1), np.arange(-2, 2, 0.1))
z = (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
[4]:
zmax = np.max(np.abs(z))
[5]:
fig, ax = plt.subplots(figsize=[5, 3.5])
ax.imshow(z, vmin=-zmax, vmax=zmax)
[5]:
<matplotlib.image.AxesImage at 0x7fe0657c49e8>
_images/gallery_cell-metadata_7_1.svg
This page was generated from doc/gallery/multiple-outputs.ipynb. Interactive online version: Binder badge.

Choosing from Multiple Outputs

By default, the last output of the selected cell is used as a thumbnail. If that’s what you want, you can simply use the nbsphinx-thumbnail cell tag.

If you want to specify one of multiple outputs, you can add a (zero-based) "output-index" to your "nbsphinx-thumbnail" cell metadata.

The following cell has this metadata, selecting the third output to be used as thumbnail in the gallery.

{
    "nbsphinx-thumbnail": {
        "output-index": 2
    }
}
[1]:
from IPython.display import Image

display(Image(url='https://jupyter.org/assets/nav_logo.svg'))
print('Hello!')
display(Image(filename='../images/notebook_icon.png'))
display(Image(url='https://www.python.org/static/img/python-logo-large.png', embed=True))
Hello!
_images/gallery_multiple-outputs_2_2.png
_images/gallery_multiple-outputs_2_3.png
This page was generated from doc/gallery/no-thumbnail.ipynb. Interactive online version: Binder badge.

A Notebook without Thumbnail

This notebook doesn’t contain any thumbnail metadata.

It should be displayed with the default thumbnail image in the gallery.

This page was generated from doc/gallery/thumbnail-from-conf-py.ipynb. Interactive online version: Binder badge.

Specifying Thumbnails in conf.py

This notebook doesn’t contain any thumbnail metadata.

But in the file conf.py, a thumbnail is specified (via the nbsphinx_thumbnails option), which will be used in the gallery.

The keys in the nbsphinx_thumbnails dictionary can contain wildcards, which behave very similarly to the html_sidebars option.

The thumbnail files can be local image files somewhere in the source directory, but you’ll need to create at least one link to them in order to copy them to the HTML output directory.

You can also use files from the _static directory (which contains all files in your html_static_path).

If you want, you can also use files from the _images directory, which contains all notebook outputs.

To demonstrate this feature, we are creating an image file here:

[1]:
%matplotlib agg
[2]:
import matplotlib.pyplot as plt
[3]:
fig, ax = plt.subplots()
ax.plot([4, 8, 15, 16, 23, 42])
fig.savefig('a-local-file.png')

Please note that the previous cell doesn’t have any outputs, but it has generated a file named a-local-file.png in the notebook’s directory.

We have to create a link to this file (which is a good idea anyway): a-local-file.png.

Now we can use this file in our conf.py like this:

nbsphinx_thumbnails = {
    'gallery/thumbnail-from-conf-py': 'gallery/a-local-file.png',
}

Please note that the notebook name does not contain the .ipynb suffix.

This page was generated from doc/subdir/toctree.ipynb. Interactive online version: Binder badge.

Using toctree In A Notebook

In Sphinx-based documentation, there is typically a file called index.rst which contains one or more toctree directives. Those can be used to pull in further source files (which themselves can contain further toctree directives).

With nbsphinx it is possible to get a similar effect within a Jupyter notebook using the "nbsphinx-toctree" cell tag or cell metadata. Markdown cells with "nbsphinx-toctree" tag/metadata are not converted like “normal” Markdown cells. Instead, they are only scanned for links to other notebooks (or *.rst files and other Sphinx source files) and those links are added to a toctree directive. External links can also be used, but they will not be visible in the LaTeX output.

If there is a section title in the selected cell, it is used as toctree caption (but it also works without a title).

Note

All other content of such a cell is ignored!

If you are satisfied with the default settings, you can simply use "nbsphinx-toctree" as a cell tag.

Alternatively, you can store "nbsphinx-toctree" cell metadata. Use …

{
  "nbsphinx-toctree": {}
}

… for the default settings, …

{
  "nbsphinx-toctree": {
    "maxdepth": 2
  }
}

… for setting the :maxdepth: option, or…

{
  "nbsphinx-toctree": {
    "hidden": true
  }
}

… for setting the :hidden: option.

Of course, multiple options can be used at the same time, e.g.

{
  "nbsphinx-toctree": {
    "maxdepth": 3,
    "numbered": true
  }
}

For more options, have a look a the Sphinx documentation. All options can be used – except :glob:, which can only be used in rst files and in raw reST cells.

Note

In HTML output, a toctree cell generates an in-line table of contents (containing links) at its position in the notebook, whereas in the LaTeX output, a new (sub-)section with the actual content is inserted at its position. All content below the toctree cell will appear after the table of contents/inserted section, respectively. If you want to use the LaTeX output, it is recommended that you don’t add further cells below a toctree cell, otherwise their content may appear at unexpected places. Multiple toctree cells in a row should be fine, though.

The following cell is tagged with "nbsphinx-toctree" and contains a link to the notebook yet-another.ipynb and an external link (which will only be visible in the HTML output). It also contains a section title which will be used as toctree caption (which also will only be visible in the HTML output).

This page was generated from doc/yet-another.ipynb. Interactive online version: Binder badge.

Yet Another Notebook

This notebook is only here to show how (sub-)toctrees can be created with Markdown cell metadata. See there.

This page was generated from doc/custom-css.ipynb. Interactive online version: Binder badge.

Custom CSS

If you are not satisfied with the CSS styles provided by nbsphinx and by your Sphinx theme, don’t worry, you can add your own styles easily.

For All Pages

Just create your own CSS file, e.g. my-own-style.css, and put it into the _static/ sub-directory of your source directory.

You’ll also have to set the config values html_static_path and html_css_files in your conf.py, e.g. like this:

html_static_path = ['_static']
html_css_files = ['my-own-style.css']

For All RST files

If you want your style to only apply to *.rst files (and not Jupyter notebooks or other source files), you can use rst_prolog with the raw directive in your conf.py like this:

rst_prolog = """
.. raw:: html

    <style>
        h1 {
            color: fuchsia;
        }
    </style>
"""

For All Notebooks

Similarly, if you want your style to only apply to notebooks, you can use nbsphinx_prolog like this:

nbsphinx_prolog = """
.. raw:: html

    <style>
        h1 {
            color: chartreuse;
        }
    </style>
"""

For a Single Notebook

For styles that should affect only the current notebook, you can simply insert <style> tags into Markdown cells like this:

<style>
    .nbinput .prompt,
    .nboutput .prompt {
        display: none;
    }
</style>

This CSS example removes the input and output prompts from code cells, see the following cell:

[1]:
6 * 7
[1]:
42

Normal reStructuredText Files

This is a normal RST file.

Note

Those still work!

Sphinx Directives for Info/Warning Boxes

Warning

This is an experimental feature! Its usage may change in the future or it might disappear completely, so don’t use it for now.

With a bit of luck, it will be possible (some time in the future) to create info/warning boxes in Markdown cells, see https://github.com/jupyter/notebook/issues/1292. If this ever happens, nbsphinx will provide directives for creating such boxes. For now, there are two directives available: nbinfo and nbwarning. This is how an info box looks like:

Note

This is an info box.

It may include nested formatting, even another info/warning box:

Warning: You should probably not use nested boxes!

Domain Objects

example_python_function(foo)

This is just for testing domain object links. See this section.

Parameters

foo (str) – Example string parameter

Citations

You could use standard Sphinx citations, but it might be more practical to use the sphinxcontrib.bibtex extension.

If you install and enable this extension, you can create citations like [PGH11]:

:cite:`perez2011python`

You can create similar citations in Jupyter notebooks with a special HTML syntax, see the section about citations in Markdown cells.

For those citations to work, you also need to specify a BibTeX file, as explained in the next section.

References

After installing and enabling the sphinxcontrib.bibtex extension, you can create a list of references from a BibTeX file like this:

.. bibliography:: references.bib

Have a look at the documentation for all the available options.

The list of references may look something like this (in HTML output):

KRKP+16

Thomas Kluyver, Benjamin Ragan-Kelley, Fernando Pérez, Brian Granger, Matthias Bussonnier, Jonathan Frederic, Kyle Kelley, Jessica Hamrick, Jason Grout, Sylvain Corlay, Paul Ivanov, Damián Avila, Safia Abdalla, Carol Willing, and Jupyter Development Team. Jupyter Notebooks—a publishing format for reproducible computational workflows. In Fernando Loizides and Birgit Schmidt, editors, Positioning and Power in Academic Publishing: Players, Agents and Agendas, pages 87–90. IOS Press, 2016. doi:10.3233/978-1-61499-649-1-87.

PGH11

Fernando Pérez, Brian E. Granger, and John D. Hunter. Python: an ecosystem for scientific computing. Computing in Science Engineering, 13(2):13–21, 2011. doi:10.1109/MCSE.2010.119.

However, in the LaTeX/PDF output the list of references will not appear here, but at the end of the document. For a possible work-around, see https://github.com/mcmtroffaes/sphinxcontrib-bibtex/issues/156.

There is an alternative Sphinx extension for creating bibliographies: https://bitbucket.org/wnielson/sphinx-natbib/. However, this project seems to be abandoned (last commit in 2011).

Thumbnail Galleries

With nbsphinx you can create thumbnail galleries in notebook files as described in Creating Thumbnail Galleries.

If you like, you can also create such galleries in reST files using the nbgallery directive.

It takes the same parameters as the toctree directive.

Note

The notes regarding LaTeX in Creating Thumbnail Galleries and Using toctree In A Notebook also apply here!

The following example gallery was created using:

.. nbgallery::
    :caption: This is a thumbnail gallery:
    :name: rst-gallery
    :glob:
    :reversed:

    gallery/*-rst
This page was generated from doc/links.ipynb. Interactive online version: Binder badge.

Contributing

If you find bugs, errors, omissions or other things that need improvement, please create an issue or a pull request at http://github.com/spatialaudio/nbsphinx/. Contributions are always welcome!

Development Installation

Instead of pip-installing the latest release from PyPI, you should get the newest development version (a.k.a. “master”) from Github:

git clone https://github.com/spatialaudio/nbsphinx.git
cd nbsphinx
python3 -m pip install -e . --user

This way, your installation always stays up-to-date, even if you pull new changes from the Github repository. If you have only Python 3 installed, you might have to use the command python instead of python3. When installing nbsphinx this way, you can also quickly check other Git branches (in this example the branch is called “another-branch”):

git checkout another-branch

When you run Sphinx now, it automatically uses the version “another-branch” of nbsphinx. If you want to go back to the “master” branch, use:

git checkout master

To get the latest changes from Github, use:

git pull --ff-only

Building the Documentation

If you make changes to the documentation, you should create the HTML pages locally using Sphinx and check if they look OK.

Initially, you might need to install a few packages that are needed to build the documentation:

python3 -m pip install -r doc/requirements.txt --user

To (re-)build the HTML files, use:

python3 setup.py build_sphinx

If you want to check the LaTeX output, use:

python3 setup.py build_sphinx -b latex

Again, you’ll probably have to use python instead of python3. The generated files will be available in the directories build/sphinx/html/ and build/sphinx/latex/, respectively.

Testing

Unfortunately, the currently available automated tests are very limited. Contributions to improve the testing situation are of course also welcome!

The nbsphinx documentation also serves as a test case. However, the resulting HTML/LaTeX/PDF files have to be inspected manually to check whether they look as expected.

Sphinx’s warnings can help spot problems, therefore it is recommended to use the -W flag to turn Sphinx warnings into errors while testing:

python3 setup.py build_sphinx -W

This flag is also used for continuous integration on Travis-CI (see the file .travis.yml) and CircleCI (see the file .circleci/config.yml).

Sphinx has a linkcheck builder that can check whether all URLs used in the documentation are still valid. This is also part of the continuous integration setup on CircelCI.

Version History

Version 0.7.1 (2020-06-16):
  • Avoid links on scaled images

Version 0.7.0 (2020-05-08):
  • Warnings can be suppressed with suppress_warnings.

  • <img> tags are handled in Markdown cells; the alt, width, height and class attributes are supported.

  • CSS: prompts protrude into left margin if nbsphinx_prompt_width is too small. If you want to hide the prompts, use custom CSS.

Version 0.6.1 (2020-04-18):
  • .ipynb_checkpoints is automatically added to exclude_patterns

Version 0.6.0 (2020-04-03):
  • Thumbnail galleries (inspired by https://sphinx-gallery.github.io/)

  • nbsphinx-toctree as cell tag

  • Keyword arguments in nbsphinx_custom_formats

  • Python 2 support has been dropped

Version 0.5.1 (2020-01-28):
Version 0.5.0 (2019-11-20):
  • Automatic support for Jupyter widgets, customizable with nbsphinx_widgets_path (and nbsphinx_widgets_options)

Version 0.4.3 (2019-09-30):
  • Add option nbsphinx_requirejs_path (and nbsphinx_requirejs_options)

Version 0.4.2 (2019-01-15):
  • Re-establish Python 2 compatibility (but the clock is ticking …)

Version 0.4.1 (2018-12-16):
  • Fix issue #266

Version 0.4.0 (2018-12-14):
  • Support for “data-cite” HTML tags in Markdown cells

  • Add option nbsphinx_custom_formats

  • LaTeX macros \nbsphinxstartnotebook and \nbsphinxstopnotebook

  • Support for cell attachments

  • Add options nbsphinx_input_prompt and nbsphinx_output_prompt

  • Re-design LaTeX output of code cells, fix image sizes

Version 0.3.5 (2018-09-10):
  • Disable nbconvert version 5.4 to avoid issue #878

Version 0.3.4 (2018-07-28):
  • Fix issue #196 and other minor changes

Version 0.3.3 (2018-04-25):
  • Locally linked files are only copied for Jupyter notebooks (and not anymore for other Sphinx source files)

Version 0.3.2 (2018-03-28):
  • Links to local files are rewritten for all Sphinx source files (not only Jupyter notebooks)

Version 0.3.1 (2018-01-17):
  • Enable notebook translations (NB: The use of reST strings is temporary!)

Version 0.3.0 (2018-01-02):
  • Add options nbsphinx_prolog and nbsphinx_epilog

  • Links from *.rst files to notebooks have to start with a slash

Version 0.2.18 (2017-12-03):
  • Fix issue #148

Version 0.2.17 (2017-11-12):
  • Fix issue #146

Version 0.2.16 (2017-11-07):
  • Fix issue #142

Version 0.2.15 (2017-11-03):
  • Links to subsections are now possible in all source files

Version 0.2.14 (2017-06-09):
  • Add option nbsphinx_kernel_name

Version 0.2.13 (2017-01-25):
  • Minor fixes

Version 0.2.12 (2016-12-19):
  • Basic support for widgets

  • CSS is now “responsive”, some new CSS classes

Version 0.2.11 (2016-11-19):
  • Minor fixes

Version 0.2.10 (2016-10-16):
  • Enable JavaScript output cells

Version 0.2.9 (2016-07-26):
  • Add option nbsphinx_prompt_width

Version 0.2.8 (2016-05-20):
  • Add options nbsphinx_execute and nbsphinx_execute_arguments

  • Separate “display priority” for HTML and LaTeX

Version 0.2.7 (2016-05-04):
  • Special CSS tuning for sphinx_rtd_theme

  • Replace info/warning <div> elements with nbinfo/nbwarning

Version 0.2.6 (2016-04-12):
  • Support for LaTeX math environments in Markdown cells

  • Add options nbsphinx_timeout and nbsphinx_codecell_lexer

Version 0.2.5 (2016-03-15):
  • Add option nbsphinx_allow_errors to globally ignore exceptions

  • Separate class nbsphinx.Exporter

Version 0.2.4 (2016-02-12):
  • Support for “nbsphinx-toctree” cell metadata

Version 0.2.3 (2016-01-22):
  • Links from notebooks to local files can now be used

Version 0.2.2 (2016-01-06):
  • Support for links to sub-sections in other notebooks

Version 0.2.1 (2016-01-04):
  • No need to mention source_suffix and source_parsers in conf.py

Version 0.2.0 (2015-12-27):
  • Add support for allow_errors and hidden metadata

  • Add custom reST template

  • Add nbinput and nboutput directives with HTML+CSS and LaTeX formatting

  • Turn nbsphinx into a Sphinx extension

Version 0.1.0 (2015-11-29):

Initial release

There is also An Orphan Notebook (HTML Only), just for the sake of it.