笔记编辑与渲染
相关源文件
本文档描述了 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 根据应用程序设置和状态选择编辑器类型。
- TinyMCE - 当
editorCodeView 为 false(默认)时,使用富文本(所见即所得)编辑器。
- CodeMirror6 - 当
editorCodeView 为 true 时,使用现代 markdown 编辑器。
- CodeMirror5 - 当
editorCodeView 为 true 且 editor.legacyMarkdown 启用时,使用旧版 markdown 编辑器。
- 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 类充当外观,根据笔记的标记语言将渲染请求路由到 MdToHtml 或 HtmlToHtml。
来源
- 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 接口表示正在编辑的笔记的当前状态并管理更改。
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