Skip to content

Commit 082d9e1

Browse files
committed
Add directivegetter
1 parent f6a736d commit 082d9e1

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

directivegetter.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
import sys
5+
from typing import TYPE_CHECKING
6+
7+
from docutils.parsers.rst.directives import _directive_registry, _directives
8+
from docutils.parsers.rst.languages import en
9+
from sphinx.builders.dummy import DummyBuilder
10+
11+
if TYPE_CHECKING:
12+
from collections.abc import Iterator, Iterable
13+
14+
from sphinx.application import Sphinx
15+
16+
DOCUTILS_DIRECTIVES = frozenset(_directive_registry.keys() | en.directives.keys())
17+
SPHINX_DIRECTIVES = frozenset({
18+
"acks", "centered", "codeauthor", "cssclass", "default-domain",
19+
"deprecated", "describe", "highlight", "hlist", "index", "literalinclude",
20+
"moduleauthor", "object", "only", "rst-class", "sectionauthor", "seealso",
21+
"tabularcolumns", "toctree", "versionadded", "versionchanged",
22+
})
23+
CORE_DIRECTIVES = DOCUTILS_DIRECTIVES | SPHINX_DIRECTIVES
24+
25+
26+
def tomlify_directives(directives: Iterable[str], comment: str) -> Iterator[str]:
27+
yield f" # {comment}:"
28+
yield from (f' "{directive}",' for directive in sorted(directives))
29+
30+
31+
def write_directives(directives: Iterable[str]):
32+
lines = [
33+
"[lint]",
34+
"known_directives = [",
35+
*tomlify_directives(DOCUTILS_DIRECTIVES, "reStructuredText"),
36+
*tomlify_directives(SPHINX_DIRECTIVES, "Added by Sphinx"),
37+
*tomlify_directives(directives, "Added by extensions or in conf.py"),
38+
"]",
39+
"", # final blank line
40+
]
41+
with open("sphinx.toml", "w", encoding="utf-8") as file:
42+
file.write("\n".join(lines))
43+
44+
45+
class DirectiveCollectorBuilder(DummyBuilder):
46+
name = "directive_collector"
47+
48+
def get_outdated_docs(self) -> str:
49+
return "nothing, just getting list of directives"
50+
51+
def read(self) -> list[str]:
52+
write_directives({*_directives} - CORE_DIRECTIVES)
53+
return []
54+
55+
def write(self, *args, **kwargs) -> None:
56+
pass
57+
58+
59+
def setup(app: Sphinx) -> dict[str, bool]:
60+
"""Plugin for Sphinx"""
61+
app.add_builder(DirectiveCollectorBuilder)
62+
return {"parallel_read_safe": True, "parallel_write_safe": True}
63+
64+
65+
def collect_directives():
66+
from sphinx import application
67+
from sphinx.application import Sphinx
68+
69+
try:
70+
source_dir, build_dir, *opts = sys.argv[1:]
71+
except ValueError:
72+
raise RuntimeError("Two arguments (source dir and build dir) are required.")
73+
74+
application.builtin_extensions = (
75+
*application.builtin_extensions,
76+
"directivegetter" # set up this file as an extension
77+
)
78+
app = Sphinx(
79+
str(Path(source_dir)),
80+
str(Path(source_dir)),
81+
str(Path(build_dir)),
82+
str(Path(build_dir, "doctrees")),
83+
"directive_collector",
84+
)
85+
app.build(force_all=True)
86+
raise SystemExit(app.statuscode)
87+
88+
89+
if __name__ == "__main__":
90+
collect_directives()

0 commit comments

Comments
 (0)