| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- 'use strict'
- module.exports = search
- var toString = require('mdast-util-to-string')
- var visit = require('unist-util-visit')
- var is = require('unist-util-is')
- var slugs = require('github-slugger')()
- var HEADING = 'heading'
- // Search a node for a location.
- function search(root, expression, settings) {
- var length = root.children.length
- var depth = null
- var lookingForToc = expression !== null
- var maxDepth = settings.maxDepth || 6
- var parents = settings.parents || root
- var map = []
- var headingIndex
- var closingIndex
- if (!lookingForToc) {
- headingIndex = -1
- }
- slugs.reset()
- // Visit all headings in `root`. We `slug` all headings (to account for
- // duplicates), but only create a TOC from top-level headings.
- visit(root, HEADING, onheading)
- if (headingIndex && !closingIndex) {
- closingIndex = length + 1
- }
- if (headingIndex === undefined) {
- headingIndex = -1
- closingIndex = -1
- map = []
- }
- return {index: headingIndex, endIndex: closingIndex, map: map}
- function onheading(child, index, parent) {
- var value = toString(child)
- var id = child.data && child.data.hProperties && child.data.hProperties.id
- if (!is(parents, parent)) {
- return
- }
- if (lookingForToc) {
- if (isClosingHeading(child, depth)) {
- closingIndex = index
- lookingForToc = false
- }
- if (isOpeningHeading(child, depth, expression)) {
- headingIndex = index + 1
- depth = child.depth
- }
- }
- if (!lookingForToc && value && child.depth <= maxDepth) {
- map.push({depth: child.depth, value: value, id: slugs.slug(id || value)})
- }
- }
- }
- // Check if `node` is the main heading.
- function isOpeningHeading(node, depth, expression) {
- return (
- depth === null &&
- node &&
- node.type === HEADING &&
- expression.test(toString(node))
- )
- }
- // Check if `node` is the next heading.
- function isClosingHeading(node, depth) {
- return depth && node && node.type === HEADING && node.depth <= depth
- }
|