Skip to content

Commit bcb8cbf

Browse files
Raiondesubrc-dd
andauthored
fix: custom titles of code snippets inside code groups (#1834)
Co-authored-by: Divyansh Singh <[email protected]>
1 parent ed90724 commit bcb8cbf

File tree

4 files changed

+58
-11
lines changed

4 files changed

+58
-11
lines changed

docs/guide/markdown.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,34 @@ export default config
651651

652652
:::
653653

654+
You can also [import snippets](#import-code-snippets) in code groups:
655+
656+
**Input**
657+
658+
```md
659+
::: code-group
660+
661+
<!-- filename is used as title by default -->
662+
663+
<<< @/snippets/snippet.js
664+
665+
<!-- you can provide a custom one too -->
666+
667+
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
668+
669+
:::
670+
```
671+
672+
**Output**
673+
674+
::: code-group
675+
676+
<<< @/snippets/snippet.js
677+
678+
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
679+
680+
:::
681+
654682
## Markdown File Inclusion
655683

656684
You can include a markdown file in another markdown file like this:

src/node/markdown/plugins/lineNumbers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ export const lineNumberPlugin = (md: MarkdownIt, enable = false) => {
2424
)
2525

2626
const lines = code.split('\n')
27-
const lineNumbersCode = [...Array(lines.length - 1)]
28-
.map((line, index) => `<span class="line-number">${index + 1}</span><br>`)
27+
28+
const lineNumbersCode = [
29+
...Array(
30+
lines.length - (lines.at(-1) === `<span class="line"></span>` ? 1 : 0)
31+
)
32+
]
33+
.map((_, index) => `<span class="line-number">${index + 1}</span><br>`)
2934
.join('')
3035

3136
const lineNumbersWrapperCode = `<div class="line-numbers-wrapper" aria-hidden="true">${lineNumbersCode}</div>`

src/node/markdown/plugins/preWrapper.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import type MarkdownIt from 'markdown-it'
33
export function preWrapperPlugin(md: MarkdownIt) {
44
const fence = md.renderer.rules.fence!
55
md.renderer.rules.fence = (...args) => {
6-
const { info } = args[0][args[1]]
7-
const lang = extractLang(info)
6+
const [tokens, idx] = args
7+
const token = tokens[idx]
8+
// remove title from info
9+
token.info = token.info.replace(/\[.*\]/, '')
10+
11+
const lang = extractLang(token.info)
812
const rawCode = fence(...args)
913
return `<div class="language-${lang}${
10-
/ active( |$)/.test(info) ? ' active' : ''
14+
/ active( |$)/.test(token.info) ? ' active' : ''
1115
}"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>${rawCode}</div>`
1216
}
1317
}
@@ -19,7 +23,7 @@ export function extractTitle(info: string) {
1923
const extractLang = (info: string) => {
2024
return info
2125
.trim()
22-
.replace(/:(no-)?line-numbers$/, '')
26+
.replace(/:(no-)?line-numbers({| |$).*/, '')
2327
.replace(/(-vue|{| ).*$/, '')
2428
.replace(/^vue-html$/, 'template')
2529
}

src/node/markdown/plugins/snippet.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,24 +95,34 @@ export const snippetPlugin = (md: MarkdownIt, srcDir: string) => {
9595
* where #region and {meta} are optional
9696
* and meta can be like '1,2,4-6 lang', 'lang' or '1,2,4-6'
9797
*
98-
* captures: ['/path/to/file.extension', 'extension', '#region', '{meta}']
98+
* captures: ['/path/to/file.extension', 'extension', '#region', '{meta}', '[title]']
9999
*/
100100
const rawPathRegexp =
101-
/^(.+(?:\.([a-z0-9]+)))(?:(#[\w-]+))?(?: ?(?:{(\d+(?:[,-]\d+)*)? ?(\S+)?}))?$/
101+
/^(.+(?:\.([a-z0-9]+)))(?:(#[\w-]+))?(?: ?(?:{(\d+(?:[,-]\d+)*)? ?(\S+)?}))? ?(?:\[(.+)\])?$/
102102

103103
const rawPath = state.src
104104
.slice(start, end)
105105
.trim()
106106
.replace(/^@/, srcDir)
107107
.trim()
108108

109-
const [filename = '', extension = '', region = '', lines = '', lang = ''] =
110-
(rawPathRegexp.exec(rawPath) || []).slice(1)
109+
const [
110+
filename = '',
111+
extension = '',
112+
region = '',
113+
lines = '',
114+
lang = '',
115+
rawTitle = ''
116+
] = (rawPathRegexp.exec(rawPath) || []).slice(1)
117+
118+
const title = rawTitle || filename.split('/').at(-1) || ''
111119

112120
state.line = startLine + 1
113121

114122
const token = state.push('fence', 'code', 0)
115-
token.info = `${lang || extension}${lines ? `{${lines}}` : ''}`
123+
token.info = `${lang || extension}${lines ? `{${lines}}` : ''}${
124+
title ? `[${title}]` : ''
125+
}`
116126

117127
// @ts-ignore
118128
token.src = path.resolve(filename) + region

0 commit comments

Comments
 (0)