#!/usr/bin/env python3 """Индекс HTML-макета → docs/mockup/INDEX.md. Для каждого *.html: заголовок, h1/h2, кнопки/ссылки-действия, названия модалок/вкладок, упоминания ANL-/ARCH-/OQ-, размер. Цель — дать агенту навигацию по макету без загрузки HTML в контекст. Запуск: python scripts/mockup_index.py docs/mockup/dkb_24.09.26 > docs/mockup/INDEX.md Зависимости: beautifulsoup4, lxml (pip install beautifulsoup4 lxml). """ from __future__ import annotations import re import sys from collections import Counter from pathlib import Path from bs4 import BeautifulSoup ACTION_TAGS = ("button", "a") MODAL_HINTS = ("modal", "dialog", "drawer", "popup", "sheet") TAB_HINTS = ("tab", "nav-link") ID_RE = re.compile(r"\b(ANL|ARCH|OQ|FIX|DECISION)-\d+\b") def text(el) -> str: return re.sub(r"\s+", " ", el.get_text(" ", strip=True))[:60] def classes(el) -> str: return " ".join(el.get("class", [])) + " " + (el.get("id") or "") def index_file(p: Path) -> dict: html = p.read_text(encoding="utf-8", errors="ignore") soup = BeautifulSoup(html, "lxml") title = soup.title.get_text(strip=True) if soup.title else "" heads = [text(h) for h in soup.find_all(["h1", "h2"])][:12] actions = Counter(text(a) for a in soup.find_all(ACTION_TAGS) if text(a)) modals = [text(m.find(["h1", "h2", "h3", "h4"]) or m) for m in soup.find_all(True) if any(h in classes(m).lower() for h in MODAL_HINTS)][:15] tabs = [text(t) for t in soup.find_all(True) if any(h in classes(t).lower() for h in TAB_HINTS) and text(t)][:20] ids = sorted(set(ID_RE.findall(html))) return {"file": p, "title": title, "heads": heads, "actions": actions, "modals": modals, "tabs": tabs, "ids": ids} def main() -> int: root = Path(sys.argv[1]) files = sorted(root.rglob("*.html")) print(f"# Индекс макета `{root}`\n") print(f"{len(files)} HTML-файлов. Сгенерировано `scripts/mockup_index.py`; колонку «Экран» и «Срез» править руками.\n") print("| Файл | КБ | Заголовок / h1-h2 | Действия (кнопки) | Модалки / вкладки | Ссылки на ANL/ARCH | Экран (DBML «Макет:») | Срез |") print("|---|---|---|---|---|---|---|---|") for f in files: d = index_file(f) rel = f.relative_to(root) kb = f.stat().st_size // 1024 heads = "; ".join([d["title"]] + d["heads"])[:160] acts = ", ".join(a for a, _ in d["actions"].most_common(10))[:160] mt = "; ".join(dict.fromkeys(d["modals"] + d["tabs"]))[:120] ids = ", ".join(d["ids"])[:80] print(f"| `{rel}` | {kb} | {heads} | {acts} | {mt} | {ids} | | |") return 0 if __name__ == "__main__": sys.exit(main())