nbconvert: Convert Notebooks to other formats¶
Using nbconvert
enables:
- presentation of information in familiar formats, such as PDF.
- publishing of research using LaTeX and opens the door for embedding notebooks in papers.
- collaboration with others who may not use the notebook in their work.
- sharing contents with many people via the web using HTML.
Overall, notebook conversion and the nbconvert
tool give scientists and
researchers the flexibility to deliver information in a timely way across
different formats.
Primarily, the nbconvert
tool allows you to convert a Jupyter .ipynb
notebook document file into another static format including HTML, LaTeX, PDF,
Markdown, reStructuredText, and more. nbconvert
can also add productivity
to your workflow when used to execute notebooks programmatically.
If used as a Python library (import nbconvert
), nbconvert
adds
notebook conversion within a project. For example, nbconvert
is used to
implement the “Download as” feature within the Jupyter Notebook web
application. When used as a command line tool (invoked as
jupyter nbconvert ...
), users can conveniently convert just one or a
batch of notebook files to another format.
Contents:
Installation¶
See also
- Installing Jupyter
- Nbconvert is part of the Jupyter ecosystem.
Installing nbconvert¶
Nbconvert is packaged for both pip and conda, so you can install it with:
pip install nbconvert
# OR
conda install nbconvert
If you’re new to Python, we recommend installing Anaconda, a Python distribution which includes nbconvert and the other Jupyter components.
Important
To unlock nbconvert’s full capabilities requires Pandoc and TeX (specifically, XeLaTeX). These must be installed separately.
Installing Pandoc¶
For converting markdown to formats other than HTML, nbconvert uses Pandoc (1.12.1 or later).
To install pandoc on Linux, you can generally use your package manager:
sudo apt-get install pandoc
On other platforms, you can get pandoc from their website.
Installing TeX¶
For converting to PDF, nbconvert uses the TeX document preparation
ecosystem. It produces an intermediate .tex
file which is
compiled by the XeTeX engine with the LaTeX2e format (via the
xelatex
command) to produce PDF output.
New in version 5.0: We use XeTeX as the rendering engine rather than pdfTeX (as in earlier versions). XeTeX can access fonts through native operating system libraries, it has better support for OpenType formatted fonts and Unicode characters.
To install a complete TeX environment (including XeLaTeX and the necessary supporting packages) by hand can be tricky. Fortunately, there are packages that make this much easier. These packages are specific to different operating systems:
- Linux: TeX Live
- E.g. on Debian or Ubuntu:
sudo apt-get install texlive-xetex
- E.g. on Debian or Ubuntu:
- macOS (OS X): MacTeX.
- Windows: MikTex
Because nbconvert depends on packages and fonts included in standard TeX distributions, if you do not have a complete installation, you may not be able to use nbconvert’s standard tooling to convert notebooks to PDF.
PDF conversion on a limited TeX environment¶
If you are only able to install a limited TeX environment, there are two main routes you could take to convert to PDF:
- Using TeX by hand
- You could convert to
.tex
directly; this requires Pandoc. - edit the file to accord with your local environment
- run
xelatex
directly.
- You could convert to
- Custom exporter
- You could write a custom exporter that takes your system’s limitations into account.
Using as a command line tool¶
The command-line syntax to run the nbconvert
script is:
$ jupyter nbconvert --to FORMAT notebook.ipynb
This will convert the Jupyter notebook file notebook.ipynb
into the output
format given by the FORMAT
string.
Default output format - HTML¶
The default output format is HTML, for which the --to
argument may be
omitted:
$ jupyter nbconvert notebook.ipynb
Supported output formats¶
The currently supported output formats are:
Jupyter also provides a few templates for output formats. These can be
specified via an additional --template
argument and are listed in the
sections below.
HTML¶
--to html
--template full
(default)A full static HTML render of the notebook. This looks very similar to the interactive view.
--template basic
Simplified HTML, useful for embedding in webpages, blogs, etc. This excludes HTML headers.
LaTeX¶
--to latex
Latex export. This generates
NOTEBOOK_NAME.tex
file, ready for export.--template article
(default)Latex article, derived from Sphinx’s howto template.
--template report
Latex report, providing a table of contents and chapters.
--template basic
Very basic latex output - mainly meant as a starting point for custom templates.
Note
nbconvert uses pandoc to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText.
PDF¶
--to pdf
Generates a PDF via latex. Supports the same templates as
--to latex
.
Reveal.js HTML slideshow¶
--to slides
This generates a Reveal.js HTML slideshow.
Running this slideshow requires a copy of reveal.js (version 3.x).
By default, this will include a script tag in the html that will directly load reveal.js from a public CDN.
This means that if you include your slides on a webpage, they should work as expected. However, some features (specifically, speaker notes & timers) will not work on website because they require access to a local copy of reveal.js.
Speaker notes require a local copy of reveal.js. Then, you need to tell
nbconvert
how to find that local copy.
Timers only work if you already have speaker notes, but also require a local https server. You can read more about this in ServePostProcessorExample.
To make this clearer, let’s look at an example of how to get speaker notes working with a local copy of reveal.js: SlidesWithNotesExample.
Note
In order to designate a mapping from notebook cells to Reveal.js slides, from within the Jupyter notebook, select menu item View –> Cell Toolbar –> Slideshow. That will reveal a drop-down menu on the upper-right of each cell. From it, one may choose from “Slide,” “Sub-Slide”, “Fragment”, “Skip”, and “Notes.” On conversion, cells designated as “skip” will not be included, “notes” will be included only in presenter notes, etc.
Example: creating slides w/ speaker notes¶
Let’s suppose you have a notebook your_talk.ipynb
that you want to convert
to slides. For this example, we’ll assume that you are working in the same
directory as the notebook you want to convert (i.e., when you run ls .
,
your_talk.ipynb
shows up amongst the list of files).
First, we need a copy of reveal.js in the same directory as your slides. One way to do this is to use the following commands in your terminal:
git clone https://github.com/hakimel/reveal.js.git
cd reveal.js
git checkout 3.5.0
cd ..
Then we need to tell nbconvert to point to this local copy. To do that we use
the --reveal-prefix
command line flag to point to the local copy.
jupyter nbconvert your_talk.ipynb --to slides --reveal-prefix reveal.js
This will create file your_talk.slides.html
, which you should be able to
access with open your_talk.slides.html
. To access the speaker notes, press
s
after the slides load and they should open in a new window.
Note: This does not enable slides that run completely offline. While you have a local copy of reveal.js, by default, the slides need to access mathjax, require, and jquery via a public CDN. Addressing this use case is an open issue and PRs are always encouraged.
Serving slides with an https server: --post serve
¶
Once you have speaker notes working you may notice that your timers don’t work. Timers require a bit more infrastructure; you need to serve your local copy of reveal.js from a local https server.
Fortunately, nbconvert
makes this fairly straightforward through the use of
the ServePostProcessor
. To activate this server, we append the command line
flag --post serve
to our call to nbconvert.
jupyter nbconvert your_talk.ipynb --to slides --reveal-prefix reveal.js --post serve
This will run the server, which will occupy the terminal that you ran the
command in until you stop it. You can stop the server by pressing ctrl C
twice.
Markdown¶
--to markdown
Simple markdown output. Markdown cells are unaffected, and code cells indented 4 spaces.
reStructuredText¶
--to rst
Basic reStructuredText output. Useful as a starting point for embedding notebooks in Sphinx docs.
Note
nbconvert uses pandoc to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText.
Executable script¶
--to script
Convert a notebook to an executable script. This is the simplest way to get a Python (or other language, depending on the kernel) script out of a notebook. If there were any magics in an Jupyter notebook, this may only be executable from a Jupyter session.
For example, to convert a Julia notebook to a Julia executable script:
jupyter nbconvert --to script my_julia_notebook.ipynb
Notebook and preprocessors¶
--to notebook
New in version 3.0.
This doesn’t convert a notebook to a different format per se, instead it allows the running of nbconvert preprocessors on a notebook, and/or conversion to other notebook formats. For example:
jupyter nbconvert --to notebook --execute mynotebook.ipynb
This will open the notebook, execute it, capture new output, and save the
result in mynotebook.nbconvert.ipynb
. Specifying --inplace
will
overwrite the input file instead of writing a new file. By default,
nbconvert
will abort conversion if any exceptions occur during
execution of a cell. If you specify --allow-errors
(in addition to the
–execute` flag) then conversion will continue and the output from any
exception will be included in the cell output.
The following command:
jupyter nbconvert --to notebook --nbformat 3 mynotebook
will create a copy of mynotebook.ipynb
in mynotebook.v3.ipynb
in version 3 of the notebook format.
If you want to convert a notebook in-place, you can specify the output file to be the same as the input file:
jupyter nbconvert --to notebook mynb --output mynb
Be careful with that, since it will replace the input file.
Note
nbconvert uses pandoc to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText.
The output file created by nbconvert
will have the same base name as
the notebook and will be placed in the current working directory. Any
supporting files (graphics, etc) will be placed in a new directory with the
same base name as the notebook, suffixed with _files
:
$ jupyter nbconvert notebook.ipynb
$ ls
notebook.ipynb notebook.html notebook_files/
For simple single-file output, such as html, markdown, etc., the output may be sent to standard output with:
$ jupyter nbconvert --to markdown notebook.ipynb --stdout
Converting multiple notebooks¶
Multiple notebooks can be specified from the command line:
$ jupyter nbconvert notebook*.ipynb
$ jupyter nbconvert notebook1.ipynb notebook2.ipynb
or via a list in a configuration file, say mycfg.py
, containing the text:
c = get_config()
c.NbConvertApp.notebooks = ["notebook1.ipynb", "notebook2.ipynb"]
and using the command:
$ jupyter nbconvert --config mycfg.py
Using nbconvert as a library¶
In this notebook, you will be introduced to the programmatic API of nbconvert and how it can be used in various contexts.
A great blog post by [@jakevdp](https://github.com/jakevdp) will be used to demonstrate. This notebook will not focus on using the command line tool. The attentive reader will point-out that no data is read from or written to disk during the conversion process. This is because nbconvert has been designed to work in memory so that it works well in a database or web-based environment too.
Quick overview¶
Credit: Jonathan Frederic (@jdfreder on github)
The main principle of nbconvert is to instantiate an Exporter
that
controls the pipeline through which notebooks are converted.
First, download @jakevdp’s notebook (if you do not have requests
,
install it by running pip install requests
, or if you don’t have pip
installed, you can find it on PYPI):
In [1]:
from urllib.request import urlopen
url = 'http://jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb'
response = urlopen(url).read().decode()
response[0:60] + ' ...'
Out[1]:
'{\n "metadata": {\n "name": "XKCD_plots"\n },\n "nbformat": 3,\n ...'
The response is a JSON string which represents a Jupyter notebook.
Next, we will read the response using nbformat. Doing this will guarantee that the notebook structure is valid. Note that the in-memory format and on disk format are slightly different. In particual, on disk, multiline strings might be split into a list of strings.
In [2]:
import nbformat
jake_notebook = nbformat.reads(response, as_version=4)
jake_notebook.cells[0]
Out[2]:
{'cell_type': 'markdown',
'metadata': {},
'source': '# XKCD plots in Matplotlib'}
The nbformat API returns a special type of dictionary. For this example, you don’t need to worry about the details of the structure (if you are interested, please see the nbformat documentation).
The nbconvert API exposes some basic exporters for common formats and defaults. You will start by using one of them. First, you will import one of these exporters (specifically, the HTML exporter), then instantiate it using most of the defaults, and then you will use it to process the notebook we downloaded earlier.
In [3]:
from traitlets.config import Config
# 1. Import the exporter
from nbconvert import HTMLExporter
# 2. Instantiate the exporter. We use the `basic` template for now; we'll get into more details
# later about how to customize the exporter further.
html_exporter = HTMLExporter()
html_exporter.template_file = 'basic'
# 3. Process the notebook we loaded earlier
(body, resources) = html_exporter.from_notebook_node(jake_notebook)
The exporter returns a tuple containing the source of the converted notebook, as well as a resources dict. In this case, the source is just raw HTML:
In [4]:
print(body[:400] + '...')
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="XKCD-plots-in-Matplotlib">XKCD plots in Matplotlib<a class="anchor-link" href="#XKCD-plots-in-Matplotlib">¶</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div cl...
If you understand HTML, you’ll notice that some common tags are omitted,
like the body
tag. Those tags are included in the default
HtmlExporter
, which is what would have been constructed if we had
not modified the template_file
.
The resource dict contains (among many things) the extracted .png
,
.jpg
, etc. from the notebook when applicable. The basic HTML
exporter leaves the figures as embedded base64, but you can configure it
to extract the figures. So for now, the resource dict should be mostly
empty, except for a key containing CSS and a few others whose content
will be obvious:
In [5]:
print("Resources:", resources.keys())
print("Metadata:", resources['metadata'].keys())
print("Inlining:", resources['inlining'].keys())
print("Extension:", resources['output_extension'])
Resources: dict_keys(['metadata', 'output_extension', 'raw_mimetypes', 'inlining'])
Metadata: dict_keys(['name'])
Inlining: dict_keys(['css'])
Extension: .html
Exporter
s are stateless, so you won’t be able to extract any
useful information beyond their configuration. You can re-use an
exporter instance to convert another notebook. In addition to the
from_notebook_node
used above, each exporter exposes from_file
and from_filename
methods.
Extracting Figures using the RST Exporter¶
When exporting, you may want to extract the base64 encoded figures as
files. While the HTML exporter does not do this by default, the
RstExporter
does:
In [6]:
# Import the RST exproter
from nbconvert import RSTExporter
# Instantiate it
rst_exporter = RSTExporter()
# Convert the notebook to RST format
(body, resources) = rst_exporter.from_notebook_node(jake_notebook)
print(body[:970] + '...')
print('[.....]')
print(body[800:1200] + '...')
XKCD plots in Matplotlib
========================
This notebook originally appeared as a blog post at `Pythonic
Perambulations <http://jakevdp.github.com/blog/2012/10/07/xkcd-style-plots-in-matplotlib/>`__
by Jake Vanderplas.
.. raw:: html
<!-- PELICAN_BEGIN_SUMMARY -->
*Update: the matplotlib pull request has been merged! See* `*This
post* <http://jakevdp.github.io/blog/2013/07/10/XKCD-plots-in-matplotlib/>`__
*for a description of the XKCD functionality now built-in to
matplotlib!*
One of the problems I've had with typical matplotlib figures is that
everything in them is so precise, so perfect. For an example of what I
mean, take a look at this figure:
.. code:: python
from IPython.display import Image
Image('http://jakevdp.github.com/figures/xkcd_version.png')
.. image:: output_3_0.png
Sometimes when showing schematic plots, this is the type of figure I
want to display. But drawing it by hand is a pain: I'd rather just use
matp...
[.....]
image:: output_3_0.png
Sometimes when showing schematic plots, this is the type of figure I
want to display. But drawing it by hand is a pain: I'd rather just use
matplotlib. The problem is, matplotlib is a bit too precise. Attempting
to duplicate this figure in matplotlib leads to something like this:
.. code:: python
Image('http://jakevdp.github.com/figures/mpl_version.png')
.. imag...
Notice that base64 images are not embedded, but instead there are
filename-like strings, such as output_3_0.png
. The strings actually
are (configurable) keys that map to the binary data in the resources
dict.
Note, if you write an RST Plugin, you are responsible for writing all the files to the disk (or uploading, etc…) in the right location. Of course, the naming scheme is configurable.
As an exercise, this notebook will show you how to get one of those
images. First, take a look at the 'outputs'
of the returned
resources dictionary. This is a dictionary that contains a key for each
extracted resource, with values corresponding to the actual base64
encoding:
In [7]:
sorted(resources['outputs'].keys())
Out[7]:
['output_13_1.png',
'output_16_0.png',
'output_18_1.png',
'output_3_0.png',
'output_5_0.png']
In this case, there are 5 extracted binary figures, all png
s. We
can use the Image display object to actually display one of the images:
In [8]:
from IPython.display import Image
Image(data=resources['outputs']['output_3_0.png'], format='png')
Out[8]:

Note that this image is being rendered without ever reading or writing to the disk.
Extracting Figures using the HTML Exporter¶
As mentioned above, by default, the HTML exporter does not extract images – it just leaves them as inline base64 encodings. However, this is not always what you might want. For example, here is a use case from @jakevdp:
I write an awesome blog using Jupyter notebooks converted to HTML, and I want the images to be cached. Having one html file with all of the images base64 encoded inside it is nice when sharing with a coworker, but for a website, not so much. I need an HTML exporter, and I want it to extract the figures!
Some theory¶
Before we get into actually extracting the figures, it will be helpful to give a high-level overview of the process of converting a notebook to a another format:
- Retrieve the notebook and it’s accompanying resources (you are responsible for this).
- Feed the notebook into the
Exporter
, which:- Sequentially feeds the notebook into an array of
Preprocessor
s. Preprocessors only act on the structure of the notebook, and have unrestricted access to it. - Feeds the notebook into the Jinja templating engine, which converts it to a particular format depending on which template is selected.
- Sequentially feeds the notebook into an array of
- The exporter returns the converted notebook and other relevant resources as a tuple.
- You write the data to the disk using the built-in
FilesWriter
(which writes the notebook and any extracted files to disk), or elsewhere using a customWriter
.
Using different preprocessors¶
To extract the figures when using the HTML exporter, we will want to
change which Preprocessor
s we are using. There are several
preprocessors that come with nbconvert, including one called the
ExtractOutputPreprocessor
.
The ExtractOutputPreprocessor
is responsible for crawling the
notebook, finding all of the figures, and putting them into the
resources directory, as well as choosing the key (i.e.
filename_xx_y.extension
) that can replace the figure inside the
template. To enable the ExtractOutputPreprocessor
, we must add it to
the exporter’s list of preprocessors:
In [9]:
# create a configuration object that changes the preprocessors
from traitlets.config import Config
c = Config()
c.HTMLExporter.preprocessors = ['nbconvert.preprocessors.ExtractOutputPreprocessor']
# create the new exporter using the custom config
html_exporter_with_figs = HTMLExporter(config=c)
html_exporter_with_figs.preprocessors
Out[9]:
['nbconvert.preprocessors.ExtractOutputPreprocessor']
We can compare the result of converting the notebook using the original HTML exporter and our new customized one:
In [10]:
(_, resources) = html_exporter.from_notebook_node(jake_notebook)
(_, resources_with_fig) = html_exporter_with_figs.from_notebook_node(jake_notebook)
print("resources without figures:")
print(sorted(resources.keys()))
print("\nresources with extracted figures (notice that there's one more field called 'outputs'):")
print(sorted(resources_with_fig.keys()))
print("\nthe actual figures are:")
print(sorted(resources_with_fig['outputs'].keys()))
resources without figures:
['inlining', 'metadata', 'output_extension', 'raw_mimetypes']
resources with extracted figures (notice that there's one more field called 'outputs'):
['inlining', 'metadata', 'output_extension', 'outputs', 'raw_mimetypes']
the actual figures are:
['output_13_1.png', 'output_16_0.png', 'output_18_1.png', 'output_3_0.png', 'output_5_0.png']
Custom Preprocessors¶
There are an endless number of transformations that you may want to
apply to a notebook. In particularly complicated cases, you may want to
actually create your own Preprocessor
. Above, when we customized the
list of preprocessors accepted by the HTMLExporter
, we passed in a
string – this can be any valid module name. So, if you create your own
preprocessor, you can include it in that same list and it will be used
by the exporter.
To create your own preprocessor, you will need to subclass from
nbconvert.preprocessors.Preprocessor
and overwrite either the
preprocess
and/or preprocess_cell
methods.
Example¶
The following demonstration adds the ability to exclude a cell by index.
Note: injecting cells is similar, and won’t be covered here. If you want to inject static content at the beginning/end of a notebook, use a custom template.
In [11]:
from traitlets import Integer
from nbconvert.preprocessors import Preprocessor
class PelicanSubCell(Preprocessor):
"""A Pelican specific preprocessor to remove some of the cells of a notebook"""
# I could also read the cells from nb.metadata.pelican if someone wrote a JS extension,
# but for now I'll stay with configurable value.
start = Integer(0, help="first cell of notebook to be converted")
end = Integer(-1, help="last cell of notebook to be converted")
start.tag(config='True')
end.tag(config='True')
def preprocess(self, nb, resources):
self.log.info("I'll keep only cells from %d to %d", self.start, self.end)
nb.cells = nb.cells[self.start:self.end]
return nb, resources
Here a Pelican exporter is created that takes PelicanSubCell
preprocessors and a config
object as parameters. This may seem
redundant, but with the configuration system you can register an
inactive preprocessor on all of the exporters and activate it from
config files or the command line.
In [12]:
# Create a new config object that configures both the new preprocessor, as well as the exporter
c = Config()
c.PelicanSubCell.start = 4
c.PelicanSubCell.end = 6
c.RSTExporter.preprocessors = [PelicanSubCell]
# Create our new, customized exporter that uses our custom preprocessor
pelican = RSTExporter(config=c)
# Process the notebook
print(pelican.from_notebook_node(jake_notebook)[0])
Sometimes when showing schematic plots, this is the type of figure I
want to display. But drawing it by hand is a pain: I'd rather just use
matplotlib. The problem is, matplotlib is a bit too precise. Attempting
to duplicate this figure in matplotlib leads to something like this:
.. code:: python
Image('http://jakevdp.github.com/figures/mpl_version.png')
.. image:: output_5_0.png
Programmatically creating templates¶
In [13]:
from jinja2 import DictLoader
dl = DictLoader({'full.tpl':
"""
{%- extends 'basic.tpl' -%}
{% block footer %}
FOOOOOOOOTEEEEER
{% endblock footer %}
"""})
exportHTML = HTMLExporter(extra_loaders=[dl])
(body, resources) = exportHTML.from_notebook_node(jake_notebook)
for l in body.split('\n')[-4:]:
print(l)
</div>
</div>
FOOOOOOOOTEEEEER
Real World Uses¶
@jakevdp uses Pelican and Jupyter Notebook to blog. Pelican will use nbconvert programmatically to generate blog post. Have a look a Pythonic Preambulations for Jake’s blog post.
@damianavila wrote the Nikola Plugin to write blog post as Notebooks and is developping a js-extension to publish notebooks via one click from the web app.
As @Mbussonn requested… easieeeeer! Deploy your Nikola site with just a click in the IPython notebook! http://t.co/860sJunZvj cc @ralsina
— Damián Avila (@damian_avila) August 21, 2013
LaTeX citations¶
nbconvert
now has support for LaTeX citations. With this capability you
can:
- Manage citations using BibTeX.
- Cite those citations in Markdown cells using HTML data attributes.
- Have
nbconvert
generate proper LaTeX citations and run BibTeX.
For an example of how this works, please see the citations example in the nbconvert-examples repository.
Executing notebooks¶
Jupyter notebooks are often saved with output cells that have been cleared. nbconvert provides a convenient way to execute the input cells of an .ipynb notebook file and save the results, both input and output cells, as a .ipynb file.
In this section we show how to execute a .ipynb
notebook
document saving the result in notebook format. If you need to export
notebooks to other formats, such as reStructured Text or Markdown (optionally
executing them) see section Using nbconvert as a library.
Executing notebooks can be very helpful, for example, to run all notebooks in Python library in one step, or as a way to automate the data analysis in projects involving more than one notebook.
Executing notebooks from the command line¶
The same functionality of executing notebooks is exposed through a command line interface or a Python API interface. As an example, a notebook can be executed from the command line with:
jupyter nbconvert --to notebook --execute mynotebook.ipynb
Executing notebooks using the Python API interface¶
This section will illustrate the Python API interface.
Example¶
Let’s start with a complete quick example, leaving detailed explanations to the following sections.
Import: First we import nbconvert and the ExecutePreprocessor
class:
import nbformat
from nbconvert.preprocessors import ExecutePreprocessor
Load: Assuming that notebook_filename
contains the path of a notebook,
we can load it with:
with open(notebook_filename) as f:
nb = nbformat.read(f, as_version=4)
Configure: Next, we configure the notebook execution mode:
ep = ExecutePreprocessor(timeout=600, kernel_name='python3')
We specified two (optional) arguments timeout
and kernel_name
, which
define respectively the cell execution timeout and the execution kernel.
The option to specify kernel_name is new in nbconvert 4.2. When not specified or when using nbconvert <4.2, the default Python kernel is chosen.
Execute/Run (preprocess): To actually run the notebook we call the method
preprocess
:
ep.preprocess(nb, {'metadata': {'path': 'notebooks/'}})
Hopefully, we will not get any errors during the notebook execution
(see the last section for error handling). Note that path
specifies
in which folder to execute the notebook.
Save: Finally, save the resulting notebook with:
with open('executed_notebook.ipynb', 'wt') as f:
nbformat.write(nb, f)
That’s all. Your executed notebook will be saved in the current folder
in the file executed_notebook.ipynb
.
Execution arguments (traitlets)¶
The arguments passed to ExecutePreprocessor
are configuration options
called traitlets.
There are many cool things about traitlets. For example,
they enforce the input type, and they can be accessed/modified as
class attributes. Moreover, each traitlet is automatically exposed
as command-line options. For example, we can pass the timeout from the
command-line like this:
jupyter nbconvert --ExecutePreprocessor.timeout=600 --to notebook --execute mynotebook.ipynb
Let’s now discuss in more detail the two traitlets we used.
The timeout
traitlet defines the maximum time (in seconds) each notebook
cell is allowed to run, if the execution takes longer an exception will be
raised. The default is 30 s, so in cases of long-running cells you may want to
specify an higher value. The timeout
option can also be set to None
or -1
to remove any restriction on execution time.
The second traitlet, kernel_name
, allows specifying the name of the kernel
to be used for the execution. By default, the kernel name is obtained from the
notebook metadata. The traitlet kernel_name
allows specifying a
user-defined kernel, overriding the value in the notebook metadata. A common
use case is that of a Python 2/3 library which includes documentation/testing
notebooks. These notebooks will specify either a python2 or python3 kernel in
their metadata (depending on the kernel used the last time the notebook was
saved). In reality, these notebooks will work on both Python 2 and Python 3,
and, for testing, it is important to be able to execute them programmatically
on both versions. Here the traitlet kernel_name
helps simplify and
maintain consistency: we can just run a notebook twice, specifying first
“python2” and then “python3” as the kernel name.
Handling errors and exceptions¶
In the previous sections we saw how to save an executed notebook, assuming there are no execution errors. But, what if there are errors?
Execution until first error¶
An error during the notebook execution, by default, will stop the execution
and raise a CellExecutionError
. Conveniently, the source cell causing
the error and the original error name and message are also printed.
After an error, we can still save the notebook as before:
with open('executed_notebook.ipynb', mode='wt') as f:
nbformat.write(nb, f)
The saved notebook contains the output up until the failing cell, and includes a full stack-trace and error (which can help debugging).
Handling errors¶
A useful pattern to execute notebooks while handling errors is the following:
from nbconvert.preprocessors import CellExecutionError
try:
out = ep.preprocess(nb, {'metadata': {'path': run_path}})
except CellExecutionError:
out = None
msg = 'Error executing the notebook "%s".\n\n' % notebook_filename
msg += 'See notebook "%s" for the traceback.' % notebook_filename_out
print(msg)
raise
finally:
with open(notebook_filename_out, mode='wt') as f:
nbformat.write(nb, f)
This will save the executed notebook regardless of execution errors.
In case of errors, however, an additional message is printed and the
CellExecutionError
is raised. The message directs the user to
the saved notebook for further inspection.
Execute and save all errors¶
As a last scenario, it is sometimes useful to execute notebooks which raise
exceptions, for example to show an error condition. In this case, instead of
stopping the execution on the first error, we can keep executing the notebook
using the traitlet allow_errors
(default is False). With
allow_errors=True
, the notebook is executed until the end, regardless of
any error encountered during the execution. The output notebook, will contain
the stack-traces and error messages for all the cells raising exceptions.
Configuration options¶
Configuration options may be set in a file, ~/.jupyter/jupyter_nbconvert_config.py
,
or at the command line when starting nbconvert, i.e. jupyter nbconvert --Application.log_level=10
.
- Application.log_datefmt : Unicode
Default:
'%Y-%m-%d %H:%M:%S'
The date format used by logging formatters for %(asctime)s
- Application.log_format : Unicode
Default:
'[%(name)s]%(highlevel)s %(message)s'
The Logging format template
- Application.log_level : 0|10|20|30|40|50|’DEBUG’|’INFO’|’WARN’|’ERROR’|’CRITICAL’
Default:
30
Set the log level by value or name.
- JupyterApp.answer_yes : Bool
Default:
False
Answer yes to any prompts.
- JupyterApp.config_file : Unicode
Default:
''
Full path of a config file.
- JupyterApp.config_file_name : Unicode
Default:
''
Specify a config file to load.
- JupyterApp.generate_config : Bool
Default:
False
Generate default config file.
- NbConvertApp.export_format : Unicode
Default:
'html'
The export format to be used, either one of the built-in formats, or a dotted object name that represents the import path for an Exporter class
- NbConvertApp.from_stdin : Bool
Default:
False
read a single notebook from stdin.
- NbConvertApp.ipywidgets_base_url : Unicode
Default:
'https://unpkg.com/'
URL base for ipywidgets package
- NbConvertApp.notebooks : List
Default:
[]
List of notebooks to convert. Wildcards are supported. Filenames passed positionally will be added to the list.
- NbConvertApp.output_base : Unicode
Default:
''
overwrite base name use for output files. can only be used when converting one notebook at a time.
- NbConvertApp.output_files_dir : Unicode
Default:
'{notebook_name}_files'
Directory to copy extra files (figures) to. ‘{notebook_name}’ in the string will be converted to notebook basename
- NbConvertApp.postprocessor_class : DottedOrNone
Default:
''
PostProcessor class used to write the results of the conversion
- NbConvertApp.use_output_suffix : Bool
Default:
True
Whether to apply a suffix prior to the extension (only relevant when converting to notebook format). The suffix is determined by the exporter, and is usually ‘.nbconvert’.
- NbConvertApp.writer_class : DottedObjectName
Default:
'FilesWriter'
Writer class used to write the results of the conversion
- NbConvertBase.default_language : Unicode
Default:
'ipython'
Deprecated default highlight language as of 5.0, please use language_info metadata instead
- NbConvertBase.display_data_priority : List
Default:
['text/html', 'application/pdf', 'text/latex', 'image/svg+xml...
An ordered list of preferred output type, the first encountered will usually be used when converting discarding the others.
- Exporter.default_preprocessors : List
Default:
['nbconvert.preprocessors.TagRemovePreprocessor', 'nbconvert....
List of preprocessors available by default, by name, namespace, instance, or type.
- Exporter.file_extension : FilenameExtension
Default:
'.txt'
Extension of the file that should be written to disk
- Exporter.preprocessors : List
Default:
[]
List of preprocessors, by name or namespace, to enable.
- TemplateExporter.exclude_code_cell : Bool
Default:
False
This allows you to exclude code cells from all templates if set to True.
- TemplateExporter.exclude_input : Bool
Default:
False
This allows you to exclude code cell inputs from all templates if set to True.
- TemplateExporter.exclude_input_prompt : Bool
Default:
False
This allows you to exclude input prompts from all templates if set to True.
- TemplateExporter.exclude_markdown : Bool
Default:
False
This allows you to exclude markdown cells from all templates if set to True.
- TemplateExporter.exclude_output : Bool
Default:
False
This allows you to exclude code cell outputs from all templates if set to True.
- TemplateExporter.exclude_output_prompt : Bool
Default:
False
This allows you to exclude output prompts from all templates if set to True.
- TemplateExporter.exclude_raw : Bool
Default:
False
This allows you to exclude raw cells from all templates if set to True.
- TemplateExporter.exclude_unknown : Bool
Default:
False
This allows you to exclude unknown cells from all templates if set to True.
- TemplateExporter.filters : Dict
Default:
{}
Dictionary of filters, by name and namespace, to add to the Jinja environment.
- TemplateExporter.raw_mimetypes : List
Default:
[]
formats of raw cells to be included in this Exporter’s output.
- TemplateExporter.template_extension : Unicode
Default:
'.tpl'
No description
- TemplateExporter.template_file : Unicode
Default:
''
Name of the template file to use
- TemplateExporter.template_path : List
Default:
['.']
No description
- HTMLExporter.anchor_link_text : Unicode
Default:
'¶'
The text used as the text for anchor links.
- LatexExporter.template_extension : Unicode
Default:
'.tplx'
No description
- NotebookExporter.nbformat_version : 1|2|3|4
Default:
4
The nbformat version to write. Use this to downgrade notebooks.
- PDFExporter.bib_command : List
Default:
['bibtex', '{filename}']
Shell command used to run bibtex.
- PDFExporter.latex_command : List
Default:
['xelatex', '{filename}']
Shell command used to compile latex.
- PDFExporter.latex_count : Int
Default:
3
How many times latex will be called.
- PDFExporter.verbose : Bool
Default:
False
Whether to display the output of latex commands.
- SlidesExporter.font_awesome_url : Unicode
Default:
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/cs...
URL to load font awesome from.
Defaults to loading from cdnjs.
- SlidesExporter.jquery_url : Unicode
Default:
'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.m...
URL to load jQuery from.
Defaults to loading from cdnjs.
- SlidesExporter.require_js_url : Unicode
Default:
'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/req...
URL to load require.js from.
Defaults to loading from cdnjs.
- SlidesExporter.reveal_scroll : Bool
Default:
False
If True, enable scrolling within each slide
- SlidesExporter.reveal_theme : Unicode
Default:
'simple'
Name of the reveal.js theme to use.
We look for a file with this name under
reveal_url_prefix
/css/theme/reveal_theme
.css.https://github.com/hakimel/reveal.js/tree/master/css/theme has list of themes that ship by default with reveal.js.
- SlidesExporter.reveal_transition : Unicode
Default:
'slide'
Name of the reveal.js transition to use.
The list of transitions that ships by default with reveal.js are: none, fade, slide, convex, concave and zoom.
- SlidesExporter.reveal_url_prefix : Unicode
Default:
''
The URL prefix for reveal.js (version 3.x). This defaults to the reveal CDN, but can be any url pointing to a copy of reveal.js.
For speaker notes to work, this must be a relative path to a local copy of reveal.js: e.g., “reveal.js”.
If a relative path is given, it must be a subdirectory of the current directory (from which the server is run).
See the usage documentation (https://nbconvert.readthedocs.io/en/latest/usage.html#reveal-js-html-slideshow) for more details.
- Preprocessor.enabled : Bool
Default:
False
No description
- CSSHTMLHeaderPreprocessor.highlight_class : Unicode
Default:
'.highlight'
CSS highlight class identifier
- ClearOutputPreprocessor.remove_metadata_fields : Set
Default:
{'scrolled', 'collapsed'}
No description
- ConvertFiguresPreprocessor.from_format : Unicode
Default:
''
Format the converter accepts
- ConvertFiguresPreprocessor.to_format : Unicode
Default:
''
Format the converter writes
- ExecutePreprocessor.allow_errors : Bool
Default:
False
If False (default), when a cell raises an error the execution is stopped and a CellExecutionError is raised. If True, execution errors are ignored and the execution is continued until the end of the notebook. Output from exceptions is included in the cell output in both cases.
- ExecutePreprocessor.force_raise_errors : Bool
Default:
False
If False (default), errors from executing the notebook can be allowed with a raises-exception tag on a single cell, or the allow_errors configurable option for all cells. An allowed error will be recorded in notebook output, and execution will continue. If an error occurs when it is not explicitly allowed, a CellExecutionError will be raised. If True, CellExecutionError will be raised for any error that occurs while executing the notebook. This overrides both the allow_errors option and the raises-exception cell tag.
- ExecutePreprocessor.interrupt_on_timeout : Bool
Default:
False
If execution of a cell times out, interrupt the kernel and continue executing other cells rather than throwing an error and stopping.
- ExecutePreprocessor.iopub_timeout : Int
Default:
4
The time to wait (in seconds) for IOPub output. This generally doesn’t need to be set, but on some slow networks (such as CI systems) the default timeout might not be long enough to get all messages.
- ExecutePreprocessor.kernel_manager_class : Type
Default:
'builtins.object'
The kernel manager class to use.
- ExecutePreprocessor.kernel_name : Unicode
Default:
''
Name of kernel to use to execute the cells. If not set, use the kernel_spec embedded in the notebook.
- ExecutePreprocessor.raise_on_iopub_timeout : Bool
Default:
False
If False (default), then the kernel will continue waiting for iopub messages until it receives a kernel idle message, or until a timeout occurs, at which point the currently executing cell will be skipped. If True, then an error will be raised after the first timeout. This option generally does not need to be used, but may be useful in contexts where there is the possibility of executing notebooks with memory-consuming infinite loops.
- ExecutePreprocessor.shutdown_kernel : ‘graceful’|’immediate’
Default:
'graceful'
If graceful (default), then the kernel is given time to clean up after executing all cells, e.g., to execute its atexit hooks. If immediate, then the kernel is signaled to immediately terminate.
- ExecutePreprocessor.startup_timeout : Int
Default:
60
The time to wait (in seconds) for the kernel to start. If kernel startup takes longer, a RuntimeError is raised.
- ExecutePreprocessor.timeout : Int
Default:
30
The time to wait (in seconds) for output from executions. If a cell execution takes longer, an exception (TimeoutError on python 3+, RuntimeError on python 2) is raised.
None or -1 will disable the timeout. If timeout_func is set, it overrides timeout.
- ExecutePreprocessor.timeout_func : Any
Default:
None
A callable which, when given the cell source as input, returns the time to wait (in seconds) for output from cell executions. If a cell execution takes longer, an exception (TimeoutError on python 3+, RuntimeError on python 2) is raised.
Returning None or -1 will disable the timeout for the cell. Not setting timeout_func will cause the preprocessor to default to using the timeout trait for all cells. The timeout_func trait overrides timeout if it is not None.
- ExtractOutputPreprocessor.extract_output_types : Set
Default:
{'image/svg+xml', 'image/jpeg', 'application/pdf', 'image/png'}
No description
- ExtractOutputPreprocessor.output_filename_template : Unicode
Default:
'{unique_key}_{cell_index}_{index}{extension}'
No description
- HighlightMagicsPreprocessor.languages : Dict
Default:
{}
Syntax highlighting for magic’s extension languages. Each item associates a language magic extension such as %%R, with a pygments lexer such as r.
- RegexRemovePreprocessor.patterns : List
Default:
[]
No description
- SVG2PDFPreprocessor.command : Unicode
Default:
''
The command to use for converting SVG to PDF
This string is a template, which will be formatted with the keys to_filename and from_filename.
The conversion call must read the SVG from {from_flename}, and write a PDF to {to_filename}.
- SVG2PDFPreprocessor.inkscape : Unicode
Default:
''
The path to Inkscape, if necessary
- TagRemovePreprocessor.remove_all_outputs_tags : Set
Default:
set()
Tags indicating cells for which the outputs are to be removed,matches tags in cell.metadata.tags.
- TagRemovePreprocessor.remove_cell_tags : Set
Default:
set()
Tags indicating which cells are to be removed,matches tags in cell.metadata.tags.
- TagRemovePreprocessor.remove_input_tags : Set
Default:
set()
Tags indicating cells for which input is to be removed,matches tags in cell.metadata.tags.
- TagRemovePreprocessor.remove_single_output_tags : Set
Default:
set()
Tags indicating which individual outputs are to be removed,matches output i tags in cell.outputs[i].metadata.tags.
- WriterBase.files : List
Default:
[]
List of the files that the notebook references. Files will be included with written output.
- FilesWriter.build_directory : Unicode
Default:
''
Directory to write output(s) to. Defaults to output to the directory of each notebook. To recover previous default behaviour (outputting to the current working directory) use . as the flag value.
- FilesWriter.relpath : Unicode
Default:
''
When copying files that the notebook depends on, copy them in relation to this path, such that the destination filename will be os.path.relpath(filename, relpath). If FilesWriter is operating on a notebook that already exists elsewhere on disk, then the default will be the directory containing that notebook.
- ServePostProcessor.browser : Unicode
Default:
''
Specify what browser should be used to open slides. See https://docs.python.org/3/library/webbrowser.html#webbrowser.register to see how keys are mapped to browser executables. If not specified, the default browser will be determined by the webbrowser standard library module, which allows setting of the BROWSER environment variable to override it.
- ServePostProcessor.ip : Unicode
Default:
'127.0.0.1'
The IP address to listen on.
- ServePostProcessor.open_in_browser : Bool
Default:
True
Should the browser be opened automatically?
- ServePostProcessor.port : Int
Default:
8000
port for the server to listen on.
- ServePostProcessor.reveal_cdn : Unicode
Default:
'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.5.0'
URL for reveal.js CDN.
- ServePostProcessor.reveal_prefix : Unicode
Default:
'reveal.js'
URL prefix for reveal.js
Customizing nbconvert¶
Under the hood, nbconvert uses Jinja templates to specify how the notebooks should be formatted. These templates can be fully customized, allowing you to use nbconvert to create notebooks in different formats with different styles as well.
Converting a notebook to an (I)Python script and printing to stdout¶
Out of the box, nbconvert can be used to convert notebooks to plain
Python files. For example, the following command converts the
example.ipynb
notebook to Python and prints out the result:
In [1]:
!jupyter nbconvert --to python 'example.ipynb' --stdout
[NbConvertApp] Converting notebook example.ipynb to python
# coding: utf-8
# # Example notebook
# ### Markdown cells
#
# This is an example notebook that can be converted with `nbconvert` to different formats. This is an example of a markdown cell.
# ### LaTeX Equations
#
# Here is an equation:
#
# $$
# y = \sin(x)
# $$
# ### Code cells
# In[1]:
print("This is a code cell that produces some output")
# ### Inline figures
# In[1]:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
From the code, you can see that non-code cells are also exported. If you wanted to change that behaviour, you would first look to nbconvert configuration options page to see if there is an option available that can give you your desired behaviour.
In this case, if you wanted to remove code cells from the output, you
could use the TemplateExporter.exclude_markdown
traitlet directly,
as below.
In [2]:
!jupyter nbconvert --to python 'example.ipynb' --stdout --TemplateExporter.exclude_markdown=True
[NbConvertApp] Converting notebook example.ipynb to python
# coding: utf-8
# In[1]:
print("This is a code cell that produces some output")
# In[1]:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
Custom Templates¶
As mentioned above, if you want to change this behavior, you can use a custom template. The custom template inherits from the Python template and overwrites the markdown blocks so that they are empty.
Below is an example of a custom template, which we write to a file
called simplepython.tpl
. This template removes markdown cells from
the output, and also changes how the execution count numbers are
formatted:
In [3]:
%%writefile simplepython.tpl
{% extends 'python.tpl'%}
## remove markdown cells
{% block markdowncell -%}
{% endblock markdowncell %}
## change the appearance of execution count
{% block in_prompt %}
# [{{ cell.execution_count if cell.execution_count else ' ' }}]:
{% endblock in_prompt %}
Overwriting simplepython.tpl
Using this template, we see that the resulting Python code does not
contain anything that was previously in a markdown cell, and only
displays execution counts (i.e., [#]:
not In[#]:
):
In [4]:
!jupyter nbconvert --to python 'example.ipynb' --stdout --template=simplepython.tpl
[NbConvertApp] Converting notebook example.ipynb to python
# coding: utf-8
# [1]:
print("This is a code cell that produces some output")
# [1]:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
Template structure¶
Nbconvert templates consist of a set of nested blocks. When defining a new template, you extend an existing template by overriding some of the blocks.
All the templates shipped in nbconvert have the basic structure described here, though some may define additional blocks.
In [5]:
from IPython.display import HTML, display
with open('template_structure.html') as f:
display(HTML(f.read()))
Main page
Outputs
Extra HTML blocks
basic.tpl
full.tpl
<head>
</head>
Extra Latex blocks
A few gotchas¶
Jinja blocks use {% %}
by default which does not play nicely with
LaTeX, so those are replaced by ((* *))
in LaTeX templates.
Templates using cell tags¶
The notebook file format supports attaching arbitrary JSON metadata to
each cell. In addition, every cell has a special tags
metadata field
that accepts a list of strings that indicate the cell’s tags. To apply
these, go to the View → CellToolbar → Tags
option which will create
a Tag editor at the top of every cell.
First choose a notebook you want to convert to html, and apply the tags:
"Easy"
, "Medium"
, or "Hard"
.
With this in place, the notebook can be converted using a custom template.
Design your template in the cells provided below.
Hint: tags are located at cell.metadata.tags
, the following Python
code collects the value of the tag:
cell['metadata'].get('tags', [])
Which you can then use inside a Jinja template as in the following:
In [6]:
%%writefile mytemplate.tpl
{% extends 'full.tpl'%}
{% block any_cell %}
{% if 'Hard' in cell['metadata'].get('tags', []) %}
<div style="border:thin solid red">
{{ super() }}
</div>
{% elif 'Medium' in cell['metadata'].get('tags', []) %}
<div style="border:thin solid orange">
{{ super() }}
</div>
{% elif 'Easy' in cell['metadata'].get('tags', []) %}
<div style="border:thin solid green">
{{ super() }}
</div>
{% else %}
{{ super() }}
{% endif %}
{% endblock any_cell %}
Overwriting mytemplate.tpl
Now, if we collect the result of using nbconvert with this template, and display the resulting html, we see the following:
In [7]:
example = !jupyter nbconvert --to html 'example.ipynb' --template=mytemplate.tpl --stdout
example = example[3:] # have to remove the first three lines which are not proper html
from IPython.display import HTML, display
display(HTML('\n'.join(example)))
Example notebook¶
Markdown cells¶
This is an example notebook that can be converted with nbconvert
to different formats. This is an example of a markdown cell.
LaTeX Equations¶
Here is an equation:
$$ y = \sin(x) $$Code cells¶
print("This is a code cell that produces some output")
Inline figures¶
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
Templates using custom cell metadata¶
We demonstrated above how to use cell
tags in a template to apply custom styling to a notebook. But remember,
the notebook file format supports attaching arbitrary JSON metadata to
each cell, not only cell tags. Here, we describe an exercise for using
an example.difficulty
metadata field (rather than cell tags) to do
the same as before (to mark up different cells as being “Easy”, “Medium”
or “Hard”).
How to edit cell metadata¶
To edit the cell metadata from within the notebook, go to the menu item:
View → Cell Toolbar → Edit Metadata
. This will bring up a toolbar
above each cell with a button that says “Edit Metadata”. Click this
button, and a field will pop up in which you will directly edit the cell
metadata JSON.
NB: Because it is JSON, you will need to ensure that what you write is valid JSON.
Template challenges: dealing with missing custom metadata fields¶
One of the challenges of dealing with custom metadata is to handle the case where the metadata is not present on every cell. This can get somewhat tricky because of JSON objects tendency to be deeply nested coupled with Python’s (and therefore Jinja’s) approach to calling into dictionaries. Specifically, the following code will error:
foo = {}
foo["bar"]
Accordingly, it is better to use the `{}.get
method <https://docs.python.org/3.6/library/stdtypes.html#dict.get>`__
which allows you to set a default value to return if no key is found as
the second argument.
Hint: if your metadata items are located at
cell.metadata.example.difficulty
, the following Python code would
get the value defaulting to an empty string (''
) if nothing is
found:
cell['metadata'].get('example', {}).get('difficulty', '')
Exercise: Write a template for handling custom metadata¶
Now, write a template that will look for Easy
, Medium
and
Hard
metadata values for the cell.metadata.example.difficulty
field and wrap them in a div with a green, orange, or red thin solid
border (respectively).
NB: This is the same design and logic as used in the previous cell tag example.
How to get example.ipynb
¶
We have provided an example file in example.ipynb
in the nbconvert
documentation that has already been marked up with both tags and the
above metadata for you to test with. You can get it from this link to
the raw
file
or by cloning the repository from
GitHub and navingating to
nbconvert/docs/source/example.ipynb
.
Convert example.ipynb
using cell tags¶
First, make sure that you can reproduce the previous result using the cell tags template that we have provided above.
Easy: If you want to make it easy on yourself, create a new file
my_template.tpl
in the same directory as example.ipynb
and copy
the contents of the cell we use to write mytemplate.tpl
to the file
system.
Then run
jupyter nbconvert --to html 'example.ipynb' --template=mytemplate.tpl
and see if your
Moderate: If you want more of a challenge, try recreating the jinja template by modifying the following jinja template file:
{% extends 'full.tpl'%}
{% block any_cell %}
<div style="border:thin solid red">
{{ super() }}
</div>
{% endblock any_cell %}
Hard: If you want even more of a challenge, try recreating the jinja template from scratch.
Write your template¶
Once you’ve done at least the Easy version of the previous step, try
modifying your template to use cell.metadata.example.difficulty
fields rather than cell tags.
Convert example.ipynb
with formatting from custom metadata¶
Once you’ve written your template, try converting example.ipynb
using the following command (making sure that your_template.tpl
is
in your local directory where you are running the command):
jupyter nbconvert --to html 'example.ipynb' --template=your_template.tpl --stdout
The resulting display should pick out different cells to be bordered with green, orange, or red.
If you do that successfullly, the resulting html document should look like the following cell’s contents:
example
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
<!-- MathJax configuration -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true,
processEnvironments: true
},
// Center justify equations in code and markdown cells. Elsewhere
// we use CSS to left justify single line equations in code cells.
displayAlign: 'center',
"HTML-CSS": {
styles: {'.MathJax_Display': {"margin": 0}},
linebreaks: { automatic: true }
}
});
</script>
<!-- End of mathjax configuration --></head>
<div class="container" id="notebook-container">
<div style="border:thin solid red">
Example notebook¶
</div>
Markdown cells¶
This is an example notebook that can be converted with nbconvert to different formats. This is an example of a markdown cell.
LaTeX Equations¶
Here is an equation:
<div style="border:thin solid green">
Code cells¶
</div>
In [1]:
<div class="input_area">
print("This is a code cell that produces some output")
Inline figures¶
In [1]:
<div class="input_area">
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
Out[1]:
In [ ]:
<div class="input_area">