Skip to content

Commit 8709d51

Browse files
committed
Move label generating code to one place.
1 parent 5ef98a4 commit 8709d51

File tree

11 files changed

+187
-83
lines changed

11 files changed

+187
-83
lines changed

src/antsibull_docs/data/docsite/ansible-docsite/plugin-error.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
.. Anchors
2020

21-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@:
21+
.. _@{ rst_plugin_ref(plugin_name, plugin_type) }@:
2222

2323
.. Title
2424

src/antsibull_docs/data/docsite/ansible-docsite/plugin-redirect.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
.. Anchors
1515

16-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@:
16+
.. _@{ rst_plugin_ref(plugin_name, plugin_type) }@:
1717

1818
.. Title
1919

src/antsibull_docs/data/docsite/ansible-docsite/plugin-tombstone.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
.. Anchors
1515

16-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@:
16+
.. _@{ rst_plugin_ref(plugin_name, plugin_type) }@:
1717

1818
.. Title
1919

src/antsibull_docs/data/docsite/ansible-docsite/plugin.rst.j2

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
.. Anchors
3232

33-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@:
33+
.. _@{ rst_plugin_ref(plugin_name, plugin_type) }@:
3434

3535
.. Anchors: short name for ansible.builtin
3636

@@ -84,7 +84,7 @@
8484
To install it, use: @{ collection | collection_install | rst_code }@.
8585
{% if doc['requirements'] %}
8686
You need further requirements to be able to use this {% if plugin_type == 'module' %}module{% else %}@{ plugin_type }@ plugin{% endif %},
87-
see :ref:`Requirements <ansible_collections.@{plugin_name}@_@{plugin_type}@_requirements>` for details.
87+
see :ref:`Requirements <@{ rst_requirements_ref(plugin_name, plugin_type) }@>` for details.
8888
{% endif %}
8989

9090
To use it in a playbook, specify: :code:`@{plugin_name}@`.

src/antsibull_docs/data/docsite/ansible-docsite/role.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
.. Anchors
2727

28-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@:
28+
.. _@{ rst_plugin_ref(plugin_name, plugin_type) }@:
2929

3030
.. Title
3131

src/antsibull_docs/jinja2/environment.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from jinja2 import BaseLoader, Environment, FileSystemLoader, PackageLoader
1414

1515
from ..markup.rstify import rst_code, rst_escape
16+
from ..rst_labels import get_plugin_ref, get_requirements_ref
1617
from ..utils.collection_name_transformer import CollectionNameTransformer
1718
from . import FilenameGenerator, OutputFormat
1819
from .filters import (
@@ -38,7 +39,7 @@
3839

3940
def reference_plugin_rst(plugin_name: str, plugin_type: str) -> str:
4041
fqcn = f"{plugin_name}"
41-
return f"\\ :ref:`{rst_escape(fqcn)} <ansible_collections.{fqcn}_{plugin_type}>`\\ "
42+
return f"\\ :ref:`{rst_escape(fqcn)} <{get_plugin_ref(fqcn, plugin_type)}>`\\ "
4243

4344

4445
def reference_plugin_rst_simplified(plugin_name: str, plugin_type: str) -> str:
@@ -139,6 +140,8 @@ def doc_environment(
139140

140141
env.globals["reference_plugin_rst"] = make_reference_plugin_rst(output_format)
141142
env.globals["referable_envvars"] = referable_envvars
143+
env.globals["rst_plugin_ref"] = get_plugin_ref
144+
env.globals["rst_requirements_ref"] = get_requirements_ref
142145
env.filters["rst_ify"] = make_rst_ify(output_format)
143146
env.filters["html_ify"] = html_ify
144147
env.filters["fmt"] = rst_fmt

src/antsibull_docs/rst_labels.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Author: Felix Fontein <[email protected]>
2+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
3+
# https://www.gnu.org/licenses/gpl-3.0.txt)
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
# SPDX-FileCopyrightText: 2023, Ansible Project
6+
"""
7+
Label helpers.
8+
"""
9+
10+
from __future__ import annotations
11+
12+
from antsibull_docs.utils.rst import massage_rst_label
13+
14+
15+
def get_plugin_ref(plugin_fqcn: str, plugin_type: str) -> str:
16+
return f"ansible_collections.{plugin_fqcn}_{plugin_type}"
17+
18+
19+
def get_attribute_ref(
20+
plugin_fqcn: str,
21+
plugin_type: str,
22+
role_entrypoint: str | None,
23+
attribute: str,
24+
) -> str:
25+
ref = massage_rst_label(attribute)
26+
ep = (
27+
f"{role_entrypoint}__"
28+
if role_entrypoint is not None and plugin_type == "role"
29+
else ""
30+
)
31+
return f"{get_plugin_ref(plugin_fqcn, plugin_type)}__attribute-{ep}{ref}"
32+
33+
34+
def get_option_ref(
35+
plugin_fqcn: str,
36+
plugin_type: str,
37+
role_entrypoint: str | None,
38+
option: list[str],
39+
) -> str:
40+
ref = "/".join(massage_rst_label(part) for part in option)
41+
ep = (
42+
f"{role_entrypoint}__"
43+
if role_entrypoint is not None and plugin_type == "role"
44+
else ""
45+
)
46+
return f"{get_plugin_ref(plugin_fqcn, plugin_type)}__parameter-{ep}{ref}"
47+
48+
49+
def get_return_value_ref(
50+
plugin_fqcn: str,
51+
plugin_type: str,
52+
role_entrypoint: str | None,
53+
return_value: list[str],
54+
) -> str:
55+
ref = "/".join(massage_rst_label(part) for part in return_value)
56+
ep = (
57+
f"{role_entrypoint}__"
58+
if role_entrypoint is not None and plugin_type == "role"
59+
else ""
60+
)
61+
return f"{get_plugin_ref(plugin_fqcn, plugin_type)}__return-{ep}{ref}"
62+
63+
64+
def get_requirements_ref(
65+
plugin_fqcn: str,
66+
plugin_type: str,
67+
role_entrypoint: str | None = None,
68+
) -> str:
69+
ep = (
70+
f"-{role_entrypoint}"
71+
if role_entrypoint is not None and plugin_type == "role"
72+
else ""
73+
)
74+
return f"{get_plugin_ref(plugin_fqcn, plugin_type)}_requirements{ep}"

src/sphinx_antsibull_ext/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from .assets import setup_assets
2020
from .directives import setup_directives
21+
from .domains import setup_domains
2122
from .nodes import setup_nodes
2223
from .roles import setup_roles
2324

@@ -40,6 +41,9 @@ def setup(app):
4041
# Add directives
4142
setup_directives(app)
4243

44+
# Add domains
45+
setup_domains(app)
46+
4347
return {
4448
"parallel_read_safe": True,
4549
"parallel_write_safe": True,

src/sphinx_antsibull_ext/directives.py

+16-64
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
from urllib.parse import quote as _urllib_quote
1414

1515
from docutils import nodes
16-
from docutils.nodes import Element
17-
from sphinx import addnodes, domains
18-
from sphinx.builders import Builder
16+
from sphinx import addnodes
1917
from sphinx.domains.std import StandardDomain
20-
from sphinx.environment import BuildEnvironment
21-
from sphinx.locale import _
2218
from sphinx.util import logging
2319
from sphinx.util.docutils import SphinxDirective
2420
from sphinx.util.nodes import make_id
2521

26-
from antsibull_docs.utils.rst import massage_rst_label
22+
from antsibull_docs.rst_labels import (
23+
get_attribute_ref,
24+
get_option_ref,
25+
get_requirements_ref,
26+
get_return_value_ref,
27+
)
2728

2829
from .directive_helper import YAMLDirective
30+
from .domains import AnsibleDomain
2931
from .nodes import ansible_attribute, ansible_option, ansible_return_value, link_button
3032
from .schemas.ansible_links import AnsibleLinks
3133
from .schemas.ansible_plugin import (
@@ -93,51 +95,6 @@ def _run(self, content_str: str, content: AnsibleLinks) -> list[nodes.Node]:
9395
return [node]
9496

9597

96-
class AnsibleDomain(domains.Domain):
97-
name = "ansible"
98-
99-
object_types: dict[str, domains.ObjType] = {
100-
"plugin": domains.ObjType(_("plugin"), "plugin", searchprio=-1),
101-
"role_entrypoint": domains.ObjType(
102-
_("role entrypoint"), "role_entrypoint", searchprio=-1
103-
),
104-
}
105-
106-
@property
107-
def objects(self) -> dict[tuple[str, str], tuple[str, str]]:
108-
return self.data.setdefault(
109-
"objects", {}
110-
) # (objtype, name) -> docname, labelid
111-
112-
def note_object(
113-
self, objtype: str, name: str, labelid: str, location: t.Any = None
114-
) -> None:
115-
if (objtype, name) in self.objects:
116-
docname = self.objects[objtype, name][0]
117-
logger.warning(
118-
f"Duplicate {objtype} description of {name}, other instance in {docname}",
119-
location=location,
120-
)
121-
self.objects[objtype, name] = (self.env.docname, labelid)
122-
123-
def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None:
124-
"""Merge in data regarding *docnames* from a different domaindata
125-
inventory (coming from a subprocess in parallel builds).
126-
"""
127-
128-
def resolve_any_xref(
129-
self,
130-
env: BuildEnvironment,
131-
fromdocname: str,
132-
builder: Builder,
133-
target: str,
134-
node: addnodes.pending_xref,
135-
contnode: Element,
136-
) -> list[tuple[str, Element]]:
137-
"""Resolve the pending_xref *node* with the given *target*."""
138-
return []
139-
140-
14198
class _Plugin(YAMLDirective[AnsiblePlugin]):
14299
schema = AnsiblePlugin
143100

@@ -241,16 +198,12 @@ def _run(
241198
title = titles[0]
242199
self.state.document.note_explicit_target(title)
243200
std = t.cast(StandardDomain, self.env.get_domain("std"))
244-
rst_id = (
245-
f"ansible_collections.{content.fqcn}_{content.plugin_type}_requirements"
201+
rst_id = get_requirements_ref(
202+
content.fqcn, content.plugin_type, content.role_entrypoint
246203
)
247204
plugin_name = _plugin_name(content.fqcn, content.plugin_type)
248205
ref_title = f"Requirements of the {plugin_name}"
249206
if content.role_entrypoint is not None and content.plugin_type == "role":
250-
rst_id = (
251-
f"ansible_collections.{content.fqcn}_role"
252-
f"-{content.role_entrypoint}_requirements"
253-
)
254207
ref_title = f"{ref_title}, {content.role_entrypoint} entrypoint"
255208
std.note_hyperlink_target(
256209
rst_id,
@@ -270,9 +223,8 @@ class _Attribute(YAMLDirective[AnsibleAttribute]):
270223

271224
def _run(self, content_str: str, content: AnsibleAttribute) -> list[nodes.Node]:
272225
html_id = f"attribute-{_percent_encode(content.name)}"
273-
rst_id = (
274-
f"ansible_collections.{content.fqcn}_{content.plugin_type}"
275-
f"__attribute-{content.name}"
226+
rst_id = get_attribute_ref(
227+
content.fqcn, content.plugin_type, content.role_entrypoint, content.name
276228
)
277229
node = ansible_attribute(
278230
"", content.name, classes=["ansible-option-title"], ids=[html_id]
@@ -309,17 +261,16 @@ def _compile_ids(
309261
role_entrypoint: str | None,
310262
full_keys: list[list[str]],
311263
prefix_type: str,
264+
get_ref: t.Callable[[str, str, str | None, list[str]], str],
312265
) -> tuple[dict[str, tuple[str, str, str]], list[str]]:
313-
rst_id_prefix = f"ansible_collections.{fqcn}_{plugin_type}__{prefix_type}-"
314266
html_id_prefix = f"{prefix_type}-"
315267
if role_entrypoint is not None:
316-
rst_id_prefix += f"{role_entrypoint}__"
317268
html_id_prefix += f"{role_entrypoint}--"
318269
rst_ids = {}
319270
html_ids = []
320271
for full_key in full_keys:
321272
html_id = html_id_prefix + "/".join([_percent_encode(k) for k in full_key])
322-
rst_id = rst_id_prefix + "/".join([massage_rst_label(k) for k in full_key])
273+
rst_id = get_ref(fqcn, plugin_type, role_entrypoint, full_key)
323274
html_ids.append(html_id)
324275
rst_ids[rst_id] = (html_id, ".".join(full_key), ".".join(full_key[1:]))
325276
return rst_ids, _make_unique(html_ids)
@@ -335,6 +286,7 @@ def _run(self, content_str: str, content: AnsibleOption) -> list[nodes.Node]:
335286
content.role_entrypoint,
336287
content.full_keys,
337288
"parameter",
289+
get_option_ref,
338290
)
339291
node = ansible_option(
340292
"",
@@ -392,6 +344,7 @@ def _run(self, content_str: str, content: AnsibleReturnValue) -> list[nodes.Node
392344
content.role_entrypoint,
393345
content.full_keys,
394346
"return",
347+
get_return_value_ref,
395348
)
396349
node = ansible_return_value(
397350
"",
@@ -446,6 +399,5 @@ def setup_directives(app):
446399
"""
447400
Setup directives for a Sphinx app object.
448401
"""
449-
app.add_domain(AnsibleDomain)
450402
for name, directive in DIRECTIVES.items():
451403
app.add_directive(name, directive)

0 commit comments

Comments
 (0)