diff --git a/changelogs/fragments/290-empty.yml b/changelogs/fragments/290-empty.yml new file mode 100644 index 00000000..5e0d973c --- /dev/null +++ b/changelogs/fragments/290-empty.yml @@ -0,0 +1,4 @@ +bugfixes: + - "Improve handling of empty markup parameters for RST (https://github.com/ansible-community/antsibull-docs/pull/290)." +minor_changes: + - "Bump minimum dependency of ``antsibull-docs-parser`` to 1.0.2 or newer (https://github.com/ansible-community/antsibull-docs/pull/290)." diff --git a/pyproject.toml b/pyproject.toml index b5ee2d04..37dfa47a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "ansible-pygments", "antsibull-changelog >= 0.24.0", "antsibull-core >= 2.1.0, < 4.0.0", - "antsibull-docs-parser >= 1.0.0, < 2.0.0", + "antsibull-docs-parser >= 1.0.2, < 2.0.0", "asyncio-pool", "docutils", "jinja2 >= 3.0", diff --git a/src/antsibull_docs/markup/rstify.py b/src/antsibull_docs/markup/rstify.py index deceb429..206b8647 100644 --- a/src/antsibull_docs/markup/rstify.py +++ b/src/antsibull_docs/markup/rstify.py @@ -46,8 +46,14 @@ def __init__(self, referable_envvars: set[str] | None = None): def format_env_variable(self, part: dom.EnvVariablePart) -> str: envvar = part.name.split("=", 1)[0].strip() if envvar in self._referable_envvars: - return f"\\ :ansenvvarref:`{_rst_escape(part.name, True)}`\\ " - return f"\\ :ansenvvar:`{_rst_escape(part.name, True)}`\\ " + text = _rst_escape( + part.name, escape_ending_whitespace=True, must_not_be_empty=True + ) + return f"\\ :ansenvvarref:`{text}`\\ " + text = _rst_escape( + part.name, escape_ending_whitespace=True, must_not_be_empty=True + ) + return f"\\ :ansenvvar:`{text}`\\ " class SimplifiedRSTLinkProvider(LinkProvider): diff --git a/tests/functional/ansible-doc-cache-all-others.json b/tests/functional/ansible-doc-cache-all-others.json index 8d3bab67..aea6439a 100644 --- a/tests/functional/ansible-doc-cache-all-others.json +++ b/tests/functional/ansible-doc-cache-all-others.json @@ -22712,7 +22712,8 @@ "The option O(foo) exists, but O(foobar) does not.", "The return value RV(bar) exists, but RV(barbaz) does not.", "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)", - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)", + "C() I() B() C() U() L(,) R(,) V() O() RV() E()" ], "filename": "ansible_collections/ns/col2/plugins/modules/foo2.py", "has_action": false, diff --git a/tests/functional/ansible-doc-cache-all.json b/tests/functional/ansible-doc-cache-all.json index 7b5bd6fd..425e2bc0 100644 --- a/tests/functional/ansible-doc-cache-all.json +++ b/tests/functional/ansible-doc-cache-all.json @@ -22629,7 +22629,8 @@ "The option O(foo) exists, but O(foobar) does not.", "The return value RV(bar) exists, but RV(barbaz) does not.", "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)", - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)", + "C() I() B() C() U() L(,) R(,) V() O() RV() E()" ], "filename": "ansible_collections/ns/col2/plugins/modules/foo2.py", "has_action": false, diff --git a/tests/functional/ansible-doc-cache-ansible.builtin-ns.col2-ns2.col.json b/tests/functional/ansible-doc-cache-ansible.builtin-ns.col2-ns2.col.json index b06f70cf..a0e6f353 100644 --- a/tests/functional/ansible-doc-cache-ansible.builtin-ns.col2-ns2.col.json +++ b/tests/functional/ansible-doc-cache-ansible.builtin-ns.col2-ns2.col.json @@ -22629,7 +22629,8 @@ "The option O(foo) exists, but O(foobar) does not.", "The return value RV(bar) exists, but RV(barbaz) does not.", "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)", - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)", + "C() I() B() C() U() L(,) R(,) V() O() RV() E()" ], "filename": "ansible_collections/ns/col2/plugins/modules/foo2.py", "has_action": false, diff --git a/tests/functional/ansible-doc-cache-ns.col1-ns.col2-ns2.col-ns2.flatcol.json b/tests/functional/ansible-doc-cache-ns.col1-ns.col2-ns2.col-ns2.flatcol.json index 20678f43..61bb6ae2 100644 --- a/tests/functional/ansible-doc-cache-ns.col1-ns.col2-ns2.col-ns2.flatcol.json +++ b/tests/functional/ansible-doc-cache-ns.col1-ns.col2-ns2.col-ns2.flatcol.json @@ -1239,7 +1239,8 @@ "The option O(foo) exists, but O(foobar) does not.", "The return value RV(bar) exists, but RV(barbaz) does not.", "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)", - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)", + "C() I() B() C() U() L(,) R(,) V() O() RV() E()" ], "filename": "ansible_collections/ns/col2/plugins/modules/foo2.py", "has_action": false, diff --git a/tests/functional/ansible-doc-cache-ns.col2.json b/tests/functional/ansible-doc-cache-ns.col2.json index 7dcfd3ef..d5fa7c00 100644 --- a/tests/functional/ansible-doc-cache-ns.col2.json +++ b/tests/functional/ansible-doc-cache-ns.col2.json @@ -804,7 +804,8 @@ "The option O(foo) exists, but O(foobar) does not.", "The return value RV(bar) exists, but RV(barbaz) does not.", "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)", - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)", + "C() I() B() C() U() L(,) R(,) V() O() RV() E()" ], "filename": "ansible_collections/ns/col2/plugins/modules/foo2.py", "has_action": false, diff --git a/tests/functional/baseline-default/collections/ns/col2/foo2_module.rst b/tests/functional/baseline-default/collections/ns/col2/foo2_module.rst index e8a646ec..fcf7285b 100644 --- a/tests/functional/baseline-default/collections/ns/col2/foo2_module.rst +++ b/tests/functional/baseline-default/collections/ns/col2/foo2_module.rst @@ -55,6 +55,7 @@ Synopsis - The return value \ :ansretval:`ns.col2.foo2#module:bar`\ exists, but \ :ansretval:`ns.col2.foo2#module:barbaz`\ does not. - Again existing: \ :ansopt:`ns.col2.foo#module:foo=1`\ , \ :ansretval:`ns.col2.foo#module:bar=2`\ - Again not existing: \ :ansopt:`ns.col2.foo#module:foobar=1`\ , \ :ansretval:`ns.col2.foo#module:barbaz=2`\ +- \ :literal:`\ `\ \ :emphasis:`\ `\ \ :strong:`\ `\ \ :literal:`\ `\ \ \ \ :ref:`\ <>`\ \ :ansval:`\ `\ \ :ansopt:`ns.col2.foo2#module:`\ \ :ansretval:`ns.col2.foo2#module:`\ \ :ansenvvar:`\ `\ .. Aliases diff --git a/tests/functional/baseline-no-breadcrumbs/collections/ns/col2/foo2_module.rst b/tests/functional/baseline-no-breadcrumbs/collections/ns/col2/foo2_module.rst index e8a646ec..fcf7285b 100644 --- a/tests/functional/baseline-no-breadcrumbs/collections/ns/col2/foo2_module.rst +++ b/tests/functional/baseline-no-breadcrumbs/collections/ns/col2/foo2_module.rst @@ -55,6 +55,7 @@ Synopsis - The return value \ :ansretval:`ns.col2.foo2#module:bar`\ exists, but \ :ansretval:`ns.col2.foo2#module:barbaz`\ does not. - Again existing: \ :ansopt:`ns.col2.foo#module:foo=1`\ , \ :ansretval:`ns.col2.foo#module:bar=2`\ - Again not existing: \ :ansopt:`ns.col2.foo#module:foobar=1`\ , \ :ansretval:`ns.col2.foo#module:barbaz=2`\ +- \ :literal:`\ `\ \ :emphasis:`\ `\ \ :strong:`\ `\ \ :literal:`\ `\ \ \ \ :ref:`\ <>`\ \ :ansval:`\ `\ \ :ansopt:`ns.col2.foo2#module:`\ \ :ansretval:`ns.col2.foo2#module:`\ \ :ansenvvar:`\ `\ .. Aliases diff --git a/tests/functional/baseline-simplified-rst/collections/ns/col2/foo2_module.rst b/tests/functional/baseline-simplified-rst/collections/ns/col2/foo2_module.rst index 5566b4d9..3400097f 100644 --- a/tests/functional/baseline-simplified-rst/collections/ns/col2/foo2_module.rst +++ b/tests/functional/baseline-simplified-rst/collections/ns/col2/foo2_module.rst @@ -30,6 +30,7 @@ Synopsis - The return value \ :literal:`bar` (`link <#return-bar>`_)\ exists, but \ :literal:`barbaz` (`link <#return-barbaz>`_)\ does not. - Again existing: \ :literal:`foo=1` (of module `ns.col2.foo `__)\ , \ :literal:`bar=2` (of module `ns.col2.foo `__)\ - Again not existing: \ :literal:`foobar=1` (of module `ns.col2.foo `__)\ , \ :literal:`barbaz=2` (of module `ns.col2.foo `__)\ +- \ :literal:`\ `\ \ :emphasis:`\ `\ \ :strong:`\ `\ \ :literal:`\ `\ \ \ \ :ref:`\ <>`\ \ :literal:`\ `\ \ :literal:`` (`link <#parameter->`_)\ \ :literal:`` (`link <#return->`_)\ \ :literal:``\ diff --git a/tests/functional/collections/ansible_collections/ns/col2/plugins/modules/foo2.py b/tests/functional/collections/ansible_collections/ns/col2/plugins/modules/foo2.py index 3ffc0e03..421dc171 100644 --- a/tests/functional/collections/ansible_collections/ns/col2/plugins/modules/foo2.py +++ b/tests/functional/collections/ansible_collections/ns/col2/plugins/modules/foo2.py @@ -21,6 +21,7 @@ - The return value RV(bar) exists, but RV(barbaz) does not. - "Again existing: O(ns.col2.foo#module:foo=1), RV(ns.col2.foo#module:bar=2)" - "Again not existing: O(ns.col2.foo#module:foobar=1), RV(ns.col2.foo#module:barbaz=2)" + - C() I() B() C() U() L(,) R(,) V() O() RV() E() options: foo: description: The foo source. diff --git a/tests/functional/test_docs_linting.py b/tests/functional/test_docs_linting.py index 872fde12..821cf4b7 100644 --- a/tests/functional/test_docs_linting.py +++ b/tests/functional/test_docs_linting.py @@ -225,6 +225,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -288,6 +290,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -371,6 +375,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -462,6 +468,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -588,6 +596,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -696,6 +706,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz", @@ -802,6 +814,8 @@ def test_docsite_linting_failure(tmp_path_factory): "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[5]: RV(ns.col2.foo#module:bar=2): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: O(ns.col2.foo#module:foobar=1): there is no module ns.col2.foo", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[6]: RV(ns.col2.foo#module:barbaz=2): there is no module ns.col2.foo", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: O(): option name does not reference to an existing option of the module ns.col2.foo2", + "plugins/modules/foo2.py:0:0: DOCUMENTATION -> description[7]: RV(): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> bar -> description[2]: O(broken markup): option name does not reference to an existing option of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> options -> subfoo -> suboptions -> foo -> description[4]: RV(foobarbaz): return value name does not reference to an existing return value of the module ns.col2.foo2", "plugins/modules/foo2.py:0:0: DOCUMENTATION -> seealso[2]: there is no module ns.col2.foobarbaz",