meanas/scripts/prepare_docs_sources.py
2026-04-19 16:40:05 -07:00

93 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Prepare a temporary source tree for docs generation.
The live source keeps readable display-math blocks written as standalone
`$$ ... $$` docstring sections. MkDocs + mkdocstrings does not consistently
preserve those blocks as MathJax input when they appear inside API docstrings,
so the docs build rewrites them in a temporary copy into explicit
`<div class="arithmatex">...</div>` containers.
"""
from __future__ import annotations
from pathlib import Path
import shutil
import sys
def _rewrite_display_math(text: str) -> str:
lines = text.splitlines(keepends=True)
output: list[str] = []
in_block = False
block_indent = ""
for line in lines:
stripped = line.strip()
indent = line[: len(line) - len(line.lstrip())]
if not in_block:
if stripped == "$$":
block_indent = indent
output.append(f'{block_indent}<div class="arithmatex">\\[\n')
in_block = True
continue
if stripped.startswith("$$") and stripped.endswith("$$") and stripped != "$$":
body = stripped[2:-2].strip()
output.append(f'{indent}<div class="arithmatex">\\[ {body} \\]</div>\n')
continue
if stripped.startswith("$$"):
block_indent = indent
body = stripped[2:].strip()
output.append(f'{block_indent}<div class="arithmatex">\\[\n')
if body:
output.append(f"{block_indent}{body}\n")
in_block = True
continue
output.append(line)
continue
if stripped == "$$":
output.append(f"{block_indent}\\]</div>\n")
in_block = False
block_indent = ""
continue
if stripped.endswith("$$"):
body = stripped[:-2].rstrip()
if body:
output.append(f"{block_indent}{body}\n")
output.append(f"{block_indent}\\]</div>\n")
in_block = False
block_indent = ""
continue
output.append(line)
if in_block:
raise ValueError("unterminated display-math block")
return "".join(output)
def main() -> int:
if len(sys.argv) != 3:
print("usage: prepare_docs_sources.py <src_package_dir> <dst_root>", file=sys.stderr)
return 2
src_dir = Path(sys.argv[1]).resolve()
dst_root = Path(sys.argv[2]).resolve()
dst_pkg = dst_root / src_dir.name
shutil.copytree(src_dir, dst_pkg)
for path in dst_pkg.rglob("*.py"):
path.write_text(_rewrite_display_math(path.read_text()))
return 0
if __name__ == "__main__":
raise SystemExit(main())