python:Flask 3, mistune 2, 实现在线编辑 Markdown 文档的 Web 服务程序

承上一篇: nodejs: 能在线编辑 Markdown 文档的 Web 服务程序,更多扩展功能

模仿 app2.js, 请用 python编程 : flask 3, mistune 2, 或者其它模块 实现同样功能的Web服务

以下是使用 Flask 3 + Mistune 2 实现与 app2.js 相同功能的 Python Web 服务,包含 Markdown 解析(支持代码高亮、Mermaid、表格、公式)、文档保存/加载/列表查询等核心功能:

1. 先安装依赖

pip install flask==3.0.3 mistune==2.0.5 pip install pygments python-multipart python-dotenv 

2. 完整代码(app.py)

# -*- coding: utf-8 -*-""" Markdown 在线编辑器 (支持表格/公式/Mermaid) """import os import json from pathlib import Path import mistune from mistune.renderers import HTMLRenderer from mistune.plugins import table, task_lists, footnotes from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer from pygments.formatters import HtmlFormatter from flask import Flask, render_template, request, jsonify, send_from_directory # 初始化 Flask 应用 app = Flask(__name__, static_url_path='/', static_folder='public',# 静态文件目录(对应前端资源) template_folder='views')# 模板目录(对应editor.html)# 配置 app.config['JSON_AS_ASCII']=False# 支持中文 DOCS_DIR = Path(__file__).parent /'docs'# 文档保存目录 DOCS_DIR.mkdir(exist_ok=True)# 确保目录存在# ---- Markdown 解析配置 ----# 自定义代码高亮渲染器(支持 Mermaid/代码高亮)classCustomRenderer(HTMLRenderer):defblock_code(self, code, info=None):# 处理 Mermaid 代码块if info and info.strip()=='mermaid':returnf'<div>{mistune.escape(code)}</div>'# 处理普通代码块高亮try:# 尝试获取指定语言的 lexer lexer = get_lexer_by_name(info.strip())if info else guess_lexer(code)except:# 自动检测语言 lexer = guess_lexer(code)# 使用 Pygments 高亮代码 formatter = HtmlFormatter( noclasses=False,# 生成带类名的 HTML(配合 highlight.js 样式) cssclass='hljs',# 兼容 highlight.js 样式类 linenos=False# 不显示行号(可根据需求开启)) highlighted = highlight(code, lexer, formatter)returnf'<pre>{highlighted}</pre>'# 初始化 Mistune 解析器(启用所有扩展) markdown_parser = mistune.create_markdown( renderer=CustomRenderer(), plugins=['table',# 表格支持'task_lists',# 任务列表支持'footnotes'# 脚注支持], escape=False# 关键配置:禁用字符转义)# ---- 路由配置 ----# 首页 - 编辑器界面@app.route('/')defindex():return render_template('editor.html', title='Markdown 在线编辑器 (支持表格/公式/Mermaid)')# 解析 Markdown 为 HTML (API)@app.route('/api/parse', methods=['POST'])defparse_markdown():try: data = request.get_json() markdown = data.get('markdown','')ifnot markdown:return jsonify({'error':'Markdown 内容不能为空'}),400# 解析 Markdown 为 HTML html = markdown_parser(markdown)return jsonify({'html': html})except Exception as e:return jsonify({'error':f'解析 Markdown 失败: {str(e)}'}),500# 保存文档 (API)@app.route('/api/save', methods=['POST'])defsave_document():try: data = request.get_json() filename = data.get('filename','').strip() content = data.get('content','').strip()ifnot filename ornot content:return jsonify({'error':'文件名和内容不能为空'}),400# 拼接文件路径 file_path = DOCS_DIR /f'{filename}.md'# 写入文件(UTF-8 编码)withopen(file_path,'w', encoding='utf-8')as f: f.write(content)return jsonify({'success':True,'message':'文件保存成功','filePath':str(file_path)})except Exception as e:return jsonify({'error':f'保存文件失败: {str(e)}'}),500# 加载文档 (API)@app.route('/api/load/<filename>', methods=['GET'])defload_document(filename):try: file_path = DOCS_DIR /f'{filename}.md'# 检查文件是否存在ifnot file_path.exists():return jsonify({'error':'文件不存在'}),404# 读取文件内容withopen(file_path,'r', encoding='utf-8')as f: content = f.read()return jsonify({'success':True,'content': content})except Exception as e:return jsonify({'error':f'加载文件失败: {str(e)}'}),500# 获取文档列表 (API)@app.route('/api/docs', methods=['GET'])deflist_docs():try:# 读取目录下所有 .md 文件 docs =[]forfilein DOCS_DIR.glob('*.md'): docs.append({'name':file.stem,# 不带扩展名的文件名'path':str(file)})return jsonify({'success':True,'docs': docs})except Exception as e:return jsonify({'error':f'获取文档列表失败: {str(e)}'}),500# 静态文件服务(兼容前端资源加载)@app.route('/public/<path:path>')defserve_static(path):return send_from_directory('public', path)# ---- 启动服务器 ----if __name__ =='__main__':# 启动 Flask 开发服务器(生产环境建议用 Gunicorn) app.run( host='127.0.0.1',# 不允许外部访问 port=8000,# 与原 Node.js 端口保持一致 debug=True# 开发模式(生产环境关闭))

3. 目录结构说明

需要和原 Node.js 版本保持一致的目录结构,确保前端页面能正常加载:

TREE /F md-editor md-editor ├── app.py # Python 服务端代码 ├── docs/ # 文档保存目录(自动创建) │ └── demo.md ├── public/ # 静态资源目录(前端 JS/CSS) │ ├── js/ │ │ ├── mermaid.min.js │ │ └── highlight.min.js │ └── css/ │ └── github-dark.min.css └── views/ # 模板目录 └── editor.html # 原 Node.js 版本的 editor.ejs(无需修改) 

4. 核心功能说明

  1. Markdown 解析
    • 使用 mistune 2 作为核心解析器,兼容 GFM 规范
    • 自定义渲染器支持 Mermaid 代码块(输出 <div>
    • 使用 Pygments 实现代码高亮(兼容 highlight.js 样式)
    • 启用表格、任务列表、脚注等扩展
  2. API 接口
    • /api/parse:POST 请求,解析 Markdown 为 HTML
    • /api/save:POST 请求,保存 Markdown 文档
    • /api/load/<filename>:GET 请求,加载指定文档
    • /api/docs:GET 请求,获取所有文档列表
  3. 前端兼容
    • 静态资源路径、接口地址与原 Node.js 版本完全一致
    • 复用原 editor.html 前端页面,只需修改一行
      cd public\css
      rename editor.ejs editor.html
      修改第6行:<title>{{ title }}</title>

5. 运行方式

直接运行

python app.py

生产环境建议用 Gunicorn

gunicorn -w 4 -b 0.0.0.0:8000 app:app

6. 关键注意事项

  1. 静态资源:需要将原 Node.js 版本中 public 目录下的 js/mermaid.min.jsjs/highlight.min.jscss/github-dark.min.css 复制到 Python 项目的 public 目录中。
  2. 公式渲染:数学公式渲染仍由前端 KaTeX 处理,服务端仅负责 Markdown 解析,与原逻辑一致。
  3. 编码:所有文件读写均使用 UTF-8 编码,确保中文正常显示。
  4. 兼容性:接口返回格式与原 Node.js 版本完全一致,前端无需任何修改即可对接。

该实现完整复刻了原 Node.js 版本的所有核心功能,同时符合 Python/Flask 的开发规范,可直接替换原服务端使用。

Read more

【实战】Windows 下为 Stable Diffusion WebUI 编译 Flash-Attention 2.8.0 专属 Wheel(RTX 3090 sm_86)

【实战】Windows 下为 Stable Diffusion WebUI 编译 Flash-Attention 2.8.0 专属 Wheel(RTX 3090 sm_86)

【实战】Windows 下为 Stable Diffusion WebUI 编译 Flash-Attention 2.8.0 专属 Wheel(RTX 3090 sm_86) 系列:Windows AI 环境 “没有轮子(.whl)就自己造” 从零到一 · 第 N 期 难度:⭐⭐⭐⭐ 适用场景:SD WebUI + xformers 0.0.31.post1 + flash-attn 版本冲突修复 适用场景:其他版本的 Flash-Attention 编译实战请见文末引用链接 一、背景与问题描述 彻底解决 Stable Diffusion WebUI 启动报错:

零基础掌握OpenDroneMap:无人机影像一键转3D建模的神奇工具

零基础掌握OpenDroneMap:无人机影像一键转3D建模的神奇工具 【免费下载链接】ODMA command line toolkit to generate maps, point clouds, 3D models and DEMs from drone, balloon or kite images. 📷 项目地址: https://gitcode.com/gh_mirrors/od/ODM 还在为复杂的无人机数据处理而头疼?OpenDroneMap这款开源神器让你轻松实现从航拍照片到专业三维模型的华丽转变。无论是农业监测、地形分析还是建筑测绘,这个免费工具都能帮你完成从原始影像到精美成果的完整处理流程。 🚀 五分钟快速上手:从安装到出图 环境搭建超简单 git clone https://gitcode.com/gh_mirrors/od/ODM cd ODM 一键处理真便捷

【ros2】从零认识URDF:机器人模型描述的“说明书”

文章目录 * 从零认识URDF:机器人模型描述的“说明书” * 一、URDF到底是什么?能做什么? * 1. 核心定位:机器人的“数字孪生说明书” * 2. URDF的四大核心功能 * 二、URDF的基本结构:XML格式的“零件清单” * 1. 根节点:`<robot>` * 2. 核心组件一:`<link>`——机器人的“零件” * (1)`<visual>`:定义零件的“长相”(仅用于显示) * (2)`<collision>`:定义零件的“碰撞边界”(物理计算用) * (3)`<inertial>`:定义零件的“重量和惯性”(动力学计算用)

智元 D1 强化学习sim-to-real系列 | Robot Lab 基于 Isaac Lab 的机器人强化学习使用(四)

智元 D1 强化学习sim-to-real系列 | Robot Lab 基于 Isaac Lab 的机器人强化学习使用(四)

1. 项目简介 Robot Lab 是一个基于 NVIDIA Isaac Lab 构建的机器人强化学习扩展库,专注于为各类机器人提供标准化的强化学习训练环境。该项目允许开发者在独立的环境中进行开发,而无需修改核心 Isaac Lab 仓库。对应ISaac lab 使用需要你参考并学习。然后可以参考Isaac Sim|操作界面指南,ISAAC SIM安装与软件实践学习(二)—用户界面与工作流程,Nvidia Isaac Sim图形界面 入门教程 2024(3)学习操作。最全的资料还是我们之前讲到的isaacsim官方教程以及isaaclab翻译版本 NVIDIA的机器人平台主要由两大核心组件构成,它们之间是层级关系:基础仿真平台Isaac Sim,以及构建于其上的机器人学习应用框架Isaac Lab。要精通 Isaac Sim,必须理解其分层架构中的五个核心概念。Isaac Sim 是什么? 它是一个通用的机器人模拟器,提供了高保真的物理引擎(PhysX)和照片级的渲染技术(