UNPKG

@rtdui/editor

Version:

React rich text editor based on tiptap

68 lines (65 loc) 2.02 kB
import { findChildren } from "@tiptap/core"; import katex from "katex"; import { Plugin, PluginKey } from "prosemirror-state"; import { Decoration, DecorationSet } from "prosemirror-view"; //#region packages/editor/src/RichTextEditor/tiptap_extensions/extension-math/math-katex-block-plugin.ts function getDecorations({ editor, doc, name, katexOptions, selection }) { const decorations = []; findChildren(doc, (node) => node.type.name === name).forEach((block) => { const from = block.pos + 1; const to = from + block.node.textContent.length; const mathText = block.node.textContent; if (selection.$anchor.pos < from || selection.$anchor.pos > to || !editor.isEditable) { const mathRender = document.createElement("div"); mathRender.classList.add("tiptap-math-render"); katex.render(mathText, mathRender, { displayMode: true, output: "html" }); const decoration = Decoration.widget(from, mathRender); decorations.push(decoration); const decoration2 = Decoration.inline(from, to, { nodeName: "pre", class: "titap-math-source hidden" }); decorations.push(decoration2); } else if (editor.isEditable) { const decoration2 = Decoration.inline(from, to, { nodeName: "pre", class: "titap-math-source" }); decorations.push(decoration2); } }); return DecorationSet.create(doc, decorations); } function KatexBlockPlugin({ editor, name, katexOptions }) { const katexBlockPlugin = new Plugin({ key: new PluginKey("mathKatexBlock"), state: { init: (_, { doc, selection }) => getDecorations({ editor, doc, name, katexOptions, selection }), apply: (transaction, decorationSet, oldState, newState) => { const { selection } = newState; return getDecorations({ editor, doc: transaction.doc, name, katexOptions, selection }); } }, props: { decorations(state) { return katexBlockPlugin.getState(state); } } }); return katexBlockPlugin; } //#endregion export { KatexBlockPlugin };