convert code 2 markdown by python
| """convert code to markdown |
| """ |
| import os |
| import re |
| import sys |
| from datetime import datetime |
| |
| |
| exclude_dirs = ["__pycache__", "venv", "build", "dist", "node_modules", "public", "LICENSE", "assets", "vendor", "tmp", "static", "templates", "bin", "obj", "Migrations", "Properties"] |
| |
| |
| exclude_files = ["_NOTE.md", ".d.ts", ".lock", ".png", ".woff2", ".ttf", ".woff", ".css", "README.md", ".toml", "swagger-ui-bundle.js", "-lock.json"] |
| |
| |
| include_exts = [".py", ".vue", ".js", ".ts", ".html", ".go", ".mod", ".json", ".txt", ".sh", ".command", "cs", "csproj", ".jsx"] |
| |
| |
| md_suffix_table = { |
| "command": "sh", |
| } |
| |
| |
| def get_root_dir(dir_path): |
| file_list = os.listdir(dir_path) |
| path_list = [] |
| root_file_list = [] |
| for file in file_list: |
| print(file) |
| |
| if file.startswith("."): |
| continue |
| |
| is_file = re.findall(r'\.[^.\\/:*?"<>|\r\n]+$', file) |
| if len(is_file): |
| |
| res_abort = re.findall(re.compile(r"(d\.ts|config\.ts|-lock\.json)$"), file) |
| if res_abort: |
| continue |
| |
| res_save = re.findall(re.compile(r"(\.py|vue|config\.js|js|ts|html|txt|go|mod|json)$"), file) |
| if len(res_save): |
| root_file_list.append(file) |
| continue |
| |
| res_abort = re.findall(re.compile(r"(__pycache__|venv|build|dist|node_modules|public|LICENSE)"), file) |
| if len(res_abort): |
| continue |
| |
| code_file_path = os.path.join(dir_path, file) |
| path_list.append(code_file_path) |
| return path_list, root_file_list |
| |
| |
| def get_deep_dirs(path): |
| file_path = [] |
| for root, dirs, files in os.walk(path): |
| |
| del_dir_index = [] |
| for i, dir in enumerate(dirs): |
| |
| if dir.startswith("."): |
| del_dir_index.append(i) |
| |
| res_abort = re.findall(re.compile(r"(__pycache__|venv|build|dist|node_modules|public|LICENSE|assets|vendor|tmp|static|templates)"), dir) |
| if len(res_abort): |
| del_dir_index.append(i) |
| |
| |
| del_dir_index = list(set(del_dir_index)) |
| del_dir_index.sort() |
| for counter, index in enumerate(del_dir_index): |
| index = index - counter |
| dirs.pop(index) |
| |
| |
| del_file_index = [] |
| for i, file in enumerate(files): |
| |
| |
| if file.startswith("."): |
| del_file_index.append(i) |
| |
| res_abort = re.findall(re.compile(r"(_NOTE\.md|\.d\.ts|\.lock|\.png|\.woff2|\.ttf|\.woff|\.css|README\.md|\.toml|swagger-ui-bundle.js|-lock\.json)$"), file) |
| if len(res_abort): |
| del_file_index.append(i) |
| |
| |
| del_file_index = list(set(del_file_index)) |
| del_file_index.sort() |
| for counter, index in enumerate(del_file_index): |
| index = index - counter |
| files.pop(index) |
| |
| |
| for file in files: |
| |
| res_save = re.findall(re.compile(r"(\.py|vue|js|ts|html|go|mod|json)$"), file) |
| if len(res_save): |
| file_path.append(os.path.join(root, file)) |
| return file_path |
| |
| |
| def get_deep_dirs_fast(path): |
| """获取所有的代码文件的路径 |
| |
| Args: |
| path (_type_): 项目的根目录 |
| |
| Returns: |
| _type_: 所有的代码文件的路径,是个列表 |
| """ |
| |
| |
| |
| |
| code_file_path = [] |
| for root, dirs, files in os.walk(path): |
| |
| dirs[:] = [d for d in dirs if not d.startswith(".") and not any(ex in d for ex in exclude_dirs)] |
| |
| files[:] = [f for f in files if not f.startswith(".") and not any(ex in f for ex in exclude_files)] |
| |
| for file in files: |
| |
| if any(file.endswith(ext) for ext in include_exts): |
| code_file_path.append(os.path.join(root, file)) |
| return code_file_path |
| |
| |
| def readcode_writemd(code_file_path, project_path, markdown_file_path): |
| """读取代码文件,写入markdown文件 |
| |
| Args: |
| code_file_path (_type_): 代码文件的路径 |
| project_path (_type_): 项目的根路径 |
| markdown_file_path (_type_): 输出的markdown文件的路径 |
| """ |
| |
| suffix = re.findall(r'\.[^.\\/:*?"<>|\r\n]+$', code_file_path) |
| if len(suffix): |
| suffix = suffix[0][1:] |
| with open(code_file_path, "r", encoding="utf-8") as f: |
| try: |
| rest_line = f.read() |
| except Exception as e: |
| print(f"{code_file_path}{e}文件编码读取错误,非utf-8") |
| rest_line = "" |
| write2md(rest_line, suffix, code_file_path, project_path, markdown_file_path) |
| |
| |
| def get_md_title_path(code_file_path, project_path): |
| """获取每个代码文件的md标题,去掉项目之前的文件路径 |
| |
| Args: |
| code_file_path (_type_): 代码路径 |
| project_path (_type_): 项目根路径 |
| |
| Returns: |
| _type_: 每个代码文件的md标题 |
| """ |
| |
| common_prefix = os.path.commonprefix([code_file_path, project_path]) |
| |
| diff1 = code_file_path[len(common_prefix) + 1 :] |
| md_title = os.path.join(os.path.basename(project_path), diff1) |
| return md_title |
| |
| |
| def get_code_md_lable_by_suffix(suffix): |
| if md_suffix_table.get(suffix) is not None: |
| return md_suffix_table.get(suffix) |
| |
| return suffix |
| |
| |
| def write2md(content, suffix, code_file_path, project_path, markdown_file_path): |
| with open(markdown_file_path, "a", encoding="utf-8") as f: |
| md_title = get_md_title_path(code_file_path, project_path) |
| f.write("\n") |
| f.write(f"# `{md_title}`\n\n") |
| f.write(f"```{get_code_md_lable_by_suffix(suffix)}\n") |
| f.write(content) |
| f.write("\n") |
| f.write("```\n\n\n") |
| |
| |
| def get_root_path(path): |
| dir_path = path |
| |
| if os.path.isfile(path): |
| dir_path = os.path.dirname(path) |
| return dir_path |
| |
| |
| def get_file_name(): |
| |
| now = datetime.now() |
| |
| time_str = now.strftime("%Y-%m-%d_%H-%M-%S") |
| |
| file_name = f"Z_{time_str}_NOTE.md" |
| return file_name |
| |
| |
| if __name__ == "__main__": |
| print("请拖入项目根目录下随便一个文件:\n") |
| root_path = get_root_path(sys.argv[1]) |
| md_file_name = get_file_name() |
| md_file_path = os.path.join(root_path, md_file_name) |
| file_path_list = get_deep_dirs_fast(root_path) |
| |
| for i, file_path in enumerate(file_path_list): |
| print(i, "->", get_md_title_path(file_path, root_path)) |
| readcode_writemd(file_path, root_path, md_file_path) |
| |
| print("=============done=============") |
| |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战