1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
"""
This module adds cross-reference types which are used in the documentation of Django and Sphinx to
allow intersphinx mappings to these custom types.
The supported text roles are:
Django:
* ``:setting:``, e.g. ``:setting:`INSTALLED_APPS``` renders as :setting:`INSTALLED_APPS`
* ``:templatetag:``, e.g. ``:templatetag:`block``` renders as :templatetag:`block`
* ``:templatefilter:``, e.g. ``:templatefilter:`add``` renders as :templatefilter:`add`
* ``:fieldlookup:``, e.g. ``:fieldlookup:`equals``` renders as :fieldlookup:`equals`
Sphinx:
* ``:event:``, e.g. ``:event:`autodoc-skip-member``` renders as :event:`autodoc-skip-member`
* ``:confval:``, e.g. ``:confval:`extensions``` renders as :confval:`extensions`
This module can also be used separately in ``conf.py``::
extensions = [
"sphinxcontrib_django.roles",
]
"""
from __future__ import annotations
import django
import os
import logging
import sys
from sphinx.application import Sphinx
from sphinx.config import Config
from sphinx.errors import ExtensionError
from . import __version__
logger = logging.getLogger(__name__)
def setup(app: Sphinx) -> dict:
"""
Allow this module to be used as Sphinx extension.
This is also called from the top-level :meth:`~sphinxcontrib_django.setup`.
It adds cross-reference types via :meth:`~sphinx.application.Sphinx.add_crossref_type`.
:param app: The Sphinx application object
"""
# Load sphinx.ext.intersphinx extension
app.setup_extension("sphinx.ext.intersphinx")
# Add default intersphinx mappings after config is initialized
app.connect("config-inited", add_default_intersphinx_mappings)
# Allow intersphinx mappings to custom Django roles
django_crossref_types = ["setting", "templatetag", "templatefilter", "fieldlookup"]
# Allow intersphinx mappings to custom Sphinx roles
sphinx_crossref_types = ["event", "confval"]
for crossref_type in django_crossref_types + sphinx_crossref_types:
try:
app.add_crossref_type(directivename=crossref_type, rolename=crossref_type)
except ExtensionError as e:
logger.warning("Unable to register cross-reference type: %s", e)
return {
"version:": __version__,
"parallel_read_safe": True,
"parallel_write_safe": True,
}
def add_default_intersphinx_mappings(app: Sphinx, config: Config) -> None:
"""
This function provides a default intersphinx mapping to the documentations of Python, Django
and Sphinx if ``intersphinx_mapping`` is not given in ``conf.py``.
Called on the :event:`config-inited` event.
:param app: The Sphinx application object
:param config: The Sphinx configuration
"""
def check_object_path(key, url, path):
if os.path.isfile(path):
return {key: (url, path)}
return {}
if not config.intersphinx_mapping:
DEFAULT_INTERSPHINX_MAPPING = {}
DEFAULT_INTERSPHINX_MAPPING.update(
check_object_path(
'python',
f"https://docs.python.org/{sys.version_info.major}.{sys.version_info.minor}/",
f"/usr/share/doc/python{sys.version_info.major}.{sys.version_info.minor}/html/objects.inv"
)
)
DEFAULT_INTERSPHINX_MAPPING.update(
check_object_path(
'sphinx',
'https://www.sphinx-doc.org/en/master/',
'/usr/share/doc/sphinx-doc/html/objects.inv'
)
)
DEFAULT_INTERSPHINX_MAPPING.update(
check_object_path(
'django',
'https://docs.djangoproject.com/en/' + '.'.join((str(c) for c in django.VERSION[:2])) + '/_objects/',
'/usr/share/doc/python-django-doc/html/objects.inv'
)
)
# TYPING: type hints are missing `.intersphinx_mapping` attribute.
config.intersphinx_mapping = DEFAULT_INTERSPHINX_MAPPING # type: ignore[attr-defined ]
|