esbonio.tutorial extension’s aim is to make it easy to export tutorials written as part of
your project’s documentation to Jupyter Notebooks allowing the reader to follow along
in an interactive environment and further explore for themselves.
With online services such as Binder it’s also possible to create fully interactive online versions of your tutorials allowing the user to just try things out bypassing any (potentially) complicated setup steps.
This extension is available through the
esbonio-extensions Python package but the
tutorial extra is required due to some additional dependencies.
$ pip install esbonio-extensions[tutorial]
Ensure the extension is enabled by including
extensions list inside your project’s
extensions = [ "esbonio.tutorial", ]
Tutorials are then written in the same way as you would write any other Sphinx based documentation. Here is a simple “Hello, World!” Python tutorial.
:tutorial: notebook Hello World =========== Here is how you print the string ``Hello, World!`` in Python:: print("Hello, World!")
Note the only thing specific to this extension is the
field list at the start of the document to indicate
that this document is a tutorial.
This extension includes a Sphinx Builder called
that can then be used to export tutorials as
$ sphinx-build -b tutorial docs/ docs/_build/
docs/_build/tutorial directory, there should then be a
file containing the “Hello, World!” tutorial.
If you want your tutorials to include exercises that the reader is meant to solve
solution directive can be used to insert solutions.
Solution (click to reveal)
x = 1 + 3 print(x)
- .. solution::#
Mark the content of the directive as being the solution to a tutorial exercise.
.. solution:: .. code-block:: python x = 1 + 3 print(x)
Since the notebook version of the tutorial is generated from your documentation you can also leverage Sphinx’s Internationalization support to produce translated versions of your tutorials!
If you are already familair with producing translated versions of your documentation
then the process is almost identicial, just replace your final build step with one
that invokes the
tutorial builder e.g.
$ SPHINXOPTS=-Dlanguage=cy make tutorial
If you haven’t worked with translations before, here is a brief overview of a potential translation workflow, be sure to check the documentation for details.
Install the sphinx-intl package
$ pip install sphinx-intl
conf.pyto specify where to store your translation strings
locale_dirs = ["locale/"] gettext_compact = False # optional.
Extract your translation strings from the documentation for each of your target languages
$ make gettext $ sphinx-intl update -p _build/gettext -l cy # -l fr -l de ... etc.
This will produce a folder
locale/<language_code>/LC_MESSAGESfor each language you specified containing
*.pofiles ready to be translated.
Translate each of the files in the
locale/<language_code>/LC_MESSAGESfolder for your language. A
*.pofile is a long sequence of
#: ../../extensions/tutorial/hello-world.rst:4 msgid "Hello World" msgstr ""
msgidcorresponds with the text to be translated, to provide a translation “simply” replace the empty string next to
msgstrwith the translation for the string above and save the file
#: ../../extensions/tutorial/hello-world.rst:4 msgid "Hello World" msgstr "Shwmae i gyd"
Assuming that you build your docs with something like the default Makefile you can produce a translated build by setting the
SPHINXOPTSenvironment variable to specify the language.
$ SPHINXOPTS=-Dlanguage=cy make tutorial
Once you’ve written and exported your tutorials, you probably want to make them accessible to your users. Below are a few examples on ways you could distribute them.
Perhaps the most straightforward way is to package the tutorial alongside your project. You could then provide a cli command that will automate the process of copying the tutorial into a location on the user’s machine and starting up a Jupyter Lab instance.
The exported tutorial can be bundled in your Python package using the
Data Files support built into setuptools. This requires you to add the
following flag to your
[options] include_package_data = True
Additionally you need to specify the folder(s) to include in your
MANIFEST.in file (create one in the same folder as your
file if you don’t have one already). To use the
package as an example, you would add the following line
recursive-include esbonio/tutorial/demo *
If it’s setup correctly, you should see your tutorial files listed in the build output when you run
$ python setup.py sdist bdist_wheel ... adding 'esbonio/tutorial/__init__.py' adding 'esbonio/tutorial/__main__.py' adding 'esbonio/tutorial/commands.py' adding 'esbonio/tutorial/demo/extensions/tutorial/formatting-example.ipynb' adding 'esbonio/tutorial/demo/extensions/tutorial/hello-world.ipynb' adding 'esbonio/tutorial/demo/extensions/tutorial/solution-example.ipynb' adding 'esbonio/tutorial/demo/resources/extensions/tutorial/formatting-example/vscode-screenshot.png' adding 'esbonio/tutorial/demo/resources/extensions/tutorial/solution-example/solution-example-soln-01.py' adding 'esbonio/tutorial/demo/resources/extensions/tutorial/solution-example/solution-example-soln-02.py' adding 'esbonio/tutorial/demo/resources/extensions/tutorial/solution-example/solution-example-soln-03.py' adding 'esbonio_extensions-0.0.2.dist-info/LICENSE' adding 'esbonio_extensions-0.0.2.dist-info/METADATA' adding 'esbonio_extensions-0.0.2.dist-info/WHEEL' adding 'esbonio_extensions-0.0.2.dist-info/top_level.txt' adding 'esbonio_extensions-0.0.2.dist-info/RECORD'