From e14f9359945762a36471127340429e61a132bc7b Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 23 Oct 2026 19:06:08 +0200 Subject: [PATCH] feat: short code marks, lazy search, index fields Inline code of 30 characters or fewer is marked rb-short at build time and the options table rb-options. The search UI loads on first use. Title, crumbs and footer leave the search index, and consoles and terms weigh as a title. --- tests/test_site_r2_components.py | 2 +- website/astro.config.mjs | 15 +- website/src/components/Footer.astro | 8 +- website/src/components/MarkdownContent.astro | 7 + website/src/components/PageTitle.astro | 10 +- website/src/components/Search.astro | 498 +++++++++++++++++++ website/src/plugins/rehype-short-code.mjs | 94 ++++ 7 files changed, 625 insertions(+), 9 deletions(-) create mode 100644 website/src/components/Search.astro create mode 100644 website/src/plugins/rehype-short-code.mjs diff --git a/tests/test_site_r2_components.py b/tests/test_site_r2_components.py index 0d037a223..07cbbe093 100644 --- a/tests/test_site_r2_components.py +++ b/tests/test_site_r2_components.py @@ -52,7 +52,7 @@ class TablesStackWhenBuilt(unittest.TestCase): def test_the_plugin_is_registered_and_the_runtime_rule_is_gone(self): config = _read(CONFIG) self.assertIn("import stackTables from './src/plugins/rehype-stack-tables.mjs'", config) - self.assertIn("hastPlugins: [stackTables()]", config) + self.assertIn("hastPlugins: [stackTables(), ", config) self.assertNotIn("stackActionTable", _read(SITE_TS)) def test_setup_tables_carry_the_layout_in_the_html(self): diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 71fa2b654..4fd5748d1 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -13,6 +13,7 @@ import starlightLinksValidator from 'starlight-links-validator'; import sidebar from './src/generated/sidebar.json' with { type: 'json' }; import lastmod from './src/generated/lastmod.json' with { type: 'json' }; import stackTables from './src/plugins/rehype-stack-tables.mjs'; +import shortCode from './src/plugins/rehype-short-code.mjs'; import unbrokenTokens from './src/plugins/ec-unbroken-tokens.mjs'; const SITE = 'https://abdess.github.io'; @@ -52,7 +53,7 @@ export default defineConfig({ redirects: readRedirects(), markdown: { processor: satteri({ - hastPlugins: [stackTables()], + hastPlugins: [stackTables(), shortCode()], features: { headingAttributes: true, definitionList: true, @@ -81,6 +82,7 @@ export default defineConfig({ MarkdownContent: './src/components/MarkdownContent.astro', Footer: './src/components/Footer.astro', Header: './src/components/Header.astro', + Search: './src/components/Search.astro', }, routeMiddleware: ['./src/routeData.ts'], tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 3 }, @@ -109,15 +111,20 @@ export default defineConfig({ // every other query. Two fields name the page's subject in other words // and weigh half a title: `aliases`, the ids setups file a system under // (psx, dreamcast, gba), and `devices`, the handhelds and boxes a - // setup's own site names (R36S, Miyoo Mini). All three are attributes - // on an empty element, so no text of theirs reaches an excerpt. + // setup's own site names (R36S, Miyoo Mini). Two more weigh as much as + // a title, since each names what a reader types to reach the page: + // `consoles`, the consoles a manufacturer page holds (Neo Geo, + // WonderSwan Color), and `terms`, the words of a task or a message on + // screen (bios not found, mame version, check dump). All of them are + // attributes on an empty element, so no text of theirs reaches an + // excerpt. pagefind: { ranking: { pageLength: 0.1, termFrequency: 0.5, termSaturation: 1.4, termSimilarity: 9, - metaWeights: { title: 10, files: 0.5, aliases: 5, devices: 5 }, + metaWeights: { title: 10, files: 0.5, aliases: 5, devices: 5, consoles: 10, terms: 10 }, }, }, plugins: [ diff --git a/website/src/components/Footer.astro b/website/src/components/Footer.astro index e96db4d84..c70aae7ea 100644 --- a/website/src/components/Footer.astro +++ b/website/src/components/Footer.astro @@ -2,7 +2,9 @@ // Starlight's footer (edit link, previous and next), who keeps the project // and where to report a problem, the release the packs come from, and the // licence line. The release is read from release.json, written when the -// packs were published: the site may be newer than the packs. +// packs were published: the site may be newer than the packs. None of it +// is in the search index: "MIT for the tooling" was the excerpt of short +// pages, and "bios", "release" and "problem" matched every page. import Default from '@astrojs/starlight/components/Footer.astro'; import release from '../../../release.json'; @@ -19,6 +21,7 @@ const tag: string = release.tag; const date = releaseDate(tag); --- +
diff --git a/website/src/components/PageTitle.astro b/website/src/components/PageTitle.astro index 168949b33..b4795bb3a 100644 --- a/website/src/components/PageTitle.astro +++ b/website/src/components/PageTitle.astro @@ -7,6 +7,10 @@ // a dark mark stays visible in the dark theme. A setup page with no logo file // gets its initials in the same square, as its tile does (sitemarkup.py // platform_tiles). +// +// The crumbs and the title stay out of the search index: every excerpt +// began with the title and the crumbs matched "bios" on every page. The +// title still names the result, as the page's title field. import setups from '../../public/data/picker/index.json'; const PAGE_TITLE_ID = '_top'; @@ -46,7 +50,7 @@ const setup = !logoSrc && setups.find((entry) => id === `platforms/${entry.platf { crumbs.length > 0 && ( -