feat: add post toc
This commit is contained in:
@@ -9,12 +9,14 @@ import raw from 'rehype-raw'
|
||||
import html from 'rehype-stringify'
|
||||
import highlight from 'rehype-highlight'
|
||||
import etpl from 'etpl'
|
||||
import stringifyObject from 'stringify-object'
|
||||
import { readFileSync, writeFileSync, replaceExtSync } from './util'
|
||||
import demo from './remark-demo'
|
||||
import ref from './remark-ref'
|
||||
import anchor from './remark-anchor'
|
||||
import details from './remark-details'
|
||||
import custom from './remark-custom'
|
||||
import toc from './remark-extract-toc'
|
||||
import extractFrontmatter from './remark-extract-frontmatter'
|
||||
import rehypePreviewImg from './rehype-preview-img'
|
||||
import rehypeLink from './rehype-link'
|
||||
@@ -40,6 +42,7 @@ const md = remark()
|
||||
.use(demo)
|
||||
.use(extractFrontmatter)
|
||||
.use(slug)
|
||||
.use(toc)
|
||||
.use(remarkToRehype, { allowDangerousHTML: true })
|
||||
.use(raw)
|
||||
.use(rehypePreviewImg)
|
||||
@@ -67,14 +70,15 @@ export function renderDocToPage (file) {
|
||||
components = {},
|
||||
meta = {},
|
||||
deps = {},
|
||||
hasAlert = false
|
||||
hasAlert = false,
|
||||
toc
|
||||
} = data
|
||||
|
||||
Object.keys(deps || {}).forEach(dep => {
|
||||
add({ [dep]: { [src]: true } })
|
||||
})
|
||||
|
||||
let { layout, style = 'post' } = meta
|
||||
let { layout, style = 'post', toc: showToc } = meta
|
||||
let componentList = Object.keys(components)
|
||||
let demoList = Object.keys(demos)
|
||||
let result = renderPage({
|
||||
@@ -87,7 +91,7 @@ export function renderDocToPage (file) {
|
||||
demos: demoList.map(name => {
|
||||
return {
|
||||
name,
|
||||
src: join('@/components/demos', relative(DOCS_DIR, demos[name].path))
|
||||
src: join('@/components/demos', relative(DOCS_DIR, demos[name].filePath))
|
||||
}
|
||||
}),
|
||||
components: componentList,
|
||||
@@ -95,7 +99,8 @@ export function renderDocToPage (file) {
|
||||
boilerplate: demoList.length || componentList.length || hasAlert || style === 'post',
|
||||
layout,
|
||||
style,
|
||||
path: file
|
||||
path: file,
|
||||
toc: showToc !== false ? stringifyObject(toc[0].children) : null
|
||||
})
|
||||
|
||||
writeFileSync(dest, result)
|
||||
|
@@ -20,6 +20,7 @@ const KNOWN_SCOPES = Object.entries(KNOWN_SCOPES_CONFIG).reduce(
|
||||
export default function attacher () {
|
||||
return tree => {
|
||||
let scope = null
|
||||
|
||||
visit(tree, (node, index, parent) => {
|
||||
const { type, depth, children, value, position } = node
|
||||
if (type === 'heading') {
|
||||
|
49
one/build/remark-extract-toc.js
Normal file
49
one/build/remark-extract-toc.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import toString from 'mdast-util-to-string'
|
||||
import visit from 'unist-util-visit'
|
||||
|
||||
export default function attacher () {
|
||||
return transformer
|
||||
|
||||
function transformer (tree, vfile) {
|
||||
const headings = []
|
||||
|
||||
visit(tree, 'heading', onHeading)
|
||||
|
||||
vfile.data.toc = createTree(headings)
|
||||
|
||||
function onHeading (node) {
|
||||
const heading = {
|
||||
depth: node.depth,
|
||||
label: toString(node)
|
||||
}
|
||||
if (node.data !== undefined && node.data.id != null) {
|
||||
heading.value = `#${node.data.id}`
|
||||
}
|
||||
headings.push(heading)
|
||||
}
|
||||
|
||||
function createTree (headings) {
|
||||
const root = { depth: 0 }
|
||||
const parents = []
|
||||
let previous = root
|
||||
|
||||
headings.forEach((heading) => {
|
||||
if (heading.depth > previous.depth) {
|
||||
if (previous.children === undefined) {
|
||||
previous.children = []
|
||||
}
|
||||
parents.push(previous)
|
||||
} else if (heading.depth < previous.depth) {
|
||||
while (parents[parents.length - 1].depth >= heading.depth) {
|
||||
parents.pop()
|
||||
}
|
||||
}
|
||||
|
||||
parents[parents.length - 1].children.push(heading)
|
||||
previous = heading
|
||||
})
|
||||
|
||||
return root.children
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user