blob: 148dd300d73b32fa3d40ff7586f531a6a142faf2 [file]
#!/usr/bin/env python3
"""Remove page-local contents directives from Sphinx documentation."""
from __future__ import annotations
import argparse
import re
from pathlib import Path
CONTENTS = re.compile(
r"(?m)^```\{contents\}[^\n]*\n(?:.*\n)*?^```\n?|"
r"\n*^\.\. contents::[^\n]*(?:\n(?:[ \t].*|[ \t]*))*\n*"
)
SUFFIXES = (".rst", ".md", ".td")
def iter_sources(root: Path):
if root.is_file():
if root.suffix in SUFFIXES:
yield root
return
for suffix in SUFFIXES:
yield from root.rglob(f"*{suffix}")
def rewrite(path: Path) -> int:
text = path.read_text(encoding="utf-8")
def replacement(match: re.Match[str]) -> str:
if match.group(0).lstrip("\n").startswith("```") or not match.start():
return ""
return "\n\n" if match.end() < len(text) else "\n"
new_text, removed = CONTENTS.subn(replacement, text)
if new_text != text:
path.write_text(new_text, encoding="utf-8")
return removed
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"roots",
nargs="*",
type=Path,
default=[
Path("clang/docs"),
Path("clang/Maintainers.md"),
Path("clang/include/clang/Basic"),
Path("clang/include/clang/Options"),
],
help="Documentation roots to scan, defaults to Clang docs and generated-doc inputs.",
)
args = parser.parse_args()
removals = [
(path, rewrite(path))
for root in args.roots
for path in sorted(iter_sources(root))
]
changed = [(path, count) for path, count in removals if count]
for path, count in changed:
print(f"{path}: removed {count} contents directive(s)")
print(
f"removed {sum(count for _, count in changed)} contents directive(s) from {len(changed)} file(s)"
)
return 0
if __name__ == "__main__":
raise SystemExit(main())