[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 15/21] docs/qapidoc: create qmp-example directive
From: |
Markus Armbruster |
Subject: |
Re: [PATCH v2 15/21] docs/qapidoc: create qmp-example directive |
Date: |
Fri, 28 Jun 2024 15:24:12 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
John Snow <jsnow@redhat.com> writes:
> This is a directive that creates a syntactic sugar for creating
> "Example" boxes very similar to the ones already used in the bitmaps.rst
> document, please see e.g.
> https://www.qemu.org/docs/master/interop/bitmaps.html#creation-block-dirty-bitmap-add
>
> In its simplest form, when a custom title is not needed or wanted, and
> the example body is *solely* a QMP example:
>
> ```
> .. qmp-example::
>
> {body}
> ```
>
> is syntactic sugar for:
>
> ```
> .. admonition:: Example:
>
> .. code-block:: QMP
>
> {body}
> ```
>
> When a custom, plaintext title that describes the example is desired,
> this form:
>
> ```
> .. qmp-example::
> :title: Defrobnification
>
> {body}
> ```
>
> Is syntactic sugar for:
>
> ```
> .. admonition:: Example: Defrobnification
>
> .. code-block:: QMP
>
> {body}
> ```
>
> Lastly, when Examples are multi-step processes that require non-QMP
> exposition, have lengthy titles, or otherwise involve prose with rST
> markup (lists, cross-references, etc), the most complex form:
>
> ```
> .. qmp-example::
> :annotated:
>
> This example shows how to use `foo-command`::
>
> {body}
> ```
>
> Is desugared to:
>
> ```
> .. admonition:: Example:
>
> This example shows how to use `foo-command`::
>
> {body}
>
> For more information, please see `frobnozz`.
> ```
Can we combine the latter two? Like this:
.. qmp-example::
:title: Defrobnification
:annotated:
This example shows how to use `foo-command`::
{body}
> The primary benefit here being documentation source consistently using
> the same directive for all forms of examples to ensure consistent visual
> styling, and ensuring all relevant prose is visually grouped alongside
> the code literal block.
>
> Note that as of this commit, the code-block rST syntax "::" does not
> apply QMP highlighting; you would need to use ".. code-block:: QMP". The
> very next commit changes this behavior to assume all "::" code blocks
> within this directive are QMP blocks.
>
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
> docs/sphinx/qapidoc.py | 60 ++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 58 insertions(+), 2 deletions(-)
No tests? Hmm, I see you convert existing tests in PATCH 19-21. While
that works, test coverage now would make it easier to see how each patch
affects doc generator output.
> diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
> index 43dd99e21e6..a2fa05fc491 100644
> --- a/docs/sphinx/qapidoc.py
> +++ b/docs/sphinx/qapidoc.py
> @@ -27,16 +27,19 @@
> import os
> import re
> import textwrap
> +from typing import List
>
> from docutils import nodes
> -from docutils.parsers.rst import Directive, directives
> +from docutils.parsers.rst import directives
> from docutils.statemachine import ViewList
> from qapi.error import QAPIError, QAPISemError
> from qapi.gen import QAPISchemaVisitor
> from qapi.schema import QAPISchema
>
> import sphinx
> +from sphinx.directives.code import CodeBlock
> from sphinx.errors import ExtensionError
> +from sphinx.util.docutils import SphinxDirective
> from sphinx.util.nodes import nested_parse_with_titles
>
>
> @@ -494,7 +497,7 @@ def visit_module(self, name):
> super().visit_module(name)
>
>
> -class NestedDirective(Directive):
> +class NestedDirective(SphinxDirective):
What is this about?
> def run(self):
> raise NotImplementedError
>
> @@ -567,10 +570,63 @@ def run(self):
> raise ExtensionError(str(err)) from err
>
>
> +class QMPExample(CodeBlock, NestedDirective):
> + """
> + Custom admonition for QMP code examples.
> +
> + When the :annotated: option is present, the body of this directive
> + is parsed as normal rST instead. Code blocks must be explicitly
> + written by the user, but this allows for intermingling explanatory
> + paragraphs with arbitrary rST syntax and code blocks for more
> + involved examples.
> +
> + When :annotated: is absent, the directive body is treated as a
> + simple standalone QMP code block literal.
> + """
> +
> + required_argument = 0
> + optional_arguments = 0
> + has_content = True
> + option_spec = {
> + "annotated": directives.flag,
> + "title": directives.unchanged,
> + }
> +
> + def admonition_wrap(self, *content) -> List[nodes.Node]:
> + title = "Example:"
> + if "title" in self.options:
> + title = f"{title} {self.options['title']}"
> +
> + admon = nodes.admonition(
> + "",
> + nodes.title("", title),
> + *content,
> + classes=["admonition", "admonition-example"],
> + )
> + return [admon]
> +
> + def run_annotated(self) -> List[nodes.Node]:
> + content_node: nodes.Element = nodes.section()
> + self.do_parse(self.content, content_node)
> + return content_node.children
> +
> + def run(self) -> List[nodes.Node]:
> + annotated = "annotated" in self.options
> +
> + if annotated:
> + content_nodes = self.run_annotated()
> + else:
> + self.arguments = ["QMP"]
> + content_nodes = super().run()
> +
> + return self.admonition_wrap(*content_nodes)
> +
> +
> def setup(app):
> """Register qapi-doc directive with Sphinx"""
> app.add_config_value("qapidoc_srctree", None, "env")
> app.add_directive("qapi-doc", QAPIDocDirective)
> + app.add_directive("qmp-example", QMPExample)
>
> return {
> "version": __version__,
- [PATCH v2 11/21] qapi: update prose in note blocks, (continued)
- [PATCH v2 11/21] qapi: update prose in note blocks, John Snow, 2024/06/26
- [PATCH v2 10/21] qapi: convert "Note" sections to plain rST, John Snow, 2024/06/26
- [PATCH v2 12/21] qapi: add markup to note blocks, John Snow, 2024/06/26
- [PATCH v2 13/21] qapi/parser: don't parse rST markup as section headers, John Snow, 2024/06/26
- [PATCH v2 14/21] docs/qapidoc: factor out do_parse(), John Snow, 2024/06/26
- [PATCH v2 15/21] docs/qapidoc: create qmp-example directive, John Snow, 2024/06/26
- Re: [PATCH v2 15/21] docs/qapidoc: create qmp-example directive,
Markus Armbruster <=
- [PATCH v2 18/21] qapi: convert "Example" sections without titles, John Snow, 2024/06/26
- [PATCH v2 19/21] qapi: convert "Example" sections with titles, John Snow, 2024/06/26
- [PATCH v2 17/21] docs/sphinx: add CSS styling for qmp-example directive, John Snow, 2024/06/26
- [PATCH v2 20/21] qapi: convert "Example" sections with longer prose, John Snow, 2024/06/26
- [PATCH v2 16/21] docs/qapidoc: add QMP highlighting to annotated qmp-example blocks, John Snow, 2024/06/26
- [PATCH v2 21/21] qapi: remove "Example" doc section, John Snow, 2024/06/26