diff --git a/packages/@vuepress/core/lib/prepare/AppContext.js b/packages/@vuepress/core/lib/prepare/AppContext.js index c1176a154b..b95823201a 100644 --- a/packages/@vuepress/core/lib/prepare/AppContext.js +++ b/packages/@vuepress/core/lib/prepare/AppContext.js @@ -73,6 +73,7 @@ module.exports = class AppContext { this.base = this.siteConfig.base || '/' this.themeConfig = this.siteConfig.themeConfig || {} + this.extractHeaders = this.siteConfig.markdown && this.siteConfig.markdown.extractHeaders const rawOutDir = this.cliOptions.dest || this.siteConfig.dest this.outDir = rawOutDir @@ -292,6 +293,7 @@ module.exports = class AppContext { async addPage (options) { options.permalinkPattern = this.siteConfig.permalink + options.siteConfig = this.siteConfig const page = new Page(options, this) await page.process({ markdown: this.markdown, diff --git a/packages/@vuepress/core/lib/prepare/Page.js b/packages/@vuepress/core/lib/prepare/Page.js index 04b7178a50..a0d4dd3786 100644 --- a/packages/@vuepress/core/lib/prepare/Page.js +++ b/packages/@vuepress/core/lib/prepare/Page.js @@ -45,7 +45,8 @@ module.exports = class Page { relative, permalink, frontmatter = {}, - permalinkPattern + permalinkPattern, + extractHeaders = ['h2', 'h3'] }, context) { this.title = title this._meta = meta @@ -54,6 +55,7 @@ module.exports = class Page { this._permalink = permalink this.frontmatter = frontmatter this._permalinkPattern = permalinkPattern + this._extractHeaders = extractHeaders this._context = context if (relative) { @@ -107,12 +109,13 @@ module.exports = class Page { this.title = title } - // headers + // extract headers const headers = extractHeaders( this._strippedContent, - ['h2', 'h3'], + this._extractHeaders, markdown ) + if (headers.length) { this.headers = headers } diff --git a/packages/@vuepress/core/lib/webpack/createBaseConfig.js b/packages/@vuepress/core/lib/webpack/createBaseConfig.js index c04aae63d5..7a840e615c 100644 --- a/packages/@vuepress/core/lib/webpack/createBaseConfig.js +++ b/packages/@vuepress/core/lib/webpack/createBaseConfig.js @@ -33,6 +33,7 @@ module.exports = function createBaseConfig ({ const inlineLimit = 10000 const config = new Config() + const extractHeaders = siteConfig.markdown && siteConfig.markdown.extractHeaders config .mode(isProd && !env.isDebug ? 'production' : 'development') @@ -116,7 +117,7 @@ module.exports = function createBaseConfig ({ mdRule .use('markdown-loader') .loader(require.resolve('@vuepress/markdown-loader')) - .options({ sourceDir, markdown }) + .options({ sourceDir, markdown, extractHeaders }) config.module .rule('pug') diff --git a/packages/@vuepress/markdown-loader/index.js b/packages/@vuepress/markdown-loader/index.js index f4fd02ab9b..3be7c68c9e 100644 --- a/packages/@vuepress/markdown-loader/index.js +++ b/packages/@vuepress/markdown-loader/index.js @@ -21,7 +21,7 @@ module.exports = function (src) { const isProd = process.env.NODE_ENV === 'production' const isServer = this.target === 'node' const options = getOptions(this) - const { sourceDir } = options + const { sourceDir, extractHeaders: extractHeadersPattern = ['h2', 'h3'] } = options let { markdown } = options if (!markdown) { markdown = md() @@ -42,7 +42,7 @@ module.exports = function (src) { if (!isProd && !isServer) { const inferredTitle = inferTitle(frontmatter.data, frontmatter.content) - const headers = extractHeaders(content, ['h2', 'h3'], markdown) + const headers = extractHeaders(content, extractHeadersPattern, markdown) delete frontmatter.content // diff frontmatter and title, since they are not going to be part of the diff --git a/packages/docs/docs/theme/default-theme-config.md b/packages/docs/docs/theme/default-theme-config.md index e921d46ce2..71c5fda210 100644 --- a/packages/docs/docs/theme/default-theme-config.md +++ b/packages/docs/docs/theme/default-theme-config.md @@ -154,6 +154,17 @@ module.exports = { } ``` +### Extract Headers + While preparing the page, headers are extracted from the markdown file and stored in `this.$page.headers`. By default, VuePress will extract `h2` and `h3` elements for you. + You can override the headers it pulls out in your `markdown` options. + ``` js +module.exports = { + markdown: { + extractHeaders: [ 'h2', 'h3', 'h4' ] + } +} +``` + ### Active Header Links By default, the nested header links and the hash in the URL are updated as the user scrolls to view the different sections of the page. This behavior can be disabled with the following theme config: