Buckets:
| #!/usr/bin/env python3 | |
| """Render poster.html to a PNG at print size and extract bounding boxes for | |
| every element carrying data-logbook-target, for building poster_embed.html.""" | |
| import json | |
| import re | |
| import sys | |
| from pathlib import Path | |
| from playwright.sync_api import sync_playwright | |
| POSTER = Path(sys.argv[1] if len(sys.argv) > 1 else "poster.html").resolve() | |
| OUT_PNG = Path(sys.argv[2] if len(sys.argv) > 2 else "poster.png").resolve() | |
| OUT_JSON = Path(sys.argv[3] if len(sys.argv) > 3 else "hotspots.json").resolve() | |
| text = POSTER.read_text() | |
| m = re.search(r"@page\s*{\s*size:\s*([\d.]+)in\s+([\d.]+)in", text) | |
| if not m: | |
| raise SystemExit("Could not find @page size in poster.html") | |
| w_in, h_in = float(m.group(1)), float(m.group(2)) | |
| DPI = 150 | |
| W, H = round(w_in * DPI), round(h_in * DPI) | |
| with sync_playwright() as p: | |
| browser = p.chromium.launch() | |
| page = browser.new_page(viewport={"width": W, "height": H}, device_scale_factor=1) | |
| page.emulate_media(media="print") | |
| page.goto(POSTER.as_uri()) | |
| page.wait_for_timeout(500) | |
| try: | |
| page.wait_for_function("window.MathJax && MathJax.startup && MathJax.startup.document", timeout=3000) | |
| page.wait_for_timeout(300) | |
| except Exception: | |
| pass | |
| poster_el = page.query_selector('[data-measure-role="poster"]') | |
| poster_box = poster_el.bounding_box() | |
| hotspots = [] | |
| for el in page.query_selector_all("[data-logbook-target]"): | |
| slug = el.get_attribute("data-logbook-target") | |
| box = el.bounding_box() | |
| if not box: | |
| continue | |
| hotspots.append( | |
| { | |
| "slug": slug, | |
| "left_pct": 100 * (box["x"] - poster_box["x"]) / poster_box["width"], | |
| "top_pct": 100 * (box["y"] - poster_box["y"]) / poster_box["height"], | |
| "width_pct": 100 * box["width"] / poster_box["width"], | |
| "height_pct": 100 * box["height"] / poster_box["height"], | |
| } | |
| ) | |
| page.screenshot(path=str(OUT_PNG), full_page=False, clip=poster_box) | |
| browser.close() | |
| OUT_JSON.write_text(json.dumps({"hotspots": hotspots, "png_w": W, "png_h": H}, indent=2)) | |
| print(f"Wrote {OUT_PNG} and {OUT_JSON} ({len(hotspots)} hotspots)") | |
Xet Storage Details
- Size:
- 2.22 kB
- Xet hash:
- 380e7abf498889607d21b346c744bbf0f604e309d22c517b450a30da21ce63f5
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.