Initial commit
This commit is contained in:
120
scripts/generate-sidebar.ts
Normal file
120
scripts/generate-sidebar.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
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 {
|
||||
title: string
|
||||
path: string
|
||||
items: SidebarItem[]
|
||||
}
|
||||
|
||||
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(): SidebarGroup[] {
|
||||
const sidebar: SidebarGroup[] = []
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
sidebar.push({
|
||||
title: entry.name,
|
||||
path: `/${entry.name}/`,
|
||||
items
|
||||
})
|
||||
}
|
||||
|
||||
return sidebar
|
||||
}
|
||||
|
||||
function updateConfig() {
|
||||
const sidebar = generateSidebar()
|
||||
|
||||
const outputPath = path.resolve(__dirname, '../docs/.vitepress/theme/data/sidebar.json')
|
||||
const outputDir = path.dirname(outputPath)
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true })
|
||||
}
|
||||
|
||||
fs.writeFileSync(outputPath, JSON.stringify(sidebar, null, 2))
|
||||
|
||||
console.log('Sidebar JSON generated:')
|
||||
console.log(JSON.stringify(sidebar, null, 2))
|
||||
}
|
||||
|
||||
updateConfig()
|
||||
Reference in New Issue
Block a user