summaryrefslogtreecommitdiff
path: root/docs/tox_conf.py
blob: e5134ff84285863229a3e7a5f3df34498f390e63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from __future__ import annotations

from typing import cast

from docutils.nodes import Element, Node, Text, container, fully_normalize_name, literal, paragraph, reference, strong
from docutils.parsers.rst.directives import flag, unchanged, unchanged_required
from docutils.parsers.rst.states import RSTState, RSTStateMachine
from docutils.statemachine import StringList, string2lines
from sphinx.domains.std import StandardDomain
from sphinx.locale import __
from sphinx.util.docutils import SphinxDirective
from sphinx.util.logging import getLogger

LOGGER = getLogger(__name__)


class ToxConfig(SphinxDirective):
    name = "conf"
    has_content = True
    option_spec = {
        "keys": unchanged_required,
        "version_added": unchanged,
        "version_changed": unchanged,
        "default": unchanged,
        "constant": flag,
        "ref_suffix": unchanged,
    }

    def __init__(
        self,
        name: str,
        arguments: list[str],
        options: dict[str, str],
        content: StringList,
        lineno: int,
        content_offset: int,
        block_text: str,
        state: RSTState,
        state_machine: RSTStateMachine,
    ):
        super().__init__(
            name,
            arguments,
            options,
            content,
            lineno,
            content_offset,
            block_text,
            state,
            state_machine,
        )
        self._std_domain: StandardDomain = cast(StandardDomain, self.env.get_domain("std"))

    def run(self) -> list[Node]:
        self.env.note_reread()  # this document needs to be always updated

        line = paragraph()
        line += Text("■" if "constant" in self.options else "⚙️")
        for key in (i.strip() for i in self.options["keys"].split(",")):
            line += Text(" ")
            self._mk_key(line, key)
        if "default" in self.options:
            default = self.options["default"]
            line += Text(" with default value of ")
            line += literal(default, default)
        if "version_added" in self.options:
            line += Text(" 📢 added in ")
            ver = self.options["version_added"]
            line += literal(ver, ver)

        p = container("")
        self.state.nested_parse(StringList(string2lines("\n".join(f"    {i}" for i in self.content))), 0, p)
        line += p

        return [line]

    def _mk_key(self, line: paragraph, key: str) -> None:
        ref_id = key if "ref_suffix" not in self.options else f"{key}-{self.options['ref_suffix']}"
        ref = reference("", refid=ref_id, reftitle=key)
        line.attributes["ids"].append(ref_id)
        st = strong()
        st += literal(text=key)
        ref += st
        self._register_ref(ref_id, ref_id, ref)
        line += ref

    def _register_ref(self, ref_name: str, ref_title: str, node: Element) -> None:
        of_name, doc_name = fully_normalize_name(ref_name), self.env.docname
        if of_name in self._std_domain.labels:
            LOGGER.warning(
                __("duplicate label %s, other instance in %s"),
                of_name,
                self.env.doc2path(self._std_domain.labels[of_name][0]),
                location=node,
                type="sphinx-argparse-cli",
                subtype=self.env.docname,
            )
        self._std_domain.anonlabels[of_name] = doc_name, ref_name
        self._std_domain.labels[of_name] = doc_name, ref_name, ref_title