On Fri, Mar 7, 2025 at 7:10 AM Markus Armbruster <armbru@redhat.com> wrote:
> John Snow <jsnow@redhat.com> writes:
>
> > Signed-off-by: John Snow <jsnow@redhat.com>
> > ---
> > docs/sphinx/qapidoc.py | 50 ++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 50 insertions(+)
> >
> > diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
> > index 6de8c900543..cf5dbb0133d 100644
> > --- a/docs/sphinx/qapidoc.py
> > +++ b/docs/sphinx/qapidoc.py
> > @@ -29,6 +29,7 @@
> > from contextlib import contextmanager
> > import os
> > from pathlib import Path
> > +import re
> > import sys
> > from typing import TYPE_CHECKING
> >
> > @@ -55,6 +56,8 @@
> > Sequence,
> > )
> >
> > + from qapi.parser import QAPIDoc
> > +
> > from sphinx.application import Sphinx
> > from sphinx.util.typing import ExtensionMetadata
> >
> > @@ -130,6 +133,53 @@ def visit_module(self, path: str) -> None:
> > 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(" ")
>
>
>
> > + level = len(leader) + 1 # Implicit +1 for heading in .rST
> stub
>
> What is the ".rST stub"?
>
sorry, I meant the .rst document in-tree that invokes the qapidoc
directive. that document inherently has a title, so I treat everything in
the generated doc as a sub-heading of some kind.
(i.e., only one <h1>)
>
> > +
> > + #
> https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections
> > + markers = {
> > + 1: "#",
> > + 2: "*",
> > + 3: "=",
> > + 4: "-",
> > + 5: "^",
> > + 6: '"',
> > + }
>
> I'd be tempted to use markers = '#*=-^". Matter of taste, yours takes
> precedence here.
>
Oh, yeah. I think I need a vacation from Python.
>
> > + 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
>
>