Headings and subheadings
~~~~~~~~~~~~~~~~~~~~~~~~
-A free-form documentation comment containing a line which starts with
-some ``=`` symbols and then a space defines a section heading::
+Free-form documentation does not start with ``@SYMBOL`` and can contain
+arbitrary rST markup. Headings can be marked up using the standard rST
+syntax::
##
- # = This is a top level heading
+ # *************************
+ # This is a level 2 heading
+ # *************************
#
# This is a free-form comment which will go under the
# top level heading.
##
##
- # == This is a second level heading
+ # This is a third level heading
+ # ==============================
+ #
+ # Level 4
+ # _______
+ #
+ # Level 5
+ # ^^^^^^^
+ #
+ # Level 6
+ # """""""
##
-A heading line must be the first line of the documentation
-comment block.
-
-Section headings must always be correctly nested, so you can only
-define a third-level heading inside a second-level heading, and so on.
+Level 1 headings are reserved for use by the generated documentation
+page itself, leaving level 2 as the highest level that should be used.
Documentation markup
# later. See the COPYING file in the top-level directory.
##
-# = Firmware
+# ********
+# Firmware
+# ********
##
{ 'pragma': {
# later. See the COPYING file in the top-level directory.
##
-# = vhost user backend discovery & capabilities
+# *******************************************
+# vhost user backend discovery & capabilities
+# *******************************************
##
##
self.ensure_blank_line()
def visit_freeform(self, doc: QAPIDoc) -> None:
- # TODO: Once the old qapidoc transformer is deprecated, freeform
- # sections can be updated to pure rST, and this transformed removed.
- #
- # For now, translate our micro-format into rST. Code adapted
- # from Peter Maydell's freeform().
-
assert len(doc.all_sections) == 1, doc.all_sections
body = doc.all_sections[0]
- text = self.reformat_arobase(body.text)
- info = doc.info
-
- if re.match(r"=+ ", text):
- # Section/subsection heading (if present, will always be the
- # first line of the block)
- (heading, _, text) = text.partition("\n")
- (leader, _, heading) = heading.partition(" ")
- # Implicit +1 for heading in the containing .rst doc
- level = len(leader) + 1
-
- # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections
- markers = ' #*=_^"'
- overline = level <= 2
- marker = markers[level]
-
- self.ensure_blank_line()
- # This credits all 2 or 3 lines to the single source line.
- if overline:
- self.add_line(marker * len(heading), info)
- self.add_line(heading, info)
- self.add_line(marker * len(heading), info)
- self.ensure_blank_line()
-
- # Eat blank line(s) and advance info
- trimmed = text.lstrip("\n")
- text = trimmed
- info = info.next_line(len(text) - len(trimmed) + 1)
-
- self.add_lines(text, info)
+ self.add_lines(self.reformat_arobase(body.text), doc.info)
self.ensure_blank_line()
def visit_entity(self, ent: QAPISchemaDefinition) -> None:
# SPDX-License-Identifier: GPL-2.0-or-later
##
-# = ACPI
+# ****
+# ACPI
+# ****
##
##
# See the COPYING file in the top-level directory.
##
-# = Audio
+# *****
+# Audio
+# *****
##
##
# vim: filetype=python
##
-# = User authorization
+# ******************
+# User authorization
+# ******************
##
##
# vim: filetype=python
##
-# == Block core (VM unrelated)
+# Block core (VM unrelated)
+# =========================
##
{ 'include': 'common.json' }
# vim: filetype=python
##
-# == Block device exports
+# Block device exports
+# ====================
##
{ 'include': 'sockets.json' }
# vim: filetype=python
##
-# = Block devices
+# *************
+# Block devices
+# *************
##
{ 'include': 'block-core.json' }
##
-# == Additional block stuff (VM related)
+# Additional block stuff (VM related)
+# ===================================
##
##
#
##
-# = Character devices
+# *****************
+# Character devices
+# *****************
##
{ 'include': 'sockets.json' }
# vim: filetype=python
##
-# = Common data types
+# *****************
+# Common data types
+# *****************
##
##
# vim: filetype=python
##
-# = Compatibility policy
+# ********************
+# Compatibility policy
+# ********************
##
##
#
##
-# = QMP monitor control
+# *******************
+# QMP monitor control
+# *******************
##
##
#
##
-# = Cryptography
+# ************
+# Cryptography
+# ************
##
##
# See the COPYING file in the top-level directory.
##
-# = Cryptography devices
+# ********************
+# Cryptography devices
+# ********************
##
##
# vim: filetype=python
##
-# = CXL devices
+# ***********
+# CXL devices
+# ***********
##
##
# See the COPYING file in the top-level directory.
##
-# = Dump guest memory
+# *****************
+# Dump guest memory
+# *****************
##
##
# See the COPYING file in the top-level directory.
##
-# = eBPF Objects
+# ************
+# eBPF Objects
+# ************
#
# eBPF object is an ELF binary that contains the eBPF program and eBPF
# map description(BTF). Overall, eBPF object should contain the
# vim: filetype=python
##
-# = QMP errors
+# **********
+# QMP errors
+# **********
##
##
# See the COPYING file in the top-level directory.
##
-# = QMP introspection
+# *****************
+# QMP introspection
+# *****************
##
##
# vim: filetype=python
##
-# = Background jobs
+# ***************
+# Background jobs
+# ***************
##
##
# See the COPYING file in the top-level directory.
##
-# = Common machine types
+# ********************
+# Common machine types
+# ********************
##
##
# See the COPYING file in the top-level directory.
##
-# = Machines
+# ********
+# Machines
+# ********
##
{ 'include': 'common.json' }
#
##
-# = Migration
+# *********
+# Migration
+# *********
##
{ 'include': 'common.json' }
#
##
-# = Miscellanea
+# ***********
+# Miscellanea
+# ***********
##
{ 'include': 'common.json' }
#
##
-# = Net devices
+# ***********
+# Net devices
+# ***********
##
{ 'include': 'sockets.json' }
# SPDX-License-Identifier: GPL-2.0-or-later
##
-# = PCI
+# ***
+# PCI
+# ***
##
##
# -*- Mode: Python -*-
# vim: filetype=python
##
-# = Introduction
+# ************
+# Introduction
+# ************
#
# This manual describes the commands and events supported by the QEMU
# Monitor Protocol (QMP).
# See the COPYING file in the top-level directory.
##
-# = Device infrastructure (qdev)
+# ****************************
+# Device infrastructure (qdev)
+# ****************************
##
{ 'include': 'qom.json' }
{ 'include': 'crypto.json' }
##
-# = QEMU Object Model (QOM)
+# ***********************
+# QEMU Object Model (QOM)
+# ***********************
##
##
#
##
-# = Record/replay
+# *************
+# Record/replay
+# *************
##
{ 'include': 'common.json' }
# vim: filetype=python
##
-# = Rocker switch device
+# ********************
+# Rocker switch device
+# ********************
##
##
#
##
-# = VM run state
+# ************
+# VM run state
+# ************
##
##
# vim: filetype=python
##
-# = Socket data types
+# *****************
+# Socket data types
+# *****************
##
##
# SPDX-License-Identifier: GPL-2.0-or-later
##
-# = Statistics
+# **********
+# Statistics
+# **********
##
##
#
##
-# = TPM (trusted platform module) devices
+# *************************************
+# TPM (trusted platform module) devices
+# *************************************
##
##
# See the COPYING file in the top-level directory.
##
-# = Tracing
+# *******
+# Tracing
+# *******
##
##
#
##
-# = Transactions
+# ************
+# Transactions
+# ************
##
{ 'include': 'block-core.json' }
#
##
-# = UEFI Variable Store
+# *******************
+# UEFI Variable Store
+# *******************
#
# The QEMU efi variable store implementation (hw/uefi/) uses this to
# store non-volatile variables in json format on disk.
#
##
-# = Remote desktop
+# **************
+# Remote desktop
+# **************
##
{ 'include': 'common.json' }
'if': 'CONFIG_PIXMAN' }
##
-# == Spice
+# Spice
+# =====
##
##
'if': 'CONFIG_SPICE' }
##
-# == VNC
+# VNC
+# ===
##
##
'if': 'CONFIG_VNC' }
##
-# = Input
+# *****
+# Input
+# *****
##
##
#
##
-# = VFIO devices
+# ************
+# VFIO devices
+# ************
##
##
#
##
-# = Virtio devices
+# **************
+# Virtio devices
+# **************
##
##
#
##
-# = Yank feature
+# ************
+# Yank feature
+# ************
##
##
# Free-form documentation
doc = QAPIDoc(info)
doc.ensure_untagged_section(self.info)
- first = True
while line is not None:
if match := self._match_at_name_colon(line):
raise QAPIParseError(
self,
"'@%s:' not allowed in free-form documentation"
% match.group(1))
- if line.startswith('='):
- if not first:
- raise QAPIParseError(
- self,
- "'=' heading must come first in a comment block")
doc.append_line(line)
self.accept(False)
line = self.get_doc_line()
- first = False
self.accept()
doc.end()
# storage daemon.
##
-# = Introduction
+# ************
+# Introduction
+# ************
#
# This manual describes the commands and events supported by the QEMU
# storage daemon QMP.
{ 'include': '../../qapi/job.json' }
##
-# = Block devices
+# *************
+# Block devices
+# *************
##
{ 'include': '../../qapi/block-core.json' }
{ 'include': '../../qapi/block-export.json' }
'documentation-exceptions': [ 'Enum', 'Variant1', 'Alternate', 'cmd' ] } }
##
-# = Section
+# *******
+# Section
+# *******
##
##
##
##
-# == Subsection
+# Subsection
+# ==========
#
# *with emphasis*
# @var {in braces}
'if': { 'not': { 'any': [ 'IFONE', 'IFTWO' ] } } }
##
-# == Another subsection
+# Another subsection
+# ==================
##
##
feature feat3
doc freeform
body=
-= Section
+*******
+Section
+*******
doc freeform
body=
Just text, no heading.
doc freeform
body=
-== Subsection
+Subsection
+==========
*with emphasis*
@var {in braces}
a feature
doc freeform
body=
-== Another subsection
+Another subsection
+==================
doc symbol=cmd
body=