diff --git a/scripts/generate_site.py b/scripts/generate_site.py
index c3414d0a..aa8808fe 100644
--- a/scripts/generate_site.py
+++ b/scripts/generate_site.py
@@ -2931,35 +2931,44 @@ def generate_systems_index(manufacturers: dict) -> str:
"",
]
- for heading, games, first in (("Consoles and computers", False, "Console"),
- ("Game engines and PC games", True, "Name")):
+ # Other holds one folder per emulator: a7800 or altirra in the console
+ # table named no console.
+ def kind(mfr: str) -> str:
+ if mfr in GAME_DATA_TOPS:
+ return "games"
+ return "programs" if mfr == "Other" else "consoles"
+
+ for heading, group, first, note in (
+ ("Consoles and computers", "consoles", "Console", ""),
+ ("Emulator folders", "programs", "Folder",
+ "Files kept under the emulator that reads them, not under a console."),
+ ("Game engines and PC games", "games", "Name",
+ "Game engines and PC games hold the files a game engine reads, such "
+ "as the data of a game, rather than the BIOS of a machine."),
+ ):
rows = sorted(
((_console_display(mfr, console), mfr, console, len(files))
- for mfr, consoles in manufacturers.items()
- if (mfr in GAME_DATA_TOPS) == games
+ for mfr, consoles in manufacturers.items() if kind(mfr) == group
for console, files in consoles.items()),
key=lambda row: (row[0].casefold(), row[1].casefold(), row[2]),
)
if not rows:
continue
+ lines += [f"## {heading}", ""]
+ if note:
+ lines += [note, ""]
lines += [
- f"## {heading}",
- "",
- f"| {first} | Manufacturer | Files |",
- "|---------|--------------|------:|",
+ # The count before the maker: on a phone the last column is
+ # the one scrolled off, and most names carry the maker already.
+ f"| {first} | Files | Maker |",
+ "|---------|------:|-------|",
]
for name, mfr, console, count in rows:
cell = name.replace("|", "-")
anchor = _slugify_anchor(console)
href = f"{_slug(mfr)}.md" + (f"#{anchor}" if anchor else "")
- lines.append(f"| [{cell}]({href}) | [{mfr}]({_slug(mfr)}.md) | {count:,} |")
+ lines.append(f"| [{cell}]({href}) | {count:,} | [{mfr}]({_slug(mfr)}.md) |")
lines.append("")
- if games:
- lines += [
- "Game engines and PC games hold the files a game engine reads, such "
- "as the data of a game, rather than the BIOS of a machine.",
- "",
- ]
return "\n".join(lines) + "\n"
@@ -3467,7 +3476,10 @@ def _system_file_card(
if group:
lines.append(f'
')
# One value cell per label: the grid pairs each dt with one dd.
- lines.extend(f"- {label}
- "
+ # A searched value keeps its label out: the excerpt ran the two
+ # together, "On the setup's listAmberELEC".
+ label_skip = f" {skip}" if not attributes else ""
+ lines.extend(f"
- {label}
- "
+ "
".join(_inline_card_html(v) for v in values) + " "
for label, values, _searched in group)
lines.append("
")
diff --git a/tests/test_site_r2_systems.py b/tests/test_site_r2_systems.py
index 04cf75ae..7f2e2aa6 100644
--- a/tests/test_site_r2_systems.py
+++ b/tests/test_site_r2_systems.py
@@ -155,8 +155,9 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase):
def test_labels_and_display_names(self):
text = "\n".join(self.lines)
- self.assertIn("On the setup's listBatocera: scph5501.bin", text)
+ self.assertIn("On the setup's listBatocera: scph5501.bin",
+ text)
self.assertIn("Packed for its emulators byRetroBat: bios/scph5501.bin", text)
self.assertNotIn("Platforms:", text)
@@ -168,6 +169,9 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase):
searched = "\n".join(self.lines).split('', 1)[1].split("
")[0]
self.assertIn("On the setup's list", searched)
self.assertNotIn("SHA1", searched)
+ # The label stays out of the excerpt: the search ran the two
+ # together, "On the setup's listAmberELEC".
+ self.assertIn("On the setup's list", searched)
def test_the_page_defines_both_lines(self):
page = gs.generate_system_page("Sony", {"PlayStation": [_file("scph5501.bin", "4")]},
@@ -235,12 +239,14 @@ class TheSystemsIndexListsConsoles(unittest.TestCase):
"Game Engines": {"TheXTech": [_file("d.png", "d")]},
}
page = gs.generate_systems_index(groups)
- self.assertIn("| [Sony PlayStation](sony.md#playstation) | [Sony](sony.md) | 1 |", page)
- self.assertIn("| [Sony PlayStation 2](sony.md#playstation-2) | [Sony](sony.md) | 1 |",
+ self.assertIn("| [Sony PlayStation](sony.md#playstation) | 1 | [Sony](sony.md) |", page)
+ self.assertIn("| [Sony PlayStation 2](sony.md#playstation-2) | 1 | [Sony](sony.md) |",
page)
- # A program's folder under Other is named alone.
- self.assertIn("| [ScummVM](other.md#scummvm) | [Other](other.md) | 1 |", page)
- consoles = page.split("## Game engines")[0]
+ # A program's folder under Other is named alone, in its own table.
+ consoles = page.split("## Emulator folders")[0]
+ self.assertNotIn("ScummVM", consoles)
+ self.assertIn("| [ScummVM](other.md#scummvm) | 1 | [Other](other.md) |",
+ page.split("## Emulator folders")[1])
self.assertNotIn("TheXTech", consoles)
self.assertIn("| [TheXTech](game-engines.md#thextech)", page)
diff --git a/tests/test_site_render.py b/tests/test_site_render.py
index ad238838..c957d34c 100644
--- a/tests/test_site_render.py
+++ b/tests/test_site_render.py
@@ -2,7 +2,6 @@
from __future__ import annotations
-import re
import sys
import tempfile
import unittest
@@ -357,13 +356,14 @@ class TheSearchSkipsLinkLists(unittest.TestCase):
entry = {"name": "a.bin", "sha1": sha1, "md5": "b" * 32, "size": 3}
lines = generate_site._system_file_card(entry, consumers)
self.assertIn("a.bin", lines[2])
- rows = {re.search(r"(.*?)", line)[1]: line for line in lines
- if line.startswith("" in line}
+ text = "\n".join(lines)
+ searched, _sep, skipped = text.partition('
')
for label in ("MD5", "Emulators", "Packed for its emulators by"):
- self.assertTrue(rows[label].startswith(""), label)
+ self.assertIn(f"
- {label}
", skipped)
+ self.assertNotIn(f">{label}", searched)
# The platforms line names the file as each setup does: the site
# search reads it, so a file name finds its card.
- self.assertTrue(rows["On the setup's list"].startswith("
- "))
+ self.assertRegex(searched, r'
\n- ]*>On the setup\'s list
')
def test_a_game_data_card_skips_its_name_too(self):
import generate_site