spaCy/website/plugins/remarkWrapSections.mjs

67 lines
2.3 KiB
JavaScript

/**
* 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
*/
import { visit } from 'unist-util-visit'
const defaultOptions = {
element: 'section',
prefix: 'section-',
depth: 2,
slugify: true,
}
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 = {})
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: 'section',
children,
data: { hName: options.element, hProperties: { id: sectionId } },
}
newTree.push(wrapperNode)
}
}
tree.children = newTree
}
return tree
}
return transformer
}
export default remarkWrapSection