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.

>          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