From b034d7970d2ebd2aca9e1052437196fd1a4ae4ed Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Thu, 17 Nov 2022 15:58:53 +0800 Subject: [PATCH] website: add search data. #105 --- scripts/create.mjs | 25 ++++++++++++++++++++++--- scripts/index.mjs | 15 ++++++++++++--- scripts/utils/getTocsTree.mjs | 7 ++++++- scripts/utils/rehypeTitle.mjs | 2 ++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/scripts/create.mjs b/scripts/create.mjs index fd3b0e7..5a15825 100644 --- a/scripts/create.mjs +++ b/scripts/create.mjs @@ -3,6 +3,7 @@ import rehypeDocument from 'rehype-document'; import remarkGemoji from 'remark-gemoji'; import rehypeRaw from 'rehype-raw'; import rehypeAutolinkHeadings from 'rehype-autolink-headings'; +import { getCodeString } from 'rehype-rewrite'; import rehypeSlug from 'rehype-slug'; import { htmlTagAddAttri } from './nodes/htmlTagAddAttri.mjs'; import { footer } from './nodes/footer.mjs'; @@ -26,6 +27,14 @@ export function create(str = '', options = {}) { .replace(/\[([\s\S]*?)?\]\(([\s\S]*?)?\)/g, '$1') .replace(/\n/, ''); const subTitle = options.filename && !options.isHome ? `${options.filename} cheatsheet & ` : ''; + /** 用于搜索数据 */ + const detailData = { + title: title.replace(/\n/g, ''), + path: '', + intro: description, + icon: '', + sections: [], + }; const mdOptions = { showLineNumbers: false, hastNode: false, @@ -66,7 +75,10 @@ export function create(str = '', options = {}) { return plugins; }, rewrite: (node, index, parent) => { - rehypeTitle(node, options.filename); + const iconName = rehypeTitle(node, options.filename); + if (iconName) { + detailData.icon = iconName; + } homeCardIcons(node, parent, options.isHome); tooltips(node, index, parent); htmlTagAddAttri(node, options); @@ -77,6 +89,13 @@ export function create(str = '', options = {}) { if (!options.isHome) { const tocsMenus = getTocsTitleNode([...tocsData]); node.children = addTocsInWarp([...tocsData], getTocsTitleNodeWarpper(tocsMenus)); + tocsMenus.forEach((menu) => { + detailData.sections.push({ + a: menu?.properties?.href, + t: getCodeString(menu.children), + l: menu?.properties['data-num'], + }); + }); } else { node.children = tocsData; } @@ -87,6 +106,6 @@ export function create(str = '', options = {}) { } }, }; - - return markdown(str, mdOptions); + const htmlStr = markdown(str, mdOptions); + return { html: htmlStr, data: detailData }; } diff --git a/scripts/index.mjs b/scripts/index.mjs index 13d0def..79c74f9 100644 --- a/scripts/index.mjs +++ b/scripts/index.mjs @@ -5,6 +5,8 @@ import { create } from './create.mjs'; export const OUTOUT = path.resolve(process.cwd(), 'dist'); export const DOCS = path.resolve(process.cwd(), 'docs'); +/** 搜索数据路径 */ +export const SEARCH_DATA = path.resolve(OUTOUT, 'data.json'); export async function createHTML(files = [], num = 0) { const dataFile = files[num]; @@ -25,8 +27,7 @@ export async function createHTML(files = [], num = 0) { .replace(/.md$/, '.html'); await fs.ensureDir(path.dirname(outputHTMLPath)); - - const html = create(mdstr.toString(), { + const options = { filename: path.basename(outputHTMLPath, '.html'), isHome: /README.md$/.test(path.relative(process.cwd(), dataFile.path)), githubURL, @@ -35,7 +36,14 @@ export async function createHTML(files = [], num = 0) { path.relative(path.dirname(outputHTMLPath), path.resolve(OUTOUT, 'style/style.css')), path.relative(path.dirname(outputHTMLPath), path.resolve(OUTOUT, 'style/katex.css')), ], - }); + }; + const { html, data } = create(mdstr.toString(), options); + if (!options.isHome) { + const searchData = await fs.readJSON(SEARCH_DATA); + data.path = path.relative(OUTOUT, outputHTMLPath); + searchData[options.filename] = data; + await fs.writeJSON(SEARCH_DATA, searchData, { spaces: 2 }); + } await fs.writeFile(outputHTMLPath, html); console.log(`♻️ \x1b[32;1m ${path.relative(OUTOUT, outputHTMLPath)} \x1b[0m`); createHTML(files, num); @@ -45,6 +53,7 @@ export async function run() { await fs.ensureDir(OUTOUT); await fs.emptyDir(OUTOUT); await fs.ensureDir(path.resolve(OUTOUT, 'style')); + await fs.writeFile(SEARCH_DATA, '{}'); await fs.copy(path.resolve(process.cwd(), 'scripts/style'), path.resolve(OUTOUT, 'style')); const files = await recursiveReaddirFiles(process.cwd(), { ignored: /\/(node_modules|\.git)/, diff --git a/scripts/utils/getTocsTree.mjs b/scripts/utils/getTocsTree.mjs index f2ccafc..1b81a2c 100644 --- a/scripts/utils/getTocsTree.mjs +++ b/scripts/utils/getTocsTree.mjs @@ -10,7 +10,12 @@ 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 props = { + 'aria-hidden': 'true', + class: `leve${num} tocs-link`, + 'data-num': num, + href: '#' + (properties.id || ''), + }; const title = getCodeString(children || []); result.push({ tagName: 'a', type, properties: props, children: [{ type: 'text', value: title || ' ' }] }); } else if (children?.length > 0) { diff --git a/scripts/utils/rehypeTitle.mjs b/scripts/utils/rehypeTitle.mjs index 1f21320..8345a02 100644 --- a/scripts/utils/rehypeTitle.mjs +++ b/scripts/utils/rehypeTitle.mjs @@ -10,6 +10,8 @@ export function rehypeTitle(node, iconName) { if (iconExist) { const svgNode = getSVGNode(iconPath); node.children = [...svgNode, ...node.children]; + // 如果存在返回图标名称 + return iconName; } else { const svgNode = getSVGNode(iconDefaultPath); node.children = [...svgNode, ...node.children];