feat: share cards for manufacturer pages

One card per systems page, titled with the manufacturer and listing its consoles as far as three lines hold. Rendered once and committed like the platform cards.
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 10:56:33 +02:00
1 parent 3d0b013588
commit cdffbcdfe4
92 files changed
+65 -14

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+65 -14
View File
@@ -5,14 +5,16 @@ Each card is an SVG written by ``sitediagrams.og_card_svg`` from the
registry, rasterised by a headless Chromium through Playwright, then
committed under ``docs_assets/og/``. The site build copies the PNG files and
never runs this script, so it adds nothing to the build's dependencies.
Run it again when a section's wording, the platform count or the list of
platforms changes.
Run it again when a section's wording, the platform count, the list of
platforms or the consoles of a manufacturer change.
python scripts/make_og_cards.py
python scripts/make_og_cards.py --only platforms
python scripts/make_og_cards.py --only systems
A platform page shares a card with its own name (``og/platforms/<id>.png``),
the other pages their section's.
a manufacturer's systems page one with the manufacturer's name and its
consoles (``og/systems/<slug>.png``), the other pages their section's.
"""
from __future__ import annotations
@@ -25,27 +27,73 @@ ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "scripts"))
from common import list_registered_platforms, load_platform_config # noqa: E402
from sitediagrams import OG_SECTIONS, og_card_svg # noqa: E402
from sitediagrams import OG_SECTIONS, og_card_svg, wrap # noqa: E402
OUT = ROOT / "docs_assets" / "og"
LOGO = ROOT / ".github" / "assets" / "logo.png"
PLATFORM_TAGLINE = "Which BIOS files it needs, and where each one goes"
# The tagline's box on the card: og_card_svg wraps it at this width and
# size, and three lines fit above the address.
TAGLINE_WIDTH, TAGLINE_SIZE, TAGLINE_LINES = 1000, 34, 3
def platform_cards() -> dict[str, str]:
def platform_cards() -> dict[str, tuple[str, str]]:
"""Each platform page's card, by its path under og/, with its title."""
platforms = ROOT / "platforms"
return {
f"platforms/{name}": load_platform_config(name, str(platforms))["platform"]
f"platforms/{name}": (load_platform_config(name, str(platforms))["platform"],
PLATFORM_TAGLINE)
for name in list_registered_platforms(str(platforms), include_archived=True)
}
def card_svg(key: str, logo: bytes, titles: dict[str, str]) -> str:
def consoles_tagline(consoles: list[str], lead: str = "BIOS files for") -> str:
""""BIOS files for PlayStation, PlayStation 2 and 5 more": as many
names as the card's three lines hold, the rest counted."""
names = sorted(consoles, key=str.casefold)
for shown in range(len(names), 0, -1):
rest = len(names) - shown
listed = names[:shown]
if rest:
text = f"{lead} {', '.join(listed)} and {rest} more"
elif len(listed) > 1:
text = f"{lead} {', '.join(listed[:-1])} and {listed[-1]}"
else:
text = f"{lead} {listed[0]}"
if len(wrap(text, TAGLINE_WIDTH, TAGLINE_SIZE)) <= TAGLINE_LINES:
return text
return f"{lead} {len(names)} sections"
def system_cards() -> dict[str, tuple[str, str]]:
"""Each manufacturer page's card under og/systems/, titled with the
manufacturer and listing its consoles. Read from the same grouping the
system pages are written from."""
from common import GAME_DATA_TOPS, load_database
from generate_site import _group_by_manufacturer, _slug
def lead(manufacturer: str) -> str:
# Other holds one folder per emulator, a game publisher's page its
# games' data: neither is a list of consoles.
if manufacturer in GAME_DATA_TOPS:
return "Game data for"
return "Files kept for the emulators" if manufacturer == "Other" else "BIOS files for"
manufacturers = _group_by_manufacturer(load_database(str(ROOT / "database.json")))
return {
f"systems/{_slug(manufacturer)}": (
manufacturer, consoles_tagline(list(consoles), lead(manufacturer)))
for manufacturer, consoles in sorted(manufacturers.items())
}
def card_svg(key: str, logo: bytes, titles: dict[str, tuple[str, str]]) -> str:
if key in OG_SECTIONS:
return og_card_svg(key, logo)
# A platform card is a section card with the platform's name for title.
OG_SECTIONS[key] = (titles[key], PLATFORM_TAGLINE)
# A page card is a section card with the page's own title and tagline.
# The tagline is a format string there: braces in a name stay text.
title, tagline = titles[key]
OG_SECTIONS[key] = (title, tagline.replace("{", "{{").replace("}", "}}"))
try:
return og_card_svg(key, logo)
finally:
@@ -55,16 +103,19 @@ def card_svg(key: str, logo: bytes, titles: dict[str, str]) -> str:
def main() -> None:
parser = argparse.ArgumentParser(description="Render the sharing cards to PNG.",
allow_abbrev=False)
parser.add_argument("--only", choices=("sections", "platforms"),
help="render one kind of card (default: both)")
parser.add_argument("--only", choices=("sections", "platforms", "systems"),
help="render one kind of card (default: all)")
args = parser.parse_args()
try:
from playwright.sync_api import sync_playwright
except ImportError as exc:
raise SystemExit("Playwright with Chromium is needed: pip install playwright") from exc
titles = platform_cards()
keys = [*([] if args.only == "platforms" else OG_SECTIONS),
*([] if args.only == "sections" else titles)]
titles: dict[str, tuple[str, str]] = {}
if args.only in (None, "platforms"):
titles.update(platform_cards())
if args.only in (None, "systems"):
titles.update(system_cards())
keys = [*(OG_SECTIONS if args.only in (None, "sections") else []), *titles]
logo = LOGO.read_bytes()
with sync_playwright() as playwright:
browser = playwright.chromium.launch()