On Tue, Jun 9, 2026 at 9:36 AM Markus Armbruster <[email protected]> wrote:
>
> John Snow <[email protected]> writes:
>
> > Amend the qapidoc generator to handle and render INTRO sections.
> >
> > The only real difference here from other sections is that we need to
> > dedent the text so it renders correctly. Members and Features are also
> > indented, but do not require a dedent() because they are always used
> > in tandem with an rST construct that forms the start of a new indented
> > block; there is coincidental harmony.
> >
> > Plaintext sections, however, do not start their own block and thus
> > need to be dedented to prevent accidentally rendering them as a
> > blockquote or a syntax error.
> >
> > This dedent transformation on the text does not reflow the text, so
> > source line information remains accurate, and the "blame" chain of
> > custody for sphinx rST parsing error messages continues to be correct
> > even through this transformation.
> >
> > Signed-off-by: John Snow <[email protected]>
> > ---
> >  docs/sphinx/qapidoc.py | 15 ++++++++++++---
> >  1 file changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
> > index 16ad15fe94f..317dc44b1b8 100644
> > --- a/docs/sphinx/qapidoc.py
> > +++ b/docs/sphinx/qapidoc.py
> > @@ -35,6 +35,7 @@
> >  from pathlib import Path
> >  import re
> >  import sys
> > +import textwrap
> >  from typing import TYPE_CHECKING
> >
> >  from docutils import nodes
> > @@ -150,8 +151,15 @@ def add_lines(
> >          self,
> >          content: str,
> >          info: QAPISourceInfo,
> > +        dedent: bool = False,
> >      ) -> None:
> >          lines = content.splitlines(True)
> > +
> > +        if dedent:
> > +            lines = textwrap.dedent(content).splitlines(True)
> > +        else:
> > +            lines = content.splitlines(True)
> > +
> >          for i, line in enumerate(lines):
> >              self.add_line_raw(line, info.fname, info.line + i)
> >
> > @@ -223,13 +231,14 @@ def reformat_arobase(text: str) -> str:
> >
> >      # Transmogrification helpers
> >
> > -    def visit_paragraph(self, section: QAPIDoc.Section) -> None:
> > +    def visit_plaintext(self, section: QAPIDoc.Section) -> None:
> >          # Squelch empty paragraphs.
> >          if not section.text:
> >              return
> >
> > +        dedent = bool(section.kind == QAPIDoc.Kind.INTRO)
>
> Could use a comment explaining why INTRO needs to be dedented.

# Please see commit message

(Joking, I added a comment.)

>
> >          self.ensure_blank_line()
> > -        self.add_lines(section.text, section.info)
> > +        self.add_lines(section.text, section.info, dedent)
> >          self.ensure_blank_line()
> >
> >      def visit_member(self, section: QAPIDoc.ArgSection) -> None:
> > @@ -373,7 +382,7 @@ def visit_sections(self, ent: QAPISchemaDefinition) -> 
> > None:
> >              section.text = self.reformat_arobase(section.text)
> >
> >              if section.kind.name in ("PLAIN", "INTRO"):
> > -                self.visit_paragraph(section)
> > +                self.visit_plaintext(section)
> >              elif section.kind == QAPIDoc.Kind.MEMBER:
> >                  assert isinstance(section, QAPIDoc.ArgSection)
> >                  if section.name == "q_dummy":
>


Reply via email to