Skip to content

Commit

Permalink
fix: custom titles of code snippets inside code groups (#1834)
Browse files Browse the repository at this point in the history
Co-authored-by: Divyansh Singh <[email protected]>
  • Loading branch information
Raiondesu and brc-dd authored Feb 14, 2023
1 parent ed90724 commit bcb8cbf
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
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

0 comments on commit bcb8cbf

Please sign in to comment.