| {escape(c)} | '
f'{s["accuracy"]}%({s["correct"]}/{s["total"]},'
f'未答 {s.get("no_answer", 0)}) | '
f'{btxt} | {delta} |
')
return "\n ".join(rows)
def render(score: dict, template: str, assets: Path, score_json_name: str) -> str:
ov = score["overall"]
bo = score["baseline"]["overall"]
delta = round(ov["accuracy"] - bo["accuracy"], 1)
values = {
"TITLE": f"评测记分卡:{score['model']}({score['skill_mode']})",
"LOGO_B64": asset_b64(assets, "lingyao-logo.png"),
"FONT_B64": asset_b64(assets, "logo-font.ttf"),
"MODEL": score["model"],
"SKILL_MODE_LABEL": "加载技能" if score["skill_mode"] == "with-skill"
else "裸答对照",
"BENCHMARK": score["benchmark"],
"SKILL_VERSION": score.get("skill_version", "—"),
"EVAL_DATE": score.get("eval_date", "—"),
"OVERALL_ACC": f'{ov["accuracy"]}',
"OVERALL_CORRECT": f'{ov["correct"]}',
"OVERALL_TOTAL": f'{ov["total"]}',
"NO_ANSWER": f'{ov.get("no_answer", 0)}',
"BASELINE_NAME": score["baseline"].get("name", "官方基线"),
"BASELINE_ACC": f'{bo["accuracy"]}',
"DELTA_CLASS": "up" if delta >= 0 else "down",
"DELTA_TEXT": f'({"+" if delta >= 0 else ""}{delta}pp)',
"DIM_BARS": dim_bars(score),
"CONTEST_ROWS": contest_rows(score),
"SCORE_JSON": score_json_name,
}
out = template
for k, v in values.items():
out = out.replace("{{" + k + "}}", v if k in STRUCTURAL else escape(str(v)))
leftover = [p.split("}}")[0] for p in out.split("{{")[1:]]
assert not leftover, f"模板存在未填充占位符: {leftover}"
return out
def main() -> int:
ap = argparse.ArgumentParser(description="得分.json → 单文件 HTML 记分卡")
ap.add_argument("--score", type=Path, default=DEFAULT_SCORE)
ap.add_argument("--out", type=Path, default=None,
help="默认与得分.json 同目录的 得分.html")
ap.add_argument("--template", type=Path,
default=Path(__file__).resolve().parent / "scorecard_template.html")
ap.add_argument("--assets", type=Path,
default=SKILL / "scripts" / "render" / "assets")
a = ap.parse_args()
score = json.loads(a.score.read_text(encoding="utf-8"))
template = a.template.read_text(encoding="utf-8")
out = a.out or a.score.with_name("得分.html")
html = render(score, template, a.assets, a.score.name)
out.write_text(html, encoding="utf-8")
print(f"OK: {out}({len(html)} 字符,logo/字体"
f"{'已内嵌' if asset_b64(a.assets, 'lingyao-logo.png') else '未找到,已留空'})")
return 0
if __name__ == "__main__":
sys.exit(main())