spaCy/website/src/plugins/remark-wrap-section.js

76 lines
2.6 KiB
JavaScript
Raw Normal View History

/**
* Check the tree for headlines of a certain depth and wrap the headline and
* all content up to the next headline in a section.
* Based on: https://github.com/luhmann/tufte-markdown
*/
const visit = require('unist-util-visit')
const slugify = require('@sindresorhus/slugify')
const defaultOptions = {
element: 'section',
prefix: 'section-',
depth: 2,
slugify: true,
}
function slugifyNode(node) {
if (node.children.length && node.children[0].type === 'text') {
return slugify(node.children[0].value)
}
return null
}
function remarkWrapSection(userOptions = {}) {
const options = Object.assign({}, defaultOptions, userOptions)
function transformer(tree) {
const headingsMap = []
const newTree = []
visit(tree, 'import', node => {
// For compatibility with MDX / gatsby-mdx, make sure import nodes
// are not moved further down into children (which means they're not
// recognized and interpreted anymore). Add them to the very start
// of the tree.
newTree.push(node)
})
visit(tree, 'heading', (node, index) => {
if (node.depth === options.depth) {
const data = node.data || (node.data = {})
const hProps = data.hProperties || (data.hProperties = {})
hProps.id = hProps.id ? hProps.id : slugifyNode(node)
headingsMap.push({ index, id: hProps.id })
}
})
if (headingsMap.length) {
for (let index = 0; index <= headingsMap.length; index++) {
const sectionStartIndex = index === 0 ? 0 : headingsMap[index - 1].index
const sectionEndIndex =
index === headingsMap.length ? tree.children.length : headingsMap[index].index
const children = tree.children
.slice(sectionStartIndex, sectionEndIndex)
.filter(node => node.type !== 'import')
if (children.length) {
const headingId = index === 0 ? 0 : headingsMap[index - 1].id
const sectionId = headingId ? options.prefix + headingId : undefined
const wrapperNode = {
type: 'paragraph',
children,
data: { hName: options.element, hProperties: { id: sectionId } },
}
newTree.push(wrapperNode)
}
}
tree.children = newTree
}
return tree
}
return transformer
}
module.exports = remarkWrapSection