diff --git a/build/pkgs/sagemath_doc_html/dependencies b/build/pkgs/sagemath_doc_html/dependencies
index 1d286fe50bc..801c36fcd9e 100644
--- a/build/pkgs/sagemath_doc_html/dependencies
+++ b/build/pkgs/sagemath_doc_html/dependencies
@@ -1,4 +1,4 @@
-sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol ipywidgets jupyter_sphinx sage_docbuild elliptic_curves furo fpylll graphs
+sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol ipywidgets sage_docbuild elliptic_curves furo fpylll graphs
# Building the documentation has many dependencies, because all
# documented modules are imported and because we use matplotlib to
diff --git a/build/pkgs/sagemath_doc_html/dependencies_optional b/build/pkgs/sagemath_doc_html/dependencies_optional
new file mode 100644
index 00000000000..e9b59e89755
--- /dev/null
+++ b/build/pkgs/sagemath_doc_html/dependencies_optional
@@ -0,0 +1 @@
+jupyter_sphinx
diff --git a/configure.ac b/configure.ac
index df6a785251e..58adf54f78f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -450,7 +450,7 @@ AC_ARG_ENABLE([cvxopt],
AC_ARG_ENABLE([notebook],
AS_HELP_STRING([--disable-notebook],
[disable build of the Jupyter notebook and related packages]), [
- for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema anyio arrow async_lru fqdn isoduration json5 jsonpointer jsonschema_specifications jupyter_events jupyter_lsp jupyter_server jupyter_server_terminals jupyterlab jupyterlab_server jupyterlab_pygments jupyterlab_mathjax2 notebook_shim overrides python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator sniffio types_python_dateutil uri_template webcolors websocket_client; do
+ for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema anyio arrow async_lru fqdn isoduration json5 jsonpointer jsonschema_specifications jupyter_events jupyter_lsp jupyter_server jupyter_server_terminals jupyterlab jupyterlab_server jupyterlab_pygments jupyterlab_mathjax2 jupyter_sphinx notebook_shim overrides python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator sniffio types_python_dateutil uri_template webcolors websocket_client; do
AS_VAR_SET([SAGE_ENABLE_$pkg], [$enableval])
done
])
diff --git a/src/doc/ca/intro/conf.py b/src/doc/ca/intro/conf.py
index 71d81dcdbf3..877eba7eeb7 100644
--- a/src/doc/ca/intro/conf.py
+++ b/src/doc/ca/intro/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/de/a_tour_of_sage/conf.py b/src/doc/de/a_tour_of_sage/conf.py
index 71fc7ef9012..fb960f06ffd 100644
--- a/src/doc/de/a_tour_of_sage/conf.py
+++ b/src/doc/de/a_tour_of_sage/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/de/thematische_anleitungen/conf.py b/src/doc/de/thematische_anleitungen/conf.py
index 337f1a98c68..b8ec2573f90 100644
--- a/src/doc/de/thematische_anleitungen/conf.py
+++ b/src/doc/de/thematische_anleitungen/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/de/tutorial/conf.py b/src/doc/de/tutorial/conf.py
index 399a915e9f4..da1c19e0ffc 100644
--- a/src/doc/de/tutorial/conf.py
+++ b/src/doc/de/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/el/a_tour_of_sage/conf.py b/src/doc/el/a_tour_of_sage/conf.py
index 5548c31525e..ff4e9436313 100644
--- a/src/doc/el/a_tour_of_sage/conf.py
+++ b/src/doc/el/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py
index 7cf31297409..689eed59af3 100644
--- a/src/doc/en/a_tour_of_sage/conf.py
+++ b/src/doc/en/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/constructions/conf.py b/src/doc/en/constructions/conf.py
index b6bbbbaab3b..a28d011781c 100644
--- a/src/doc/en/constructions/conf.py
+++ b/src/doc/en/constructions/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/developer/conf.py b/src/doc/en/developer/conf.py
index e8877d61770..6e80447f4c7 100644
--- a/src/doc/en/developer/conf.py
+++ b/src/doc/en/developer/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/faq/conf.py b/src/doc/en/faq/conf.py
index 4c8a71bd9d1..a175e9cf0ee 100644
--- a/src/doc/en/faq/conf.py
+++ b/src/doc/en/faq/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/installation/conf.py b/src/doc/en/installation/conf.py
index ea6956d2678..7e6174b0d90 100644
--- a/src/doc/en/installation/conf.py
+++ b/src/doc/en/installation/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/prep/conf.py b/src/doc/en/prep/conf.py
index 645d451644d..03ff6ed7afc 100644
--- a/src/doc/en/prep/conf.py
+++ b/src/doc/en/prep/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/reference/conf.py b/src/doc/en/reference/conf.py
index 984c43363f2..92b8a8d45b4 100644
--- a/src/doc/en/reference/conf.py
+++ b/src/doc/en/reference/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release, latex_elements, exclude_patterns
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/reference/conf_sub.py b/src/doc/en/reference/conf_sub.py
index 479e9c306d2..c7adc1da994 100644
--- a/src/doc/en/reference/conf_sub.py
+++ b/src/doc/en/reference/conf_sub.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release, exclude_patterns
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/thematic_tutorials/conf.py b/src/doc/en/thematic_tutorials/conf.py
index cb6d1662f47..581a8e89fc6 100644
--- a/src/doc/en/thematic_tutorials/conf.py
+++ b/src/doc/en/thematic_tutorials/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py
index b8eef385e4f..9de7aa68adb 100644
--- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py
+++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/thematic_tutorials/numerical_sage/conf.py b/src/doc/en/thematic_tutorials/numerical_sage/conf.py
index 5772289f6fa..c8e220f8f99 100644
--- a/src/doc/en/thematic_tutorials/numerical_sage/conf.py
+++ b/src/doc/en/thematic_tutorials/numerical_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/tutorial/conf.py b/src/doc/en/tutorial/conf.py
index b566ec19677..52be3420ed1 100644
--- a/src/doc/en/tutorial/conf.py
+++ b/src/doc/en/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/en/tutorial/latex.rst b/src/doc/en/tutorial/latex.rst
index a173afd75c5..73ef2df3a31 100644
--- a/src/doc/en/tutorial/latex.rst
+++ b/src/doc/en/tutorial/latex.rst
@@ -49,7 +49,7 @@ output of the entered commands automatically. You can start this
automatic rendering by executing ``%display latex`` (and stop by executing
``%display plain``).
-.. ONLY:: html
+.. ONLY:: html and feature_jupyter_sphinx
Thus, in the Jupyter notebook, you get
diff --git a/src/doc/en/website/conf.py b/src/doc/en/website/conf.py
index 38f31e5d46f..b238169bb3c 100644
--- a/src/doc/en/website/conf.py
+++ b/src/doc/en/website/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/es/a_tour_of_sage/conf.py b/src/doc/es/a_tour_of_sage/conf.py
index dee2afa4d66..801f7cadb95 100644
--- a/src/doc/es/a_tour_of_sage/conf.py
+++ b/src/doc/es/a_tour_of_sage/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/es/tutorial/conf.py b/src/doc/es/tutorial/conf.py
index 43e23fdc568..dcb44232ca0 100644
--- a/src/doc/es/tutorial/conf.py
+++ b/src/doc/es/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/fr/a_tour_of_sage/conf.py b/src/doc/fr/a_tour_of_sage/conf.py
index af1f453f3e4..9cca4b7d1f8 100644
--- a/src/doc/fr/a_tour_of_sage/conf.py
+++ b/src/doc/fr/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/fr/tutorial/conf.py b/src/doc/fr/tutorial/conf.py
index af70d3eb4ff..38e0160f3ba 100644
--- a/src/doc/fr/tutorial/conf.py
+++ b/src/doc/fr/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/hu/a_tour_of_sage/conf.py b/src/doc/hu/a_tour_of_sage/conf.py
index b097f56dfe0..2e5215fcf5d 100644
--- a/src/doc/hu/a_tour_of_sage/conf.py
+++ b/src/doc/hu/a_tour_of_sage/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/it/a_tour_of_sage/conf.py b/src/doc/it/a_tour_of_sage/conf.py
index d06280ece36..48a568cc4d1 100644
--- a/src/doc/it/a_tour_of_sage/conf.py
+++ b/src/doc/it/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/it/faq/conf.py b/src/doc/it/faq/conf.py
index e3898184a1f..84a8ac93eab 100644
--- a/src/doc/it/faq/conf.py
+++ b/src/doc/it/faq/conf.py
@@ -15,6 +15,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import *
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/it/tutorial/conf.py b/src/doc/it/tutorial/conf.py
index 15186edb4ba..ea77f3199b0 100644
--- a/src/doc/it/tutorial/conf.py
+++ b/src/doc/it/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py
index e8ec7cca39b..eef0eba83b3 100644
--- a/src/doc/ja/a_tour_of_sage/conf.py
+++ b/src/doc/ja/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/ja/tutorial/conf.py b/src/doc/ja/tutorial/conf.py
index 9002593de99..eaaa4558a34 100644
--- a/src/doc/ja/tutorial/conf.py
+++ b/src/doc/ja/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release, latex_elements
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/pt/a_tour_of_sage/conf.py b/src/doc/pt/a_tour_of_sage/conf.py
index 267d499ca64..806bc1b77c8 100644
--- a/src/doc/pt/a_tour_of_sage/conf.py
+++ b/src/doc/pt/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/pt/tutorial/conf.py b/src/doc/pt/tutorial/conf.py
index a5cabc5b0d1..26368567ee4 100644
--- a/src/doc/pt/tutorial/conf.py
+++ b/src/doc/pt/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/ru/tutorial/conf.py b/src/doc/ru/tutorial/conf.py
index 5d39f7d2600..f2f44113045 100644
--- a/src/doc/ru/tutorial/conf.py
+++ b/src/doc/ru/tutorial/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py
index b7536470bd4..9d2a503d78d 100644
--- a/src/doc/tr/a_tour_of_sage/conf.py
+++ b/src/doc/tr/a_tour_of_sage/conf.py
@@ -13,6 +13,11 @@
from sage_docbuild.conf import release
from sage_docbuild.conf import * # NOQA
+
+for tag in feature_tags():
+ tags.add(tag)
+
+
# Add any paths that contain custom static files (such as style sheets),
# relative to this directory to html_static_path. They are copied after the
# builtin static files, so a file named "default.css" will overwrite the
diff --git a/src/sage/features/sphinx.py b/src/sage/features/sphinx.py
index ec7c8be17b6..672b826f59d 100644
--- a/src/sage/features/sphinx.py
+++ b/src/sage/features/sphinx.py
@@ -39,5 +39,33 @@ def __init__(self):
PythonModule.__init__(self, 'sphinx', spkg='sphinx', type='standard')
+class JupyterSphinx(PythonModule):
+ r"""
+ A :class:`sage.features.Feature` describing the presence of
+ :ref:`jupyter_sphinx `.
+
+ It is provided by a standard package in the Sage distribution,
+ but it can be disabled by ``configure --disable-doc`` and
+ ``configure --disable-notebook``.
+
+ EXAMPLES::
+
+ sage: from sage.features.sphinx import JupyterSphinx
+ sage: JupyterSphinx().is_present() # optional - jupyter_sphinx
+ FeatureTestResult('jupyter_sphinx', True)
+ """
+ def __init__(self):
+ r"""
+ TESTS::
+
+ sage: from sage.features.sphinx import JupyterSphinx
+ sage: isinstance(JupyterSphinx(), JupyterSphinx)
+ True
+ """
+ PythonModule.__init__(self, 'jupyter_sphinx',
+ spkg='jupyter_sphinx', type='standard')
+
+
def all_features():
- return [Sphinx()]
+ return [Sphinx(),
+ JupyterSphinx()]
diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py
index ddd64c2718f..0f0333338e3 100644
--- a/src/sage_docbuild/conf.py
+++ b/src/sage_docbuild/conf.py
@@ -27,11 +27,12 @@
import sphinx.ext.intersphinx as intersphinx
from sphinx import highlighting
from sphinx.transforms import SphinxTransform
+from sphinx.util.docutils import SphinxDirective
from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer
from sage.misc.sagedoc import extlinks
from sage.env import SAGE_DOC_SRC, SAGE_DOC, PPLPY_DOCS, MATHJAX_DIR
from sage.misc.latex_macros import sage_mathjax_macros
-from sage.features import PythonModule
+from sage.features.sphinx import JupyterSphinx
from sage.features.all import all_features
import sage.version
@@ -56,12 +57,15 @@
'sphinx_inline_tabs',
'IPython.sphinxext.ipython_directive',
'matplotlib.sphinxext.plot_directive',
- 'jupyter_sphinx',
]
+if JupyterSphinx().is_present():
+ extensions.append('jupyter_sphinx')
+
jupyter_execute_default_kernel = 'sagemath'
if SAGE_LIVE_DOC == 'yes':
+ JupyterSphinx().require()
SAGE_JUPYTER_SERVER = os.environ.get('SAGE_JUPYTER_SERVER', 'binder')
if SAGE_JUPYTER_SERVER.startswith('binder'):
# format: "binder" or
@@ -1037,6 +1041,14 @@ def apply(self):
parent.insert(index + 1, container)
+class Ignore(SphinxDirective):
+
+ has_content = True
+
+ def run(self):
+ return []
+
+
# This replaces the setup() in sage.misc.sagedoc_conf
def setup(app):
app.connect('autodoc-process-docstring', process_docstring_cython)
@@ -1050,6 +1062,12 @@ def setup(app):
app.add_transform(SagemathTransform)
if SAGE_LIVE_DOC == 'yes' or SAGE_PREPARSED_DOC == 'yes':
app.add_transform(SagecodeTransform)
+ if not JupyterSphinx().is_present():
+ app.add_directive("jupyter-execute", Ignore)
+ app.add_directive("jupyter-kernel", Ignore)
+ app.add_directive("jupyter-input", Ignore)
+ app.add_directive("jupyter-output", Ignore)
+ app.add_directive("thebe-button", Ignore)
# When building the standard docs, app.srcdir is set to SAGE_DOC_SRC +
# 'LANGUAGE/DOCNAME'.
@@ -1071,12 +1089,7 @@ def setup(app):
# https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#tags
# https://www.sphinx-doc.org/en/master/usage/configuration.html#conf-tags
# https://github.com/readthedocs/readthedocs.org/issues/4603#issuecomment-1411594800
-# Workaround to allow importing this file from other confs
-if 'tags' not in locals():
- class Tags(set):
- has = set.__contains__
- tags = Tags()
-
-
-for feature in all_features():
- tags.add('feature_' + feature.name.replace('.', '_'))
+def feature_tags():
+ for feature in all_features():
+ if feature.is_present():
+ yield 'feature_' + feature.name.replace('.', '_')