|
4 | 4 |
|
5 | 5 | from typing import TYPE_CHECKING
|
6 | 6 |
|
| 7 | +from docutils import nodes |
| 8 | +from sphinx import addnodes |
| 9 | +from sphinx.locale import _ as sphinx_gettext |
7 | 10 | from sphinx.util import logging
|
8 |
| -from support import SmartItemList |
| 11 | +from sphinx.util.docutils import SphinxDirective |
9 | 12 |
|
10 | 13 | if TYPE_CHECKING:
|
11 | 14 | from sphinx.application import Sphinx
|
|
46 | 49 | KNOWN_PLATFORMS = _PLATFORMS | _LIBC | _THREADING
|
47 | 50 |
|
48 | 51 |
|
49 |
| -class Availability(SmartItemList): |
50 |
| - """Parse platform information from arguments |
51 |
| -
|
52 |
| - Arguments is a comma-separated string of platforms. A platform may |
53 |
| - be prefixed with "not " to indicate that a feature is not available. |
54 |
| -
|
55 |
| - Example:: |
56 |
| -
|
57 |
| - .. availability:: Windows, Linux >= 4.2, not WASI |
58 |
| -
|
59 |
| - Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not |
60 |
| - parsed into separate tokens. |
61 |
| - """ |
62 |
| - |
63 |
| - title = "Availability" |
64 |
| - reftarget = "availability" |
65 |
| - classes = ["availability"] |
66 |
| - |
67 |
| - def check_information(self, platforms: dict[str, str | bool], /) -> None: |
68 |
| - unknown = platforms.keys() - KNOWN_PLATFORMS |
69 |
| - self._check_information( |
70 |
| - logger, |
71 |
| - f"{__file__}:KNOWN_PLATFORMS", |
72 |
| - unknown, |
73 |
| - ("platform", "platforms"), |
74 |
| - len(platforms), |
| 52 | +class Availability(SphinxDirective): |
| 53 | + has_content = True |
| 54 | + required_arguments = 1 |
| 55 | + optional_arguments = 0 |
| 56 | + final_argument_whitespace = True |
| 57 | + |
| 58 | + def run(self) -> list[nodes.container]: |
| 59 | + title = sphinx_gettext("Availability") |
| 60 | + refnode = addnodes.pending_xref( |
| 61 | + title, |
| 62 | + nodes.inline(title, title, classes=["xref", "std", "std-ref"]), |
| 63 | + refdoc=self.env.docname, |
| 64 | + refdomain="std", |
| 65 | + refexplicit=True, |
| 66 | + reftarget="availability", |
| 67 | + reftype="ref", |
| 68 | + refwarn=True, |
75 | 69 | )
|
| 70 | + sep = nodes.Text(": ") |
| 71 | + parsed, msgs = self.state.inline_text(self.arguments[0], self.lineno) |
| 72 | + pnode = nodes.paragraph(title, "", refnode, sep, *parsed, *msgs) |
| 73 | + self.set_source_info(pnode) |
| 74 | + cnode = nodes.container("", pnode, classes=["availability"]) |
| 75 | + self.set_source_info(cnode) |
| 76 | + if self.content: |
| 77 | + self.state.nested_parse(self.content, self.content_offset, cnode) |
| 78 | + self.parse_platforms() |
| 79 | + |
| 80 | + return [cnode] |
| 81 | + |
| 82 | + def parse_platforms(self) -> dict[str, str | bool]: |
| 83 | + """Parse platform information from arguments |
| 84 | +
|
| 85 | + Arguments is a comma-separated string of platforms. A platform may |
| 86 | + be prefixed with "not " to indicate that a feature is not available. |
| 87 | +
|
| 88 | + Example:: |
| 89 | +
|
| 90 | + .. availability:: Windows, Linux >= 4.2, not WASI |
| 91 | +
|
| 92 | + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not |
| 93 | + parsed into separate tokens. |
| 94 | + """ |
| 95 | + platforms = {} |
| 96 | + for arg in self.arguments[0].rstrip(".").split(","): |
| 97 | + arg = arg.strip() |
| 98 | + platform, _, version = arg.partition(" >= ") |
| 99 | + if platform.startswith("not "): |
| 100 | + version = False |
| 101 | + platform = platform.removeprefix("not ") |
| 102 | + elif not version: |
| 103 | + version = True |
| 104 | + platforms[platform] = version |
| 105 | + |
| 106 | + if unknown := set(platforms).difference(KNOWN_PLATFORMS): |
| 107 | + logger.warning( |
| 108 | + "Unknown platform%s or syntax '%s' in '.. availability:: %s', " |
| 109 | + "see %s:KNOWN_PLATFORMS for a set of known platforms.", |
| 110 | + "s" if len(platforms) != 1 else "", |
| 111 | + " ".join(sorted(unknown)), |
| 112 | + self.arguments[0], |
| 113 | + __file__, |
| 114 | + ) |
| 115 | + |
| 116 | + return platforms |
76 | 117 |
|
77 | 118 |
|
78 | 119 | def setup(app: Sphinx) -> ExtensionMetadata:
|
|
0 commit comments