156 lines
4.8 KiB
JavaScript
156 lines
4.8 KiB
JavaScript
import path from 'path';
|
|
import { getCodeString } from 'rehype-rewrite';
|
|
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)) {
|
|
const num = titleNum(tagName);
|
|
const props = { 'aria-hidden': 'true', class: `leve${num} tocs-link`, href: '#' + (properties.id || '') };
|
|
const title = getCodeString(children || []);
|
|
result.push({ tagName: 'a', type, properties: props, children: [{ type: 'text', value: title || ' ' }] });
|
|
} else if (children?.length > 0) {
|
|
result = result.concat(getTocsTitleNode(children));
|
|
}
|
|
});
|
|
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) {
|
|
item.children = addTocsInWarp([...item.children], menuData, isDone);
|
|
}
|
|
return item;
|
|
});
|
|
if (isDone) {
|
|
childs.splice(1, 0, menuData);
|
|
}
|
|
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',
|
|
},
|
|
children: [...svgNode],
|
|
},
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
properties: {
|
|
class: 'menu-modal',
|
|
},
|
|
children: children,
|
|
},
|
|
],
|
|
};
|
|
};
|
|
|
|
/** Markdown 文档转成树形结构 */
|
|
export function getTocsTree(arr = [], result = []) {
|
|
const data = panelAddNumber(arr);
|
|
|
|
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) {
|
|
const header = getHeader(data.slice(n), level);
|
|
const childs = getChilds([...data.slice(n + 1)], level);
|
|
const resultChilds = getTocsTree(childs);
|
|
const wrapCls = ['wrap'];
|
|
const headerCls = ['wrap-header', `h${level}wrap`];
|
|
wrapCls.push(`h${level}body-${resultChilds.length === 0 ? 'not-' : ''}exist`);
|
|
|
|
if (level === 1) wrapCls.push('max-container');
|
|
const wrapStyle = toc.properties['wrap-style'];
|
|
delete toc.properties['wrap-style'];
|
|
const wrapClass = toc.properties['wrap-class'];
|
|
if (wrapClass) wrapCls.push(wrapClass);
|
|
delete toc.properties['wrap-class'];
|
|
let panle = {
|
|
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',
|
|
properties: { class: ['wrap-body'] },
|
|
children: [...header],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
if (titleNum(toc.tagName) > 3) {
|
|
panle = [toc, ...header];
|
|
}
|
|
if (resultChilds.length > -1) {
|
|
const bodyStyle = toc.properties['body-style'];
|
|
delete toc.properties['body-style'];
|
|
const bodyClass = toc.properties['body-class'];
|
|
delete toc.properties['body-class'];
|
|
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 {
|
|
panle.children[0].children[1].properties?.class.push(bodyClass);
|
|
panle.children[0].children[1].children = panle.children[0].children[1].children.concat(resultChilds);
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (Array.isArray(panle)) {
|
|
result = result.concat(panle);
|
|
} else {
|
|
result.push(panle);
|
|
}
|
|
}
|
|
|
|
n++;
|
|
}
|
|
return result;
|
|
}
|