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"