Skip to content

Commit ada51ee

Browse files
essential-randomnessdelucisEssential Randomness
authored
Allow asides titles to contain markdown formatting (#2126)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Essential Randomness <essential.randomn3ss@gmail.com>
1 parent 0f09ace commit ada51ee

5 files changed

Lines changed: 50 additions & 7 deletions

File tree

.changeset/mean-tigers-hunt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@astrojs/starlight': patch
3+
---
4+
5+
Adds support for markdown formatting in aside titles

packages/starlight/__tests__/remark-rehype/asides.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,39 @@ Some text
7070
});
7171
});
7272

73+
describe('custom labels with nested markdown', () => {
74+
test.each(['note', 'tip', 'caution', 'danger'])('%s with custom code label', async (type) => {
75+
const label = 'Custom `code` Label';
76+
const labelWithoutMarkdown = 'Custom code Label';
77+
const labelHtml = 'Custom <code>code</code> Label';
78+
const res = await processor.render(`
79+
:::${type}[${label}]
80+
Some text
81+
:::
82+
`);
83+
expect(res.code).includes(`aria-label="${labelWithoutMarkdown}"`);
84+
expect(res.code).includes(`</svg>${labelHtml}</p>`);
85+
});
86+
});
87+
88+
describe('custom labels with doubly-nested markdown', () => {
89+
test.each(['note', 'tip', 'caution', 'danger'])(
90+
'%s with custom doubly-nested label',
91+
async (type) => {
92+
const label = 'Custom **strong with _emphasis_** Label';
93+
const labelWithoutMarkdown = 'Custom strong with emphasis Label';
94+
const labelHtml = 'Custom <strong>strong with <em>emphasis</em></strong> Label';
95+
const res = await processor.render(`
96+
:::${type}[${label}]
97+
Some text
98+
:::
99+
`);
100+
expect(res.code).includes(`aria-label="${labelWithoutMarkdown}"`);
101+
expect(res.code).includes(`</svg>${labelHtml}</p>`);
102+
}
103+
);
104+
});
105+
73106
test('ignores unknown directive variants', async () => {
74107
const res = await processor.render(`
75108
:::unknown

packages/starlight/integrations/asides.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import type { AstroConfig, AstroIntegration, AstroUserConfig } from 'astro';
44
import { h as _h, s as _s, type Properties } from 'hastscript';
5-
import type { Node, Paragraph as P, Parent, Root } from 'mdast';
5+
import type { Node, Paragraph as P, Parent, PhrasingContent, Root } from 'mdast';
66
import {
77
type Directives,
88
directiveToMarkdown,
99
type TextDirective,
1010
type LeafDirective,
1111
} from 'mdast-util-directive';
1212
import { toMarkdown } from 'mdast-util-to-markdown';
13+
import { toString } from 'mdast-util-to-string';
1314
import remarkDirective from 'remark-directive';
1415
import type { Plugin, Transformer } from 'unified';
1516
import { visit } from 'unist-util-visit';
@@ -156,16 +157,16 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
156157
// prop to <Aside>, so when we find a directive label, we store it for the title prop and
157158
// remove the paragraph from the container’s children.
158159
let title = t(`aside.${variant}`);
160+
let titleNode: PhrasingContent[] = [{ type: 'text', value: title }];
159161
const firstChild = node.children[0];
160162
if (
161163
firstChild?.type === 'paragraph' &&
162164
firstChild.data &&
163-
'directiveLabel' in firstChild.data
165+
'directiveLabel' in firstChild.data &&
166+
firstChild.children.length > 0
164167
) {
165-
const firstGrandChild = firstChild.children[0];
166-
if (firstGrandChild?.type === 'text') {
167-
title = firstGrandChild.value;
168-
}
168+
titleNode = firstChild.children;
169+
title = toString(firstChild.children);
169170
// The first paragraph contains a directive label, we can safely remove it.
170171
node.children.splice(0, 1);
171172
}
@@ -189,7 +190,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
189190
},
190191
iconPaths[variant]
191192
),
192-
{ type: 'text', value: title },
193+
...titleNode,
193194
]),
194195
h('section', { class: 'starlight-aside__content' }, node.children),
195196
]

packages/starlight/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
"hastscript": "^9.0.0",
201201
"mdast-util-directive": "^3.0.0",
202202
"mdast-util-to-markdown": "^2.1.0",
203+
"mdast-util-to-string": "^4.0.0",
203204
"pagefind": "^1.0.3",
204205
"rehype": "^13.0.1",
205206
"rehype-format": "^5.0.0",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)