docs: 태하 리포트 단일 HTML 내보내기 + export_html.py (링·진행바 점수 고정)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9ca5c593b8
commit
58fb4a317d
58
docs/reports/Taeha_AI_Answer_Readiness_Report.html
Normal file
58
docs/reports/Taeha_AI_Answer_Readiness_Report.html
Normal file
File diff suppressed because one or more lines are too long
69
docs/reports/export_html.py
Normal file
69
docs/reports/export_html.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
"""
|
||||||
|
/discovery/:id 리포트 페이지를 단일 HTML 파일로 내보낸다.
|
||||||
|
|
||||||
|
npm run build && npx vite preview --port 3012
|
||||||
|
python3 docs/reports/export_html.py taeha docs/reports/Taeha_AI_Answer_Readiness_Report.html
|
||||||
|
|
||||||
|
- 헤드리스 Chrome으로 렌더된 DOM을 덤프하고 빌드 CSS를 인라인한다
|
||||||
|
- Navbar·Footer·스크립트 제거, motion 애니메이션 고정
|
||||||
|
- ScoreRing 오프셋과 카테고리 진행 바 폭을 점수 텍스트에서 다시 계산한다
|
||||||
|
"""
|
||||||
|
import glob, re, subprocess, sys
|
||||||
|
|
||||||
|
CHROME = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||||
|
BASE = "http://localhost:3012"
|
||||||
|
|
||||||
|
slug, out = sys.argv[1], sys.argv[2]
|
||||||
|
title = sys.argv[3] if len(sys.argv) > 3 else f"{slug} AI Answer Readiness Report"
|
||||||
|
|
||||||
|
dom = subprocess.run(
|
||||||
|
[CHROME, "--headless=new", "--disable-gpu", "--window-size=1440,900", "--virtual-time-budget=20000",
|
||||||
|
"--dump-dom", f"{BASE}/discovery/{slug}"],
|
||||||
|
capture_output=True, text=True).stdout
|
||||||
|
css = open(glob.glob("dist/assets/*.css")[0], encoding="utf-8").read()
|
||||||
|
|
||||||
|
m = re.search(r'<div id="root">(.*)</div>\s*</body>', dom, re.S)
|
||||||
|
body = m.group(1)
|
||||||
|
body = re.sub(r"<script.*?</script>", "", body, flags=re.S)
|
||||||
|
body = re.sub(r"<nav\b.*?</nav>", "", body, flags=re.S, count=1)
|
||||||
|
body = re.sub(r"<footer\b.*?</footer>", "", body, flags=re.S)
|
||||||
|
|
||||||
|
# ScoreRing: dashoffset = circumference * (1 - score/100)
|
||||||
|
def fix_ring(mm):
|
||||||
|
circ = float(mm.group(2)); score = int(mm.group(5))
|
||||||
|
return f"{mm.group(1)}{circ * (1 - min(score, 100) / 100):.4f}{mm.group(4)}{score}{mm.group(6)}"
|
||||||
|
body, n_ring = re.subn(
|
||||||
|
r'(stroke-dasharray="([\d.]+)"\s+stroke-dashoffset=")([\d.]+)("></circle></svg><div class="absolute inset-0 flex items-center justify-center"><span[^>]*>)(\d+)(</span>)',
|
||||||
|
fix_ring, body)
|
||||||
|
|
||||||
|
# 카테고리 바: <div class="h-full rounded-full" style="background: X; width: 0%;"> … <span class="font-semibold">NN%</span>
|
||||||
|
def fix_bar(mm):
|
||||||
|
return f'{mm.group(1)}width: {mm.group(3)}%;{mm.group(4)}{mm.group(3)}%{mm.group(5)}'
|
||||||
|
body, n_bar = re.subn(
|
||||||
|
r'(<div class="h-full rounded-full" style="[^"]*?)width:\s*[\d.]+%;?([^"]*"[^>]*></div></div><div class="flex justify-between mt-2 text-sm"><span class="font-semibold">)(\d+)(%</span>)',
|
||||||
|
lambda mm: f'{mm.group(1)}width: {mm.group(3)}%;{mm.group(2)}{mm.group(3)}{mm.group(4)}', body)
|
||||||
|
|
||||||
|
html = f"""<!DOCTYPE html>
|
||||||
|
<html lang="ko">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{title}</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;0,900;1,400&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css">
|
||||||
|
<style>{css}</style>
|
||||||
|
<style>
|
||||||
|
[style*="opacity"], [style*="transform"] {{ opacity: 1 !important; transform: none !important; }}
|
||||||
|
html, body {{ background: #fff; }}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="min-h-screen bg-white">
|
||||||
|
{body}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>"""
|
||||||
|
open(out, "w", encoding="utf-8").write(html)
|
||||||
|
print(f"saved {out} ({len(html):,} bytes) rings={n_ring} bars={n_bar}")
|
||||||
Loading…
Reference in New Issue
Block a user