reference/scripts/utils/getTocsTree.mjs

161 lines
4.8 KiB
JavaScript
Raw Normal View History

import path from 'path';
2022-10-29 00:24:39 +08:00
import { getCodeString } from 'rehype-rewrite';
2022-09-30 23:18:13 +08:00
import { panelAddNumber } from './panelAddNumber.mjs';
import { getChilds, getHeader } from './childs.mjs';
import { ICONS_PATH, getSVGNode } from './getSVGNode.mjs';
export const titleNum = (tagName = '') => Number(tagName.replace(/^h/, ''));
export function getTocsTitleNode(arr = [], result = []) {
arr.forEach(({ tagName, type, properties, children }) => {
if (/^h[23456]/.test(tagName)) {
2022-10-29 00:24:39 +08:00
const num = titleNum(tagName);
2022-11-17 15:58:53 +08:00
const props = {
'aria-hidden': 'true',
class: `leve${num} tocs-link`,
'data-num': num,
href: '#' + (properties.id || ''),
};
2022-10-29 00:24:39 +08:00
const title = getCodeString(children || []);
result.push({ tagName: 'a', type, properties: props, children: [{ type: 'text', value: title || ' ' }] });
} else if (children?.length > 0) {
2022-10-29 00:24:39 +08:00
result = result.concat(getTocsTitleNode(children));
}
});
2022-10-29 00:24:39 +08:00
return result;
}
export function addTocsInWarp(tocsData = [], menuData, isDone = false) {
const childs = tocsData.map((item) => {
if (item.properties?.class?.includes('h1wrap-body')) {
isDone = true;
}
if (!isDone && item.children) {
2022-10-29 00:24:39 +08:00
item.children = addTocsInWarp([...item.children], menuData, isDone);
}
2022-10-29 00:24:39 +08:00
return item;
});
if (isDone) {
childs.splice(1, 0, menuData);
}
2022-10-29 00:24:39 +08:00
return childs;
}
export const getTocsTitleNodeWarpper = (children = []) => {
const iconPath = path.resolve(ICONS_PATH, `menu.svg`);
const svgNode = getSVGNode(iconPath);
return {
type: 'element',
tagName: 'div',
properties: {
class: 'menu-tocs',
},
children: [
{
type: 'element',
tagName: 'div',
properties: {
class: 'menu-btn',
},
2022-10-29 00:24:39 +08:00
children: [...svgNode],
},
{
type: 'element',
tagName: 'div',
properties: {
class: 'menu-modal',
},
2022-10-29 00:24:39 +08:00
children: children,
},
],
};
};
2022-09-30 23:18:13 +08:00
/** Markdown 文档转成树形结构 */
export function getTocsTree(arr = [], result = []) {
const data = panelAddNumber(arr);
2022-10-29 00:24:39 +08:00
2022-09-30 23:18:13 +08:00
let n = 0;
let level = -1;
while (n < data.length) {
const toc = data[n];
if (level === -1) {
level = toc.number;
}
if (toc.number === level && titleNum(toc.tagName) === level) {
2022-09-30 23:18:13 +08:00
const header = getHeader(data.slice(n), level);
2022-10-31 15:18:50 +08:00
const childs = getChilds([...data.slice(n + 1)], level);
const resultChilds = getTocsTree(childs);
2022-09-30 23:18:13 +08:00
const wrapCls = ['wrap'];
const headerCls = ['wrap-header', `h${level}wrap`];
2022-10-31 15:18:50 +08:00
wrapCls.push(`h${level}body-${resultChilds.length === 0 ? 'not-' : ''}exist`);
2022-09-30 23:18:13 +08:00
if (level === 1) wrapCls.push('max-container');
const wrapStyle = toc.properties['wrap-style'];
2022-10-29 00:24:39 +08:00
delete toc.properties['wrap-style'];
2022-09-30 23:18:13 +08:00
const wrapClass = toc.properties['wrap-class'];
if (wrapClass) wrapCls.push(wrapClass);
delete toc.properties['wrap-class'];
2022-10-31 16:38:04 +08:00
let panle = {
2022-09-30 23:18:13 +08:00
type: 'element',
tagName: 'div',
properties: { class: wrapCls, style: wrapStyle },
children: [
{
type: 'element',
tagName: level === 1 ? 'header' : 'div',
properties: { class: headerCls },
children: [
toc,
{
type: 'element',
tagName: 'div',
2022-11-13 23:20:45 +08:00
properties: { class: ['wrap-body'] },
2022-10-29 00:24:39 +08:00
children: [...header],
},
2022-09-30 23:18:13 +08:00
],
2022-10-29 00:24:39 +08:00
},
2022-09-30 23:18:13 +08:00
],
2022-10-29 00:24:39 +08:00
};
2022-10-31 16:38:04 +08:00
if (titleNum(toc.tagName) > 3) {
panle = [toc, ...header];
}
if (resultChilds.length > -1) {
2022-09-30 23:18:13 +08:00
const bodyStyle = toc.properties['body-style'];
2022-10-29 00:24:39 +08:00
delete toc.properties['body-style'];
2022-09-30 23:18:13 +08:00
const bodyClass = toc.properties['body-class'];
2022-10-29 00:24:39 +08:00
delete toc.properties['body-class'];
2022-10-31 16:38:04 +08:00
if (Array.isArray(panle)) {
panle = panle.concat(resultChilds);
} else if (panle.children) {
if (titleNum(toc.tagName) < 3) {
panle.children = panle.children.concat({
type: 'element',
tagName: 'div',
properties: { class: [`h${level}wrap-body`, bodyClass], style: bodyStyle },
children: [...resultChilds],
});
} else {
2022-11-13 23:20:45 +08:00
panle.children[0].children[1].properties?.class.push(bodyClass);
panle.children[0].children[1].children = panle.children[0].children[1].children.concat(resultChilds);
2022-11-13 23:20:45 +08:00
if (panle.children[0].children[1].properties && bodyStyle) {
const initStyle = panle.children[0].children[1].properties?.style || '';
panle.children[0].children[1].properties.style = initStyle + bodyStyle;
}
}
2022-10-31 16:38:04 +08:00
}
}
if (Array.isArray(panle)) {
result = result.concat(panle);
} else {
result.push(panle);
2022-09-30 23:18:13 +08:00
}
}
n++;
}
return result;
}