菜单

笔记编辑与渲染

相关源文件

本文档描述了 Joplin 的笔记编辑和渲染系统,涵盖了用户如何在桌面和移动应用程序中与笔记内容进行交互。它解释了各种编辑器实现(富文本、markdown 和纯文本)、内容如何在不同格式之间转换以及如何显示给用户。

有关数据模型和笔记存储方式的信息,请参阅 数据模型。有关设备之间同步的详细信息,请参阅 同步引擎

核心架构

Joplin 提供多种笔记编辑方式,并通过单独的渲染管道来显示笔记内容。

来源

  • packages/app-desktop/gui/NoteEditor/NoteEditor.tsx
  • packages/app-desktop/gui/NoteEditor/utils/types.ts
  • packages/app-desktop/gui/NoteTextViewer.tsx

编辑器选择流程

Joplin 根据应用程序设置和状态选择编辑器类型。

  1. TinyMCE - 当 editorCodeView 为 false(默认)时,使用富文本(所见即所得)编辑器。
  2. CodeMirror6 - 当 editorCodeView 为 true 时,使用现代 markdown 编辑器。
  3. CodeMirror5 - 当 editorCodeView 为 true 且 editor.legacyMarkdown 启用时,使用旧版 markdown 编辑器。
  4. PlainEditor - 在安全模式下使用的简单文本编辑器。

选择逻辑定义在:

来源

  • packages/app-desktop/gui/NoteEditor/NoteEditor.tsx:680-686

通用编辑器接口

所有编辑器都实现相同的接口,为容器组件提供一致的 API。

NoteBodyEditorProps 接口为所有编辑器提供了标准化的 props。

  • content:当前笔记内容。
  • contentKey:唯一 ID(通常是笔记 ID)。
  • contentMarkupLanguage:格式类型(Markdown 或 HTML)。
  • onChange:内容更改的回调。
  • markupToHtml:用于渲染的转换函数。
  • htmlToMarkdown:用于 TinyMCE 的转换函数。
  • 许多其他配置选项和回调。

来源

  • packages/app-desktop/gui/NoteEditor/utils/types.ts:72-79
  • packages/app-desktop/gui/NoteEditor/utils/types.ts:82-142

编辑器实现

TinyMCE(富文本)

TinyMCE 为笔记提供所见即所得的编辑体验。

主要功能

  • 带格式化控件的工具栏
  • 即时可视化格式
  • 链接插入和编辑
  • 表格、列表和复选框
  • 资源嵌入(图片、文件)
  • 用于扩展功能的插件

来源

  • packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx

CodeMirror(Markdown)

CodeMirror 为 markdown 提供面向代码的编辑体验。

主要功能

  • Markdown 语法高亮
  • 分屏视图,带 HTML 预览
  • 搜索和替换
  • 多光标支持
  • 代码折叠
  • 可选的 Vim/Emacs 键绑定

来源

  • packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx
  • packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx
  • packages/editor/CodeMirror/CodeMirrorControl.ts

渲染管道

渲染管道将笔记内容从存储格式(markdown 或 HTML)转换为显示的 HTML。

MarkupToHtml

MarkupToHtml 类充当外观,根据笔记的标记语言将渲染请求路由到 MdToHtmlHtmlToHtml

来源

  • packages/renderer/MarkupToHtml.ts
  • packages/renderer/MdToHtml.ts
  • packages/renderer/HtmlToHtml.ts

MdToHtml

MdToHtml 类使用一系列规则和插件来渲染 markdown 内容。

来源

  • packages/renderer/MdToHtml.ts:43-58

NoteTextViewer

NoteTextViewer 组件是一个 WebView,用于显示渲染后的 HTML。它处理:

  • 加载渲染的 HTML
  • 加载插件资源(CSS、JS)
  • 双向滚动同步
  • 链接处理
  • 用户交互

来源

  • packages/app-desktop/gui/NoteTextViewer.tsx
  • packages/app-desktop/gui/note-viewer/index.html

使用 FormNote 进行状态管理

FormNote 接口表示正在编辑的笔记的当前状态并管理更改。

useFormNote hook 提供:

  • 从数据库加载笔记
  • 跟踪笔记内容的更改
  • 处理保存操作
  • 资源附件管理
  • 处理笔记加密/解密

来源

  • packages/app-desktop/gui/NoteEditor/utils/useFormNote.ts
  • packages/app-desktop/gui/NoteEditor/utils/types.ts:144-190

命令系统

编辑器实现了一个通用的命令系统,提供了一致的功能。

命令类型定义在 EditorCommandType 枚举中。

来源

  • packages/editor/types.ts:4-80
  • packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.ts
  • packages/editor/CodeMirror/editorCommands/editorCommands.ts

移动端实现

移动应用使用了不同的基于 WebView 集成的架构。

与桌面的主要区别:

  • 使用 WebView 托管 CodeMirror。
  • 通过 React Native 和 WebView 之间的消息传递进行通信。
  • 为触摸界面简化的工具栏和控件。
  • 平台特定的资源处理。

来源

  • packages/app-mobile/components/NoteEditor/NoteEditor.tsx
  • packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts

上下文菜单和特殊功能

两个编辑器都实现了具有不同功能的上下文菜单。

上下文菜单的实现因编辑器而异。

  • TinyMCE:在 useContextMenu.ts 中使用自定义处理程序。
  • CodeMirror:使用带有扩展的内置上下文菜单。

来源

  • packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts
  • packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts

结论

Joplin 的笔记编辑和渲染系统提供了多种编辑笔记的方式,同时保持了应用程序内的一致显示。该架构将编辑器实现与渲染管道分开,从而在笔记的编辑和显示方式上具有灵活性。

模块化设计和标准化的接口允许:

  • 多种编辑器实现(TinyMCE、CodeMirror、PlainText)。
  • 跨编辑器的一致命令执行。
  • 跨平台支持(桌面和移动)。
  • 通过插件和自定义渲染规则进行扩展。

这种方法确保用户可以选择他们喜欢的编辑体验,同时可靠地渲染具有数学公式、图表、代码高亮和资源附件等高级功能的笔记内容。

来源

  • packages/app-desktop/gui/NoteEditor/NoteEditor.tsx
  • packages/renderer/MarkupToHtml.ts
  • packages/editor/types.ts