diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index d156505384..68756bd6c5 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -72,20 +72,6 @@ export default defineUserConfig({ extendsMarkdown: (md) => { md.use(footnote) - - // FIXME: Should be removed with next vuepress version - const rawFence = md.renderer.rules.fence! - const rawCodeInline = md.renderer.rules.code_inline! - - md.renderer.rules.fence = (...args) => { - const result = rawFence(...args) - return result.replace('
{
- const result = rawCodeInline(...args)
- return ` ``)
.join('')
- const lineNumbersWrapperCode = `
`
+ const lineNumbersWrapperCode = ` `
const finalCode = rawCode
.replace(/<\/div>$/, `${lineNumbersWrapperCode}`)
diff --git a/plugins/plugin-prismjs/tests/__snapshots__/prismjs-preWrapper.spec.ts.snap b/plugins/plugin-prismjs/tests/__snapshots__/prismjs-preWrapper.spec.ts.snap
index add59dfff3..db1b8df587 100644
--- a/plugins/plugin-prismjs/tests/__snapshots__/prismjs-preWrapper.spec.ts.snap
+++ b/plugins/plugin-prismjs/tests/__snapshots__/prismjs-preWrapper.spec.ts.snap
@@ -5,7 +5,7 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
Raw text
-Raw text
+
Raw text
const foo = 'foo'
@@ -19,7 +19,7 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -37,7 +37,7 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -49,9 +49,9 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers / :no-line-numbers > should work properly if \`lineNumbers\` is enabled by default 1`] = `
"Raw text
-Raw text
+
Raw text
-Raw text
+
Raw text
const foo = 'foo'
@@ -59,13 +59,13 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -77,13 +77,13 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -97,7 +97,7 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
Raw text
-Raw text
+
Raw text
const foo = 'foo'
@@ -105,13 +105,13 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -123,13 +123,13 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -138,6 +138,48 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers /
"
`;
+exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is disabled by default 1`] = `
+"const line2 = 'line 2'
+const line3 = 'line 3'
+
+const line3 = 'line 3'
+const line4 = 'line 4'
+const line5 = 'line 5'
+
+const line10 = 'line 10'
+const line11 = 'line 11'
+
+"
+`;
+
+exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is enabled by default 1`] = `
+"const line2 = 'line 2'
+const line3 = 'line 3'
+
+const line3 = 'line 3'
+const line4 = 'line 4'
+const line5 = 'line 5'
+
+const line10 = 'line 10'
+const line11 = 'line 11'
+
+"
+`;
+
+exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is set to a number by default 1`] = `
+"const line2 = 'line 2'
+const line3 = 'line 3'
+
+const line3 = 'line 3'
+const line4 = 'line 4'
+const line5 = 'line 5'
+
+const line10 = 'line 10'
+const line11 = 'line 11'
+
+"
+`;
+
exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > highlight notation > should highlight notation 1`] = `
"const foo = 'foo'
const bar = 'bar'
@@ -146,25 +188,25 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > highlight notati
const quux = 'quux'
const corge = 'corge'
-"
+
Raw text
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -174,7 +216,7 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > plugin options >
return 2048
}
-{{ inlineCode }}
{{ inlineCode }}
const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -261,26 +303,26 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > plugin options >
return 2048
}
-{{ inlineCode }}
{{ inlineCode }}
Raw text
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
}
-const foo = 'foo'
+
const foo = 'foo'
function bar () {
return 1024
@@ -290,56 +332,56 @@ exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > plugin options >
return 2048
}
-{{ inlineCode }}
{{ inlineCode }}
\` 1`] = ` "-highlighted code: Raw text , lang:
highlighted code: const foo = 'foo' +
-highlighted code: const foo = 'foo' function bar () { return 1024 } , lang: js
highlighted code: const foo: string = 'foo' +
-highlighted code: const foo: string = 'foo' function bar (): number { return 1024 } , lang: ts
highlighted code: +
" + " `; exports[`@vuepress/plugin-prismjs > markdown fence preWrapper > syntax highlighting > should work if highlighted code is wrapped with \`-highlighted code:
msg: {{msg}}const msg = 'hello world'; , lang: vue-html\` 1`] = ` "--highlighted code: Raw text , lang:
highlighted code: const foo = 'foo' +
-highlighted code: const foo = 'foo' function bar () { return 1024 } , lang: js
highlighted code: const foo: string = 'foo' +
-highlighted code: const foo: string = 'foo' function bar (): number { return 1024 } , lang: ts
highlighted code: +
" + " `; diff --git a/plugins/plugin-prismjs/tests/prismjs-preWrapper.spec.ts b/plugins/plugin-prismjs/tests/prismjs-preWrapper.spec.ts index 55e61cc4f4..a0e0b72b67 100644 --- a/plugins/plugin-prismjs/tests/prismjs-preWrapper.spec.ts +++ b/plugins/plugin-prismjs/tests/prismjs-preWrapper.spec.ts @@ -214,6 +214,49 @@ ${codeFence} }) }) + describe(':line-numbers=number', () => { + const source = `\ +${codeFence}ts:line-numbers=2 +const line2 = 'line 2' +const line3 = 'line 3' +${codeFence} + +${codeFence}ts{2,3}:line-numbers=3 +const line3 = 'line 3' +const line4 = 'line 4' +const line5 = 'line 5' +${codeFence} + +${codeFence}ts title="config/foo.ts" foo="foo" {1,2}:line-numbers=10 +const line10 = 'line 10' +const line11 = 'line 11' +${codeFence} +` + it('should work properly if `lineNumbers` is enabled by default', () => { + const md = createMarkdown({ + lineNumbers: true, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + + it('should work properly if `lineNumbers` is disabled by default', () => { + const md = createMarkdown({ + lineNumbers: false, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + + it('should work properly if `lineNumbers` is set to a number by default', () => { + const md = createMarkdown({ + lineNumbers: 4, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + }) + describe('syntax highlighting', () => { const source = `\ ${codeFence} diff --git a/plugins/plugin-shiki/src/node/markdown/lineNumberPlugin.ts b/plugins/plugin-shiki/src/node/markdown/lineNumberPlugin.ts index 577e3cda1c..311829d9fd 100644 --- a/plugins/plugin-shiki/src/node/markdown/lineNumberPlugin.ts +++ b/plugins/plugin-shiki/src/node/markdown/lineNumberPlugin.ts @@ -6,6 +6,7 @@ import type { LineNumberOptions } from '../types.js' const LINE_NUMBERS_REGEXP = /:line-numbers\b/ const NO_LINE_NUMBERS_REGEXP = /:no-line-numbers\b/ +const LINE_NUMBERS_START_REGEXP = /:line-numbers=(\d+)\b/ export const lineNumberPlugin = ( md: Markdown, @@ -43,11 +44,15 @@ export const lineNumberPlugin = ( return rawCode } + const startNumbers = + Number(info.match(LINE_NUMBERS_START_REGEXP)?.[1] ?? 1) - 1 + const lineNumbersStyle = `style="counter-reset:line-number ${startNumbers}"` + const lineNumbersCode = [...Array(lines.length)] .map(() => ``) .join('') - const lineNumbersWrapperCode = ` ` + const lineNumbersWrapperCode = ` ` const finalCode = rawCode .replace(/<\/div>$/, `${lineNumbersWrapperCode}`) diff --git a/plugins/plugin-shiki/tests/__snapshots__/shiki-preWrapper.spec.ts.snap b/plugins/plugin-shiki/tests/__snapshots__/shiki-preWrapper.spec.ts.snap index ec03e05166..e8af6309eb 100644 --- a/plugins/plugin-shiki/tests/__snapshots__/shiki-preWrapper.spec.ts.snap +++ b/plugins/plugin-shiki/tests/__snapshots__/shiki-preWrapper.spec.ts.snap @@ -3,7 +3,7 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-numbers > should work properly if \`lineNumbers\` is disabled by default 1`] = ` "-highlighted code:
msg: {{msg}}const msg = 'hello world'; , lang: vue-htmlRaw text
-Raw text
+Raw text
Raw text
-const foo = 'foo' function bar () { @@ -14,7 +14,7 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 @@ -29,7 +29,7 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu function bar () { return 1024 }
const foo = 'foo' +
const foo = 'foo' function bar () { return 1024 @@ -39,19 +39,19 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-numbers > should work properly if \`lineNumbers\` is enabled by default 1`] = ` "
-Raw text
-Raw text
+Raw text
+Raw text
Raw text
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 @@ -61,12 +61,12 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 } const foo = 'foo' +
" `; exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should disable \`highlightLines\` 1`] = ` "const foo = 'foo' function bar () { return 1024 @@ -77,18 +77,18 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-numbers > should work properly if \`lineNumbers\` is set to a number by default 1`] = ` "
Raw text
-Raw text
+Raw text
Raw text
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 @@ -98,12 +98,12 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 } const foo = 'foo' +
" `; +exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is disabled by default 1`] = ` +"const foo = 'foo' function bar () { return 1024 @@ -111,6 +111,39 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers / :no-line-nu
+const line2 = 'line 2' +const line3 = 'line 3'
+const line3 = 'line 3' +const line4 = 'line 4' +const line5 = 'line 5'
" +`; + +exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is enabled by default 1`] = ` +"+const line10 = 'line 10' +const line11 = 'line 11'
+const line2 = 'line 2' +const line3 = 'line 3'
+const line3 = 'line 3' +const line4 = 'line 4' +const line5 = 'line 5'
" +`; + +exports[`@vuepress/plugin-shiki > fence preWrapper > :line-numbers=number > should work properly if \`lineNumbers\` is set to a number by default 1`] = ` +"+const line10 = 'line 10' +const line11 = 'line 11'
+const line2 = 'line 2' +const line3 = 'line 3'
+const line3 = 'line 3' +const line4 = 'line 4' +const line5 = 'line 5'
" +`; + exports[`@vuepress/plugin-shiki > fence preWrapper > notation transformers > should work notation enabled 1`] = ` "+const line10 = 'line 10' +const line11 = 'line 11'
-const foo = 'foo' const bar = 'bar' @@ -118,25 +151,25 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > notation transformers > sho const bax = 'bax' const buz = 'buz' const qux = 'qux'
+
" +-const foo = 'foo' const bar = 'bar'
-Raw text
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 @@ -145,8 +178,8 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should dis const baz = () => { return 2048 }
-console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
+
{{ inlineCode }}
+console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
" `; @@ -209,12 +242,12 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should ena function bar () { return 1024 }
{{ inlineCode }}
const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 } const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 @@ -223,24 +256,24 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should ena const baz = () => { return 2048 } +console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
" `; exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should process code fences with default options 1`] = ` "
{{ inlineCode }}
-Raw text
const foo = 'foo' +
-const foo = 'foo' function bar () { return 1024 }
const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 } const foo = 'foo' +
-const foo = 'foo'
function bar () { return 1024 @@ -249,7 +282,7 @@ exports[`@vuepress/plugin-shiki > fence preWrapper > plugin options > should pro const baz = () => { return 2048 } -console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
+
{{ inlineCode }}
+console.log('1 + 2 + 3 =' + {{ 1 + 2 + 3 }})
" `; diff --git a/plugins/plugin-shiki/tests/shiki-preWrapper.spec.ts b/plugins/plugin-shiki/tests/shiki-preWrapper.spec.ts index b68281edbd..b4945e670e 100644 --- a/plugins/plugin-shiki/tests/shiki-preWrapper.spec.ts +++ b/plugins/plugin-shiki/tests/shiki-preWrapper.spec.ts @@ -216,6 +216,49 @@ ${codeFence} }) }) + describe(':line-numbers=number', () => { + const source = `\ +${codeFence}ts:line-numbers=2 +const line2 = 'line 2' +const line3 = 'line 3' +${codeFence} + +${codeFence}ts{2,3}:line-numbers=3 +const line3 = 'line 3' +const line4 = 'line 4' +const line5 = 'line 5' +${codeFence} + +${codeFence}ts title="config/foo.ts" foo="foo" {1,2}:line-numbers=10 +const line10 = 'line 10' +const line11 = 'line 11' +${codeFence} +` + it('should work properly if `lineNumbers` is enabled by default', async () => { + const md = await createMarkdown({ + lineNumbers: true, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + + it('should work properly if `lineNumbers` is disabled by default', async () => { + const md = await createMarkdown({ + lineNumbers: false, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + + it('should work properly if `lineNumbers` is set to a number by default', async () => { + const md = await createMarkdown({ + lineNumbers: 4, + }) + + expect(md.render(source)).toMatchSnapshot() + }) + }) + describe('notation transformers', () => { const source = `\ ${codeFence}ts
{{ inlineCode }}