diff --git a/docs/src/content/docs/reference/plugin-compatibility.mdx b/docs/src/content/docs/reference/plugin-compatibility.mdx index 4104ca6..de1f11c 100644 --- a/docs/src/content/docs/reference/plugin-compatibility.mdx +++ b/docs/src/content/docs/reference/plugin-compatibility.mdx @@ -61,7 +61,7 @@ starlightLlmsTxt({ }), ``` -The code in `llms-full.txt` is then the code that the copy button copies. Placeholder fields keep their text. Annotations, callouts and footnote badges go. Notes that show under a block, such as the list of footnotes, stay. +The code in `llms-full.txt` is then the code that the copy button copies. Placeholder fields keep their text. Annotations, callouts and footnote badges go. Notes that show under a block, such as the list of footnotes, stay as a plain numbered list. Pagefind needs no set-up. It does not index these elements, because each one has `data-pagefind-ignore`. diff --git a/packages/starlight-codeblocks/src/expressive-code/core.ts b/packages/starlight-codeblocks/src/expressive-code/core.ts index 676b6b9..0efe439 100644 --- a/packages/starlight-codeblocks/src/expressive-code/core.ts +++ b/packages/starlight-codeblocks/src/expressive-code/core.ts @@ -68,7 +68,9 @@ const decorations = [ 'state-label', 'annotation', 'annotation-popover', + 'annotation-note-num', 'footnote-badge', + 'footnote-num', 'callout', 'hidden-marker', 'expandable-bar', diff --git a/packages/starlight-codeblocks/test/decorations.test.ts b/packages/starlight-codeblocks/test/decorations.test.ts index 2bc3350..052e198 100644 --- a/packages/starlight-codeblocks/test/decorations.test.ts +++ b/packages/starlight-codeblocks/test/decorations.test.ts @@ -12,20 +12,18 @@ const blocks = [ block('sh placeholder="TOKEN"', 'curl -H "Bearer TOKEN"'), ]; -/** The text of each rendered line without the marked decorations, as a tool that drops `.scb-deco` reads it. */ -function codeText(html: string) { +/** The text of each element that matches `selector` without the marked decorations, as a tool that drops `.scb-deco` reads it. */ +function textOf(html: string, selector: string) { const root = fromHtml(html, { fragment: true }); for (const element of selectAll('.scb-deco, input', root)) element.children = []; const text = (node: { type: string; value?: string; children?: unknown[] }): string => node.type === 'text' ? (node.value ?? '') : (node.children ?? []).map((c) => text(c as never)).join(''); - return selectAll('.ec-line', root) - .map((line) => text(line)) - .join('\n'); + return selectAll(selector, root).map((element) => text(element)); } test.each(blocks)('drops every decoration and keeps the code text: %s', async (markdown) => { const { rawHtml, copyText } = await render(markdown); - expect(codeText(rawHtml)).toBe(copyText); + expect(textOf(rawHtml, '.ec-line').join('\n')).toBe(copyText); }); test('marks each decoration for Pagefind too, and leaves the code unmarked', async () => { @@ -36,3 +34,11 @@ test('marks each decoration for Pagefind too, and leaves the code unmarked', asy expect(marked.every((element) => element.properties.dataPagefindIgnore === '')).toBe(true); expect(selectAll('.ec-line, .code', root).some((element) => matches('.scb-deco', element))).toBe(false); }); + +test.each([ + [block('py', '# [!ref] Needs uv.', 'run()'), '.scb-footnotes li', 'Needs uv.'], + [block('py annotations="side"', 'run() # [!annotate] Runs it.'), '.scb-annotation-notes li', 'Runs it.'], +])('drops the numbers that repeat the list numbers under the code: %s', async (markdown, item, note) => { + const { rawHtml } = await render(markdown); + expect(textOf(rawHtml, item)).toEqual([note]); +});