reference/scripts/create.mjs

148 lines
4.3 KiB
JavaScript
Raw Normal View History

2022-09-26 09:52:59 +08:00
import markdown from '@wcj/markdown-to-html';
import rehypeDocument from 'rehype-document';
import rehypeFormat from 'rehype-format';
2022-09-26 17:13:24 +08:00
import { rehypeUrls } from './nodes/rehypeUrls.mjs';
import { htmlTagAddAttri } from './nodes/htmlTagAddAttri.mjs';
2022-09-26 22:14:52 +08:00
import { footer } from './nodes/footer.mjs';
2022-09-27 23:09:51 +08:00
import { header } from './nodes/header.mjs';
2022-09-26 09:52:59 +08:00
/** 标记 Number */
function panelAddNumber(arr = [], result = []) {
let n = 0;
let level = -1;
while (n < arr.length) {
const toc = arr[n];
const titleNum = Number(toc?.tagName?.replace(/^h/, ''));
if (titleNum && titleNum > -1) {
level = titleNum;
}
if (toc) {
result.push({ ...toc, number: level })
}
n++;
}
return result
}
function getChilds(data = [], level, result = []) {
for (let i = 1; i <= data.length; i++) {
const titleNum = Number(data[i]?.tagName?.replace(/^h/, ''));
if (titleNum && titleNum === level) break;
result.push(data[i]);
}
return result;
}
/** 获取 Heading 到下一个 Heading 之间的内容*/
function getHeader(data = [], level, result = []) {
for (let i = 1; i <= data.length; i++) {
if (/^h\d$/.test(data[i]?.tagName) || data[i]?.number !== level) break;
result.push(data[i]);
}
return result;
}
/** 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;
}
const titleNum = Number(toc.tagName?.replace(/^h/, ''));
if (toc.number === level && titleNum === level) {
const header = getHeader(data.slice(n), level);
const warpCls = ['warp'];
const headerCls = ['warp-header', `h${level}warp`];
if (level === 1) warpCls.push('max-container');
const warpStyle = toc.properties['data-warp-style'];
delete toc.properties['data-warp-style']
2022-09-26 22:14:52 +08:00
const warpClass = toc.properties['warp-class'];
if (warpClass) warpCls.push(warpClass);
delete toc.properties['warp-class'];
2022-09-26 09:52:59 +08:00
const panle = {
type: 'element',
tagName: 'div',
properties: { class: warpCls, style: warpStyle },
children: [
{
type: 'element',
tagName: level === 1 ? 'header' : 'div',
properties: { class: headerCls },
children: [
toc,
{
type: 'element',
tagName: 'div',
properties: { class: 'warp-body' },
children: [
...header
],
}
],
}
],
}
const childs = getChilds([...data.slice(n + 1)], level);
const resultChilds = getTocsTree(childs);
if (resultChilds.length > 0) {
2022-09-26 22:14:52 +08:00
const bodyStyle = toc.properties['data-body-style'];
delete toc.properties['data-body-style']
const bodyClass = toc.properties['body-class'];
delete toc.properties['body-class']
2022-09-26 09:52:59 +08:00
panle.children = panle.children.concat({
type: 'element',
tagName: 'div',
2022-09-26 22:14:52 +08:00
properties: { class: [`h${level}warp-body`, bodyClass], style: bodyStyle },
2022-09-26 09:52:59 +08:00
children: [...resultChilds]
});
}
result.push(panle);
}
n++;
}
return result;
}
export function create(str = '', options = {}) {
2022-09-27 23:09:51 +08:00
let title = str.match(/[^===]+(?=[===])/g);
let description = str.match(/\n==={1,}\n+([\s\S]*?)\n/g);
title = title[0] || '';
description = (description[0] || '').replace(/^\n[=\n]+/, '').replace(/\[([\s\S]*?)?\]\(([\s\S]*?)?\)/g, '$1').replace(/\n/, '');
2022-09-26 09:52:59 +08:00
const mdOptions = {
hastNode: false,
remarkPlugins: [],
rehypePlugins: [
rehypeFormat,
[rehypeDocument, {
2022-09-27 23:09:51 +08:00
title: `${title ? `${title} & ` : ''} Quick Reference`,
2022-09-26 09:52:59 +08:00
css: [ ...options.css ],
meta: [
2022-09-27 23:09:51 +08:00
{ description: `${description}为开发人员分享快速参考备忘单。` },
2022-09-26 09:52:59 +08:00
{ keywords: 'Quick,Reference' }
]
}],
],
rewrite: (node, index, parent) => {
2022-09-27 23:09:51 +08:00
htmlTagAddAttri(node, options);
2022-09-26 17:13:24 +08:00
rehypeUrls(node);
2022-09-26 09:52:59 +08:00
if (node.type === 'element' && node.tagName === 'body') {
node.children = getTocsTree([ ...node.children ]);
2022-09-27 23:09:51 +08:00
node.children.unshift(header(options));
2022-09-26 22:14:52 +08:00
node.children.push(footer());
2022-09-26 09:52:59 +08:00
}
}
}
return markdown(str, mdOptions);
}