import { Node, nodeInputRule } from "@tiptap/core"; import { ReactNodeViewRenderer } from "@tiptap/react"; declare module "@tiptap/core" { interface Commands { mathInline: { setMathInline: () => ReturnType; }; } } export interface MathInlineOption { HTMLAttributes: Record; view: any; } export interface MathInlineAttributes { text: string; } export const inputRegex = /(?:^|\s)((?:\$\$)((?:[^$]+))(?:\$\$))$/; export const MathInline = Node.create({ name: "mathInline", group: "inline", inline: true, atom: true, addOptions() { return { HTMLAttributes: {}, view: null, }; }, addAttributes() { return { text: { default: "", parseHTML: (element) => element.innerHTML.split("$")[1], }, }; }, parseHTML() { return [ { tag: "span", getAttrs: (node: HTMLElement) => { return node.hasAttribute("data-katex") ? {} : false; }, }, ]; }, renderHTML({ HTMLAttributes }) { return [ "div", {}, ["span", { "data-katex": true }, `$${HTMLAttributes.text}$`], ]; }, renderText({ node }) { return node.attrs.text; }, addNodeView() { return ReactNodeViewRenderer(this.options.view); }, addCommands() { return { setMathInline: (attributes?: Record) => ({ commands }) => { return commands.insertContent({ type: this.name, attrs: attributes, }); }, }; }, addInputRules() { return [ nodeInputRule({ find: inputRegex, type: this.type, getAttributes: (match) => ({ text: match[1].replaceAll("$", ""), }), }), ]; }, });