* docs(gallery): refresh canonical visual catalog * docs: document screenshot renderer setup
55 lines
1.5 KiB
Python
55 lines
1.5 KiB
Python
"""Shared helpers for the canonical README screenshot catalog."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import re
|
|
import struct
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
SKILL = ROOT / "skills/diagram-design/SKILL.md"
|
|
ASSET_DIR = ROOT / "skills/diagram-design/assets"
|
|
SCREENSHOT_DIR = ROOT / "docs/screenshots"
|
|
MANIFEST = SCREENSHOT_DIR / "manifest.json"
|
|
|
|
|
|
def canonical_slugs() -> list[str]:
|
|
"""Return the visual-type order declared by SKILL.md's selection table."""
|
|
|
|
markdown = SKILL.read_text(encoding="utf-8")
|
|
start = markdown.find("### Visual-type guide")
|
|
end = markdown.find("Rules of thumb", start)
|
|
if start < 0 or end < 0:
|
|
raise ValueError("SKILL.md visual-type guide is missing")
|
|
return re.findall(
|
|
r"^\|[^\n]*\]\(references/type-([a-z0-9-]+)\.md\)\s*\|$",
|
|
markdown[start:end],
|
|
re.MULTILINE,
|
|
)
|
|
|
|
|
|
def source_path(slug: str) -> Path:
|
|
return ASSET_DIR / f"example-{slug}.html"
|
|
|
|
|
|
def screenshot_path(slug: str) -> Path:
|
|
return SCREENSHOT_DIR / f"{slug}.png"
|
|
|
|
|
|
def sha256(path: Path) -> str:
|
|
digest = hashlib.sha256()
|
|
with path.open("rb") as handle:
|
|
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
digest.update(chunk)
|
|
return digest.hexdigest()
|
|
|
|
|
|
def png_dimensions(path: Path) -> tuple[int, int]:
|
|
with path.open("rb") as handle:
|
|
header = handle.read(24)
|
|
if len(header) != 24 or header[:8] != b"\x89PNG\r\n\x1a\n":
|
|
raise ValueError(f"not a PNG: {path}")
|
|
return struct.unpack(">II", header[16:24])
|