]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
docs/qapidoc: add visit_freeform() method
authorJohn Snow <jsnow@redhat.com>
Tue, 11 Mar 2025 03:42:40 +0000 (23:42 -0400)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 11 Mar 2025 09:10:57 +0000 (10:10 +0100)
Add the transmogrifier implementation for converting freeform doc blocks
to rST.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-ID: <20250311034303.75779-43-jsnow@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
docs/sphinx/qapidoc.py

index 6de8c9005430fecf448ce425ddbc6cc09ac893e7..ddad6041455b560f8f8971f7c3e116871cb9da52 100644 (file)
@@ -29,6 +29,7 @@ from __future__ import annotations
 from contextlib import contextmanager
 import os
 from pathlib import Path
+import re
 import sys
 from typing import TYPE_CHECKING
 
@@ -55,6 +56,8 @@ if TYPE_CHECKING:
         Sequence,
     )
 
+    from qapi.parser import QAPIDoc
+
     from sphinx.application import Sphinx
     from sphinx.util.typing import ExtensionMetadata
 
@@ -130,6 +133,47 @@ class Transmogrifier:
         self.add_line_raw(f".. qapi:module:: {name}", path, 1)
         self.ensure_blank_line()
 
+    def visit_freeform(self, doc: QAPIDoc) -> None:
+        # TODO: Once the old qapidoc transformer is deprecated, freeform
+        # sections can be updated to pure rST, and this transformed removed.
+        #
+        # For now, translate our micro-format into rST. Code adapted
+        # from Peter Maydell's freeform().
+
+        assert len(doc.all_sections) == 1, doc.all_sections
+        body = doc.all_sections[0]
+        text = body.text
+        info = doc.info
+
+        if re.match(r"=+ ", text):
+            # Section/subsection heading (if present, will always be the
+            # first line of the block)
+            (heading, _, text) = text.partition("\n")
+            (leader, _, heading) = heading.partition(" ")
+            # Implicit +1 for heading in the containing .rst doc
+            level = len(leader) + 1
+
+            # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections
+            markers = ' #*=_^"'
+            overline = level <= 2
+            marker = markers[level]
+
+            self.ensure_blank_line()
+            # This credits all 2 or 3 lines to the single source line.
+            if overline:
+                self.add_line(marker * len(heading), info)
+            self.add_line(heading, info)
+            self.add_line(marker * len(heading), info)
+            self.ensure_blank_line()
+
+            # Eat blank line(s) and advance info
+            trimmed = text.lstrip("\n")
+            text = trimmed
+            info = info.next_line(len(text) - len(trimmed) + 1)
+
+        self.add_lines(text, info)
+        self.ensure_blank_line()
+
 
 class QAPISchemaGenDepVisitor(QAPISchemaVisitor):
     """A QAPI schema visitor which adds Sphinx dependencies each module