Skip to content

Commit c6ff5c7

Browse files
authoredSep 10, 2023
feat: process md includes before building local search index (#2906)
1 parent 070fc0a commit c6ff5c7

File tree

3 files changed

+46
-36
lines changed

3 files changed

+46
-36
lines changed
 

‎src/node/markdownToVue.ts

+2-35
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ import {
1717
type PageData
1818
} from './shared'
1919
import { getGitTimestamp } from './utils/getGitTimestamp'
20+
import { processIncludes } from './utils/processIncludes'
2021

2122
const debug = _debug('vitepress:md')
2223
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
23-
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g
24-
const rangeRE = /\{(\d*),(\d*)\}$/
2524

2625
export interface MarkdownCompileResult {
2726
vueSrc: string
@@ -89,39 +88,7 @@ export async function createMarkdownToVueRenderFn(
8988

9089
// resolve includes
9190
let includes: string[] = []
92-
93-
function processIncludes(src: string, file: string): string {
94-
return src.replace(includesRE, (m: string, m1: string) => {
95-
if (!m1.length) return m
96-
97-
const range = m1.match(rangeRE)
98-
range && (m1 = m1.slice(0, -range[0].length))
99-
const atPresent = m1[0] === '@'
100-
try {
101-
const includePath = atPresent
102-
? path.join(srcDir, m1.slice(m1[1] === '/' ? 2 : 1))
103-
: path.join(path.dirname(file), m1)
104-
let content = fs.readFileSync(includePath, 'utf-8')
105-
if (range) {
106-
const [, startLine, endLine] = range
107-
const lines = content.split(/\r?\n/)
108-
content = lines
109-
.slice(
110-
startLine ? parseInt(startLine, 10) - 1 : undefined,
111-
endLine ? parseInt(endLine, 10) : undefined
112-
)
113-
.join('\n')
114-
}
115-
includes.push(slash(includePath))
116-
// recursively process includes in the content
117-
return processIncludes(content, includePath)
118-
} catch (error) {
119-
return m // silently ignore error if file is not present
120-
}
121-
})
122-
}
123-
124-
src = processIncludes(src, fileOrig)
91+
src = processIncludes(srcDir, src, fileOrig, includes)
12592

12693
// reset env before render
12794
const env: MarkdownEnv = {

‎src/node/plugins/localSearchPlugin.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
type DefaultTheme,
1212
type MarkdownEnv
1313
} from '../shared'
14+
import { processIncludes } from '../utils/processIncludes'
1415

1516
const debug = _debug('vitepress:local-search')
1617

@@ -56,7 +57,8 @@ export async function localSearchPlugin(
5657
const { srcDir, cleanUrls = false } = siteConfig
5758
const relativePath = slash(path.relative(srcDir, file))
5859
const env: MarkdownEnv = { path: file, relativePath, cleanUrls }
59-
const src = fs.readFileSync(file, 'utf-8')
60+
let src = fs.readFileSync(file, 'utf-8')
61+
src = processIncludes(srcDir, src, file, [])
6062
if (options._render) return options._render(src, env, md)
6163
const html = md.render(src, env)
6264
return env.frontmatter?.search === false ? '' : html

‎src/node/utils/processIncludes.ts

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import path from 'path'
2+
import fs from 'fs-extra'
3+
import { slash } from '../shared'
4+
5+
export function processIncludes(
6+
srcDir: string,
7+
src: string,
8+
file: string,
9+
includes: string[]
10+
): string {
11+
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g
12+
const rangeRE = /\{(\d*),(\d*)\}$/
13+
return src.replace(includesRE, (m: string, m1: string) => {
14+
if (!m1.length) return m
15+
16+
const range = m1.match(rangeRE)
17+
range && (m1 = m1.slice(0, -range[0].length))
18+
const atPresent = m1[0] === '@'
19+
try {
20+
const includePath = atPresent
21+
? path.join(srcDir, m1.slice(m1[1] === '/' ? 2 : 1))
22+
: path.join(path.dirname(file), m1)
23+
let content = fs.readFileSync(includePath, 'utf-8')
24+
if (range) {
25+
const [, startLine, endLine] = range
26+
const lines = content.split(/\r?\n/)
27+
content = lines
28+
.slice(
29+
startLine ? parseInt(startLine, 10) - 1 : undefined,
30+
endLine ? parseInt(endLine, 10) : undefined
31+
)
32+
.join('\n')
33+
}
34+
includes.push(slash(includePath))
35+
// recursively process includes in the content
36+
return processIncludes(srcDir, content, includePath, includes)
37+
} catch (error) {
38+
return m // silently ignore error if file is not present
39+
}
40+
})
41+
}

0 commit comments

Comments
 (0)
Please sign in to comment.