diff --git a/.readthedocs.yaml b/.readthedocs.yaml index f64e6bd310..cbc25285b3 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -13,6 +13,9 @@ sphinx: # Set the version of Python and other tools you might need build: + # Install Graphviz to build SVG files + apt_packages: + - "graphviz" os: ubuntu-22.04 tools: python: "3.11" diff --git a/docs/conf.py b/docs/conf.py index 1325f2da36..cc4e4a8306 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,8 +16,12 @@ import sys import pybamm +# Path for repository root sys.path.insert(0, os.path.abspath("../")) +# Path for local Sphinx extensions +sys.path.append(os.path.abspath("./sphinxext/")) + # -- Project information ----------------------------------------------------- @@ -41,16 +45,21 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + # Sphinx extensions "sphinx.ext.autodoc", "sphinx.ext.doctest", "sphinx.ext.intersphinx", "sphinx.ext.mathjax", "sphinx.ext.viewcode", "sphinx.ext.napoleon", + "sphinx.ext.inheritance_diagram", + # Local and custom extensions + "extend_parent", + "inheritance_diagram", + # Third-party extensions "sphinx_design", "sphinx_copybutton", "myst_parser", - "sphinx_extend_parent", "sphinx_inline_tabs", "sphinxcontrib.bibtex", "sphinx_last_updated_by_git", @@ -60,13 +69,6 @@ "hoverxref.extension", ] -# -- sphinxcontrib-bibtex configuration -------------------------------------- -bibtex_bibfiles = ["../pybamm/CITATIONS.bib"] -bibtex_style = "unsrt" -bibtex_footbibliography_header = """.. rubric:: References""" -bibtex_reference_style = "author_year" -bibtex_tooltips = True - napoleon_use_rtype = True napoleon_google_docstring = False @@ -273,6 +275,14 @@ "matplotlib": ("https://matplotlib.org/stable/", None), } +# -- sphinxcontrib-bibtex configuration -------------------------------------- + +bibtex_bibfiles = ["../pybamm/CITATIONS.bib"] +bibtex_style = "unsrt" +bibtex_footbibliography_header = """.. rubric:: References""" +bibtex_reference_style = "author_year" +bibtex_tooltips = True + # -- nbsphinx configuration options ------------------------------------------ nbsphinx_prolog = r""" @@ -336,6 +346,57 @@ hoverxref_tooltip_theme = ["tooltipster-shadow", "tooltipster-shadow-custom"] +# -- sphinxext/inheritance_diagram.py options -------------------------------- + +graphviz_output_format = "svg" +inheritance_graph_attrs = dict( + rankdir="TB", + size='"10.0, 10.0"', + fontsize=10, + ratio="auto", + center="true", + nodesep=5, + ranksep=0.35, + bgcolor="white", +) +inheritance_node_attrs = dict( + shape="box", + fontsize=14, + fontname="monospace", + height=0.20, + color="black", + style="filled", +) +inheritance_edge_attrs = dict( + arrowsize=0.75, + style='"setlinewidth(0.5)"', +) + +# -- Options for sphinx-hoverxref -------------------------------------------- + +# Hoverxref settings + +hoverxref_default_type = "tooltip" +hoverxref_auto_ref = True + +hoverxref_roles = ["class", "meth", "func", "ref", "term"] +hoverxref_role_types = dict.fromkeys(hoverxref_roles, "tooltip") + +hoverxref_domains = ["py"] + +# Currently, only projects that are hosted on readthedocs + CPython, NumPy, and +# SymPy are supported +hoverxref_intersphinx = list(intersphinx_mapping.keys()) + +# Tooltips settings +hoverxref_tooltip_lazy = False +hoverxref_tooltip_maxwidth = 750 +hoverxref_tooltip_animation = "fade" +hoverxref_tooltip_animation_duration = 1 +hoverxref_tooltip_content = "Loading information..." +hoverxref_tooltip_theme = ["tooltipster-shadow", "tooltipster-shadow-custom"] + + # -- Jinja templating -------------------------------------------------------- # Credit to: https://ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/ diff --git a/docs/source/_static/pybamm.css b/docs/source/_static/pybamm.css index 02620d3b17..d0628ba4e1 100644 --- a/docs/source/_static/pybamm.css +++ b/docs/source/_static/pybamm.css @@ -130,7 +130,7 @@ html[data-theme="dark"] .sd-shadow-sm { html[data-theme="dark"] .sd-card .sd-card-header { background-color: var(--pst-color-background); - color: #150458 !important; + color: #459db9 !important; } html[data-theme="dark"] .sd-card .sd-card-footer { diff --git a/docs/source/user_guide/installation/install-from-source.rst b/docs/source/user_guide/installation/install-from-source.rst index b8961f9891..1eaf3ae229 100644 --- a/docs/source/user_guide/installation/install-from-source.rst +++ b/docs/source/user_guide/installation/install-from-source.rst @@ -30,6 +30,7 @@ To install PyBaMM, you will need: - A BLAS library (for instance `openblas `_). - A C compiler (ex: ``gcc``). - A Fortran compiler (ex: ``gfortran``). +- ``graphviz`` (optional), if you wish to build the documentation locally. You can install the above with @@ -37,7 +38,7 @@ You can install the above with .. code:: bash - sudo apt install python3.X python3.X-dev libopenblas-dev gcc gfortran + sudo apt install python3.X python3.X-dev libopenblas-dev gcc gfortran graphviz Where ``X`` is the version sub-number. @@ -45,7 +46,12 @@ You can install the above with .. code:: bash - brew install python openblas gcc gfortran libomp + brew install python openblas gcc gfortran graphviz libomp + +.. note:: + + On Windows, you can install ``graphviz`` using the `Chocolatey `_ package manager, or + follow the instructions on the `graphviz website `_. Finally, we recommend using `Nox `_. You can install it with diff --git a/sphinx_extend_parent.py b/docs/sphinxext/extend_parent.py similarity index 100% rename from sphinx_extend_parent.py rename to docs/sphinxext/extend_parent.py diff --git a/docs/sphinxext/inheritance_diagram.py b/docs/sphinxext/inheritance_diagram.py new file mode 100644 index 0000000000..29c60726c3 --- /dev/null +++ b/docs/sphinxext/inheritance_diagram.py @@ -0,0 +1,37 @@ +# Sphinx extension to add an inheritance diagram in the docstring of a class built upon +# the built-in sphinxext.inheritance_diagram extension. The inheritance diagram is +# generated via graphviz and the fully qualified name of the class. + +from inspect import getmro, isclass + + +def add_diagram(app, what, name, obj, options, lines): + # if it is not a class, do nothing + if not isclass(obj): + return + # if it is a model or submodel class, add the inheritance diagram + else: + # get the fully qualified name of the class + cls_name = f"{obj.__module__}.{obj.__qualname__}" + # check if the class is a model or submodel + if "pybamm.models" in cls_name: + # check if the class derives from another class + if not len(getmro(obj)) > 2: + # do nothing if it is not a derived class + return + + # Append the inheritance diagram to the docstring + lines.append("\n") + lines.append(".. dropdown:: View inheritance diagram for this model") + lines.append(" :animate: fade-in-slide-down") + lines.append(" :icon: eye\n") + lines.append(" :class-title: sd-align-major-center sd-fs-6 \n") + lines.append(" :class-container: sd-text-info \n") + lines.append("\n") + lines.append(" .. inheritance-diagram:: " + cls_name) + lines.append(" :parts: 2\n") + lines.append("\n") + + +def setup(app): + app.connect("autodoc-process-docstring", add_diagram)