From nobody Thu Apr 3 09:58:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1741665586; cv=none; d=zohomail.com; s=zohoarc; b=nJYuwqnU/wK2VRn0tzyz6Nvwe8HE2BjE+KnyBpXmTeAZVXVpC0cmwz+jGYrLXEINqa3FI4zqCUhH5IRjZxvCbBOF0ZNYoe6DzyH+u3gNsSSruUfe0hM/7/meerXLs2HWrUoX5zxsPxa7oaU6u/2xRJU08/8WJisguguZH8fjqMo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1741665586; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BQvE/HneCGz1g30jzw3OwriCq5NXZt5xVT54X3KVDic=; b=abaLLN0j4wjUBmloZLXHglENwu6Vy7l3MulVbbBCvAeamH1D4Uak/Cj1ZUdRQyxqpdxTchFTLN62wegdDQVmPkIv0p9yfX4XrdzvkxoZjJ4ZjX2n7To32zNaiRatcYUUcsN/VG6eeUCDsgFzJnn9aQbagyPybR81mzqe3fpobuE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1741665586450388.11774179707265; Mon, 10 Mar 2025 20:59:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trqZ0-0007rV-GE; Mon, 10 Mar 2025 23:45:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trqYg-0007DX-PF for qemu-devel@nongnu.org; Mon, 10 Mar 2025 23:45:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trqYe-0002fh-WD for qemu-devel@nongnu.org; Mon, 10 Mar 2025 23:45:34 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-43-U7PTEA9wNSawwX2qrnQFkw-1; Mon, 10 Mar 2025 23:45:25 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 441231800258; Tue, 11 Mar 2025 03:45:24 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.64.49]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 531181800373; Tue, 11 Mar 2025 03:45:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741664731; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BQvE/HneCGz1g30jzw3OwriCq5NXZt5xVT54X3KVDic=; b=ZJMVxVCACzcEclrXE3hBhQVsFXkJdtuTGcjirQI/mZ94HZQA/WMwYSGbzC60yHC421om0G y3vyHNE8ulv/EA31Zf7Bm8EwkOLcGUhGldwUQ97pVQlkGXUVFiTGt7Yza+HzLp9G20qDht lRlp8+fm05HcdID07wpUUlkIchYGRLA= X-MC-Unique: U7PTEA9wNSawwX2qrnQFkw-1 X-Mimecast-MFC-AGG-ID: U7PTEA9wNSawwX2qrnQFkw_1741664724 From: John Snow To: qemu-devel@nongnu.org Cc: Peter Maydell , John Snow , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Eric Blake , Michael Roth , Thomas Huth , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Markus Armbruster Subject: [PATCH v3 39/63] docs/qapidoc: add transmogrifier class stub Date: Mon, 10 Mar 2025 23:42:37 -0400 Message-ID: <20250311034303.75779-40-jsnow@redhat.com> In-Reply-To: <20250311034303.75779-1-jsnow@redhat.com> References: <20250311034303.75779-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1741665587740019100 Content-Type: text/plain; charset="utf-8" Add the beginnings of the Transmogrifier class by adding the rST conversion helpers that will be used to build the virtual rST document. This version of the class does not actually "do anything" yet; each individual feature is added one-at-a-time in the forthcoming commits. Signed-off-by: John Snow --- docs/sphinx/qapidoc.py | 73 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 5246832b68c..c243bb6faaa 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -26,14 +26,17 @@ =20 from __future__ import annotations =20 +from contextlib import contextmanager import os import sys from typing import TYPE_CHECKING =20 from docutils import nodes from docutils.parsers.rst import Directive, directives +from docutils.statemachine import StringList from qapi.error import QAPIError from qapi.schema import QAPISchema, QAPISchemaVisitor +from qapi.source import QAPISourceInfo =20 from qapidoc_legacy import QAPISchemaGenRSTVisitor # type: ignore from sphinx import addnodes @@ -44,9 +47,12 @@ =20 =20 if TYPE_CHECKING: - from typing import Any, List, Sequence - - from docutils.statemachine import StringList + from typing import ( + Any, + Generator, + List, + Sequence, + ) =20 from sphinx.application import Sphinx from sphinx.util.typing import ExtensionMetadata @@ -55,6 +61,67 @@ __version__ =3D "1.0" =20 =20 +class Transmogrifier: + def __init__(self) -> None: + self._result =3D StringList() + self.indent =3D 0 + + # General-purpose rST generation functions + + def get_indent(self) -> str: + return " " * self.indent + + @contextmanager + def indented(self) -> Generator[None]: + self.indent +=3D 1 + try: + yield + finally: + self.indent -=3D 1 + + def add_line_raw(self, line: str, source: str, *lineno: int) -> None: + """Append one line of generated reST to the output.""" + + # NB: Sphinx uses zero-indexed lines; subtract one. + lineno =3D tuple((n - 1 for n in lineno)) + + if line.strip(): + # not a blank line + self._result.append( + self.get_indent() + line.rstrip("\n"), source, *lineno + ) + else: + self._result.append("", source, *lineno) + + def add_line(self, content: str, info: QAPISourceInfo) -> None: + # NB: We *require* an info object; this works out OK because we + # don't document built-in objects that don't have + # one. Everything else should. + self.add_line_raw(content, info.fname, info.line) + + def add_lines( + self, + content: str, + info: QAPISourceInfo, + ) -> None: + lines =3D content.splitlines(True) + for i, line in enumerate(lines): + self.add_line_raw(line, info.fname, info.line + i) + + def ensure_blank_line(self) -> None: + # Empty document -- no blank line required. + if not self._result: + return + + # Last line isn't blank, add one. + if self._result[-1].strip(): # pylint: disable=3Dno-member + fname, line =3D self._result.info(-1) + assert isinstance(line, int) + # New blank line is credited to one-after the current last lin= e. + # +2: correct for zero/one index, then increment by one. + self.add_line_raw("", fname, line + 2) + + class QAPISchemaGenDepVisitor(QAPISchemaVisitor): """A QAPI schema visitor which adds Sphinx dependencies each module =20 --=20 2.48.1