Skip to content

Commit a882895

Browse files
committed
Use RST roles for formatting.
1 parent 60de6fa commit a882895

File tree

4 files changed

+97
-16
lines changed

4 files changed

+97
-16
lines changed

src/antsibull/jinja2/filters.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131

3232

3333
def _option_name_html(matcher):
34-
parts = matcher.group(1).split('=', 1)
35-
if len(parts) == 1:
36-
return f'<em>{parts[0]}</em>'
37-
return f'<em>{parts[0]}</em>=<code>{parts[1]}</code>'
34+
text = matcher.group(1)
35+
if '=' not in text and ':' not in text:
36+
return f'<code class="ansible-option literal"><strong>{text}</strong></code>'
37+
return f'<code class="ansible-option-value literal">{text}</code>'
3838

3939

4040
def html_ify(text):
@@ -56,8 +56,10 @@ def html_ify(text):
5656
text, _counts['link'] = _LINK.subn(r"<a href='\2'>\1</a>", text)
5757
text, _counts['const'] = _CONST.subn(r"<code>\1</code>", text)
5858
text, _counts['option-name'] = _SEM_OPTION_NAME.subn(_option_name_html, text)
59-
text, _counts['option-value'] = _SEM_OPTION_VALUE.subn(r"<code>\1</code>", text)
60-
text, _counts['environment-var'] = _SEM_ENV_VARIABLE.subn(r"<code>\1</code>", text)
59+
text, _counts['option-value'] = _SEM_OPTION_VALUE.subn(
60+
r"""<code class="ansible-value literal">\1</code>""", text)
61+
text, _counts['environment-var'] = _SEM_ENV_VARIABLE.subn(
62+
r"""<code class="xref std std-envvar literal">\1</code>""", text)
6163
text, _counts['ruler'] = _RULER.subn(r"<hr/>", text)
6264

6365
text = text.strip()
@@ -87,13 +89,6 @@ def do_max(seq):
8789
return max(seq)
8890

8991

90-
def _option_name_rst(matcher):
91-
parts = matcher.group(1).split('=', 1)
92-
if len(parts) == 1:
93-
return f'*{parts[0]}*'
94-
return f'*{parts[0]}* |equalsign| ``{parts[1]}``'
95-
96-
9792
def rst_ify(text):
9893
''' convert symbols like I(this is in italics) to valid restructured text '''
9994

@@ -111,9 +106,9 @@ def rst_ify(text):
111106
text, _counts['ref'] = _URL.subn(r"\1", text)
112107
text, _counts['link'] = _REF.subn(r":ref:`\1 <\2>`", text)
113108
text, _counts['const'] = _CONST.subn(r"``\1``", text)
114-
text, _counts['option-name'] = _SEM_OPTION_NAME.subn(_option_name_rst, text)
115-
text, _counts['option-value'] = _SEM_OPTION_VALUE.subn(r"``\1``", text)
116-
text, _counts['environment-var'] = _SEM_ENV_VARIABLE.subn(r"``\1``", text)
109+
text, _counts['option-name'] = _SEM_OPTION_NAME.subn(r":ansopt:`\1`", text)
110+
text, _counts['option-value'] = _SEM_OPTION_VALUE.subn(r":ansval:`\1`", text)
111+
text, _counts['environment-var'] = _SEM_ENV_VARIABLE.subn(r":envvar:`\1`", text)
117112
text, _counts['ruler'] = _RULER.subn(f"\n\n{'-' * 13}\n\n", text)
118113

119114
flog.fields(counts=_counts).info('Number of macros converted to rst equivalents')

src/antsibull/lint_extra_docs.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import docutils.utils
1212
import rstcheck
1313

14+
from docutils.parsers.rst import roles as docutils_roles
15+
16+
from sphinx_antsibull_ext import roles as antsibull_roles
17+
1418
from .extra_docs import (
1519
find_extra_docs,
1620
lint_required_conditions,
@@ -46,6 +50,12 @@ def lint_optional_conditions(content: str, path: str, collection_name: str
4650
return [(result[0], 0, result[1]) for result in results]
4751

4852

53+
def _setup_rstcheck():
54+
'''Make sure that rstcheck knows about our roles.'''
55+
for name, role in antsibull_roles.ROLES.items():
56+
docutils_roles.register_local_role(name, role)
57+
58+
4959
def lint_collection_extra_docs_files(path_to_collection: str
5060
) -> t.List[t.Tuple[str, int, int, str]]:
5161
try:
@@ -56,6 +66,7 @@ def lint_collection_extra_docs_files(path_to_collection: str
5666
result = []
5767
all_labels = set()
5868
docs = find_extra_docs(path_to_collection)
69+
_setup_rstcheck()
5970
for doc in docs:
6071
try:
6172
# Load content

src/sphinx_antsibull_ext/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616

1717
from .assets import setup_assets
18+
from .roles import setup_roles
1819

1920

2021
def setup(app):
@@ -26,6 +27,9 @@ def setup(app):
2627
# Add assets
2728
setup_assets(app)
2829

30+
# Add roles
31+
setup_roles(app)
32+
2933
return dict(
3034
parallel_read_safe=True,
3135
parallel_write_safe=True,

src/sphinx_antsibull_ext/roles.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# coding: utf-8
2+
# Author: Felix Fontein <[email protected]>
3+
# License: GPLv3+
4+
# Copyright: Ansible Project, 2021
5+
'''
6+
Add roles for semantic markup.
7+
'''
8+
9+
from __future__ import (absolute_import, division, print_function)
10+
11+
12+
from docutils import nodes
13+
14+
15+
def option_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
16+
"""Format Ansible option key, or option key-value.
17+
18+
Returns 2 part tuple containing list of nodes to insert into the
19+
document and a list of system messages. Both are allowed to be
20+
empty.
21+
22+
:param name: The role name used in the document.
23+
:param rawtext: The entire markup snippet, with role.
24+
:param text: The text marked with the role.
25+
:param lineno: The line number where rawtext appears in the input.
26+
:param inliner: The inliner instance that called us.
27+
:param options: Directive options for customization.
28+
:param content: The directive content for customization.
29+
"""
30+
children = []
31+
classes = []
32+
if '=' not in text and ':' not in text:
33+
children.append(nodes.strong(rawtext, text))
34+
rawtext = ''
35+
text = ''
36+
classes.append('ansible-option')
37+
else:
38+
classes.append('ansible-option-value')
39+
return [nodes.literal(rawtext, text, *children, classes=classes)], []
40+
41+
42+
def value_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
43+
"""Format Ansible option value.
44+
45+
Returns 2 part tuple containing list of nodes to insert into the
46+
document and a list of system messages. Both are allowed to be
47+
empty.
48+
49+
:param name: The role name used in the document.
50+
:param rawtext: The entire markup snippet, with role.
51+
:param text: The text marked with the role.
52+
:param lineno: The line number where rawtext appears in the input.
53+
:param inliner: The inliner instance that called us.
54+
:param options: Directive options for customization.
55+
:param content: The directive content for customization.
56+
"""
57+
return [nodes.literal(rawtext, text, classes=['ansible-value'])], []
58+
59+
60+
ROLES = {
61+
'ansopt': option_role,
62+
'ansval': value_role,
63+
}
64+
65+
66+
def setup_roles(app):
67+
'''
68+
Setup roles for a Sphinx app object.
69+
'''
70+
for name, role in ROLES.items():
71+
app.add_role(name, role)

0 commit comments

Comments
 (0)