#!/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())