@kerebron/extension-odt 0.3.0 → 0.3.1
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/README.md +8 -2
- package/esm/editor/src/CoreEditor.d.ts.map +1 -1
- package/esm/editor/src/CoreEditor.js +3 -1
- package/esm/editor/src/Extension.d.ts.map +1 -1
- package/esm/editor/src/ExtensionManager.d.ts +1 -1
- package/esm/editor/src/ExtensionManager.d.ts.map +1 -1
- package/esm/editor/src/nodeToTreeString.d.ts +8 -2
- package/esm/editor/src/nodeToTreeString.d.ts.map +1 -1
- package/esm/editor/src/nodeToTreeString.js +27 -11
- package/esm/editor/src/utilities/SmartOutput.d.ts +39 -0
- package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -0
- package/esm/editor/src/utilities/SmartOutput.js +213 -0
- package/esm/extension-odt/src/ExtensionOdt.d.ts +0 -1
- package/esm/extension-odt/src/ExtensionOdt.d.ts.map +1 -1
- package/esm/extension-odt/src/ExtensionOdt.js +25 -28
- package/esm/extension-odt/src/OdtParser.d.ts +41 -63
- package/esm/extension-odt/src/OdtParser.d.ts.map +1 -1
- package/esm/extension-odt/src/OdtParser.js +172 -474
- package/esm/extension-odt/src/lists.d.ts +23 -0
- package/esm/extension-odt/src/lists.d.ts.map +1 -0
- package/esm/extension-odt/src/lists.js +55 -0
- package/esm/extension-odt/src/node_handlers/basic_node_handlers.d.ts +4 -0
- package/esm/extension-odt/src/node_handlers/basic_node_handlers.d.ts.map +1 -0
- package/esm/extension-odt/src/node_handlers/basic_node_handlers.js +138 -0
- package/esm/extension-odt/src/node_handlers/list_node_handlers.d.ts +3 -0
- package/esm/extension-odt/src/node_handlers/list_node_handlers.d.ts.map +1 -0
- package/esm/extension-odt/src/node_handlers/list_node_handlers.js +91 -0
- package/esm/extension-odt/src/node_handlers/table_node_handlers.d.ts +3 -0
- package/esm/extension-odt/src/node_handlers/table_node_handlers.d.ts.map +1 -0
- package/esm/extension-odt/src/node_handlers/table_node_handlers.js +24 -0
- package/esm/extension-odt/src/postprocess/convertCodeParagraphsToCodeBlocks.d.ts.map +1 -1
- package/esm/extension-odt/src/postprocess/convertCodeParagraphsToCodeBlocks.js +3 -1
- package/package.json +1 -1
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { Mark, } from 'prosemirror-model';
|
|
2
|
+
import { getBasicNodesHandlers, getInlineNodesHandlers, } from './node_handlers/basic_node_handlers.js';
|
|
3
|
+
import { getListNodesHandlers } from './node_handlers/list_node_handlers.js';
|
|
4
|
+
import { getTableNodesHandlers } from './node_handlers/table_node_handlers.js';
|
|
5
|
+
import { ListTracker } from './lists.js';
|
|
2
6
|
const COURIER_FONTS = ['Courier New', 'Courier', 'Roboto Mono'];
|
|
3
|
-
function
|
|
4
|
-
if (spec.getAttrs)
|
|
5
|
-
return spec.getAttrs(token, style);
|
|
6
|
-
// For backwards compatibility when `attrs` is a Function
|
|
7
|
-
else if (spec.attrs instanceof Function)
|
|
8
|
-
return spec.attrs(token);
|
|
9
|
-
else
|
|
10
|
-
return spec.attrs;
|
|
11
|
-
}
|
|
12
|
-
function resolveStyle(stylesTree, automaticStyles, name) {
|
|
7
|
+
export function resolveStyle(stylesTree, automaticStyles, name) {
|
|
13
8
|
let style;
|
|
14
9
|
if (!style) {
|
|
15
10
|
style = stylesTree.styles['list-style'].find((item) => item['@name'] === name);
|
|
@@ -21,7 +16,9 @@ function resolveStyle(stylesTree, automaticStyles, name) {
|
|
|
21
16
|
style = automaticStyles.style.find((item) => item['@name'] === name);
|
|
22
17
|
}
|
|
23
18
|
if (!style) {
|
|
24
|
-
style = {
|
|
19
|
+
style = {
|
|
20
|
+
'@name': name,
|
|
21
|
+
};
|
|
25
22
|
}
|
|
26
23
|
style['styles'] = [name];
|
|
27
24
|
if (style['@parent-style-name']) {
|
|
@@ -42,20 +39,47 @@ function resolveStyle(stylesTree, automaticStyles, name) {
|
|
|
42
39
|
}
|
|
43
40
|
return style;
|
|
44
41
|
}
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
export function tagEnum(item) {
|
|
43
|
+
if ('string' === typeof item) {
|
|
44
|
+
return {
|
|
45
|
+
tag: item, // '$text',
|
|
46
|
+
value: item,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if ('object' === typeof item) {
|
|
50
|
+
const entries = Object.entries(item);
|
|
51
|
+
if (entries.length === 1) {
|
|
52
|
+
return {
|
|
53
|
+
tag: entries[0][0],
|
|
54
|
+
value: entries[0][1],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new Error('Incorrect enum: ' + JSON.stringify(item));
|
|
59
|
+
}
|
|
60
|
+
export function iterateChildren(nodes, callback) {
|
|
61
|
+
for (const child of nodes) {
|
|
62
|
+
if ('Unknown' === child) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const item = tagEnum(child);
|
|
66
|
+
callback(item);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function iterateEnum($value) {
|
|
70
|
+
if (!$value) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
return $value.map(tagEnum);
|
|
74
|
+
}
|
|
75
|
+
export class OdtStashContext {
|
|
76
|
+
constructor(schema, handlers, stylesTree, automaticStyles) {
|
|
47
77
|
Object.defineProperty(this, "schema", {
|
|
48
78
|
enumerable: true,
|
|
49
79
|
configurable: true,
|
|
50
80
|
writable: true,
|
|
51
81
|
value: schema
|
|
52
82
|
});
|
|
53
|
-
Object.defineProperty(this, "tokens", {
|
|
54
|
-
enumerable: true,
|
|
55
|
-
configurable: true,
|
|
56
|
-
writable: true,
|
|
57
|
-
value: tokens
|
|
58
|
-
});
|
|
59
83
|
Object.defineProperty(this, "stylesTree", {
|
|
60
84
|
enumerable: true,
|
|
61
85
|
configurable: true,
|
|
@@ -68,236 +92,121 @@ class OdtParseState {
|
|
|
68
92
|
writable: true,
|
|
69
93
|
value: automaticStyles
|
|
70
94
|
});
|
|
71
|
-
Object.defineProperty(this, "
|
|
95
|
+
Object.defineProperty(this, "ctxStash", {
|
|
72
96
|
enumerable: true,
|
|
73
97
|
configurable: true,
|
|
74
98
|
writable: true,
|
|
75
|
-
value:
|
|
99
|
+
value: []
|
|
76
100
|
});
|
|
77
|
-
Object.defineProperty(this, "
|
|
101
|
+
Object.defineProperty(this, "currentCtx", {
|
|
78
102
|
enumerable: true,
|
|
79
103
|
configurable: true,
|
|
80
104
|
writable: true,
|
|
81
|
-
value:
|
|
105
|
+
value: void 0
|
|
82
106
|
});
|
|
83
|
-
Object.defineProperty(this, "
|
|
107
|
+
Object.defineProperty(this, "listTracker", {
|
|
84
108
|
enumerable: true,
|
|
85
109
|
configurable: true,
|
|
86
110
|
writable: true,
|
|
87
|
-
value: new
|
|
111
|
+
value: new ListTracker()
|
|
88
112
|
});
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
113
|
+
this.currentCtx = {
|
|
114
|
+
handlers,
|
|
115
|
+
content: [],
|
|
116
|
+
marks: [],
|
|
117
|
+
meta: {},
|
|
118
|
+
};
|
|
119
|
+
this.stash();
|
|
94
120
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
stash() {
|
|
122
|
+
this.ctxStash.push(this.currentCtx);
|
|
123
|
+
const funcs = {};
|
|
124
|
+
const handlers = { ...this.currentCtx.handlers };
|
|
125
|
+
const content = this.currentCtx.content;
|
|
126
|
+
const marks = this.currentCtx.marks;
|
|
127
|
+
this.currentCtx = {
|
|
128
|
+
...structuredClone({
|
|
129
|
+
...this.currentCtx,
|
|
130
|
+
content: undefined,
|
|
131
|
+
marks: undefined,
|
|
132
|
+
handlers: undefined,
|
|
133
|
+
}),
|
|
134
|
+
...funcs,
|
|
135
|
+
content,
|
|
136
|
+
marks,
|
|
137
|
+
handlers,
|
|
138
|
+
};
|
|
139
|
+
return this.ctxStash.length - 1;
|
|
98
140
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return;
|
|
104
|
-
let top = this.top(), nodes = top.content, last = nodes[nodes.length - 1];
|
|
105
|
-
let marks = top.marks;
|
|
106
|
-
for (const textMark of this.textMarks) {
|
|
107
|
-
const markType = this.schema.marks[textMark.markName];
|
|
108
|
-
const mark = markType.create(textMark.markAttributes || {});
|
|
109
|
-
marks = mark.addToSet(marks);
|
|
141
|
+
unstash() {
|
|
142
|
+
const ctx = this.ctxStash.pop();
|
|
143
|
+
if (!ctx) {
|
|
144
|
+
throw new Error('Unstash failed');
|
|
110
145
|
}
|
|
111
|
-
|
|
112
|
-
const markType = this.schema.marks[textMark.markName];
|
|
113
|
-
const mark = markType.create(textMark.markAttributes || {});
|
|
114
|
-
marks = mark.addToSet(marks);
|
|
115
|
-
}
|
|
116
|
-
this.nextTextMarks.clear();
|
|
117
|
-
let node = this.schema.text(text, marks), merged;
|
|
118
|
-
nodes.push(node);
|
|
119
|
-
}
|
|
120
|
-
// Adds the given mark to the set of active marks.
|
|
121
|
-
openMark(mark) {
|
|
122
|
-
let top = this.top();
|
|
123
|
-
top.marks = mark.addToSet(top.marks);
|
|
124
|
-
return mark.type;
|
|
146
|
+
this.currentCtx = ctx;
|
|
125
147
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
top.marks = mark.removeFromSet(top.marks);
|
|
148
|
+
openNode() {
|
|
149
|
+
this.stash();
|
|
150
|
+
this.current.content = [];
|
|
130
151
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
|
|
152
|
+
closeNode(type, attrs = {}, marks = Mark.none) {
|
|
153
|
+
const node = this.createNode(type, attrs, marks);
|
|
154
|
+
this.unstash();
|
|
155
|
+
if (node) {
|
|
156
|
+
this.current.content.push(node);
|
|
136
157
|
}
|
|
137
|
-
let node = type.createAndFill(attrs, content, marks);
|
|
138
|
-
if (!node)
|
|
139
|
-
return null;
|
|
140
|
-
this.push(node);
|
|
141
158
|
return node;
|
|
142
159
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
type: type
|
|
147
|
-
attrs: attrs,
|
|
148
|
-
content: [],
|
|
149
|
-
marks: Mark.none,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
// Close and return the node that is currently on top of the stack.
|
|
153
|
-
closeNode(marks = Mark.none) {
|
|
154
|
-
let info = this.stack.pop();
|
|
155
|
-
return this.addNode(info.type, info.attrs, info.content, marks);
|
|
156
|
-
}
|
|
157
|
-
handleElement(nodeType, element) {
|
|
158
|
-
const spec = this.tokens[nodeType];
|
|
159
|
-
if (!spec) {
|
|
160
|
-
console.warn('No spec for:', nodeType, element, this.stack.map((item) => item.type.name));
|
|
161
|
-
return;
|
|
160
|
+
createNode(type, attrs = {}, marks = Mark.none) {
|
|
161
|
+
const nodeType = this.schema.nodes[type];
|
|
162
|
+
if (!nodeType) {
|
|
163
|
+
throw new Error('Invalid node type: ' + type);
|
|
162
164
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
const node = nodeType.createAndFill(attrs, this.current.content, marks);
|
|
166
|
+
if (!node) {
|
|
167
|
+
throw new Error('Error creating node: ' + type);
|
|
166
168
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
return node;
|
|
170
|
+
}
|
|
171
|
+
createText(text) {
|
|
172
|
+
if (!text)
|
|
173
|
+
return;
|
|
174
|
+
return this.schema.text(text, this.current.marks);
|
|
175
|
+
}
|
|
176
|
+
styleToMarks(style) {
|
|
173
177
|
const marks = [];
|
|
178
|
+
const textProperties = style && style['text-properties'] || {};
|
|
174
179
|
if (COURIER_FONTS.indexOf(textProperties['@font-name'] || '') > -1) {
|
|
175
|
-
this.textMarks.add({
|
|
176
|
-
markName: 'code',
|
|
177
|
-
markAttributes: {},
|
|
178
|
-
});
|
|
179
180
|
const markType = this.schema.mark('code');
|
|
180
181
|
marks.push(markType);
|
|
181
182
|
}
|
|
182
|
-
// if (style.textProperties?.fontStyle === 'italic' && style.textProperties?.fontWeight === 'bold') {
|
|
183
|
-
// const block = this.chunks.createNode('BI');
|
|
184
|
-
// this.chunks.append(currentTagNode, block);
|
|
185
|
-
// currentTagNode = block;
|
|
186
|
-
// } else
|
|
187
183
|
if (textProperties['@font-style'] === 'italic') {
|
|
188
|
-
const markType = this.schema.
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
else if (textProperties['@font-weight'] === 'bold') {
|
|
192
|
-
const markType = this.schema.marks['strong'];
|
|
193
|
-
markToClose.push(this.openMark(markType.create(attrs(spec, element, style))));
|
|
194
|
-
}
|
|
195
|
-
if (spec.block) {
|
|
196
|
-
let block = spec.block;
|
|
197
|
-
if ('string' !== typeof block) {
|
|
198
|
-
block = block(element, style)[0];
|
|
199
|
-
}
|
|
200
|
-
let nodeType = this.schema.nodeType(block);
|
|
201
|
-
this.openNode(nodeType, attrs(spec, element, style));
|
|
202
|
-
if (children) {
|
|
203
|
-
iterateChildren(children, (nodeType, node) => {
|
|
204
|
-
this.handleElement(nodeType, node);
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
// this.addText(withoutTrailingNewline(tok.content));
|
|
208
|
-
this.closeNode(marks);
|
|
209
|
-
}
|
|
210
|
-
else if (spec.node) {
|
|
211
|
-
}
|
|
212
|
-
else if (spec.mark) {
|
|
213
|
-
const markType = this.schema.marks[spec.mark];
|
|
214
|
-
this.openMark(markType.create(attrs(spec, element, style)));
|
|
215
|
-
if (children) {
|
|
216
|
-
iterateChildren(children, (nodeType, node) => {
|
|
217
|
-
this.handleElement(nodeType, node);
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
this.closeMark(markType);
|
|
221
|
-
}
|
|
222
|
-
else if (spec.text) {
|
|
223
|
-
this.addText(spec.text(element));
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
if (children) {
|
|
227
|
-
iterateChildren(children, (nodeType, node) => {
|
|
228
|
-
this.handleElement(nodeType, node);
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
while (markToClose.length > 0) {
|
|
233
|
-
const markType = markToClose.pop();
|
|
234
|
-
this.closeMark(markType);
|
|
235
|
-
}
|
|
236
|
-
if (COURIER_FONTS.indexOf(textProperties['@font-name'] || '') > -1) {
|
|
237
|
-
this.textMarks.forEach((x) => x.markName === 'code' ? this.textMarks.delete(x) : x);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
function iterateChildren(nodes, callback) {
|
|
242
|
-
for (const child of nodes) {
|
|
243
|
-
if ('Unknown' === child) {
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
let key = '';
|
|
247
|
-
let value = null;
|
|
248
|
-
if (typeof child === 'string') {
|
|
249
|
-
key = '$text';
|
|
250
|
-
value = child;
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
const keys = Object.keys(child).filter((key) => key !== 'annotation');
|
|
254
|
-
key = keys[0];
|
|
255
|
-
value = child[key];
|
|
184
|
+
const markType = this.schema.mark('em');
|
|
185
|
+
marks.push(markType);
|
|
256
186
|
}
|
|
257
|
-
if (
|
|
258
|
-
|
|
187
|
+
if (textProperties['@font-weight'] === 'bold') {
|
|
188
|
+
const markType = this.schema.mark('strong');
|
|
189
|
+
marks.push(markType);
|
|
259
190
|
}
|
|
260
|
-
|
|
191
|
+
return marks;
|
|
261
192
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return [];
|
|
266
|
-
}
|
|
267
|
-
return $value.map((item) => {
|
|
268
|
-
if ('string' === typeof item) {
|
|
269
|
-
return {
|
|
270
|
-
[item]: true,
|
|
271
|
-
};
|
|
193
|
+
handle(nodeType, value) {
|
|
194
|
+
if (!this.current.handlers[nodeType]) {
|
|
195
|
+
throw new Error('No handler for node: ' + nodeType);
|
|
272
196
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
class ListNumbering {
|
|
277
|
-
constructor() {
|
|
278
|
-
Object.defineProperty(this, "levels", {
|
|
279
|
-
enumerable: true,
|
|
280
|
-
configurable: true,
|
|
281
|
-
writable: true,
|
|
282
|
-
value: {}
|
|
283
|
-
});
|
|
284
|
-
Object.defineProperty(this, "levelNodes", {
|
|
285
|
-
enumerable: true,
|
|
286
|
-
configurable: true,
|
|
287
|
-
writable: true,
|
|
288
|
-
value: {}
|
|
289
|
-
});
|
|
290
|
-
for (let i = 0; i < 20; i++) {
|
|
291
|
-
this.levels[i] = 1;
|
|
197
|
+
if ('function' !== typeof this.current.handlers[nodeType]) {
|
|
198
|
+
throw new Error('Invalid handler for node: ' + nodeType);
|
|
292
199
|
}
|
|
200
|
+
this.current.handlers[nodeType](this, value);
|
|
293
201
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
this.
|
|
297
|
-
|
|
202
|
+
getElementStyle(element) {
|
|
203
|
+
const style = ('object' === typeof element && element['@style-name'])
|
|
204
|
+
? resolveStyle(this.stylesTree, this.automaticStyles, element['@style-name'])
|
|
205
|
+
: {};
|
|
206
|
+
return style;
|
|
298
207
|
}
|
|
299
|
-
|
|
300
|
-
this.
|
|
208
|
+
get current() {
|
|
209
|
+
return this.currentCtx;
|
|
301
210
|
}
|
|
302
211
|
}
|
|
303
212
|
export class OdtParser {
|
|
@@ -314,278 +223,67 @@ export class OdtParser {
|
|
|
314
223
|
writable: true,
|
|
315
224
|
value: config
|
|
316
225
|
});
|
|
317
|
-
Object.defineProperty(this, "listStack", {
|
|
318
|
-
enumerable: true,
|
|
319
|
-
configurable: true,
|
|
320
|
-
writable: true,
|
|
321
|
-
value: []
|
|
322
|
-
});
|
|
323
|
-
Object.defineProperty(this, "listNumberings", {
|
|
324
|
-
enumerable: true,
|
|
325
|
-
configurable: true,
|
|
326
|
-
writable: true,
|
|
327
|
-
value: new Map()
|
|
328
|
-
});
|
|
329
|
-
Object.defineProperty(this, "lastNumbering", {
|
|
330
|
-
enumerable: true,
|
|
331
|
-
configurable: true,
|
|
332
|
-
writable: true,
|
|
333
|
-
value: void 0
|
|
334
|
-
});
|
|
335
|
-
Object.defineProperty(this, "preserveMinLevel", {
|
|
336
|
-
enumerable: true,
|
|
337
|
-
configurable: true,
|
|
338
|
-
writable: true,
|
|
339
|
-
value: 999
|
|
340
|
-
});
|
|
341
|
-
// this.tokenHandlers = tokenHandlers(schema, tokens);
|
|
342
226
|
}
|
|
343
227
|
parse(files) {
|
|
344
228
|
const contentTree = files.contentTree;
|
|
345
229
|
const stylesTree = files.stylesTree;
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
'p': {
|
|
352
|
-
block: (odtElement, style) => {
|
|
353
|
-
if (style.styles.find((item) => item.startsWith('Heading_20_'))) {
|
|
354
|
-
return ['heading'];
|
|
355
|
-
}
|
|
356
|
-
return ['paragraph'];
|
|
357
|
-
},
|
|
358
|
-
getAttrs: (odtElement, style) => {
|
|
359
|
-
const heading = style.styles.find((item) => item.startsWith('Heading_20_'));
|
|
360
|
-
if (heading) {
|
|
361
|
-
return {
|
|
362
|
-
level: parseInt(heading.substring('Heading_20_'.length)),
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
children: (odtElement) => iterateEnum(odtElement.$value),
|
|
367
|
-
},
|
|
368
|
-
'span': {
|
|
369
|
-
children: (odtElement) => iterateEnum(odtElement.$value),
|
|
370
|
-
},
|
|
371
|
-
'list': {
|
|
372
|
-
custom: (state, odtElement) => {
|
|
373
|
-
const list = {
|
|
374
|
-
level: this.listStack.length + 1,
|
|
375
|
-
odtElement,
|
|
376
|
-
};
|
|
377
|
-
this.listStack.push(list);
|
|
378
|
-
let style = {};
|
|
379
|
-
let listId = null;
|
|
380
|
-
for (let i = this.listStack.length - 1; i >= 0; i--) {
|
|
381
|
-
const element = this.listStack[i].odtElement;
|
|
382
|
-
if (!listId) {
|
|
383
|
-
if (element['@id']) {
|
|
384
|
-
listId = element['@id'];
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
if (!style['@style-name']) {
|
|
388
|
-
style = ('object' === typeof element && element['@style-name'])
|
|
389
|
-
? resolveStyle(stylesTree, automaticStyles, element['@style-name'])
|
|
390
|
-
: {};
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
let nodeTypeName = 'bullet_list';
|
|
394
|
-
const attrs = {};
|
|
395
|
-
if (style) {
|
|
396
|
-
const numLevelStyle = style['list-level-style-number'].find((levelStyle) => parseInt(levelStyle['@level']) === list.level);
|
|
397
|
-
if (numLevelStyle) {
|
|
398
|
-
attrs['type'] = numLevelStyle['@num-format'] || '1';
|
|
399
|
-
nodeTypeName = 'ordered_list';
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
let listNumbering = null;
|
|
403
|
-
if (listId && this.listNumberings.has(listId)) {
|
|
404
|
-
listNumbering = this.listNumberings.get(listId);
|
|
405
|
-
}
|
|
406
|
-
let isContinue = false;
|
|
407
|
-
if (odtElement['@continue-list'] &&
|
|
408
|
-
this.listNumberings.has(odtElement['@continue-list'])) {
|
|
409
|
-
listNumbering = this.listNumberings.get(odtElement['@continue-list']);
|
|
410
|
-
isContinue = true;
|
|
411
|
-
}
|
|
412
|
-
if (odtElement['@continue-numbering']) {
|
|
413
|
-
listNumbering = this.lastNumbering;
|
|
414
|
-
isContinue = true;
|
|
415
|
-
}
|
|
416
|
-
if (!listNumbering) {
|
|
417
|
-
listNumbering = new ListNumbering();
|
|
418
|
-
}
|
|
419
|
-
if (isContinue) {
|
|
420
|
-
this.preserveMinLevel = 999;
|
|
421
|
-
}
|
|
422
|
-
if (listId) {
|
|
423
|
-
this.listNumberings.set(listId, listNumbering);
|
|
424
|
-
}
|
|
425
|
-
this.lastNumbering = listNumbering;
|
|
426
|
-
if (this.preserveMinLevel <= list.level) {
|
|
427
|
-
listNumbering.clearAbove(list.level - 1);
|
|
428
|
-
}
|
|
429
|
-
if (nodeTypeName === 'ordered_list') {
|
|
430
|
-
attrs['start'] = listNumbering.levels[list.level] || 1;
|
|
431
|
-
}
|
|
432
|
-
let nodeType = this.schema.nodeType(nodeTypeName);
|
|
433
|
-
state.openNode(nodeType, attrs);
|
|
434
|
-
const children = odtElement['list-item'].map((item) => ({
|
|
435
|
-
'list-item': item,
|
|
436
|
-
}));
|
|
437
|
-
if (children) {
|
|
438
|
-
iterateChildren(children, (nodeType, node) => {
|
|
439
|
-
state.handleElement(nodeType, node);
|
|
440
|
-
});
|
|
441
|
-
listNumbering.levels[list.level] += children.length;
|
|
442
|
-
}
|
|
443
|
-
state.closeNode();
|
|
444
|
-
if (this.preserveMinLevel >= list.level) {
|
|
445
|
-
this.preserveMinLevel = list.level;
|
|
446
|
-
}
|
|
447
|
-
this.listStack.pop();
|
|
448
|
-
},
|
|
449
|
-
},
|
|
450
|
-
'list-item': {
|
|
451
|
-
block: 'list_item',
|
|
452
|
-
children: (odtElement) => iterateEnum(odtElement.$value),
|
|
453
|
-
},
|
|
454
|
-
'table': {
|
|
455
|
-
block: 'table',
|
|
456
|
-
children: (odtElement) => odtElement['table-row'].map((item) => ({ 'table-row': item })),
|
|
457
|
-
},
|
|
458
|
-
'table-row': {
|
|
459
|
-
block: 'table_row',
|
|
460
|
-
children: (odtElement) => odtElement['table-cell'].map((item) => ({ 'table-cell': item })),
|
|
461
|
-
},
|
|
462
|
-
'table-cell': {
|
|
463
|
-
block: 'table_cell',
|
|
464
|
-
children: (odtElement) => iterateEnum(odtElement.$value),
|
|
465
|
-
},
|
|
466
|
-
'a': {
|
|
467
|
-
mark: 'link',
|
|
468
|
-
getAttrs: (tok) => {
|
|
469
|
-
let href = tok['@href'];
|
|
470
|
-
if (this.config.linkFromRewriter) {
|
|
471
|
-
href = this.config.linkFromRewriter(href);
|
|
472
|
-
}
|
|
473
|
-
return {
|
|
474
|
-
href,
|
|
475
|
-
// title: tok.attrGet('title') || null,
|
|
476
|
-
};
|
|
477
|
-
},
|
|
478
|
-
children: (odtElement) => iterateEnum(odtElement.$value),
|
|
479
|
-
},
|
|
480
|
-
'$value': {
|
|
481
|
-
children: (odtElement) => iterateEnum(odtElement),
|
|
482
|
-
},
|
|
483
|
-
'$text': {
|
|
484
|
-
// TODO: fix trimming: https://github.com/tafia/quick-xml/issues/285
|
|
485
|
-
text: (odtElement) => String(odtElement || ''),
|
|
486
|
-
},
|
|
487
|
-
's': {
|
|
488
|
-
text: (odtElement) => {
|
|
489
|
-
const chars = odtElement['@c'] || 1;
|
|
490
|
-
return ' '.substring(0, chars);
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
'tab': {
|
|
494
|
-
text: (odtElement) => '\t',
|
|
495
|
-
},
|
|
496
|
-
'line-break': {
|
|
497
|
-
block: 'br',
|
|
498
|
-
},
|
|
499
|
-
'soft-page-break': {
|
|
500
|
-
block: 'br',
|
|
501
|
-
},
|
|
502
|
-
'table-of-content': {
|
|
503
|
-
block: 'paragraph',
|
|
504
|
-
children: (odtElement) => odtElement['index-body']['p'] || [],
|
|
505
|
-
},
|
|
230
|
+
const handlers = {
|
|
231
|
+
...getInlineNodesHandlers(),
|
|
232
|
+
...getBasicNodesHandlers(),
|
|
233
|
+
...getListNodesHandlers(),
|
|
234
|
+
...getTableNodesHandlers(),
|
|
506
235
|
'change-start': {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
236
|
+
// custom(state) {
|
|
237
|
+
// state.textMarks.add({
|
|
238
|
+
// markName: 'change',
|
|
239
|
+
// markAttributes: {},
|
|
240
|
+
// });
|
|
241
|
+
// },
|
|
513
242
|
},
|
|
514
243
|
'change-end': {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
custom: (state, odtElement) => {
|
|
521
|
-
if (odtElement.object && odtElement.object['@href']) { // TODO MathML
|
|
522
|
-
// const fileName= drawFrame.object.href.replace(/\s/g, '_').replace(/^\.\//, '') + '.xml';
|
|
523
|
-
// try {
|
|
524
|
-
// const mathMl = this.xmlMap[fileName];
|
|
525
|
-
// if (mathMl && mathMl.indexOf('<math ') > -1) {
|
|
526
|
-
// const node = this.chunks.createNode('MATHML');
|
|
527
|
-
// const latex = MathMLToLaTeX.convert(mathMl);
|
|
528
|
-
// this.chunks.appendText(node, latex);
|
|
529
|
-
// this.chunks.append(currentTagNode, node);
|
|
530
|
-
// }
|
|
531
|
-
// } catch (err) {
|
|
532
|
-
// console.warn(err);
|
|
533
|
-
// }
|
|
534
|
-
}
|
|
535
|
-
if (odtElement.image && odtElement.image['@href']) { // TODO links rewrite
|
|
536
|
-
const nodeType = this.schema.nodeType('image');
|
|
537
|
-
const alt = odtElement.description?.value || '';
|
|
538
|
-
state.addNode(nodeType, {
|
|
539
|
-
src: odtElement.image['@href'],
|
|
540
|
-
alt,
|
|
541
|
-
}, []);
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
},
|
|
545
|
-
'rect': {
|
|
546
|
-
ignore: true,
|
|
547
|
-
},
|
|
548
|
-
'bookmark': {
|
|
549
|
-
custom(state, element) {
|
|
550
|
-
state.nextTextMarks.add({
|
|
551
|
-
markName: 'bookmark',
|
|
552
|
-
markAttributes: {
|
|
553
|
-
id: element['@name'],
|
|
554
|
-
},
|
|
555
|
-
});
|
|
556
|
-
},
|
|
244
|
+
// custom(state) {
|
|
245
|
+
// state.textMarks.forEach((x) =>
|
|
246
|
+
// x.markName === 'change' ? state.textMarks.delete(x) : x
|
|
247
|
+
// );
|
|
248
|
+
// },
|
|
557
249
|
},
|
|
558
|
-
'
|
|
559
|
-
custom(state,
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
250
|
+
'frame': (ctx, odtElement) => {
|
|
251
|
+
// custom: (state, odtElement) => {
|
|
252
|
+
if (odtElement.object && odtElement.object['@href']) { // TODO MathML
|
|
253
|
+
// const fileName= drawFrame.object.href.replace(/\s/g, '_').replace(/^\.\//, '') + '.xml';
|
|
254
|
+
// try {
|
|
255
|
+
// const mathMl = this.xmlMap[fileName];
|
|
256
|
+
// if (mathMl && mathMl.indexOf('<math ') > -1) {
|
|
257
|
+
// const node = this.chunks.createNode('MATHML');
|
|
258
|
+
// const latex = MathMLToLaTeX.convert(mathMl);
|
|
259
|
+
// this.chunks.appendText(node, latex);
|
|
260
|
+
// this.chunks.append(currentTagNode, node);
|
|
261
|
+
// }
|
|
262
|
+
// } catch (err) {
|
|
263
|
+
// console.warn(err);
|
|
264
|
+
// }
|
|
265
|
+
}
|
|
266
|
+
if (odtElement.image && odtElement.image['@href']) { // TODO links rewrite
|
|
267
|
+
// const nodeType = this.schema.nodeType('image');
|
|
268
|
+
const alt = odtElement.description?.value || '';
|
|
269
|
+
ctx.openNode();
|
|
270
|
+
ctx.closeNode('image', {
|
|
271
|
+
src: odtElement.image['@href'],
|
|
272
|
+
alt,
|
|
565
273
|
});
|
|
566
|
-
}
|
|
274
|
+
}
|
|
275
|
+
// },
|
|
567
276
|
},
|
|
568
|
-
'
|
|
569
|
-
|
|
570
|
-
state.textMarks.forEach((x) => x.markName === 'bookmark' &&
|
|
571
|
-
x.markAttributes.id === element['@name']
|
|
572
|
-
? state.textMarks.delete(x)
|
|
573
|
-
: x);
|
|
574
|
-
},
|
|
277
|
+
'rect': () => {
|
|
278
|
+
// ignore: true,
|
|
575
279
|
},
|
|
576
|
-
'annotation': {
|
|
577
|
-
ignore: true,
|
|
280
|
+
'annotation': () => {
|
|
281
|
+
// ignore: true,
|
|
578
282
|
},
|
|
579
283
|
};
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
doc = state.closeNode();
|
|
585
|
-
} while (state.stack.length);
|
|
586
|
-
if (!doc) {
|
|
587
|
-
throw new Error('Incorrect stack handling');
|
|
588
|
-
}
|
|
589
|
-
return doc || null; //this.schema.topNodeType.createAndFill()!;
|
|
284
|
+
const ctx = new OdtStashContext(this.schema, handlers, stylesTree, contentTree['automatic-styles']);
|
|
285
|
+
ctx.openNode();
|
|
286
|
+
ctx.handle('body', contentTree.body);
|
|
287
|
+
return ctx.closeNode('doc');
|
|
590
288
|
}
|
|
591
289
|
}
|