mirror of
https://github.com/Nanaloveyuki/BitLogger.git
synced 2026-07-24 00:42:18 +00:00
120 lines
3.8 KiB
JavaScript
120 lines
3.8 KiB
JavaScript
import { readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
import { basename, extname, resolve } from 'node:path'
|
|
|
|
import matter from 'gray-matter'
|
|
|
|
const root = process.cwd()
|
|
const docsDir = resolve(root, 'docs')
|
|
const apiDir = resolve(docsDir, 'api')
|
|
const changesDir = resolve(docsDir, 'changes')
|
|
const outFile = resolve(docsDir, '.vitepress', 'generated', 'docs-data.mjs')
|
|
|
|
function splitWords(input) {
|
|
return input
|
|
.split(/[^A-Za-z0-9]+/)
|
|
.map(part => part.trim())
|
|
.filter(Boolean)
|
|
}
|
|
|
|
function formatWord(word) {
|
|
const lower = word.toLowerCase()
|
|
if (lower === 'api') return 'API'
|
|
if (lower === 'json') return 'JSON'
|
|
if (lower === 'js') return 'JS'
|
|
if (lower === 'wasm') return 'WASM'
|
|
if (lower === 'llvm') return 'LLVM'
|
|
return lower.charAt(0).toUpperCase() + lower.slice(1)
|
|
}
|
|
|
|
function humanize(input) {
|
|
const words = splitWords(input)
|
|
if (words.length === 0) return input
|
|
return words.map(formatWord).join(' ')
|
|
}
|
|
|
|
function extractTitle(source, fallback) {
|
|
const heading = source.match(/^##\s+(.+)$/m)?.[1]?.trim()
|
|
return humanize(heading ?? fallback)
|
|
}
|
|
|
|
function readApiDocs() {
|
|
const entries = readdirSync(apiDir, { withFileTypes: true })
|
|
.filter(entry => entry.isFile())
|
|
.filter(entry => extname(entry.name) === '.md')
|
|
.filter(entry => !entry.name.startsWith('.'))
|
|
.map(entry => {
|
|
const file = entry.name
|
|
const slug = basename(file, '.md')
|
|
const source = readFileSync(resolve(apiDir, file), 'utf8')
|
|
const parsed = matter(source)
|
|
const data = parsed.data
|
|
const keywords = Array.isArray(data['key-word']) ? data['key-word'].map(String) : []
|
|
return {
|
|
file,
|
|
slug,
|
|
title: extractTitle(parsed.content, data.name ?? slug),
|
|
name: String(data.name ?? slug),
|
|
group: String(data.group ?? 'misc'),
|
|
category: String(data.category ?? 'misc'),
|
|
description: String(data.description ?? ''),
|
|
updateTime: data['update-time'] == null ? '' : String(data['update-time']),
|
|
keywords,
|
|
link: `/api/${slug}`,
|
|
}
|
|
})
|
|
.sort((left, right) => left.title.localeCompare(right.title))
|
|
|
|
const grouped = [...new Set(entries.map(entry => entry.group))]
|
|
.sort((left, right) => humanize(left).localeCompare(humanize(right)))
|
|
.map(group => {
|
|
const items = entries.filter(entry => entry.group === group)
|
|
const categories = [...new Set(items.map(entry => entry.category))]
|
|
.sort((left, right) => humanize(left).localeCompare(humanize(right)))
|
|
.map(category => ({
|
|
id: category,
|
|
label: humanize(category),
|
|
entries: items.filter(entry => entry.category === category),
|
|
}))
|
|
|
|
return {
|
|
id: group,
|
|
label: humanize(group),
|
|
entryCount: items.length,
|
|
categories,
|
|
}
|
|
})
|
|
|
|
const categorySummaries = [...new Set(entries.map(entry => entry.category))]
|
|
.sort((left, right) => humanize(left).localeCompare(humanize(right)))
|
|
.map(category => ({
|
|
id: category,
|
|
label: humanize(category),
|
|
entryCount: entries.filter(entry => entry.category === category).length,
|
|
}))
|
|
|
|
return {
|
|
entries,
|
|
groups: grouped,
|
|
categories: categorySummaries,
|
|
}
|
|
}
|
|
|
|
function readChanges() {
|
|
return readdirSync(changesDir, { withFileTypes: true })
|
|
.filter(entry => entry.isFile())
|
|
.filter(entry => extname(entry.name) === '.md')
|
|
.filter(entry => entry.name !== 'index.md')
|
|
.map(entry => basename(entry.name, '.md'))
|
|
.sort((left, right) => right.localeCompare(left, undefined, { numeric: true }))
|
|
.map(version => ({
|
|
version,
|
|
link: `/changes/${version}`,
|
|
}))
|
|
}
|
|
|
|
const api = readApiDocs()
|
|
const changes = readChanges()
|
|
|
|
const output = `export const docsData = ${JSON.stringify({ api, changes }, null, 2)}\n`
|
|
writeFileSync(outFile, output)
|