This repository provides User Manual for setting up a Docker environment tailored for testing DGTD code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.7 KiB

8 months ago
"""The metadata collector components for sphinx.environment."""
from __future__ import annotations
from typing import TYPE_CHECKING, cast
from docutils import nodes
from sphinx.environment.collectors import EnvironmentCollector
if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from sphinx.util.typing import ExtensionMetadata
class MetadataCollector(EnvironmentCollector):
"""metadata collector for sphinx.environment."""
def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None:
env.metadata.pop(docname, None)
def merge_other(self, app: Sphinx, env: BuildEnvironment,
docnames: set[str], other: BuildEnvironment) -> None:
for docname in docnames:
env.metadata[docname] = other.metadata[docname]
def process_doc(self, app: Sphinx, doctree: nodes.document) -> None:
"""Process the docinfo part of the doctree as metadata.
Keep processing minimal -- just return what docutils says.
"""
index = doctree.first_child_not_matching_class(nodes.PreBibliographic) # type: ignore[arg-type]
if index is None:
return
elif isinstance(doctree[index], nodes.docinfo):
md = app.env.metadata[app.env.docname]
for node in doctree[index]: # type: ignore[attr-defined]
# nodes are multiply inherited...
if isinstance(node, nodes.authors):
authors = cast(list[nodes.author], node)
md['authors'] = [author.astext() for author in authors]
elif isinstance(node, nodes.field):
assert len(node) == 2
field_name = cast(nodes.field_name, node[0])
field_body = cast(nodes.field_body, node[1])
md[field_name.astext()] = field_body.astext()
elif isinstance(node, nodes.TextElement):
# other children must be TextElement
# see: https://docutils.sourceforge.io/docs/ref/doctree.html#bibliographic-elements # NoQA: E501
md[node.__class__.__name__] = node.astext()
for name, value in md.items():
if name == 'tocdepth':
try:
value = int(value)
except ValueError:
value = 0
md[name] = value
doctree.pop(index)
def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(MetadataCollector)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}