Merge pull request #262 from Kiameow/feat/generate-sidebar
feat: generate sidebar based on file structure
This commit is contained in:
@@ -134,6 +134,14 @@ export class GamePlay {
|
|||||||
this.state.value.mineGenerated = true;
|
this.state.value.mineGenerated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (block.revealed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (block.flagged) {
|
||||||
|
block.flagged = !block.flagged;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
block.revealed = true;
|
block.revealed = true;
|
||||||
if (block.mine) {
|
if (block.mine) {
|
||||||
this.onGameOver('lost');
|
this.onGameOver('lost');
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// import { defineConfig } from 'vitepress'
|
// import { defineConfig } from 'vitepress'
|
||||||
import { withMermaid } from "vitepress-plugin-mermaid-xyxsw";
|
import { transformerTwoslash } from '@shikijs/vitepress-twoslash';
|
||||||
|
import PanguPlugin from 'markdown-it-pangu';
|
||||||
|
import { fileURLToPath, URL } from 'node:url';
|
||||||
|
import VueMacros from 'unplugin-vue-macros/vite';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
import { main_sidebar, main_sidebar_old, chapter2_old, chapter3_old, chapter4_old, chapter5_old, chapter6_old, chapter7_old, chapter8_old, chapter9_old } from './sidebar.js';
|
import { withMermaid } from "vitepress-plugin-mermaid-xyxsw";
|
||||||
import { nav } from './nav.js';
|
import { nav } from './nav.js';
|
||||||
import PanguPlugin from 'markdown-it-pangu'
|
import { chapter2_old, chapter3_old, chapter4_old, chapter5_old, chapter6_old, chapter7_old, chapter8_old, chapter9_old, generateSidebar, main_sidebar, main_sidebar_old } from './sidebar.js';
|
||||||
import { fileURLToPath, URL } from 'node:url'
|
|
||||||
import VueMacros from 'unplugin-vue-macros/vite'
|
|
||||||
import { transformerTwoslash } from '@shikijs/vitepress-twoslash'
|
|
||||||
|
|
||||||
// https://vitepress.dev/reference/site-config
|
// https://vitepress.dev/reference/site-config
|
||||||
export default withMermaid({
|
export default withMermaid({
|
||||||
@@ -51,6 +51,11 @@ export default withMermaid({
|
|||||||
|
|
||||||
sidebar: {
|
sidebar: {
|
||||||
'/': main_sidebar(),
|
'/': main_sidebar(),
|
||||||
|
'/1.杭电生存指南/': generateSidebar('1.杭电生存指南'),
|
||||||
|
'/2.编程模块/': generateSidebar('2.编程模块'),
|
||||||
|
'/3.AI模块/': generateSidebar('3.AI模块'),
|
||||||
|
'/4.WEB模块/': generateSidebar('4.WEB模块'),
|
||||||
|
'/5.安全模块/': generateSidebar('5.安全模块'),
|
||||||
'/2023旧版内容/': main_sidebar_old(),
|
'/2023旧版内容/': main_sidebar_old(),
|
||||||
'/2023旧版内容/2.高效学习/': chapter2_old(),
|
'/2023旧版内容/2.高效学习/': chapter2_old(),
|
||||||
'/2023旧版内容/3.编程思维体系构建/': chapter3_old(),
|
'/2023旧版内容/3.编程思维体系构建/': chapter3_old(),
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
export function main_sidebar() {
|
export function main_sidebar() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -518,3 +521,94 @@ export function chapter9_old() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to extract numeric prefix as an array of numbers
|
||||||
|
function getNumericPrefix(fileName) {
|
||||||
|
const match = fileName.match(/^(\d+(\.\d+)?(?:\.\d+)*)/);
|
||||||
|
if (match) {
|
||||||
|
return match[0].split('.').map(Number); // Convert to array of numbers
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to compare two numeric prefixes
|
||||||
|
function compareNumericPrefixes(a, b) {
|
||||||
|
const prefixA = getNumericPrefix(a);
|
||||||
|
const prefixB = getNumericPrefix(b);
|
||||||
|
|
||||||
|
for (let i = 0; i < Math.max(prefixA.length, prefixB.length); i++) {
|
||||||
|
const numA = prefixA[i] || 0;
|
||||||
|
const numB = prefixB[i] || 0;
|
||||||
|
if (numA !== numB) {
|
||||||
|
return numA - numB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function generateSidebarBasic(dir, excludeDir = [], maxDepth, currentDepth = 0) {
|
||||||
|
if (currentDepth >= maxDepth)
|
||||||
|
console.warn("the file depth is beyond the maxium depth that your sidebar can show!");
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
const sortedFiles = files.sort(compareNumericPrefixes);
|
||||||
|
|
||||||
|
const sidebar =
|
||||||
|
sortedFiles.map((file) => {
|
||||||
|
const fullPath = path.join(dir, file);
|
||||||
|
const stats = fs.statSync(fullPath);
|
||||||
|
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
if (excludeDir.includes(file)) return null; // Skip excluded directories
|
||||||
|
return {
|
||||||
|
text: file,
|
||||||
|
collapsed: true,
|
||||||
|
items: generateSidebarBasic(fullPath, excludeDir, maxDepth, currentDepth + 1),
|
||||||
|
};
|
||||||
|
} else if (file.endsWith('.md')) {
|
||||||
|
return {
|
||||||
|
text: file.replace('.md', ''),
|
||||||
|
link: `/${fullPath.replace('.md', '')}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return sidebar.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a sidebar configuration for VitePress.
|
||||||
|
*
|
||||||
|
* @param {string} dir - The directory to generate the sidebar from.
|
||||||
|
* @param {Object} [options] - Optional parameters.
|
||||||
|
* @param {string[]} [options.excludeDir=['static']] - Directories to exclude from the sidebar.
|
||||||
|
* @param {string} [options.previousLevel='/'] - Link to the previous level.
|
||||||
|
* @param {string} [options.previousLevelDescription='返回上一层'] - Description for the previous level link.
|
||||||
|
* @param {string} [options.topLevelName] - Name for the top level of the sidebar.
|
||||||
|
* @param {number} [options.maxDepth=5] - Maximum depth of directories to include.
|
||||||
|
* @returns {Object[]} Sidebar configuration array.
|
||||||
|
*/
|
||||||
|
export function generateSidebar(
|
||||||
|
dir,
|
||||||
|
{
|
||||||
|
excludeDir = ['static'],
|
||||||
|
previousLevel = '/',
|
||||||
|
previousLevelDescription = '返回上一层',
|
||||||
|
topLevelName,
|
||||||
|
maxDepth = 5
|
||||||
|
} = {}
|
||||||
|
) {
|
||||||
|
const sidebar = [
|
||||||
|
{
|
||||||
|
text: previousLevelDescription,
|
||||||
|
link: previousLevel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: topLevelName ?? dir,
|
||||||
|
collapsed: false,
|
||||||
|
items: generateSidebarBasic(dir, excludeDir, maxDepth),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return sidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,52 @@
|
|||||||
- 网站页面设计
|
- 网站页面设计
|
||||||
- 在各种媒体、博客文章、群内宣传 HDU-CS-WIKI
|
- 在各种媒体、博客文章、群内宣传 HDU-CS-WIKI
|
||||||
|
|
||||||
|
## 文档命名
|
||||||
|
|
||||||
|
1. 对于 md 文件,请命名为 `数字与小数点前缀+文档标题` 的格式
|
||||||
|
|
||||||
|
```
|
||||||
|
1.1.2 新内容.md
|
||||||
|
2. 序言.md
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 如果您需要开启新的小章节模块,请新建一个文件夹,文件夹的命名格式与 md 文件类似,为 `数字与小数点前缀+模块名`
|
||||||
|
|
||||||
|
```
|
||||||
|
2.2 模块 2
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 不论是 md 文件还是文件夹,请不要使用字母或其他特殊符号作为前缀
|
||||||
|
|
||||||
|
一个合理的文档结构如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
└─ 1.第一章
|
||||||
|
├── 1.1 模块 1
|
||||||
|
│ ├── 1.1.10 JavaScript.md
|
||||||
|
│ ├── 1.1.11 Lua.md
|
||||||
|
│ ├── 1.1.12 Lisp.md
|
||||||
|
│ ├── 1.1.1 Ruby.md
|
||||||
|
│ ├── 1.1.2 Java.md
|
||||||
|
│ ├── 1.1.3 C++.md
|
||||||
|
│ ├── 1.1.4 C.md
|
||||||
|
│ ├── 1.1.5 Math.md
|
||||||
|
│ ├── 1.1.6 Matlab.md
|
||||||
|
│ ├── 1.1.7 React.md
|
||||||
|
│ ├── 1.1.8 Jupyter.md
|
||||||
|
│ └── 1.1.9 Vue.md
|
||||||
|
├── 1.2 模块 2
|
||||||
|
│ ├── 1.2.1 C#.md
|
||||||
|
│ ├── 1.2.2 Python.md
|
||||||
|
│ └── static
|
||||||
|
├── 1.3 结语.md
|
||||||
|
├── 1. 序言.md
|
||||||
|
└── static
|
||||||
|
```
|
||||||
|
|
||||||
|
static 文件夹用于存放您的静态资源,如图片,您也可以在模块文件夹下放置新的 static 文件夹,方便引用资源
|
||||||
|
|
||||||
## 文档风格
|
## 文档风格
|
||||||
|
|
||||||
1. 使用 Markdown 编写文档,文档格式参考 Markdown 语法。
|
1. 使用 Markdown 编写文档,文档格式参考 Markdown 语法。
|
||||||
|
|||||||
Reference in New Issue
Block a user