@tiptap/extension-mathematics 2.24.2 → 3.0.0-beta.10

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.js CHANGED
@@ -1,166 +1,169 @@
1
- import { getChangedRanges, Extension } from '@tiptap/core';
2
- import { Plugin, PluginKey } from '@tiptap/pm/state';
3
- import { DecorationSet, Decoration } from '@tiptap/pm/view';
4
- import katex from 'katex';
1
+ // src/mathematics.ts
2
+ import { Extension } from "@tiptap/core";
5
3
 
6
- /**
7
- * Get the range of positions that have been affected by a transaction
8
- */
4
+ // src/MathematicsPlugin.ts
5
+ import { getChangedRanges } from "@tiptap/core";
6
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
7
+ import { Decoration, DecorationSet } from "@tiptap/pm/view";
8
+ import katex from "katex";
9
9
  function getAffectedRange(newState, previousPluginState, isEditable, tr, state) {
10
- const docSize = newState.doc.nodeSize - 2;
11
- let minFrom = 0;
12
- let maxTo = docSize;
13
- if (previousPluginState.isEditable !== isEditable) {
14
- // When the editable state changes, run on all nodes just to be safe
15
- minFrom = 0;
16
- maxTo = docSize;
17
- }
18
- else if (tr.docChanged) {
19
- // When the document changes, only run on the nodes that have changed
20
- minFrom = docSize;
21
- maxTo = 0;
22
- getChangedRanges(tr).forEach(range => {
23
- // Purposefully over scan the range to ensure we catch all decorations
24
- minFrom = Math.min(minFrom, range.newRange.from - 1, range.oldRange.from - 1);
25
- maxTo = Math.max(maxTo, range.newRange.to + 1, range.oldRange.to + 1);
26
- });
27
- }
28
- else if (tr.selectionSet) {
29
- const { $from, $to } = state.selection;
30
- const { $from: $newFrom, $to: $newTo } = newState.selection;
31
- // When the selection changes, run on all the nodes between the old and new selection
32
- minFrom = Math.min(
33
- // Purposefully over scan the range to ensure we catch all decorations
34
- $from.depth === 0 ? 0 : $from.before(), $newFrom.depth === 0 ? 0 : $newFrom.before());
35
- maxTo = Math.max($to.depth === 0 ? maxTo : $to.after(), $newTo.depth === 0 ? maxTo : $newTo.after());
36
- }
37
- return {
38
- minFrom: Math.max(minFrom, 0),
39
- maxTo: Math.min(maxTo, docSize),
40
- };
10
+ const docSize = newState.doc.nodeSize - 2;
11
+ let minFrom = 0;
12
+ let maxTo = docSize;
13
+ if (previousPluginState.isEditable !== isEditable) {
14
+ minFrom = 0;
15
+ maxTo = docSize;
16
+ } else if (tr.docChanged) {
17
+ minFrom = docSize;
18
+ maxTo = 0;
19
+ getChangedRanges(tr).forEach((range) => {
20
+ minFrom = Math.min(minFrom, range.newRange.from - 1, range.oldRange.from - 1);
21
+ maxTo = Math.max(maxTo, range.newRange.to + 1, range.oldRange.to + 1);
22
+ });
23
+ } else if (tr.selectionSet) {
24
+ const { $from, $to } = state.selection;
25
+ const { $from: $newFrom, $to: $newTo } = newState.selection;
26
+ minFrom = Math.min(
27
+ // Purposefully over scan the range to ensure we catch all decorations
28
+ $from.depth === 0 ? 0 : $from.before(),
29
+ $newFrom.depth === 0 ? 0 : $newFrom.before()
30
+ );
31
+ maxTo = Math.max($to.depth === 0 ? maxTo : $to.after(), $newTo.depth === 0 ? maxTo : $newTo.after());
32
+ }
33
+ return {
34
+ minFrom: Math.max(minFrom, 0),
35
+ maxTo: Math.min(maxTo, docSize)
36
+ };
41
37
  }
42
- const MathematicsPlugin = (options) => {
43
- const { regex, katexOptions = {}, editor, shouldRender, } = options;
44
- return new Plugin({
45
- key: new PluginKey('mathematics'),
46
- state: {
47
- init() {
48
- return { decorations: undefined, isEditable: undefined };
49
- },
50
- apply(tr, previousPluginState, state, newState) {
51
- if (!tr.docChanged && !tr.selectionSet && previousPluginState.decorations) {
52
- // Just reuse the existing decorations, since nothing should have changed
53
- return previousPluginState;
38
+ var MathematicsPlugin = (options) => {
39
+ const { regex, katexOptions = {}, editor, shouldRender } = options;
40
+ return new Plugin({
41
+ key: new PluginKey("mathematics"),
42
+ state: {
43
+ init() {
44
+ return { decorations: void 0, isEditable: void 0 };
45
+ },
46
+ apply(tr, previousPluginState, state, newState) {
47
+ if (!tr.docChanged && !tr.selectionSet && previousPluginState.decorations) {
48
+ return previousPluginState;
49
+ }
50
+ const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(tr.mapping, tr.doc);
51
+ const { selection } = newState;
52
+ const isEditable = editor.isEditable;
53
+ const decorationsToAdd = [];
54
+ const { minFrom, maxTo } = getAffectedRange(newState, previousPluginState, isEditable, tr, state);
55
+ newState.doc.nodesBetween(minFrom, maxTo, (node, pos) => {
56
+ const enabled = shouldRender(newState, pos, node);
57
+ if (node.isText && node.text && enabled) {
58
+ let match;
59
+ while (match = regex.exec(node.text)) {
60
+ const from = pos + match.index;
61
+ const to = from + match[0].length;
62
+ const content = match.slice(1).find(Boolean);
63
+ if (content) {
64
+ const selectionSize = selection.from - selection.to;
65
+ const anchorIsInside = selection.anchor >= from && selection.anchor <= to;
66
+ const rangeIsInside = selection.from >= from && selection.to <= to;
67
+ const isEditing = selectionSize === 0 && anchorIsInside || rangeIsInside;
68
+ if (
69
+ // Are the decorations already present?
70
+ nextDecorationSet.find(
71
+ from,
72
+ to,
73
+ (deco) => isEditing === deco.isEditing && content === deco.content && isEditable === deco.isEditable && katexOptions === deco.katexOptions
74
+ ).length
75
+ ) {
76
+ continue;
54
77
  }
55
- const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(tr.mapping, tr.doc);
56
- const { selection } = newState;
57
- const isEditable = editor.isEditable;
58
- const decorationsToAdd = [];
59
- const { minFrom, maxTo } = getAffectedRange(newState, previousPluginState, isEditable, tr, state);
60
- newState.doc.nodesBetween(minFrom, maxTo, (node, pos) => {
61
- const enabled = shouldRender(newState, pos, node);
62
- if (node.isText && node.text && enabled) {
63
- let match;
64
- // eslint-disable-next-line no-cond-assign
65
- while ((match = regex.exec(node.text))) {
66
- const from = pos + match.index;
67
- const to = from + match[0].length;
68
- const content = match.slice(1).find(Boolean);
69
- if (content) {
70
- const selectionSize = selection.from - selection.to;
71
- const anchorIsInside = selection.anchor >= from && selection.anchor <= to;
72
- const rangeIsInside = selection.from >= from && selection.to <= to;
73
- const isEditing = (selectionSize === 0 && anchorIsInside) || rangeIsInside;
74
- if (
75
- // Are the decorations already present?
76
- nextDecorationSet.find(from, to, (deco) => isEditing === deco.isEditing
77
- && content === deco.content
78
- && isEditable === deco.isEditable
79
- && katexOptions === deco.katexOptions).length) {
80
- // Decoration exists in set, no need to add it again
81
- continue;
82
- }
83
- // Use an inline decoration to either hide original (preview is showing) or show it (editing "mode")
84
- decorationsToAdd.push(Decoration.inline(from, to, {
85
- class: isEditing && isEditable
86
- ? 'Tiptap-mathematics-editor'
87
- : 'Tiptap-mathematics-editor Tiptap-mathematics-editor--hidden',
88
- style: !isEditing || !isEditable
89
- ? 'display: inline-block; height: 0; opacity: 0; overflow: hidden; position: absolute; width: 0;'
90
- : undefined,
91
- }, {
92
- content,
93
- isEditable,
94
- isEditing,
95
- katexOptions,
96
- }));
97
- if (!isEditable || !isEditing) {
98
- // Create decoration widget and add KaTeX preview if selection is not within the math-editor
99
- decorationsToAdd.push(Decoration.widget(from, () => {
100
- const element = document.createElement('span');
101
- // TODO: changeable class names
102
- element.classList.add('Tiptap-mathematics-render');
103
- if (isEditable) {
104
- element.classList.add('Tiptap-mathematics-render--editable');
105
- }
106
- try {
107
- katex.render(content, element, katexOptions);
108
- }
109
- catch {
110
- element.innerHTML = content;
111
- }
112
- return element;
113
- }, {
114
- content,
115
- isEditable,
116
- isEditing,
117
- katexOptions,
118
- }));
119
- }
120
- }
121
- }
78
+ decorationsToAdd.push(
79
+ Decoration.inline(
80
+ from,
81
+ to,
82
+ {
83
+ class: isEditing && isEditable ? "Tiptap-mathematics-editor" : "Tiptap-mathematics-editor Tiptap-mathematics-editor--hidden",
84
+ style: !isEditing || !isEditable ? "display: inline-block; height: 0; opacity: 0; overflow: hidden; position: absolute; width: 0;" : void 0
85
+ },
86
+ {
87
+ content,
88
+ isEditable,
89
+ isEditing,
90
+ katexOptions
122
91
  }
123
- });
124
- // Remove any decorations that exist at the same position, they will be replaced by the new decorations
125
- const decorationsToRemove = decorationsToAdd.flatMap(deco => nextDecorationSet.find(deco.from, deco.to));
126
- return {
127
- decorations: nextDecorationSet
128
- // Remove existing decorations that are going to be replaced
129
- .remove(decorationsToRemove)
130
- // Add any new decorations
131
- .add(tr.doc, decorationsToAdd),
132
- isEditable,
133
- };
134
- },
135
- },
136
- props: {
137
- decorations(state) {
138
- var _a, _b;
139
- return (_b = (_a = this.getState(state)) === null || _a === void 0 ? void 0 : _a.decorations) !== null && _b !== void 0 ? _b : DecorationSet.empty;
140
- },
141
- },
142
- });
143
- };
144
-
145
- const defaultShouldRender = (state, pos) => {
146
- const $pos = state.doc.resolve(pos);
147
- const isInCodeBlock = $pos.parent.type.name === 'codeBlock';
148
- return !isInCodeBlock;
149
- };
150
- const Mathematics = Extension.create({
151
- name: 'Mathematics',
152
- addOptions() {
92
+ )
93
+ );
94
+ if (!isEditable || !isEditing) {
95
+ decorationsToAdd.push(
96
+ Decoration.widget(
97
+ from,
98
+ () => {
99
+ const element = document.createElement("span");
100
+ element.classList.add("Tiptap-mathematics-render");
101
+ if (isEditable) {
102
+ element.classList.add("Tiptap-mathematics-render--editable");
103
+ }
104
+ try {
105
+ katex.render(content, element, katexOptions);
106
+ } catch {
107
+ element.innerHTML = content;
108
+ }
109
+ return element;
110
+ },
111
+ {
112
+ content,
113
+ isEditable,
114
+ isEditing,
115
+ katexOptions
116
+ }
117
+ )
118
+ );
119
+ }
120
+ }
121
+ }
122
+ }
123
+ });
124
+ const decorationsToRemove = decorationsToAdd.flatMap((deco) => nextDecorationSet.find(deco.from, deco.to));
153
125
  return {
154
- // eslint-disable-next-line no-useless-escape
155
- regex: /\$([^\$]*)\$/gi,
156
- katexOptions: undefined,
157
- shouldRender: defaultShouldRender,
126
+ decorations: nextDecorationSet.remove(decorationsToRemove).add(tr.doc, decorationsToAdd),
127
+ isEditable
158
128
  };
129
+ }
159
130
  },
160
- addProseMirrorPlugins() {
161
- return [MathematicsPlugin({ ...this.options, editor: this.editor })];
162
- },
131
+ props: {
132
+ decorations(state) {
133
+ var _a, _b;
134
+ return (_b = (_a = this.getState(state)) == null ? void 0 : _a.decorations) != null ? _b : DecorationSet.empty;
135
+ }
136
+ }
137
+ });
138
+ };
139
+
140
+ // src/mathematics.ts
141
+ var defaultShouldRender = (state, pos) => {
142
+ const $pos = state.doc.resolve(pos);
143
+ const isInCodeBlock = $pos.parent.type.name === "codeBlock";
144
+ return !isInCodeBlock;
145
+ };
146
+ var Mathematics = Extension.create({
147
+ name: "Mathematics",
148
+ addOptions() {
149
+ return {
150
+ // eslint-disable-next-line no-useless-escape
151
+ regex: /\$([^\$]*)\$/gi,
152
+ katexOptions: void 0,
153
+ shouldRender: defaultShouldRender
154
+ };
155
+ },
156
+ addProseMirrorPlugins() {
157
+ return [MathematicsPlugin({ ...this.options, editor: this.editor })];
158
+ }
163
159
  });
164
160
 
165
- export { Mathematics, MathematicsPlugin, Mathematics as default, defaultShouldRender };
166
- //# sourceMappingURL=index.js.map
161
+ // src/index.ts
162
+ var index_default = Mathematics;
163
+ export {
164
+ Mathematics,
165
+ MathematicsPlugin,
166
+ index_default as default,
167
+ defaultShouldRender
168
+ };
169
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/MathematicsPlugin.ts","../src/mathematics.ts"],"sourcesContent":["import { getChangedRanges } from '@tiptap/core'\nimport {\n EditorState, Plugin, PluginKey, Transaction,\n} from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\nimport katex from 'katex'\n\nimport { MathematicsOptionsWithEditor } from './types.js'\n\ntype DecoSpec = {\n isEditable: boolean;\n isEditing: boolean;\n katexOptions: MathematicsOptionsWithEditor['katexOptions'];\n content: string;\n};\n\ntype Deco = Omit<Decoration, 'spec'> & { spec: DecoSpec };\n\ntype PluginState =\n| { decorations: DecorationSet; isEditable: boolean }\n| { decorations: undefined; isEditable: undefined }\n\n/**\n * Get the range of positions that have been affected by a transaction\n */\nfunction getAffectedRange(newState: EditorState, previousPluginState: PluginState, isEditable: boolean, tr: Transaction, state: EditorState) {\n const docSize = newState.doc.nodeSize - 2\n let minFrom = 0\n let maxTo = docSize\n\n if (previousPluginState.isEditable !== isEditable) {\n // When the editable state changes, run on all nodes just to be safe\n minFrom = 0\n maxTo = docSize\n } else if (tr.docChanged) {\n // When the document changes, only run on the nodes that have changed\n minFrom = docSize\n maxTo = 0\n\n getChangedRanges(tr).forEach(range => {\n // Purposefully over scan the range to ensure we catch all decorations\n minFrom = Math.min(minFrom, range.newRange.from - 1, range.oldRange.from - 1)\n maxTo = Math.max(maxTo, range.newRange.to + 1, range.oldRange.to + 1)\n })\n } else if (tr.selectionSet) {\n const { $from, $to } = state.selection\n const { $from: $newFrom, $to: $newTo } = newState.selection\n\n // When the selection changes, run on all the nodes between the old and new selection\n minFrom = Math.min(\n // Purposefully over scan the range to ensure we catch all decorations\n $from.depth === 0 ? 0 : $from.before(),\n $newFrom.depth === 0 ? 0 : $newFrom.before(),\n )\n maxTo = Math.max(\n $to.depth === 0 ? maxTo : $to.after(),\n $newTo.depth === 0 ? maxTo : $newTo.after(),\n )\n }\n\n return {\n minFrom: Math.max(minFrom, 0),\n maxTo: Math.min(maxTo, docSize),\n }\n}\n\nexport const MathematicsPlugin = (options: MathematicsOptionsWithEditor) => {\n const {\n regex, katexOptions = {}, editor, shouldRender,\n } = options\n\n return new Plugin<PluginState>({\n key: new PluginKey('mathematics'),\n\n state: {\n init() {\n return { decorations: undefined, isEditable: undefined }\n },\n apply(tr, previousPluginState, state, newState) {\n\n if (!tr.docChanged && !tr.selectionSet && previousPluginState.decorations) {\n // Just reuse the existing decorations, since nothing should have changed\n return previousPluginState\n }\n\n const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(\n tr.mapping,\n tr.doc,\n )\n const { selection } = newState\n const isEditable = editor.isEditable\n const decorationsToAdd = [] as Deco[]\n const { minFrom, maxTo } = getAffectedRange(newState, previousPluginState, isEditable, tr, state)\n\n newState.doc.nodesBetween(minFrom, maxTo, (node, pos) => {\n const enabled = shouldRender(newState, pos, node)\n\n if (node.isText && node.text && enabled) {\n let match: RegExpExecArray | null\n\n // eslint-disable-next-line no-cond-assign\n while ((match = regex.exec(node.text))) {\n const from = pos + match.index\n const to = from + match[0].length\n const content = match.slice(1).find(Boolean)\n\n if (content) {\n const selectionSize = selection.from - selection.to\n const anchorIsInside = selection.anchor >= from && selection.anchor <= to\n const rangeIsInside = selection.from >= from && selection.to <= to\n const isEditing = (selectionSize === 0 && anchorIsInside) || rangeIsInside\n\n if (\n // Are the decorations already present?\n nextDecorationSet.find(\n from,\n to,\n (deco: DecoSpec) => isEditing === deco.isEditing\n && content === deco.content\n && isEditable === deco.isEditable\n && katexOptions === deco.katexOptions,\n ).length\n ) {\n // Decoration exists in set, no need to add it again\n continue\n }\n // Use an inline decoration to either hide original (preview is showing) or show it (editing \"mode\")\n decorationsToAdd.push(\n Decoration.inline(\n from,\n to,\n {\n class:\n isEditing && isEditable\n ? 'Tiptap-mathematics-editor'\n : 'Tiptap-mathematics-editor Tiptap-mathematics-editor--hidden',\n style:\n !isEditing || !isEditable\n ? 'display: inline-block; height: 0; opacity: 0; overflow: hidden; position: absolute; width: 0;'\n : undefined,\n },\n {\n content,\n isEditable,\n isEditing,\n katexOptions,\n } satisfies DecoSpec,\n ),\n )\n\n if (!isEditable || !isEditing) {\n // Create decoration widget and add KaTeX preview if selection is not within the math-editor\n decorationsToAdd.push(\n Decoration.widget(\n from,\n () => {\n const element = document.createElement('span')\n\n // TODO: changeable class names\n element.classList.add('Tiptap-mathematics-render')\n\n if (isEditable) {\n element.classList.add('Tiptap-mathematics-render--editable')\n }\n\n try {\n katex.render(content!, element, katexOptions)\n } catch {\n element.innerHTML = content!\n }\n\n return element\n },\n {\n content,\n isEditable,\n isEditing,\n katexOptions,\n } satisfies DecoSpec,\n ),\n )\n }\n }\n }\n }\n })\n\n // Remove any decorations that exist at the same position, they will be replaced by the new decorations\n const decorationsToRemove = decorationsToAdd.flatMap(deco => nextDecorationSet.find(deco.from, deco.to))\n\n return {\n decorations: nextDecorationSet\n // Remove existing decorations that are going to be replaced\n .remove(decorationsToRemove)\n // Add any new decorations\n .add(tr.doc, decorationsToAdd),\n isEditable,\n }\n },\n },\n\n props: {\n decorations(state) {\n return this.getState(state)?.decorations ?? DecorationSet.empty\n },\n },\n })\n}\n","import { Extension } from '@tiptap/core'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { MathematicsPlugin } from './MathematicsPlugin.js'\nimport { MathematicsOptions } from './types.js'\n\nexport const defaultShouldRender = (state: EditorState, pos: number) => {\n const $pos = state.doc.resolve(pos)\n const isInCodeBlock = $pos.parent.type.name === 'codeBlock'\n\n return !isInCodeBlock\n}\n\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n // eslint-disable-next-line no-useless-escape\n regex: /\\$([^\\$]*)\\$/gi,\n katexOptions: undefined,\n shouldRender: defaultShouldRender,\n }\n },\n\n addProseMirrorPlugins() {\n return [MathematicsPlugin({ ...this.options, editor: this.editor })]\n },\n})\n\nexport default Mathematics\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"sources":["../src/mathematics.ts","../src/MathematicsPlugin.ts","../src/index.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport type { EditorState } from '@tiptap/pm/state'\n\nimport { MathematicsPlugin } from './MathematicsPlugin.js'\nimport type { MathematicsOptions } from './types.js'\n\nexport const defaultShouldRender = (state: EditorState, pos: number) => {\n const $pos = state.doc.resolve(pos)\n const isInCodeBlock = $pos.parent.type.name === 'codeBlock'\n\n return !isInCodeBlock\n}\n\nexport const Mathematics = Extension.create<MathematicsOptions>({\n name: 'Mathematics',\n\n addOptions() {\n return {\n // eslint-disable-next-line no-useless-escape\n regex: /\\$([^\\$]*)\\$/gi,\n katexOptions: undefined,\n shouldRender: defaultShouldRender,\n }\n },\n\n addProseMirrorPlugins() {\n return [MathematicsPlugin({ ...this.options, editor: this.editor })]\n },\n})\n\nexport default Mathematics\n","import { getChangedRanges } from '@tiptap/core'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\nimport katex from 'katex'\n\nimport type { MathematicsOptionsWithEditor } from './types.js'\n\ntype DecoSpec = {\n isEditable: boolean\n isEditing: boolean\n katexOptions: MathematicsOptionsWithEditor['katexOptions']\n content: string\n}\n\ntype Deco = Omit<Decoration, 'spec'> & { spec: DecoSpec }\n\ntype PluginState =\n | { decorations: DecorationSet; isEditable: boolean }\n | { decorations: undefined; isEditable: undefined }\n\n/**\n * Get the range of positions that have been affected by a transaction\n */\nfunction getAffectedRange(\n newState: EditorState,\n previousPluginState: PluginState,\n isEditable: boolean,\n tr: Transaction,\n state: EditorState,\n) {\n const docSize = newState.doc.nodeSize - 2\n let minFrom = 0\n let maxTo = docSize\n\n if (previousPluginState.isEditable !== isEditable) {\n // When the editable state changes, run on all nodes just to be safe\n minFrom = 0\n maxTo = docSize\n } else if (tr.docChanged) {\n // When the document changes, only run on the nodes that have changed\n minFrom = docSize\n maxTo = 0\n\n getChangedRanges(tr).forEach(range => {\n // Purposefully over scan the range to ensure we catch all decorations\n minFrom = Math.min(minFrom, range.newRange.from - 1, range.oldRange.from - 1)\n maxTo = Math.max(maxTo, range.newRange.to + 1, range.oldRange.to + 1)\n })\n } else if (tr.selectionSet) {\n const { $from, $to } = state.selection\n const { $from: $newFrom, $to: $newTo } = newState.selection\n\n // When the selection changes, run on all the nodes between the old and new selection\n minFrom = Math.min(\n // Purposefully over scan the range to ensure we catch all decorations\n $from.depth === 0 ? 0 : $from.before(),\n $newFrom.depth === 0 ? 0 : $newFrom.before(),\n )\n maxTo = Math.max($to.depth === 0 ? maxTo : $to.after(), $newTo.depth === 0 ? maxTo : $newTo.after())\n }\n\n return {\n minFrom: Math.max(minFrom, 0),\n maxTo: Math.min(maxTo, docSize),\n }\n}\n\nexport const MathematicsPlugin = (options: MathematicsOptionsWithEditor) => {\n const { regex, katexOptions = {}, editor, shouldRender } = options\n\n return new Plugin<PluginState>({\n key: new PluginKey('mathematics'),\n\n state: {\n init() {\n return { decorations: undefined, isEditable: undefined }\n },\n apply(tr, previousPluginState, state, newState) {\n if (!tr.docChanged && !tr.selectionSet && previousPluginState.decorations) {\n // Just reuse the existing decorations, since nothing should have changed\n return previousPluginState\n }\n\n const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(tr.mapping, tr.doc)\n const { selection } = newState\n const isEditable = editor.isEditable\n const decorationsToAdd = [] as Deco[]\n const { minFrom, maxTo } = getAffectedRange(newState, previousPluginState, isEditable, tr, state)\n\n newState.doc.nodesBetween(minFrom, maxTo, (node, pos) => {\n const enabled = shouldRender(newState, pos, node)\n\n if (node.isText && node.text && enabled) {\n let match: RegExpExecArray | null\n\n // eslint-disable-next-line no-cond-assign\n while ((match = regex.exec(node.text))) {\n const from = pos + match.index\n const to = from + match[0].length\n const content = match.slice(1).find(Boolean)\n\n if (content) {\n const selectionSize = selection.from - selection.to\n const anchorIsInside = selection.anchor >= from && selection.anchor <= to\n const rangeIsInside = selection.from >= from && selection.to <= to\n const isEditing = (selectionSize === 0 && anchorIsInside) || rangeIsInside\n\n if (\n // Are the decorations already present?\n nextDecorationSet.find(\n from,\n to,\n (deco: DecoSpec) =>\n isEditing === deco.isEditing &&\n content === deco.content &&\n isEditable === deco.isEditable &&\n katexOptions === deco.katexOptions,\n ).length\n ) {\n // Decoration exists in set, no need to add it again\n continue\n }\n // Use an inline decoration to either hide original (preview is showing) or show it (editing \"mode\")\n decorationsToAdd.push(\n Decoration.inline(\n from,\n to,\n {\n class:\n isEditing && isEditable\n ? 'Tiptap-mathematics-editor'\n : 'Tiptap-mathematics-editor Tiptap-mathematics-editor--hidden',\n style:\n !isEditing || !isEditable\n ? 'display: inline-block; height: 0; opacity: 0; overflow: hidden; position: absolute; width: 0;'\n : undefined,\n },\n {\n content,\n isEditable,\n isEditing,\n katexOptions,\n } satisfies DecoSpec,\n ),\n )\n\n if (!isEditable || !isEditing) {\n // Create decoration widget and add KaTeX preview if selection is not within the math-editor\n decorationsToAdd.push(\n Decoration.widget(\n from,\n () => {\n const element = document.createElement('span')\n\n // TODO: changeable class names\n element.classList.add('Tiptap-mathematics-render')\n\n if (isEditable) {\n element.classList.add('Tiptap-mathematics-render--editable')\n }\n\n try {\n katex.render(content!, element, katexOptions)\n } catch {\n element.innerHTML = content!\n }\n\n return element\n },\n {\n content,\n isEditable,\n isEditing,\n katexOptions,\n } satisfies DecoSpec,\n ),\n )\n }\n }\n }\n }\n })\n\n // Remove any decorations that exist at the same position, they will be replaced by the new decorations\n const decorationsToRemove = decorationsToAdd.flatMap(deco => nextDecorationSet.find(deco.from, deco.to))\n\n return {\n decorations: nextDecorationSet\n // Remove existing decorations that are going to be replaced\n .remove(decorationsToRemove)\n // Add any new decorations\n .add(tr.doc, decorationsToAdd),\n isEditable,\n }\n },\n },\n\n props: {\n decorations(state) {\n return this.getState(state)?.decorations ?? DecorationSet.empty\n },\n },\n })\n}\n","import { Mathematics } from './mathematics.js'\n\nexport * from './mathematics.js'\nexport * from './MathematicsPlugin.js'\nexport * from './types.js'\n\nexport default Mathematics\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-mathematics",
3
3
  "description": "latex math extension for tiptap",
4
- "version": "2.24.2",
4
+ "version": "3.0.0-beta.10",
5
5
  "homepage": "https://tiptap.dev/api/extensions/mathematics",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -20,31 +20,33 @@
20
20
  "type": "module",
21
21
  "exports": {
22
22
  ".": {
23
- "types": "./dist/index.d.ts",
23
+ "types": {
24
+ "import": "./dist/index.d.ts",
25
+ "require": "./dist/index.d.cts"
26
+ },
24
27
  "import": "./dist/index.js",
25
28
  "require": "./dist/index.cjs"
26
29
  }
27
30
  },
28
31
  "main": "dist/index.cjs",
29
32
  "module": "dist/index.js",
30
- "umd": "dist/index.umd.js",
31
33
  "types": "dist/index.d.ts",
32
34
  "files": [
33
35
  "src",
34
36
  "dist"
35
37
  ],
36
38
  "devDependencies": {
37
- "@tiptap/core": "^2.24.2",
38
- "@tiptap/pm": "^2.24.2",
39
- "@types/katex": "^0.16.7"
39
+ "@types/katex": "^0.16.7",
40
+ "@tiptap/core": "3.0.0-beta.10",
41
+ "@tiptap/pm": "3.0.0-beta.10"
40
42
  },
41
43
  "peerDependencies": {
42
- "@tiptap/core": "^2.7.0",
43
- "@tiptap/pm": "^2.7.0",
44
- "katex": "^0.16.4"
44
+ "katex": "^0.16.4",
45
+ "@tiptap/pm": "3.0.0-beta.10",
46
+ "@tiptap/core": "3.0.0-beta.10"
45
47
  },
46
48
  "scripts": {
47
- "clean": "rm -rf dist",
48
- "build": "npm run clean && rollup -c"
49
+ "build": "tsup",
50
+ "lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
49
51
  }
50
- }
52
+ }
@@ -1,29 +1,34 @@
1
1
  import { getChangedRanges } from '@tiptap/core'
2
- import {
3
- EditorState, Plugin, PluginKey, Transaction,
4
- } from '@tiptap/pm/state'
2
+ import type { EditorState, Transaction } from '@tiptap/pm/state'
3
+ import { Plugin, PluginKey } from '@tiptap/pm/state'
5
4
  import { Decoration, DecorationSet } from '@tiptap/pm/view'
6
5
  import katex from 'katex'
7
6
 
8
- import { MathematicsOptionsWithEditor } from './types.js'
7
+ import type { MathematicsOptionsWithEditor } from './types.js'
9
8
 
10
9
  type DecoSpec = {
11
- isEditable: boolean;
12
- isEditing: boolean;
13
- katexOptions: MathematicsOptionsWithEditor['katexOptions'];
14
- content: string;
15
- };
10
+ isEditable: boolean
11
+ isEditing: boolean
12
+ katexOptions: MathematicsOptionsWithEditor['katexOptions']
13
+ content: string
14
+ }
16
15
 
17
- type Deco = Omit<Decoration, 'spec'> & { spec: DecoSpec };
16
+ type Deco = Omit<Decoration, 'spec'> & { spec: DecoSpec }
18
17
 
19
18
  type PluginState =
20
- | { decorations: DecorationSet; isEditable: boolean }
21
- | { decorations: undefined; isEditable: undefined }
19
+ | { decorations: DecorationSet; isEditable: boolean }
20
+ | { decorations: undefined; isEditable: undefined }
22
21
 
23
22
  /**
24
23
  * Get the range of positions that have been affected by a transaction
25
24
  */
26
- function getAffectedRange(newState: EditorState, previousPluginState: PluginState, isEditable: boolean, tr: Transaction, state: EditorState) {
25
+ function getAffectedRange(
26
+ newState: EditorState,
27
+ previousPluginState: PluginState,
28
+ isEditable: boolean,
29
+ tr: Transaction,
30
+ state: EditorState,
31
+ ) {
27
32
  const docSize = newState.doc.nodeSize - 2
28
33
  let minFrom = 0
29
34
  let maxTo = docSize
@@ -52,10 +57,7 @@ function getAffectedRange(newState: EditorState, previousPluginState: PluginStat
52
57
  $from.depth === 0 ? 0 : $from.before(),
53
58
  $newFrom.depth === 0 ? 0 : $newFrom.before(),
54
59
  )
55
- maxTo = Math.max(
56
- $to.depth === 0 ? maxTo : $to.after(),
57
- $newTo.depth === 0 ? maxTo : $newTo.after(),
58
- )
60
+ maxTo = Math.max($to.depth === 0 ? maxTo : $to.after(), $newTo.depth === 0 ? maxTo : $newTo.after())
59
61
  }
60
62
 
61
63
  return {
@@ -65,9 +67,7 @@ function getAffectedRange(newState: EditorState, previousPluginState: PluginStat
65
67
  }
66
68
 
67
69
  export const MathematicsPlugin = (options: MathematicsOptionsWithEditor) => {
68
- const {
69
- regex, katexOptions = {}, editor, shouldRender,
70
- } = options
70
+ const { regex, katexOptions = {}, editor, shouldRender } = options
71
71
 
72
72
  return new Plugin<PluginState>({
73
73
  key: new PluginKey('mathematics'),
@@ -77,16 +77,12 @@ export const MathematicsPlugin = (options: MathematicsOptionsWithEditor) => {
77
77
  return { decorations: undefined, isEditable: undefined }
78
78
  },
79
79
  apply(tr, previousPluginState, state, newState) {
80
-
81
80
  if (!tr.docChanged && !tr.selectionSet && previousPluginState.decorations) {
82
81
  // Just reuse the existing decorations, since nothing should have changed
83
82
  return previousPluginState
84
83
  }
85
84
 
86
- const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(
87
- tr.mapping,
88
- tr.doc,
89
- )
85
+ const nextDecorationSet = (previousPluginState.decorations || DecorationSet.empty).map(tr.mapping, tr.doc)
90
86
  const { selection } = newState
91
87
  const isEditable = editor.isEditable
92
88
  const decorationsToAdd = [] as Deco[]
@@ -115,10 +111,11 @@ export const MathematicsPlugin = (options: MathematicsOptionsWithEditor) => {
115
111
  nextDecorationSet.find(
116
112
  from,
117
113
  to,
118
- (deco: DecoSpec) => isEditing === deco.isEditing
119
- && content === deco.content
120
- && isEditable === deco.isEditable
121
- && katexOptions === deco.katexOptions,
114
+ (deco: DecoSpec) =>
115
+ isEditing === deco.isEditing &&
116
+ content === deco.content &&
117
+ isEditable === deco.isEditable &&
118
+ katexOptions === deco.katexOptions,
122
119
  ).length
123
120
  ) {
124
121
  // Decoration exists in set, no need to add it again
@@ -1,8 +1,8 @@
1
1
  import { Extension } from '@tiptap/core'
2
- import { EditorState } from '@tiptap/pm/state'
2
+ import type { EditorState } from '@tiptap/pm/state'
3
3
 
4
4
  import { MathematicsPlugin } from './MathematicsPlugin.js'
5
- import { MathematicsOptions } from './types.js'
5
+ import type { MathematicsOptions } from './types.js'
6
6
 
7
7
  export const defaultShouldRender = (state: EditorState, pos: number) => {
8
8
  const $pos = state.doc.resolve(pos)
package/src/types.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { Editor } from '@tiptap/core'
2
- import { Node } from '@tiptap/pm/model'
3
- import { EditorState } from '@tiptap/pm/state'
4
- import { KatexOptions } from 'katex'
1
+ import type { Editor } from '@tiptap/core'
2
+ import type { Node } from '@tiptap/pm/model'
3
+ import type { EditorState } from '@tiptap/pm/state'
4
+ import type { KatexOptions } from 'katex'
5
5
 
6
6
  export type MathematicsOptions = {
7
- regex: RegExp,
8
- katexOptions?: KatexOptions,
9
- shouldRender: (state: EditorState, pos: number, node: Node) => boolean,
7
+ regex: RegExp
8
+ katexOptions?: KatexOptions
9
+ shouldRender: (state: EditorState, pos: number, node: Node) => boolean
10
10
  }
11
11
 
12
12
  export type MathematicsOptionsWithEditor = MathematicsOptions & { editor: Editor }
@@ -1,13 +0,0 @@
1
- import { Plugin } from '@tiptap/pm/state';
2
- import { DecorationSet } from '@tiptap/pm/view';
3
- import { MathematicsOptionsWithEditor } from './types.js';
4
- type PluginState = {
5
- decorations: DecorationSet;
6
- isEditable: boolean;
7
- } | {
8
- decorations: undefined;
9
- isEditable: undefined;
10
- };
11
- export declare const MathematicsPlugin: (options: MathematicsOptionsWithEditor) => Plugin<PluginState>;
12
- export {};
13
- //# sourceMappingURL=MathematicsPlugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MathematicsPlugin.d.ts","sourceRoot":"","sources":["../src/MathematicsPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EACQ,MAAM,EACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAc,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAG3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AAWzD,KAAK,WAAW,GACd;IAAE,WAAW,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,WAAW,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,SAAS,CAAA;CAAE,CAAA;AA8CnD,eAAO,MAAM,iBAAiB,YAAa,4BAA4B,wBA6ItE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,YAAY,CAAA;AAE1B,eAAe,WAAW,CAAA"}