Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: custom titles of code snippets inside code groups #1834

Merged
merged 11 commits into from
Feb 14, 2023
28 changes: 28 additions & 0 deletions docs/guide/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,34 @@ export default config

:::

You can also [import snippets](#import-code-snippets) in code groups:

**Input**

```md
::: code-group

<!-- filename is used as title by default -->

<<< @/snippets/snippet.js

<!-- you can provide a custom one too -->

<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]

:::
```

**Output**

::: code-group

<<< @/snippets/snippet.js

<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]

:::

## Markdown File Inclusion

You can include a markdown file in another markdown file like this:
Expand Down
9 changes: 7 additions & 2 deletions src/node/markdown/plugins/lineNumbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ export const lineNumberPlugin = (md: MarkdownIt, enable = false) => {
)

const lines = code.split('\n')
const lineNumbersCode = [...Array(lines.length - 1)]
.map((line, index) => `<span class="line-number">${index + 1}</span><br>`)

const lineNumbersCode = [
...Array(
lines.length - (lines.at(-1) === `<span class="line"></span>` ? 1 : 0)
)
]
.map((_, index) => `<span class="line-number">${index + 1}</span><br>`)
.join('')

const lineNumbersWrapperCode = `<div class="line-numbers-wrapper" aria-hidden="true">${lineNumbersCode}</div>`
Expand Down
12 changes: 8 additions & 4 deletions src/node/markdown/plugins/preWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ import type MarkdownIt from 'markdown-it'
export function preWrapperPlugin(md: MarkdownIt) {
const fence = md.renderer.rules.fence!
md.renderer.rules.fence = (...args) => {
const { info } = args[0][args[1]]
const lang = extractLang(info)
const [tokens, idx] = args
const token = tokens[idx]
// remove title from info
token.info = token.info.replace(/\[.*\]/, '')

const lang = extractLang(token.info)
const rawCode = fence(...args)
return `<div class="language-${lang}${
/ active( |$)/.test(info) ? ' active' : ''
/ active( |$)/.test(token.info) ? ' active' : ''
}"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>${rawCode}</div>`
}
}
Expand All @@ -19,7 +23,7 @@ export function extractTitle(info: string) {
const extractLang = (info: string) => {
return info
.trim()
.replace(/:(no-)?line-numbers$/, '')
.replace(/:(no-)?line-numbers({| |$).*/, '')
.replace(/(-vue|{| ).*$/, '')
.replace(/^vue-html$/, 'template')
}
20 changes: 15 additions & 5 deletions src/node/markdown/plugins/snippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,34 @@ export const snippetPlugin = (md: MarkdownIt, srcDir: string) => {
* where #region and {meta} are optional
* and meta can be like '1,2,4-6 lang', 'lang' or '1,2,4-6'
*
* captures: ['/path/to/file.extension', 'extension', '#region', '{meta}']
* captures: ['/path/to/file.extension', 'extension', '#region', '{meta}', '[title]']
*/
const rawPathRegexp =
/^(.+(?:\.([a-z0-9]+)))(?:(#[\w-]+))?(?: ?(?:{(\d+(?:[,-]\d+)*)? ?(\S+)?}))?$/
/^(.+(?:\.([a-z0-9]+)))(?:(#[\w-]+))?(?: ?(?:{(\d+(?:[,-]\d+)*)? ?(\S+)?}))? ?(?:\[(.+)\])?$/

const rawPath = state.src
.slice(start, end)
.trim()
.replace(/^@/, srcDir)
.trim()

const [filename = '', extension = '', region = '', lines = '', lang = ''] =
(rawPathRegexp.exec(rawPath) || []).slice(1)
const [
filename = '',
extension = '',
region = '',
lines = '',
lang = '',
rawTitle = ''
] = (rawPathRegexp.exec(rawPath) || []).slice(1)

const title = rawTitle || filename.split('/').at(-1) || ''

state.line = startLine + 1

const token = state.push('fence', 'code', 0)
token.info = `${lang || extension}${lines ? `{${lines}}` : ''}`
token.info = `${lang || extension}${lines ? `{${lines}}` : ''}${
title ? `[${title}]` : ''
}`

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