"""Listet Python-Codeblöcke mit Einrückungsfehlern in Markdown-Dateien (mit Inhalt, zum Vergleich mit der Quelle). Aufruf: python tools/qa/pyblocks.py AUSGABE/chapters/*.md """ from __future__ import annotations import ast import re import sys def main() -> None: for path in sys.argv[1:]: with open(path, encoding="utf-8") as fh: lines = fh.read().split("\n") i = 0 while i < len(lines): m = re.match(r"^(`{3,})python\s*$", lines[i]) if m: j = i + 1 while j < len(lines) and not lines[j].startswith(m.group(1)): j += 1 try: ast.parse("\n".join(lines[i + 1:j])) except IndentationError as exc: print(f"== {path}:{i + 1} {exc.msg} (Blockzeile {exc.lineno})") print("\n".join(f"{k + 1:3}|{line}" for k, line in enumerate(lines[i + 1:j]))) except SyntaxError: pass # fragments and program output are no indentation defects i = j i += 1 if __name__ == "__main__": main()