跳到正文
QuireKit MSFE
开发者文档
v0.0.0 · 实验版本

Markdown 插件

把新的语法接入增量解析、语义查询和源码呈现,而不引入 HTML 往返。

先区分三类插件

能力MSFE 入口是否改源码
新语法识别addMarkdownExtensions() 的 Lezer Markdown 扩展否
已有语法的组件和视觉效果addSource()、addNodeView()、addProjectionLayers()渲染本身不改
输入和粘贴时替换文本InputRule、PasteRule是,参与事务和历史

markdown-it 插件接受 token 流、规则链和 HTML renderer;MSFE 使用 Lezer 的增量语法树。这两种协议不同,不能把 md.use(plugin) 的插件对象直接放进 extensions。可以在隔离的非编辑预览中使用第三方渲染库,但解析、源码范围和写回仍需自己接入。

一个真实的解析插件

可选文档属性

Frontmatter 只识别源码。只有显式安装 DocumentProperties 才会将文首 YAML 显示成属性表; MD Editor 默认不安装它。Vue 宿主可以复用公共编辑面板:

vue

MD Editor 已包含 Frontmatter;直接使用 MSFE Core 时须在 extensions 中同时加入 Frontmatter。不传 render 时提供原生属性展示和查看源码入口。

setDocumentPropertiesEnabled(editor, false) 可恢复原始 Frontmatter,true 再次启用, 不重建编辑器、不清空撤销、不改正文和选区。用 documentPropertiesEnabled(editor.state) 读取实际状态。示例页的“文档属性”开关使用这个公共接口。

defaultCollapsed: true 让属性区初始只显示标题和数量,适合优先展示正文的产品; 省略或设为 false 时默认展开。此配置同时适用于 Vue 面板与默认原生渲染器。 用户手动切换后,同一文档内的编辑、模式切换、投影开关和视口重挂载都会保留选择; replaceDocument 加载另一篇文档时重新使用默认值。enabled: false 会显示原 YAML, 与折叠属性区不同。跨会话记忆可由宿主保存,并作为下一次安装的默认值。

运行时可通过 documentPropertiesCollapsed(editor.state) 读取、 setDocumentPropertiesCollapsed(editor, true) 收起,false 展开;自定义渲染器使用 view.collapsed 与 view.setCollapsed()。只读模式也能折叠,不改变编辑权限。

MdDocumentProperties 默认预览六个字段,长文本与标签列表可单独展开。 点击字段值直接编辑,确认与取消保持同行;单行 Enter 保存,Escape 取消,多行可用 ⌘/Ctrl + Enter 保存。收起面板保留未保存草稿,展开状态不会写入 Markdown。

字符串、数字、布尔和字符串列表可编辑,操作参与源码撤销。其他值展示原文;无效 YAML、 重复键、别名、锚点、显式标签、行内或缩进根映射、显式或跨行键、TOML、未闭合或超过 20,000 字符的头部回退源码。新增属性名始终编码为字符串键。 写回只替换目标范围,保留其他字段、注释和空行;文档或头部已变化时拒绝过期表单。 源码模式显示完整原文,编辑器只读时不提供修改控件。

自定义徽标

本例支持 :badge[label]:,保留可见分隔符并用主题色标记。未闭合、超长或含嵌套方括号的内容保持普通源码;代码 span 内的同样字符串不被当作徽标。

正在准备编辑器…

1. 贡献语法

依赖 @quirekit/lezer-markdown,使用 MarkdownExtension。plugins/syntax.ts 的 defineNodes 注册 ExampleBadge,parseInline 在看到 : 时先检查精确前缀,再在最多 82 个后续单元内寻找合法结束。

context.elt() 创建与规范源码同坐标的语法元素,addElement() 返回消费到的位置;不匹配返回 -1。before / after 是解析规则顺序,不是视觉优先级。这个例子有意不支持嵌套;更复杂语法必须定义明确的块/行内规则和回退。

简单的、不嵌套的单行字面分隔符可以直接使用 defineSource({ syntax }),参考 状态节点。不要为了简单 token 额外维护一个全文件解析器。

2. 接入语义查询

addSource() 将已确认的 ExampleBadge 解释为 { label }。read() 只读匹配范围;需要可编辑字段时再增加 addAttributes() 的验证与 patch()。语义层不需要渲染成 HTML。

ts

查询默认针对当前选区,可传显式有界范围。pending 表示相关解析还未确认,不能误判为文档里不存在语法;unsupported 表示该语义入口不可用。需要解析推进时使用 requestMarkdownParse(editor.state),再通过接受状态的通知重试,不在输入路径同步解析全文。

3. 选择视觉与写回

示例 inline 层只返回 mark,并用 EditorView.theme() 设置颜色,不隐藏分隔符。需要点击控件时使用 NodeView;需要跨行结构替换时使用 block 层。只做显示的插件不要附带输入转换,避免加载插件时悄悄改文档。

迁移一个 markdown-it 插件

  1. 列出它的语法、输入输出、是否有块嵌套、转义和引用规则。
  2. 用 Lezer 语法保证不完整输入、代码区域和嵌套上下文的行为。
  3. 用源码 codec 描述字段;没有可逆编码的字段先保持只读。
  4. 通过投影或组件提供视觉结果;HTML 输出另由导出管线实现。
  5. 为每项能力建立源码 fixture:原样读取、局部写回、撤销、加载/错误、只读及解析未完成。

很多常用能力已经有内置扩展,不需要移植同名插件。先查 功能与安装,再看 输入规则 和 投影层。

MSFE · QuireKitMarkdown 源码始终属于你。