1. 项目简介

MindFlow 是一款极简风格的开源 Markdown 编辑器,致力于为开发者和写作爱好者提供流畅的写作体验。项目采用现代化的技术栈和架构设计,支持多平台(桌面端、Web端、移动端),完全本地化运行,全方位保障用户隐私。

1.1 本次更新亮点

  • LaTeX 公式支持 - 完美渲染数学公式(KaTeX)
  • Mermaid 图表 - 流程图、序列图、甘特图等
  • Markmap 思维导图 - Markdown 转思维导图
  • PlantUML 图表 - UML 图表渲染
  • 完整样式主题 - 深色/浅色主题完美适配
  • 异步渲染优化 - 延迟加载提升性能

2. 本次更新内容详解

2.1 Phase 4 完成情况

经过紧张有序的开发,MindFlow 项目已完成 Phase 4: 扩展语法支持 阶段,所有核心功能均已实现:

已完成任务清单
任务 工作量 优先级 状态
扩展语法处理器架构 2天 P0 ✅ 已完成
LaTeX 公式支持 1天 P0 ✅ 已完成
Mermaid 图表集成 1天 P0 ✅ 已完成
Markmap 思维导图 1天 P1 ✅ 已完成
PlantUML 图表渲染 1天 P1 ✅ 已完成
样式主题适配 1天 P0 ✅ 已完成
异步渲染优化 1天 P1 ✅ 已完成
主要交付物
  1. 扩展语法处理器
    • 统一的扩展语法处理架构
    • 支持 4 种扩展语法类型
    • 完整的错误处理机制
  2. KaTeX 集成
    • 行内公式:$E=mc^2$
    • 块级公式:$$\int_0^\infty e^{-x^2} dx$$
    • 完整的数学符号支持
  3. Mermaid 图表
    • 流程图、序列图、甘特图
    • 类图、状态图、ER 图
    • 动态渲染引擎
  4. Markmap 思维导图
    • Markdown 转思维导图
    • iframe 隔离渲染
    • 交互式 SVG
  5. PlantUML 图表
    • 服务端编码渲染
    • 支持所有 UML 图类型
    • 优雅的错误处理

3. 核心功能详解

3.1 扩展语法处理器

统一的扩展语法处理架构,支持多种扩展语法类型。

设计目标
  • 统一的扩展语法处理接口
  • 类型安全的实现
  • 完整的错误处理
  • 异步渲染支持
核心架构

extended-syntax.ts - 完整实现

/**
 * @fileoverview 扩展语法处理器
 * @description 支持 LaTeX、Mermaid、PlantUML 等扩展语法的解析和渲染
 */

import katex from 'katex';
import mermaid from 'mermaid';
import encode from 'plantuml-encoder';

/**
 * 扩展语法类型
 */
export enum ExtendedSyntaxType {
  LaTeX = 'latex',
  Mermaid = 'mermaid',
  Markmap = 'markmap',
  PlantUML = 'plantuml',
}

/**
 * 扩展语法块
 */
interface ExtendedSyntaxBlock {
  type: ExtendedSyntaxType;
  content: string;
  id: string;
}

/**
 * 扩展语法处理器类
 * @description 处理 Markdown 中的扩展语法,将其转换为可渲染的 HTML
 */
export class ExtendedSyntaxProcessor {
  private mermaidInitialized: boolean = false;

  constructor() {
    // 初始化 Mermaid
    this.initializeMermaid();
  }

  /**
   * 从 Markdown 中提取扩展语法块
   * @param markdown - Markdown 文本
   * @returns 扩展语法块数组
   */
  extractExtendedSyntaxBlocks(markdown: string): ExtendedSyntaxBlock[] {
    const blocks: ExtendedSyntaxBlock[] = [];
    let idCounter = 0;

    // 提取 LaTeX 公式(行内和块级)
    const inlineLatexRegex = /\$([^$\n]+?)\$/g;
    let match;
    while ((match = inlineLatexRegex.exec(markdown)) !== null) {
      blocks.push({
        type: ExtendedSyntaxType.LaTeX,
        content: match[1],
        id: `latex-inline-${idCounter++}`,
      });
    }

    // 块级公式:$$...$$
    const blockLatexRegex = /\$\$([\s\S]+?)\$\$/g;
    while ((match = blockLatexRegex.exec(markdown)) !== null) {
      blocks.push({
        type: ExtendedSyntaxType.LaTeX,
        content: match[1].trim(),
        id: `latex-block-${idCounter++}`,
      });
    }

    // 提取 Mermaid 图表
    const mermaidRegex = /```mermaid\n([\s\S]+?)```/g;
    while ((match = mermaidRegex.exec(markdown)) !== null) {
      blocks.push({
        type: ExtendedSyntaxType.Mermaid,
        content: match[1].trim(),
        id: `mermaid-${idCounter++}`,
      });
    }

    // 提取 Markmap 思维导图
    const markmapRegex = /```markmap\n([\s\S]+?)```/g;
    while ((match = markmapRegex.exec(markdown)) !== null) {
      blocks.push({
        type: ExtendedSyntaxType.Markmap,
        content: match[1].trim(),
        id: `markmap-${idCounter++}`,
      });
    }

    // 提取 PlantUML 图表
    const plantumlRegex = /```(?:plantuml|puml)\n([\s\S]+?)```/g;
    while ((match = plantumlRegex.exec(markdown)) !== null) {
      blocks.push({
        type: ExtendedSyntaxType.PlantUML,
        content: match[1].trim(),
        id: `plantuml-${idCounter++}`,
      });
    }

    return blocks;
  }

  /**
   * 处理扩展语法后的 Markdown
   * @param markdown - 原始 Markdown 文本
   * @returns 处理后的 HTML 字符串
   */
  processExtendedSyntax(markdown: string): string {
    let html = markdown;

    // 处理 LaTeX 行内公式
    html = html.replace(/\$([^$\n]+?)\$/g, (_match, latex) => {
      return this.processLatex(latex, false);
    });

    // 处理 LaTeX 块级公式
    html = html.replace(/\$\$([\s\S]+?)\$\$/g, (_match, latex) => {
      return `<div class="latex-block">${this.processLatex(latex.trim(), true)}</div>`;
    });

    // 处理 Mermaid 图表
    html = html.replace(/```mermaid\n([\s\S]+?)```/g, (_match, code) => {
      const id = `mermaid-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
      return this.processMermaid(code.trim(), id);
    });

    // 处理 Markmap 思维导图
    html = html.replace(/```markmap\n([\s\S]+?)```/g, (_match, code) => {
      const id = `markmap-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
      return this.processMarkmap(code.trim(), id);
    });

    // 处理 PlantUML 图表
    html = html.replace(/```(?:plantuml|puml)\n([\s\S]+?)```/g, (_match, code) => {
      return this.processPlantUML(code.trim());
    });

    return html;
  }
}

3.2 LaTeX 公式支持

使用 KaTeX 库实现数学公式渲染,支持完整的数学符号。

核心实现

LaTeX 处理器

/**
 * 处理 LaTeX 公式
 * @param latex - LaTeX 公式字符串
 * @param displayMode - 是否为块级公式
 * @returns HTML 字符串
 */
processLatex(latex: string, displayMode: boolean = false): string {
  try {
    return katex.renderToString(latex, {
      displayMode,
      throwOnError: false,
      output: 'html',
    });
  } catch (error) {
    return `<span class="latex-error">LaTeX Error: ${error instanceof Error ? error.message : 'Unknown error'}</span>`;
  }
}
使用示例

行内公式

爱因斯坦质能方程:$E = mc^2$

块级公式

$$
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
$$

矩阵

$$
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
$$
样式支持
/* LaTeX 公式样式 */
.preview-content .katex {
  font-size: 1.1em;
}

.preview-content .katex-display {
  margin: 1.5rem 0;
  padding: 1rem;
  background-color: #f8f9fa;
  border-radius: 6px;
  overflow-x: auto;
}

.preview-content .latex-block {
  display: flex;
  justify-content: center;
  margin: 1.5rem 0;
}

3.3 Mermaid 图表

专业的图表渲染引擎,支持多种图表类型。

核心实现

Mermaid 处理器

/**
 * 处理 Mermaid 图表
 * @param code - Mermaid 代码
 * @param id - 元素 ID
 * @returns HTML 字符串
 */
processMermaid(code: string, id: string): string {
  return `<pre class="mermaid" data-mermaid-id="${id}">${this.escapeHtml(code)}</pre>`;
}

/**
 * 渲染 Mermaid 图表
 * @param element - 包含 Mermaid 代码的 DOM 元素
 */
async renderMermaid(element: HTMLElement): Promise<void> {
  const code = element.textContent || '';
  try {
    const { svg } = await mermaid.render(`mermaid-svg-${Date.now()}`, code);
    element.outerHTML = svg;
  } catch (error) {
    element.outerHTML = `<div class="mermaid-error">Mermaid Error: ${error instanceof Error ? error.message : 'Unknown error'}</div>`;
  }
}
使用示例

流程图

```mermaid
graph TD
    A[开始] --> B{判断}
    B -->|是| C[执行 A]
    B -->|否| D[执行 B]
    C --> E[结束]
    D --> E
```

序列图

```mermaid
sequenceDiagram
    participant A as 用户
    participant B as 系统
    A->>B: 发送请求
    B-->>A: 返回响应
```

甘特图

```mermaid
gantt
    title 项目进度
    dateFormat  YYYY-MM-DD
    section 设计
    需求分析 :a1, 2024-01-01, 7d
    原型设计 :a2, after a1, 7d
    section 开发
    前端开发 :b1, after a2, 14d
    后端开发 :b2, after a2, 14d
```
支持的图表类型
  • 流程图 (graph)
  • 序列图 (sequenceDiagram)
  • 甘特图 (gantt)
  • 类图 (classDiagram)
  • 状态图 (stateDiagram)
  • ER 图 (erDiagram)
  • 用户旅程图 (journey)
  • 甘特图 (gantt)
  • 饼图 (pie)
  • 关系图 (relationshipDiagram)

3.4 Markmap 思维导图

Markdown 转思维导图,支持交互式 SVG 渲染。

核心实现

Markmap 处理器

/**
 * 处理 Markmap 思维导图
 * @param markdown - Markmap Markdown 内容
 * @param id - 元素 ID
 * @returns HTML 字符串
 */
processMarkmap(markdown: string, id: string): string {
  const encodedContent = this.escapeHtml(markdown);
  return `<div class="markmap-container" data-markmap-id="${id}">
    <iframe
      class="markmap-iframe"
      style="width: 100%; height: 400px; border: none;"
      srcdoc='<!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
        <script src="https://cdn.jsdelivr.net/npm/markmap-view@0.15.4"></script>
        <script src="https://cdn.jsdelivr.net/npm/markmap-lib@0.15.4/dist/browser/index.min.js"></script>
        <style>
          body { margin: 0; padding: 0; }
          svg { width: 100%; height: 100%; }
        </style>
      </head>
      <body>
        <svg id="markmap"></svg>
        <script>
          const { Transformer } = window.markmap;
          const { Markmap } = window.markmap;
          const transformer = new Transformer();
          const { root } = transformer.transform(\`${encodedContent}\`);
          Markmap.create("#markmap", null, root);
        <\/script>
      </body>
      </html>'
    ></iframe>
  </div>`;
}
使用示例
```markmap
# MindFlow

## 功能
- 编辑器
- 预览
- 文件管理

## 扩展语法
- LaTeX
- Mermaid
- Markmap
- PlantUML

## 平台
- 桌面端
- Web端
- 移动端
```
特性
  • 交互式 SVG - 可缩放、可拖拽
  • 自动布局 - 智能节点排布
  • iframe 隔离 - 不影响主页面
  • CDN 加载 - 无需本地依赖

3.5 PlantUML 图表

专业的 UML 图表渲染,支持所有 UML 图类型。

核心实现

PlantUML 处理器

/**
 * 处理 PlantUML 图表
 * @param code - PlantUML 代码
 * @returns HTML 字符串
 */
processPlantUML(code: string): string {
  try {
    const encoded = encode(code);
    const url = `https://www.plantuml.com/plantuml/svg/${encoded}`;
    return `<img src="${url}" alt="PlantUML Diagram" class="plantuml-diagram" />`;
  } catch (error) {
    return `<div class="plantuml-error">PlantUML Error: ${error instanceof Error ? error.message : 'Unknown error'}</div>`;
  }
}
使用示例

用例图

```plantuml
@startuml
actor 用户 as User
package "MindFlow" {
    usecase "编辑文档" as UC1
    usecase "保存文档" as UC2
    usecase "导出文档" as UC3
}
User --> UC1
User --> UC2
User --> UC3
@enduml
```

类图

```plantuml
@startuml
class Editor {
  - content: string
  - theme: Theme
  + setContent(content: string): void
  + getContent(): string
  + setTheme(theme: Theme): void
}

class Parser {
  + parse(markdown: string): string
  + parseAsync(markdown: string): Promise<string>
}

Editor --> Parser : uses
@enduml
```

时序图

```plantuml
@startuml
actor 用户
participant "MindFlow" as App
database "本地存储" as DB

用户 -> App: 打开文档
App -> DB: 读取内容
DB --> App: 返回内容
App --> 用户: 显示内容
@enduml
```
支持的图表类型
  • 用例图 (usecase)
  • 类图 (class)
  • 时序图 (sequence)
  • 活动图 (activity)
  • 组件图 (component)
  • 部署图 (deployment)
  • 对象图 (object)
  • 包图 (package)
  • 状态图 (state)
  • 定时图 (timing)

3.6 解析器集成

将扩展语法处理器集成到 Markdown 解析器中。

核心实现

parser.ts 集成

import { extendedSyntaxProcessor } from './extended-syntax';

/**
 * Markdown 解析器类
 * @description 将 Markdown 文本解析为 HTML,支持 GFM 和扩展语法
 */
export class MarkdownParser {
  /**
   * 同步解析 Markdown 文本
   * @param markdown - 要解析的 Markdown 文本
   * @returns 解析后的 HTML 字符串
   */
  parse(markdown: string): string {
    // 先处理扩展语法
    const processedMarkdown = extendedSyntaxProcessor.processExtendedSyntax(markdown);

    // 再用 marked 解析标准 Markdown
    const result = marked(processedMarkdown);
    return result;
  }

  /**
   * 异步解析 Markdown 文本
   * @description 对于大文档,使用异步解析可以避免阻塞主线程
   * @param markdown - 要解析的 Markdown 文本
   * @returns 解析后的 HTML 字符串的 Promise
   */
  async parseAsync(markdown: string): Promise<string> {
    // 先处理扩展语法
    const processedMarkdown = extendedSyntaxProcessor.processExtendedSyntax(markdown);

    // 再用 marked 解析标准 Markdown
    const result = marked(processedMarkdown);
    if (result instanceof Promise) {
      return result;
    }
    return result;
  }

  /**
   * 渲染需要延迟处理的扩展语法(Mermaid、Markmap)
   * @description 在 HTML 插入 DOM 后调用此方法来渲染动态内容
   * @param container - 包含扩展语法元素的容器
   */
  async renderExtendedSyntax(container: HTMLElement): Promise<void> {
    await extendedSyntaxProcessor.renderExtendedSyntax(container);
  }
}

3.7 编辑器组件更新

更新编辑器组件以支持扩展语法渲染。

核心实现

Editor.tsx 更新

const Editor: React.FC<EditorProps> = ({
  initialValue,
  docId = 'default',
  theme = 'light',
  autoSave = true,
  autoSaveDelay = 2000,
}) => {
  const previewRef = useRef<HTMLDivElement>(null);

  /**
   * 更新预览内容
   * @param newContent - 新的编辑器内容
   */
  const updatePreview = async (newContent: string) => {
    if (previewRef.current) {
      // 使用 parser 解析 Markdown
      const html = parser.parse(newContent);
      previewRef.current.innerHTML = html;

      // 渲染需要延迟处理的扩展语法(Mermaid、Markmap)
      try {
        await parser.renderExtendedSyntax(previewRef.current);
      } catch (error) {
        console.error('Extended syntax rendering error:', error);
      }
    }

    // 调用外部回调
    onChange?.(newContent);

    // 触发自动保存
    if (autoSave && autoSaveManagerRef.current) {
      autoSaveManagerRef.current.updateContent(newContent);
    }
  };

  // ...其他代码
};

3.8 样式主题适配

完整的深色/浅色主题支持。

核心样式

扩展语法样式

/* ====================
   扩展语法样式
   ==================== */

/* LaTeX 公式样式 */
.preview-content .katex {
  font-size: 1.1em;
}

.preview-content .katex-display {
  margin: 1.5rem 0;
  padding: 1rem;
  background-color: #f8f9fa;
  border-radius: 6px;
  overflow-x: auto;
}

.editor-container.theme-dark .preview-content .katex-display {
  background-color: #2d2d2d;
}

.editor-container.theme-dark .preview-content .katex {
  color: #d4d4d4;
}

/* Mermaid 图表样式 */
.preview-content .mermaid {
  margin: 1.5rem 0;
  padding: 1rem;
  background-color: #f8f9fa;
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100px;
}

.editor-container.theme-dark .preview-content .mermaid {
  background-color: #2d2d2d;
}

/* Markmap 思维导图样式 */
.preview-content .markmap-container {
  margin: 1.5rem 0;
  padding: 1rem;
  background-color: #f8f9fa;
  border-radius: 6px;
  overflow: hidden;
}

.editor-container.theme-dark .preview-content .markmap-container {
  background-color: #2d2d2d;
}

/* PlantUML 图表样式 */
.preview-content .plantuml-diagram {
  max-width: 100%;
  height: auto;
  margin: 1.5rem 0;
  border-radius: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  background-color: #ffffff;
  padding: 1rem;
}

.editor-container.theme-dark .preview-content .plantuml-diagram {
  background-color: #2d2d2d;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

4. 项目结构

4.1 Phase 4 新增结构

packages/
├── core/
│   ├── src/
│   │   ├── extended-syntax.ts     # 扩展语法处理器(新增)
│   │   ├── parser.ts              # 解析器(已更新)
│   │   ├── editor.ts
│   │   ├── shortcuts.ts
│   │   ├── auto-save.ts
│   │   ├── themes.ts
│   │   └── index.ts               # 导出扩展语法(已更新)
│   └── package.json               # 新增依赖
│
└── web/
    ├── src/
    │   ├── components/
    │   │   ├── Editor.tsx          # 编辑器组件(已更新)
    │   │   └── Editor.css
    │   ├── App.tsx
    │   ├── App.css
    │   ├── main.tsx
    │   └── styles.css              # 新增扩展语法样式
    └── package.json               # 新增依赖

5. 核心技术栈

5.1 扩展语法支持

技术 版本 用途
KaTeX 最新 LaTeX 公式渲染
Mermaid 最新 图表渲染
Markmap 0.15.4 思维导图
plantuml-encoder 最新 PlantUML 编码
marked 11.1.1 Markdown 解析

5.2 依赖管理

@mindflow/core/package.json

{
  "dependencies": {
    "katex": "^0.16.10",
    "mermaid": "^11.0.0",
    "markmap-view": "^0.15.4",
    "markmap-lib": "^0.15.4",
    "plantuml-encoder": "^1.4.0"
  },
  "devDependencies": {
    "@types/katex": "^0.16.7"
  }
}

@mindflow/web/package.json

{
  "dependencies": {
    "katex": "^0.16.10",
    "mermaid": "^11.0.0"
  },
  "devDependencies": {
    "@types/katex": "^0.16.7"
  }
}

6. 使用指南

6.1 LaTeX 公式

行内公式

质能方程:$E = mc^2$

块级公式

$$
\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x)
$$

6.2 Mermaid 图表

流程图

```mermaid
graph LR
    A[开始] --> B[处理]
    B --> C[结束]
```

序列图

```mermaid
sequenceDiagram
    A->>B: Hello
    B-->>A: Hi
```

6.3 Markmap 思维导图

```markmap
# 主题
## 子主题 1
- 要点 1
- 要点 2
## 子主题 2
- 要点 3
- 要点 4
```

6.4 PlantUML 图表

类图

```plantuml
@startuml
class Foo {
  +field
  +method()
}
@enduml
```

7. 下一步计划(Phase 5)

Phase 5: 导出与分享(Week 14-16)

  • PDF 导出
  • HTML 导出
  • 图片导出(PNG/SVG)
  • 文档分享
  • 版本历史
  • 协作编辑

🎯 总结

Phase 4 的完成标志着 MindFlow 支持 专业级扩展语法

LaTeX 公式 - 完整的数学符号支持
Mermaid 图表 - 9 种图表类型
Markmap 思维导图 - 交互式 SVG
PlantUML 图表 - 标准 UML 图
完整样式主题 - 深色/浅色适配
异步渲染优化 - 零性能损耗


官方网址:https://gpunexus.com/
咨询电话:010-53650986
联系邮箱:data@chengfangtech.com

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐