UNPKG

@nuxtjs/mdc

Version:
60 lines (59 loc) 1.62 kB
import { flattenNode, flattenNodeText } from "../utils/ast.js"; const TOC_TAGS = ["h2", "h3", "h4", "h5", "h6"]; const TOC_TAGS_DEPTH = TOC_TAGS.reduce((tags, tag) => { tags[tag] = Number(tag.charAt(tag.length - 1)); return tags; }, {}); const getHeaderDepth = (node) => TOC_TAGS_DEPTH[node.tag]; const getTocTags = (depth) => { if (depth < 1 || depth > 5) { console.log(`\`toc.depth\` is set to ${depth}. It should be a number between 1 and 5. `); depth = 1; } return TOC_TAGS.slice(0, depth); }; function nestHeaders(headers) { if (headers.length <= 1) { return headers; } const toc = []; let parent; headers.forEach((header) => { if (!parent || header.depth <= parent.depth) { header.children = []; parent = header; toc.push(header); } else { parent.children.push(header); } }); toc.forEach((header) => { if (header.children?.length) { header.children = nestHeaders(header.children); } else { delete header.children; } }); return toc; } export function generateFlatToc(body, options) { const { searchDepth, depth, title = "" } = options; const tags = getTocTags(depth); const headers = flattenNode(body, searchDepth).filter((node) => tags.includes(node.tag || "")); const links = headers.map((node) => ({ id: node.props?.id, depth: getHeaderDepth(node), text: flattenNodeText(node) })); return { title, searchDepth, depth, links }; } export function generateToc(body, options) { const toc = generateFlatToc(body, options); toc.links = nestHeaders(toc.links); return toc; }