Skip to content

Define Headers to Parse during Page Prep - resolve #984 #1004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/@vuepress/core/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
exports.dev = require('./dev')
exports.build = require('./build')
exports.eject = require('./eject')
exports.loadConfig = require('./prepare/loadConfig')
1 change: 1 addition & 0 deletions packages/@vuepress/core/lib/prepare/AppContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,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,
Expand Down
24 changes: 15 additions & 9 deletions packages/@vuepress/core/lib/prepare/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ module.exports = class Page {
relative,
permalink,
frontmatter = {},
permalinkPattern
permalinkPattern,
siteConfig
}, context) {
this.title = title
this._meta = meta
Expand All @@ -54,6 +55,7 @@ module.exports = class Page {
this._permalink = permalink
this.frontmatter = frontmatter
this._permalinkPattern = permalinkPattern
this._siteConfig = siteConfig
this._context = context

if (relative) {
Expand Down Expand Up @@ -108,14 +110,18 @@ module.exports = class Page {
}

// headers
const headers = extractHeaders(
this._strippedContent,
['h2', 'h3'],
markdown
)
if (headers.length) {
this.headers = headers
}
this.headersToExtract = ['h2', 'h3']
if (this._siteConfig.markdown && this._siteConfig.markdown.extractHeaders) {
this.headersToExtract = this._siteConfig.markdown.extractHeaders
}
const headers = extractHeaders(
this._strippedContent,
this.headersToExtract,
markdown
)
if (headers.length) {
this.headers = headers
}

if (excerpt) {
const { html } = markdown.render(excerpt)
Expand Down
17 changes: 14 additions & 3 deletions packages/@vuepress/markdown-loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

const { EventEmitter } = require('events')
const { getOptions } = require('loader-utils')
const { fs, path, hash, parseFrontmatter, inferTitle, extractHeaders } = require('@vuepress/shared-utils')
const { loadConfig } = require('@vuepress/core')
const {
fs, path, hash, parseFrontmatter, inferTitle, extractHeaders,
datatypes: { isFunction }
} = require('@vuepress/shared-utils')
const LRU = require('lru-cache')
const md = require('@vuepress/markdown')

Expand All @@ -26,7 +30,10 @@ module.exports = function (src) {
if (!markdown) {
markdown = md()
}

let config = loadConfig(path.resolve(sourceDir, '.vuepress'), false)
if (isFunction(config)) {
config = config(this)
}
Copy link
Member

@ulivz ulivz Dec 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't re-load user's config at the scope of makrdown-loader, while this loader should only focus on how to transpile the source markdown file to Vue component.

extractHeaders should be a option for this loader.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ill do some more digging, but I couldn't find any way to get to the extractHeaders option from within this file already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying it should be available already inside of the loader file if defined in the .vuepress/config.js file such as:

module.exports = ctx => ({
  markdown: {
    extractHeaders: ['h2','h3','h4','h5']
  }
})

if that is the case, I have looked at the this object and could not find it anywhere.

// we implement a manual cache here because this loader is chained before
// vue-loader, and will be applied on the same file multiple times when
// selecting the individual blocks.
Expand All @@ -42,7 +49,11 @@ module.exports = function (src) {

if (!isProd && !isServer) {
const inferredTitle = inferTitle(frontmatter.data, frontmatter.content)
const headers = extractHeaders(content, ['h2', 'h3'], markdown)
let headersToExtract = ['h2', 'h3']
if (config.markdown && config.markdown.extractHeaders) {
headersToExtract = this._siteConfig.markdown.extractHeaders
}
const headers = extractHeaders(content, headersToExtract, markdown)
delete frontmatter.content

// diff frontmatter and title, since they are not going to be part of the
Expand Down
1 change: 1 addition & 0 deletions packages/@vuepress/markdown-loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
],
"dependencies": {
"@vuepress/markdown": "^1.0.0-alpha.27",
"@vuepress/core": "^1.0.0-alpha.27",
"loader-utils": "^1.1.0"
},
"author": "Evan You",
Expand Down
24 changes: 19 additions & 5 deletions packages/docs/docs/theme/default-theme-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,20 @@ 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:
Expand Down Expand Up @@ -329,7 +343,7 @@ module.exports = {
```

::: warning Note
Unlike the [built-in search](#built-in-search) engine which works out of the box, [Algolia DocSearch](https://community.algolia.com/docsearch/) requires you to submit your site to them for indexing before it starts working.
Unlike the [built-in search](#built-in-search) engine which works out of the box, [Algolia DocSearch](https://community.algolia.com/docsearch/) requires you to submit your site to them for indexing before it starts working.
:::

For more options, refer to [Algolia DocSearch's documentation](https://github.com/algolia/docsearch#docsearch-options).
Expand Down Expand Up @@ -373,10 +387,10 @@ module.exports = {
themeConfig: {
serviceWorker: {
updatePopup: true // Boolean | Object, default to undefined.
// If set to true, the default text config will be:
// updatePopup: {
// message: "New content is available.",
// buttonText: "Refresh"
// If set to true, the default text config will be:
// updatePopup: {
// message: "New content is available.",
// buttonText: "Refresh"
// }
}
}
Expand Down