From 5f13a1ba4603c285a421d4619d68795a59d8c65b Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 30 Aug 2024 19:11:19 +0800 Subject: [PATCH] feat(theme): add normalize page title markdown plugin --- theme/src/node/plugins/markdown-title.ts | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 theme/src/node/plugins/markdown-title.ts diff --git a/theme/src/node/plugins/markdown-title.ts b/theme/src/node/plugins/markdown-title.ts new file mode 100644 index 00000000..e3eb2350 --- /dev/null +++ b/theme/src/node/plugins/markdown-title.ts @@ -0,0 +1,46 @@ +import type { Plugin } from 'vuepress/core' +import type { MarkdownEnv } from 'vuepress/markdown' + +const REG_HEADING = /^#\s*?(\S.*)?\n/ + +export function markdownTitlePlugin(): Plugin { + return { + name: '@vuepress-plume/plugin-markdown-title', + + extendsMarkdown(md) { + const render = md.render + md.render = (source, env: MarkdownEnv) => { + if (!env.filePathRelative) + return render(source, env) + + let { matter, content } = parseSource(source.trim()) + let title = '' + content = content.trim().replace(REG_HEADING, (_, match) => { + title = match.trim() + return '' + }) + source = `${matter}\n${content}` + const result = render(source, env) + if (title) + env.title = title + return result + } + }, + } +} + +function parseSource(source: string) { + const char = '---' + + if (!source.startsWith(char)) { + return { matter: '', content: source } + } + else { + const end = source.indexOf(`\n${char}`) + const len = char.length + 1 + return { + matter: source.slice(0, end + len), + content: source.slice(end + len), + } + } +}