67 lines
2.9 KiB
Python
67 lines
2.9 KiB
Python
#!/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())
|