From 516736147367968b158c797ab1acd4003868f6f9 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 23 Oct 2026 02:42:11 +0200 Subject: [PATCH] feat: readable diagrams and wiki command tabs Diagram text reads at 14 px in the column, boxes take the height of their lines, paths are mono on a line of their own. One setup count for every page. Wiki pages expand install commands into system tabs, an options table read from install.py, and keep example hashes out of search. --- docs_assets/og/home.png | Bin 22442 -> 67092 bytes scripts/sitediagrams.py | 325 +++++++++++++++++++++++++++++++------- tests/test_site_images.py | 3 +- wiki/getting-started.md | 24 --- 4 files changed, 267 insertions(+), 85 deletions(-) delete mode 100644 wiki/getting-started.md diff --git a/docs_assets/og/home.png b/docs_assets/og/home.png index 3d2b7e17573b63dfd6b987f2ccad1083330f0f93..a10a74f97c12f19b2f3d6bab53c43aca498980b3 100644 GIT binary patch literal 67092 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[ PLACEHOLDER_ANYWHERE = re.compile(r"") FONT = "system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif" -TITLE_SIZE = 14 -TEXT_SIZE = 12.5 -LINE = 17 -PAD = 10 +# The stylesheet sets the page font on every , so a path takes the +# mono font from an inline style, which outranks it. +MONO_STYLE = "font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)" WIDE = 720 NARROW = 340 +# The wide drawing is scaled to a column about 700 px wide: these sizes read +# at 14 px of body text there, the size of the prose around the figure. +COLUMN = 700 +TEXT_SIZE = round(14 * WIDE / COLUMN, 1) +TITLE_SIZE = round(15 * WIDE / COLUMN, 1) +LINE = 20 +PAD = 12 +# A box holds a title and at most this many lines: the rest is the caption's. +MAX_BOX_LINES = 3 # Default colours for an SVG read outside the page. The stylesheet replaces # them on the site through the rb-d-* classes. @@ -58,13 +66,20 @@ ACCENT = "#3b3f7a" MUTED = "#546e7a" +class Mono(str): + """A path or a name typed as is: drawn in the mono font on a line of its + own, never broken.""" + + def _width(text: str, size: float, bold: bool = False) -> float: - """Rough advance of a sans-serif string: 0.56 em a character, 0.6 bold.""" - return len(text) * size * (0.6 if bold else 0.56) + """Rough advance of a string: 0.56 em a character, 0.6 bold or mono.""" + return len(text) * size * (0.6 if bold or isinstance(text, Mono) else 0.56) def wrap(text: str, width: float, size: float, bold: bool = False) -> list[str]: - """Greedy word wrap against the estimated advance.""" + """Greedy word wrap against the estimated advance. A Mono line stays whole.""" + if isinstance(text, Mono): + return [text] lines: list[str] = [] current = "" for word in text.split(): @@ -111,10 +126,11 @@ def _text(x: float, y: float, value: str, size: float = TEXT_SIZE, bold: bool = False, anchor: str = "start", cls: str = "") -> str: weight = ' font-weight="600"' if bold else "" klass = f' class="{cls}"' if cls else "" + style = f' style="{MONO_STYLE}"' if isinstance(value, Mono) else "" fill = MUTED if cls == "rb-d-muted" else ("#ffffff" if cls == "rb-d-numtext" else INK) return ( f'{escape(value)}' + f'text-anchor="{anchor}" fill="{fill}"{klass}{style}>{escape(value)}' ) @@ -167,13 +183,19 @@ def _line(points: list[tuple[float, float]], head: bool = True) -> list[str]: return out -def _box_height(box: Box, width: float) -> tuple[list[str], list[str], float]: +def box_lines(box: Box, width: float) -> tuple[list[str], list[str]]: + """The title and body lines of *box* drawn *width* wide, as wrapped.""" inner = width - 2 * PAD title_lines = wrap(box.title, inner - (_badge_side(box.number) + 8 if box.number else 0), TITLE_SIZE, True) body: list[str] = [] for line in box.lines: body.extend(wrap(line, inner, TEXT_SIZE)) + return title_lines, body + + +def _box_height(box: Box, width: float) -> tuple[list[str], list[str], float]: + title_lines, body = box_lines(box, width) height = PAD + len(title_lines) * LINE + (6 if body else 0) + len(body) * LINE + PAD if box.number: height = max(height, PAD * 2 + 20) @@ -187,7 +209,7 @@ def _draw_box(box: Box, x: float, y: float, width: float, height: float, if box.number: out.extend(_badge(x + PAD, y + PAD, box.number)) tx += _badge_side(box.number) + 8 - cy = y + PAD + 13 + cy = y + PAD + 15 for line in title_lines: out.append(_text(tx, cy, line, TITLE_SIZE, True)) cy += LINE @@ -216,9 +238,10 @@ def flow(boxes: list[Box], vertical: bool, total: float) -> tuple[float, float, width = (total - gap * (len(boxes) - 1) - 2) / len(boxes) measured = [_box_height(box, width) for box in boxes] height = max(m[2] for m in measured) - for index, (box, (title_lines, body, _)) in enumerate(zip(boxes, measured)): + for index, (box, (title_lines, body, own)) in enumerate(zip(boxes, measured)): x = 1 + index * (width + gap) - out.extend(_draw_box(box, x, 1, width, height, title_lines, body)) + # A box is as tall as its lines, centred on the row the arrows run along. + out.extend(_draw_box(box, x, 1 + (height - own) / 2, width, own, title_lines, body)) if index < len(boxes) - 1: mid = 1 + height / 2 out.extend(_line([(x + width, mid), (x + width + gap - 1, mid)])) @@ -239,8 +262,8 @@ def columns(boxes: list[Box], vertical: bool, total: float) -> tuple[float, floa width = (total - gap * (len(boxes) - 1) - 2) / len(boxes) measured = [_box_height(box, width) for box in boxes] height = max(m[2] for m in measured) - for index, (box, (title_lines, body, _)) in enumerate(zip(boxes, measured)): - out.extend(_draw_box(box, 1 + index * (width + gap), 1, width, height, title_lines, body)) + for index, (box, (title_lines, body, own)) in enumerate(zip(boxes, measured)): + out.extend(_draw_box(box, 1 + index * (width + gap), 1, width, own, title_lines, body)) return total, height + 2, out @@ -296,13 +319,28 @@ def registry() -> dict: return yaml.safe_load(handle).get("platforms", {}) +@lru_cache(maxsize=None) +def setups() -> tuple[str, ...]: + """The registered setups, archived ones included: each has its own page, + pack and file list, so every count of setups on the site is this one.""" + from common import list_registered_platforms + + return tuple(sorted(list_registered_platforms(str(ROOT / "platforms"), include_archived=True))) + + +def setups_named(named: list[str]) -> str: + """*named*, then how many other setups there are: "A, B and 15 more".""" + others = len(setups()) - len(named) + return ", ".join(named) + (f" and {others} more" if others else "") + + @lru_cache(maxsize=None) def platform_modes() -> dict[str, tuple[str, str, str | None]]: """name -> (display name, verification mode, hash rule) for every platform.""" - from common import list_registered_platforms, load_platform_config + from common import load_platform_config out: dict[str, tuple[str, str, str | None]] = {} - for name in sorted(list_registered_platforms(str(ROOT / "platforms"), include_archived=True)): + for name in setups(): config = load_platform_config(name, str(ROOT / "platforms")) rule = registry().get(name, {}).get("hash_rule") or config.get("hash_rule") out[name] = (config.get("platform", name), config.get("verification_mode", ""), rule) @@ -335,64 +373,70 @@ def emulator_names() -> dict[str, str]: def _bios_chain_boxes() -> list[Box]: - active = sum(1 for entry in registry().values() if entry.get("status") == "active") - frontends = [_display(platform) for platform, _ in CHAIN_EXAMPLES] - emulators = [emulator_names()[emulator] for _, emulator in CHAIN_EXAMPLES] - folders = [f"{_display(platform)}: {_folder(platform)}" for platform, _ in CHAIN_EXAMPLES] + platform, _emulator = CHAIN_EXAMPLES[0] return [ Box("Your device", ["A PC, a Steam Deck, a handheld or a TV box"], number="1"), - Box("Frontend", [ - "The menu you pick a game from:", - f"{', '.join(frontends)} and {active - len(frontends)} more", - ], number="2"), - Box("Emulator", [ - "Starts the game and reads its BIOS:", - ", ".join(emulators), - ], number="3"), - Box("BIOS folder", folders + ["The pack or the installer fills it"], + Box("Setup", ["The menu you pick a game from"], number="2"), + Box("Emulator", ["Starts the game and reads its BIOS"], number="3"), + Box("BIOS folder", [f"{_display(platform)} reads", Mono(_folder(platform))], accent=True, number="4"), ] +def _bios_chain_caption() -> str: + """The examples the boxes leave out, read from the registry and profiles.""" + named = setups_named([_display(platform) for platform, _ in CHAIN_EXAMPLES]) + pairs = ", ".join( + f"{_display(platform)} starts {emulator_names()[emulator]}" + for platform, emulator in CHAIN_EXAMPLES + ) + folders = ", ".join(f"{_display(platform)} {_folder(platform)}" for platform, _ in CHAIN_EXAMPLES) + return ( + f"Setups: {named}. Examples: {pairs}. " + f"BIOS folders: {folders}. The ZIP or the command fills that folder." + ) + + def _install_boxes() -> list[Box]: - detected = sum(1 for entry in registry().values() if entry.get("install", {}).get("detect")) return [ - Box("Run one command", ["The same line on Linux, macOS, Windows and handhelds"], number="1"), - Box("Find the setup", [f"Looks for {detected} frontends and their BIOS folders"], number="2"), - Box("Read the folder", ["Hashes the files already there"], number="3"), - Box("Download the rest", ["Only what is missing or different"], number="4"), - Box("Check each file", ["Its SHA-1 must match before it is saved"], accent=True, number="5"), + Box("Finds your setup", ["And the folder it reads"], number="1"), + Box("Looks at your files", ["The ones already in the folder"], number="2"), + Box("Downloads the rest", ["Only what is missing or different"], number="3"), + Box("Checks each file", ["Before saving it"], accent=True, number="4"), ] MODE_TEXT = { - "existence": ("Name only", "Only the file's name and place count. Its content is not read."), + "existence": ("Name only", "Only the name and place count."), "md5": ("MD5 fingerprint", "The content must match an MD5 the platform lists."), "sha1": ("SHA-1 fingerprint", "The content must match a SHA-1 the platform lists."), } -def _mode_boxes() -> list[Box]: +def _modes() -> dict[str, list[str]]: + """Mode -> the platforms checking that way, RomM's size rule named.""" by_mode: dict[str, list[str]] = {mode: [] for mode in MODE_TEXT} for display, mode, rule in platform_modes().values(): label = f"{display} (size, then any hash)" if rule == "size_and_any_hash" else display by_mode.setdefault(mode, []).append(label) + return {mode: sorted(names, key=str.casefold) for mode, names in by_mode.items()} + + +def _mode_boxes() -> list[Box]: + """Each way of checking and how many platforms use it. The names are in + the caption: eleven of them do not fit in three lines of a box.""" boxes = [] for mode, (title, text) in MODE_TEXT.items(): - names = sorted(by_mode.get(mode, []), key=str.casefold) - count = f"{len(names)} platform" + ("" if len(names) == 1 else "s") - boxes.append(Box(title, [text, f"{count}: " + ", ".join(names)])) + count = len(_modes().get(mode, [])) + boxes.append(Box(title, [text, f"{count} platform" + ("" if count == 1 else "s")])) return boxes def _mode_summary() -> str: - parts = [] - for mode, (title, _) in MODE_TEXT.items(): - names = sorted( - (display for display, m, _ in platform_modes().values() if m == mode), key=str.casefold - ) - parts.append(f"{title}: {', '.join(names)}.") - return " ".join(parts) + return " ".join( + f"{title}: {', '.join(_modes().get(mode, []))}." + for mode, (title, _) in MODE_TEXT.items() + ) # MinUI names a BIOS folder after the tag in parentheses of the ROM folder. @@ -529,21 +573,20 @@ def _figures() -> dict[str, Figure]: "bios-chain": Figure( "bios-chain", "How a BIOS file is used", - "A device runs a frontend, the frontend starts an emulator, and the emulator " - "reads BIOS files from one folder. The pack or the installer fills that folder.", - "The frontend is the menu, the emulator runs the game, and the BIOS folder is the " - "one place both look. Filling that folder is all a pack does.", + "A device runs a setup, the setup starts an emulator, and the emulator " + "reads BIOS files from one folder. The ZIP or the command fills that folder.", + _bios_chain_caption(), lambda: flow(chain(), False, WIDE), lambda: flow(chain(), True, NARROW), ), "install-flow": Figure( "install-flow", - "What the installer does", - "Install flow: run the command, the installer finds your setup, reads the BIOS " - "folder, downloads what is missing or different, then checks each file before " + "What the command does", + "The command finds your setup and its BIOS folder, looks at the files already " + "there, downloads what is missing or different, then checks each file before " "saving it.", "Running the command again repeats the same steps and downloads only what changed.", - lambda: flow(install(), False, WIDE), + lambda: grid(install(), 2, WIDE), lambda: flow(install(), True, NARROW), ), "verification-modes": Figure( @@ -551,7 +594,7 @@ def _figures() -> dict[str, Figure]: "How each platform checks a file", "Three ways platforms check a BIOS file. " + _mode_summary(), "Each platform's own check, read from its source code. A file that passes on one " - "platform can be refused on another.", + "platform can be refused on another. " + _mode_summary(), lambda: columns(_mode_boxes(), False, WIDE), lambda: columns(_mode_boxes(), True, NARROW), ), @@ -689,9 +732,174 @@ def localize_images(markdown: str, page: Path) -> str: return IMG_SRC.sub(swap, IMAGE_LINK.sub(swap, markdown)) +# Installer commands on wiki pages. The page keeps the Linux line, readable +# where the Markdown is read as is, and the site shows it in one tab per +# system, the Windows form written by the same function as the setup pages'. + +OS_TABS = re.compile( + r"(?m)^(?P[ \t]*)[ \t]*\n" + r"(?P=indent)```(?:sh|bash)[^\n]*\n(?P.*?)\n(?P=indent)```[ \t]*$", + re.S, +) +OS_TAB_KEYS = ("windows", "macos", "linux", "steamdeck") +FENCE_TITLES = {"sh": "Terminal", "powershell": "PowerShell"} + + +def _installer_args(body: str) -> str: + """The options of a one-line install command, continuation lines joined.""" + from siteguides import INSTALL_BASE + + line = " ".join(part.strip().rstrip("\\").strip() for part in body.splitlines()) + match = re.fullmatch(rf"curl -fsSL {re.escape(INSTALL_BASE)}/install\.sh \| sh(?: -s -- (.+))?", line) + if not match: + raise ValueError(f"an os-tabs block holds no install command: {line!r}") + return match.group(1) or "" + + +def expand_commands(markdown: str) -> str: + """Each install command marked `` as Windows, macOS, + Linux and Steam Deck tabs. `` gives the + Windows tab its own options, for a path written another way there.""" + if "os-tabs" not in markdown: + return markdown + from siteguides import TERMINALS, install_command + + def replace(match: re.Match[str]) -> str: + indent = match.group("indent") + args = _installer_args(match.group("body")) + items = [] + for key in OS_TAB_KEYS: + label, _how, shell = TERMINALS[key] + own = match.group("windows") if key == "windows" and match.group("windows") else args + items.append((label, [f'```{shell} title="{FENCE_TITLES[shell]}"', + install_command(shell, own), "```"])) + return "\n".join(markup.tabs(items, indent)).rstrip("\n") + + return OS_TABS.sub(replace, markdown) + + +# The installer's options at a glance, read from its argument parser. + +OPTIONS_MARKER = re.compile(r"(?m)^[ \t]*$") +_SEE_LINK = re.compile(r"\(#([a-z0-9-]+)\)") + + +def _string(node: ast.expr, constants: dict[str, str]) -> str: + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value + if isinstance(node, ast.JoinedStr): + parts = [] + for value in node.values: + if isinstance(value, ast.FormattedValue) and isinstance(value.value, ast.Name): + parts.append(constants[value.value.id]) + else: + parts.append(_string(value, constants)) + return "".join(parts) + raise ValueError(f"install.py: an option help that is not a string: {ast.unparse(node)}") + + +@lru_cache(maxsize=None) +def installer_options() -> tuple[tuple[str, str], ...]: + """(usage, help) for each option of install.py, in the order --help lists them.""" + tree = ast.parse((ROOT / "install.py").read_text(encoding="utf-8")) + constants = { + node.targets[0].id: node.value.value + for node in tree.body + if isinstance(node, ast.Assign) and isinstance(node.targets[0], ast.Name) + and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str) + } + main = next(node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == "main") + options = [] + for node in ast.walk(main): + if not (isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) + and node.func.attr == "add_argument"): + continue + flags = [arg.value for arg in node.args if isinstance(arg, ast.Constant)] + keywords = {kw.arg: kw.value for kw in node.keywords} + action = keywords.get("action") + takes_value = not (isinstance(action, ast.Constant) + and action.value in ("store_true", "store_false", "version")) + metavar = "" + if takes_value: + given = keywords.get("metavar") + metavar = given.value if isinstance(given, ast.Constant) else flags[0].lstrip("-").upper() + usage = ", ".join(f"{flag} {metavar}".strip() for flag in flags) + options.append((usage, _string(keywords["help"], constants) if "help" in keywords else "")) + # argparse's own, added to every parser. + options.append(("--help, -h", "show this help message and exit")) + return tuple(options) + + +def _sentences(text: str) -> str: + """A help string as sentences: capitalised, clauses split, a full stop.""" + parts = [part.strip() for part in text.split("; ")] + text = ". ".join(part[0].upper() + part[1:] for part in parts if part) + text = re.sub(r"(? list[str]: + """One row per option: what it does, and the section that says more, + the one the option's row in the page's own Options table sends to.""" + sections: dict[str, str] = {} + for line in markdown.splitlines(): + flag = re.match(r"\| `(--[a-z-]+)", line) + see = _SEE_LINK.search(line) + if flag and see: + sections[flag.group(1)] = see.group(1) + headings = { + re.sub(r"[^a-z0-9 -]", "", title.lower()).strip().replace(" ", "-"): title + for title in re.findall(r"(?m)^##+ (.+?)(?:\s*\{[^}]*\})?\s*$", markdown) + } + rows = ["| Option | What it does | More |", "|---|---|---|"] + for usage, help_text in installer_options(): + anchor = sections.get(usage.split()[0].rstrip(",")) + more = f"[{headings.get(anchor, anchor)}](#{anchor})" if anchor else "" + rows.append(f"| `{usage}` | {_sentences(help_text)} | {more} |") + return rows + + +def expand_options(markdown: str) -> str: + if "installer-options" not in markdown: + return markdown + return OPTIONS_MARKER.sub(lambda _m: "\n".join(options_table(markdown)), markdown) + + +# Example hashes in the documentation stay out of search, so a hash typed in +# the search box finds the file card that holds it, not a page quoting it. + +HASH_SPAN = re.compile(r"`[^`\n]*\b(?:[0-9a-f]{64}|[0-9a-f]{40}|[0-9a-f]{32})\b[^`\n]*`") +HASH_TEXT = re.compile(r"\b(?:[0-9a-f]{64}|[0-9a-f]{40}|[0-9a-f]{32})\b") +FENCE = re.compile(r"(?m)^(?P[ \t]*)(?P```|~~~)[^\n]*\n.*?\n(?P=indent)(?P=mark)[ \t]*$", re.S) + + +def hide_hashes(markdown: str) -> str: + """Wrap each code block and code span quoting a hash in a search exclusion.""" + if not HASH_TEXT.search(markdown): + return markdown + attribute = markup.search_exclude() + pieces: list[str] = [] + position = 0 + for match in FENCE.finditer(markdown): + pieces.append(HASH_SPAN.sub(lambda m: f"{m.group(0)}", + markdown[position:match.start()])) + block = match.group(0) + if HASH_TEXT.search(block): + indent = match.group("indent") + block = f"{indent}
\n\n{block}\n\n{indent}
" + pieces.append(block) + position = match.end() + pieces.append(HASH_SPAN.sub(lambda m: f"{m.group(0)}", + markdown[position:])) + return "".join(pieces) + + def prepare_page(markdown: str, page: Path) -> str: """Everything this module does to a page before it is decorated.""" - return resolve_images(localize_images(markdown, page)) + markdown = expand_options(expand_commands(resolve_images(localize_images(markdown, page)))) + if page.parts[:1] == ("wiki",): + markdown = hide_hashes(markdown) + return markdown # Sharing cards: one 1200x630 card per section of the site, rendered to PNG @@ -711,8 +919,7 @@ def og_card_svg(section: str, logo_png: bytes) -> str: import base64 title, tagline = OG_SECTIONS[section] - active = sum(1 for entry in registry().values() if entry.get("status") == "active") - tagline = tagline.format(frontends=f"RetroArch, Batocera, EmuDeck and {active - 3} more") + tagline = tagline.format(frontends=setups_named(["RetroArch", "Batocera", "EmuDeck"])) logo = base64.b64encode(logo_png).decode("ascii") body = [ '', diff --git a/tests/test_site_images.py b/tests/test_site_images.py index 2084bc56..969550cc 100644 --- a/tests/test_site_images.py +++ b/tests/test_site_images.py @@ -96,8 +96,7 @@ class PlaceholdersResolve(unittest.TestCase): class DiagramsMatchTheData(unittest.TestCase): def test_every_platform_appears_under_its_mode(self): - boxes = sitediagrams._mode_boxes() - text = " ".join(" ".join(box.lines) for box in boxes) + text = sitediagrams.figures()["verification-modes"].caption for display, mode, _ in sitediagrams.platform_modes().values(): with self.subTest(platform=display): self.assertIn(mode, sitediagrams.MODE_TEXT) diff --git a/wiki/getting-started.md b/wiki/getting-started.md deleted file mode 100644 index ec50eee6..00000000 --- a/wiki/getting-started.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -level: start -nav: false ---- - -# Getting started - -Three pages take you from nothing to games that start. - -
Get your files - -## What is a BIOS? - -[What is a BIOS?](what-are-bios-files.md) tells you which consoles need one. - -## Install - -[Get your files](../which-pack.md) gives the command and the ZIP for your -setup. [First install, step by step](first-install.md) shows each step. - -## Check your folder - -[When a game does not start](troubleshooting.md#checking-what-you-installed) -shows how to check your BIOS folder.