diff --git a/.constraints/py3.10.txt b/.constraints/py3.10.txt
index d16edd3d..2bec979b 100644
--- a/.constraints/py3.10.txt
+++ b/.constraints/py3.10.txt
@@ -169,11 +169,13 @@ sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
sphinx==7.2.6
+sphinx-api-relink==0.0.8
sphinx-autobuild==2021.3.14
sphinx-book-theme==1.1.0
sphinx-codeautolink==0.15.0
sphinx-copybutton==0.5.2
sphinx-design==0.5.0
+sphinx-pybtex-etal-style==0.0.2
sphinx-reredirects==0.1.3
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.8
@@ -199,6 +201,7 @@ tox==4.12.1
tqdm==4.66.1
traitlets==5.14.1
types-python-dateutil==2.8.19.20240106
+types-requests==2.31.0.20240106
typing-extensions==4.9.0
tzdata==2023.4
ujson==5.9.0
diff --git a/.constraints/py3.11.txt b/.constraints/py3.11.txt
index 6ee5d559..3df8a883 100644
--- a/.constraints/py3.11.txt
+++ b/.constraints/py3.11.txt
@@ -168,11 +168,13 @@ sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
sphinx==7.2.6
+sphinx-api-relink==0.0.8
sphinx-autobuild==2021.3.14
sphinx-book-theme==1.1.0
sphinx-codeautolink==0.15.0
sphinx-copybutton==0.5.2
sphinx-design==0.5.0
+sphinx-pybtex-etal-style==0.0.2
sphinx-reredirects==0.1.3
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.8
@@ -197,6 +199,7 @@ tox==4.12.1
tqdm==4.66.1
traitlets==5.14.1
types-python-dateutil==2.8.19.20240106
+types-requests==2.31.0.20240106
typing-extensions==4.9.0
tzdata==2023.4
ujson==5.9.0
diff --git a/.constraints/py3.12.txt b/.constraints/py3.12.txt
index 6a03ad6b..85ff39bf 100644
--- a/.constraints/py3.12.txt
+++ b/.constraints/py3.12.txt
@@ -168,11 +168,13 @@ sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
sphinx==7.2.6
+sphinx-api-relink==0.0.8
sphinx-autobuild==2021.3.14
sphinx-book-theme==1.1.0
sphinx-codeautolink==0.15.0
sphinx-copybutton==0.5.2
sphinx-design==0.5.0
+sphinx-pybtex-etal-style==0.0.2
sphinx-reredirects==0.1.3
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.8
@@ -197,6 +199,7 @@ tox==4.12.1
tqdm==4.66.1
traitlets==5.14.1
types-python-dateutil==2.8.19.20240106
+types-requests==2.31.0.20240106
typing-extensions==4.9.0
tzdata==2023.4
ujson==5.9.0
diff --git a/.constraints/py3.8.txt b/.constraints/py3.8.txt
index 75d0f078..09038ad5 100644
--- a/.constraints/py3.8.txt
+++ b/.constraints/py3.8.txt
@@ -173,11 +173,13 @@ sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
sphinx==5.3.0
+sphinx-api-relink==0.0.8
sphinx-autobuild==2021.3.14
sphinx-book-theme==1.0.1
sphinx-codeautolink==0.15.0
sphinx-copybutton==0.5.2
sphinx-design==0.5.0
+sphinx-pybtex-etal-style==0.0.2
sphinx-reredirects==0.1.3
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.4
@@ -203,6 +205,7 @@ tox==4.12.1
tqdm==4.66.1
traitlets==5.14.1
types-python-dateutil==2.8.19.20240106
+types-requests==2.31.0.20240106
typing-extensions==4.9.0
tzdata==2023.4
ujson==5.9.0
diff --git a/.constraints/py3.9.txt b/.constraints/py3.9.txt
index cadc19af..b79ba4bf 100644
--- a/.constraints/py3.9.txt
+++ b/.constraints/py3.9.txt
@@ -170,11 +170,13 @@ sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
sphinx==7.2.6
+sphinx-api-relink==0.0.8
sphinx-autobuild==2021.3.14
sphinx-book-theme==1.1.0
sphinx-codeautolink==0.15.0
sphinx-copybutton==0.5.2
sphinx-design==0.5.0
+sphinx-pybtex-etal-style==0.0.2
sphinx-reredirects==0.1.3
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.8
@@ -200,6 +202,7 @@ tox==4.12.1
tqdm==4.66.1
traitlets==5.14.1
types-python-dateutil==2.8.19.20240106
+types-requests==2.31.0.20240106
typing-extensions==4.9.0
tzdata==2023.4
ujson==5.9.0
diff --git a/.gitignore b/.gitignore
index 24ae1f74..acbf8a8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ version.py
.mypy*/
.pytest_cache/
.sympy-cache*/
+.virtual_documents/
__pycache__/
htmlcov/
prof/
diff --git a/docs/_templates/module.rst_t b/docs/_templates/module.rst_t
deleted file mode 100644
index ac37fd52..00000000
--- a/docs/_templates/module.rst_t
+++ /dev/null
@@ -1,12 +0,0 @@
-{%- if show_headings and not separate %}
-{{ basename.split(".")[-1] | e | heading }}
-
-.. code-block:: python
-
- import {{ basename }}
-
-{% endif -%}
-.. automodule:: {{ qualname }}
-{%- for option in automodule_options %}
- :{{ option }}:
-{%- endfor %}
diff --git a/docs/_templates/package.rst_t b/docs/_templates/package.rst_t
deleted file mode 100644
index 97011393..00000000
--- a/docs/_templates/package.rst_t
+++ /dev/null
@@ -1,49 +0,0 @@
-{%- macro automodule(modname, options) -%}
-.. automodule:: {{ modname }}
-{%- for option in options %}
- :{{ option }}:
-{%- endfor %}
-{%- endmacro %}
-
-{%- macro toctree(docnames) -%}
-.. toctree::
-{% for docname in docnames %}
- {{ docname }}
-{%- endfor %}
-{%- endmacro %}
-
-{{ pkgname.split(".")[-1] | e | heading }}
-
-.. code-block:: python
-
- import {{ pkgname }}
-
-{%- if modulefirst and not is_namespace %}
-{{ automodule(pkgname, automodule_options) }}
-{% endif %}
-
-{%- if not modulefirst and not is_namespace %}
-
-{{ automodule(pkgname, automodule_options) }}
-{% endif %}
-
-{%- if submodules or subpackages %}
-.. rubric:: Submodules and Subpackages
-{% endif %}
-
-{%- if subpackages %}
-
-{{ toctree(subpackages) }}
-{% endif %}
-{%- if submodules %}
-{% if separatemodules %}
-{{ toctree(submodules) }}
-{%- else %}
-{%- for submodule in submodules %}
-{% if show_headings %}
-{{- [submodule, "module"] | join(" ") | e | heading(2) }}
-{% endif %}
-{{ automodule(submodule, automodule_options) }}
-{% endfor %}
-{%- endif %}
-{% endif %}
diff --git a/docs/_templates/toc.rst_t b/docs/_templates/toc.rst_t
deleted file mode 100644
index 878540ce..00000000
--- a/docs/_templates/toc.rst_t
+++ /dev/null
@@ -1,7 +0,0 @@
-{{ header | heading }}
-
-.. toctree::
- :maxdepth: {{ maxdepth }}
-{% for docname in docnames %}
- {{ docname }}
-{%- endfor %}
diff --git a/docs/conf.py b/docs/conf.py
index 8dbcdf83..dbf1551d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,18 +1,21 @@
from __future__ import annotations
import os
-import re
import shutil
import subprocess
import sys
from datetime import datetime
-from importlib.metadata import PackageNotFoundError
-from importlib.metadata import version as get_package_version
from pathlib import Path
from textwrap import dedent, indent
-import requests # pyright: ignore[reportMissingModuleSource]
+import requests
from attrs import define, field
+from sphinx_api_relink.helpers import (
+ get_package_version,
+ pin,
+ pin_minor,
+ set_intersphinx_version_remapping,
+)
sys.path.insert(0, os.path.abspath("extensions"))
@@ -168,30 +171,6 @@ def get_timestamp() -> str:
return now.strftime("%d/%m/%Y %H:%M:%S")
-def get_polarimetry_package_version() -> str:
- try:
- return get_package_version("polarimetry")
- except PackageNotFoundError:
- return ""
-
-
-def generate_api() -> None:
- shutil.rmtree("api", ignore_errors=True)
- subprocess.call(
- " ".join([
- "sphinx-apidoc",
- "../src/polarimetry/",
- "../src/polarimetry/version.py",
- "-o api/",
- "--force",
- "--no-toc",
- "--separate",
- "--templatedir _templates",
- ]),
- shell=True, # noqa: S602
- )
-
-
def get_link_to_single_pdf() -> str:
build_file = "_build/latex/polarimetry.pdf"
embedded_file = "_static/polarimetry.pdf"
@@ -209,65 +188,14 @@ def get_link_to_single_pdf() -> str:
return ""
-def get_minor_version(package_name: str) -> str:
- installed_version = get_version(package_name)
- if installed_version == "stable":
- return installed_version
- matches = re.match(r"^([0-9]+\.[0-9]+).*$", installed_version)
- if matches is None:
- msg = f"Could not find documentation for {package_name} v{installed_version}"
- raise ValueError(msg)
- return matches[1]
-
-
def get_scipy_url() -> str:
- url = f"https://docs.scipy.org/doc/scipy-{get_version('scipy')}/"
+ url = f"https://docs.scipy.org/doc/scipy-{pin('scipy')}/"
r = requests.get(url) # noqa: S113
if r.status_code != 200:
return "https://docs.scipy.org/doc/scipy"
return url
-def get_version(package_name: str) -> str:
- python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
- constraints_path = f"../.constraints/py{python_version}.txt"
- package_name = package_name.lower()
- with open(constraints_path) as stream:
- constraints = stream.read()
- version_remapping = {
- "ipython": {
- "8.12.2": "8.12.1",
- "8.12.3": "8.12.1",
- },
- "ipywidgets": {
- "8.0.3": "8.0.5",
- "8.0.4": "8.0.5",
- "8.0.6": "8.0.5",
- "8.1.1": "8.1.2",
- },
- }
- for line in constraints.split("\n"):
- line = line.split("#")[0] # remove comments
- line = line.strip()
- line = line.lower()
- if not line.startswith(package_name):
- continue
- if not line:
- continue
- line_segments = tuple(line.split("=="))
- if len(line_segments) != 2:
- continue
- _, installed_version, *_ = line_segments
- installed_version = installed_version.strip()
- remapped_versions = version_remapping.get(package_name)
- if remapped_versions is not None:
- existing_version = remapped_versions.get(installed_version)
- if existing_version is not None:
- return existing_version
- return installed_version
- return "stable"
-
-
@define
class MissingFileCollector:
paths: list[Path] = field(factory=list)
@@ -286,10 +214,57 @@ def print(self) -> None:
execute_pluto_notebooks()
-generate_api()
+set_intersphinx_version_remapping({
+ "ipywidgets": {
+ "8.1.1": "8.1.2",
+ },
+})
+
MISSING_FILES = MissingFileCollector()
+BRANCH = "main"
+PACKAGE = "polarimetry-lc2pkpi"
+PACKAGE_NAME = "polarimetry"
+ORGANIZATION = "ComPWA"
+REPO_NAME = "polarimetry"
+
add_module_names = False
+api_github_repo = f"{ORGANIZATION}/{REPO_NAME}"
+api_target_substitutions = {
+ "Axes": "matplotlib.axes.Axes",
+ "DataSample": ("obj", "tensorwaves.interface.DataSample"),
+ "Function": ("obj", "tensorwaves.interface.Function"),
+ "LineCollection": "matplotlib.collections.LineCollection",
+ "LineshapeName": ("obj", "polarimetry.lhcb.LineshapeName"),
+ "Literal[(-1, 1)]": "typing.Literal",
+ "Literal[- 1, 1]": "typing.Literal",
+ "Literal[-1, 1]": "typing.Literal",
+ "ModelName": ("obj", "polarimetry.lhcb.ModelName"),
+ "OuterStates": ("obj", "polarimetry.decay.OuterStates"),
+ "ParameterType": ("obj", "polarimetry.lhcb.ParameterType"),
+ "ParameterValue": ("obj", "tensorwaves.interface.ParameterValue"),
+ "ParametrizedFunction": ("obj", "tensorwaves.interface.ParametrizedFunction"),
+ "Path": "pathlib.Path",
+ "Pattern": "typing.Pattern",
+ "PoolSum": "ampform.sympy.PoolSum",
+ "PositionalArgumentFunction": "tensorwaves.function.PositionalArgumentFunction",
+ "QuadContourSet": "matplotlib.contour.QuadContourSet",
+ "ResonanceName": ("obj", "polarimetry.lhcb.ResonanceName"),
+ "SympyDataTransformer": "tensorwaves.data.transform.SympyDataTransformer",
+ "UnevaluatedExpression": "ampform.sympy.UnevaluatedExpression",
+ "implement_doit_method": "ampform.sympy.implement_doit_method",
+ "polarimetry.lhcb._T": "typing.TypeVar",
+ "sp.Expr": "sympy.core.expr.Expr",
+ "sp.Indexed": "sympy.tensor.indexed.Indexed",
+ "sp.Mul": "sympy.core.mul.Mul",
+ "sp.Rational": "sympy.core.numbers.Rational",
+ "sp.Symbol": "sympy.core.symbol.Symbol",
+ "sp.acos": "sympy.functions.elementary.trigonometric.acos",
+ "typing.Literal[-1, 1]": "typing.Literal",
+}
+api_target_types = {
+ "jax.numpy.ndarray": "obj",
+}
author = "Mikhail Mikhasenko, Remco de Boer, Miriam Fritsch"
autodoc_default_options = {
"exclude-members": ", ".join([
@@ -313,6 +288,7 @@ def print(self) -> None:
bibtex_bibfiles = [
"_static/references.bib",
]
+bibtex_default_style = "unsrt_et_al"
codeautolink_concat_default = True
copyright = "2023"
default_role = "py:obj"
@@ -325,23 +301,23 @@ def print(self) -> None:
]
extensions = [
"myst_nb",
- "relink_references",
"sphinx.ext.autosectionlabel",
"sphinx.ext.githubpages",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
- "sphinx.ext.viewcode",
+ "sphinx_api_relink",
"sphinx_book_theme",
"sphinx_codeautolink",
"sphinx_copybutton",
"sphinx_design",
+ "sphinx_pybtex_etal_style",
"sphinx_reredirects",
"sphinx_togglebutton",
"sphinxcontrib.bibtex",
"sphinxcontrib.inkscapeconverter",
"support_bibtex_math",
- "unsrt_et_al",
]
+generate_apidoc_package_path = f"../src/{PACKAGE_NAME}"
html_css_files = [
"custom.css",
]
@@ -355,40 +331,69 @@ def print(self) -> None:
html_static_path = ["_static"]
html_theme = "sphinx_book_theme"
html_theme_options = {
+ "icon_links": [
+ {
+ "name": "Common Partial Wave Analysis",
+ "url": "https://compwa.github.io/_static/favicon.ico",
+ "icon": "_static/favicon.ico",
+ "type": "local",
+ },
+ {
+ "name": "GitHub",
+ "url": f"https://github.com/{ORGANIZATION}/{REPO_NAME}",
+ "icon": "fa-brands fa-github",
+ },
+ {
+ "name": "PyPI",
+ "url": f"https://pypi.org/project/{PACKAGE}",
+ "icon": "fa-brands fa-python",
+ },
+ {
+ "name": "Launch on Binder",
+ "url": f"https://mybinder.org/v2/gh/{ORGANIZATION}/{REPO_NAME}/{BRANCH}?filepath=docs",
+ "icon": "https://mybinder.readthedocs.io/en/latest/_static/favicon.png",
+ "type": "url",
+ },
+ {
+ "name": "Launch on Colaboratory",
+ "url": f"https://colab.research.google.com/github/{ORGANIZATION}/{REPO_NAME}/blob/{BRANCH}",
+ "icon": "https://avatars.githubusercontent.com/u/33467679?s=100",
+ "type": "url",
+ },
+ ],
"launch_buttons": {
"binderhub_url": "https://mybinder.org",
+ "colab_url": "https://colab.research.google.com",
+ "deepnote_url": "https://deepnote.com",
"notebook_interface": "jupyterlab",
},
+ "logo": {"text": "Λc⁺ → p K⁻ π⁺"},
"path_to_docs": "docs",
- "repository_url": "https://github.com/ComPWA/polarimetry",
- "repository_branch": "0.0.9",
+ "repository_branch": BRANCH,
+ "repository_url": f"https://github.com/{ORGANIZATION}/{REPO_NAME}",
"show_navbar_depth": 1,
"show_toc_level": 2,
- "use_repository_button": True,
- "use_edit_page_button": False,
+ "use_download_button": False,
+ "use_edit_page_button": True,
"use_issues_button": True,
+ "use_repository_button": True,
+ "use_source_button": True,
}
html_title = "Λc → p K π polarimetry"
intersphinx_mapping = {
- "IPython": (f"https://ipython.readthedocs.io/en/{get_version('IPython')}", None),
- "ampform": (f"https://ampform.readthedocs.io/en/{get_version('ampform')}", None),
- "attrs": (f"https://www.attrs.org/en/{get_version('attrs')}", None),
+ "IPython": (f"https://ipython.readthedocs.io/en/{pin('IPython')}", None),
+ "ampform": (f"https://ampform.readthedocs.io/en/{pin('ampform')}", None),
+ "attrs": (f"https://www.attrs.org/en/{pin('attrs')}", None),
"iminuit": ("https://iminuit.readthedocs.io/en/stable", None),
- "ipywidgets": (
- f"https://ipywidgets.readthedocs.io/en/{get_version('ipywidgets')}",
- None,
- ),
+ "ipywidgets": (f"https://ipywidgets.readthedocs.io/en/{pin('ipywidgets')}", None),
"jax": ("https://jax.readthedocs.io/en/latest", None),
- "matplotlib": (f"https://matplotlib.org/{get_version('matplotlib')}", None),
- "numpy": (f"https://numpy.org/doc/{get_minor_version('numpy')}", None),
+ "matplotlib": (f"https://matplotlib.org/{pin('matplotlib')}", None),
+ "numpy": (f"https://numpy.org/doc/{pin_minor('numpy')}", None),
"plotly": ("https://plotly.com/python-api-reference", None),
"python": ("https://docs.python.org/3", None),
"scipy": (get_scipy_url(), None),
"sympy": ("https://docs.sympy.org/latest", None),
- "tensorwaves": (
- f"https://tensorwaves.readthedocs.io/en/{get_version('tensorwaves')}",
- None,
- ),
+ "tensorwaves": (f"https://tensorwaves.rtfd.io/en/{pin('tensorwaves')}", None),
}
latex_documents = [
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-latex_documents
@@ -423,7 +428,7 @@ def print(self) -> None:
},
}
""",
- "releasename": f"{get_polarimetry_package_version()} ({get_timestamp()})",
+ "releasename": f"{get_package_version(PACKAGE)} ({get_timestamp()})",
}
latex_engine = "xelatex" # https://tex.stackexchange.com/a/570691
latex_show_pagerefs = True
@@ -431,6 +436,7 @@ def print(self) -> None:
"https://arxiv.org/pdf/2208.03262.pdf",
"https://arxiv.org/pdf/hep-ex/0510019.pdf",
"https://journals.aps.org/prd/pdf/10.1103/PhysRevD.101.034033",
+ "https://www.bookfinder.com",
]
myst_enable_extensions = [
"colon_fence",
@@ -482,50 +488,6 @@ def print(self) -> None:
"FIG_SUB_REGIONS": get_figure_link("_images/sub-regions.svg"),
"LINK_TO_JULIA_PAGES": get_link_to_julia_pages(),
}
-relink_ref_types = {
- "jax.numpy.ndarray": "obj",
- "polarimetry.decay.OuterStates": "obj",
- "polarimetry.lhcb.LineshapeName": "obj",
- "polarimetry.lhcb.ModelName": "obj",
- "polarimetry.lhcb.ParameterType": "obj",
- "polarimetry.lhcb.ResonanceName": "obj",
- "tensorwaves.interface.DataSample": "obj",
- "tensorwaves.interface.Function": "obj",
- "tensorwaves.interface.ParameterValue": "obj",
- "tensorwaves.interface.ParametrizedFunction": "obj",
-}
-relink_targets = {
- "Axes": "matplotlib.axes.Axes",
- "DataSample": "tensorwaves.interface.DataSample",
- "Function": "tensorwaves.interface.Function",
- "LineCollection": "matplotlib.collections.LineCollection",
- "LineshapeName": "polarimetry.lhcb.LineshapeName",
- "Literal[(-1, 1)]": "typing.Literal",
- "Literal[- 1, 1]": "typing.Literal",
- "Literal[-1, 1]": "typing.Literal",
- "ModelName": "polarimetry.lhcb.ModelName",
- "OuterStates": "polarimetry.decay.OuterStates",
- "ParameterType": "polarimetry.lhcb.ParameterType",
- "ParameterValue": "tensorwaves.interface.ParameterValue",
- "ParametrizedFunction": "tensorwaves.interface.ParametrizedFunction",
- "Path": "pathlib.Path",
- "Pattern": "typing.Pattern",
- "PoolSum": "ampform.sympy.PoolSum",
- "PositionalArgumentFunction": "tensorwaves.function.PositionalArgumentFunction",
- "QuadContourSet": "matplotlib.contour.QuadContourSet",
- "ResonanceName": "polarimetry.lhcb.ResonanceName",
- "SympyDataTransformer": "tensorwaves.data.transform.SympyDataTransformer",
- "UnevaluatedExpression": "ampform.sympy.UnevaluatedExpression",
- "implement_doit_method": "ampform.sympy.implement_doit_method",
- "polarimetry.lhcb._T": "typing.TypeVar",
- "sp.Expr": "sympy.core.expr.Expr",
- "sp.Indexed": "sympy.tensor.indexed.Indexed",
- "sp.Mul": "sympy.core.mul.Mul",
- "sp.Rational": "sympy.core.numbers.Rational",
- "sp.Symbol": "sympy.core.symbol.Symbol",
- "sp.acos": "sympy.functions.elementary.trigonometric.acos",
- "typing.Literal[-1, 1]": "typing.Literal",
-}
nb_execution_allow_errors = False
nb_execution_mode = get_execution_mode()
nb_execution_show_tb = True
@@ -551,7 +513,6 @@ def print(self) -> None:
"mystnb.unknown_mime_type",
]
use_multitoc_numbering = True
-version = get_polarimetry_package_version()
-viewcode_follow_imported_members = True
+version = get_package_version(PACKAGE)
MISSING_FILES.print()
diff --git a/docs/extensions/relink_references.py b/docs/extensions/relink_references.py
deleted file mode 100644
index c060d31d..00000000
--- a/docs/extensions/relink_references.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# cspell:ignore refdomain refspecific reftarget reftype
-# pyright: reportMissingImports=false
-# pyright: reportMissingModuleSource=false
-"""Abbreviated the annotations generated by sphinx-autodoc.
-
-It's not necessary to generate the full path of type hints, because they are
-rendered as clickable links.
-
-See also https://github.com/sphinx-doc/sphinx/issues/5868.
-"""
-from __future__ import annotations
-
-import sphinx.domains.python
-from docutils import nodes
-from sphinx.addnodes import pending_xref, pending_xref_condition
-from sphinx.application import Sphinx
-from sphinx.domains.python import parse_reftarget
-from sphinx.environment import BuildEnvironment
-
-
-def setup(app: Sphinx) -> None:
- app.add_config_value("relink_ref_types", {}, "html")
- app.add_config_value("relink_targets", {}, "html")
- sphinx.domains.python.type_to_xref = _patch_type_to_xref
-
-
-def _patch_type_to_xref(
- target: str,
- env: BuildEnvironment = None,
- suppress_prefix: bool = False,
-) -> pending_xref:
- ref_type_substitutions: dict[str, str] = env.app.config.relink_ref_types
- target_substitutions: dict[str, str] = env.app.config.relink_targets
- reftype, target, title, refspecific = parse_reftarget(target, suppress_prefix)
- target = target_substitutions.get(target, target)
- reftype = ref_type_substitutions.get(target, reftype)
- assert env is not None # noqa: S101
- return pending_xref(
- "",
- *__create_nodes(env, title),
- refdomain="py",
- reftype=reftype,
- reftarget=target,
- refspecific=refspecific,
- **__get_env_kwargs(env),
- )
-
-
-def __get_env_kwargs(env: BuildEnvironment) -> dict:
- if env:
- return {
- "py:module": env.ref_context.get("py:module"),
- "py:class": env.ref_context.get("py:class"),
- }
- return {}
-
-
-def __create_nodes(env: BuildEnvironment, title: str) -> list[nodes.Node]:
- short_name = title.split(".")[-1]
- if env.config.python_use_unqualified_type_names:
- return [
- pending_xref_condition("", short_name, condition="resolved"),
- pending_xref_condition("", title, condition="*"),
- ]
- return [nodes.Text(short_name)]
diff --git a/docs/extensions/unsrt_et_al.py b/docs/extensions/unsrt_et_al.py
deleted file mode 100644
index c07053c7..00000000
--- a/docs/extensions/unsrt_et_al.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# pyright: reportMissingImports=false
-# pyright: reportMissingModuleSource=false
-from pybtex.database import Entry
-from pybtex.plugin import register_plugin
-from pybtex.richtext import Tag, Text
-from pybtex.style.formatting.unsrt import Style as UnsrtStyle
-from pybtex.style.template import (
- FieldIsMissing,
- Node,
- _format_list, # pyright:ignore[reportPrivateUsage]
- field,
- href,
- join,
- node,
- sentence,
- words,
-)
-from sphinx.application import Sphinx
-
-
-def setup(app: Sphinx) -> None:
- register_plugin("pybtex.style.formatting", "unsrt_et_al", UnsrtEtAl)
-
-
-class UnsrtEtAl(UnsrtStyle):
- def __init__(self) -> None:
- super().__init__(abbreviate_names=True)
-
- def format_names(self, role, as_sentence: bool = True) -> Node:
- formatted_names = names(role, sep=", ", sep2=" and ", last_sep=", and ")
- if as_sentence:
- return sentence[formatted_names]
- return formatted_names
-
- def format_eprint(self, e: Entry) -> Node:
- if "doi" in e.fields:
- return ""
- return super().format_eprint(e)
-
- def format_url(self, e: Entry) -> Node:
- if "doi" in e.fields or "eprint" in e.fields:
- return ""
- return words[
- href[
- field("url", raw=True),
- field("url", raw=True, apply_func=_remove_http),
- ]
- ]
-
- def format_isbn(self, e: Entry) -> Node:
- return href[
- join[
- "https://isbnsearch.org/isbn/",
- field("isbn", raw=True, apply_func=_remove_dashes_and_spaces),
- ],
- join[
- "ISBN:",
- field("isbn", raw=True),
- ],
- ]
-
-
-@node
-def names(children, context, role, **kwargs):
- """Return formatted names."""
- assert not children # noqa: S101
- try:
- persons = context["entry"].persons[role]
- except KeyError:
- raise FieldIsMissing(role, context["entry"]) from None
-
- style: UnsrtStyle = context["style"]
- formatted_names = [
- style.format_name(person, style.abbreviate_names) for person in persons
- ]
- return et_al(**kwargs)[formatted_names].format_data(context)
-
-
-@node
-def et_al(children, data, sep="", sep2=None, last_sep=None):
- if sep2 is None:
- sep2 = sep
- if last_sep is None:
- last_sep = sep
- parts = [part for part in _format_list(children, data) if part]
- if len(parts) <= 1:
- return Text(*parts)
- if len(parts) == 2:
- return Text(sep2).join(parts)
- if len(parts) == 3:
- return Text(last_sep).join([Text(sep).join(parts[:-1]), parts[-1]])
- return Text(parts[0], Tag("em", " et al"))
-
-
-def _remove_dashes_and_spaces(isbn: str) -> str:
- to_remove = ["-", " "]
- for remove in to_remove:
- isbn = isbn.replace(remove, "")
- return isbn
-
-
-def _remove_http(url: str) -> str:
- to_remove = ["https://", "http://"]
- for remove in to_remove:
- url = url.replace(remove, "")
- return url
diff --git a/docs/references.md b/docs/references.md
index a8bd6fe8..672dfcc4 100644
--- a/docs/references.md
+++ b/docs/references.md
@@ -12,7 +12,6 @@ Download BibTeX
```{bibliography} /_static/references.bib
---
-style: unsrt_et_al
cited:
---
```
diff --git a/pyproject.toml b/pyproject.toml
index a42fa181..7b4aa435 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -66,10 +66,12 @@ doc = [
"plotly",
"psutil",
"scipy",
+ "sphinx-api-relink",
"sphinx-book-theme",
"sphinx-codeautolink[ipython]",
"sphinx-copybutton",
"sphinx-design",
+ "sphinx-pybtex-etal-style",
"sphinx-reredirects",
"sphinx-togglebutton",
"sphinxcontrib-bibtex >=2.2",
@@ -91,8 +93,8 @@ jupyter = [
]
sty = [
"black",
+ "polarimetry-lc2pkpi[types]",
"pre-commit >=1.4.0",
- "pytest",
"ruff",
]
test = [
@@ -100,6 +102,11 @@ test = [
"pytest >=6.0",
"pytest-xdist",
]
+types = [
+ "pytest",
+ "sphinx-api-relink",
+ "types-requests",
+]
[project.readme]
content-type = "text/markdown"