summary refs log tree commit diff stats
path: root/docs/sphinx/qapi_domain.py
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2025-03-10 23:42:55 -0400
committerMarkus Armbruster <armbru@redhat.com>2025-03-11 10:26:52 +0100
commit1884492e64da659323a8da4de98b344bc689f62a (patch)
treea564474b4f4bf1d431d418d69254bae3f8341137 /docs/sphinx/qapi_domain.py
parent7f6f24aaf55b567df2729d283cf8eac57c399493 (diff)
downloadfocaccia-qemu-1884492e64da659323a8da4de98b344bc689f62a.tar.gz
focaccia-qemu-1884492e64da659323a8da4de98b344bc689f62a.zip
docs/qapidoc: Add "the members of" pointers
Add "the members of ..." pointers to Members and Arguments lists where
appropriate, with clickable cross-references - so it's a slight
improvement over the old system :)

This patch is meant to be a temporary solution until we can review and
merge the inliner.

The implementation of this patch is a little bit of a hack: Sphinx is
not designed to allow you to mix fields of different "type"; i.e. mixing
member descriptions and free-form text under the same heading. To
accomplish this with a minimum of hackery, we technically document a
"dummy field" and then just strip off the documentation for that dummy
field in a post-processing step. We use the "q_dummy" variable for this
purpose, then strip it back out before final processing. If this
processing step should fail, you'll see warnings for a bad
cross-reference. (So if you don't see any, it must be working!)

Signed-off-by: John Snow <jsnow@redhat.com>
Message-ID: <20250311034303.75779-58-jsnow@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'docs/sphinx/qapi_domain.py')
-rw-r--r--docs/sphinx/qapi_domain.py22
1 files changed, 20 insertions, 2 deletions
diff --git a/docs/sphinx/qapi_domain.py b/docs/sphinx/qapi_domain.py
index ca3f3a7e2d..7ff618d8cd 100644
--- a/docs/sphinx/qapi_domain.py
+++ b/docs/sphinx/qapi_domain.py
@@ -433,6 +433,24 @@ class QAPIObject(QAPIDescription):
                     self._validate_field(field)
 
 
+class SpecialTypedField(CompatTypedField):
+    def make_field(self, *args: Any, **kwargs: Any) -> nodes.field:
+        ret = super().make_field(*args, **kwargs)
+
+        # Look for the characteristic " -- " text node that Sphinx
+        # inserts for each TypedField entry ...
+        for node in ret.traverse(lambda n: str(n) == " -- "):
+            par = node.parent
+            if par.children[0].astext() != "q_dummy":
+                continue
+
+            # If the first node's text is q_dummy, this is a dummy
+            # field we want to strip down to just its contents.
+            del par.children[:-1]
+
+        return ret
+
+
 class QAPICommand(QAPIObject):
     """Description of a QAPI Command."""
 
@@ -440,7 +458,7 @@ class QAPICommand(QAPIObject):
     doc_field_types.extend(
         [
             # :arg TypeName ArgName: descr
-            CompatTypedField(
+            SpecialTypedField(
                 "argument",
                 label=_("Arguments"),
                 names=("arg",),
@@ -508,7 +526,7 @@ class QAPIObjectWithMembers(QAPIObject):
     doc_field_types.extend(
         [
             # :member type name: descr
-            CompatTypedField(
+            SpecialTypedField(
                 "member",
                 label=_("Members"),
                 names=("memb",),