(advanced/sphinx-config)=
Jupyter Book uses the excellent documentation tool Sphinx to build your book and manage citations, cross-references, and extensibility.
While Jupyter Book comes pre-configured with several Sphinx extensions, power-users may wish to add their own extensions and configuration. This page describes how to do so.
:::{warning} Adding your own Sphinx configuration and extensions may cause Jupyter Book to behave unpredictably. Use at your own risk! :::
To enable your own Sphinx extensions when building a Jupyter Book, use the following
configuration in your _config.yml
file:
sphinx:
extra_extensions:
- extension1
- extension2
Any extensions that are listed will be appended to the list of Sphinx extensions at build time.
:::{note} Make sure that you have your extension installed on your machine, or Sphinx won't know how to build the extensions. :::
By default, Jupyter Book ships with tabs via sphinx-design
.
There are other packages for tabs in the Sphinx ecosystem with different functionality.
One-such package is sphinx-inline-tabs
, which allows for syncronized tabs in case you'd like your tabs to shift across the page at the same time.
sphinx-inline-tabs
is not included with Jupyter Book by default, but we can activate it with Jupyter Book like so:
-
Install
sphinx-inline-tabs
. Here's the command to do so:pip install sphinx-inline-tabs
-
Add
sphinx-inline-tabs
content to your book. Here's an example with MyST Markdown:First two tabs showing off defining a function. ````{tab} Python ```python def main(): return ``` ```` ````{tab} C++ ```c++ int main(const int argc, const char **argv) { return 0; } ``` ```` Second two tabs showing off printing. ````{tab} Python ```python print("Hello World!") ``` ```` ````{tab} C++ ```c++ #include <iostream> int main() { std::cout << "Hello World!" << std::endl; } ``` ````
-
Activate
sphinx-inline-tabs
in_config.yml
. Thesphinx-inline-tabs
documentation says we activate it in Sphinx by addingextensions = ["sphinx_inline_tabs"]
, so we'll add it to our Jupyter Book like so:sphinx: extra_extensions: - sphinx_inline_tabs
Now, Jupyter Book will know how to interpret the {tab}
directive
(and any other directives that sphinx-inline-tabs
supports).
For example, here is a rendered version of the tab code pasted above:
First two tabs showing off defining a function.
```python
def main():
return
```
```c++
int main(const int argc, const char **argv) {
return 0;
}
```
Second two tabs showing off printing.
```python
print("Hello World!")
```
```c++
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
}
```
(config:sphinx:local_extensions)=
Sphinx is able to use local extensions by adding additional directories to the Python path. You can use local extensions by
specifying them as local_extensions
in the _config.yml
file.
To add a local extension that requires a path, use:
sphinx:
local_extensions:
<name>: <path>
This will append to the list of extensions already loaded by Jupyter Book and update the sys.path
so
the local extension can be found.
(sphinx:configuration)=
You may also directly override the key-value pairs that Sphinx normally has
you configure in conf.py
. To do so, use the following section of _config.yml
:
sphinx:
config:
key1: value1
key2: value2
By default, any values in your sphinx: config:
section will entirely replace the default configurations set by Jupyter Book.
For example, if values are dictionaries, the whole dictionary will be replaced, not just the keys that you specify in _config.yml
.
Alternatively, you can override default configurations recursively with the recursive_update
option in the sphinx:
section.
In this case, only the values you specify in sphinx: config:
will overwrite their defaults, and the configuration you do not specify will remain.
You can trigger this behavior like so:
sphinx:
recursive_update: true
config:
# Sphinx Configuration options to be added recursively
This option defaults to false
.
:::{tip}
If you wish to inspect a conf.py
representation of the generated configuration,
which Jupyter Book will pass to Sphinx, you can run from the command-line:
jb config sphinx mybookname/
:::
Sphinx provides support for many different themes to control the look and feel of the output. Jupyter Book uses the Sphinx Book Theme by default, but it is possible to use any Sphinx theme for your Jupyter Book by directly configuring Sphinx.
For example, if you wished to use the PyData Sphinx Theme, you could install the theme with:
pip install pydata-sphinx-theme
and then configure your book like so:
...
sphinx:
config:
html_theme: pydata_sphinx_theme
...
When you build your book, the PyData theme will be used. In this case, you should consult the PyData theme documentation for information about how to configure it.
:::{warning} While you may choose any theme, there is some Jupyter Book configuration that only works with the Sphinx Book Theme, so some functionality may not be present if you choose a custom theme. For example, the Launch Buttons are not supported in most Sphinx themes. :::
As discussed in the components of Jupyter Book, two of the main components of Jupyter Book are Sphinx extensions; MyST-Parser for Markdown parsing, and MyST-NB for notebook execution and output rendering.
These two extensions are highly customizable via Sphinx configuration.
Some of their configuration is already exposed in the _config.yml
, but you can also directly set configuration, see:
- the MyST-Parser configuration options
- the MyST-NB configuration options
(sphinx/tex-macros)=
You can add LaTeX macros for the whole book by defining them under the Macros
option of the TeX
block. For example, the following two macros have been pre-defined in the Sphinx configuration
sphinx:
config:
mathjax_config:
tex:
macros:
"N": "\\mathbb{N}"
"floor": ["\\lfloor#1\\rfloor", 1]
"bmat" : ["\\left[\\begin{array}"]
"emat" : ["\\end{array}\\right]"]
You can also define TeX macros for a specific file by introducing them at the beginning of the file under a math
directive. For example
```{math}
\newcommand\N{\mathbb{N}}
\newcommand\floor[1]{\lfloor#1\rfloor}
\newcommand{\bmat}{\left[\begin{array}}
\newcommand{\emat}{\end{array}\right]}
```
The commands can be used inside a math
directive, $$
, or in-line $
. For example,
$$
A = \bmat{} 1 & 1 \\ 2 & 1\\ 3 & 2 \emat{},\ b=\bmat{} 2\\ 3 \\ 4\emat{},\ \gamma = 0.5
$$
will be rendered as:
$$
A = \bmat{} 1 & 1 \\ 2 & 1\\ 3 & 2 \emat{},\ b=\bmat{} 2\\ 3 \\ 4\emat{},\ \gamma = 0.5
$$
:::{seealso} How MyST-Parser works with MathJax, and the section on math and equations. :::
:::{important}
To have "bare" LaTeX rendered in HTML, enable the amsmath
extension in your _config.yml
:
parse:
myst_enable_extensions:
# don't forget to list any other extensions you want enabled,
# including those that are enabled by default!
- amsmath
Then you can include:
\begin{equation}
\int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}
\end{equation}
which renders as
\begin{equation} \int_0^\infty \frac{x^3}{e^x-1},dx = \frac{\pi^4}{15} \end{equation}
:::
You can initiate builds for a custom builder using:
jb build <project> --builder=custom --custom-builder=<builder-name>
Advanced sphinx
users may find an extension that builds a different type of output from
the Sphinx AST such as sphinx-tojupyter
which is an extension for building notebooks that only includes basic
markdown.
[sphinx-tojupyter](https://github.com/QuantEcon/sphinx-tojupyter) will be deprecated once
`myst` syntax rendering support is available in jupyter notebooks.
You can enable the jupyter
builder by adding it to the _config.yml
sphinx:
extra_extensions: [sphinx_tojupyter]
and using the custom
option via jupyter-book
:
jb build <project> --builder=custom --custom-builder=jupyter
**Developers:** When using other output targets, the package will need to support specifying the
`mime` type priority for `myst_nb` compatibility.
See [this code](https://github.com/QuantEcon/sphinx-tojupyter/blob/ef85226e5e3e30903b62ddda24d8a32d36687944/sphinx_tojupyter/__init__.py#L124) for
further details