'use client' import { findInlineMathStart } from '@admin/utils/editor/find-inline-math-start' import { getInlineMathDelimiter } from '@admin/utils/editor/get-inline-math-delimiter' import { getRawContentToken } from '@admin/utils/editor/get-raw-content-token' import { getStringAttr } from '@admin/utils/editor/get-string-attr' import { InlineMathNodeView } from '@admin/utils/editor/inline-math-node-view' import { matchInlineMath } from '@admin/utils/editor/match-inline-math' import { mergeAttributes, Node as TiptapNode } from '@tiptap/core' export const ContentEditorInlineMath = TiptapNode.create({ name: 'inlineMath', group: 'inline', inline: true, atom: true, selectable: true, addAttributes() { return { raw: { default: '' }, delimiter: { default: '$' } } }, parseHTML() { return [ { tag: 'span[data-content-editor-inline-math]', getAttrs: (element) => { if (!(element instanceof HTMLElement)) return false return { raw: element.dataset.raw ?? element.textContent ?? '', delimiter: element.dataset.delimiter === '\\(' ? '\\(' : '$' } } } ] }, renderHTML({ HTMLAttributes, node }) { const raw = getStringAttr(node.attrs.raw) const delimiter = getInlineMathDelimiter(node.attrs.delimiter) return [ 'span', mergeAttributes(HTMLAttributes, { 'data-content-editor-inline-math': '', 'data-raw': raw, 'data-delimiter': delimiter }), raw ] }, parseMarkdown: (token) => { const mathToken = getRawContentToken(token) return { type: 'inlineMath', attrs: { raw: mathToken.text ?? mathToken.raw ?? '', delimiter: getInlineMathDelimiter(mathToken.delimiter) } } }, renderMarkdown: (node) => { const raw = getStringAttr(node.attrs?.raw) const delimiter = getInlineMathDelimiter(node.attrs?.delimiter) if (delimiter === '\\(') { return `\\(${raw}\\)` } return `$${raw}$` }, markdownTokenizer: { name: 'inlineMath', level: 'inline', start: findInlineMathStart, tokenize(src) { const match = matchInlineMath(src) if (!match) return undefined return { type: 'inlineMath', raw: match.raw, text: match.text, delimiter: match.delimiter } } }, addNodeView() { return ({ node }) => { return new InlineMathNodeView(node) } } })