UNPKG

vite-plugin-vitepress-auto-sidebar-whp98

Version:

The vite plugin that automatically generates sidebar data by scanning directories, based on vitepress

177 lines (170 loc) 5.09 kB
'use strict'; const path = require('path'); const fs = require('fs'); const c = require('picocolors'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } const c__default = /*#__PURE__*/_interopDefaultLegacy(c); const DEFAULT_IGNORE_FOLDER = ["scripts", "components", "assets", ".vitepress"]; function log(...info) { console.log(c__default.bold(c__default.cyan("[auto-sidebar]")), ...info); } function removePrefix(str, identifier) { return str.replace(identifier, ""); } let option; function getTitleFromFile(realFileName) { if (!fs.existsSync(realFileName)) { return void 0; } const fileExtension = realFileName.substring( realFileName.lastIndexOf(".") + 1 ); if (fileExtension !== "md" && fileExtension !== "MD") { return void 0; } const data = fs.readFileSync(realFileName, { encoding: "utf-8" }); const lines = data.split(/\r?\n/); for (let index = 0; index < lines.length; index++) { const line = lines[index]; if (line.includes("# ")) { return line.replace("# ", ""); } } return void 0; } function createSideBarItems(targetPath, ...reset) { const { ignoreIndexItem, deletePrefix, collapsed = false, sideBarItemsResolved, beforeCreateSideBarItems, ignoreList = [], titleFromFile = false } = option; const rawNode = fs.readdirSync(path.join(targetPath, ...reset)); const node = beforeCreateSideBarItems?.(rawNode) ?? rawNode; const currentDir = path.join(targetPath, ...reset); if (ignoreIndexItem && node.length === 1 && node[0] === "index.md") { return []; } const result = []; for (const fname of node) { if (fs.statSync(path.join(targetPath, ...reset, fname)).isDirectory()) { if (ignoreList.includes(fname)) { continue; } const items = createSideBarItems(path.join(targetPath), ...reset, fname); let text = fname; if (titleFromFile) { const title1 = getTitleFromFile(path.join(currentDir, fname, "index.md")); const title2 = getTitleFromFile(path.join(currentDir, fname, "index.MD")); const title3 = getTitleFromFile(path.join(currentDir, fname, fname + ".md")); if (title1) { text = title1; } else if (title2) { text = title2; } else if (title3) { text = title3; } } if (deletePrefix) { text = removePrefix(text, deletePrefix); } if (items.length > 0) { const sidebarItem = { text, items }; sidebarItem.collapsed = collapsed; result.push(sidebarItem); } } else { if (ignoreIndexItem && fname === "index.md" || /^-.*\.(md|MD)$/.test(fname)) { continue; } const fileName = fname.replace(/\.md$/, ""); let text = fileName; if (deletePrefix) { text = removePrefix(text, deletePrefix); } const realFileName = path.join(currentDir, fname); if (titleFromFile) { const title = getTitleFromFile(realFileName); if (title) { text = title; } } const item = { text, link: "/" + [...reset, `${fileName}.html`].join("/") }; result.push(item); } } return sideBarItemsResolved?.(result) ?? result; } function createSideBarGroups(targetPath, folder) { return [ { items: createSideBarItems(targetPath, folder) } ]; } function createSidebarMulti(path$1) { const { ignoreList = [], ignoreIndexItem = false, sideBarResolved } = option; const il = [...DEFAULT_IGNORE_FOLDER, ...ignoreList]; const data = {}; const node = fs.readdirSync(path$1).filter( (n) => fs.statSync(path.join(path$1, n)).isDirectory() && !il.includes(n) ); for (const k of node) { data[`/${k}/`] = createSideBarGroups(path$1, k); } if (ignoreIndexItem) { for (const i in data) { let obj = data[i]; obj = obj.filter((i2) => i2.items != null && i2.items.length > 0); if (obj.length === 0) { Reflect.deleteProperty(data, i); } } } return sideBarResolved?.(data) ?? data; } function VitePluginVitePressAutoSidebar(opt = {}) { return { name: "vite-plugin-vitepress-auto-sidebar", configureServer({ watcher, restart }) { const fsWatcher = watcher.add("*.md"); fsWatcher.on("all", async (event, path) => { if (event !== "change") { log(`${event} ${path}`); try { await restart(); log("update sidebar..."); } catch { log(`${event} ${path}`); log("update sidebar failed"); } } }); }, config(config) { option = opt; const { path: path$1 = "/docs" } = option; const docsPath = path.join(process.cwd(), path$1); config.vitepress.site.themeConfig.sidebar = createSidebarMulti(docsPath); log("injected sidebar data successfully"); return config; } }; } module.exports = VitePluginVitePressAutoSidebar;