feat(build): support markdown frontmatter options (#1218)

pull/1224/head
meteorlxy 2 years ago committed by GitHub
parent a4af194608
commit bfb0220989
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -93,7 +93,9 @@
}, },
"devDependencies": { "devDependencies": {
"@mdit-vue/plugin-component": "^0.9.2", "@mdit-vue/plugin-component": "^0.9.2",
"@mdit-vue/plugin-frontmatter": "^0.9.2",
"@mdit-vue/plugin-toc": "^0.9.2", "@mdit-vue/plugin-toc": "^0.9.2",
"@mdit-vue/types": "^0.9.2",
"@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-commonjs": "^22.0.2", "@rollup/plugin-commonjs": "^22.0.2",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
@ -129,7 +131,6 @@
"execa": "^6.1.0", "execa": "^6.1.0",
"fast-glob": "^3.2.11", "fast-glob": "^3.2.11",
"fs-extra": "^10.1.0", "fs-extra": "^10.1.0",
"gray-matter": "^4.0.3",
"lint-staged": "^13.0.3", "lint-staged": "^13.0.3",
"lru-cache": "^7.13.2", "lru-cache": "^7.13.2",
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",

@ -7,7 +7,9 @@ importers:
'@docsearch/css': ^3.2.1 '@docsearch/css': ^3.2.1
'@docsearch/js': ^3.2.1 '@docsearch/js': ^3.2.1
'@mdit-vue/plugin-component': ^0.9.2 '@mdit-vue/plugin-component': ^0.9.2
'@mdit-vue/plugin-frontmatter': ^0.9.2
'@mdit-vue/plugin-toc': ^0.9.2 '@mdit-vue/plugin-toc': ^0.9.2
'@mdit-vue/types': ^0.9.2
'@rollup/plugin-alias': ^3.1.9 '@rollup/plugin-alias': ^3.1.9
'@rollup/plugin-commonjs': ^22.0.2 '@rollup/plugin-commonjs': ^22.0.2
'@rollup/plugin-json': ^4.1.0 '@rollup/plugin-json': ^4.1.0
@ -47,7 +49,6 @@ importers:
execa: ^6.1.0 execa: ^6.1.0
fast-glob: ^3.2.11 fast-glob: ^3.2.11
fs-extra: ^10.1.0 fs-extra: ^10.1.0
gray-matter: ^4.0.3
lint-staged: ^13.0.3 lint-staged: ^13.0.3
lru-cache: ^7.13.2 lru-cache: ^7.13.2
markdown-it: ^13.0.1 markdown-it: ^13.0.1
@ -90,7 +91,9 @@ importers:
vue: 3.2.37 vue: 3.2.37
devDependencies: devDependencies:
'@mdit-vue/plugin-component': 0.9.2 '@mdit-vue/plugin-component': 0.9.2
'@mdit-vue/plugin-frontmatter': 0.9.2
'@mdit-vue/plugin-toc': 0.9.2 '@mdit-vue/plugin-toc': 0.9.2
'@mdit-vue/types': 0.9.2
'@rollup/plugin-alias': 3.1.9_rollup@2.78.0 '@rollup/plugin-alias': 3.1.9_rollup@2.78.0
'@rollup/plugin-commonjs': 22.0.2_rollup@2.78.0 '@rollup/plugin-commonjs': 22.0.2_rollup@2.78.0
'@rollup/plugin-json': 4.1.0_rollup@2.78.0 '@rollup/plugin-json': 4.1.0_rollup@2.78.0
@ -126,7 +129,6 @@ importers:
execa: 6.1.0 execa: 6.1.0
fast-glob: 3.2.11 fast-glob: 3.2.11
fs-extra: 10.1.0 fs-extra: 10.1.0
gray-matter: 4.0.3
lint-staged: 13.0.3_a6syxerf33u6jkjxxnsrpgxntq lint-staged: 13.0.3_a6syxerf33u6jkjxxnsrpgxntq
lru-cache: 7.13.2 lru-cache: 7.13.2
markdown-it: 13.0.1 markdown-it: 13.0.1
@ -401,6 +403,15 @@ packages:
markdown-it: 13.0.1 markdown-it: 13.0.1
dev: true dev: true
/@mdit-vue/plugin-frontmatter/0.9.2:
resolution: {integrity: sha512-qHVgr6v0sH4C2KPD/q/EMUQBGLjuxpS24gyqLHwKHzg+o977CJGS0UA2TymGybHTliaIqmRiQ9DGkIzqO7sJCQ==}
dependencies:
'@mdit-vue/types': 0.9.2
'@types/markdown-it': 12.2.3
gray-matter: 4.0.3
markdown-it: 13.0.1
dev: true
/@mdit-vue/plugin-toc/0.9.2: /@mdit-vue/plugin-toc/0.9.2:
resolution: {integrity: sha512-Du3fFz+YezlXex9Syn+bc8ADDRx/kBfBokeHXfd/qCW5XqS7I4THLR/IRqlvi9CgIZ0dx7bJv0avxil9EX1PoQ==} resolution: {integrity: sha512-Du3fFz+YezlXex9Syn+bc8ADDRx/kBfBokeHXfd/qCW5XqS7I4THLR/IRqlvi9CgIZ0dx7bJv0avxil9EX1PoQ==}
dependencies: dependencies:

@ -0,0 +1,8 @@
import type { MarkdownItEnv } from '@mdit-vue/types'
import { CleanUrlsMode } from '../shared'
export interface MarkdownEnv extends MarkdownItEnv {
path: string
relativePath: string
cleanUrls: CleanUrlsMode
}

@ -0,0 +1,2 @@
export * from './env'
export * from './markdown'

@ -3,6 +3,10 @@ import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs' import attrsPlugin from 'markdown-it-attrs'
import emojiPlugin from 'markdown-it-emoji' import emojiPlugin from 'markdown-it-emoji'
import { componentPlugin } from '@mdit-vue/plugin-component' import { componentPlugin } from '@mdit-vue/plugin-component'
import {
frontmatterPlugin,
type FrontmatterPluginOptions
} from '@mdit-vue/plugin-frontmatter'
import { tocPlugin, type TocPluginOptions } from '@mdit-vue/plugin-toc' import { tocPlugin, type TocPluginOptions } from '@mdit-vue/plugin-toc'
import { IThemeRegistration } from 'shiki' import { IThemeRegistration } from 'shiki'
import { highlight } from './plugins/highlight' import { highlight } from './plugins/highlight'
@ -32,6 +36,7 @@ export interface MarkdownOptions extends MarkdownIt.Options {
allowedAttributes?: string[] allowedAttributes?: string[]
disable?: boolean disable?: boolean
} }
frontmatter?: FrontmatterPluginOptions
theme?: ThemeOptions theme?: ThemeOptions
toc?: TocPluginOptions toc?: TocPluginOptions
externalLinks?: Record<string, string> externalLinks?: Record<string, string>
@ -92,6 +97,9 @@ export const createMarkdownRenderer = async (
permalink: anchorPlugin.permalink.ariaHidden({}), permalink: anchorPlugin.permalink.ariaHidden({}),
...options.anchor ...options.anchor
} as anchorPlugin.AnchorOptions) } as anchorPlugin.AnchorOptions)
.use(frontmatterPlugin, {
...options.frontmatter
} as FrontmatterPluginOptions)
.use(tocPlugin, { .use(tocPlugin, {
slugify, slugify,
...options.toc ...options.toc

@ -3,7 +3,8 @@
// 2. normalize internal links to end with `.html` // 2. normalize internal links to end with `.html`
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import { MarkdownRenderer } from '../markdown' import type { MarkdownEnv } from '../env'
import type { MarkdownRenderer } from '../markdown'
import { URL } from 'url' import { URL } from 'url'
import { EXTERNAL_URL_RE, CleanUrlsMode } from '../../shared' import { EXTERNAL_URL_RE, CleanUrlsMode } from '../../shared'
@ -14,7 +15,13 @@ export const linkPlugin = (
externalAttrs: Record<string, string>, externalAttrs: Record<string, string>,
base: string base: string
) => { ) => {
md.renderer.rules.link_open = (tokens, idx, options, env, self) => { md.renderer.rules.link_open = (
tokens,
idx,
options,
env: MarkdownEnv,
self
) => {
const token = tokens[idx] const token = tokens[idx]
const hrefIndex = token.attrIndex('href') const hrefIndex = token.attrIndex('href')
if (hrefIndex >= 0) { if (hrefIndex >= 0) {
@ -37,7 +44,7 @@ export const linkPlugin = (
// links to files (other than html/md) // links to files (other than html/md)
!/\.(?!html|md)\w+($|\?)/i.test(url) !/\.(?!html|md)\w+($|\?)/i.test(url)
) { ) {
normalizeHref(hrefAttr, env.cleanUrl) normalizeHref(hrefAttr, env.cleanUrls)
} }
// encode vite-specific replace strings in case they appear in URLs // encode vite-specific replace strings in case they appear in URLs

@ -1,13 +1,16 @@
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import c from 'picocolors' import c from 'picocolors'
import matter from 'gray-matter'
import LRUCache from 'lru-cache' import LRUCache from 'lru-cache'
import { PageData, HeadConfig, EXTERNAL_URL_RE, CleanUrlsMode } from './shared' import { PageData, HeadConfig, EXTERNAL_URL_RE, CleanUrlsMode } from './shared'
import { slash } from './utils/slash' import { slash } from './utils/slash'
import { deeplyParseHeader } from './utils/parseHeader' import { deeplyParseHeader } from './utils/parseHeader'
import { getGitTimestamp } from './utils/getGitTimestamp' import { getGitTimestamp } from './utils/getGitTimestamp'
import { createMarkdownRenderer, MarkdownOptions } from './markdown/markdown' import {
createMarkdownRenderer,
type MarkdownEnv,
type MarkdownOptions
} from './markdown'
import _debug from 'debug' import _debug from 'debug'
const debug = _debug('vitepress:md') const debug = _debug('vitepress:md')
@ -69,19 +72,18 @@ export async function createMarkdownToVueRenderFn(
} }
}) })
const { content, data: frontmatter } = matter(src)
// reset state before render // reset state before render
md.__path = file md.__path = file
md.__relativePath = relativePath md.__relativePath = relativePath
const html = md.render(content, { const env: MarkdownEnv = {
path: file, path: file,
relativePath, relativePath,
cleanUrls, cleanUrls
frontmatter }
}) const html = md.render(src, env)
const data = md.__data const data = md.__data
const { content = '', frontmatter = {} } = env
// validate data.links // validate data.links
const deadLinks: string[] = [] const deadLinks: string[] = []
@ -128,7 +130,7 @@ export async function createMarkdownToVueRenderFn(
const pageData: PageData = { const pageData: PageData = {
title: inferTitle(frontmatter, content), title: inferTitle(frontmatter, content),
titleTemplate: frontmatter.titleTemplate, titleTemplate: frontmatter.titleTemplate as any,
description: inferDescription(frontmatter), description: inferDescription(frontmatter),
frontmatter, frontmatter,
headers: data.headers || [], headers: data.headers || [],

Loading…
Cancel
Save