mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-25 05:09:03 -05:00
feat: file emulator folders apart on systems index
Other holds one folder per emulator, so it gets its own table. The file count comes before the maker so it stays on a phone screen, and a card's searched label stays out of the search excerpt.
This commit is contained in:
1 parent
b084863ab1
commit
5da589bcaa
3 files changed
+46
-28
No files matched your search
+28
-16
@@ -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'<dl class="rb-facts"{attributes}>')
|
||||
# One value cell per label: the grid pairs each dt with one dd.
|
||||
lines.extend(f"<dt>{label}</dt><dd>"
|
||||
# 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"<dt{label_skip}>{label}</dt><dd>"
|
||||
+ "<br>".join(_inline_card_html(v) for v in values) + "</dd>"
|
||||
for label, values, _searched in group)
|
||||
lines.append("</dl>")
|
||||
|
||||
@@ -155,8 +155,9 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase):
|
||||
|
||||
def test_labels_and_display_names(self):
|
||||
text = "\n".join(self.lines)
|
||||
self.assertIn("<dt>On the setup's list</dt><dd><a href=\"../platforms/batocera.md"
|
||||
"#sony-playstation\">Batocera</a>: scph5501.bin</dd>", text)
|
||||
self.assertIn("<dt data-pagefind-ignore>On the setup's list</dt><dd><a href=\"../"
|
||||
"platforms/batocera.md#sony-playstation\">Batocera</a>: scph5501.bin</dd>",
|
||||
text)
|
||||
self.assertIn("<dt>Packed for its emulators by</dt><dd><a href=\"../platforms/"
|
||||
"retrobat.md\">RetroBat</a>: bios/scph5501.bin</dd>", text)
|
||||
self.assertNotIn("Platforms:", text)
|
||||
@@ -168,6 +169,9 @@ class TheCardLinesSayWhatTheyMean(unittest.TestCase):
|
||||
searched = "\n".join(self.lines).split('<dl class="rb-facts">', 1)[1].split("</dl>")[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("<dt data-pagefind-ignore>On the setup's list</dt><dd>", 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)
|
||||
|
||||
|
||||
@@ -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("<code>a.bin</code>", lines[2])
|
||||
rows = {re.search(r"<dt>(.*?)</dt>", line)[1]: line for line in lines
|
||||
if line.startswith("<div") and "<dt>" in line}
|
||||
text = "\n".join(lines)
|
||||
searched, _sep, skipped = text.partition('<dl class="rb-facts" data-pagefind-ignore>')
|
||||
for label in ("MD5", "Emulators", "Packed for its emulators by"):
|
||||
self.assertTrue(rows[label].startswith("<div data-pagefind-ignore>"), label)
|
||||
self.assertIn(f"<dt>{label}</dt>", skipped)
|
||||
self.assertNotIn(f">{label}</dt>", 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("<div><dt>"))
|
||||
self.assertRegex(searched, r'<dl class="rb-facts">\n<dt[^>]*>On the setup\'s list</dt>')
|
||||
|
||||
def test_a_game_data_card_skips_its_name_too(self):
|
||||
import generate_site
|
||||
|
||||
Reference in new issue
Block a user