diff --git a/add_docs_to_mkdocs.py b/add_docs_to_mkdocs.py new file mode 100644 index 0000000..b7f8abe --- /dev/null +++ b/add_docs_to_mkdocs.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +自动将docs目录下的文件添加到mkdocs.yml导航配置中 +""" + +import os +import sys +import re +import yaml +from pathlib import Path + +def load_mkdocs_nav(mkdocs_path='mkdocs.yml'): + """加载mkdocs.yml中的导航配置""" + try: + with open(mkdocs_path, 'r', encoding='utf-8') as f: + content = f.read() + + # 使用正则表达式提取nav部分 + nav_match = re.search(r'nav:\s*\n(.*?)(?=\n\w+:|$)', content, re.DOTALL) + if not nav_match: + print("错误: 找不到nav配置") + sys.exit(1) + + nav_content = nav_match.group(1) + + # 解析YAML格式的nav内容 + # 为nav内容添加适当的缩进 + nav_yaml = "nav:\n" + nav_content + config = yaml.safe_load(nav_yaml) + return config.get('nav', []) + + except FileNotFoundError: + print(f"错误: 找不到文件 {mkdocs_path}") + sys.exit(1) + except Exception as e: + print(f"错误: 解析文件失败: {e}") + sys.exit(1) + +def save_mkdocs_nav(nav, mkdocs_path='mkdocs.yml'): + """保存导航配置到mkdocs.yml""" + try: + with open(mkdocs_path, 'r', encoding='utf-8') as f: + content = f.read() + + # 生成新的nav内容 + nav_yaml = yaml.dump({'nav': nav}, allow_unicode=True, default_flow_style=False, sort_keys=False) + + # 移除第一行的"nav:" + nav_lines = nav_yaml.split('\n') + new_nav_content = '\n'.join(nav_lines[1:]) # 跳过第一行 + + # 替换原有的nav部分,使用re.escape避免特殊字符问题 + nav_pattern = r'(nav:\s*\n)(.*?)(?=\n\w+:|$)' + # 对new_nav_content进行转义处理 + escaped_content = re.escape(new_nav_content) + # 但我们需要保留实际的换行符等,所以使用更简单的方法 + new_content = re.sub(nav_pattern, r'\1' + new_nav_content, content, flags=re.DOTALL) + + with open(mkdocs_path, 'w', encoding='utf-8') as f: + f.write(new_content) + + print(f"✓ 已更新 {mkdocs_path}") + + except Exception as e: + print(f"错误: 保存文件失败: {e}") + sys.exit(1) + +def get_all_md_files(docs_dir='docs'): + """获取docs目录下的所有.md文件""" + md_files = [] + for root, dirs, files in os.walk(docs_dir): + for file in files: + if file.endswith('.md'): + rel_path = os.path.relpath(os.path.join(root, file), docs_dir) + # 将Windows路径分隔符转换为Unix风格(/) + rel_path = rel_path.replace('\\', '/') + md_files.append(rel_path) + return sorted(md_files) + +def get_nav_files(nav): + """从导航配置中提取所有文件路径""" + nav_files = [] + + def extract_files(item): + if isinstance(item, dict): + for key, value in item.items(): + if isinstance(value, list): + for subitem in value: + extract_files(subitem) + elif isinstance(value, str): + nav_files.append(value) + elif isinstance(item, str): + nav_files.append(item) + + for item in nav: + extract_files(item) + + return nav_files + +def categorize_file(file_path): + """根据文件路径分类文件""" + path_parts = file_path.split('/') + + # 如果文件在根目录 + if len(path_parts) == 1: + return "其他" + + # 根据目录名分类 + category_map = { + '技术文档': '技术文档', + '开发指南': '开发指南', + '学习笔记': '学习笔记', + 'DevOps平台': 'DevOps平台', + 'cursor': 'Cursor工具', + 'Obsidian': 'Obsidian笔记' + } + + first_dir = path_parts[0] + # 如果目录名在映射中,使用映射的名称,否则使用目录名 + return category_map.get(first_dir, first_dir) + +def add_files_to_nav(nav, missing_files): + """将缺失的文件添加到导航配置中""" + # 创建分类字典 + categories = {} + for file_path in missing_files: + category = categorize_file(file_path) + if category not in categories: + categories[category] = [] + categories[category].append(file_path) + + # 将文件添加到现有分类或创建新分类 + for category, files in categories.items(): + category_found = False + + # 查找是否已存在该分类 + for i, item in enumerate(nav): + if isinstance(item, dict) and category in item: + # 添加到现有分类 + existing_files = set(item[category]) + for file_path in files: + if file_path not in existing_files: + item[category].append(file_path) + category_found = True + print(f"✓ 已将 {len(files)} 个文件添加到 '{category}' 分类") + break + + # 如果分类不存在,创建新分类 + if not category_found: + nav.append({category: sorted(files)}) + print(f"✓ 已创建新分类 '{category}' 并添加 {len(files)} 个文件") + + return nav + +def main(): + print("开始自动将docs目录下的文件添加到mkdocs.yml中...") + print("=" * 60) + + # 1. 加载当前导航配置 + print("1. 加载mkdocs.yml导航配置...") + nav = load_mkdocs_nav() + + # 2. 获取所有.md文件 + print("2. 扫描docs目录下的所有.md文件...") + all_md_files = get_all_md_files() + print(f" 找到 {len(all_md_files)} 个.md文件") + + # 3. 获取导航中的文件 + print("3. 分析当前导航配置...") + nav_files = get_nav_files(nav) + print(f" 导航中已有 {len(nav_files)} 个文件") + + # 4. 找出缺失的文件 + missing_files = [] + for md_file in all_md_files: + # 将路径统一为Unix风格进行比较 + if md_file not in nav_files and md_file != 'index.md': + missing_files.append(md_file) + + if not missing_files: + print("✓ 所有文件已在导航中,无需更新") + return + + print(f"4. 发现 {len(missing_files)} 个文件不在导航中:") + for i, file_path in enumerate(missing_files, 1): + print(f" {i:2d}. {file_path}") + + # 5. 确认是否继续 + print("\n5. 是否继续添加这些文件到mkdocs.yml?") + response = input(" 输入 'y' 继续,其他键取消: ") + + if response.lower() != 'y': + print("操作已取消") + return + + # 6. 添加文件到导航 + print("\n6. 正在更新mkdocs.yml...") + updated_nav = add_files_to_nav(nav, missing_files) + + # 7. 保存配置 + save_mkdocs_nav(updated_nav) + + print("\n" + "=" * 60) + print("完成!mkdocs.yml已更新") + print(f"总计添加了 {len(missing_files)} 个文件到导航中") + +if __name__ == '__main__': + main() diff --git a/docs/renjiabo/test.md b/docs/renjiabo/test.md new file mode 100644 index 0000000..e69de29 diff --git a/mkdocs.yml b/mkdocs.yml index b6e6313..fb00aed 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,39 +41,59 @@ plugins: # 导航配置 nav: - - 首页: index.md - - 开发指南: - - 开发指南/快速开始.md - - 开发指南/项目结构.md - - 开发指南/开发规范.md - - DevOps平台: - - DevOps平台/Gerrit使用指南.md - - DevOps平台/Gitea使用指南.md - - DevOps平台/Drone CI使用指南.md - - DevOps平台/MinIO使用指南.md - - DevOps平台/Nexus使用指南.md - - 技术文档: - - 技术文档/架构设计.md - - 技术文档/API文档.md - - 技术文档/部署文档.md - - Cursor工具: - - cursor/cursor.md - - 学习笔记: - - 学习笔记/Java学习.md - - 学习笔记/前端学习.md - - 学习笔记/DevOps学习.md - - 学习笔记/gerrit上传代码详细指南.md - - 学习笔记/gerrit分支规范.md - - 学习笔记/生成并配置SSH密钥、克隆仓库.md - - 学习笔记/git设置用户名和邮箱.md - - 学习笔记/git同步远程分支总结.md - - 学习笔记/提交代码时候的钩子.md - - 学习笔记/MkDocs 是什么.md - - 学习笔记/个人全自动研发体系.md - - 学习笔记/效率提升.md - - 学习笔记/重要.md +- 首页: index.md +- 开发指南: + - 开发指南/快速开始.md + - 开发指南/项目结构.md + - 开发指南/开发规范.md +- DevOps平台: + - DevOps平台/Gerrit使用指南.md + - DevOps平台/Gitea使用指南.md + - DevOps平台/Drone CI使用指南.md + - DevOps平台/MinIO使用指南.md + - DevOps平台/Nexus使用指南.md +- 技术文档: + - 技术文档/架构设计.md + - 技术文档/API文档.md + - 技术文档/部署文档.md +- Cursor工具: + - cursor/cursor.md +- 学习笔记: + - 学习笔记/Java学习.md + - 学习笔记/前端学习.md + - 学习笔记/DevOps学习.md + - 学习笔记/gerrit上传代码详细指南.md + - 学习笔记/gerrit分支规范.md + - 学习笔记/生成并配置SSH密钥、克隆仓库.md + - 学习笔记/git设置用户名和邮箱.md + - 学习笔记/git同步远程分支总结.md + - 学习笔记/提交代码时候的钩子.md + - 学习笔记/MkDocs 是什么.md + - 学习笔记/个人全自动研发体系.md + - 学习笔记/效率提升.md + - 学习笔记/重要.md +- Obsidian笔记: + - Obsidian/2026-01-05 个人文档管理.md + - Obsidian/高频命令.md + - Obsidian/欢迎.md + - Obsidian/重要笔记.md + - Obsidian/资源网站.md + - Obsidian/创业/我是一名从事android 应用的开发者,写过多款应用,写过微信小程序,写过h5,也做过3年的framework开发,写过python后台。我想创业,不知道可以具体怎么来做?.md + - Obsidian/生活/教育/9个国家级免费学习平台.md + - Obsidian/adb调试命令/常用linux命令.md + - Obsidian/adb调试命令/adb常用命令.md + - Obsidian/dify/使用dify,可以生成一个专项事务助手吗,比如公司正规化事务助手.md + - Obsidian/dify/作为安卓高级开发工程师,除了项目管理,你完全可以在技术专项、团队效能和个人成长三大领域构建更懂你的专属助手.md + - Obsidian/git/Git add . 后如何撤销.md + - Obsidian/git/git常用命令.md + - Obsidian/saars开发/互联网saar系统是什么,可以解决哪些场景需求的问题.md + - Obsidian/saars开发/数据库配置.md + - Obsidian/saars开发/aitsc维护命令.md + - Obsidian/saars开发/营养师/健康营养师分析数据.md + - Obsidian/saars开发/营养师/营养师分析数据.md +- renjiabo: + - renjiabo/test.md -# Markdown扩展 markdown_extensions: - pymdownx.highlight: anchor_linenums: true diff --git a/test_script.py b/test_script.py new file mode 100644 index 0000000..924366c --- /dev/null +++ b/test_script.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +测试add_docs_to_mkdocs.py脚本的基本功能 +""" + +import os +import yaml + +# 测试get_all_md_files函数 +def test_get_all_md_files(): + print("测试get_all_md_files函数...") + md_files = [] + for root, dirs, files in os.walk('docs'): + for file in files: + if file.endswith('.md'): + rel_path = os.path.relpath(os.path.join(root, file), 'docs') + rel_path = rel_path.replace('\\', '/') + md_files.append(rel_path) + + print(f"找到 {len(md_files)} 个.md文件") + print("前10个文件:") + for i, f in enumerate(sorted(md_files)[:10], 1): + print(f" {i:2d}. {f}") + + return sorted(md_files) + +# 测试categorize_file函数 +def test_categorize_file(): + print("\n测试categorize_file函数...") + test_cases = [ + ('技术文档/API文档.md', '技术文档'), + ('开发指南/快速开始.md', '开发指南'), + ('学习笔记/Java学习.md', '学习笔记'), + ('DevOps平台/Gerrit使用指南.md', 'DevOps平台'), + ('cursor/cursor.md', 'Cursor工具'), + ('Obsidian/高频命令.md', 'Obsidian笔记'), + ('其他文件.md', '其他'), + ] + + for file_path, expected in test_cases: + # 模拟categorize_file函数 + path_parts = file_path.split('/') + if len(path_parts) == 1: + category = "其他" + else: + category_map = { + '技术文档': '技术文档', + '开发指南': '开发指南', + '学习笔记': '学习笔记', + 'DevOps平台': 'DevOps平台', + 'cursor': 'Cursor工具', + 'Obsidian': 'Obsidian笔记' + } + first_dir = path_parts[0] + category = category_map.get(first_dir, first_dir) + + status = "✓" if category == expected else "✗" + print(f" {status} {file_path:40} -> {category:15} (期望: {expected})") + +# 主测试 +def main(): + print("=" * 60) + print("测试add_docs_to_mkdocs.py脚本功能") + print("=" * 60) + + # 测试1: 获取所有md文件 + all_md_files = test_get_all_md_files() + + # 测试2: 分类函数 + test_categorize_file() + + # 测试3: 检查当前mkdocs.yml中的文件 + print("\n检查当前mkdocs.yml中的导航文件...") + try: + with open('mkdocs.yml', 'r', encoding='utf-8') as f: + content = f.read() + + # 简单统计nav中的文件 + import re + # 计算nav部分有多少行包含.md + nav_section = re.search(r'nav:\s*\n(.*?)(?=\n\w+:|$)', content, re.DOTALL) + if nav_section: + nav_content = nav_section.group(1) + md_count = nav_content.count('.md') + print(f"mkdocs.yml导航中大约有 {md_count} 个.md文件引用") + + # 提取所有文件路径 + file_paths = re.findall(r'\s+-\s+(.*?\.md)', nav_content) + print(f"实际提取到 {len(file_paths)} 个文件路径") + print("导航中的分类:") + lines = nav_content.split('\n') + for line in lines: + if line.strip() and not line.strip().startswith('-') and ':' in line: + print(f" - {line.strip()}") + except Exception as e: + print(f"读取mkdocs.yml时出错: {e}") + + print("\n" + "=" * 60) + print("测试完成") + +if __name__ == '__main__': + main()