docs: better handle description tags in generate-docs-nm-settings-docs-merge.py

When we generate the manual page for nm-settings-nmcli, we run:

   "/usr/bin/python" \
        ./tools/generate-docs-nm-settings-docs-merge.py \
        --only-from-first \
        man/nm-settings-docs-nmcli.xml \
        src/nmcli/gen-metadata-nm-settings-nmcli.xml \
        src/libnm-client-impl/nm-property-infos-nmcli.xml \
        src/libnm-client-impl/nm-settings-docs-gir.xml

If "gen-metadata-nm-settings-nmcli.xml" contains either a <description>
or a <description-docbook>, then we must not continue searching the
other XML documents. The user provided an explicit override, and
fallback (search further) is wrong. Previously, we might take
<description> from the first file, and <description-docbook> from the
second file. As "man/nm-settings-nmcli.xsl" prefers
<description-docbook>, it takes the wrong text. Instead, as we search
the files during merge, we must prefer the first one.

Note that the change doesn't really matter anymore, because each XML
now must also contain both <description> and <description-docbook>.
There is an assertion for that.

Also, stop generating <deprecated-docbook>. First, it lacked the
important "since=" attribute and was necessary. Also, it's redundant and
does not contain anything interesting. So far, we don't need special
formatting for the deprecated message, and we likely never will.

Also, stop accepting or generating the "description=" attribute. This
should always be an XML element now.
This commit is contained in:
Thomas Haller 2023-05-17 12:19:34 +02:00
parent 89abede3df
commit 42aa225185
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 70 additions and 26 deletions

View file

@ -154,11 +154,11 @@
<xsl:when test="description-docbook">
<xsl:copy-of select="./description-docbook/*/."/>
</xsl:when>
<xsl:otherwise>
<xsl:when test="description">
<para>
<xsl:value-of select="@description"/>
<xsl:value-of select="description"/>
</para>
</xsl:otherwise>
</xsl:when>
</xsl:choose>
<xsl:if test="@type = 'NMSettingSecretFlags (uint32)'">
<para>

View file

@ -133,7 +133,6 @@ keywords = collections.OrderedDict(
)
def keywords_allowed(tag, keyword):
# certain keywords might not be valid for some tags.
# Currently, all of them are always valid.
@ -177,11 +176,17 @@ def write_data(tag, setting_node, line_no, parsed_data):
and parsed_data.get("description-docbook", None) is None
):
# we have a description, but no docbook. Generate one.
node = ET.SubElement(property_node, 'description-docbook')
node = ET.SubElement(property_node, "description-docbook")
for l in re.split("\n", parsed_data["description"]):
paragraph = ET.SubElement(node, "para")
paragraph.text = l
elif (
parsed_data.get("description-docbook", None) is not None
and parsed_data.get("description", None) is None
):
raise Exception(
'Invalid configuration. When specifying "description-docbook:" there MUST be also a "description:"'
)
kwd_first_line_re = re.compile(r"^ *\* ([-a-z0-9]+): (.*)$")

View file

@ -328,12 +328,9 @@ def main(gir_path_str, output_path_str):
},
).text = deprecated_desc
deprecated_docbook = ET.SubElement(
property_element,
"deprecated-docbook",
)
create_desc_docbook(deprecated_docbook, deprecated_desc)
# The text should only be one line. Otherwise, our simple "<deprecated>" element
# cannot be rendered nicely.
assert re.split("\n", deprecated_desc) == [deprecated_desc]
docs_gir.write(
output_path_str,

View file

@ -113,12 +113,62 @@ def node_set_attr(dst_node, name, nodes):
def find_attr(properties_attrs, name):
for p_attr in properties_attrs:
if p_attr is not None:
p_attr = p_attr.find(name)
if p_attr is None:
continue
p_attr = p_attr.find(name)
if p_attr is not None:
return p_attr
def find_description(properties_attrs):
for p in properties_attrs:
if p is None:
continue
# These are not attributes, but XML element.
assert p.get("description", None) is None
assert p.get("description-docbook", None) is None
p_elem = p.find("description")
p_elem_docbook = p.find("description-docbook")
if p_elem is not None or p_elem_docbook is not None:
if p_elem is None or p_elem_docbook is None:
# invalid input!
if p_elem:
s = ET.tostring(p_elem)
else:
s = ET.tostring(p_elem_docbook)
raise Exception(
f"We expect both a <description> and <description-docbook> tag, but we only have {s}"
)
return p_elem, p_elem_docbook
return None, None
def find_deprecated(properties_attrs):
for p in properties_attrs:
if p is None:
continue
# These are not attributes, but XML element.
assert p.get("deprecated", None) is None
assert p.get("deprecated-docbook", None) is None
# We don't expect a <deprecated-docbook> tag.
assert p.find("deprecated-docbook") is None
p_elem = p.find("deprecated")
if p_elem is not None:
# We require a "since" attribute
assert p_elem.get("since", None) is not None
return p_elem
return None
###############################################################################
gl_only_from_first = False
@ -181,10 +231,9 @@ for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name):
dbg("> > > > property_name: %s" % (property_name))
properties_attrs = [p.get(property_name) for p in properties]
description_docbook = find_attr(properties_attrs, "description-docbook")
description = find_attr(properties_attrs, "description")
deprecated_docbook = find_attr(properties_attrs, "deprecated-docbook")
deprecated = find_attr(properties_attrs, "deprecated")
description, description_docbook = find_description(properties_attrs)
deprecated = find_deprecated(properties_attrs)
if gl_only_from_first and properties_attrs[0] is None:
dbg("> > > > skip (only-from-first")
@ -203,20 +252,13 @@ for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name):
node_set_attr(property_node, "type", properties_attrs)
node_set_attr(property_node, "default", properties_attrs)
desc_value = node_get_attr(properties_attrs, "description")
node_set_attr(property_node, "alias", properties_attrs)
if description_docbook is not None:
property_node.insert(0, description_docbook)
if desc_value:
description = ET.Element("description")
description.text = desc_value
property_node.append(description)
elif description is not None:
if description is not None:
property_node.append(description)
if deprecated_docbook is not None:
property_node.insert(0, deprecated_docbook)
if deprecated is not None:
property_node.insert(0, deprecated)