@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.
Files changed (33) hide show
  1. package/README.md +8 -2
  2. package/esm/editor/src/CoreEditor.d.ts.map +1 -1
  3. package/esm/editor/src/CoreEditor.js +3 -1
  4. package/esm/editor/src/Extension.d.ts.map +1 -1
  5. package/esm/editor/src/ExtensionManager.d.ts +1 -1
  6. package/esm/editor/src/ExtensionManager.d.ts.map +1 -1
  7. package/esm/editor/src/nodeToTreeString.d.ts +8 -2
  8. package/esm/editor/src/nodeToTreeString.d.ts.map +1 -1
  9. package/esm/editor/src/nodeToTreeString.js +27 -11
  10. package/esm/editor/src/utilities/SmartOutput.d.ts +39 -0
  11. package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -0
  12. package/esm/editor/src/utilities/SmartOutput.js +213 -0
  13. package/esm/extension-odt/src/ExtensionOdt.d.ts +0 -1
  14. package/esm/extension-odt/src/ExtensionOdt.d.ts.map +1 -1
  15. package/esm/extension-odt/src/ExtensionOdt.js +25 -28
  16. package/esm/extension-odt/src/OdtParser.d.ts +41 -63
  17. package/esm/extension-odt/src/OdtParser.d.ts.map +1 -1
  18. package/esm/extension-odt/src/OdtParser.js +172 -474
  19. package/esm/extension-odt/src/lists.d.ts +23 -0
  20. package/esm/extension-odt/src/lists.d.ts.map +1 -0
  21. package/esm/extension-odt/src/lists.js +55 -0
  22. package/esm/extension-odt/src/node_handlers/basic_node_handlers.d.ts +4 -0
  23. package/esm/extension-odt/src/node_handlers/basic_node_handlers.d.ts.map +1 -0
  24. package/esm/extension-odt/src/node_handlers/basic_node_handlers.js +138 -0
  25. package/esm/extension-odt/src/node_handlers/list_node_handlers.d.ts +3 -0
  26. package/esm/extension-odt/src/node_handlers/list_node_handlers.d.ts.map +1 -0
  27. package/esm/extension-odt/src/node_handlers/list_node_handlers.js +91 -0
  28. package/esm/extension-odt/src/node_handlers/table_node_handlers.d.ts +3 -0
  29. package/esm/extension-odt/src/node_handlers/table_node_handlers.d.ts.map +1 -0
  30. package/esm/extension-odt/src/node_handlers/table_node_handlers.js +24 -0
  31. package/esm/extension-odt/src/postprocess/convertCodeParagraphsToCodeBlocks.d.ts.map +1 -1
  32. package/esm/extension-odt/src/postprocess/convertCodeParagraphsToCodeBlocks.js +3 -1
  33. 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 attrs(spec, token, style) {
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
- class OdtParseState {
46
- constructor(schema, tokens, stylesTree, automaticStyles) {
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, "stack", {
95
+ Object.defineProperty(this, "ctxStash", {
72
96
  enumerable: true,
73
97
  configurable: true,
74
98
  writable: true,
75
- value: void 0
99
+ value: []
76
100
  });
77
- Object.defineProperty(this, "textMarks", {
101
+ Object.defineProperty(this, "currentCtx", {
78
102
  enumerable: true,
79
103
  configurable: true,
80
104
  writable: true,
81
- value: new Set()
105
+ value: void 0
82
106
  });
83
- Object.defineProperty(this, "nextTextMarks", {
107
+ Object.defineProperty(this, "listTracker", {
84
108
  enumerable: true,
85
109
  configurable: true,
86
110
  writable: true,
87
- value: new Set()
111
+ value: new ListTracker()
88
112
  });
89
- this.stack = [];
90
- this.openNode(schema.topNodeType, null);
91
- }
92
- top() {
93
- return this.stack[this.stack.length - 1];
113
+ this.currentCtx = {
114
+ handlers,
115
+ content: [],
116
+ marks: [],
117
+ meta: {},
118
+ };
119
+ this.stash();
94
120
  }
95
- push(elt) {
96
- if (this.stack.length)
97
- this.top().content.push(elt);
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
- // Adds the given text to the current position in the document,
100
- // using the current marks as styling.
101
- addText(text) {
102
- if (!text)
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
- for (const textMark of this.nextTextMarks) {
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
- // Removes the given mark from the set of active marks.
127
- closeMark(mark) {
128
- let top = this.top();
129
- top.marks = mark.removeFromSet(top.marks);
148
+ openNode() {
149
+ this.stash();
150
+ this.current.content = [];
130
151
  }
131
- // Add a node at the current position.
132
- addNode(type, attrs, content, marks = Mark.none) {
133
- let top = this.top();
134
- if (top?.marks) {
135
- marks = [...top.marks, ...marks];
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
- // Wrap subsequent content in a node of the given type.
144
- openNode(type, attrs) {
145
- this.stack.push({
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
- if (spec.custom) {
164
- spec.custom(this, element);
165
- return;
165
+ const node = nodeType.createAndFill(attrs, this.current.content, marks);
166
+ if (!node) {
167
+ throw new Error('Error creating node: ' + type);
166
168
  }
167
- const children = spec.children ? spec.children(element) : [];
168
- const style = ('object' === typeof element && element['@style-name'])
169
- ? resolveStyle(this.stylesTree, this.automaticStyles, element['@style-name'])
170
- : {};
171
- const markToClose = [];
172
- const textProperties = style && style['text-properties'] || {};
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.marks['em'];
189
- markToClose.push(this.openMark(markType.create(attrs(spec, element, style))));
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 (!key) {
258
- return;
187
+ if (textProperties['@font-weight'] === 'bold') {
188
+ const markType = this.schema.mark('strong');
189
+ marks.push(markType);
259
190
  }
260
- callback(key, value);
191
+ return marks;
261
192
  }
262
- }
263
- function iterateEnum($value) {
264
- if (!$value) {
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
- return item;
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
- clearAbove(level) {
295
- for (let i = level + 1; i < 20; i++) {
296
- this.levels[i] = 1;
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
- setLevelNode(level, node) {
300
- this.levelNodes[level] = node;
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 automaticStyles = contentTree['automatic-styles'];
347
- const tokens = {
348
- 'body': {
349
- children: (odtElement) => iterateEnum(odtElement.text?.$value),
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
- custom(state) {
508
- state.textMarks.add({
509
- markName: 'change',
510
- markAttributes: {},
511
- });
512
- },
236
+ // custom(state) {
237
+ // state.textMarks.add({
238
+ // markName: 'change',
239
+ // markAttributes: {},
240
+ // });
241
+ // },
513
242
  },
514
243
  'change-end': {
515
- custom(state) {
516
- state.textMarks.forEach((x) => x.markName === 'change' ? state.textMarks.delete(x) : x);
517
- },
518
- },
519
- 'frame': {
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
- 'bookmark-start': {
559
- custom(state, element) {
560
- state.textMarks.add({
561
- markName: 'bookmark',
562
- markAttributes: {
563
- id: element['@name'],
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
- 'bookmark-end': {
569
- custom(state, element) {
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 state = new OdtParseState(this.schema, tokens, stylesTree, contentTree['automatic-styles']);
581
- state.handleElement('body', contentTree.body);
582
- let doc;
583
- do {
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
  }