@tiptap/extension-mathematics 3.23.6 → 3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +8 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/package.json +18 -19
- package/src/extensions/BlockMath.ts +9 -3
- package/src/mathematics.ts +8 -2
- package/src/utils.ts +5 -1
package/dist/index.cjs
CHANGED
|
@@ -388,8 +388,14 @@ var Mathematics = import_core3.Extension.create({
|
|
|
388
388
|
},
|
|
389
389
|
addExtensions() {
|
|
390
390
|
return [
|
|
391
|
-
BlockMath.configure({
|
|
392
|
-
|
|
391
|
+
BlockMath.configure({
|
|
392
|
+
...this.options.blockOptions,
|
|
393
|
+
katexOptions: this.options.katexOptions
|
|
394
|
+
}),
|
|
395
|
+
InlineMath.configure({
|
|
396
|
+
...this.options.inlineOptions,
|
|
397
|
+
katexOptions: this.options.katexOptions
|
|
398
|
+
})
|
|
393
399
|
];
|
|
394
400
|
}
|
|
395
401
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/mathematics.ts","../src/extensions/BlockMath.ts","../src/extensions/InlineMath.ts","../src/utils.ts"],"sourcesContent":["import { Mathematics } from './mathematics.js'\n\nexport * from './extensions/index.js'\nexport * from './mathematics.js'\nexport * from './types.js'\nexport * from './utils.js'\n\nexport default Mathematics\n","import { Extension } from '@tiptap/core'\n\nimport { BlockMath, InlineMath } from './extensions/index.js'\nimport type { MathematicsOptions } from './types.js'\n\n/**\n * Mathematics extension for Tiptap that provides both inline and block math support using KaTeX.\n * This extension combines the InlineMath and BlockMath extensions to provide a complete\n * mathematical expression solution for rich text editing. It supports LaTeX syntax,\n * custom rendering options, and interactive math nodes.\n *\n * @example\n * ```typescript\n * import { Editor } from '@tiptap/core'\n * import { Mathematics } from '@tiptap/extension-mathematics'\n * import { migrateMathStrings } from '@tiptap/extension-mathematics/utils'\n *\n * const editor = new Editor({\n * extensions: [\n * Mathematics.configure({\n * inlineOptions: {\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex)\n * }\n * },\n * blockOptions: {\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex)\n * }\n * },\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * })\n * ],\n * content: `\n * <p>Inline math: $E = mc^2$</p>\n * <div data-type=\"block-math\" data-latex=\"\\\\sum_{i=1}^{n} x_i = X\"></div>\n * `,\n * onCreate({ editor }) {\n * // Optional: Migrate existing math strings to math nodes\n * migrateMathStrings(editor)\n * }\n * })\n * ```\n */\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n inlineOptions: undefined,\n blockOptions: undefined,\n katexOptions: undefined,\n }\n },\n\n addExtensions() {\n return [\n BlockMath.configure({ ...this.options.blockOptions, katexOptions: this.options.katexOptions }),\n InlineMath.configure({ ...this.options.inlineOptions, katexOptions: this.options.katexOptions }),\n ]\n },\n})\n\nexport default Mathematics\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the BlockMath extension.\n */\nexport type BlockMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: true,\n * throwOnError: false,\n * },\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for block math nodes.\n * Called when a user clicks on a block math expression in the editor.\n *\n * @param node - The ProseMirror node representing the block math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertBlockMath: {\n /**\n * Inserts a math block node with LaTeX string.\n * @param options - Options for inserting block math.\n * @returns ReturnType\n */\n insertBlockMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Deletes a block math node.\n * @returns ReturnType\n */\n deleteBlockMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update block math node with optional LaTeX string.\n * @param options - Options for updating block math.\n * @returns ReturnType\n */\n updateBlockMath: (options?: { latex: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * BlockMath is a Tiptap extension for rendering block mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions block within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { BlockMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * BlockMath.configure({\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const BlockMath = Node.create<BlockMathOptions>({\n name: 'blockMath',\n\n group: 'block',\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertBlockMath:\n options =>\n ({ commands, editor }) => {\n const { latex, pos } = options\n\n if (!latex) {\n return false\n }\n\n return commands.insertContentAt(pos ?? editor.state.selection.from, {\n type: this.name,\n attrs: { latex },\n })\n },\n\n deleteBlockMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateBlockMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, {\n ...node.attrs,\n latex: latex ?? node.attrs.latex,\n })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"block-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'block-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'blockMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n const output = ['$$', latex, '$$']\n return output.join('\\n')\n },\n\n markdownTokenizer: {\n name: 'blockMath',\n level: 'block',\n start: (src: string) => src.indexOf('$$'),\n tokenize: (src: string) => {\n // Match $$latex$$ syntax for block math\n const match = src.match(/^\\$\\$([^$]+)\\$\\$/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'blockMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /^\\$\\$\\$([^$]+)\\$\\$\\$$/,\n handler: ({ state, range, match }) => {\n const [, latex] = match\n const { tr } = state\n const $from = state.doc.resolve(range.from)\n const node = this.type.create({ latex })\n\n const consumesHostTextblock =\n $from.depth > 0 && $from.parent.isTextblock && range.from === $from.start() && range.to === $from.end()\n // Whether the node containing the host textblock can replace it with a blockMath node.\n const canReplaceHostTextblock =\n consumesHostTextblock && $from.node(-1).canReplaceWith($from.index(-1), $from.indexAfter(-1), this.type)\n\n const replacementRange = canReplaceHostTextblock ? { from: $from.before(), to: $from.after() } : range\n\n tr.replaceWith(replacementRange.from, replacementRange.to, node)\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('div')\n const innerWrapper = document.createElement('div')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n innerWrapper.className = 'block-math-inner'\n wrapper.dataset.type = 'block-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n wrapper.appendChild(innerWrapper)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, innerWrapper, katexOptions)\n wrapper.classList.remove('block-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('block-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the InlineMath extension.\n */\nexport type InlineMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * ```\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for inline math nodes.\n * Called when a user clicks on an inline math expression in the editor.\n *\n * @param node - The ProseMirror node representing the inline math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * }\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n inlineMath: {\n /**\n * Insert a inline math node with LaTeX string.\n * @param options - Options for inserting inline math.\n * @returns ReturnType\n */\n insertInlineMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Delete an inline math node.\n * @returns ReturnType\n */\n deleteInlineMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update inline math node with optional LaTeX string.\n * @param options - Options for updating inline math.\n * @returns ReturnType\n */\n updateInlineMath: (options?: { latex?: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * InlineMath is a Tiptap extension for rendering inline mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions inline within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { InlineMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * InlineMath.configure({\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const InlineMath = Node.create<InlineMathOptions>({\n name: 'inlineMath',\n\n group: 'inline',\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options.latex\n\n const from = options?.pos ?? editor.state.selection.from\n\n if (!latex) {\n return false\n }\n\n tr.replaceWith(from, from, this.type.create({ latex }))\n return true\n },\n\n deleteInlineMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, { ...node.attrs, latex })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"inline-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'inline-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'inlineMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n return `$${latex}$`\n },\n\n markdownTokenizer: {\n name: 'inlineMath',\n level: 'inline',\n start: (src: string) => src.indexOf('$'),\n tokenize: (src: string) => {\n // Match $latex$ syntax for inline math (but not $$)\n const match = src.match(/^\\$([^$]+)\\$(?!\\$)/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'inlineMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /(?<!\\$)(\\$\\$([^$\\n]+?)\\$\\$)(?!\\$)/,\n handler: ({ state, range, match }) => {\n const latex = match[2]\n const { tr } = state\n const start = range.from\n const end = range.to\n\n tr.replaceWith(start, end, this.type.create({ latex }))\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('span')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n wrapper.dataset.type = 'inline-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, wrapper, katexOptions)\n wrapper.classList.remove('inline-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('inline-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import type { Editor } from '@tiptap/core'\nimport type { Transaction } from '@tiptap/pm/state'\n\n/**\n * Regular expression to match LaTeX math strings wrapped in single dollar signs.\n * This should not catch dollar signs which are not part of a math expression,\n * like those used for currency or other purposes.\n * It ensures that the dollar signs are not preceded or followed by digits,\n * allowing for proper identification of inline math expressions.\n *\n * - `$x^2 + y^2 = z^2$` will match\n * - `This is $inline math$ in text.` will match\n * - `This is $100$ dollars.` will not match (as it is not a math expression)\n * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions\n */\nexport const mathMigrationRegex = /\\$(?!\\d+\\$)(.+?)\\$(?!\\d)/g\n\n/**\n * Creates a transaction that migrates existing math strings in the document to new math nodes.\n * This function traverses the document and replaces LaTeX math syntax (wrapped in single dollar signs)\n * with proper inline math nodes, preserving the mathematical content.\n *\n * @param editor - The editor instance containing the schema and configuration\n * @param tr - The transaction to modify with the migration operations\n * @returns The modified transaction with math string replacements\n *\n * @example\n * ```typescript\n * const editor = new Editor({ ... })\n * const tr = editor.state.tr\n * const updatedTr = createMathMigrateTransaction(editor, tr)\n * editor.view.dispatch(updatedTr)\n * ```\n */\nexport function createMathMigrateTransaction(editor: Editor, tr: Transaction, regex: RegExp = mathMigrationRegex) {\n // we traverse the document and replace all math nodes with the new math nodes\n tr.doc.descendants((node, pos) => {\n if (!node.isText || !node.text || !node.text.includes('$')) {\n return\n }\n\n const { text } = node\n\n const match = node.text.match(regex)\n if (!match) {\n return\n }\n\n match.forEach(mathMatch => {\n const start = text.indexOf(mathMatch)\n const end = start + mathMatch.length\n\n const from = tr.mapping.map(pos + start)\n\n const $from = tr.doc.resolve(from)\n const parent = $from.parent\n const index = $from.index()\n\n const { inlineMath } = editor.schema.nodes\n\n if (!parent.canReplaceWith(index, index + 1, inlineMath)) {\n return\n }\n\n // Replace the math syntax with a new math node\n tr.replaceWith(\n tr.mapping.map(pos + start),\n tr.mapping.map(pos + end),\n inlineMath.create({ latex: mathMatch.slice(1, -1) }),\n )\n })\n })\n\n // don't add to history\n tr.setMeta('addToHistory', false)\n return tr\n}\n\n/**\n * Migrates existing math strings in the editor document to math nodes.\n * This function creates and dispatches a transaction that converts LaTeX math syntax\n * (text wrapped in single dollar signs) into proper inline math nodes. The migration\n * happens immediately and is not added to the editor's history.\n *\n * @param editor - The editor instance to perform the migration on\n *\n * @example\n * ```typescript\n * const editor = new Editor({\n * extensions: [Mathematics],\n * content: 'This is inline math: $x^2 + y^2 = z^2$ in text.'\n * })\n *\n * // Math strings will be automatically migrated to math nodes\n * migrateMathStrings(editor)\n * ```\n */\nexport function migrateMathStrings(editor: Editor, regex: RegExp = mathMigrationRegex) {\n const tr = createMathMigrateTransaction(editor, editor.state.tr, regex)\n editor.view.dispatch(tr)\n}\n"],"mappings":"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","names":["import_core","katex","import_core","import_katex","katex"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/mathematics.ts","../src/extensions/BlockMath.ts","../src/extensions/InlineMath.ts","../src/utils.ts"],"sourcesContent":["import { Mathematics } from './mathematics.js'\n\nexport * from './extensions/index.js'\nexport * from './mathematics.js'\nexport * from './types.js'\nexport * from './utils.js'\n\nexport default Mathematics\n","import { Extension } from '@tiptap/core'\n\nimport { BlockMath, InlineMath } from './extensions/index.js'\nimport type { MathematicsOptions } from './types.js'\n\n/**\n * Mathematics extension for Tiptap that provides both inline and block math support using KaTeX.\n * This extension combines the InlineMath and BlockMath extensions to provide a complete\n * mathematical expression solution for rich text editing. It supports LaTeX syntax,\n * custom rendering options, and interactive math nodes.\n *\n * @example\n * ```typescript\n * import { Editor } from '@tiptap/core'\n * import { Mathematics } from '@tiptap/extension-mathematics'\n * import { migrateMathStrings } from '@tiptap/extension-mathematics/utils'\n *\n * const editor = new Editor({\n * extensions: [\n * Mathematics.configure({\n * inlineOptions: {\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex)\n * }\n * },\n * blockOptions: {\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex)\n * }\n * },\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * })\n * ],\n * content: `\n * <p>Inline math: $E = mc^2$</p>\n * <div data-type=\"block-math\" data-latex=\"\\\\sum_{i=1}^{n} x_i = X\"></div>\n * `,\n * onCreate({ editor }) {\n * // Optional: Migrate existing math strings to math nodes\n * migrateMathStrings(editor)\n * }\n * })\n * ```\n */\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n inlineOptions: undefined,\n blockOptions: undefined,\n katexOptions: undefined,\n }\n },\n\n addExtensions() {\n return [\n BlockMath.configure({\n ...this.options.blockOptions,\n katexOptions: this.options.katexOptions,\n }),\n InlineMath.configure({\n ...this.options.inlineOptions,\n katexOptions: this.options.katexOptions,\n }),\n ]\n },\n})\n\nexport default Mathematics\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the BlockMath extension.\n */\nexport type BlockMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: true,\n * throwOnError: false,\n * },\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for block math nodes.\n * Called when a user clicks on a block math expression in the editor.\n *\n * @param node - The ProseMirror node representing the block math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertBlockMath: {\n /**\n * Inserts a math block node with LaTeX string.\n * @param options - Options for inserting block math.\n * @returns ReturnType\n */\n insertBlockMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Deletes a block math node.\n * @returns ReturnType\n */\n deleteBlockMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update block math node with optional LaTeX string.\n * @param options - Options for updating block math.\n * @returns ReturnType\n */\n updateBlockMath: (options?: { latex: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * BlockMath is a Tiptap extension for rendering block mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions block within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { BlockMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * BlockMath.configure({\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const BlockMath = Node.create<BlockMathOptions>({\n name: 'blockMath',\n\n group: 'block',\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertBlockMath:\n options =>\n ({ commands, editor }) => {\n const { latex, pos } = options\n\n if (!latex) {\n return false\n }\n\n return commands.insertContentAt(pos ?? editor.state.selection.from, {\n type: this.name,\n attrs: { latex },\n })\n },\n\n deleteBlockMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateBlockMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, {\n ...node.attrs,\n latex: latex ?? node.attrs.latex,\n })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"block-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'block-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'blockMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n const output = ['$$', latex, '$$']\n return output.join('\\n')\n },\n\n markdownTokenizer: {\n name: 'blockMath',\n level: 'block',\n start: (src: string) => src.indexOf('$$'),\n tokenize: (src: string) => {\n // Match $$latex$$ syntax for block math\n const match = src.match(/^\\$\\$([^$]+)\\$\\$/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'blockMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /^\\$\\$\\$([^$]+)\\$\\$\\$$/,\n handler: ({ state, range, match }) => {\n const [, latex] = match\n const { tr } = state\n const $from = state.doc.resolve(range.from)\n const node = this.type.create({ latex })\n\n const consumesHostTextblock =\n $from.depth > 0 &&\n $from.parent.isTextblock &&\n range.from === $from.start() &&\n range.to === $from.end()\n // Whether the node containing the host textblock can replace it with a blockMath node.\n const canReplaceHostTextblock =\n consumesHostTextblock &&\n $from.node(-1).canReplaceWith($from.index(-1), $from.indexAfter(-1), this.type)\n\n const replacementRange = canReplaceHostTextblock\n ? { from: $from.before(), to: $from.after() }\n : range\n\n tr.replaceWith(replacementRange.from, replacementRange.to, node)\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('div')\n const innerWrapper = document.createElement('div')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n innerWrapper.className = 'block-math-inner'\n wrapper.dataset.type = 'block-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n wrapper.appendChild(innerWrapper)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, innerWrapper, katexOptions)\n wrapper.classList.remove('block-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('block-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the InlineMath extension.\n */\nexport type InlineMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * ```\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for inline math nodes.\n * Called when a user clicks on an inline math expression in the editor.\n *\n * @param node - The ProseMirror node representing the inline math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * }\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n inlineMath: {\n /**\n * Insert a inline math node with LaTeX string.\n * @param options - Options for inserting inline math.\n * @returns ReturnType\n */\n insertInlineMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Delete an inline math node.\n * @returns ReturnType\n */\n deleteInlineMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update inline math node with optional LaTeX string.\n * @param options - Options for updating inline math.\n * @returns ReturnType\n */\n updateInlineMath: (options?: { latex?: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * InlineMath is a Tiptap extension for rendering inline mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions inline within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { InlineMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * InlineMath.configure({\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const InlineMath = Node.create<InlineMathOptions>({\n name: 'inlineMath',\n\n group: 'inline',\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options.latex\n\n const from = options?.pos ?? editor.state.selection.from\n\n if (!latex) {\n return false\n }\n\n tr.replaceWith(from, from, this.type.create({ latex }))\n return true\n },\n\n deleteInlineMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, { ...node.attrs, latex })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"inline-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'inline-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'inlineMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n return `$${latex}$`\n },\n\n markdownTokenizer: {\n name: 'inlineMath',\n level: 'inline',\n start: (src: string) => src.indexOf('$'),\n tokenize: (src: string) => {\n // Match $latex$ syntax for inline math (but not $$)\n const match = src.match(/^\\$([^$]+)\\$(?!\\$)/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'inlineMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /(?<!\\$)(\\$\\$([^$\\n]+?)\\$\\$)(?!\\$)/,\n handler: ({ state, range, match }) => {\n const latex = match[2]\n const { tr } = state\n const start = range.from\n const end = range.to\n\n tr.replaceWith(start, end, this.type.create({ latex }))\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('span')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n wrapper.dataset.type = 'inline-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, wrapper, katexOptions)\n wrapper.classList.remove('inline-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('inline-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import type { Editor } from '@tiptap/core'\nimport type { Transaction } from '@tiptap/pm/state'\n\n/**\n * Regular expression to match LaTeX math strings wrapped in single dollar signs.\n * This should not catch dollar signs which are not part of a math expression,\n * like those used for currency or other purposes.\n * It ensures that the dollar signs are not preceded or followed by digits,\n * allowing for proper identification of inline math expressions.\n *\n * - `$x^2 + y^2 = z^2$` will match\n * - `This is $inline math$ in text.` will match\n * - `This is $100$ dollars.` will not match (as it is not a math expression)\n * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions\n */\nexport const mathMigrationRegex = /\\$(?!\\d+\\$)(.+?)\\$(?!\\d)/g\n\n/**\n * Creates a transaction that migrates existing math strings in the document to new math nodes.\n * This function traverses the document and replaces LaTeX math syntax (wrapped in single dollar signs)\n * with proper inline math nodes, preserving the mathematical content.\n *\n * @param editor - The editor instance containing the schema and configuration\n * @param tr - The transaction to modify with the migration operations\n * @returns The modified transaction with math string replacements\n *\n * @example\n * ```typescript\n * const editor = new Editor({ ... })\n * const tr = editor.state.tr\n * const updatedTr = createMathMigrateTransaction(editor, tr)\n * editor.view.dispatch(updatedTr)\n * ```\n */\nexport function createMathMigrateTransaction(\n editor: Editor,\n tr: Transaction,\n regex: RegExp = mathMigrationRegex,\n) {\n // we traverse the document and replace all math nodes with the new math nodes\n tr.doc.descendants((node, pos) => {\n if (!node.isText || !node.text || !node.text.includes('$')) {\n return\n }\n\n const { text } = node\n\n const match = node.text.match(regex)\n if (!match) {\n return\n }\n\n match.forEach(mathMatch => {\n const start = text.indexOf(mathMatch)\n const end = start + mathMatch.length\n\n const from = tr.mapping.map(pos + start)\n\n const $from = tr.doc.resolve(from)\n const parent = $from.parent\n const index = $from.index()\n\n const { inlineMath } = editor.schema.nodes\n\n if (!parent.canReplaceWith(index, index + 1, inlineMath)) {\n return\n }\n\n // Replace the math syntax with a new math node\n tr.replaceWith(\n tr.mapping.map(pos + start),\n tr.mapping.map(pos + end),\n inlineMath.create({ latex: mathMatch.slice(1, -1) }),\n )\n })\n })\n\n // don't add to history\n tr.setMeta('addToHistory', false)\n return tr\n}\n\n/**\n * Migrates existing math strings in the editor document to math nodes.\n * This function creates and dispatches a transaction that converts LaTeX math syntax\n * (text wrapped in single dollar signs) into proper inline math nodes. The migration\n * happens immediately and is not added to the editor's history.\n *\n * @param editor - The editor instance to perform the migration on\n *\n * @example\n * ```typescript\n * const editor = new Editor({\n * extensions: [Mathematics],\n * content: 'This is inline math: $x^2 + y^2 = z^2$ in text.'\n * })\n *\n * // Math strings will be automatically migrated to math nodes\n * migrateMathStrings(editor)\n * ```\n */\nexport function migrateMathStrings(editor: Editor, regex: RegExp = mathMigrationRegex) {\n const tr = createMathMigrateTransaction(editor, editor.state.tr, regex)\n editor.view.dispatch(tr)\n}\n"],"mappings":"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","names":["import_core","katex","import_core","import_katex","katex"]}
|
package/dist/index.js
CHANGED
|
@@ -346,8 +346,14 @@ var Mathematics = Extension.create({
|
|
|
346
346
|
},
|
|
347
347
|
addExtensions() {
|
|
348
348
|
return [
|
|
349
|
-
BlockMath.configure({
|
|
350
|
-
|
|
349
|
+
BlockMath.configure({
|
|
350
|
+
...this.options.blockOptions,
|
|
351
|
+
katexOptions: this.options.katexOptions
|
|
352
|
+
}),
|
|
353
|
+
InlineMath.configure({
|
|
354
|
+
...this.options.inlineOptions,
|
|
355
|
+
katexOptions: this.options.katexOptions
|
|
356
|
+
})
|
|
351
357
|
];
|
|
352
358
|
}
|
|
353
359
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mathematics.ts","../src/extensions/BlockMath.ts","../src/extensions/InlineMath.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\n\nimport { BlockMath, InlineMath } from './extensions/index.js'\nimport type { MathematicsOptions } from './types.js'\n\n/**\n * Mathematics extension for Tiptap that provides both inline and block math support using KaTeX.\n * This extension combines the InlineMath and BlockMath extensions to provide a complete\n * mathematical expression solution for rich text editing. It supports LaTeX syntax,\n * custom rendering options, and interactive math nodes.\n *\n * @example\n * ```typescript\n * import { Editor } from '@tiptap/core'\n * import { Mathematics } from '@tiptap/extension-mathematics'\n * import { migrateMathStrings } from '@tiptap/extension-mathematics/utils'\n *\n * const editor = new Editor({\n * extensions: [\n * Mathematics.configure({\n * inlineOptions: {\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex)\n * }\n * },\n * blockOptions: {\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex)\n * }\n * },\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * })\n * ],\n * content: `\n * <p>Inline math: $E = mc^2$</p>\n * <div data-type=\"block-math\" data-latex=\"\\\\sum_{i=1}^{n} x_i = X\"></div>\n * `,\n * onCreate({ editor }) {\n * // Optional: Migrate existing math strings to math nodes\n * migrateMathStrings(editor)\n * }\n * })\n * ```\n */\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n inlineOptions: undefined,\n blockOptions: undefined,\n katexOptions: undefined,\n }\n },\n\n addExtensions() {\n return [\n BlockMath.configure({ ...this.options.blockOptions, katexOptions: this.options.katexOptions }),\n InlineMath.configure({ ...this.options.inlineOptions, katexOptions: this.options.katexOptions }),\n ]\n },\n})\n\nexport default Mathematics\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the BlockMath extension.\n */\nexport type BlockMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: true,\n * throwOnError: false,\n * },\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for block math nodes.\n * Called when a user clicks on a block math expression in the editor.\n *\n * @param node - The ProseMirror node representing the block math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertBlockMath: {\n /**\n * Inserts a math block node with LaTeX string.\n * @param options - Options for inserting block math.\n * @returns ReturnType\n */\n insertBlockMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Deletes a block math node.\n * @returns ReturnType\n */\n deleteBlockMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update block math node with optional LaTeX string.\n * @param options - Options for updating block math.\n * @returns ReturnType\n */\n updateBlockMath: (options?: { latex: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * BlockMath is a Tiptap extension for rendering block mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions block within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { BlockMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * BlockMath.configure({\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const BlockMath = Node.create<BlockMathOptions>({\n name: 'blockMath',\n\n group: 'block',\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertBlockMath:\n options =>\n ({ commands, editor }) => {\n const { latex, pos } = options\n\n if (!latex) {\n return false\n }\n\n return commands.insertContentAt(pos ?? editor.state.selection.from, {\n type: this.name,\n attrs: { latex },\n })\n },\n\n deleteBlockMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateBlockMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, {\n ...node.attrs,\n latex: latex ?? node.attrs.latex,\n })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"block-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'block-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'blockMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n const output = ['$$', latex, '$$']\n return output.join('\\n')\n },\n\n markdownTokenizer: {\n name: 'blockMath',\n level: 'block',\n start: (src: string) => src.indexOf('$$'),\n tokenize: (src: string) => {\n // Match $$latex$$ syntax for block math\n const match = src.match(/^\\$\\$([^$]+)\\$\\$/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'blockMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /^\\$\\$\\$([^$]+)\\$\\$\\$$/,\n handler: ({ state, range, match }) => {\n const [, latex] = match\n const { tr } = state\n const $from = state.doc.resolve(range.from)\n const node = this.type.create({ latex })\n\n const consumesHostTextblock =\n $from.depth > 0 && $from.parent.isTextblock && range.from === $from.start() && range.to === $from.end()\n // Whether the node containing the host textblock can replace it with a blockMath node.\n const canReplaceHostTextblock =\n consumesHostTextblock && $from.node(-1).canReplaceWith($from.index(-1), $from.indexAfter(-1), this.type)\n\n const replacementRange = canReplaceHostTextblock ? { from: $from.before(), to: $from.after() } : range\n\n tr.replaceWith(replacementRange.from, replacementRange.to, node)\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('div')\n const innerWrapper = document.createElement('div')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n innerWrapper.className = 'block-math-inner'\n wrapper.dataset.type = 'block-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n wrapper.appendChild(innerWrapper)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, innerWrapper, katexOptions)\n wrapper.classList.remove('block-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('block-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the InlineMath extension.\n */\nexport type InlineMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * ```\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for inline math nodes.\n * Called when a user clicks on an inline math expression in the editor.\n *\n * @param node - The ProseMirror node representing the inline math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * }\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n inlineMath: {\n /**\n * Insert a inline math node with LaTeX string.\n * @param options - Options for inserting inline math.\n * @returns ReturnType\n */\n insertInlineMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Delete an inline math node.\n * @returns ReturnType\n */\n deleteInlineMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update inline math node with optional LaTeX string.\n * @param options - Options for updating inline math.\n * @returns ReturnType\n */\n updateInlineMath: (options?: { latex?: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * InlineMath is a Tiptap extension for rendering inline mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions inline within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { InlineMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * InlineMath.configure({\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const InlineMath = Node.create<InlineMathOptions>({\n name: 'inlineMath',\n\n group: 'inline',\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options.latex\n\n const from = options?.pos ?? editor.state.selection.from\n\n if (!latex) {\n return false\n }\n\n tr.replaceWith(from, from, this.type.create({ latex }))\n return true\n },\n\n deleteInlineMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, { ...node.attrs, latex })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"inline-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'inline-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'inlineMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n return `$${latex}$`\n },\n\n markdownTokenizer: {\n name: 'inlineMath',\n level: 'inline',\n start: (src: string) => src.indexOf('$'),\n tokenize: (src: string) => {\n // Match $latex$ syntax for inline math (but not $$)\n const match = src.match(/^\\$([^$]+)\\$(?!\\$)/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'inlineMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /(?<!\\$)(\\$\\$([^$\\n]+?)\\$\\$)(?!\\$)/,\n handler: ({ state, range, match }) => {\n const latex = match[2]\n const { tr } = state\n const start = range.from\n const end = range.to\n\n tr.replaceWith(start, end, this.type.create({ latex }))\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('span')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n wrapper.dataset.type = 'inline-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, wrapper, katexOptions)\n wrapper.classList.remove('inline-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('inline-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import type { Editor } from '@tiptap/core'\nimport type { Transaction } from '@tiptap/pm/state'\n\n/**\n * Regular expression to match LaTeX math strings wrapped in single dollar signs.\n * This should not catch dollar signs which are not part of a math expression,\n * like those used for currency or other purposes.\n * It ensures that the dollar signs are not preceded or followed by digits,\n * allowing for proper identification of inline math expressions.\n *\n * - `$x^2 + y^2 = z^2$` will match\n * - `This is $inline math$ in text.` will match\n * - `This is $100$ dollars.` will not match (as it is not a math expression)\n * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions\n */\nexport const mathMigrationRegex = /\\$(?!\\d+\\$)(.+?)\\$(?!\\d)/g\n\n/**\n * Creates a transaction that migrates existing math strings in the document to new math nodes.\n * This function traverses the document and replaces LaTeX math syntax (wrapped in single dollar signs)\n * with proper inline math nodes, preserving the mathematical content.\n *\n * @param editor - The editor instance containing the schema and configuration\n * @param tr - The transaction to modify with the migration operations\n * @returns The modified transaction with math string replacements\n *\n * @example\n * ```typescript\n * const editor = new Editor({ ... })\n * const tr = editor.state.tr\n * const updatedTr = createMathMigrateTransaction(editor, tr)\n * editor.view.dispatch(updatedTr)\n * ```\n */\nexport function createMathMigrateTransaction(editor: Editor, tr: Transaction, regex: RegExp = mathMigrationRegex) {\n // we traverse the document and replace all math nodes with the new math nodes\n tr.doc.descendants((node, pos) => {\n if (!node.isText || !node.text || !node.text.includes('$')) {\n return\n }\n\n const { text } = node\n\n const match = node.text.match(regex)\n if (!match) {\n return\n }\n\n match.forEach(mathMatch => {\n const start = text.indexOf(mathMatch)\n const end = start + mathMatch.length\n\n const from = tr.mapping.map(pos + start)\n\n const $from = tr.doc.resolve(from)\n const parent = $from.parent\n const index = $from.index()\n\n const { inlineMath } = editor.schema.nodes\n\n if (!parent.canReplaceWith(index, index + 1, inlineMath)) {\n return\n }\n\n // Replace the math syntax with a new math node\n tr.replaceWith(\n tr.mapping.map(pos + start),\n tr.mapping.map(pos + end),\n inlineMath.create({ latex: mathMatch.slice(1, -1) }),\n )\n })\n })\n\n // don't add to history\n tr.setMeta('addToHistory', false)\n return tr\n}\n\n/**\n * Migrates existing math strings in the editor document to math nodes.\n * This function creates and dispatches a transaction that converts LaTeX math syntax\n * (text wrapped in single dollar signs) into proper inline math nodes. The migration\n * happens immediately and is not added to the editor's history.\n *\n * @param editor - The editor instance to perform the migration on\n *\n * @example\n * ```typescript\n * const editor = new Editor({\n * extensions: [Mathematics],\n * content: 'This is inline math: $x^2 + y^2 = z^2$ in text.'\n * })\n *\n * // Math strings will be automatically migrated to math nodes\n * migrateMathStrings(editor)\n * ```\n */\nexport function migrateMathStrings(editor: Editor, regex: RegExp = mathMigrationRegex) {\n const tr = createMathMigrateTransaction(editor, editor.state.tr, regex)\n editor.view.dispatch(tr)\n}\n","import { Mathematics } from './mathematics.js'\n\nexport * from './extensions/index.js'\nexport * from './mathematics.js'\nexport * from './types.js'\nexport * from './utils.js'\n\nexport default Mathematics\n"],"mappings":"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","names":["InputRule","mergeAttributes","Node","katex"]}
|
|
1
|
+
{"version":3,"sources":["../src/mathematics.ts","../src/extensions/BlockMath.ts","../src/extensions/InlineMath.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\n\nimport { BlockMath, InlineMath } from './extensions/index.js'\nimport type { MathematicsOptions } from './types.js'\n\n/**\n * Mathematics extension for Tiptap that provides both inline and block math support using KaTeX.\n * This extension combines the InlineMath and BlockMath extensions to provide a complete\n * mathematical expression solution for rich text editing. It supports LaTeX syntax,\n * custom rendering options, and interactive math nodes.\n *\n * @example\n * ```typescript\n * import { Editor } from '@tiptap/core'\n * import { Mathematics } from '@tiptap/extension-mathematics'\n * import { migrateMathStrings } from '@tiptap/extension-mathematics/utils'\n *\n * const editor = new Editor({\n * extensions: [\n * Mathematics.configure({\n * inlineOptions: {\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex)\n * }\n * },\n * blockOptions: {\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex)\n * }\n * },\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * })\n * ],\n * content: `\n * <p>Inline math: $E = mc^2$</p>\n * <div data-type=\"block-math\" data-latex=\"\\\\sum_{i=1}^{n} x_i = X\"></div>\n * `,\n * onCreate({ editor }) {\n * // Optional: Migrate existing math strings to math nodes\n * migrateMathStrings(editor)\n * }\n * })\n * ```\n */\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n inlineOptions: undefined,\n blockOptions: undefined,\n katexOptions: undefined,\n }\n },\n\n addExtensions() {\n return [\n BlockMath.configure({\n ...this.options.blockOptions,\n katexOptions: this.options.katexOptions,\n }),\n InlineMath.configure({\n ...this.options.inlineOptions,\n katexOptions: this.options.katexOptions,\n }),\n ]\n },\n})\n\nexport default Mathematics\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the BlockMath extension.\n */\nexport type BlockMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: true,\n * throwOnError: false,\n * },\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for block math nodes.\n * Called when a user clicks on a block math expression in the editor.\n *\n * @param node - The ProseMirror node representing the block math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n insertBlockMath: {\n /**\n * Inserts a math block node with LaTeX string.\n * @param options - Options for inserting block math.\n * @returns ReturnType\n */\n insertBlockMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Deletes a block math node.\n * @returns ReturnType\n */\n deleteBlockMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update block math node with optional LaTeX string.\n * @param options - Options for updating block math.\n * @returns ReturnType\n */\n updateBlockMath: (options?: { latex: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * BlockMath is a Tiptap extension for rendering block mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions block within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { BlockMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * BlockMath.configure({\n * onClick: (node, pos) => {\n * console.log('Block math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const BlockMath = Node.create<BlockMathOptions>({\n name: 'blockMath',\n\n group: 'block',\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertBlockMath:\n options =>\n ({ commands, editor }) => {\n const { latex, pos } = options\n\n if (!latex) {\n return false\n }\n\n return commands.insertContentAt(pos ?? editor.state.selection.from, {\n type: this.name,\n attrs: { latex },\n })\n },\n\n deleteBlockMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateBlockMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, {\n ...node.attrs,\n latex: latex ?? node.attrs.latex,\n })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"block-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'block-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'blockMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n const output = ['$$', latex, '$$']\n return output.join('\\n')\n },\n\n markdownTokenizer: {\n name: 'blockMath',\n level: 'block',\n start: (src: string) => src.indexOf('$$'),\n tokenize: (src: string) => {\n // Match $$latex$$ syntax for block math\n const match = src.match(/^\\$\\$([^$]+)\\$\\$/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'blockMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /^\\$\\$\\$([^$]+)\\$\\$\\$$/,\n handler: ({ state, range, match }) => {\n const [, latex] = match\n const { tr } = state\n const $from = state.doc.resolve(range.from)\n const node = this.type.create({ latex })\n\n const consumesHostTextblock =\n $from.depth > 0 &&\n $from.parent.isTextblock &&\n range.from === $from.start() &&\n range.to === $from.end()\n // Whether the node containing the host textblock can replace it with a blockMath node.\n const canReplaceHostTextblock =\n consumesHostTextblock &&\n $from.node(-1).canReplaceWith($from.index(-1), $from.indexAfter(-1), this.type)\n\n const replacementRange = canReplaceHostTextblock\n ? { from: $from.before(), to: $from.after() }\n : range\n\n tr.replaceWith(replacementRange.from, replacementRange.to, node)\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('div')\n const innerWrapper = document.createElement('div')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n innerWrapper.className = 'block-math-inner'\n wrapper.dataset.type = 'block-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n wrapper.appendChild(innerWrapper)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, innerWrapper, katexOptions)\n wrapper.classList.remove('block-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('block-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import { InputRule, mergeAttributes, Node } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport katex, { type KatexOptions } from 'katex'\n\n/**\n * Configuration options for the InlineMath extension.\n */\nexport type InlineMathOptions = {\n /**\n * KaTeX specific options\n * @see https://katex.org/docs/options.html\n * @example\n * ```ts\n * katexOptions: {\n * displayMode: false,\n * throwOnError: false,\n * macros: {\n * '\\\\RR': '\\\\mathbb{R}',\n * '\\\\ZZ': '\\\\mathbb{Z}'\n * }\n * }\n * ```\n */\n katexOptions?: KatexOptions\n\n /**\n * Optional click handler for inline math nodes.\n * Called when a user clicks on an inline math expression in the editor.\n *\n * @param node - The ProseMirror node representing the inline math element\n * @param pos - The position of the node within the document\n * @example\n * ```ts\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * }\n * ```\n */\n onClick?: (node: PMNode, pos: number) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n inlineMath: {\n /**\n * Insert a inline math node with LaTeX string.\n * @param options - Options for inserting inline math.\n * @returns ReturnType\n */\n insertInlineMath: (options: { latex: string; pos?: number }) => ReturnType\n\n /**\n * Delete an inline math node.\n * @returns ReturnType\n */\n deleteInlineMath: (options?: { pos?: number }) => ReturnType\n\n /**\n * Update inline math node with optional LaTeX string.\n * @param options - Options for updating inline math.\n * @returns ReturnType\n */\n updateInlineMath: (options?: { latex?: string; pos?: number }) => ReturnType\n }\n }\n}\n\n/**\n * InlineMath is a Tiptap extension for rendering inline mathematical expressions using KaTeX.\n * It allows users to insert LaTeX formatted math expressions inline within text.\n * It supports rendering, input rules for LaTeX syntax, and click handling for interaction.\n *\n * @example\n * ```javascript\n * import { InlineMath } from '@tiptap/extension-mathematics'\n * import { Editor } from '@tiptap/core'\n *\n * const editor = new Editor({\n * extensions: [\n * InlineMath.configure({\n * onClick: (node, pos) => {\n * console.log('Inline math clicked:', node.attrs.latex, 'at position:', pos)\n * },\n * }),\n * ],\n * })\n */\nexport const InlineMath = Node.create<InlineMathOptions>({\n name: 'inlineMath',\n\n group: 'inline',\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n onClick: undefined,\n katexOptions: undefined,\n }\n },\n\n addAttributes() {\n return {\n latex: {\n default: '',\n parseHTML: element => element.getAttribute('data-latex'),\n renderHTML: attributes => {\n return {\n 'data-latex': attributes.latex,\n }\n },\n },\n }\n },\n\n addCommands() {\n return {\n insertInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options.latex\n\n const from = options?.pos ?? editor.state.selection.from\n\n if (!latex) {\n return false\n }\n\n tr.replaceWith(from, from, this.type.create({ latex }))\n return true\n },\n\n deleteInlineMath:\n options =>\n ({ editor, tr }) => {\n const pos = options?.pos ?? editor.state.selection.$from.pos\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.delete(pos, pos + node.nodeSize)\n return true\n },\n\n updateInlineMath:\n options =>\n ({ editor, tr }) => {\n const latex = options?.latex\n let pos = options?.pos\n\n if (pos === undefined) {\n pos = editor.state.selection.$from.pos\n }\n\n const node = editor.state.doc.nodeAt(pos)\n\n if (!node || node.type.name !== this.name) {\n return false\n }\n\n tr.setNodeMarkup(pos, this.type, { ...node.attrs, latex })\n\n return true\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"inline-math\"]',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'inline-math' })]\n },\n\n parseMarkdown: (token: any) => {\n return {\n type: 'inlineMath',\n attrs: {\n latex: token.latex,\n },\n }\n },\n\n renderMarkdown: node => {\n const latex = node.attrs?.latex || ''\n\n return `$${latex}$`\n },\n\n markdownTokenizer: {\n name: 'inlineMath',\n level: 'inline',\n start: (src: string) => src.indexOf('$'),\n tokenize: (src: string) => {\n // Match $latex$ syntax for inline math (but not $$)\n const match = src.match(/^\\$([^$]+)\\$(?!\\$)/)\n if (!match) {\n return undefined\n }\n\n const [fullMatch, latex] = match\n\n return {\n type: 'inlineMath',\n raw: fullMatch,\n latex: latex.trim(),\n }\n },\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /(?<!\\$)(\\$\\$([^$\\n]+?)\\$\\$)(?!\\$)/,\n handler: ({ state, range, match }) => {\n const latex = match[2]\n const { tr } = state\n const start = range.from\n const end = range.to\n\n tr.replaceWith(start, end, this.type.create({ latex }))\n },\n }),\n ]\n },\n\n addNodeView() {\n const { katexOptions } = this.options\n\n return ({ node, getPos }) => {\n const wrapper = document.createElement('span')\n wrapper.className = 'tiptap-mathematics-render'\n\n if (this.editor.isEditable) {\n wrapper.classList.add('tiptap-mathematics-render--editable')\n }\n\n wrapper.dataset.type = 'inline-math'\n wrapper.setAttribute('data-latex', node.attrs.latex)\n\n function renderMath() {\n try {\n katex.render(node.attrs.latex, wrapper, katexOptions)\n wrapper.classList.remove('inline-math-error')\n } catch {\n wrapper.textContent = node.attrs.latex\n wrapper.classList.add('inline-math-error')\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n const pos = getPos()\n\n if (pos == null) {\n return\n }\n\n if (this.options.onClick) {\n this.options.onClick(node, pos)\n }\n }\n\n if (this.options.onClick) {\n wrapper.addEventListener('click', handleClick)\n }\n\n renderMath()\n\n return {\n dom: wrapper,\n destroy() {\n wrapper.removeEventListener('click', handleClick)\n },\n }\n }\n },\n})\n","import type { Editor } from '@tiptap/core'\nimport type { Transaction } from '@tiptap/pm/state'\n\n/**\n * Regular expression to match LaTeX math strings wrapped in single dollar signs.\n * This should not catch dollar signs which are not part of a math expression,\n * like those used for currency or other purposes.\n * It ensures that the dollar signs are not preceded or followed by digits,\n * allowing for proper identification of inline math expressions.\n *\n * - `$x^2 + y^2 = z^2$` will match\n * - `This is $inline math$ in text.` will match\n * - `This is $100$ dollars.` will not match (as it is not a math expression)\n * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions\n */\nexport const mathMigrationRegex = /\\$(?!\\d+\\$)(.+?)\\$(?!\\d)/g\n\n/**\n * Creates a transaction that migrates existing math strings in the document to new math nodes.\n * This function traverses the document and replaces LaTeX math syntax (wrapped in single dollar signs)\n * with proper inline math nodes, preserving the mathematical content.\n *\n * @param editor - The editor instance containing the schema and configuration\n * @param tr - The transaction to modify with the migration operations\n * @returns The modified transaction with math string replacements\n *\n * @example\n * ```typescript\n * const editor = new Editor({ ... })\n * const tr = editor.state.tr\n * const updatedTr = createMathMigrateTransaction(editor, tr)\n * editor.view.dispatch(updatedTr)\n * ```\n */\nexport function createMathMigrateTransaction(\n editor: Editor,\n tr: Transaction,\n regex: RegExp = mathMigrationRegex,\n) {\n // we traverse the document and replace all math nodes with the new math nodes\n tr.doc.descendants((node, pos) => {\n if (!node.isText || !node.text || !node.text.includes('$')) {\n return\n }\n\n const { text } = node\n\n const match = node.text.match(regex)\n if (!match) {\n return\n }\n\n match.forEach(mathMatch => {\n const start = text.indexOf(mathMatch)\n const end = start + mathMatch.length\n\n const from = tr.mapping.map(pos + start)\n\n const $from = tr.doc.resolve(from)\n const parent = $from.parent\n const index = $from.index()\n\n const { inlineMath } = editor.schema.nodes\n\n if (!parent.canReplaceWith(index, index + 1, inlineMath)) {\n return\n }\n\n // Replace the math syntax with a new math node\n tr.replaceWith(\n tr.mapping.map(pos + start),\n tr.mapping.map(pos + end),\n inlineMath.create({ latex: mathMatch.slice(1, -1) }),\n )\n })\n })\n\n // don't add to history\n tr.setMeta('addToHistory', false)\n return tr\n}\n\n/**\n * Migrates existing math strings in the editor document to math nodes.\n * This function creates and dispatches a transaction that converts LaTeX math syntax\n * (text wrapped in single dollar signs) into proper inline math nodes. The migration\n * happens immediately and is not added to the editor's history.\n *\n * @param editor - The editor instance to perform the migration on\n *\n * @example\n * ```typescript\n * const editor = new Editor({\n * extensions: [Mathematics],\n * content: 'This is inline math: $x^2 + y^2 = z^2$ in text.'\n * })\n *\n * // Math strings will be automatically migrated to math nodes\n * migrateMathStrings(editor)\n * ```\n */\nexport function migrateMathStrings(editor: Editor, regex: RegExp = mathMigrationRegex) {\n const tr = createMathMigrateTransaction(editor, editor.state.tr, regex)\n editor.view.dispatch(tr)\n}\n","import { Mathematics } from './mathematics.js'\n\nexport * from './extensions/index.js'\nexport * from './mathematics.js'\nexport * from './types.js'\nexport * from './utils.js'\n\nexport default Mathematics\n"],"mappings":"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","names":["InputRule","mergeAttributes","Node","katex"]}
|
package/package.json
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/extension-mathematics",
|
|
3
|
+
"version": "3.24.0",
|
|
3
4
|
"description": "latex math extension for tiptap",
|
|
4
|
-
"version": "3.23.6",
|
|
5
|
-
"homepage": "https://tiptap.dev/api/extensions/mathematics",
|
|
6
5
|
"keywords": [
|
|
7
6
|
"tiptap",
|
|
8
7
|
"tiptap extension"
|
|
9
8
|
],
|
|
9
|
+
"homepage": "https://tiptap.dev/api/extensions/mathematics",
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"funding": {
|
|
12
|
-
"type": "github",
|
|
13
|
-
"url": "https://github.com/sponsors/ueberdosis"
|
|
14
|
-
},
|
|
15
11
|
"repository": {
|
|
16
12
|
"type": "git",
|
|
17
13
|
"url": "https://github.com/ueberdosis/tiptap",
|
|
18
14
|
"directory": "packages/extension-mathematics"
|
|
19
15
|
},
|
|
16
|
+
"funding": {
|
|
17
|
+
"type": "github",
|
|
18
|
+
"url": "https://github.com/sponsors/ueberdosis"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"src",
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
20
24
|
"type": "module",
|
|
25
|
+
"main": "dist/index.cjs",
|
|
26
|
+
"module": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
21
28
|
"exports": {
|
|
22
29
|
".": {
|
|
23
30
|
"types": {
|
|
@@ -28,25 +35,17 @@
|
|
|
28
35
|
"require": "./dist/index.cjs"
|
|
29
36
|
}
|
|
30
37
|
},
|
|
31
|
-
"main": "dist/index.cjs",
|
|
32
|
-
"module": "dist/index.js",
|
|
33
|
-
"types": "dist/index.d.ts",
|
|
34
|
-
"files": [
|
|
35
|
-
"src",
|
|
36
|
-
"dist"
|
|
37
|
-
],
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/katex": "^0.16.7",
|
|
40
|
-
"@tiptap/core": "^3.
|
|
41
|
-
"@tiptap/pm": "^3.
|
|
40
|
+
"@tiptap/core": "^3.24.0",
|
|
41
|
+
"@tiptap/pm": "^3.24.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"katex": "^0.16.4",
|
|
45
|
-
"@tiptap/core": "3.
|
|
46
|
-
"@tiptap/pm": "3.
|
|
45
|
+
"@tiptap/core": "3.24.0",
|
|
46
|
+
"@tiptap/pm": "3.24.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
|
-
"build": "tsup"
|
|
50
|
-
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
|
|
49
|
+
"build": "tsup"
|
|
51
50
|
}
|
|
52
51
|
}
|
|
@@ -225,12 +225,18 @@ export const BlockMath = Node.create<BlockMathOptions>({
|
|
|
225
225
|
const node = this.type.create({ latex })
|
|
226
226
|
|
|
227
227
|
const consumesHostTextblock =
|
|
228
|
-
$from.depth > 0 &&
|
|
228
|
+
$from.depth > 0 &&
|
|
229
|
+
$from.parent.isTextblock &&
|
|
230
|
+
range.from === $from.start() &&
|
|
231
|
+
range.to === $from.end()
|
|
229
232
|
// Whether the node containing the host textblock can replace it with a blockMath node.
|
|
230
233
|
const canReplaceHostTextblock =
|
|
231
|
-
consumesHostTextblock &&
|
|
234
|
+
consumesHostTextblock &&
|
|
235
|
+
$from.node(-1).canReplaceWith($from.index(-1), $from.indexAfter(-1), this.type)
|
|
232
236
|
|
|
233
|
-
const replacementRange = canReplaceHostTextblock
|
|
237
|
+
const replacementRange = canReplaceHostTextblock
|
|
238
|
+
? { from: $from.before(), to: $from.after() }
|
|
239
|
+
: range
|
|
234
240
|
|
|
235
241
|
tr.replaceWith(replacementRange.from, replacementRange.to, node)
|
|
236
242
|
},
|
package/src/mathematics.ts
CHANGED
|
@@ -62,8 +62,14 @@ export const Mathematics = Extension.create<MathematicsOptions>({
|
|
|
62
62
|
|
|
63
63
|
addExtensions() {
|
|
64
64
|
return [
|
|
65
|
-
BlockMath.configure({
|
|
66
|
-
|
|
65
|
+
BlockMath.configure({
|
|
66
|
+
...this.options.blockOptions,
|
|
67
|
+
katexOptions: this.options.katexOptions,
|
|
68
|
+
}),
|
|
69
|
+
InlineMath.configure({
|
|
70
|
+
...this.options.inlineOptions,
|
|
71
|
+
katexOptions: this.options.katexOptions,
|
|
72
|
+
}),
|
|
67
73
|
]
|
|
68
74
|
},
|
|
69
75
|
})
|
package/src/utils.ts
CHANGED
|
@@ -32,7 +32,11 @@ export const mathMigrationRegex = /\$(?!\d+\$)(.+?)\$(?!\d)/g
|
|
|
32
32
|
* editor.view.dispatch(updatedTr)
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
export function createMathMigrateTransaction(
|
|
35
|
+
export function createMathMigrateTransaction(
|
|
36
|
+
editor: Editor,
|
|
37
|
+
tr: Transaction,
|
|
38
|
+
regex: RegExp = mathMigrationRegex,
|
|
39
|
+
) {
|
|
36
40
|
// we traverse the document and replace all math nodes with the new math nodes
|
|
37
41
|
tr.doc.descendants((node, pos) => {
|
|
38
42
|
if (!node.isText || !node.text || !node.text.includes('$')) {
|