Skip to content

Python API

This page describes the Python API provided by the antsibull-docs-parser Python package. The code can be found in the antsibull-docs-parser GitHub repository.

The API is split into three parts:

  1. Parsing Ansible markup.
  2. Processing Ansible markup.
  3. Rendering Ansible markup.

The library uses an internal representation of markup. This is basically a list of paragraphs, and every paragraph is a list of parts. Every part represents a piece of markup, including unformatted text. Parsing converts a string of Ansible markup into this internal representation. This internal representation can be modified or analyzed. Finally, rendering converts this internal representation back to strings in other markup languages, or as plain text with markup stripped.

Complete example for parsing and rendering

The following code snippet parses a piece of Ansible markup and renders it in HTML:

from antsibull_docs_parser.parser import parse
from antsibull_docs_parser.parser import Context, parse
from antsibull_docs_parser.html import to_html

input = "This is a B(simple) example of L(Ansible markup, https://docs.ansible.com/projects/ansible/devel/dev_guide/ansible_markup.html)."
context = Context()
data = parse(input, context, strict=True)
print(to_html(data))

This prints:

<p>This is a <b>simple</b> example of <a href='https://docs.ansible.com/projects/ansible/devel/dev_guide/ansible_markup.html'>Ansible markup</a>.</p>

The internal representation

The classes making up the internal representation can be found in the antsibull_docs_parser.dom module. This module also provides basic functionality to process markup.

Parts

All the classes and data types mentioned in this section are part of antsibull_docs_parser.dom.

Every kind of part has its own class representing it. Every these classes has a property type of type PartType. The type AnyPart represents the union of all these classes, and Paragraph is a list of AnyPart objects.

antsibull_docs_parser.dom.PartType

Bases: Enum

Identifies a part class.

Source code in src/antsibull_docs_parser/dom.py
class PartType(Enum):
    """
    Identifies a part class.
    """

    ERROR = 0
    BOLD = 1
    CODE = 2
    HORIZONTAL_LINE = 3
    ITALIC = 4
    LINK = 5
    MODULE = 6
    RST_REF = 7
    URL = 8
    TEXT = 9
    ENV_VARIABLE = 10
    OPTION_NAME = 11
    OPTION_VALUE = 12
    PLUGIN = 13
    RETURN_VALUE = 14

antsibull_docs_parser.dom.Paragraph

Paragraph = list[AnyPart]

A paragraph is a sequence of parts.

Every part class has a source property, which is either a string or None. The parser allows to fill the markup's source into the parts. This can be useful when for example producing error messages during analysis, like when an invalid object is referenced.

  • antsibull_docs_parser.dom.TextPart

    Bases: NamedTuple

    Represents arbitrary unformatted (plain) text.

    Source code in src/antsibull_docs_parser/dom.py
    class TextPart(NamedTuple):
        """
        Represents arbitrary unformatted (plain) text.
        """
    
        text: str
        """The unformatted text."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.TEXT] = PartType.TEXT
        """The type of this part."""
    
    text
    text: str
    

    The unformatted text.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[TEXT] = TEXT
    

    The type of this part.

  • antsibull_docs_parser.dom.ItalicPart

    Bases: NamedTuple

    Represents some text formatted in italics.

    Source code in src/antsibull_docs_parser/dom.py
    class ItalicPart(NamedTuple):
        """
        Represents some text formatted in italics.
        """
    
        text: str
        """The text to render in italics."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.ITALIC] = PartType.ITALIC
        """The type of this part."""
    
    text
    text: str
    

    The text to render in italics.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[ITALIC] = ITALIC
    

    The type of this part.

  • antsibull_docs_parser.dom.BoldPart

    Bases: NamedTuple

    Represents some text formatted in bold.

    Source code in src/antsibull_docs_parser/dom.py
    class BoldPart(NamedTuple):
        """
        Represents some text formatted in bold.
        """
    
        text: str
        """The text to render in bold."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.BOLD] = PartType.BOLD
        """The type of this part."""
    
    text
    text: str
    

    The text to render in bold.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[BOLD] = BOLD
    

    The type of this part.

  • antsibull_docs_parser.dom.ModulePart

    Bases: NamedTuple

    Represents an Ansible module reference.

    Source code in src/antsibull_docs_parser/dom.py
    class ModulePart(NamedTuple):
        """
        Represents an Ansible module reference.
        """
    
        fqcn: str
        """The module's FQCN (fully qualified collection name)."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.MODULE] = PartType.MODULE
        """The type of this part."""
    
    fqcn
    fqcn: str
    

    The module's FQCN (fully qualified collection name).

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[MODULE] = MODULE
    

    The type of this part.

  • antsibull_docs_parser.dom.PluginPart

    Bases: NamedTuple

    Represents an Ansible plugin reference. This also covers modules, roles, and playbooks.

    Source code in src/antsibull_docs_parser/dom.py
    class PluginPart(NamedTuple):
        """
        Represents an Ansible plugin reference.
        This also covers modules, roles, and playbooks.
        """
    
        plugin: PluginIdentifier
        """The plugin."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.PLUGIN] = PartType.PLUGIN
        """The type of this part."""
    
    plugin

    The plugin.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[PLUGIN] = PLUGIN
    

    The type of this part.

    antsibull_docs_parser.dom.PluginIdentifier

    Bases: NamedTuple

    A plugin identifier.

    Source code in src/antsibull_docs_parser/dom.py
    class PluginIdentifier(NamedTuple):
        """
        A plugin identifier.
        """
    
        fqcn: str
        """The plugin's FQCN (fully qualified collection name)."""
    
        type: str
        """The plugin's type. Can also be ``"module"`` or ``"role"``."""
    
    fqcn
    fqcn: str
    

    The plugin's FQCN (fully qualified collection name).

    type
    type: str
    

    The plugin's type. Can also be "module" or "role".

  • antsibull_docs_parser.dom.URLPart

    Bases: NamedTuple

    Represents an URL without a title.

    Source code in src/antsibull_docs_parser/dom.py
    class URLPart(NamedTuple):
        """
        Represents an URL without a title.
        """
    
        url: str
        """The URL."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.URL] = PartType.URL
        """The type of this part."""
    
    url
    url: str
    

    The URL.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[URL] = URL
    

    The type of this part.

  • antsibull_docs_parser.dom.LinkPart

    Bases: NamedTuple

    Represents an URL with a title.

    Source code in src/antsibull_docs_parser/dom.py
    class LinkPart(NamedTuple):
        """
        Represents an URL with a title.
        """
    
        text: str
        """The link's title."""
    
        url: str
        """The link's URL."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.LINK] = PartType.LINK
        """The type of this part."""
    
    text
    text: str
    

    The link's title.

    url
    url: str
    

    The link's URL.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[LINK] = LINK
    

    The type of this part.

  • antsibull_docs_parser.dom.RSTRefPart

    Bases: NamedTuple

    Represents a reference to a ReStructuredText label in a Sphinx docsite. Most renderers simply reproduce the link's title (the text).

    Source code in src/antsibull_docs_parser/dom.py
    class RSTRefPart(NamedTuple):
        """
        Represents a reference to a ReStructuredText label in a Sphinx docsite.
        Most renderers simply reproduce the link's title (the text).
        """
    
        text: str
        """The reference's title."""
    
        ref: str
        """The RST (ReStructuredText) reference for the Sphinx Ansible docsite."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.RST_REF] = PartType.RST_REF
        """The type of this part."""
    
    text
    text: str
    

    The reference's title.

    ref
    ref: str
    

    The RST (ReStructuredText) reference for the Sphinx Ansible docsite.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[RST_REF] = RST_REF
    

    The type of this part.

  • antsibull_docs_parser.dom.CodePart

    Bases: NamedTuple

    Represents "code" formatted text.

    Source code in src/antsibull_docs_parser/dom.py
    class CodePart(NamedTuple):
        """
        Represents "code" formatted text.
        """
    
        text: str
        """The text to render as code."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.CODE] = PartType.CODE
        """The type of this part."""
    
    text
    text: str
    

    The text to render as code.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[CODE] = CODE
    

    The type of this part.

  • antsibull_docs_parser.dom.OptionNamePart

    Bases: NamedTuple

    References an option name, optionally with reference to the plugin, a role entrypoint (if the plugin is a role), link information, and a value.

    Source code in src/antsibull_docs_parser/dom.py
    class OptionNamePart(NamedTuple):
        """
        References an option name, optionally with reference to the plugin,
        a role entrypoint (if the plugin is a role), link information, and a value.
        """
    
        plugin: PluginIdentifier | None
        """The (optional) plugin this option belongs to."""
    
        entrypoint: str | None  # present iff plugin.type == 'role'
        """The (optional) role's entry point this option belongs to."""
    
        link: list[str]
        """
        The option's name split up as a sequence of strings.
    
        For example, ``foo.bar[].baz`` will result in ``["foo", "bar", "baz"]``.
        """
    
        name: str
        """The option's name."""
    
        value: str | None
        """The (optional) option's value."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.OPTION_NAME] = PartType.OPTION_NAME
    
    plugin
    plugin: PluginIdentifier | None
    

    The (optional) plugin this option belongs to.

    entrypoint
    entrypoint: str | None
    

    The (optional) role's entry point this option belongs to.

    link: list[str]
    

    The option's name split up as a sequence of strings.

    For example, foo.bar[].baz will result in ["foo", "bar", "baz"].

    name
    name: str
    

    The option's name.

    value
    value: str | None
    

    The (optional) option's value.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[OPTION_NAME] = OPTION_NAME
    
  • antsibull_docs_parser.dom.OptionValuePart

    Bases: NamedTuple

    References an Ansible value.

    Source code in src/antsibull_docs_parser/dom.py
    class OptionValuePart(NamedTuple):
        """
        References an Ansible value.
        """
    
        value: str
        """The value."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.OPTION_VALUE] = PartType.OPTION_VALUE
        """The type of this part."""
    
    value
    value: str
    

    The value.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[OPTION_VALUE] = OPTION_VALUE
    

    The type of this part.

  • antsibull_docs_parser.dom.EnvVariablePart

    Bases: NamedTuple

    References an environment variable.

    Source code in src/antsibull_docs_parser/dom.py
    class EnvVariablePart(NamedTuple):
        """
        References an environment variable.
        """
    
        name: str
        """The environment variable's name."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.ENV_VARIABLE] = PartType.ENV_VARIABLE
        """The type of this part."""
    
    name
    name: str
    

    The environment variable's name.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[ENV_VARIABLE] = ENV_VARIABLE
    

    The type of this part.

  • antsibull_docs_parser.dom.ReturnValuePart

    Bases: NamedTuple

    References an return value name, optionally with reference to the plugin, a role entrypoint (if the plugin is a role), link information, and a value.

    Source code in src/antsibull_docs_parser/dom.py
    class ReturnValuePart(NamedTuple):
        """
        References an return value name, optionally with reference to the plugin,
        a role entrypoint (if the plugin is a role), link information, and a value.
        """
    
        plugin: PluginIdentifier | None
        """The (optional) plugin this return value belongs to."""
    
        entrypoint: str | None  # present iff plugin.type == 'role'
        """The (optional) role's entry point this return value belongs to."""
    
        link: list[str]
        """
        The return value's name split up as a sequence of strings.
    
        For example, ``foo.bar[].baz`` will result in ``["foo", "bar", "baz"]``.
        """
    
        name: str
        """The return value's name."""
    
        value: str | None
        """The (optional) return value's value."""
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.RETURN_VALUE] = PartType.RETURN_VALUE
        """The type of this part."""
    
    plugin
    plugin: PluginIdentifier | None
    

    The (optional) plugin this return value belongs to.

    entrypoint
    entrypoint: str | None
    

    The (optional) role's entry point this return value belongs to.

    link: list[str]
    

    The return value's name split up as a sequence of strings.

    For example, foo.bar[].baz will result in ["foo", "bar", "baz"].

    name
    name: str
    

    The return value's name.

    value
    value: str | None
    

    The (optional) return value's value.

    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[RETURN_VALUE] = RETURN_VALUE
    

    The type of this part.

  • antsibull_docs_parser.dom.HorizontalLinePart

    Bases: NamedTuple

    References a HTML <hr> tag.

    Source code in src/antsibull_docs_parser/dom.py
    class HorizontalLinePart(NamedTuple):
        """
        References a HTML `<hr>` tag.
        """
    
        source: str | None = None
        """The (optional) source of the markup."""
    
        type: t.Literal[PartType.HORIZONTAL_LINE] = PartType.HORIZONTAL_LINE
        """The type of this part."""
    
    source
    source: str | None = None
    

    The (optional) source of the markup.

    type
    type: Literal[HORIZONTAL_LINE] = HORIZONTAL_LINE
    

    The type of this part.

  • antsibull_docs_parser.dom.ErrorPart

    Bases: NamedTuple

    References a parsing error.

    The parser can ignore errors, raise them as exceptions, or emit them as error parts into the output. ErrorPart is used in the third case.

    Source code in src/antsibull_docs_parser/dom.py
    class ErrorPart(NamedTuple):
        """
        References a parsing error.
    
        The parser can ignore errors, raise them as exceptions,
        or emit them as error parts into the output. `ErrorPart` is used in the third case.
        """
    
        message: str
        """The error message."""
    
        source: str | None = None
        """The (optional) source of the markup that caused the error."""
    
        type: t.Literal[PartType.ERROR] = PartType.ERROR
        """The type of this part."""
    
    message
    message: str
    

    The error message.

    source
    source: str | None = None
    

    The (optional) source of the markup that caused the error.

    type
    type: Literal[ERROR] = ERROR
    

    The type of this part.

Walking parts

A walker is a class that provides a method for every part type. The walk() function will go through all parts of a paragraph and call the corresponding method of the walker for every part.

antsibull_docs_parser.dom.walk

walk(paragraph: Paragraph, walker: Walker) -> None

Call the corresponding methods of a walker object for every part of the paragraph.

Source code in src/antsibull_docs_parser/dom.py
def walk(paragraph: Paragraph, walker: Walker) -> None:  # noqa: C901
    """
    Call the corresponding methods of a walker object for every part of the paragraph.
    """
    for part in paragraph:
        if part.type == PartType.ERROR:
            walker.process_error(t.cast(ErrorPart, part))
        elif part.type == PartType.BOLD:
            walker.process_bold(t.cast(BoldPart, part))
        elif part.type == PartType.CODE:
            walker.process_code(t.cast(CodePart, part))
        elif part.type == PartType.HORIZONTAL_LINE:
            walker.process_horizontal_line(t.cast(HorizontalLinePart, part))
        elif part.type == PartType.ITALIC:
            walker.process_italic(t.cast(ItalicPart, part))
        elif part.type == PartType.LINK:
            walker.process_link(t.cast(LinkPart, part))
        elif part.type == PartType.MODULE:
            walker.process_module(t.cast(ModulePart, part))
        elif part.type == PartType.RST_REF:
            walker.process_rst_ref(t.cast(RSTRefPart, part))
        elif part.type == PartType.URL:
            walker.process_url(t.cast(URLPart, part))
        elif part.type == PartType.TEXT:
            walker.process_text(t.cast(TextPart, part))
        elif part.type == PartType.ENV_VARIABLE:
            walker.process_env_variable(t.cast(EnvVariablePart, part))
        elif part.type == PartType.OPTION_NAME:
            walker.process_option_name(t.cast(OptionNamePart, part))
        elif part.type == PartType.OPTION_VALUE:
            walker.process_option_value(t.cast(OptionValuePart, part))
        elif part.type == PartType.PLUGIN:
            walker.process_plugin(t.cast(PluginPart, part))
        elif part.type == PartType.RETURN_VALUE:
            walker.process_return_value(t.cast(ReturnValuePart, part))
        else:
            raise RuntimeError(f"Internal error: unknown type {part.type!r}")

antsibull_docs_parser.dom provides two walker base classes:

  • Walker is an abstract base class where every method is abstract and needs to be implemented. Use this if you want to be sure to handle every type, even if new types are added in the future.

  • NoopWalker is a concrete base class where every method from Walker is implemented and does nothing by default. Use this if you only want to do something for some specific parts, and do not want to bother implementing all other required methods.

antsibull_docs_parser.dom.Walker

Bases: ABC

Abstract base class for walker whose methods will be called for parts of a paragraph.

Source code in src/antsibull_docs_parser/dom.py
class Walker(abc.ABC):
    """
    Abstract base class for walker whose methods will be called for parts of a paragraph.
    """

    @abc.abstractmethod
    def process_error(self, part: ErrorPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_bold(self, part: BoldPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_code(self, part: CodePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_horizontal_line(self, part: HorizontalLinePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_italic(self, part: ItalicPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_link(self, part: LinkPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_module(self, part: ModulePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_rst_ref(self, part: RSTRefPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_url(self, part: URLPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_text(self, part: TextPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_env_variable(self, part: EnvVariablePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_option_name(self, part: OptionNamePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_option_value(self, part: OptionValuePart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_plugin(self, part: PluginPart) -> None:
        pass  # pragma: no cover

    @abc.abstractmethod
    def process_return_value(self, part: ReturnValuePart) -> None:
        pass  # pragma: no cover
process_error
process_error(part: ErrorPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_error(self, part: ErrorPart) -> None:
    pass  # pragma: no cover
process_bold
process_bold(part: BoldPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_bold(self, part: BoldPart) -> None:
    pass  # pragma: no cover
process_code
process_code(part: CodePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_code(self, part: CodePart) -> None:
    pass  # pragma: no cover
process_horizontal_line
process_horizontal_line(part: HorizontalLinePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_horizontal_line(self, part: HorizontalLinePart) -> None:
    pass  # pragma: no cover
process_italic
process_italic(part: ItalicPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_italic(self, part: ItalicPart) -> None:
    pass  # pragma: no cover
process_link(part: LinkPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_link(self, part: LinkPart) -> None:
    pass  # pragma: no cover
process_module
process_module(part: ModulePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_module(self, part: ModulePart) -> None:
    pass  # pragma: no cover
process_rst_ref
process_rst_ref(part: RSTRefPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_rst_ref(self, part: RSTRefPart) -> None:
    pass  # pragma: no cover
process_url
process_url(part: URLPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_url(self, part: URLPart) -> None:
    pass  # pragma: no cover
process_text
process_text(part: TextPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_text(self, part: TextPart) -> None:
    pass  # pragma: no cover
process_env_variable
process_env_variable(part: EnvVariablePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_env_variable(self, part: EnvVariablePart) -> None:
    pass  # pragma: no cover
process_option_name
process_option_name(part: OptionNamePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_option_name(self, part: OptionNamePart) -> None:
    pass  # pragma: no cover
process_option_value
process_option_value(part: OptionValuePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_option_value(self, part: OptionValuePart) -> None:
    pass  # pragma: no cover
process_plugin
process_plugin(part: PluginPart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_plugin(self, part: PluginPart) -> None:
    pass  # pragma: no cover
process_return_value
process_return_value(part: ReturnValuePart) -> None
Source code in src/antsibull_docs_parser/dom.py
@abc.abstractmethod
def process_return_value(self, part: ReturnValuePart) -> None:
    pass  # pragma: no cover

antsibull_docs_parser.dom.NoopWalker

Bases: Walker

Concrete base class for walker whose methods will be called for parts of a paragraph. The default implementation for every part will not do anything.

Source code in src/antsibull_docs_parser/dom.py
class NoopWalker(Walker):
    """
    Concrete base class for walker whose methods will be called for parts of a paragraph.
    The default implementation for every part will not do anything.
    """

    def process_error(self, part: ErrorPart) -> None:
        pass

    def process_bold(self, part: BoldPart) -> None:
        pass

    def process_code(self, part: CodePart) -> None:
        pass

    def process_horizontal_line(self, part: HorizontalLinePart) -> None:
        pass

    def process_italic(self, part: ItalicPart) -> None:
        pass

    def process_link(self, part: LinkPart) -> None:
        pass

    def process_module(self, part: ModulePart) -> None:
        pass

    def process_rst_ref(self, part: RSTRefPart) -> None:
        pass

    def process_url(self, part: URLPart) -> None:
        pass

    def process_text(self, part: TextPart) -> None:
        pass

    def process_env_variable(self, part: EnvVariablePart) -> None:
        pass

    def process_option_name(self, part: OptionNamePart) -> None:
        pass

    def process_option_value(self, part: OptionValuePart) -> None:
        pass

    def process_plugin(self, part: PluginPart) -> None:
        pass

    def process_return_value(self, part: ReturnValuePart) -> None:
        pass
process_error
process_error(part: ErrorPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_error(self, part: ErrorPart) -> None:
    pass
process_bold
process_bold(part: BoldPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_bold(self, part: BoldPart) -> None:
    pass
process_code
process_code(part: CodePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_code(self, part: CodePart) -> None:
    pass
process_horizontal_line
process_horizontal_line(part: HorizontalLinePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_horizontal_line(self, part: HorizontalLinePart) -> None:
    pass
process_italic
process_italic(part: ItalicPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_italic(self, part: ItalicPart) -> None:
    pass
process_link(part: LinkPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_link(self, part: LinkPart) -> None:
    pass
process_module
process_module(part: ModulePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_module(self, part: ModulePart) -> None:
    pass
process_rst_ref
process_rst_ref(part: RSTRefPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_rst_ref(self, part: RSTRefPart) -> None:
    pass
process_url
process_url(part: URLPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_url(self, part: URLPart) -> None:
    pass
process_text
process_text(part: TextPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_text(self, part: TextPart) -> None:
    pass
process_env_variable
process_env_variable(part: EnvVariablePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_env_variable(self, part: EnvVariablePart) -> None:
    pass
process_option_name
process_option_name(part: OptionNamePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_option_name(self, part: OptionNamePart) -> None:
    pass
process_option_value
process_option_value(part: OptionValuePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_option_value(self, part: OptionValuePart) -> None:
    pass
process_plugin
process_plugin(part: PluginPart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_plugin(self, part: PluginPart) -> None:
    pass
process_return_value
process_return_value(part: ReturnValuePart) -> None
Source code in src/antsibull_docs_parser/dom.py
def process_return_value(self, part: ReturnValuePart) -> None:
    pass

Parsing Ansible markup

The parser can be found in the Python module antsibull_docs_parser.parser.

antsibull_docs_parser.parser.parse

parse(
    text: str | Sequence[str],
    context: Context,
    errors: ErrorType = "message",
    only_classic_markup: bool = False,
    strict: bool = False,
    add_source: bool = False,
    helpful_errors: bool = True,
    *,
    whitespace: Whitespace = IGNORE
) -> list[Paragraph]

Parse a string, or a sequence of strings, to a list of paragraphs.

Parameters:

  • text (str | Sequence[str]) –

    A string or a sequence of strings. If given a sequence of strings, will assume that this is a list of paragraphs.

  • context (Context) –

    Contextual information.

    Set current_plugin if the Ansible markup is parsed in the context of a specific plugin, like when parsing a plugin's description, or the option and return value descriptions of a plugin. If a role's documentation is parsed, and the markup belongs to a specific entrypoint, you can also specify this entrypoint as role_entrypoint.

    This allows to automatically fill in this context in option and return value parts so it is clear which plugin's or role entrypoint's option or return value is referenced in case the markup does not specify the plugin resp. role entrypoint.

    Simply use an unmodified instance of Context when parsing general markup.

  • errors (ErrorType, default: 'message' ) –

    How to handle errors while parsing.

    "ignore" Simply ignores errors.

    "message" Inserts errors as :class:antsibull_docs_parser.dom.ErrorPart parts into the output.

    "exception" Makes the function throw Python exceptions. This also means that it will stop processing on the first error.

  • only_classic_markup (bool, default: False ) –

    Whether to ignore semantic markup and treat it as raw text.

    Should only be used in very special cases. This is mostly for backwards compatibility for processors that do not want to understand semantic markup.

  • strict (bool, default: False ) –

    Whether to be extra strict while parsing.

    Whether escaping should only be accepted if necessary. Only ever enable this when linting markup.

  • add_source (bool, default: False ) –

    Whether to add the source of every part to the part (source property).

  • helpful_errors (bool, default: True ) –

    Whether to include the faulty markup in error messages.

  • whitespace (Whitespace, default: IGNORE ) –

    How to handle whitespace.

    In case the parsed markup is used to format output in a markup format that is whitespace sensitive, we recommend to use :attr:.Whitespace.STRIP or :attr:.Whitespace.KEEP_SINGLE_NEWLINES.

Returns:

  • list[Paragraph]

    A list of paragraphs. Each paragraph consists of a list of parts.

Source code in src/antsibull_docs_parser/parser.py
def parse(
    text: str | t.Sequence[str],
    context: Context,
    errors: dom.ErrorType = "message",
    only_classic_markup: bool = False,
    strict: bool = False,
    add_source: bool = False,
    helpful_errors: bool = True,
    *,
    whitespace: Whitespace = Whitespace.IGNORE,
) -> list[dom.Paragraph]:
    """
    Parse a string, or a sequence of strings, to a list of paragraphs.

    :param text: A string or a sequence of strings. If given a sequence of strings, will assume
        that this is a list of paragraphs.

    :param context: Contextual information.

        Set ``current_plugin`` if the Ansible markup is parsed in the context of a specific plugin,
        like when parsing a plugin's description, or the option and return value descriptions
        of a plugin. If a role's documentation is parsed, and the markup belongs to a specific
        entrypoint, you can also specify this entrypoint as ``role_entrypoint``.

        This allows to automatically fill in this context in option and return value parts
        so it is clear which plugin's or role entrypoint's option or return value is referenced
        in case the markup does not specify the plugin resp. role entrypoint.

        Simply use an unmodified instance of ``Context`` when parsing general markup.

    :param errors: How to handle errors while parsing.

        ``"ignore"``
            Simply ignores errors.

        ``"message"``
            Inserts errors as :class:`antsibull_docs_parser.dom.ErrorPart` parts into the output.

        ``"exception"``
            Makes the function throw Python exceptions.
            This also means that it will stop processing on the first error.

    :param only_classic_markup: Whether to ignore semantic markup and treat it as raw text.

        Should only be used in very special cases. This is mostly for backwards compatibility
        for processors that do not want to understand semantic markup.

    :param strict: Whether to be extra strict while parsing.

        Whether escaping should only be accepted if necessary.
        Only ever enable this when linting markup.

    :param add_source: Whether to add the source of every part to the part (``source`` property).

    :param helpful_errors: Whether to include the faulty markup in error messages.

    :param whitespace: How to handle whitespace.

        In case the parsed markup is used to format output in a markup format that is
        whitespace sensitive, we recommend to use :attr:`.Whitespace.STRIP` or
        :attr:`.Whitespace.KEEP_SINGLE_NEWLINES`.

    :return: A list of paragraphs. Each paragraph consists of a list of parts.
    """
    has_paragraphs = True
    if isinstance(text, str):
        has_paragraphs = False
        text = [text] if text else []
    parser = _CLASSIC if only_classic_markup else _SEMANTIC_MARKUP
    return [
        parser.parse_string(
            par,
            context,
            errors=errors,
            where=f" of paragraph {index + 1}" if has_paragraphs else "",
            strict=strict,
            add_source=add_source,
            helpful_errors=helpful_errors,
            whitespace=whitespace,
        )
        for index, par in enumerate(text)
    ]

antsibull_docs_parser.parser.Context

Bases: NamedTuple

Describes the context in which markup is parsed.

If an option or return value is referenced without a plugin or role entrypoint, the information from the context is used, if available.

So if O(bam) is used in the context of a plugin foo.bar.baz, it is assumed that bam is an option of foo.bar.baz.

If the context does not have a current plugin, O(bam) references an unknown plugin.

Source code in src/antsibull_docs_parser/parser.py
class Context(t.NamedTuple):
    """
    Describes the context in which markup is parsed.

    If an option or return value is referenced without a plugin or role entrypoint,
    the information from the context is used, if available.

    So if ``O(bam)`` is used in the context of a plugin ``foo.bar.baz``,
    it is assumed that ``bam`` is an option of ``foo.bar.baz``.

    If the context does not have a current plugin, ``O(bam)`` references an unknown plugin.
    """

    current_plugin: dom.PluginIdentifier | None = None
    """The current plugin for this context."""

    role_entrypoint: str | None = None
    """The role entrypoint for this context, if the current plugin is a role."""
current_plugin
current_plugin: PluginIdentifier | None = None

The current plugin for this context.

role_entrypoint
role_entrypoint: str | None = None

The role entrypoint for this context, if the current plugin is a role.

antsibull_docs_parser.parser.Whitespace

Bases: Enum

How whitespace should be parsed.

Source code in src/antsibull_docs_parser/parser.py
class Whitespace(_Enum):
    """
    How whitespace should be parsed.
    """

    IGNORE = 0
    """Keep all whitespace as-is."""

    STRIP = 1
    """
    Reduce all whitespace (space, tabs, newlines, ...) to regular breakable or
    non-breakable spaces. Multiple spaces are kept in everything that's often
    rendered code-style, like ``C()``, ``O()``, ``V()``, ``RV()``, ``E()``.
    """

    KEEP_SINGLE_NEWLINES = 2
    """Similar to STRIP, but keep single newlines intact."""
IGNORE
IGNORE = 0

Keep all whitespace as-is.

STRIP
STRIP = 1

Reduce all whitespace (space, tabs, newlines, ...) to regular breakable or non-breakable spaces. Multiple spaces are kept in everything that's often rendered code-style, like C(), O(), V(), RV(), E().

KEEP_SINGLE_NEWLINES
KEEP_SINGLE_NEWLINES = 2

Similar to STRIP, but keep single newlines intact.

Rendering Ansible markup

antsibull-docs-parser provides multiple Python packages for formatting:

  • a general formatting framework in antsibull_docs_parser.format;
  • a specific formatter for ansible-doc like plaintext formatting in antsibull_docs_parser.ansible_doc_text;
  • customizable HTML rendering in antsibull_docs_parser.html;
  • customizable MarkDown rendering in antsibull_docs_parser.md; and
  • customizable ReStructured Text rendering in antsibull_docs_parser.rst.

General formatting

antsibull_docs_parser.format provides two abstract base classes and one function:

  • LinkProvider provides URLs for objects (plugins, options, and return values).
  • Formatter converts parts to strings. URLs provided by the LinkProvider are also passed to the methods.
  • format_paragraphs goes through one or multiple paragraphs, calls LinkProvider for parts that reference plugins, options, or return values, and passes the part together with potential URLs to the formatting methods of a Formatter object. The resulting strings are concatenated, with optional strings at the beginning of paragraphs, end of paragraphs, between paragraphs, and for empty paragraphs.

antsibull_docs_parser.format.LinkProvider

Bases: ABC

Provide URLs for objects, if available.

Source code in src/antsibull_docs_parser/format.py
class LinkProvider(abc.ABC):
    """
    Provide URLs for objects, if available.
    """

    def plugin_link(  # pylint:disable=no-self-use
        self,
        plugin: dom.PluginIdentifier,  # pylint:disable=unused-argument
    ) -> str | None:
        """Provides a link to a plugin."""
        return None

    def plugin_option_like_link(  # pylint:disable=no-self-use
        self,
        plugin: dom.PluginIdentifier,  # pylint:disable=unused-argument
        entrypoint: str | None,  # pylint:disable=unused-argument
        # pylint:disable-next=unused-argument
        what: t.Literal["option"] | t.Literal["retval"],
        # pylint:disable-next=unused-argument
        name: list[str],
        # pylint:disable-next=unused-argument
        current_plugin: bool,
    ) -> str | None:
        """Provides a link to a plugin's option or return value."""
        return None
plugin_link(plugin: PluginIdentifier) -> str | None

Provides a link to a plugin.

Source code in src/antsibull_docs_parser/format.py
def plugin_link(  # pylint:disable=no-self-use
    self,
    plugin: dom.PluginIdentifier,  # pylint:disable=unused-argument
) -> str | None:
    """Provides a link to a plugin."""
    return None
plugin_option_like_link(
    plugin: PluginIdentifier,
    entrypoint: str | None,
    what: Literal["option"] | Literal["retval"],
    name: list[str],
    current_plugin: bool,
) -> str | None

Provides a link to a plugin's option or return value.

Source code in src/antsibull_docs_parser/format.py
def plugin_option_like_link(  # pylint:disable=no-self-use
    self,
    plugin: dom.PluginIdentifier,  # pylint:disable=unused-argument
    entrypoint: str | None,  # pylint:disable=unused-argument
    # pylint:disable-next=unused-argument
    what: t.Literal["option"] | t.Literal["retval"],
    # pylint:disable-next=unused-argument
    name: list[str],
    # pylint:disable-next=unused-argument
    current_plugin: bool,
) -> str | None:
    """Provides a link to a plugin's option or return value."""
    return None

antsibull_docs_parser.format.Formatter

Bases: ABC

Abstract base class for a formatter whose functions will be called for parts of a paragraph.

Source code in src/antsibull_docs_parser/format.py
class Formatter(abc.ABC):
    """
    Abstract base class for a formatter whose functions will be called for
    parts of a paragraph.
    """

    @abc.abstractmethod
    def format_error(self, part: dom.ErrorPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_bold(self, part: dom.BoldPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_code(self, part: dom.CodePart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_horizontal_line(self, part: dom.HorizontalLinePart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_italic(self, part: dom.ItalicPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_link(self, part: dom.LinkPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_module(self, part: dom.ModulePart, url: str | None) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_rst_ref(self, part: dom.RSTRefPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_url(self, part: dom.URLPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_text(self, part: dom.TextPart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_env_variable(self, part: dom.EnvVariablePart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_option_name(self, part: dom.OptionNamePart, url: str | None) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_option_value(self, part: dom.OptionValuePart) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_plugin(self, part: dom.PluginPart, url: str | None) -> str:
        pass  # pragma: no cover

    @abc.abstractmethod
    def format_return_value(self, part: dom.ReturnValuePart, url: str | None) -> str:
        pass  # pragma: no cover
format_error
format_error(part: ErrorPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_error(self, part: dom.ErrorPart) -> str:
    pass  # pragma: no cover
format_bold
format_bold(part: BoldPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_bold(self, part: dom.BoldPart) -> str:
    pass  # pragma: no cover
format_code
format_code(part: CodePart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_code(self, part: dom.CodePart) -> str:
    pass  # pragma: no cover
format_horizontal_line
format_horizontal_line(part: HorizontalLinePart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_horizontal_line(self, part: dom.HorizontalLinePart) -> str:
    pass  # pragma: no cover
format_italic
format_italic(part: ItalicPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_italic(self, part: dom.ItalicPart) -> str:
    pass  # pragma: no cover
format_link(part: LinkPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_link(self, part: dom.LinkPart) -> str:
    pass  # pragma: no cover
format_module
format_module(part: ModulePart, url: str | None) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_module(self, part: dom.ModulePart, url: str | None) -> str:
    pass  # pragma: no cover
format_rst_ref
format_rst_ref(part: RSTRefPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_rst_ref(self, part: dom.RSTRefPart) -> str:
    pass  # pragma: no cover
format_url
format_url(part: URLPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_url(self, part: dom.URLPart) -> str:
    pass  # pragma: no cover
format_text
format_text(part: TextPart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_text(self, part: dom.TextPart) -> str:
    pass  # pragma: no cover
format_env_variable
format_env_variable(part: EnvVariablePart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_env_variable(self, part: dom.EnvVariablePart) -> str:
    pass  # pragma: no cover
format_option_name
format_option_name(part: OptionNamePart, url: str | None) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_option_name(self, part: dom.OptionNamePart, url: str | None) -> str:
    pass  # pragma: no cover
format_option_value
format_option_value(part: OptionValuePart) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_option_value(self, part: dom.OptionValuePart) -> str:
    pass  # pragma: no cover
format_plugin
format_plugin(part: PluginPart, url: str | None) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_plugin(self, part: dom.PluginPart, url: str | None) -> str:
    pass  # pragma: no cover
format_return_value
format_return_value(part: ReturnValuePart, url: str | None) -> str
Source code in src/antsibull_docs_parser/format.py
@abc.abstractmethod
def format_return_value(self, part: dom.ReturnValuePart, url: str | None) -> str:
    pass  # pragma: no cover

antsibull_docs_parser.format.format_paragraphs

format_paragraphs(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: PluginIdentifier | None = None,
    *,
    postprocess_paragraph: Callable[[str], str] | None = None
) -> str

Apply the formatter to all parts of the given paragraphs, concatenate the results, and insert start and end sequences for paragraphs and sequences between paragraphs.

link_provider and current_plugin will be used to compute optional URLs that will be passed to the formatter.

Source code in src/antsibull_docs_parser/format.py
def format_paragraphs(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: dom.PluginIdentifier | None = None,
    *,
    postprocess_paragraph: t.Callable[[str], str] | None = None,
) -> str:
    """
    Apply the formatter to all parts of the given paragraphs, concatenate the results,
    and insert start and end sequences for paragraphs and sequences between paragraphs.

    ``link_provider`` and ``current_plugin`` will be used to compute optional URLs
    that will be passed to the formatter.
    """
    if link_provider is None:
        link_provider = _DefaultLinkProvider()
    result: list[str] = []
    for paragraph in paragraphs:
        if result:
            result.append(par_sep)
        result.append(par_start)

        par_result: list[str] = []
        walker = _FormatWalker(par_result, formatter, link_provider, current_plugin)
        dom.walk(paragraph, walker)
        par = "".join(par_result)
        if postprocess_paragraph:
            par = postprocess_paragraph(par)
        if not par:
            par = par_empty
        result.append(par)

        result.append(par_end)
    return "".join(result)

Ansible-doc like plaintext formatting

antsibull_docs_parser.ansible_doc_text.to_ansible_doc_text() converts one or multiple paragraphs into plain text, similar to ansible-doc's text output.

antsibull_docs_parser.ansible_doc_text.to_ansible_doc_text

to_ansible_doc_text(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_ANSIBLE_DOC_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "",
    current_plugin: PluginIdentifier | None = None,
) -> str

Converts one or multiple paragraphs into plain text, similar to ansible-doc's text output.

Source code in src/antsibull_docs_parser/ansible_doc_text.py
def to_ansible_doc_text(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_ANSIBLE_DOC_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Converts one or multiple paragraphs into plain text, similar to ``ansible-doc``'s text output.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
    )

HTML rendering

antsibull_docs_parser.html provides two functions for formatting HTML output. These functions are customizable, and the formatters used can also be derived from to override formatting for specific parts.

antsibull_docs_parser.html.to_html

to_html(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_ANTSIBULL_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "<p>",
    par_end: str = "</p>",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: PluginIdentifier | None = None,
) -> str

Formats one or multiple paragraphs as HTML output that is suited for use in Sphinx docsites.

Source code in src/antsibull_docs_parser/html.py
def to_html(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_ANTSIBULL_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "<p>",
    par_end: str = "</p>",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Formats one or multiple paragraphs as HTML output that is suited for use in Sphinx docsites.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
    )

antsibull_docs_parser.html.to_html_plain

to_html_plain(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_PLAIN_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "<p>",
    par_end: str = "</p>",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: PluginIdentifier | None = None,
) -> str

Formats one or multiple paragraphs as plain HTML output.

Source code in src/antsibull_docs_parser/html.py
def to_html_plain(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_PLAIN_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "<p>",
    par_end: str = "</p>",
    par_sep: str = "",
    par_empty: str = "",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Formats one or multiple paragraphs as plain HTML output.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
    )

MarkDown rendering

antsibull_docs_parser.md provides a function for formatting MarkDown output, to_md. This function is customizable, and the formatter used can also be derived from to override formatting for specific parts.

antsibull_docs_parser.md.to_md

to_md(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = " ",
    current_plugin: PluginIdentifier | None = None,
) -> str

Formats one or multiple paragraphs as MarkDown.

Source code in src/antsibull_docs_parser/md.py
def to_md(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = " ",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Formats one or multiple paragraphs as MarkDown.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
        postprocess_paragraph=postprocess_md_paragraph,
    )

ReStructuredText rendering

antsibull_docs_parser.rst provides two functions for formatting ReStructuredText output. These functions are customizable, and the formatters used can also be derived from to override formatting for specific parts.

antsibull_docs_parser.rst.to_rst

to_rst(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_ANTSIBULL_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "\\",
    current_plugin: PluginIdentifier | None = None,
) -> str

Formats one or multiple paragraphs as RST output that is suited for use in Sphinx docsites that use antsibull-docs' sphinx_antsibull_ext Sphinx extension.

Source code in src/antsibull_docs_parser/rst.py
def to_rst(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_ANTSIBULL_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "\\",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Formats one or multiple paragraphs as RST output that is suited for use in Sphinx docsites
    that use antsibull-docs' ``sphinx_antsibull_ext`` Sphinx extension.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
        postprocess_paragraph=postprocess_rst_paragraph,
    )

antsibull_docs_parser.rst.to_rst_plain

to_rst_plain(
    paragraphs: Sequence[Paragraph],
    formatter: Formatter = DEFAULT_PLAIN_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "\\",
    current_plugin: PluginIdentifier | None = None,
) -> str

Formats one or multiple paragraphs as plain RST output.

Source code in src/antsibull_docs_parser/rst.py
def to_rst_plain(
    paragraphs: t.Sequence[dom.Paragraph],
    formatter: Formatter = DEFAULT_PLAIN_FORMATTER,
    link_provider: LinkProvider | None = None,
    par_start: str = "",
    par_end: str = "",
    par_sep: str = "\n\n",
    par_empty: str = "\\",
    current_plugin: dom.PluginIdentifier | None = None,
) -> str:
    """
    Formats one or multiple paragraphs as plain RST output.
    """
    return _format_paragraphs(
        paragraphs,
        formatter=formatter,
        link_provider=link_provider,
        par_start=par_start,
        par_end=par_end,
        par_sep=par_sep,
        par_empty=par_empty,
        current_plugin=current_plugin,
        postprocess_paragraph=postprocess_rst_paragraph,
    )