From 1218d01629b52615756b5fb518c10d886841db0b Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 30 Jun 2025 19:52:54 +0200 Subject: [PATCH] Move Ansible markup documentation to a separate page (#2753) * Move information on Ansible markup into a separate document. * Reference documentation fields that can use Ansible markup. * Add TOC links. * Apply adjusted version of Don's suggestion. * Add reference to ansible-core version. --- docs/docsite/rst/dev_guide/ansible_index.rst | 2 + docs/docsite/rst/dev_guide/ansible_markup.rst | 92 +++++++++++++++++++ docs/docsite/rst/dev_guide/core_index.rst | 2 + .../developing_modules_documenting.rst | 86 ++--------------- .../playbook_guide/playbooks_reuse_roles.rst | 3 + 5 files changed, 108 insertions(+), 77 deletions(-) create mode 100644 docs/docsite/rst/dev_guide/ansible_markup.rst diff --git a/docs/docsite/rst/dev_guide/ansible_index.rst b/docs/docsite/rst/dev_guide/ansible_index.rst index f5eda0ba3f..e370d07b54 100644 --- a/docs/docsite/rst/dev_guide/ansible_index.rst +++ b/docs/docsite/rst/dev_guide/ansible_index.rst @@ -46,6 +46,7 @@ Find the task that best describes what you want to do: * I want to :ref:`debug my module code `. * I want to :ref:`add tests `. * I want to :ref:`document my module `. + * I want to :ref:`improve documentation by using Ansible markup `. * I want to :ref:`document my set of modules for a network platform `. * I want to follow :ref:`conventions and tips for clean, usable module code `. * I want to :ref:`make sure my code runs on Python 2 and Python 3 `. @@ -75,6 +76,7 @@ If you prefer to read the entire guide, here's a list of the pages in order. developing_python_3 debugging developing_modules_documenting + ansible_markup sidecar developing_modules_general_windows developing_modules_in_groups diff --git a/docs/docsite/rst/dev_guide/ansible_markup.rst b/docs/docsite/rst/dev_guide/ansible_markup.rst new file mode 100644 index 0000000000..9d119bcb15 --- /dev/null +++ b/docs/docsite/rst/dev_guide/ansible_markup.rst @@ -0,0 +1,92 @@ +.. _ansible_markup: + +************** +Ansible markup +************** + +Ansible markup allows you to format and structure documentation for Ansible modules, plugins, and roles. +It lets you add basic formatting to text, such as bold, italics, code, and horizontal lines, as well as create various references, such as URLs, hyperlinks, Ansible module references, and RST references. +The Ansible markup language was extended in 2023, starting with ansible-core 2.15. It now lets you apply semantic markup for values, module/plugin options, return values, environment variables, and for referencing plugins. + +This page documents the currently supported Ansible markup. + +.. _semantic_markup: + +Semantic markup within module documentation +------------------------------------------- + +Use the semantic markup to highlight option names, option values, and environment variables. The markup processor formats these highlighted terms in a uniform way. With semantic markup, we can modify how the output looks without changing underlying code. + +The correct formats for semantic markup are as follows: + +* ``O()`` for option names, whether mentioned alone or with values. For example: ``Required if O(state=present).`` and ``Use with O(force) to require secure access.`` +* ``V()`` for option values when mentioned alone. For example: ``Possible values include V(monospace) and V(pretty).`` +* ``RV()`` for return value names, whether mentioned alone or with values. For example: ``The module returns RV(changed=true) in case of changes.`` and ``Use the RV(stdout) return value for standard output.`` +* ``E()`` for environment variables. For example: ``If not set, the environment variable E(ACME_PASSWORD) will be used.`` + +The parameters for these formatting functions can use escaping with backslashes: ``V(foo(bar="a\\b"\), baz)`` results in the formatted value ``foo(bar="a\b"), baz)``. + +.. _option_return_value_link_syntax: + +Rules for using O() and RV() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rules for using ``O()`` and ``RV()`` are very strict. You must follow syntax rules so that documentation renderers can create hyperlinks for the options and return values, respectively. + +The allowed syntaxes are as follows: + +* To reference an option for the current plugin/module, or the entrypoint of the current role (inside role entrypoint documentation), use ``O(option)`` and ``O(option=value)``. +* To reference an option for another entrypoint ``entrypoint`` from inside role documentation, use ``O(entrypoint:option)`` and ``O(entrypoint:option=name)``. The entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. +* To reference an option for *another* plugin/module ``plugin.fqcn.name`` of type ``type``, use ``O(plugin.fqcn.name#type:option)`` and ``O(plugin.fqcn.name#type:option=value)``. For modules, use ``type=module``. The FQCN and plugin type can be ignored by the documentation renderer, turned into a link to that plugin, or even directly to the option of that plugin. +* To reference an option for entrypoint ``entrypoint`` of *another* role ``role.fqcn.name``, use ``O(role.fqcn.name#role:entrypoint:option)`` and ``O(role.fqcn.name#role:entrypoint:option=value)``. The FQCN and entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. +* To reference options that do not exist (for example, options that were removed in an earlier version), use ``O(ignore:option)`` and ``O(ignore:option=value)``. The ``ignore:`` part will not be shown to the user by documentation rendering. + +Option names can refer to suboptions by listing the path to the option separated by dots. For example, if you have an option ``foo`` with suboption ``bar``, then you must use ``O(foo.bar)`` to reference that suboption. You can add array indications like ``O(foo[].bar)`` or even ``O(foo[-1].bar)`` to indicate specific list elements. Everything between ``[`` and ``]`` pairs will be ignored to determine the real name of the option. For example, ``O(foo[foo | length - 1].bar[])`` results in the same link as ``O(foo.bar)``, but the text ``foo[foo | length - 1].bar[]`` displays instead of ``foo.bar``. + +The same syntaxes can be used for ``RV()``, except that these will refer to return value names instead of option names; for example ``RV(ansible.builtin.service_facts#module:ansible_facts.services)`` refers to the :ansretval:`ansible.builtin.service_facts#module:ansible_facts.services` fact returned by the :ansplugin:`ansible.builtin.service_facts module `. + +.. _module_documents_linking: + +Linking within module documentation +----------------------------------- + +You can link from your module documentation to other module docs, other resources on docs.ansible.com, and resources elsewhere on the internet with the help of some pre-defined macros. The correct formats for these macros are: + +* ``R()`` for cross-references with a heading (supported since Ansible 2.10). For example: ``See R(Cisco IOS Platform Guide,ios_platform_options)``. Use the RST anchor for the cross-reference. See :ref:`adding_anchors_rst` for details. + + * For links outside of your collection, use ``R()`` if available. Otherwise, use ``U()`` or ``L()`` with full URLs (not relative links). + * To refer to a group of modules in a collection, use ``R()``. When a collection is not the right granularity, use ``C(..)``, for example: + + - ``Refer to the R(kubernetes.core collection, plugins_in_kubernetes.core) for information on managing kubernetes clusters.`` + - ``The C(win_*) modules (spread across several collections) allow you to manage various aspects of windows hosts.`` + +* ``L()`` for links with a heading. For example: ``See L(Ansible Automation Platform,https://www.ansible.com/products/automation-platform).`` As of Ansible 2.10, do not use ``L()`` for relative links between Ansible documentation and collection documentation. +* ``U()`` for URLs. For example: ``See U(https://www.ansible.com/products/automation-platform) for an overview.`` +* ``M()`` for module names. For example: ``See also M(ansible.builtin.yum) or M(community.general.apt_rpm)``. + + * FQCNs MUST be used, short names will create broken links; use ``ansible.builtin`` for modules in ansible-core. + +* ``P()`` for plugin names (supported since ansible-core 2.15). For example: ``See also P(ansible.builtin.file#lookup) or P(community.general.json_query#filter)``. + + * This can also reference roles: ``P(community.sops.install#role)``. + * FQCNs must be used, short names will create broken links; use ``ansible.builtin`` for plugins in ansible-core. + +* ``O()`` and ``RV()`` can also link, see :ref:`the section on their syntax `. + +.. note:: + + If you are creating your own documentation site, you will need to use the `intersphinx extension `_ to convert ``R()``, ``M()``, ``P()``, ``O()``, and ``RV()`` to the correct links. + +Format macros within module documentation +----------------------------------------- + +While it is possible to use standard Ansible formatting macros to control the look of other terms in module documentation, you should do so sparingly. + +Possible macros include the following: + +* ``C()`` for ``monospace`` (code) text. For example: ``This module functions like the unix command C(foo).`` +* ``B()`` for bold text. +* ``I()`` for italic text. +* ``HORIZONTALLINE`` for a horizontal rule (the ``
`` html tag) to separate long descriptions. + +Note that ``C()``, ``B()``, and ``I()`` do **not allow escaping**, and thus cannot contain the value ``)`` as it always ends the formatting sequence. If you need to use ``)`` inside ``C()``, we recommend to use ``V()`` instead; see the above section on semantic markup. diff --git a/docs/docsite/rst/dev_guide/core_index.rst b/docs/docsite/rst/dev_guide/core_index.rst index 9921ab302e..b516633fa8 100644 --- a/docs/docsite/rst/dev_guide/core_index.rst +++ b/docs/docsite/rst/dev_guide/core_index.rst @@ -43,6 +43,7 @@ Find the task that best describes what you want to do: * I want to :ref:`debug my module code `. * I want to :ref:`add tests `. * I want to :ref:`document my module `. + * I want to :ref:`improve documentation by using Ansible markup `. * I want to :ref:`document my set of modules for a network platform `. * I want to follow :ref:`conventions and tips for clean, usable module code `. * I want to :ref:`make sure my code runs on Python 2 and Python 3 `. @@ -72,6 +73,7 @@ If you prefer to read the entire guide, here's a list of the pages in order. developing_python_3 debugging developing_modules_documenting + ansible_markup sidecar developing_modules_general_windows developing_modules_in_groups diff --git a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst index a470a821c9..2a90431b2c 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst @@ -121,6 +121,7 @@ Documentation fields * The ``short_description`` is displayed by ``ansible-doc -l`` without any category grouping, so it needs enough detail to explain the module's purpose without the context of the directory structure in which it lives. * Unlike ``description:``, ``short_description`` MUST NOT have a trailing period/full stop. + * You can use :ref:`Ansible markup ` in this field. :description: @@ -129,6 +130,7 @@ Documentation fields * SHOULD NOT mention the module name. * Make use of multiple entries rather than using one long paragraph. * MUST NOT quote complete values unless it is required by YAML. + * You can use :ref:`Ansible markup ` in this field. :version_added: @@ -166,6 +168,7 @@ Documentation fields * Do NOT list the possible values (that's what the ``choices:`` field is for, though it should explain what the values do if they are not obvious). * If an option is only sometimes required, describe the conditions. For example, "Required when O(state=present)." * Mutually exclusive options MUST be documented as the final sentence on each of the options. + * You can use :ref:`Ansible markup ` in this field. :required: @@ -214,6 +217,7 @@ Documentation fields * List of requirements (if applicable). * Include minimum versions. + * You can use :ref:`Ansible markup ` in this field. :seealso: @@ -221,6 +225,7 @@ Documentation fields * Because it is more prominent, use ``seealso`` for general references instead of ``notes`` or adding links to the module ``description``. * References to modules MUST use the FQCN or ``ansible.builtin`` for modules in ``ansible-core``. * Plugin references are supported since ansible-core 2.15. + * You can use :ref:`Ansible markup ` in the ``description`` and ``name`` fields. * A reference can be one of the following formats: @@ -271,12 +276,14 @@ Documentation fields * Required. * A string or a list of strings. Each string is one paragraph. * Explanation of what this attribute does. It should be written in full sentences. + * You can use :ref:`Ansible markup ` in this field. :details: * Generally optional, but must be provided if ``support`` is ``partial``. * A string or a list of strings. Each string is one paragraph. * Describes how support might not work as expected by the user. + * You can use :ref:`Ansible markup ` in this field. :support: @@ -307,83 +314,7 @@ Documentation fields * Details of any important information that does not fit in one of the above sections. * Do NOT list ``check_mode`` or ``diff`` information under ``notes``. Use the ``attributes`` field instead. * Because it stands out better, use ``seealso`` for general references over the use of ``notes``. - -.. _module_documents_linking: - -Linking within module documentation ------------------------------------ - -You can link from your module documentation to other module docs, other resources on docs.ansible.com, and resources elsewhere on the internet with the help of some pre-defined macros. The correct formats for these macros are: - -* ``R()`` for cross-references with a heading (supported since Ansible 2.10). For example: ``See R(Cisco IOS Platform Guide,ios_platform_options)``. Use the RST anchor for the cross-reference. See :ref:`adding_anchors_rst` for details. - - * For links outside of your collection, use ``R()`` if available. Otherwise, use ``U()`` or ``L()`` with full URLs (not relative links). - * To refer to a group of modules in a collection, use ``R()``. When a collection is not the right granularity, use ``C(..)``, for example: - - - ``Refer to the R(kubernetes.core collection, plugins_in_kubernetes.core) for information on managing kubernetes clusters.`` - - ``The C(win_*) modules (spread across several collections) allow you to manage various aspects of windows hosts.`` - -* ``L()`` for links with a heading. For example: ``See L(Ansible Automation Platform,https://www.ansible.com/products/automation-platform).`` As of Ansible 2.10, do not use ``L()`` for relative links between Ansible documentation and collection documentation. -* ``U()`` for URLs. For example: ``See U(https://www.ansible.com/products/automation-platform) for an overview.`` -* ``M()`` for module names. For example: ``See also M(ansible.builtin.yum) or M(community.general.apt_rpm)``. - - * FQCNs MUST be used, short names will create broken links; use ``ansible.builtin`` for modules in ansible-core. - -* ``P()`` for plugin names (supported since ansible-core 2.15). For example: ``See also P(ansible.builtin.file#lookup) or P(community.general.json_query#filter)``. - - * This can also reference roles: ``P(community.sops.install#role)``. - * FQCNs must be used, short names will create broken links; use ``ansible.builtin`` for plugins in ansible-core. - -.. note:: - - If you are creating your own documentation site, you will need to use the `intersphinx extension `_ to convert ``R()`` and ``M()`` to the correct links. - -.. _semantic_markup: - -Semantic markup within module documentation -------------------------------------------- - -Use the semantic markup to highlight option names, option values, and environment variables. The markup processor formats these highlighted terms in a uniform way. With semantic markup, we can modify how the output looks without changing underlying code. - -The correct formats for semantic markup are as follows: - -* ``O()`` for option names, whether mentioned alone or with values. For example: ``Required if O(state=present).`` and ``Use with O(force) to require secure access.`` -* ``V()`` for option values when mentioned alone. For example: ``Possible values include V(monospace) and V(pretty).`` -* ``RV()`` for return value names, whether mentioned alone or with values. For example: ``The module returns RV(changed=true) in case of changes.`` and ``Use the RV(stdout) return value for standard output.`` -* ``E()`` for environment variables. For example: ``If not set, the environment variable E(ACME_PASSWORD) will be used.`` - -The parameters for these formatting functions can use escaping with backslashes: ``V(foo(bar="a\\b"\), baz)`` results in the formatted value ``foo(bar="a\b"), baz)``. - -Rules for using O() and RV() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Rules for using ``O()`` and ``RV()`` are very strict. You must follow syntax rules so that documentation renderers can create hyperlinks for the options and return values, respectively. - -The allowed syntaxes are as follows: - -* To reference an option for the current plugin/module, or the entrypoint of the current role (inside role entrypoint documentation), use ``O(option)`` and ``O(option=value)``. -* To reference an option for another entrypoint ``entrypoint`` from inside role documentation, use ``O(entrypoint:option)`` and ``O(entrypoint:option=name)``. The entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. -* To reference an option for *another* plugin/module ``plugin.fqcn.name`` of type ``type``, use ``O(plugin.fqcn.name#type:option)`` and ``O(plugin.fqcn.name#type:option=value)``. For modules, use ``type=module``. The FQCN and plugin type can be ignored by the documentation renderer, turned into a link to that plugin, or even directly to the option of that plugin. -* To reference an option for entrypoint ``entrypoint`` of *another* role ``role.fqcn.name``, use ``O(role.fqcn.name#role:entrypoint:option)`` and ``O(role.fqcn.name#role:entrypoint:option=value)``. The FQCN and entrypoint information can be ignored by the documentation renderer, turned into a link to that entrypoint, or even directly to the option of that entrypoint. -* To reference options that do not exist (for example, options that were removed in an earlier version), use ``O(ignore:option)`` and ``O(ignore:option=value)``. The ``ignore:`` part will not be shown to the user by documentation rendering. - -Option names can refer to suboptions by listing the path to the option separated by dots. For example, if you have an option ``foo`` with suboption ``bar``, then you must use ``O(foo.bar)`` to reference that suboption. You can add array indications like ``O(foo[].bar)`` or even ``O(foo[-1].bar)`` to indicate specific list elements. Everything between ``[`` and ``]`` pairs will be ignored to determine the real name of the option. For example, ``O(foo[foo | length - 1].bar[])`` results in the same link as ``O(foo.bar)``, but the text ``foo[foo | length - 1].bar[]`` displays instead of ``foo.bar``. - -The same syntaxes can be used for ``RV()``, except that these will refer to return value names instead of option names; for example ``RV(ansible.builtin.service_facts#module:ansible_facts.services)`` refers to the :ansretval:`ansible.builtin.service_facts#module:ansible_facts.services` fact returned by the :ansplugin:`ansible.builtin.service_facts module `. - -Format macros within module documentation ------------------------------------------ - -While it is possible to use standard Ansible formatting macros to control the look of other terms in module documentation, you should do so sparingly. - -Possible macros include the following: - -* ``C()`` for ``monospace`` (code) text. For example: ``This module functions like the unix command C(foo).`` -* ``B()`` for bold text. -* ``I()`` for italic text. -* ``HORIZONTALLINE`` for a horizontal rule (the ``
`` html tag) to separate long descriptions. - -Note that ``C()``, ``B()``, and ``I()`` do **not allow escaping**, and thus cannot contain the value ``)`` as it always ends the formatting sequence. If you need to use ``)`` inside ``C()``, we recommend to use ``V()`` instead; see the above section on semantic markup. + * You can use :ref:`Ansible markup ` in this field. .. _module_docs_fragments: @@ -489,6 +420,7 @@ Otherwise, for each value returned, provide the following fields. All the fields :description: Detailed description of what this value represents. Capitalized and with a trailing dot. + You can use :ref:`Ansible markup ` in this field. :returned: When this value is returned, such as ``always``, ``changed`` or ``success``. This is a string and can contain any human-readable content. :type: diff --git a/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst b/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst index 0c9e8c1e5e..b6ccaa0a7e 100644 --- a/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst +++ b/docs/docsite/rst/playbook_guide/playbooks_reuse_roles.rst @@ -333,12 +333,14 @@ role ``meta/argument_specs.yml`` file. All fields are lowercase. * The ``short_description`` is displayed by ``ansible-doc -t role -l``. * It also becomes part of the title for the role page in the documentation. * The short description should always be a string and never a list, and should not end in a period. + * You can use :ref:`Ansible markup ` in this field. :description: * A longer description that may contain multiple lines. * This can be a single string or a list of strings. In case this is a list of strings, every list element is a new paragraph. + * You can use :ref:`Ansible markup ` in this field. :version_added: @@ -366,6 +368,7 @@ role ``meta/argument_specs.yml`` file. All fields are lowercase. * Detailed explanation of what this option does. It should be written in full sentences. * This can be a single string or a list of strings. In case this is a list of strings, every list element is a new paragraph. + * You can use :ref:`Ansible markup ` in this field. :version_added: