summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiDeoo2024-09-04 23:36:35 +0200
committerGitHub2024-09-04 23:36:35 +0200
commit5062d30c08f6ede9e6c39174537bb61280e7c23d (patch)
tree3ae3b892fcf0bb292ec337a7238428c508c84c0a
parent4ba0010b4b5a82d202c1d6e161374eaf15068ac7 (diff)
downloadIT.starlight-5062d30c08f6ede9e6c39174537bb61280e7c23d.tar.gz
IT.starlight-5062d30c08f6ede9e6c39174537bb61280e7c23d.tar.bz2
IT.starlight-5062d30c08f6ede9e6c39174537bb61280e7c23d.zip
Ensure unhandled directives are restored without any extra whitespace (#2281)
-rw-r--r--.changeset/ninety-spies-count.md5
-rw-r--r--packages/starlight/__tests__/remark-rehype/asides.test.ts19
-rw-r--r--packages/starlight/integrations/asides.ts18
3 files changed, 30 insertions, 12 deletions
diff --git a/.changeset/ninety-spies-count.md b/.changeset/ninety-spies-count.md
new file mode 100644
index 00000000..da37022f
--- /dev/null
+++ b/.changeset/ninety-spies-count.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/starlight': patch
+---
+
+Fixes a potential text rendering issue that could include extra whitespaces for text containing colons.
diff --git a/packages/starlight/__tests__/remark-rehype/asides.test.ts b/packages/starlight/__tests__/remark-rehype/asides.test.ts
index 327766e4..88110f68 100644
--- a/packages/starlight/__tests__/remark-rehype/asides.test.ts
+++ b/packages/starlight/__tests__/remark-rehype/asides.test.ts
@@ -217,20 +217,25 @@ test('transforms back unhandled text directives', async () => {
`This is a:test of a sentence with a text:name[content]{key=val} directive.`
);
expect(res.code).toMatchInlineSnapshot(`
- "<p>This is a:test
- of a sentence with a text:name[content]{key="val"}
- directive.</p>"
+ "<p>This is a:test of a sentence with a text:name[content]{key="val"} directive.</p>"
`);
});
test('transforms back unhandled leaf directives', async () => {
const res = await processor.render(`::video[Title]{v=xxxxxxxxxxx}`);
expect(res.code).toMatchInlineSnapshot(`
- "<p>::video[Title]{v="xxxxxxxxxxx"}
- </p>"
+ "<p>::video[Title]{v="xxxxxxxxxxx"}</p>"
`);
});
+test('does not add any whitespace character after any unhandled directive', async () => {
+ const res = await processor.render(`## Environment variables (astro:env)`);
+ expect(res.code).toMatchInlineSnapshot(
+ `"<h2 id="environment-variables-astroenv">Environment variables (astro:env)</h2>"`
+ );
+ expect(res.code).not.toMatch(/\n/);
+});
+
test('lets remark plugin injected by Starlight plugins handle text and leaf directives', async () => {
const processor = await createMarkdownProcessor({
remarkPlugins: [
@@ -262,8 +267,6 @@ test('lets remark plugin injected by Starlight plugins handle text and leaf dire
`This is a:test of a sentence with a :abbr[SL]{name="Starlight"} directive handled by another remark plugin and some other text:name[content]{key=val} directives not handled by any plugin.`
);
expect(res.code).toMatchInlineSnapshot(`
- "<p>This is a:test
- of a sentence with a TEXT FROM REMARK PLUGIN directive handled by another remark plugin and some other text:name[content]{key="val"}
- directives not handled by any plugin.</p>"
+ "<p>This is a:test of a sentence with a TEXT FROM REMARK PLUGIN directive handled by another remark plugin and some other text:name[content]{key="val"} directives not handled by any plugin.</p>"
`);
});
diff --git a/packages/starlight/integrations/asides.ts b/packages/starlight/integrations/asides.ts
index f98cc090..d98e6a40 100644
--- a/packages/starlight/integrations/asides.ts
+++ b/packages/starlight/integrations/asides.ts
@@ -64,10 +64,20 @@ function transformUnhandledDirective(
index: number,
parent: Parent
) {
- const textNode = {
- type: 'text',
- value: toMarkdown(node, { extensions: [directiveToMarkdown()] }),
- } as const;
+ let markdown = toMarkdown(node, { extensions: [directiveToMarkdown()] });
+ /**
+ * `mdast-util-to-markdown` assumes that the tree represents a complete document (as it's an AST
+ * and not a CST) and to follow the POSIX definition of a line (a sequence of zero or more
+ * non- <newline> characters plus a terminating <newline> character), a newline is automatically
+ * added at the end of the output so that the output is a valid file.
+ * In this specific case, we can safely remove the newline character at the end of the output
+ * before replacing the directive with its value.
+ *
+ * @see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
+ * @see https://github.com/syntax-tree/mdast-util-to-markdown/blob/fd6a508cc619b862f75b762dcf876c6b8315d330/lib/index.js#L79-L85
+ */
+ if (markdown.at(-1) === '\n') markdown = markdown.slice(0, -1);
+ const textNode = { type: 'text', value: markdown } as const;
if (node.type === 'textDirective') {
parent.children[index] = textNode;
} else {