diff --git a/__tests__/unit/node/markdownToVue.test.ts b/__tests__/unit/node/markdownToVue.test.ts index 9c88cdb5..ec89e7e0 100644 --- a/__tests__/unit/node/markdownToVue.test.ts +++ b/__tests__/unit/node/markdownToVue.test.ts @@ -67,6 +67,63 @@ describe('node/markdownToVue', () => { }) }) + test('selects included heading sections after frontmatter', async () => { + root = await mkdtemp(path.join(tmpdir(), 'vitepress-include-')) + + const file = path.join(root, 'index.md') + const source = path.join(root, 'source.md') + await writeFile( + source, + [ + '---', + 'description: Source description', + '---', + '# Intro', + '', + 'intro text', + '', + '## Shared', + '', + 'shared before target', + '', + '## Target', + '', + 'target text', + '', + '### Child', + '', + 'child text', + '', + '## Shared', + '', + 'shared after target', + '' + ].join('\n') + ) + const src = '' + await writeFile(file, src) + + const siteConfig = await resolveConfig(root, 'build', 'production') + const render = await createMarkdownToVueRenderFn( + siteConfig.srcDir, + { cache: false }, + '/', + false, + false, + siteConfig + ) + + const result = await render(src, file, 'public') + + expect(result.vueSrc).toContain('

target text

') + expect(result.vueSrc).toContain('

child text

') + expect(result.vueSrc).not.toContain('Source description') + expect(result.vueSrc).not.toContain('intro text') + expect(result.vueSrc).not.toContain('shared before target') + expect(result.vueSrc).not.toContain('shared after target') + }) + test('applies rewrites with mismatched Windows drive letter case', async () => { root = await mkdtemp(path.join(tmpdir(), 'vitepress-rewrite-')) diff --git a/src/node/utils/processIncludes.ts b/src/node/utils/processIncludes.ts index 20f6fbff..021c1b0b 100644 --- a/src/node/utils/processIncludes.ts +++ b/src/node/utils/processIncludes.ts @@ -41,12 +41,18 @@ export function processIncludes( if (region) { const [regionName] = region const lines = content.split(/\r?\n/) + let selectedLines = lines let { start, end } = findRegion(lines, regionName.slice(1)) ?? {} if (start === undefined) { // region not found, it might be a header + const headerContent = + path.extname(includePath) === '.md' + ? matter(content).content + : content + const headerLines = headerContent.split(/\r?\n/) const tokens = md - .parse(content, { + .parse(headerContent, { path: includePath, relativePath: slash(path.relative(srcDir, includePath)), cleanUrls @@ -57,6 +63,7 @@ export function processIncludes( ) const token = tokens[idx] if (token) { + selectedLines = headerLines start = token.map![1] const level = parseInt(token.tag.slice(1)) for (let i = idx + 1; i < tokens.length; i++) { @@ -68,7 +75,7 @@ export function processIncludes( } } - content = lines.slice(start, end).join('\n') + content = selectedLines.slice(start, end).join('\n') } if (range) {