mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-25 21:29:05 -05:00
feat: build the site with Astro Starlight
generate_site.py writes the Starlight project in website/ and nothing else: mkdocs.yml, the MkDocs hooks, theme overrides and stylesheet go, and the wiki is written in Starlight's syntax. Both workflows set up Node with the official actions/setup-node pinned by commit, run npm ci from the committed lockfile, build with the strict link validator and check the result with validate_site.py. The search weighs a page by what it answers: Start here pages first, a system page's cards and file names before a guide citing them, deep guides, launchers, aliases and frozen copies after. Status badges, hash blocks and the export change lists leave the index. The ranking sits at the centre of a range where the 13 queries of search_gate.py all answer, in the search box itself. 839 pages, every URL and 45,611 ids match the MkDocs build. The tests read the Starlight content and syntax.
This commit is contained in:
1 parent
abe240073c
commit
123d698e43
64 files changed
+742
-3118
No files matched your search
+24
-18
@@ -126,16 +126,18 @@ class StructuredBlocks(unittest.TestCase):
|
||||
page = self.render(self.profile("firmware_titles", [
|
||||
{"id": "0005001b-10042400", "name": "Shared fonts",
|
||||
"content": ["CafeCn.ttf", "CafeKr.ttf"]}]))
|
||||
self.assertIn(" - id: 0005001b-10042400, name: Shared fonts\n", page)
|
||||
self.assertIn(" - **content:**", page)
|
||||
self.assertIn(" - CafeKr.ttf", page)
|
||||
self.assertIn("\n- id: 0005001b-10042400, name: Shared fonts\n", page)
|
||||
self.assertIn("\n - **content:**", page)
|
||||
self.assertIn("\n - CafeKr.ttf", page)
|
||||
|
||||
def test_a_folded_note_stays_inside_its_block(self):
|
||||
page = self.render(self.profile("analysis", {"tmss": {
|
||||
"note": "The core points\nsystem/tmss_path at the system directory."}}))
|
||||
self.assertIn("- **note:** The core points system/tmss_path at the", page)
|
||||
body = page.split("\n")[1:]
|
||||
self.assertEqual([line for line in body if line and not line.startswith(" ")], [])
|
||||
# Nothing of the note is left after the block closes.
|
||||
lines = page.split("\n")
|
||||
end = lines.index("</details>")
|
||||
self.assertEqual([line for line in lines[end + 1:] if line.strip()], [])
|
||||
|
||||
def test_a_long_note_is_not_cut(self):
|
||||
note = "word " * 80 + "end."
|
||||
@@ -315,7 +317,7 @@ class TheSearchLandsOnTheCard(unittest.TestCase):
|
||||
self.assertEqual(len(headings), 11)
|
||||
self.assertTrue(headings[0].endswith("{ #system-00 }"))
|
||||
self.assertNotIn('<a id="system-00"></a>', lines)
|
||||
self.assertIn('??? note "1 file (OK)"', lines)
|
||||
self.assertIn("<summary>1 file (OK)</summary>", lines)
|
||||
|
||||
def test_an_emulator_card_is_a_heading_with_its_anchor(self):
|
||||
import generate_site
|
||||
@@ -323,8 +325,8 @@ class TheSearchLandsOnTheCard(unittest.TestCase):
|
||||
entry = {"name": "scph5501.bin", "required": True}
|
||||
lines = generate_site._render_emulator_file(
|
||||
entry, {"files": [entry]}, None, [entry], lambda f: True, "file-scph5501-bin")
|
||||
self.assertTrue(lines[2].startswith("### `scph5501.bin` "))
|
||||
self.assertTrue(lines[2].endswith("{ #file-scph5501-bin .rb-file-title }"))
|
||||
self.assertTrue(lines[2].startswith('<h3 id="file-scph5501-bin" class="rb-file-title"'))
|
||||
self.assertIn("<code>scph5501.bin</code>", lines[2])
|
||||
|
||||
def test_a_system_card_is_a_heading_with_its_anchor(self):
|
||||
import generate_site
|
||||
@@ -332,8 +334,8 @@ class TheSearchLandsOnTheCard(unittest.TestCase):
|
||||
|
||||
entry = {"name": "a.bin", "sha1": "a" * 40, "md5": "b" * 32, "size": 3}
|
||||
lines = generate_site._system_file_card(entry, FileConsumers({"files": {}}))
|
||||
self.assertTrue(lines[2].startswith("### `a.bin` "))
|
||||
self.assertTrue(lines[2].endswith("{ #sha1-aaaaaaaaaaaa .rb-file-title }"))
|
||||
self.assertTrue(lines[2].startswith('<h3 id="sha1-aaaaaaaaaaaa" class="rb-file-title"'))
|
||||
self.assertIn("<code>a.bin</code>", lines[2])
|
||||
|
||||
|
||||
class TheSearchSkipsLinkLists(unittest.TestCase):
|
||||
@@ -353,11 +355,14 @@ class TheSearchSkipsLinkLists(unittest.TestCase):
|
||||
consumers.emulators = {sha1: {"duckstation"}}
|
||||
entry = {"name": "a.bin", "sha1": sha1, "md5": "b" * 32, "size": 3}
|
||||
text = "\n".join(generate_site._system_file_card(entry, consumers))
|
||||
searched, skipped = text.split("<section data-search-exclude markdown>")
|
||||
self.assertIn("`a.bin`", searched)
|
||||
searched, _sep, skipped = text.partition("<section data-pagefind-ignore>")
|
||||
self.assertIn("<code>a.bin</code>", searched)
|
||||
self.assertNotIn("- MD5:", searched)
|
||||
for line in ("- MD5:", "- Emulators:", "- Platforms:", "- Also installed by:"):
|
||||
for line in ("- MD5:", "- Emulators:", "- Also installed by:"):
|
||||
self.assertIn(line, skipped)
|
||||
# The platforms line names the file as each setup does: the site
|
||||
# search reads it, so a file name finds its card.
|
||||
self.assertIn("- Platforms:", searched + skipped.split("</section>", 1)[1])
|
||||
|
||||
def test_a_game_data_card_skips_its_name_too(self):
|
||||
import generate_site
|
||||
@@ -366,7 +371,8 @@ class TheSearchSkipsLinkLists(unittest.TestCase):
|
||||
entry = {"name": "0.ogg", "sha1": "a" * 40, "size": 3}
|
||||
lines = generate_site._system_file_card(
|
||||
entry, FileConsumers({"files": {}}), searchable=False)
|
||||
self.assertTrue(lines[2].endswith("data-search-exclude }"))
|
||||
self.assertIn("data-pagefind-ignore", lines[2])
|
||||
self.assertNotIn("data-pagefind-weight", lines[2])
|
||||
|
||||
def test_runs_alternate_in_card_order(self):
|
||||
import generate_site
|
||||
@@ -377,10 +383,10 @@ class TheSearchSkipsLinkLists(unittest.TestCase):
|
||||
out = [line for line in generate_site._search_skipped_apart(lines) if line]
|
||||
self.assertEqual(out, [
|
||||
"- Path: `p`",
|
||||
'<div class="rb-search-skip" data-search-exclude markdown>',
|
||||
'<div class="rb-search-skip" data-pagefind-ignore>',
|
||||
"- SHA1: x", "- Source: `a.c:1`", "- Platforms: p", "</div>",
|
||||
"- Destination: `d`",
|
||||
'<div class="rb-search-skip" data-search-exclude markdown>',
|
||||
'<div class="rb-search-skip" data-pagefind-ignore>',
|
||||
"- Contents (1 members):", " - `m`", "</div>",
|
||||
"- Note",
|
||||
])
|
||||
@@ -391,8 +397,8 @@ class TheSearchSkipsLinkLists(unittest.TestCase):
|
||||
short = "| a |\n|---|\n| 1 |"
|
||||
long = " | a |\n |---|\n" + "\n".join(f" | {'x' * 50} |" for _ in range(80))
|
||||
text = generate_site.tables_out_of_search(f"# T\n\n{short}\n\n{long}\n")
|
||||
self.assertEqual(text.count("data-search-exclude"), 1)
|
||||
self.assertIn(" <section data-search-exclude markdown>\n\n | a |", text)
|
||||
self.assertEqual(text.count("data-pagefind-ignore"), 1)
|
||||
self.assertIn(" <section data-pagefind-ignore>\n\n | a |", text)
|
||||
self.assertIn(short, text)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user