diff --git a/scripts/generate_site.py b/scripts/generate_site.py
index 59628a6f..25810183 100644
--- a/scripts/generate_site.py
+++ b/scripts/generate_site.py
@@ -1498,6 +1498,88 @@ def generate_platform_index(coverages: dict, registry: dict | None = None) -> st
return "\n".join(lines) + "\n"
+def _render_platform_systems(
+ by_system: dict, config_files: dict, emulator_files: dict
+) -> list[str]:
+ """One collapsible block per system, listing every file it needs.
+
+ Split out of generate_platform_page: the block is most of that
+ function's branching, since each file renders a different set of
+ hashes, sizes and provenance depending on what the platform declares.
+ """
+ lines: list[str] = []
+ # Per-system detail sections (collapsible for large platforms)
+ use_collapsible = len(by_system) > 10
+
+ for sys_id, files in sorted(by_system.items()):
+ ok_count = sum(1 for f in files if f["status"] == "ok")
+ total = len(files)
+
+ sys_emus = []
+ if emulator_files:
+ for emu_name, emu_data in emulator_files.items():
+ if sys_id in emu_data.get("systems", set()):
+ sys_emus.append(emu_name)
+
+ sys_link = _system_link(sys_id, "../")
+
+ anchor = sys_id.replace(" ", "-")
+ if use_collapsible:
+ status_tag = "OK" if ok_count == total else f"{total - ok_count} issues"
+ lines.append(f'')
+ lines.append(f'??? note "{sys_id} ({ok_count}/{total} - {status_tag})"')
+ lines.append("")
+ pad = " "
+ else:
+ lines.append(f"## {sys_link}")
+ lines.append("")
+ pad = ""
+
+ lines.append(f"{pad}{ok_count}/{total} files verified")
+ if sys_emus:
+ emu_links = ", ".join(_emulator_link(e, "../") for e in sorted(sys_emus))
+ lines.append(f"{pad}Emulators: {emu_links}")
+ lines.append("")
+
+ # File listing
+ for f in sorted(files, key=lambda x: x["name"]):
+ status = f["status"]
+ fname = f["name"]
+ cfg_entry = config_files.get(fname, {})
+ sha1 = cfg_entry.get("sha1", f.get("sha1", ""))
+ md5 = cfg_entry.get("md5", f.get("expected_md5", ""))
+ size = cfg_entry.get("size", f.get("size", 0))
+
+ if status == "ok":
+ status_display = "OK"
+ elif status == "untested":
+ reason = f.get("reason", "")
+ status_display = f"untested: {reason}" if reason else "untested"
+ elif status == "missing":
+ status_display = "**missing**"
+ else:
+ status_display = status
+
+ size_str = _fmt_size(size) if size else ""
+ details = [status_display]
+ if size_str:
+ details.append(size_str)
+
+ lines.append(f"{pad}- `{fname}` - {', '.join(details)}")
+ # Show full hashes on a sub-line (useful for copy-paste)
+ if sha1 or md5:
+ hash_parts = []
+ if sha1:
+ hash_parts.append(f"SHA1: `{sha1}`")
+ if md5:
+ hash_parts.append(f"MD5: `{md5}`")
+ lines.append(f"{pad} {' | '.join(hash_parts)}")
+
+ lines.append("")
+
+ return lines
+
+
def generate_platform_page(
name: str,
cov: dict,
@@ -1650,74 +1732,9 @@ def generate_platform_page(
)
lines.append("")
- # Per-system detail sections (collapsible for large platforms)
- use_collapsible = len(by_system) > 10
-
- for sys_id, files in sorted(by_system.items()):
- ok_count = sum(1 for f in files if f["status"] == "ok")
- total = len(files)
-
- sys_emus = []
- if emulator_files:
- for emu_name, emu_data in emulator_files.items():
- if sys_id in emu_data.get("systems", set()):
- sys_emus.append(emu_name)
-
- sys_link = _system_link(sys_id, "../")
-
- anchor = sys_id.replace(" ", "-")
- if use_collapsible:
- status_tag = "OK" if ok_count == total else f"{total - ok_count} issues"
- lines.append(f'')
- lines.append(f'??? note "{sys_id} ({ok_count}/{total} - {status_tag})"')
- lines.append("")
- pad = " "
- else:
- lines.append(f"## {sys_link}")
- lines.append("")
- pad = ""
-
- lines.append(f"{pad}{ok_count}/{total} files verified")
- if sys_emus:
- emu_links = ", ".join(_emulator_link(e, "../") for e in sorted(sys_emus))
- lines.append(f"{pad}Emulators: {emu_links}")
- lines.append("")
-
- # File listing
- for f in sorted(files, key=lambda x: x["name"]):
- status = f["status"]
- fname = f["name"]
- cfg_entry = config_files.get(fname, {})
- sha1 = cfg_entry.get("sha1", f.get("sha1", ""))
- md5 = cfg_entry.get("md5", f.get("expected_md5", ""))
- size = cfg_entry.get("size", f.get("size", 0))
-
- if status == "ok":
- status_display = "OK"
- elif status == "untested":
- reason = f.get("reason", "")
- status_display = f"untested: {reason}" if reason else "untested"
- elif status == "missing":
- status_display = "**missing**"
- else:
- status_display = status
-
- size_str = _fmt_size(size) if size else ""
- details = [status_display]
- if size_str:
- details.append(size_str)
-
- lines.append(f"{pad}- `{fname}` - {', '.join(details)}")
- # Show full hashes on a sub-line (useful for copy-paste)
- if sha1 or md5:
- hash_parts = []
- if sha1:
- hash_parts.append(f"SHA1: `{sha1}`")
- if md5:
- hash_parts.append(f"MD5: `{md5}`")
- lines.append(f"{pad} {' | '.join(hash_parts)}")
-
- lines.append("")
+ lines.extend(
+ _render_platform_systems(by_system, config_files, emulator_files)
+ )
lines.append(f"*Generated on {_timestamp()}*")
return "\n".join(lines) + "\n"