Skip to content

Commit 461bfa4

Browse files
committed
自动侧边栏脚本
1 parent fbee894 commit 461bfa4

File tree

18 files changed

+1038
-132
lines changed

18 files changed

+1038
-132
lines changed

auto_sidebar.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import os
2+
import re
3+
import json
4+
import csv
5+
6+
# 从Markdown内容中提取第一个H1标题
7+
def extract_title(md_content):
8+
match = re.search(r'^#\s+(.*)', md_content, re.MULTILINE)
9+
if match:
10+
return match.group(1)
11+
return None
12+
13+
# 生成侧边栏结构
14+
def generate_sidebar_structure(base_path, title: dict, language='zh'):
15+
# 初始化侧边栏结构
16+
path = f"/{language}/quickstart/"
17+
sidebar = { f"{path}" : []}
18+
# 遍历指定目录下的所有文件
19+
for root, dirs, files in os.walk(base_path):
20+
for file in files:
21+
if file.endswith(".md"): # 筛选Markdown文件
22+
file_path = os.path.join(root, file)
23+
with open(file_path, 'r', encoding='utf-8') as md_file:
24+
content = md_file.read()
25+
title = extract_title(content) # 提取标题
26+
if title:
27+
# 生成相对路径链接
28+
relative_path = os.path.relpath(file_path, base_path).replace('\\', '/')
29+
link = f"{path}{relative_path[:-3]}" # 移除.md扩展名
30+
# 获取分类名称
31+
category = os.path.basename(os.path.dirname(file_path))[2:]
32+
# 查找或创建分类条目
33+
if not title_dict.keys().__contains__(category):
34+
continue
35+
category_entry = next((item for item in sidebar[path] if item["text"] == title_dict[category]), None)
36+
if not category_entry:
37+
category_entry = {"text": title_dict[category], "items": []}
38+
sidebar[path].append(category_entry)
39+
# 添加链接到分类条目
40+
category_entry["items"].append({"text": title, "link": link})
41+
return sidebar
42+
43+
# 将侧边栏结构写入TypeScript文件,键名不带引号
44+
def write_sidebar_ts(sidebar, output_file):
45+
def dict_to_ts(obj, indent=0):
46+
"""递归地将字典转换为TypeScript对象字面量字符串,特定键名不带引号"""
47+
ts_str = "{\n"
48+
indent_str = " " * (indent + 1)
49+
for k, v in obj.items():
50+
# 检查键名是否为特定的几个,如果是,则不使用json.dumps
51+
if k in ["text", "item", "link"]:
52+
key_str = k
53+
else:
54+
key_str = json.dumps(k, ensure_ascii=False)
55+
56+
if isinstance(v, dict):
57+
v_str = dict_to_ts(v, indent + 1)
58+
elif isinstance(v, list):
59+
v_str = "[\n" + ",\n".join([indent_str + " " + dict_to_ts(item, indent + 2) for item in v]) + "\n" + indent_str + "]"
60+
else:
61+
v_str = json.dumps(v, ensure_ascii=False)
62+
ts_str += f"{indent_str}{key_str}: {v_str},\n"
63+
ts_str += " " * indent + "}"
64+
return ts_str
65+
66+
sidebar_ts_content = f"""import {{ DefaultTheme }} from 'vitepress';
67+
68+
export const sidebar: DefaultTheme.Sidebar = {dict_to_ts(sidebar, 0)};
69+
"""
70+
with open(output_file, 'w', encoding='utf-8') as ts_file:
71+
ts_file.write(sidebar_ts_content)
72+
73+
# 指定Markdown文件所在目录和输出文件路径
74+
output_file = 'docs/.vitepress/sidebar.ts'
75+
# 读取csv文件获取标题。第一行为文件夹名,第二行是中文标题,第三行是英文标题
76+
with open('titles.csv', 'r', encoding='utf-8') as csvfile:
77+
reader = csv.reader(csvfile)
78+
title = [row for row in reader]
79+
csvfile.close()
80+
# 生成键值对
81+
title_dict = {}
82+
for i in range(len(title[0])):
83+
title_dict[title[0][i]] = title[1][i]
84+
# 生成侧边栏结构并写入文件
85+
sidebar = generate_sidebar_structure('docs/zh/quickstart', title_dict, 'zh')
86+
#英文
87+
for i in range(len(title[0])):
88+
title_dict[title[0][i]] = title[2][i]
89+
en_sidebar = generate_sidebar_structure('docs/en/quickstart', title_dict, 'en')
90+
#合并
91+
for key in en_sidebar:
92+
sidebar[key] = en_sidebar[key]
93+
write_sidebar_ts(sidebar, output_file)

docs/.vitepress/cache/deps/_metadata.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
{
2-
"hash": "676c6e55",
2+
"hash": "24352143",
33
"configHash": "bd1e298f",
4-
"lockfileHash": "53525582",
5-
"browserHash": "1ba7939e",
4+
"lockfileHash": "657949f7",
5+
"browserHash": "275bbd23",
66
"optimized": {
77
"vue": {
88
"src": "../../../../node_modules/.pnpm/vue@3.4.15/node_modules/vue/dist/vue.runtime.esm-bundler.js",
99
"file": "vue.js",
10-
"fileHash": "0df1ba4e",
10+
"fileHash": "dec94417",
1111
"needsInterop": false
1212
},
1313
"vitepress > @vue/devtools-api": {
1414
"src": "../../../../node_modules/.pnpm/@vue+devtools-api@7.0.14/node_modules/@vue/devtools-api/dist/index.js",
1515
"file": "vitepress___@vue_devtools-api.js",
16-
"fileHash": "b6b0f716",
16+
"fileHash": "c3f51ca5",
1717
"needsInterop": false
1818
},
1919
"vitepress > @vueuse/core": {
2020
"src": "../../../../node_modules/.pnpm/@vueuse+core@10.7.2_vue@3.4.15/node_modules/@vueuse/core/index.mjs",
2121
"file": "vitepress___@vueuse_core.js",
22-
"fileHash": "23cb2f66",
22+
"fileHash": "6ec7a515",
2323
"needsInterop": false
2424
},
2525
"vitepress > @vueuse/integrations/useFocusTrap": {
2626
"src": "../../../../node_modules/.pnpm/@vueuse+integrations@10.7.2_focus-trap@7.5.4_vue@3.4.15/node_modules/@vueuse/integrations/useFocusTrap.mjs",
2727
"file": "vitepress___@vueuse_integrations_useFocusTrap.js",
28-
"fileHash": "cf6341ab",
28+
"fileHash": "13de43f6",
2929
"needsInterop": false
3030
},
3131
"vitepress > mark.js/src/vanilla.js": {
3232
"src": "../../../../node_modules/.pnpm/mark.js@8.11.1/node_modules/mark.js/src/vanilla.js",
3333
"file": "vitepress___mark__js_src_vanilla__js.js",
34-
"fileHash": "29e3e5c4",
34+
"fileHash": "2279df2d",
3535
"needsInterop": false
3636
},
3737
"vitepress > minisearch": {
3838
"src": "../../../../node_modules/.pnpm/minisearch@6.3.0/node_modules/minisearch/dist/es/index.js",
3939
"file": "vitepress___minisearch.js",
40-
"fileHash": "eddec37e",
40+
"fileHash": "eb264697",
4141
"needsInterop": false
4242
},
4343
"@theme/index": {
4444
"src": "../../../../node_modules/.pnpm/vitepress@1.0.0-rc.41_@algolia+client-search@4.22.1_search-insights@2.13.0/node_modules/vitepress/dist/client/theme-default/index.js",
4545
"file": "@theme_index.js",
46-
"fileHash": "6a367a8c",
46+
"fileHash": "2872f18a",
4747
"needsInterop": false
4848
}
4949
},

0 commit comments

Comments
 (0)