1+ // scripts/generate-community-index.js (FINAL VERSION with Multi-Level Nesting)
2+
3+ const fs = require ( 'fs' ) ;
4+ const path = require ( 'path' ) ;
5+ const { glob } = require ( 'glob' ) ;
6+ const matter = require ( 'gray-matter' ) ;
7+
8+ // --- 配置区 ---
9+ const communityShareDir = path . join ( __dirname , '../app/docs/CommunityShare' ) ;
10+ const outputFile = path . join ( communityShareDir , 'index.mdx' ) ;
11+
12+ const categoryDisplayNames = {
13+ Geek : '技术分享' ,
14+ MentalHealth : '心理健康' ,
15+ RAG : 'RAG' ,
16+ } ;
17+
18+ const headerContent = `---
19+ title: "群友分享"
20+ date: "${ new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] } "
21+ ---
22+
23+ 欢迎来到群友分享板块!无论你是技术极客,还是热爱生活,都欢迎积极投稿!
24+
25+ 一篇微不足道的文章或许可以帮助一个迷茫的陌生人~
26+
27+ > 转载文章请先联系原作者获取授权,谢谢!
28+ ` ;
29+
30+ // --- 主逻辑 ---
31+ async function generateIndex ( ) {
32+ try {
33+ const categories = fs . readdirSync ( communityShareDir , { withFileTypes : true } )
34+ . filter ( dirent => dirent . isDirectory ( ) )
35+ . map ( dirent => dirent . name ) ;
36+
37+ let allLinksContent = '' ;
38+
39+ for ( const category of categories ) {
40+ const categoryPath = path . join ( communityShareDir , category ) ;
41+ const files = await glob ( `${ categoryPath . replace ( / \\ / g, '/' ) } /**/*.{md,mdx}` ) ;
42+
43+ if ( files . length === 0 ) continue ;
44+
45+ // 自定义排序逻辑
46+ files . sort ( ( a , b ) => {
47+ const dirA = path . dirname ( a ) ;
48+ const dirB = path . dirname ( b ) ;
49+ if ( dirA !== dirB ) {
50+ return dirA . localeCompare ( dirB ) ;
51+ }
52+ const isAIndex = path . basename ( a ) . startsWith ( 'index.' ) ;
53+ const isBIndex = path . basename ( b ) . startsWith ( 'index.' ) ;
54+ if ( isAIndex ) return - 1 ;
55+ if ( isBIndex ) return 1 ;
56+ return path . basename ( a ) . localeCompare ( path . basename ( b ) ) ;
57+ } ) ;
58+
59+ const categoryTitle = categoryDisplayNames [ category ] || category ;
60+ allLinksContent += `## ${ categoryTitle } \n\n` ;
61+
62+ // --- 支持多级嵌套的链接生成逻辑 ---
63+ const links = files . map ( file => {
64+ const fileContent = fs . readFileSync ( file , 'utf8' ) ;
65+ const { data : frontmatter } = matter ( fileContent ) ;
66+
67+ const title = frontmatter . title || path . basename ( file , path . extname ( file ) ) ;
68+
69+ const relativePath = path . relative ( communityShareDir , file ) ;
70+ const urlPath = relativePath . replace ( / \\ / g, '/' ) . replace ( / \. ( m d x | m d ) $ / , '' ) ;
71+ const finalUrl = urlPath . endsWith ( '/index' ) ? urlPath . slice ( 0 , - 6 ) : urlPath ;
72+ const url = `/docs/CommunityShare/${ finalUrl } ` ;
73+
74+ // --- 动态计算缩进深度 ---
75+ const relativeToCategory = path . relative ( categoryPath , file ) ;
76+ const dirOfFile = path . dirname ( relativeToCategory ) ;
77+
78+ // 1. 计算文件所在目录的深度
79+ // 如果文件在根目录(.), 深度为0, 否则按路径分隔符数量计算
80+ const depth = dirOfFile === '.' ? 0 : dirOfFile . split ( path . sep ) . length ;
81+
82+ // 2. 判断是否为 index 文件
83+ const isIndex = path . basename ( file ) . startsWith ( 'index.' ) ;
84+
85+ // 3. index 文件使用目录深度, 非 index 文件在目录深度的基础上再缩进一级
86+ const indentLevel = isIndex ? depth : depth + 1 ;
87+
88+ const prefix = ' ' . repeat ( indentLevel ) + '- ' ;
89+
90+ return `${ prefix } [${ title } ](${ url } )` ;
91+ } ) ;
92+ // --- 新链接生成逻辑结束 ---
93+
94+ allLinksContent += links . join ( '\n' ) + '\n\n' ;
95+ }
96+
97+ const finalContent = `${ headerContent } \n${ allLinksContent . trim ( ) } ` ;
98+ fs . writeFileSync ( outputFile , finalContent ) ;
99+
100+ console . log ( `Successfully generated index for CommunityShare at ${ outputFile } ` ) ;
101+ } catch ( error ) {
102+ console . error ( 'Error generating CommunityShare index file:' , error ) ;
103+ process . exit ( 1 ) ;
104+ }
105+ }
106+
107+ generateIndex ( ) ;
0 commit comments