Implement semantic markup support for Ansible documentation in ansible-doc. (#80242)

This commit is contained in:
Felix Fontein 2023-03-21 16:29:45 +01:00 committed by GitHub
parent 4ca3a29cd2
commit a2dc5fcc7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 20 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- "ansible-doc - support semantic markup in text output (https://github.com/ansible/ansible/pull/80242)."

View File

@ -362,12 +362,23 @@ class DocCLI(CLI, RoleMixin):
_ITALIC = re.compile(r"\bI\(([^)]+)\)")
_BOLD = re.compile(r"\bB\(([^)]+)\)")
_MODULE = re.compile(r"\bM\(([^)]+)\)")
_PLUGIN = re.compile(r"\bP\(([^#)]+)#([a-z]+)\)")
_LINK = re.compile(r"\bL\(([^)]+), *([^)]+)\)")
_URL = re.compile(r"\bU\(([^)]+)\)")
_REF = re.compile(r"\bR\(([^)]+), *([^)]+)\)")
_CONST = re.compile(r"\bC\(([^)]+)\)")
_SEM_PARAMETER_STRING = r"\(((?:[^\\)]+|\\.)+)\)"
_SEM_OPTION_NAME = re.compile(r"\bO" + _SEM_PARAMETER_STRING)
_SEM_OPTION_VALUE = re.compile(r"\bV" + _SEM_PARAMETER_STRING)
_SEM_ENV_VARIABLE = re.compile(r"\bE" + _SEM_PARAMETER_STRING)
_SEM_RET_VALUE = re.compile(r"\bRV" + _SEM_PARAMETER_STRING)
_RULER = re.compile(r"\bHORIZONTALLINE\b")
# helper for unescaping
_UNESCAPE = re.compile(r"\\(.)")
_FQCN_TYPE_PREFIX_RE = re.compile(r'^([^.]+\.[^.]+\.[^#]+)#([a-z]+):(.*)$')
_IGNORE_MARKER = 'ignore:'
# rst specific
_RST_NOTE = re.compile(r".. note::")
_RST_SEEALSO = re.compile(r".. seealso::")
@ -379,6 +390,33 @@ class DocCLI(CLI, RoleMixin):
super(DocCLI, self).__init__(args)
self.plugin_list = set()
@staticmethod
def _tty_ify_sem_simle(matcher):
text = DocCLI._UNESCAPE.sub(r'\1', matcher.group(1))
return f"`{text}'"
@staticmethod
def _tty_ify_sem_complex(matcher):
text = DocCLI._UNESCAPE.sub(r'\1', matcher.group(1))
value = None
if '=' in text:
text, value = text.split('=', 1)
m = DocCLI._FQCN_TYPE_PREFIX_RE.match(text)
if m:
plugin_fqcn = m.group(1)
plugin_type = m.group(2)
text = m.group(3)
elif text.startswith(DocCLI._IGNORE_MARKER):
text = text[len(DocCLI._IGNORE_MARKER):]
plugin_fqcn = plugin_type = ''
else:
plugin_fqcn = plugin_type = ''
if value is not None:
text = f"{text}={value}"
if plugin_fqcn and plugin_type:
return f"`{text}' (of {plugin_type} {plugin_fqcn})"
return f"`{text}'"
@classmethod
def find_plugins(cls, path, internal, plugin_type, coll_filter=None):
display.deprecated("find_plugins method as it is incomplete/incorrect. use ansible.plugins.list functions instead.", version='2.17')
@ -393,8 +431,13 @@ class DocCLI(CLI, RoleMixin):
t = cls._MODULE.sub("[" + r"\1" + "]", t) # M(word) => [word]
t = cls._URL.sub(r"\1", t) # U(word) => word
t = cls._LINK.sub(r"\1 <\2>", t) # L(word, url) => word <url>
t = cls._PLUGIN.sub("[" + r"\1" + "]", t) # P(word#type) => [word]
t = cls._REF.sub(r"\1", t) # R(word, sphinx-ref) => word
t = cls._CONST.sub(r"`\1'", t) # C(word) => `word'
t = cls._SEM_OPTION_NAME.sub(cls._tty_ify_sem_complex, t) # O(expr)
t = cls._SEM_OPTION_VALUE.sub(cls._tty_ify_sem_simle, t) # V(expr)
t = cls._SEM_ENV_VARIABLE.sub(cls._tty_ify_sem_simle, t) # E(expr)
t = cls._SEM_RET_VALUE.sub(cls._tty_ify_sem_complex, t) # RV(expr)
t = cls._RULER.sub("\n{0}\n".format("-" * 13), t) # HORIZONTALLINE => -------
# remove rst

View File

@ -3,7 +3,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: randommodule
short_description: A random module
@ -18,22 +18,22 @@ deprecated:
removed_in: '3.0.0'
options:
test:
description: Some text.
description: Some text. Consider not using O(ignore:foo=bar).
type: str
version_added: 1.2.0
sub:
description: Suboptions.
description: Suboptions. Contains O(sub.subtest), which can be set to V(123). You can use E(TEST_ENV) to set this.
type: dict
suboptions:
subtest:
description: A suboption.
description: A suboption. Not compatible to O(ansible.builtin.copy#module:path=c:\\foo\(1\).txt).
type: int
version_added: 1.1.0
# The following is the wrong syntax, and should not get processed
# by add_collection_to_versions_and_dates()
options:
subtest2:
description: Another suboption.
description: Another suboption. Useful when P(ansible.builtin.shuffle#filter) is used with value V([a,b,\),d\\]).
type: float
version_added: 1.1.0
# The following is not supported in modules, and should not get processed
@ -53,7 +53,7 @@ extends_documentation_fragment:
EXAMPLES = '''
'''
RETURN = '''
RETURN = r'''
z_last:
description: A last result.
type: str
@ -63,7 +63,8 @@ z_last:
m_middle:
description:
- This should be in the middle.
- Has some more data
- Has some more data.
- Check out RV(m_middle.suboption) and compare it to RV(a_first=foo) and RV(community.general.foo#lookup:value).
type: dict
returned: success and 1st of month
contains:
@ -74,7 +75,7 @@ m_middle:
version_added: 1.4.0
a_first:
description: A first result.
description: A first result. Use RV(a_first=foo\(bar\\baz\)bam).
type: str
returned: success
'''

View File

@ -14,7 +14,8 @@ DEPRECATED:
OPTIONS (= is mandatory):
- sub
Suboptions.
Suboptions. Contains `sub.subtest', which can be set to `123'.
You can use `TEST_ENV' to set this.
set_via:
env:
- deprecated:
@ -29,7 +30,8 @@ OPTIONS (= is mandatory):
OPTIONS:
- subtest2
Another suboption.
Another suboption. Useful when [ansible.builtin.shuffle]
is used with value `[a,b,),d\]'.
default: null
type: float
added in: version 1.1.0
@ -39,14 +41,15 @@ OPTIONS (= is mandatory):
SUBOPTIONS:
- subtest
A suboption.
A suboption. Not compatible to `path=c:\foo(1).txt' (of
module ansible.builtin.copy).
default: null
type: int
added in: version 1.1.0 of testns.testcol
- test
Some text.
Some text. Consider not using `foo=bar'.
default: null
type: str
added in: version 1.2.0 of testns.testcol
@ -74,13 +77,15 @@ EXAMPLES:
RETURN VALUES:
- a_first
A first result.
A first result. Use `a_first=foo(bar\baz)bam'.
returned: success
type: str
- m_middle
This should be in the middle.
Has some more data
Has some more data.
Check out `m_middle.suboption' and compare it to `a_first=foo'
and `value' (of lookup community.general.foo).
returned: success and 1st of month
type: dict

View File

@ -19,7 +19,7 @@
"module": "randommodule",
"options": {
"sub": {
"description": "Suboptions.",
"description": "Suboptions. Contains O(sub.subtest), which can be set to V(123). You can use E(TEST_ENV) to set this.",
"env": [
{
"deprecated": {
@ -34,14 +34,14 @@
],
"options": {
"subtest2": {
"description": "Another suboption.",
"description": "Another suboption. Useful when P(ansible.builtin.shuffle#filter) is used with value V([a,b,\\),d\\\\]).",
"type": "float",
"version_added": "1.1.0"
}
},
"suboptions": {
"subtest": {
"description": "A suboption.",
"description": "A suboption. Not compatible to O(ansible.builtin.copy#module:path=c:\\\\foo\\(1\\).txt).",
"type": "int",
"version_added": "1.1.0",
"version_added_collection": "testns.testcol"
@ -50,7 +50,7 @@
"type": "dict"
},
"test": {
"description": "Some text.",
"description": "Some text. Consider not using O(ignore:foo=bar).",
"type": "str",
"version_added": "1.2.0",
"version_added_collection": "testns.testcol"
@ -78,7 +78,7 @@
"metadata": null,
"return": {
"a_first": {
"description": "A first result.",
"description": "A first result. Use RV(a_first=foo\\(bar\\\\baz\\)bam).",
"returned": "success",
"type": "str"
},
@ -98,7 +98,8 @@
},
"description": [
"This should be in the middle.",
"Has some more data"
"Has some more data.",
"Check out RV(m_middle.suboption) and compare it to RV(a_first=foo) and RV(community.general.foo#lookup:value)."
],
"returned": "success and 1st of month",
"type": "dict"