|
|
@ -6,7 +6,19 @@ import { Header } from './markdown/plugins/header'
|
|
|
|
import { deeplyParseHeader } from './utils/parseHeader'
|
|
|
|
import { deeplyParseHeader } from './utils/parseHeader'
|
|
|
|
|
|
|
|
|
|
|
|
const debug = require('debug')('vitepress:md')
|
|
|
|
const debug = require('debug')('vitepress:md')
|
|
|
|
const cache = new LRUCache<string, string>({ max: 1024 })
|
|
|
|
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface MarkdownCompileResult {
|
|
|
|
|
|
|
|
vueSrc: string
|
|
|
|
|
|
|
|
pageData: PageData
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export interface PageData {
|
|
|
|
|
|
|
|
title: string
|
|
|
|
|
|
|
|
frontmatter: Record<string, any>
|
|
|
|
|
|
|
|
headers: Header[]
|
|
|
|
|
|
|
|
lastUpdated: number
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function createMarkdownToVueRenderFn(
|
|
|
|
export function createMarkdownToVueRenderFn(
|
|
|
|
root: string,
|
|
|
|
root: string,
|
|
|
@ -29,38 +41,36 @@ export function createMarkdownToVueRenderFn(
|
|
|
|
// TODO validate data.links?
|
|
|
|
// TODO validate data.links?
|
|
|
|
|
|
|
|
|
|
|
|
// inject page data
|
|
|
|
// inject page data
|
|
|
|
const additionalBlocks = injectPageData(
|
|
|
|
const pageData: PageData = {
|
|
|
|
data.hoistedTags || [],
|
|
|
|
title: inferTitle(frontmatter, content),
|
|
|
|
content,
|
|
|
|
|
|
|
|
frontmatter,
|
|
|
|
frontmatter,
|
|
|
|
data.headers || [],
|
|
|
|
headers: data.headers,
|
|
|
|
lastUpdated
|
|
|
|
lastUpdated
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const additionalBlocks = injectPageData(
|
|
|
|
|
|
|
|
data.hoistedTags || [],
|
|
|
|
|
|
|
|
pageData
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const vueSrc =
|
|
|
|
const vueSrc =
|
|
|
|
`<template><div class="vitepress-content">${html}</div></template>\n` +
|
|
|
|
`<template><div class="vitepress-content">${html}</div></template>\n` +
|
|
|
|
additionalBlocks.join('\n')
|
|
|
|
additionalBlocks.join('\n')
|
|
|
|
debug(`[render] ${file} in ${Date.now() - start}ms.`)
|
|
|
|
debug(`[render] ${file} in ${Date.now() - start}ms.`)
|
|
|
|
cache.set(src, vueSrc)
|
|
|
|
|
|
|
|
return vueSrc
|
|
|
|
const result = { vueSrc, pageData }
|
|
|
|
|
|
|
|
cache.set(src, result)
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const scriptRE = /<\/script>/
|
|
|
|
const scriptRE = /<\/script>/
|
|
|
|
|
|
|
|
|
|
|
|
function injectPageData(
|
|
|
|
function injectPageData(
|
|
|
|
tags: string[],
|
|
|
|
tags: string[],
|
|
|
|
content: string,
|
|
|
|
data: PageData
|
|
|
|
frontmatter: object,
|
|
|
|
|
|
|
|
headers: Header[],
|
|
|
|
|
|
|
|
lastUpdated: number
|
|
|
|
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
const code = `\nexport const __pageData = ${JSON.stringify({
|
|
|
|
const code = `\nexport const __pageData = ${JSON.stringify(data)}`
|
|
|
|
title: inferTitle(frontmatter, content),
|
|
|
|
|
|
|
|
frontmatter,
|
|
|
|
|
|
|
|
headers,
|
|
|
|
|
|
|
|
lastUpdated
|
|
|
|
|
|
|
|
})}`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const existingScriptIndex = tags.findIndex((tag) => scriptRE.test(tag))
|
|
|
|
const existingScriptIndex = tags.findIndex((tag) => scriptRE.test(tag))
|
|
|
|
if (existingScriptIndex > -1) {
|
|
|
|
if (existingScriptIndex > -1) {
|
|
|
|
tags[existingScriptIndex] = tags[existingScriptIndex].replace(
|
|
|
|
tags[existingScriptIndex] = tags[existingScriptIndex].replace(
|
|
|
@ -85,4 +95,5 @@ const inferTitle = (frontmatter: any, content: string) => {
|
|
|
|
if (match) {
|
|
|
|
if (match) {
|
|
|
|
return deeplyParseHeader(match[1].trim())
|
|
|
|
return deeplyParseHeader(match[1].trim())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|