[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 09/14] docs/qapidoc: add QMP highlighting to annotated qmp-example
From: |
Markus Armbruster |
Subject: |
[PULL 09/14] docs/qapidoc: add QMP highlighting to annotated qmp-example blocks |
Date: |
Wed, 17 Jul 2024 12:49:02 +0200 |
From: John Snow <jsnow@redhat.com>
For any code literal blocks inside of a qmp-example directive, apply and
enforce the QMP lexer/highlighter to those blocks.
This way, you won't need to write:
```
.. qmp-example::
:annotated:
Blah blah
.. code-block:: QMP
-> { "lorem": "ipsum" }
```
But instead, simply:
```
.. qmp-example::
:annotated:
Blah blah::
-> { "lorem": "ipsum" }
```
Once the directive block is exited, whatever the previous default
highlight language was will be restored; localizing the forced QMP
lexing to exclusively this directive.
Note, if the default language is *already* QMP, this directive will not
generate and restore redundant highlight configuration nodes. We may
well decide that the default language ought to be QMP for any QAPI
reference pages, but this way the directive behaves consistently no
matter where it is used.
Signed-off-by: John Snow <jsnow@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20240717021312.606116-5-jsnow@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
docs/sphinx/qapidoc.py | 53 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 49 insertions(+), 4 deletions(-)
diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
index 11defcfa3f..738b2450fb 100644
--- a/docs/sphinx/qapidoc.py
+++ b/docs/sphinx/qapidoc.py
@@ -26,6 +26,7 @@
import os
import re
+import sys
import textwrap
from typing import List
@@ -36,6 +37,7 @@
from qapi.gen import QAPISchemaVisitor
from qapi.schema import QAPISchema
+from sphinx import addnodes
from sphinx.directives.code import CodeBlock
from sphinx.errors import ExtensionError
from sphinx.util.docutils import switch_source_input
@@ -545,10 +547,10 @@ 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.
+ is parsed as normal rST, but with any '::' code blocks set to use
+ the QMP lexer. 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.
@@ -562,6 +564,33 @@ class QMPExample(CodeBlock, NestedDirective):
"title": directives.unchanged,
}
+ def _highlightlang(self) -> addnodes.highlightlang:
+ """Return the current highlightlang setting for the document"""
+ node = None
+ doc = self.state.document
+
+ if hasattr(doc, "findall"):
+ # docutils >= 0.18.1
+ for node in doc.findall(addnodes.highlightlang):
+ pass
+ else:
+ for elem in doc.traverse():
+ if isinstance(elem, addnodes.highlightlang):
+ node = elem
+
+ if node:
+ return node
+
+ # No explicit directive found, use defaults
+ node = addnodes.highlightlang(
+ lang=self.env.config.highlight_language,
+ force=False,
+ # Yes, Sphinx uses this value to effectively disable line
+ # numbers and not 0 or None or -1 or something. ¯\_(ã)_/¯
+ linenothreshold=sys.maxsize,
+ )
+ return node
+
def admonition_wrap(self, *content) -> List[nodes.Node]:
title = "Example:"
if "title" in self.options:
@@ -576,8 +605,24 @@ def admonition_wrap(self, *content) -> List[nodes.Node]:
return [admon]
def run_annotated(self) -> List[nodes.Node]:
+ lang_node = self._highlightlang()
+
content_node: nodes.Element = nodes.section()
+
+ # Configure QMP highlighting for "::" blocks, if needed
+ if lang_node["lang"] != "QMP":
+ content_node += addnodes.highlightlang(
+ lang="QMP",
+ force=False, # "True" ignores lexing errors
+ linenothreshold=lang_node["linenothreshold"],
+ )
+
self.do_parse(self.content, content_node)
+
+ # Restore prior language highlighting, if needed
+ if lang_node["lang"] != "QMP":
+ content_node += addnodes.highlightlang(**lang_node.attributes)
+
return content_node.children
def run(self) -> List[nodes.Node]:
--
2.45.0
- [PULL 00/14] QAPI patches patches for 2024-07-17, Markus Armbruster, 2024/07/17
- [PULL 02/14] qapi/pci: Clean up documentation around PciDeviceClass, Markus Armbruster, 2024/07/17
- [PULL 04/14] qapi/machine: Clarify query-uuid value when none has been specified, Markus Armbruster, 2024/07/17
- [PULL 03/14] qapi/machine: Clean up documentation around CpuInstanceProperties, Markus Armbruster, 2024/07/17
- [PULL 12/14] qapi: convert "Example" sections with titles, Markus Armbruster, 2024/07/17
- [PULL 06/14] qapi/ui: Drop note on naming of SpiceQueryMouseMode, Markus Armbruster, 2024/07/17
- [PULL 05/14] qapi/sockets: Move deprecation note out of SocketAddress doc comment, Markus Armbruster, 2024/07/17
- [PULL 01/14] qapi/qom: Document feature unstable of @x-vfio-user-server, Markus Armbruster, 2024/07/17
- [PULL 10/14] docs/sphinx: add CSS styling for qmp-example directive, Markus Armbruster, 2024/07/17
- [PULL 09/14] docs/qapidoc: add QMP highlighting to annotated qmp-example blocks,
Markus Armbruster <=
- [PULL 14/14] qapi: remove "Example" doc section, Markus Armbruster, 2024/07/17
- [PULL 07/14] docs/qapidoc: factor out do_parse(), Markus Armbruster, 2024/07/17
- [PULL 11/14] qapi: convert "Example" sections without titles, Markus Armbruster, 2024/07/17
- [PULL 13/14] qapi: convert "Example" sections with longer prose, Markus Armbruster, 2024/07/17
- [PULL 08/14] docs/qapidoc: create qmp-example directive, Markus Armbruster, 2024/07/17
- Re: [PULL 00/14] QAPI patches patches for 2024-07-17, Richard Henderson, 2024/07/18