You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.3 KiB
TypeScript
97 lines
2.3 KiB
TypeScript
import type { DefaultTheme } from 'vitepress'
|
|
import { normalize } from 'vitepress/dist/client/shared'
|
|
import faqCategories from '../../../website/faq/categories.json'
|
|
|
|
import { readFileSync } from 'fs'
|
|
import { join, basename } from 'path'
|
|
import fg from 'fast-glob'
|
|
import matter from 'gray-matter'
|
|
|
|
declare interface Options {
|
|
root: string | Array<string>
|
|
ignore?: Array<string>
|
|
collapsed?: boolean
|
|
}
|
|
|
|
export default class Sidebar {
|
|
static generateSidebar(
|
|
options: Options
|
|
): DefaultTheme.SidebarItem[] {
|
|
const entries = fg.sync(options.root, options)
|
|
|
|
return entries
|
|
.map(path => Sidebar.getData(path, options))
|
|
.sort((a, b) => (a.text && b.text) ? a.text.localeCompare(b.text) : 0)
|
|
}
|
|
|
|
static generateSidebarItem(
|
|
items: DefaultTheme.SidebarItem[],
|
|
path: string,
|
|
): DefaultTheme.SidebarItem[] {
|
|
items = items.map(({ text, link, items }) => {
|
|
const item: DefaultTheme.SidebarItem = { text }
|
|
|
|
if (link) {
|
|
item.link = join(path, link).replace(/\\/g, '/')
|
|
}
|
|
|
|
if (items) {
|
|
item.collapsed = true
|
|
item.items = Sidebar.generateSidebarItem(items, path)
|
|
}
|
|
|
|
return item
|
|
})
|
|
|
|
return items
|
|
}
|
|
|
|
static getData(
|
|
path: string,
|
|
options?: Partial<Options>
|
|
): DefaultTheme.SidebarItem {
|
|
const src = readFileSync(path, 'utf-8')
|
|
const { data } = matter(src)
|
|
const {
|
|
title = Sidebar.getTitleFromContent(src) || basename(path),
|
|
items,
|
|
} = data
|
|
|
|
const link = normalize(path.replace(/^website/, ''))
|
|
|
|
const output: DefaultTheme.SidebarItem = {
|
|
text: title,
|
|
link,
|
|
}
|
|
|
|
if (items) {
|
|
output.collapsed = options.collapsed === null || options.collapsed === undefined || options.collapsed
|
|
output.items = Sidebar.generateSidebarItem(items, link)
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
static getTitleFromContent(
|
|
content: string,
|
|
): string | undefined {
|
|
const lines = content.split('\n')
|
|
for (let i = 0, len = lines.length; i < len; i += 1) {
|
|
let str = lines[i].toString().replace('\r', '')
|
|
if (str.indexOf('# ') !== -1) {
|
|
str = str.replace('# ', '')
|
|
return str
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
export { Sidebar }
|
|
|
|
export const {
|
|
generateSidebar,
|
|
generateSidebarItem,
|
|
getTitleFromContent
|
|
} = Sidebar |