172 lines
4.3 KiB
TypeScript
172 lines
4.3 KiB
TypeScript
import fs from 'fs'
|
|
import path from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __filename = fileURLToPath(import.meta.url)
|
|
const __dirname = path.dirname(__filename)
|
|
const docsDir = path.resolve(__dirname, '../docs')
|
|
|
|
interface SidebarItem {
|
|
text: string
|
|
link: string
|
|
}
|
|
|
|
interface SidebarGroup {
|
|
text: string
|
|
items: SidebarItem[]
|
|
}
|
|
|
|
interface SidebarConfig {
|
|
[path: string]: SidebarGroup[]
|
|
}
|
|
|
|
function getTitleFromFile(filePath: string): string {
|
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
|
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
|
|
if (frontmatterMatch) {
|
|
const titleMatch = frontmatterMatch[1].match(/title:\s*["']?([^"'\n]+)["']?/)
|
|
if (titleMatch) {
|
|
return titleMatch[1].trim()
|
|
}
|
|
}
|
|
|
|
const h1Match = content.match(/^#\s+(.+)$/m)
|
|
if (h1Match) {
|
|
return h1Match[1].trim()
|
|
}
|
|
|
|
return path.basename(filePath, '.md')
|
|
}
|
|
|
|
function getSidebarOrder(filePath: string, fileName: string): number {
|
|
if (fileName === 'index.md') {
|
|
return 0
|
|
}
|
|
|
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
|
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
|
|
if (frontmatterMatch) {
|
|
const orderMatch = frontmatterMatch[1].match(/sidebarOrder:\s*(\d+)/)
|
|
if (orderMatch) {
|
|
return parseInt(orderMatch[1], 10)
|
|
}
|
|
}
|
|
|
|
return 999
|
|
}
|
|
|
|
function generateSidebar(): SidebarConfig {
|
|
const sidebar: SidebarConfig = {}
|
|
|
|
const entries = fs.readdirSync(docsDir, { withFileTypes: true })
|
|
|
|
for (const entry of entries) {
|
|
if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === '.vitepress') {
|
|
continue
|
|
}
|
|
|
|
const dirPath = path.join(docsDir, entry.name)
|
|
const files = fs.readdirSync(dirPath)
|
|
.filter(f => f.endsWith('.md'))
|
|
.map(f => ({
|
|
name: f,
|
|
path: path.join(dirPath, f),
|
|
order: getSidebarOrder(path.join(dirPath, f), f)
|
|
}))
|
|
.sort((a, b) => a.order - b.order)
|
|
|
|
if (files.length === 0) continue
|
|
|
|
const items: SidebarItem[] = files.map(file => {
|
|
let title = getTitleFromFile(file.path)
|
|
if (file.name === 'index.md') {
|
|
title = '概述'
|
|
}
|
|
const linkPath = file.name === 'index.md'
|
|
? `/${entry.name}/`
|
|
: `/${entry.name}/${file.name.replace('.md', '')}`
|
|
|
|
return {
|
|
text: title,
|
|
link: linkPath
|
|
}
|
|
})
|
|
|
|
const dirName = entry.name.charAt(0).toUpperCase() + entry.name.slice(1)
|
|
|
|
sidebar[`/${entry.name}/`] = [
|
|
{
|
|
text: `${dirName} 笔记`,
|
|
items
|
|
}
|
|
]
|
|
}
|
|
|
|
return sidebar
|
|
}
|
|
|
|
function generateNav(sidebar: SidebarConfig) {
|
|
return Object.keys(sidebar).map(p => {
|
|
const name = p.replace(/\//g, '').charAt(0).toUpperCase() + p.replace(/\//g, '').slice(1)
|
|
return {
|
|
text: name,
|
|
link: p
|
|
}
|
|
})
|
|
}
|
|
|
|
function formatObject(obj: unknown, indent: number = 0): string {
|
|
const spaces = ' '.repeat(indent)
|
|
const innerSpaces = ' '.repeat(indent + 2)
|
|
|
|
if (Array.isArray(obj)) {
|
|
if (obj.length === 0) return '[]'
|
|
const items = obj.map(item => formatObject(item, indent + 2))
|
|
return `[\n${items.map(i => innerSpaces + i).join(',\n')}\n${spaces}]`
|
|
}
|
|
|
|
if (typeof obj === 'object' && obj !== null) {
|
|
const entries = Object.entries(obj)
|
|
if (entries.length === 0) return '{}'
|
|
const items = entries.map(([key, value]) => {
|
|
const formattedValue = formatObject(value, indent + 2)
|
|
return `${innerSpaces}'${key}': ${formattedValue}`
|
|
})
|
|
return `{\n${items.join(',\n')}\n${spaces}}`
|
|
}
|
|
|
|
if (typeof obj === 'string') {
|
|
return `'${obj}'`
|
|
}
|
|
|
|
return String(obj)
|
|
}
|
|
|
|
function updateConfig() {
|
|
const sidebar = generateSidebar()
|
|
const nav = generateNav(sidebar)
|
|
|
|
const configPath = path.resolve(__dirname, '../docs/.vitepress/config.mts')
|
|
let config = fs.readFileSync(configPath, 'utf-8')
|
|
|
|
const sidebarStr = formatObject(sidebar, 4)
|
|
const navStr = formatObject(nav, 4)
|
|
|
|
const sidebarRegex = /sidebar:\s*\{\s*\n\s*\}/
|
|
const navRegex = /nav:\s*\[\s*\n\s*\]/
|
|
|
|
config = config.replace(sidebarRegex, `sidebar: ${sidebarStr}`)
|
|
config = config.replace(navRegex, `nav: ${navStr}`)
|
|
|
|
fs.writeFileSync(configPath, config)
|
|
|
|
console.log('Sidebar config updated:')
|
|
console.log(JSON.stringify(sidebar, null, 2))
|
|
console.log('\nNav config updated:')
|
|
console.log(JSON.stringify(nav, null, 2))
|
|
}
|
|
|
|
updateConfig()
|