Skip to content

Commit 7740aaa

Browse files
committed
fix(docs): allow hyphens in fenced codeblock language (#2437)
The fenced-codeblock language regexes in render.ts and text.ts matched \w which excludes `-`, so languages like `glimmer-ts`, `vue-html`, and `objective-c` were truncated: the `-ts` suffix was stripped off the language and leaked into the top of the code body, breaking Shiki highlighting. Swap `\w` for `[\w-]` in the three affected regexes and add a regression test covering `glimmer-ts`. Fixes #2437
1 parent e331d86 commit 7740aaa

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

server/utils/docs/render.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ async function renderJsDocTags(tags: JsDocTag[], symbolLookup: SymbolLookup): Pr
191191
: null
192192
const examplePromises = examples.map(async example => {
193193
if (!example.doc) return ''
194-
const langMatch = example.doc.match(/```(\w+)?/)
194+
const langMatch = example.doc.match(/```([\w-]+)?/)
195195
const lang = langMatch?.[1] || 'typescript'
196-
const code = example.doc.replace(/```\w*\n?/g, '').trim()
196+
const code = example.doc.replace(/```[\w-]*\n?/g, '').trim()
197197
return highlightCodeBlock(code, lang)
198198
})
199199

server/utils/docs/text.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export async function renderMarkdown(text: string, symbolLookup: SymbolLookup):
106106
// - \r\n, \n, or \r line endings
107107
const codeBlockData: Array<{ lang: string; code: string }> = []
108108
let result = text.replace(
109-
/```[ \t]*(\w*)[ \t]*(?:\r\n|\r|\n)([\s\S]*?)(?:\r\n|\r|\n)?```/g,
109+
/```[ \t]*([\w-]*)[ \t]*(?:\r\n|\r|\n)([\s\S]*?)(?:\r\n|\r|\n)?```/g,
110110
(_, lang, code) => {
111111
const index = codeBlockData.length
112112
codeBlockData.push({ lang: lang || 'text', code: code.trim() })

test/unit/server/utils/docs/text.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,17 @@ describe('renderMarkdown', () => {
293293
expect(result).not.toContain('```')
294294
})
295295

296+
it('should handle fenced code blocks with hyphenated language (e.g. glimmer-ts)', async () => {
297+
// Regression test for #2437: regex used \w which dropped the `-ts` suffix,
298+
// leaving it at the start of the code body and breaking highlighting.
299+
const input = '```glimmer-ts\nconst x = 1;\n```'
300+
const result = await renderMarkdown(input, emptyLookup)
301+
// Code must not leak the truncated language suffix into the body
302+
expect(result).not.toContain('-ts')
303+
expect(result).toContain('const')
304+
expect(result).not.toContain('```')
305+
})
306+
296307
it('should escape HTML inside fenced code blocks', async () => {
297308
const input = '```ts\nconst arr: Array<string> = [];\n```'
298309
const result = await renderMarkdown(input, emptyLookup)

0 commit comments

Comments
 (0)