@seorii/tiptap 0.4.6 → 0.4.7
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.
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { Fragment, Slice } from '@tiptap/pm/model';
|
|
3
|
+
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
4
|
+
export default Extension.create({
|
|
5
|
+
name: 'mathPaste',
|
|
6
|
+
addProseMirrorPlugins() {
|
|
7
|
+
return [
|
|
8
|
+
new Plugin({
|
|
9
|
+
key: new PluginKey('mathPaste'),
|
|
10
|
+
props: {
|
|
11
|
+
transformPasted: (slice, view) => {
|
|
12
|
+
const { schema } = view.state;
|
|
13
|
+
const mathInline = schema.nodes.math_inline;
|
|
14
|
+
const mathDisplay = schema.nodes.math_display;
|
|
15
|
+
if (!mathInline && !mathDisplay)
|
|
16
|
+
return slice;
|
|
17
|
+
let changed = false;
|
|
18
|
+
let blockChanged = false;
|
|
19
|
+
const transformFragment = (fragment, parent) => {
|
|
20
|
+
const nodes = [];
|
|
21
|
+
for (let index = 0; index < fragment.childCount; index++) {
|
|
22
|
+
const node = fragment.child(index);
|
|
23
|
+
if (parent?.type.spec.code ||
|
|
24
|
+
node.type.spec.code ||
|
|
25
|
+
node.type.name.startsWith('math_')) {
|
|
26
|
+
nodes.push(node);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (mathDisplay && node.isTextblock && node.textContent.trim() === '$$') {
|
|
30
|
+
const source = [];
|
|
31
|
+
let endIndex = -1;
|
|
32
|
+
for (let offset = index + 1; offset < fragment.childCount; offset++) {
|
|
33
|
+
const candidate = fragment.child(offset);
|
|
34
|
+
if (candidate.type.spec.code ||
|
|
35
|
+
candidate.type.name.startsWith('math_') ||
|
|
36
|
+
!candidate.isTextblock) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
const text = candidate.textContent;
|
|
40
|
+
if (text.trim() === '$$') {
|
|
41
|
+
endIndex = offset;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
source.push(text);
|
|
45
|
+
}
|
|
46
|
+
const text = source.join('\n').trim();
|
|
47
|
+
if (endIndex > -1 && text.length) {
|
|
48
|
+
nodes.push(mathDisplay.create(null, schema.text(text)));
|
|
49
|
+
index = endIndex;
|
|
50
|
+
changed = true;
|
|
51
|
+
blockChanged = true;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (mathDisplay && node.isTextblock) {
|
|
56
|
+
const match = /^\s*\$\$([\s\S]*?)\$\$\s*$/.exec(node.textContent);
|
|
57
|
+
const text = match?.[1]?.trim();
|
|
58
|
+
if (text) {
|
|
59
|
+
nodes.push(mathDisplay.create(null, schema.text(text)));
|
|
60
|
+
changed = true;
|
|
61
|
+
blockChanged = true;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (node.isText) {
|
|
66
|
+
if (!mathInline || node.marks.some((mark) => mark.type.spec.code)) {
|
|
67
|
+
nodes.push(node);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const text = node.text || '';
|
|
71
|
+
const inlineNodes = [];
|
|
72
|
+
let cursor = 0;
|
|
73
|
+
let searchFrom = 0;
|
|
74
|
+
while (searchFrom < text.length) {
|
|
75
|
+
const open = text.indexOf('$', searchFrom);
|
|
76
|
+
if (open === -1)
|
|
77
|
+
break;
|
|
78
|
+
const beforeOpen = text[open - 1];
|
|
79
|
+
const afterOpen = text[open + 1];
|
|
80
|
+
if (beforeOpen === '\\' ||
|
|
81
|
+
beforeOpen === '$' ||
|
|
82
|
+
afterOpen === '$' ||
|
|
83
|
+
!afterOpen ||
|
|
84
|
+
/\s/.test(afterOpen)) {
|
|
85
|
+
searchFrom = open + 1;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
let close = open + 1;
|
|
89
|
+
while (close < text.length) {
|
|
90
|
+
close = text.indexOf('$', close);
|
|
91
|
+
if (close === -1)
|
|
92
|
+
break;
|
|
93
|
+
const beforeClose = text[close - 1];
|
|
94
|
+
const afterClose = text[close + 1];
|
|
95
|
+
if (beforeClose === '\\' ||
|
|
96
|
+
beforeClose === '$' ||
|
|
97
|
+
afterClose === '$' ||
|
|
98
|
+
/\s/.test(beforeClose)) {
|
|
99
|
+
close++;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
if (close === -1)
|
|
105
|
+
break;
|
|
106
|
+
const source = text.slice(open + 1, close);
|
|
107
|
+
if (!source.trim()) {
|
|
108
|
+
searchFrom = close + 1;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (open > cursor)
|
|
112
|
+
inlineNodes.push(schema.text(text.slice(cursor, open), node.marks));
|
|
113
|
+
inlineNodes.push(mathInline.create(null, schema.text(source), node.marks));
|
|
114
|
+
cursor = close + 1;
|
|
115
|
+
searchFrom = cursor;
|
|
116
|
+
}
|
|
117
|
+
if (!inlineNodes.length) {
|
|
118
|
+
nodes.push(node);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (cursor < text.length)
|
|
122
|
+
inlineNodes.push(schema.text(text.slice(cursor), node.marks));
|
|
123
|
+
nodes.push(...inlineNodes);
|
|
124
|
+
changed = true;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!node.content.size) {
|
|
128
|
+
nodes.push(node);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const content = transformFragment(node.content, node);
|
|
132
|
+
nodes.push(content.eq(node.content) ? node : node.copy(content));
|
|
133
|
+
}
|
|
134
|
+
return Fragment.fromArray(nodes);
|
|
135
|
+
};
|
|
136
|
+
const content = transformFragment(slice.content, null);
|
|
137
|
+
if (!changed)
|
|
138
|
+
return slice;
|
|
139
|
+
return blockChanged
|
|
140
|
+
? new Slice(content, 0, 0)
|
|
141
|
+
: new Slice(content, slice.openStart, slice.openEnd);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
});
|
package/dist/tiptap/tiptap.js
CHANGED
|
@@ -24,6 +24,7 @@ import Embed from '../plugin/embed';
|
|
|
24
24
|
import UploadSkeleton from '../plugin/upload/skeleton';
|
|
25
25
|
// @ts-ignore
|
|
26
26
|
import { MathInline, MathBlock } from '@seorii/prosemirror-math/tiptap';
|
|
27
|
+
import MathPaste from '../plugin/mathPaste';
|
|
27
28
|
import Youtube from '../plugin/youtube';
|
|
28
29
|
import Placeholder from '@tiptap/extension-placeholder';
|
|
29
30
|
import columns from '../plugin/columns';
|
|
@@ -240,6 +241,7 @@ const extensions = (placeholder, plugins, crossorigin, codeBlockLanguageLabels)
|
|
|
240
241
|
orderedlist,
|
|
241
242
|
MathInline,
|
|
242
243
|
MathBlock,
|
|
244
|
+
MathPaste,
|
|
243
245
|
...columns,
|
|
244
246
|
table,
|
|
245
247
|
tableHeader,
|