"""Sucht in den Codebloecken eines Plans nach Zeichen, die ein Executer nicht sehen oder nicht tippen kann. Koordinator-Werkzeug. Frage: Steht in einem Codeblock ein Zeichen, das beim Abschreiben verloren geht? Herkunft der Antwort: Unicode-Kategorie des Zeichens (unicodedata, Quelle: Python-Standardbibliothek). Befund ist jedes Zeichen der Kategorien Zl, Zp, Cf, Cc (ausser \\n und \\t) und Zs ausser dem Leerzeichen -- also Zeilen- und Absatztrenner, Formatzeichen, Steuerzeichen, geschuetzte und schmale Leerzeichen. Alle uebrigen Nicht-ASCII-Zeichen in Codebloecken werden nur gezaehlt und gezeigt (Umlaute, Gedankenstriche). Was es nicht sieht: Zeichen ausserhalb von Codezaeunen; verwechselbare sichtbare Zeichen (kyrillisches c). Aufruf: python plan_zeichen.py Exit 0 ohne Befund, 2 mit Befund. """ import sys import unicodedata from collections import Counter from pathlib import Path def main() -> int: plan = Path(sys.argv[1]) dateien = sorted(plan.glob("*.md")) if not dateien: print(f"BEFUND {plan}: keine Markdown-Dateien -- der Lauf misst nichts") return 2 befunde = 0 sichtbar: Counter[str] = Counter() bloecke = 0 for datei in dateien: zeilen = datei.read_text(encoding="utf-8").replace("\r\n", "\n").split("\n") zaun = 0 for nummer, zeile in enumerate(zeilen, start=1): kern = zeile.lstrip() if kern.startswith("```"): laenge = len(kern) - len(kern.lstrip("`")) if zaun == 0: zaun = laenge bloecke += 1 elif laenge >= zaun and not kern.strip("`").strip(): zaun = 0 continue if zaun == 0: continue for spalte, zeichen in enumerate(zeile, start=1): if ord(zeichen) < 128 and zeichen not in "\x0b\x0c\x1b" and (zeichen >= " " or zeichen == "\t"): continue kategorie = unicodedata.category(zeichen) if kategorie in ("Zl", "Zp", "Cf", "Cc") or (kategorie == "Zs" and zeichen != " "): name = unicodedata.name(zeichen, "?") print(f"BEFUND {datei.name}:{nummer}:{spalte}: U+{ord(zeichen):04X} {name} ({kategorie}) in: {zeile.strip()[:110]!r}") befunde += 1 else: sichtbar[zeichen] += 1 print(f"{len(dateien)} Dateien, {bloecke} Codebloecke gelesen.") print("Sichtbare Nicht-ASCII-Zeichen in Codebloecken: " + " ".join(f"{z}(U+{ord(z):04X})x{n}" for z, n in sichtbar.most_common())) print(f"{befunde} Befund(e).") return 2 if befunde else 0 if __name__ == "__main__": sys.exit(main())