拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Plate 如何支持 GFM 脚注并在引用与定义之间跳转?

Plate 如何支持 GFM 脚注并在引用与定义之间跳转【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate在 Plate 富文本编辑器里处理 GFM 脚注需要解决三件事把[^1]引用和[^1]: 正文定义解析成可编辑的专用节点而不是退化成 fallback 文本、支持序列化回真正的脚注 Markdown、以及在正文引用与文末定义之间快速跳转。platejs/footnote包负责节点语义、identifier 分配和导航变换platejs/markdown的MarkdownPlugin配合remark-gfm负责双向转换。节点模型先说清楚引用是行内 void 节点渲染为sup定义是位于文档末尾的块级节点携带 identifier 与正文内容。启用remark-gfm后脚注会被反序列化为footnoteReference和footnoteDefinition节点如果编辑器里没装脚注插件这些节点会回退为未知类型。这一点在 Markdown 文档/(serializing)/markdown.mdx) 的 GFM footnotes 一节中有明确说明。安装并配置脚注插件手动接入是理解整条链路的最短路径。安装三个依赖npm install platejs/footnote platejs/markdown remark-gfm创建编辑器时挂载两个脚注插件并用configure给MarkdownPlugin加上remarkGfmimport { FootnoteDefinitionPlugin, FootnoteReferencePlugin, } from platejs/footnote/react; import { MarkdownPlugin } from platejs/markdown; import { createPlateEditor } from platejs/react; import remarkGfm from remark-gfm; const editor createPlateEditor({ plugins: [ // ...otherPlugins, FootnoteReferencePlugin, FootnoteDefinitionPlugin, MarkdownPlugin.configure({ options: { remarkPlugins: [remarkGfm], }, }), ], });两个插件的分工FootnoteReferencePlugin行内 void 节点拥有[^combobox 触发器、identifier 注册表、导航变换和查询 API。FootnoteDefinitionPlugin文档末尾的块级定义节点。FootnoteReferencePlugin会自动带进FootnoteInputPlugin——那是用户键入[^…期间渲染的 inline void 输入节点只有当你自己实现 combobox 渲染时才需要手动添加。触发器行为值得注意默认trigger为^且默认triggerPreviousCharPattern为/^\[$/即^前面必须是[才会打开 combobox正文里单独的^不会误触发。trigger、triggerPreviousCharPattern、createComboboxInput、triggerQuery都可以在插件选项中覆盖。如果项目已经使用 Plate UI可以直接用MarkdownKit替代上面的手动配置它已经包含配置好默认 markdown profile 的MarkdownPlugin和脚注插件import { createPlateEditor } from platejs/react; import { MarkdownKit } from /components/editor/plugins/markdown-kit; const editor createPlateEditor({ plugins: [ // ...otherPlugins, ...MarkdownKit, ], });Kit 的参考实现见 markdown-kit.tsx脚注 UI 插件组合见 footnote-kit.tsx。插入脚注在当前选区调用tf.insert.footnote。它会插入引用、在文档末尾创建对应定义并把光标移进定义正文用户可以直接开始写editor.tf.insert.footnote();三个可选项对应不同的使用条件// 光标留在引用后的行内位置不跳到定义适合引用嵌在大段模板里的场景 editor.tf.insert.footnote({ focusDefinition: false });identifier复用已存在的 identifier。如果该 identifier 已有定义transform 会跳过创建重复定义默认值来自api.footnote.nextId()返回1、2这样的下一个可用数字 identifier。focusDefinition插入后是否聚焦定义正文默认true。其余选项按InsertNodesOptions转发给引用插入at、select等。如果调用时选区处于展开状态被选中的内容片段会直接作为新定义正文的种子——即选中一段文字后一次调用把它脚注化。在引用与定义之间跳转tf.footnote.focusDefinition和tf.footnote.focusReference各做一个方向的跳转移动选区、把目标滚动进视图并通过 Navigation Feedback 对目标做一次高亮闪烁。脚注文档里明确写了 No extra wiring needededitor.tf.footnote.focusDefinition({ identifier: 3 }); editor.tf.footnote.focusReference({ identifier: 3 });当一个定义被多个引用指向时用index指定落在哪一个引用上按文档顺序索引默认0editor.tf.footnote.focusReference({ identifier: 3, index: 1 });两个 transform 在 identifier 无法解析时返回false而不是抛异常可以据此对失效链接做分支处理if (editor.tf.footnote.focusDefinition({ identifier: 1 })) { // 跳转成功 } // 返回 false没有对应的定义属于过期引用闪烁效果来自 Plate 核心的NavigationFeedbackPlugin它由createPlateEditor自动包含不需要手动添加。默认闪烁时长 1600ms如需调整或关闭在顶层navigationFeedback选项里配置const editor createPlateEditor({ navigationFeedback: { duration: 1200, // 闪烁时长毫秒默认 1600 }, }); // 或完全禁用落地高亮 const editor createPlateEditor({ navigationFeedback: false, });插件会在目标节点的 DOM 上注入data-nav-target、data-nav-highlight、data-nav-cycle等瞬时属性和--plate-nav-feedback-durationCSS 变量可以据此写自己的闪烁动画。完整说明见 Navigation Feedback 文档/(functionality)/navigation-feedback.mdx)。修复未解析的引用从别处粘贴进来的 Markdown 可能出现引用存在、定义缺失的情况例如只粘了[^3]没粘[^3]: ...。此时用tf.footnote.createDefinition只补定义、不额外插入引用editor.tf.footnote.createDefinition({ identifier: 3 });它返回解析后定义的路径number[]——新建的定义或 identifier 已存在时的既有定义。默认创建后聚焦定义正文如果希望光标留在原地传focus: falseeditor.tf.footnote.createDefinition({ focus: false, identifier: 3 });处理重复定义同一 identifier 出现两个定义不是错误状态而是可恢复的编辑状态文档顺序中第一个定义保持权威canonical后面的被标记为重复。用tf.footnote.normalizeDuplicateDefinition给后面的重复定义重新编号const nextIdentifier editor.tf.footnote.normalizeDuplicateDefinition({ path: duplicatePath, });成功时返回新分配的 identifier 字符串当path不是重复定义、或指定的 identifier 已被占用时返回false。不传identifier时自动取api.footnote.nextId()传identifier可以指定某个空闲的 identifier。校验脚注状态与序列化结果判断引用是否已解析、定义有几份、编号是否冲突用editor.api.footnote下的查询方法它们走按编辑器惰性构建的注册表只在脚注操作使其失效时重建editor.api.footnote.isResolved(3); // 该 identifier 是否有至少一个定义 editor.api.footnote.definition(3); // 权威定义条目文档顺序第一个无匹配返回 undefined editor.api.footnote.definitions(3); // 全部定义条目按文档顺序 editor.api.footnote.references(3); // 指向该 identifier 的全部引用按文档顺序 editor.api.footnote.identifiers(); // 所有至少有 1 个定义的 identifier editor.api.footnote.duplicateIdentifiers();// 有重复定义的 identifier 列表 editor.api.footnote.hasDuplicateDefinitions(3); editor.api.footnote.definitionText(3); // 权威定义的纯文本适合做悬停预览序列化侧的验证方式是调用editor.api.markdown.serialize()后输出中应包含真实的脚注 Markdown[^1]引用与[^1]: 正文定义而不是 fallback 文本——这正是MarkdownPluginremark-gfm 脚注插件三者齐备时的预期行为。限制与可选的渲染定制两个导航 transform 和flashTarget类操作在目标不可解析时返回false不做异常处理对失效 identifier 要自己做分支。FootnoteInputPlugin由FootnoteReferencePlugin自动引入只在自绘 combobox 时才需要显式添加。包本身只负责节点语义、identifier 分配和导航变换悬停预览、^combobox、slash-command 入口、工具栏按钮等应用层 UI 需要在这些 transform 和查询 API 之上自建。渲染组件可用withComponent替换例如FootnoteReferencePlugin.withComponent(MyFootnoteReference)插件选项中的createComboboxInput也可以换成自定义的 combobox 节点工厂。更多 API 细节见 [Footnote 文档/(elements)/footnote.mdx) 和 packages/footnote/README.md。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门