Implement semantic markup support for Ansible documentation in ansible-doc. (#80242)
This commit is contained in:
parent
4ca3a29cd2
commit
a2dc5fcc7d
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "ansible-doc - support semantic markup in text output (https://github.com/ansible/ansible/pull/80242)."
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
'''
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue