Skip to content

Commit 90ea4e7

Browse files
authored
Move label generating code to one place (#269)
* Move label generating code to one place. * Address other labels. Fix wrong/ambiguous labels used. * Also make HTML anchor unambiguous. * Fix internal option/return value links for simplified RST output.
1 parent a8f0773 commit 90ea4e7

File tree

48 files changed

+168
-81
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+168
-81
lines changed

changelogs/fragments/269-refs.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
bugfixes:
2+
- "Fix internal links to options and return values in simplified RST output (https://github.com/ansible-community/antsibull-docs/pull/269)."
3+
- "Include role in role attribute references (https://github.com/ansible-community/antsibull-docs/pull/269)."

src/antsibull_docs/data/docsite/ansible-docsite/macros/attributes.rst.j2

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

77
{% from 'macros/version_added.rst.j2' import version_added_rst %}
88

9-
{% macro in_rst(attributes, role_entrypoint=None) %}
9+
{% macro in_rst(attributes, attribute_html_prefix='', role_entrypoint=None) %}
1010
.. tabularcolumns:: \X{2}{10}\X{3}{10}\X{5}{10}
1111

1212
.. list-table::
@@ -24,17 +24,17 @@
2424
* - .. raw:: html
2525

2626
<div class="ansible-option-cell">
27-
<div class="ansibleOptionAnchor" id="attribute-@{ attribute | e }@"></div>
27+
<div class="ansibleOptionAnchor" id="attribute-@{ parameter_html_prefix }@@{ attribute | e }@"></div>
2828

29-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@__attribute-@{ attribute }@:
29+
.. _@{ rst_attribute_ref(plugin_name, plugin_type, role_entrypoint=role_entrypoint, attribute=attribute) }@:
3030

3131
.. rst-class:: ansible-option-title
3232

3333
**@{ attribute }@**
3434

3535
.. raw:: html
3636

37-
<a class="ansibleOptionLink" href="#attribute-@{ attribute | e }@" title="Permalink to this attribute"></a>
37+
<a class="ansibleOptionLink" href="#attribute-@{ parameter_html_prefix }@@{ attribute | e }@" title="Permalink to this attribute"></a>
3838

3939
.. raw:: html
4040

src/antsibull_docs/data/docsite/ansible-docsite/macros/parameters.rst.j2

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{% from 'macros/deprecates.rst.j2' import in_html as deprecates_html with context %}
1111
{% from 'macros/version_added.rst.j2' import version_added_rst, version_added_html %}
1212

13-
{% macro in_rst(elements, suboption_key='suboptions', parameter_html_prefix='', parameter_rst_prefix='', role_entrypoint=None) %}
13+
{% macro in_rst(elements, suboption_key='suboptions', parameter_html_prefix='', role_entrypoint=None) %}
1414
.. tabularcolumns:: \X{1}{3}\X{2}{3}
1515

1616
.. list-table::
@@ -38,7 +38,7 @@
3838
{% endif %}
3939

4040
{% for full_key in value['full_keys_rst'] %}
41-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@__parameter-@{ parameter_rst_prefix }@{% for part in full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}:
41+
.. _@{ rst_option_ref(plugin_name, plugin_type, role_entrypoint=role_entrypoint, option=full_key) }@:
4242
{% endfor %}
4343

4444
.. rst-class:: ansible-option-title
@@ -180,7 +180,7 @@
180180

181181
{##################################################################################################################}
182182

183-
{% macro in_html(elements, suboption_key='suboptions', parameter_html_prefix='', parameter_rst_prefix='', role_entrypoint=None) %}
183+
{% macro in_html(elements, suboption_key='suboptions', parameter_html_prefix='', role_entrypoint=None) %}
184184
.. raw:: html
185185

186186
<table class="colwidths-auto ansible-option-table docutils align-default" style="width: 100%">

src/antsibull_docs/data/docsite/ansible-docsite/macros/returnvalues.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
{% endif %}
3737

3838
{% for full_key in value['full_keys_rst'] %}
39-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@__return-{% for part in full_key %}@{ part }@{% if not loop.last %}/{% endif %}{% endfor %}:
39+
.. _@{ rst_return_value_ref(plugin_name, plugin_type, role_entrypoint=role_entrypoint, return_value=full_key) }@:
4040
{% endfor %}
4141

4242
.. rst-class:: ansible-option-title

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

+3-3
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

@@ -76,7 +76,7 @@
7676
To install it, use: @{ collection | collection_install | rst_code }@.
7777
{% if doc['requirements'] %}
7878
You need further requirements to be able to use this {% if plugin_type == 'module' %}module{% else %}@{ plugin_type }@ plugin{% endif %},
79-
see :ref:`Requirements <ansible_collections.@{plugin_name}@_@{plugin_type}@_requirements>` for details.
79+
see :ref:`Requirements <@{ rst_requirements_ref(plugin_name, plugin_type) }@>` for details.
8080
{% endif %}
8181

8282
To use it in a playbook, specify: :code:`@{plugin_name}@`.
@@ -150,7 +150,7 @@ Aliases: @{ ', '.join(doc['aliases'] | sort) }@
150150
.. Requirements
151151

152152
{% if doc['requirements'] -%}
153-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@_requirements:
153+
.. _@{ rst_requirements_ref(plugin_name, plugin_type) }@:
154154

155155
Requirements
156156
------------

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

+4-4
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

@@ -130,9 +130,9 @@ Parameters
130130
^^^^^^^^^^
131131

132132
{% if use_html_blobs %}
133-
@{ parameters_html(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', parameter_rst_prefix=entry_point ~ '__', role_entrypoint=entry_point) }@
133+
@{ parameters_html(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', role_entrypoint=entry_point) }@
134134
{% else %}
135-
@{ parameters_rst(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', parameter_rst_prefix=entry_point ~ '__', role_entrypoint=entry_point) }@
135+
@{ parameters_rst(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', role_entrypoint=entry_point) }@
136136
{% endif %}
137137
{% endif %}
138138

@@ -143,7 +143,7 @@ Parameters
143143
Attributes
144144
----------
145145

146-
@{ attributes_rst(ep_doc['attributes'], role_entrypoint=entry_point) }@
146+
@{ attributes_rst(ep_doc['attributes'], attribute_html_prefix=entry_point ~ '--', role_entrypoint=entry_point) }@
147147
{% endif %}
148148

149149
.. Notes

src/antsibull_docs/data/docsite/simplified-rst/macros/attributes.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
{% for attribute, data in attributes | dictsort %}
1818
{# attribute name #}
1919

20-
* - .. _ansible_collections.@{plugin_name}@_@{plugin_type}@__attribute-@{ attribute }@:
20+
* - .. _@{ rst_attribute_ref(plugin_name, plugin_type, role_entrypoint=role_entrypoint, attribute=attribute) }@:
2121

2222
**@{ attribute }@**
2323

src/antsibull_docs/data/docsite/simplified-rst/macros/parameters.rst.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{% from 'macros/deprecates.rst.j2' import in_html as deprecates_html with context %}
99
{% from 'macros/version_added.rst.j2' import version_added_html %}
1010

11-
{% macro in_html(elements, suboption_key='suboptions', parameter_html_prefix='', parameter_rst_prefix='', role_entrypoint=None) %}
11+
{% macro in_html(elements, suboption_key='suboptions', parameter_html_prefix='', role_entrypoint=None) %}
1212
.. raw:: html
1313

1414
<table style="width: 100%;">

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ To check whether it is installed, run ``ansible-galaxy collection list``.
4848
To install it, use: @{ collection | collection_install | rst_code }@.
4949
{% if doc['requirements'] %}
5050
You need further requirements to be able to use this {% if plugin_type == 'module' %}module{% else %}@{ plugin_type }@ plugin{% endif %},
51-
see `Requirements <ansible_collections.@{plugin_name}@_@{plugin_type}@_requirements_>`_ for details.
51+
see `Requirements <@{ rst_requirements_ref(plugin_name, plugin_type) }@_>`_ for details.
5252
{% endif %}
5353

5454
To use it in a playbook, specify: ``@{plugin_name}@``.
@@ -108,7 +108,7 @@ Aliases: @{ ', '.join(doc['aliases'] | sort) }@
108108
{% endif %}
109109

110110
{% if doc['requirements'] -%}
111-
.. _ansible_collections.@{plugin_name}@_@{plugin_type}@_requirements:
111+
.. _@{ rst_requirements_ref(plugin_name, plugin_type) }@:
112112

113113
Requirements
114114
------------

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ The below requirements are needed on the remote host and/or the local controller
9393
Parameters
9494
^^^^^^^^^^
9595

96-
@{ parameters_html(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', parameter_rst_prefix=entry_point ~ '__', role_entrypoint=entry_point) }@
96+
@{ parameters_html(ep_doc['options'] | dictsort, suboption_key='options', parameter_html_prefix=entry_point ~ '--', role_entrypoint=entry_point) }@
9797
{% endif %}
9898

9999
{% if ep_doc['attributes'] %}

src/antsibull_docs/jinja2/environment.py

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

1515
from ..markup.rstify import rst_code, rst_escape
16+
from ..rst_labels import (
17+
get_attribute_ref,
18+
get_option_ref,
19+
get_plugin_ref,
20+
get_requirements_ref,
21+
get_return_value_ref,
22+
)
1623
from ..utils.collection_name_transformer import CollectionNameTransformer
1724
from . import FilenameGenerator, OutputFormat
1825
from .filters import (
@@ -38,7 +45,7 @@
3845

3946
def reference_plugin_rst(plugin_name: str, plugin_type: str) -> str:
4047
fqcn = f"{plugin_name}"
41-
return f"\\ :ref:`{rst_escape(fqcn)} <ansible_collections.{fqcn}_{plugin_type}>`\\ "
48+
return f"\\ :ref:`{rst_escape(fqcn)} <{get_plugin_ref(fqcn, plugin_type)}>`\\ "
4249

4350

4451
def reference_plugin_rst_simplified(plugin_name: str, plugin_type: str) -> str:
@@ -139,6 +146,11 @@ def doc_environment(
139146

140147
env.globals["reference_plugin_rst"] = make_reference_plugin_rst(output_format)
141148
env.globals["referable_envvars"] = referable_envvars
149+
env.globals["rst_plugin_ref"] = get_plugin_ref
150+
env.globals["rst_requirements_ref"] = get_requirements_ref
151+
env.globals["rst_attribute_ref"] = get_attribute_ref
152+
env.globals["rst_option_ref"] = get_option_ref
153+
env.globals["rst_return_value_ref"] = get_return_value_ref
142154
env.filters["rst_ify"] = make_rst_ify(output_format)
143155
env.filters["html_ify"] = html_ify
144156
env.filters["fmt"] = rst_fmt

src/antsibull_docs/markup/rstify.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def plugin_option_like_link(
6969
) -> t.Optional[str]:
7070
if current_plugin:
7171
ref = massage_rst_label("/".join(name))
72-
ep = f"{entrypoint}__" if entrypoint is not None else ""
72+
ep = f"{entrypoint}--" if entrypoint is not None else ""
7373
prefix = "return" if what == "retval" else "parameter"
7474
return f"{prefix}-{ep}{ref}_"
7575
return self.plugin_link(plugin)
@@ -83,7 +83,7 @@ def _custom_format_option_like(
8383
) -> str:
8484
plugin = part.plugin
8585
if url and url.endswith("_"):
86-
plugin_text = f" (`link <{url}>`_)"
86+
plugin_text = f" (`link <#{url[:-1]}>`_)"
8787
elif plugin:
8888
plugin_result = [plugin.type]
8989
if plugin.type not in ("module", "role", "playbook"):

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/roles.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@
2121
parse_plugin_name,
2222
parse_return_value,
2323
)
24-
from antsibull_docs.utils.rst import massage_rst_label
24+
from antsibull_docs.rst_labels import (
25+
get_option_ref,
26+
get_plugin_ref,
27+
get_return_value_ref,
28+
)
2529

2630
from .sphinx_helper import extract_explicit_title
2731

2832
logger = logging.getLogger(__name__)
2933

3034

31-
def _plugin_ref(plugin_fqcn: str, plugin_type: str) -> str:
32-
return f"ansible_collections.{plugin_fqcn}_{plugin_type}"
33-
34-
3535
def _create_option_reference(
3636
plugin_fqcn: str | None,
3737
plugin_type: str | None,
@@ -40,9 +40,7 @@ def _create_option_reference(
4040
) -> str | None:
4141
if not plugin_fqcn or not plugin_type:
4242
return None
43-
ref = massage_rst_label(option.replace(".", "/"))
44-
ep = f"{entrypoint}__" if entrypoint is not None else ""
45-
return f"{_plugin_ref(plugin_fqcn, plugin_type)}__parameter-{ep}{ref}"
43+
return get_option_ref(plugin_fqcn, plugin_type, entrypoint, option.split("."))
4644

4745

4846
def _create_return_value_reference(
@@ -53,9 +51,9 @@ def _create_return_value_reference(
5351
) -> str | None:
5452
if not plugin_fqcn or not plugin_type:
5553
return None
56-
ref = massage_rst_label(return_value.replace(".", "/"))
57-
ep = f"{entrypoint}__" if entrypoint is not None else ""
58-
return f"{_plugin_ref(plugin_fqcn, plugin_type)}__return-{ep}{ref}"
54+
return get_return_value_ref(
55+
plugin_fqcn, plugin_type, entrypoint, return_value.split(".")
56+
)
5957

6058

6159
def _create_ref_or_not(
@@ -277,7 +275,7 @@ def plugin_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
277275
refnode = addnodes.pending_xref(
278276
plugin_fqcn, nodes.inline(rawtext, title), **options
279277
)
280-
refnode["reftarget"] = _plugin_ref(plugin_fqcn, plugin_type)
278+
refnode["reftarget"] = get_plugin_ref(plugin_fqcn, plugin_type)
281279

282280
return [refnode], []
283281

0 commit comments

Comments
 (0)