mirror of
https://github.com/explosion/spaCy.git
synced 2024-11-12 04:38:28 +03:00
76 lines
2.6 KiB
JavaScript
76 lines
2.6 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
|
||
|
*/
|
||
|
|
||
|
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
|