ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Plate 数学公式定界符触发(Math Delimiter Trigger)落地指南:从规格拆分、输入规则实现到路线图切片

2026/9/16 12:41:52 拓冰建站 浏览量
Plate 数学公式定界符触发(Math Delimiter Trigger)落地指南:从规格拆分、输入规则实现到路线图切片 Plate 数学公式定界符触发Math Delimiter Trigger落地指南从规格拆分、输入规则实现到路线图切片【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本文围绕 Plate 项目中数学公式定界符触发math delimiter trigger这条独立路线图切片展开完整梳理其三条行为行$选区包裹、$...$补全转换、$$块级触发的规格来源、实现落地与测试验证。读者将掌握为什么数学触发必须拆分成多个独立行而不是一个统一触发、Plate 如何通过createRuleFactory输入规则承载这些行为、MathKit的装配方式以及哪些分支被刻意保留为默认关闭。为什么要为数学定界符触发单独立项在 2026-04-10-math-delimiter-trigger-roadmap-slice.md 这份路线图切片中核心诉求是把数学定界符触发从仅存在于 parity 积压清单里的一句话提升为一条显式的、已入队的路线图条目。理由是现实的权威归属authority split的讨论已经存在行为行behavior rows已经在研究文档与规格中完成分解这项工作横跨多个局部接缝seammath包、相邻的按键/输入行为、editor-behavior 的规格与协议矩阵。一句话概括这项工作真实存在且跨模块不能再作为无名的后续备注项搁置。该切片建议的入队位置在 Toggle Rewrite 之后、更宽泛的 date/media 扩展车道之前原因是它仍属于 markdown 功能项比 date/media 扩展更窄、更有据可依且权威归属划分更清晰。切片定义的退出条件Exit同样值得注意路线图显式点名 math delimiter triggers路线图声明包/输入归属按行拆分而非伪造一个全局 math-trigger 赢家parity 不再是唯一点名这项工作的地方。进度记录显示支撑性路线图文档、完整实现计划、canonical 路线图与镜像实现路线图均已更新完毕——这正是本篇文章要展开的全部闭环内容。三条行为行先把表面拆开再谈归属数学定界符的输入行为看起来很简单但 math-delimiter-trigger-audits-must-split-selection-wrap-pair-on-type-and-block-detection.md 指出把$...$和$$...$$当作同一个面然后指定一个编辑器作为权威是错误的做法。实际行为至少拆成三条选区包裹selection-wrap已有选区时键入$用行内数学定界符包裹选中文本成对输入pair-on-type空插入点键入$块级检测/提升block detection / promotion$$触发块级公式。对应的权威归属也按行拆分Obsidian明确拥有保守的$选区包裹以及$$块级检测/预览历史Typora明确拥有$成对输入与$$Return提升Milkdown提供可执行executable-style的证据支撑成对输入与块触发机制。这样拆分后规格就能诚实地说Obsidian 在这里重要Typora 也在这里重要但它们证明的不是同一个机制。产品选择也由此区分选区包裹对 markdown 敏感符号更保守、更安全成对输入更快但更激进块检测可以在没有 Enter 驱动提升的情况下独立存在。这正是 markdown-editing-spec.md 与 editor-protocol-matrix.md 中EDIT-PROFILE-MATH-TRIGGER-001/002/003三条协议行的来源。规格中的三条协议行Readable Lawmarkdown-editing-spec.md 中三条协议行均标记为deviation偏离行逐条展开如下EDIT-PROFILE-MATH-TRIGGER-001选区包裹保持 deferredselect word type $ $word$规格明确Obsidian 将$归入 markdown 自动成对家族并认为保守的选区包裹策略是真实的产品选择。但该分支对默认富文本模式保持 deferred归属未来 markdown-native 或显式批准过的 profile。原因很实际在 Plate 默认富文本编辑器中$与$$共享同一符号族碰撞压力足够强选区包裹不应进入已发布的契约。EDIT-PROFILE-MATH-TRIGGER-002补全转换默认富文本模式已发布type closing $ for $x$ inline math node默认富文本模式在显式补全键入闭合$时转换而不是在开定界符处提交。这保证编辑器内容里不残留裸语法同时仍允许安全的富文本转换。当前仓库已发布显式补全的行内转换$...$。EDIT-PROFILE-MATH-TRIGGER-003$$ Enter 块级提升默认富文本模式已发布type $$ press ↵ block math editor规格强调$$Enter是独立的块级公式触发不是通用自动成对。Typora 与 Milkdown 对提升行为明确Obsidian 虽然没有同样的Enter提升形态但明确记录了$$独立行块检测与块预览因此仍然有参考价值。当前富文本模式将此作为显式的块补全边界发布。落地结果实现计划的实际闭环状态2026-04-10-math-delimiter-trigger-implementation-plan.md 记录了默认富文本切片的执行结果已发布Closed补全行内$...$的显式补全转换对应 002$$Enter块级提升对应 003。保持 deferred / 非默认选区包裹001——保持延迟空选区开定界符成对输入——保持延迟。关于 deferred 分支为何不进入默认富文本模式计划给出的理由与规格一致$和$$在富文本编辑器中已共享一个符号族把$选区包裹作为默认富文本分支会增加碰撞与歧义压力Obsidian 风格的保守选区包裹更适合作为 markdown/source-first profile 的产品决策而不是默认富文本编辑器的规则。计划还特别强调了一条纪律不要因为规格点名了 Row 001 就默认它在第一轮发布——它需要一个显式的产品决策因为当前 Plate 从未发布过$选区包裹的输入行为。问题框架既有三种数学支持缺的是第四种实现计划梳理了 Plate 已有的三种数学支持路径markdown 解析/序列化通过remark-math支持数学节点解析证明见 deserializeMdParagraphs.spec.tsx显式插入变换insertInlineEquation与insertEquation编辑器 UI 入口工具栏与斜杠命令。缺失的正是第四种$与$$的 markdown 敏感键入触发。由于这条缺口已经有了真实的协议行继续以以后再说处理不再诚实而且实现横跨多个模块需要一个完整计划而非又一个路线图占位符。计划的 Non-Goals 同样重要不重写数学渲染、KaTeX 输出或公式节点 UI不改变数学节点的 markdown 解析/序列化语义不解决每个 markdown 符号的通用自动成对策略不重新开放 autoformat 作为数学触发的宿主不发布完整的 profile 引擎重写。源码实现MathRules与createRuleFactory输入规则计划最初建议把触发表面托管在共享的platejs/autoformat输入规则中新增packages/autoformat/src/lib/rules/math/autoformatMathInput.ts。从当前仓库源码看实际落地采用了等价的共享输入规则路径数学触发规则定义在 packages/math/src/lib/MathRules.ts基于createRuleFactory构建并由MathKit装配到编辑器。行内$规则对应 002MathRules.ts 中variant: $分支是一个insertText类型规则trigger: $仅在键入$时尝试解析通过matchDelimitedInline匹配已完成的行内序列配置了行内边界正则INLINE_BOUNDARY_RE /[\s([{]/与后续正则INLINE_FOLLOW_RE /[\s)]}:;,.!?]/并以open: $、requireClosingDelimiter: false、trim: reject调用apply阶段先delete匹配区间再调用insertInlineEquation(editor, texExpression)插入行内公式节点enabled通过isEquationInputBlocked检查在代码块codeBlock、块级公式equation、行内公式inlineEquation节点内一律禁用。块级$$规则对应 003variant: $$分支是blockFence类型规则fence: $$、block: KEYS.p只从段落触发on: break | match两种触发时机默认富文本使用on: break即$$行 Enterpriority: 100apply阶段移除围栏路径上的节点再调用insertEquation(editor, { at, select: true })插入块级公式节点。显式插入变换既有能力保持不变insertInlineEquation.ts当未显式传入texExpression时用editor.api.string(editor.selection)取当前选区文本作为表达式插入type: editor.getType(KEYS.inlineEquation)的行内节点insertEquation.ts插入texExpression: 的空块级公式节点。这两条变换是显式插入、工具栏、斜杠命令与触发规则共用的底层能力计划要求触发实现保持显式插入、工具栏、斜杠命令与解析器行为不变。套件装配MathKitapps/www/src/registry/components/editor/plugins/math-kit.tsx 展示了真实装配方式export const MathKit [ InlineEquationPlugin.configure({ inputRules: [MathRules.markdown({ variant: $ })], node: { component: InlineEquationElement }, }), EquationPlugin.configure({ inputRules: [MathRules.markdown({ on: break, variant: $$ })], node: { component: EquationElement }, }), ];其中MathRules.markdown({ variant: $ })开启补全行内转换MathRules.markdown({ on: break, variant: $$ })开启$$ Enter 块级提升。注意这印证了计划的关键决策行内与块级规则分别挂在各自的插件上而不是揉成一个math 触发伪机制同时BaseMathKit见 math-base-kit.tsx只装配基础节点插件不含输入规则供不需要触发行为的场景使用。类型层面的约束可参考 math-kit.type.spec.ts它锁死了variant与on的合法组合例如variant: $$必须携带onvariant: $不允许携带on。测试验证把每条行为行独立锁死packages/math/src/lib/inputRules.spec.tsx 是这套触发行为最直接的包级测试证据覆盖了计划 Test Plan 中的关键场景补全行内转换在Math: $xcursor/中insertText($)断言段落变成Math: hinlineequation texExpressionx /——证明是在闭合定界符处提交$$ Enter 提升$$cursor/段落中insertBreak()断言 children 变成{ texExpression: , type: KEYS.equation }的块公式节点on: match变体配置MathRules.markdown({ on: match, variant: $$ })后第二个$键入即触发提升——证明on是独立可控的触发时机代码块保持字面量在hcodeblock内键入$$x$保持为纯文本——证明isEquationInputBlocked的排除上下文生效enabled 覆盖enabled: () false时键入$保持字面量$x$——证明触发是可配置的不是静默全局生效。这与计划 Test Plan 中第一个$保持字面量、不提前提交触发辅助函数不得吞掉无关$文本字面量回退等场景一一对应。既有变换测试 insertInlineEquation.spec.ts、insertEquation.spec.ts、BaseInlineEquationPlugin.spec.ts、BaseEquationPlugin.spec.ts 也被要求保持绿色确保显式插入路径不受影响。应用层集成测试建议落在apps/www/src/__tests__/package-integration/math/例如math-delimiter-trigger.slow.tsx验证 markdown-first 编辑器中默认状态下选区 $不触发、补全转换生效、$$ Enter 提升、代码块保持字面量、工具栏/斜杠插入在装配后依然可用。实施切片把高风险分支与简单分支分开计划将同一车道内的实现拆成四个切片避免高风险的 Enter 路径污染简单的$表面Slice A0Row 001 选区包裹的产品决策检查点Slice A1补全行内$...$富文本转换已发布Slice B块级触发/提升已发布Slice CRow 001 选区包裹——仅在显式批准后实施。推荐实施顺序为特征化测试 → 决策检查点 → 共享触发辅助函数 → 共享触发插件显式补全行内转换→ 接入 math 套件与应用集成测试 → 决定并实现 Slice B → 最后才实现获批准的 Row 001 → 更新文档并刷新路线图/parity/规格状态。计划中还给出了建议的纯辅助函数拆分shouldWrapMathSelection、shouldPairInlineMath、shouldPromoteBlockMath各自独立保证选区包裹、空选区成对输入、块触发逻辑可独立测试。风险与缓解三条真实的产品性风险风险 1意外的通用自动成对行为如果触发插件过宽$会在任何地方表现得像普通引号对。缓解显式开启数学触发、激进测试字面量回退。风险 2$$提升与正常块归属冲突Enter路径在结构上不同于insertText。缓解放在 Slice B 单独实施通过真实块归属行为测试而非仅靠辅助函数 mock。风险 3触发创建的行内公式焦点别扭行内公式节点可能打开编辑 UI 或意外转移焦点。缓解将 useEquationInput.ts 纳入验证面测试插入后的键盘与焦点连续性。该 hook 的实现也印证了风险来源行内公式打开时open会触发focus()与select()且撤销时会对行内公式焦点做特殊处理withMerging块级公式则不会因聚焦打开弹层。验收标准与文档契约计划的验收标准Acceptance Criteria可作为读者验证当前仓库状态的清单仓库中有一个明确的共享触发宿主承载数学定界符行为EDIT-PROFILE-MATH-TRIGGER-002与003在默认富文本模式下实现并有测试EDIT-PROFILE-MATH-TRIGGER-001保持显式批准门控而非被静默假定应用套件不再只依赖工具栏/斜杠插入来支撑计划中的数学触发表面公开文档明确区分解析器支持、显式插入 API 与键入触发三者路线图与 parity 措辞如实反映已发布内容。当前仓库状态MathRulesMathKit装配 inputRules.spec.tsx测试与 1、2、4 直接吻合而 001 在规格与计划中均被标记为deviation并保持 deferred正是第 3 条的体现。相关文档入口还包括 equation.mdx/(elements)/equation.mdx)公式插件文档与 markdown.mdx/(serializing)/markdown.mdx)markdown 序列化文档以及路线图总纲 master-roadmap.md 与协议矩阵 editor-protocol-matrix.md。总结数学定界符触发的正确打开方式是先把表面拆成三条独立行为行再逐行决定归属、默认值与发布范围。Plate 在这条路线图切片中的落地给出了一个可复制的范式规格层用EDIT-PROFILE-MATH-TRIGGER-001/002/003锁死三条协议行实现层用MathRules.markdown的createRuleFactory输入规则分别承载行内补全转换与$$ Enter 块提升测试层用包级inputRules.spec.tsx与应用集成测试逐场景验证决策层则明确把选区包裹作为需要显式产品批准的 deferred 分支。这种按行拆分、逐行落地、诚实记录的节奏既避免了伪造一个全局 math-trigger 赢家也保证了默认富文本编辑器的符号碰撞压力可控。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考