Skip to content

Commit fc96a1f

Browse files
committed
Move label generating code to one place.
1 parent 5a6cb94 commit fc96a1f

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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 4 additions & 1 deletion
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 (
@@ -36,7 +37,7 @@
3637

3738
def reference_plugin_rst(plugin_name: str, plugin_type: str) -> str:
3839
fqcn = f"{plugin_name}"
39-
return f"\\ :ref:`{rst_escape(fqcn)} <ansible_collections.{fqcn}_{plugin_type}>`\\ "
40+
return f"\\ :ref:`{rst_escape(fqcn)} <{get_plugin_ref(fqcn, plugin_type)}>`\\ "
4041

4142

4243
def reference_plugin_rst_simplified(plugin_name: str, plugin_type: str) -> str:
@@ -137,6 +138,8 @@ def doc_environment(
137138

138139
env.globals["reference_plugin_rst"] = make_reference_plugin_rst(output_format)
139140
env.globals["referable_envvars"] = referable_envvars
141+
env.globals["rst_plugin_ref"] = get_plugin_ref
142+
env.globals["rst_requirements_ref"] = get_requirements_ref
140143
env.filters["rst_ify"] = make_rst_ify(output_format)
141144
env.filters["html_ify"] = html_ify
142145
env.filters["fmt"] = rst_fmt

src/antsibull_docs/rst_labels.py

Lines changed: 74 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 16 additions & 64 deletions
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 (
@@ -92,51 +94,6 @@ def _run(self, content_str: str, content: AnsibleLinks) -> list[nodes.Node]:
9294
return [node]
9395

9496

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

@@ -240,16 +197,12 @@ def _run(
240197
title = titles[0]
241198
self.state.document.note_explicit_target(title)
242199
std = t.cast(StandardDomain, self.env.get_domain("std"))
243-
rst_id = (
244-
f"ansible_collections.{content.fqcn}_{content.plugin_type}_requirements"
200+
rst_id = get_requirements_ref(
201+
content.fqcn, content.plugin_type, content.role_entrypoint
245202
)
246203
plugin_name = _plugin_name(content.fqcn, content.plugin_type)
247204
ref_title = f"Requirements of the {plugin_name}"
248205
if content.role_entrypoint is not None and content.plugin_type == "role":
249-
rst_id = (
250-
f"ansible_collections.{content.fqcn}_role"
251-
f"-{content.role_entrypoint}_requirements"
252-
)
253206
ref_title = f"{ref_title}, {content.role_entrypoint} entrypoint"
254207
std.note_hyperlink_target(
255208
rst_id,
@@ -269,9 +222,8 @@ class _Attribute(YAMLDirective[AnsibleAttribute]):
269222

270223
def _run(self, content_str: str, content: AnsibleAttribute) -> list[nodes.Node]:
271224
html_id = f"attribute-{_percent_encode(content.name)}"
272-
rst_id = (
273-
f"ansible_collections.{content.fqcn}_{content.plugin_type}"
274-
f"__attribute-{content.name}"
225+
rst_id = get_attribute_ref(
226+
content.fqcn, content.plugin_type, content.role_entrypoint, content.name
275227
)
276228
node = ansible_attribute(
277229
"", content.name, classes=["ansible-option-title"], ids=[html_id]
@@ -308,17 +260,16 @@ def _compile_ids(
308260
role_entrypoint: str | None,
309261
full_keys: list[list[str]],
310262
prefix_type: str,
263+
get_ref: t.Callable[[str, str, str | None, list[str]], str],
311264
) -> tuple[dict[str, tuple[str, str, str]], list[str]]:
312-
rst_id_prefix = f"ansible_collections.{fqcn}_{plugin_type}__{prefix_type}-"
313265
html_id_prefix = f"{prefix_type}-"
314266
if role_entrypoint is not None:
315-
rst_id_prefix += f"{role_entrypoint}__"
316267
html_id_prefix += f"{role_entrypoint}--"
317268
rst_ids = {}
318269
html_ids = []
319270
for full_key in full_keys:
320271
html_id = html_id_prefix + "/".join([_percent_encode(k) for k in full_key])
321-
rst_id = rst_id_prefix + "/".join([massage_rst_label(k) for k in full_key])
272+
rst_id = get_ref(fqcn, plugin_type, role_entrypoint, full_key)
322273
html_ids.append(html_id)
323274
rst_ids[rst_id] = (html_id, ".".join(full_key), ".".join(full_key[1:]))
324275
return rst_ids, _make_unique(html_ids)
@@ -334,6 +285,7 @@ def _run(self, content_str: str, content: AnsibleOption) -> list[nodes.Node]:
334285
content.role_entrypoint,
335286
content.full_keys,
336287
"parameter",
288+
get_option_ref,
337289
)
338290
node = ansible_option(
339291
"",
@@ -391,6 +343,7 @@ def _run(self, content_str: str, content: AnsibleReturnValue) -> list[nodes.Node
391343
content.role_entrypoint,
392344
content.full_keys,
393345
"return",
346+
get_return_value_ref,
394347
)
395348
node = ansible_return_value(
396349
"",
@@ -445,6 +398,5 @@ def setup_directives(app):
445398
"""
446399
Setup directives for a Sphinx app object.
447400
"""
448-
app.add_domain(AnsibleDomain)
449401
for name, directive in DIRECTIVES.items():
450402
app.add_directive(name, directive)

0 commit comments

Comments
 (0)