ooxml.js 3.0.1 → 3.1.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 +19 -3
- package/dist/codec-B3qT1CGZ.d.ts +89 -0
- package/dist/codec-CuzuI9Dy.d.cts +89 -0
- package/dist/codec.d.cts +1 -1
- package/dist/codec.d.ts +1 -1
- package/dist/index.cjs +104 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/typed/docx/constructs.cjs +211 -0
- package/dist/typed/docx/constructs.d.cts +27 -0
- package/dist/typed/docx/constructs.d.ts +27 -0
- package/dist/typed/docx/constructs.js +200 -0
- package/dist/typed/docx/read.cjs +275 -74
- package/dist/typed/docx/read.js +276 -75
- package/dist/typed/docx/write.cjs +676 -0
- package/dist/typed/docx/write.d.cts +2 -0
- package/dist/typed/docx/write.d.ts +2 -0
- package/dist/typed/docx/write.js +675 -0
- package/dist/typed/shared/source-path.cjs +1 -0
- package/dist/typed/shared/source-path.js +1 -0
- package/dist/typed/util.cjs +4 -3
- package/dist/typed/util.js +4 -3
- package/dist/write-C08_maSc.d.cts +11 -0
- package/dist/write-U3Ap0vHi.d.ts +11 -0
- package/package.json +2 -2
- package/dist/codec-Ch4blnoI.d.cts +0 -88
- package/dist/codec-ChWBx_WN.d.ts +0 -88
package/dist/typed/docx/read.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { base64ToBytes } from "../../util/base64.js";
|
|
2
|
-
import { attr, childrenWithTag, elementsWithTag, resolveRelationships, rootElement, textContent } from "../util.js";
|
|
2
|
+
import { attr, childrenWithTag, decodeEntities, elementsWithTag, resolveRelationships, rootElement, textContent } from "../util.js";
|
|
3
3
|
import { DocumentMetadataSchema, readCoreProperties } from "../shared/metadata.js";
|
|
4
4
|
import { sniffImageFormat } from "../../image/sniff.js";
|
|
5
5
|
import { eighthPointsToPt, emuToPt, twipsToPt } from "../shared/units.js";
|
|
@@ -7,6 +7,7 @@ import { EMPTY_THEME, readTheme } from "../shared/drawingml.js";
|
|
|
7
7
|
import { assignSourcePaths } from "../shared/source-path.js";
|
|
8
8
|
import { resolveParagraphProperties, resolveRunProperties } from "./styles.js";
|
|
9
9
|
import { NumberingDefinitionSchema, readNumberingDefinitions } from "./numbering.js";
|
|
10
|
+
import { PROVENANCE_CHANGE_BY_TAG, bookmarkAnchorDescriptor, contentBearingChildren, fieldCharType, indexParagraphContent, insertConstructMarkers, isDeletedChange, readContentControlDescriptor, readProvenanceDescriptor, runInstructionText } from "./constructs.js";
|
|
10
11
|
import { z } from "zod";
|
|
11
12
|
import { COLOR_BLACK, ContentSectionSchema, PAGE_SIZE_LETTER, clampHeadingLevel, rgbHexToColor } from "document-schema.js";
|
|
12
13
|
//#region src/typed/docx/read.ts
|
|
@@ -86,13 +87,13 @@ function readRunText(run) {
|
|
|
86
87
|
let text = "";
|
|
87
88
|
for (const child of run.children) {
|
|
88
89
|
if (child.type !== "element") continue;
|
|
89
|
-
if (child.tag === "w:t") text += textContent(child);
|
|
90
|
+
if (child.tag === "w:t" || child.tag === "w:delText") text += textContent(child);
|
|
90
91
|
else if (child.tag === "w:tab") text += " ";
|
|
91
92
|
else if (child.tag === "w:br" || child.tag === "w:cr") text += "\n";
|
|
92
93
|
}
|
|
93
94
|
return text;
|
|
94
95
|
}
|
|
95
|
-
function readDrawingImage(drawing,
|
|
96
|
+
function readDrawingImage(drawing, ctx) {
|
|
96
97
|
const container = childrenWithTag(drawing, "wp:inline")[0] ?? childrenWithTag(drawing, "wp:anchor")[0];
|
|
97
98
|
if (container === void 0) return;
|
|
98
99
|
const extent = childrenWithTag(container, "wp:extent")[0];
|
|
@@ -103,8 +104,8 @@ function readDrawingImage(drawing, rels, pkg) {
|
|
|
103
104
|
const altText = docPr === void 0 ? void 0 : attr(docPr, "descr") ?? attr(docPr, "title");
|
|
104
105
|
const blip = elementsWithTag(container.children, "a:blip")[0];
|
|
105
106
|
const rId = blip === void 0 ? void 0 : attr(blip, "r:embed");
|
|
106
|
-
const rel = rId === void 0 ? void 0 : rels.get(rId);
|
|
107
|
-
const mediaPart = rel === void 0 ? void 0 : pkg.parts[rel.target];
|
|
107
|
+
const rel = rId === void 0 ? void 0 : ctx.rels.get(rId);
|
|
108
|
+
const mediaPart = rel === void 0 ? void 0 : ctx.pkg.parts[rel.target];
|
|
108
109
|
if (mediaPart?.kind !== "binary") return;
|
|
109
110
|
const bytes = base64ToBytes(mediaPart.base64);
|
|
110
111
|
const format = sniffImageFormat(bytes);
|
|
@@ -116,26 +117,26 @@ function readDrawingImage(drawing, rels, pkg) {
|
|
|
116
117
|
widthPt: emuToPt(Number(cx)),
|
|
117
118
|
heightPt: emuToPt(Number(cy))
|
|
118
119
|
};
|
|
119
|
-
if (altText !== void 0) image.altText = altText;
|
|
120
|
+
if (altText !== void 0) image.altText = decodeEntities(altText);
|
|
120
121
|
return image;
|
|
121
122
|
}
|
|
122
|
-
function collectDrawings(nodes, out) {
|
|
123
|
+
function collectDrawings(nodes, carryDeletions, out) {
|
|
123
124
|
for (const node of nodes) {
|
|
124
125
|
if (node.type !== "element") continue;
|
|
125
|
-
if (node.tag === "w:del") continue;
|
|
126
|
+
if (!carryDeletions && (node.tag === "w:del" || node.tag === "w:moveFrom")) continue;
|
|
126
127
|
if (node.tag === "w:drawing") {
|
|
127
128
|
out.push(node);
|
|
128
129
|
continue;
|
|
129
130
|
}
|
|
130
|
-
collectDrawings(node.children, out);
|
|
131
|
+
collectDrawings(node.children, carryDeletions, out);
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
|
-
function readParagraphImages(paragraph,
|
|
134
|
+
function readParagraphImages(paragraph, ctx, carryDeletions) {
|
|
134
135
|
const drawings = [];
|
|
135
|
-
collectDrawings(paragraph.children, drawings);
|
|
136
|
+
collectDrawings(paragraph.children, carryDeletions, drawings);
|
|
136
137
|
const images = [];
|
|
137
138
|
for (const drawing of drawings) {
|
|
138
|
-
const image = readDrawingImage(drawing,
|
|
139
|
+
const image = readDrawingImage(drawing, ctx);
|
|
139
140
|
if (image !== void 0) images.push(image);
|
|
140
141
|
}
|
|
141
142
|
return images;
|
|
@@ -153,23 +154,22 @@ function readRun(run, paragraph, context) {
|
|
|
153
154
|
color: props.color
|
|
154
155
|
};
|
|
155
156
|
}
|
|
156
|
-
function readParagraphRuns(paragraph,
|
|
157
|
+
function readParagraphRuns(paragraph, ctx, carryDeletions) {
|
|
157
158
|
const runs = [];
|
|
158
159
|
let fieldState = "none";
|
|
159
160
|
function walk(nodes, hyperlinkTarget) {
|
|
160
161
|
for (const node of nodes) {
|
|
161
162
|
if (node.type !== "element") continue;
|
|
162
163
|
if (node.tag === "w:r") {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
165
|
-
const type = attr(fldChar, "w:fldCharType");
|
|
164
|
+
const type = fieldCharType(node);
|
|
165
|
+
if (type !== void 0) {
|
|
166
166
|
if (type === "begin") fieldState = "code";
|
|
167
167
|
else if (type === "separate") fieldState = "result";
|
|
168
168
|
else if (type === "end") fieldState = "none";
|
|
169
169
|
continue;
|
|
170
170
|
}
|
|
171
171
|
if (fieldState === "code") continue;
|
|
172
|
-
const run = readRun(node, paragraph,
|
|
172
|
+
const run = readRun(node, paragraph, ctx.styles);
|
|
173
173
|
runs.push(hyperlinkTarget === void 0 ? run : {
|
|
174
174
|
...run,
|
|
175
175
|
hyperlink: hyperlinkTarget
|
|
@@ -177,21 +177,27 @@ function readParagraphRuns(paragraph, context, rels) {
|
|
|
177
177
|
} else if (node.tag === "w:fldSimple") walk(node.children, hyperlinkTarget);
|
|
178
178
|
else if (node.tag === "w:hyperlink") {
|
|
179
179
|
const rId = attr(node, "r:id");
|
|
180
|
-
const target = rId === void 0 ? void 0 : rels.get(rId)?.target;
|
|
180
|
+
const target = rId === void 0 ? void 0 : ctx.rels.get(rId)?.target;
|
|
181
181
|
walk(node.children, target ?? hyperlinkTarget);
|
|
182
|
-
} else if (node.tag === "w:ins") walk(node.children, hyperlinkTarget);
|
|
182
|
+
} else if (node.tag === "w:ins" || node.tag === "w:moveTo") walk(node.children, hyperlinkTarget);
|
|
183
|
+
else if (node.tag === "w:del" || node.tag === "w:moveFrom") {
|
|
184
|
+
if (carryDeletions) walk(node.children, hyperlinkTarget);
|
|
185
|
+
} else if (node.tag === "w:sdt") {
|
|
186
|
+
const sdtContent = childrenWithTag(node, "w:sdtContent")[0];
|
|
187
|
+
if (sdtContent !== void 0) walk(sdtContent.children, hyperlinkTarget);
|
|
188
|
+
}
|
|
183
189
|
}
|
|
184
190
|
}
|
|
185
191
|
walk(paragraph.children, void 0);
|
|
186
192
|
return runs;
|
|
187
193
|
}
|
|
188
|
-
function readParagraph(paragraph,
|
|
194
|
+
function readParagraph(paragraph, ctx, carryDeletions) {
|
|
189
195
|
const pPr = childrenWithTag(paragraph, "w:pPr")[0];
|
|
190
196
|
const pStyleEl = pPr === void 0 ? void 0 : childrenWithTag(pPr, "w:pStyle")[0];
|
|
191
|
-
const props = resolveParagraphProperties(paragraph,
|
|
197
|
+
const props = resolveParagraphProperties(paragraph, ctx.styles);
|
|
192
198
|
return {
|
|
193
199
|
kind: "paragraph",
|
|
194
|
-
runs: readParagraphRuns(paragraph,
|
|
200
|
+
runs: readParagraphRuns(paragraph, ctx, carryDeletions),
|
|
195
201
|
styleId: pStyleEl === void 0 ? void 0 : attr(pStyleEl, "w:val"),
|
|
196
202
|
headingLevel: props.outlineLvl === void 0 ? void 0 : clampHeadingLevel(props.outlineLvl + 1),
|
|
197
203
|
alignment: props.alignment,
|
|
@@ -252,7 +258,7 @@ function readCellBorders(tcPr) {
|
|
|
252
258
|
if (bottom !== void 0) borders.bottom = bottom;
|
|
253
259
|
return Object.keys(borders).length === 0 ? void 0 : borders;
|
|
254
260
|
}
|
|
255
|
-
function readRawCell(tc,
|
|
261
|
+
function readRawCell(tc, ctx, carryDeletions) {
|
|
256
262
|
const tcPr = childrenWithTag(tc, "w:tcPr")[0];
|
|
257
263
|
const gridSpanEl = tcPr === void 0 ? void 0 : childrenWithTag(tcPr, "w:gridSpan")[0];
|
|
258
264
|
const gridSpanVal = gridSpanEl === void 0 ? void 0 : attr(gridSpanEl, "w:val");
|
|
@@ -263,7 +269,7 @@ function readRawCell(tc, context, rels, pkg) {
|
|
|
263
269
|
isVMergeContinuation: vMergeVal === "continue",
|
|
264
270
|
background: readCellShading(tcPr),
|
|
265
271
|
borders: readCellBorders(tcPr),
|
|
266
|
-
blocks:
|
|
272
|
+
blocks: readBlockScope(tc.children, ctx, carryDeletions)
|
|
267
273
|
};
|
|
268
274
|
}
|
|
269
275
|
function readRowHeightPt(tr) {
|
|
@@ -273,11 +279,11 @@ function readRowHeightPt(tr) {
|
|
|
273
279
|
const val = trHeight === void 0 ? void 0 : attr(trHeight, "w:val");
|
|
274
280
|
return val === void 0 ? void 0 : twipsToPt(Number(val));
|
|
275
281
|
}
|
|
276
|
-
function readTable(tbl,
|
|
282
|
+
function readTable(tbl, ctx, carryDeletions) {
|
|
277
283
|
const tblGrid = childrenWithTag(tbl, "w:tblGrid")[0];
|
|
278
284
|
const columnWidthsPt = tblGrid === void 0 ? [] : childrenWithTag(tblGrid, "w:gridCol").map((col) => twipsToPt(Number(attr(col, "w:w") ?? "0")));
|
|
279
285
|
const trs = childrenWithTag(tbl, "w:tr");
|
|
280
|
-
const rawRows = trs.map((tr) => childrenWithTag(tr, "w:tc").map((tc) => readRawCell(tc,
|
|
286
|
+
const rawRows = trs.map((tr) => childrenWithTag(tr, "w:tc").map((tc) => readRawCell(tc, ctx, carryDeletions)));
|
|
281
287
|
const rowColumnIndices = rawRows.map((row) => {
|
|
282
288
|
const indices = [];
|
|
283
289
|
let col = 0;
|
|
@@ -312,63 +318,254 @@ function readTable(tbl, context, rels, pkg) {
|
|
|
312
318
|
}))
|
|
313
319
|
};
|
|
314
320
|
}
|
|
315
|
-
function
|
|
316
|
-
|
|
321
|
+
function newFlowState() {
|
|
322
|
+
return {
|
|
323
|
+
blocks: [],
|
|
324
|
+
extents: [],
|
|
325
|
+
sectionBreaks: [],
|
|
326
|
+
bookmarkEvents: [],
|
|
327
|
+
openFields: [],
|
|
328
|
+
order: 0
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function resolveBookmarkExtents(events) {
|
|
332
|
+
const byId = /* @__PURE__ */ new Map();
|
|
333
|
+
for (const event of events) {
|
|
334
|
+
const existing = byId.get(event.id);
|
|
335
|
+
if (existing === void 0) byId.set(event.id, [event]);
|
|
336
|
+
else existing.push(event);
|
|
337
|
+
}
|
|
338
|
+
const extents = [];
|
|
339
|
+
for (const halves of byId.values()) {
|
|
340
|
+
const start = halves.filter((half) => half.kind === "start");
|
|
341
|
+
const end = halves.filter((half) => half.kind === "end");
|
|
342
|
+
const open = start[0];
|
|
343
|
+
const close = end[0];
|
|
344
|
+
if (start.length !== 1 || end.length !== 1 || open === void 0 || close === void 0) continue;
|
|
345
|
+
if (open.name === void 0 || !open.qualified || !close.qualified || close.index < open.index) continue;
|
|
346
|
+
extents.push({
|
|
347
|
+
startIndex: open.index,
|
|
348
|
+
endIndex: close.index,
|
|
349
|
+
order: open.order,
|
|
350
|
+
descriptor: bookmarkAnchorDescriptor(open.name)
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return extents;
|
|
354
|
+
}
|
|
355
|
+
function wholeParagraphTrackedChange(index) {
|
|
356
|
+
const content = contentBearingChildren(index);
|
|
357
|
+
const first = content[0];
|
|
358
|
+
if (first === void 0) return;
|
|
359
|
+
const change = PROVENANCE_CHANGE_BY_TAG.get(first.tag);
|
|
360
|
+
if (change === void 0 || !content.every((child) => child.tag === first.tag)) return;
|
|
361
|
+
return {
|
|
362
|
+
element: first,
|
|
363
|
+
change
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function recordParagraphBookmarks(index, paragraphIndex, endIndex, state) {
|
|
367
|
+
index.elements.forEach((element, position) => {
|
|
368
|
+
if (element.tag !== "w:bookmarkStart" && element.tag !== "w:bookmarkEnd") return;
|
|
369
|
+
const id = attr(element, "w:id");
|
|
370
|
+
if (id === void 0) return;
|
|
371
|
+
const leading = index.firstContentIndex === -1 || position < index.firstContentIndex;
|
|
372
|
+
const trailing = index.lastContentIndex === -1 || position > index.lastContentIndex;
|
|
373
|
+
if (element.tag === "w:bookmarkStart") {
|
|
374
|
+
const name = attr(element, "w:name");
|
|
375
|
+
state.bookmarkEvents.push({
|
|
376
|
+
id,
|
|
377
|
+
name: name === void 0 ? void 0 : decodeEntities(name),
|
|
378
|
+
kind: "start",
|
|
379
|
+
index: leading ? paragraphIndex : endIndex,
|
|
380
|
+
qualified: leading || trailing,
|
|
381
|
+
order: state.order++
|
|
382
|
+
});
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
state.bookmarkEvents.push({
|
|
386
|
+
id,
|
|
387
|
+
name: void 0,
|
|
388
|
+
kind: "end",
|
|
389
|
+
index: trailing ? endIndex : paragraphIndex,
|
|
390
|
+
qualified: leading || trailing,
|
|
391
|
+
order: state.order++
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
function scanParagraphFields(index, paragraphIndex, endIndex, state) {
|
|
396
|
+
const content = contentBearingChildren(index);
|
|
397
|
+
content.forEach((child, position) => {
|
|
398
|
+
if (child.tag === "w:fldSimple") {
|
|
399
|
+
if (content.length === 1) state.extents.push({
|
|
400
|
+
startIndex: paragraphIndex,
|
|
401
|
+
endIndex,
|
|
402
|
+
order: state.order++,
|
|
403
|
+
descriptor: {
|
|
404
|
+
kind: "field",
|
|
405
|
+
instruction: decodeEntities(attr(child, "w:instr") ?? "")
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (child.tag !== "w:r") return;
|
|
411
|
+
const type = fieldCharType(child);
|
|
412
|
+
if (type === "begin") {
|
|
413
|
+
state.openFields.push({
|
|
414
|
+
instruction: "",
|
|
415
|
+
inCode: true,
|
|
416
|
+
startIndex: paragraphIndex,
|
|
417
|
+
qualifiedStart: position === 0,
|
|
418
|
+
order: state.order++
|
|
419
|
+
});
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (type === "separate") {
|
|
423
|
+
const open = state.openFields[state.openFields.length - 1];
|
|
424
|
+
if (open !== void 0) open.inCode = false;
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (type === "end") {
|
|
428
|
+
const open = state.openFields.pop();
|
|
429
|
+
if (open !== void 0 && open.qualifiedStart && position === content.length - 1) state.extents.push({
|
|
430
|
+
startIndex: open.startIndex,
|
|
431
|
+
endIndex,
|
|
432
|
+
order: open.order,
|
|
433
|
+
descriptor: {
|
|
434
|
+
kind: "field",
|
|
435
|
+
instruction: open.instruction
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const open = state.openFields[state.openFields.length - 1];
|
|
441
|
+
if (open?.inCode === true) open.instruction += runInstructionText(child);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
function collectParagraph(paragraph, ctx, state, carryDeletions) {
|
|
445
|
+
const index = indexParagraphContent(paragraph);
|
|
446
|
+
const tracked = wholeParagraphTrackedChange(index);
|
|
447
|
+
const paragraphDeleted = carryDeletions || tracked !== void 0 && isDeletedChange(tracked.change);
|
|
448
|
+
if (hasPageBreakBefore(paragraph)) state.blocks.push({ kind: "pageBreak" });
|
|
449
|
+
const paragraphIndex = state.blocks.length;
|
|
450
|
+
state.blocks.push(readParagraph(paragraph, ctx, paragraphDeleted));
|
|
451
|
+
state.blocks.push(...readParagraphImages(paragraph, ctx, paragraphDeleted));
|
|
452
|
+
const endIndex = state.blocks.length;
|
|
453
|
+
if (tracked !== void 0) state.extents.push({
|
|
454
|
+
startIndex: paragraphIndex,
|
|
455
|
+
endIndex,
|
|
456
|
+
order: state.order++,
|
|
457
|
+
descriptor: readProvenanceDescriptor(tracked.element, tracked.change)
|
|
458
|
+
});
|
|
459
|
+
recordParagraphBookmarks(index, paragraphIndex, endIndex, state);
|
|
460
|
+
scanParagraphFields(index, paragraphIndex, endIndex, state);
|
|
461
|
+
const pPr = childrenWithTag(paragraph, "w:pPr")[0];
|
|
462
|
+
const sectPr = pPr === void 0 ? void 0 : childrenWithTag(pPr, "w:sectPr")[0];
|
|
463
|
+
if (sectPr !== void 0) state.sectionBreaks.push({
|
|
464
|
+
index: state.blocks.length,
|
|
465
|
+
sectPr
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
function collectFlowNodes(nodes, ctx, state, carryDeletions) {
|
|
317
469
|
for (const node of nodes) {
|
|
318
470
|
if (node.type !== "element") continue;
|
|
319
471
|
if (node.tag === "w:p") {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
472
|
+
collectParagraph(node, ctx, state, carryDeletions);
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (node.tag === "w:tbl") {
|
|
476
|
+
state.blocks.push(readTable(node, ctx, carryDeletions));
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (node.tag === "w:sdt") {
|
|
480
|
+
const order = state.order++;
|
|
481
|
+
const startIndex = state.blocks.length;
|
|
325
482
|
const sdtContent = childrenWithTag(node, "w:sdtContent")[0];
|
|
326
|
-
if (sdtContent !== void 0)
|
|
327
|
-
|
|
328
|
-
|
|
483
|
+
if (sdtContent !== void 0) collectFlowNodes(sdtContent.children, ctx, state, carryDeletions);
|
|
484
|
+
state.extents.push({
|
|
485
|
+
startIndex,
|
|
486
|
+
endIndex: state.blocks.length,
|
|
487
|
+
order,
|
|
488
|
+
descriptor: readContentControlDescriptor(node)
|
|
489
|
+
});
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
const change = PROVENANCE_CHANGE_BY_TAG.get(node.tag);
|
|
493
|
+
if (change !== void 0) {
|
|
494
|
+
const order = state.order++;
|
|
495
|
+
const startIndex = state.blocks.length;
|
|
496
|
+
collectFlowNodes(node.children, ctx, state, carryDeletions || isDeletedChange(change));
|
|
497
|
+
state.extents.push({
|
|
498
|
+
startIndex,
|
|
499
|
+
endIndex: state.blocks.length,
|
|
500
|
+
order,
|
|
501
|
+
descriptor: readProvenanceDescriptor(node, change)
|
|
502
|
+
});
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
if (node.tag === "mc:AlternateContent") {
|
|
329
506
|
const target = childrenWithTag(node, "mc:Fallback")[0] ?? childrenWithTag(node, "mc:Choice")[0];
|
|
330
|
-
if (target !== void 0)
|
|
507
|
+
if (target !== void 0) collectFlowNodes(target.children, ctx, state, carryDeletions);
|
|
508
|
+
continue;
|
|
331
509
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
pageSize: readPageSize(node),
|
|
343
|
-
margins: readMargins(node),
|
|
344
|
-
blocks: currentBlocks
|
|
510
|
+
if (node.tag === "w:bookmarkStart") {
|
|
511
|
+
const id = attr(node, "w:id");
|
|
512
|
+
const name = attr(node, "w:name");
|
|
513
|
+
if (id !== void 0) state.bookmarkEvents.push({
|
|
514
|
+
id,
|
|
515
|
+
name: name === void 0 ? void 0 : decodeEntities(name),
|
|
516
|
+
kind: "start",
|
|
517
|
+
index: state.blocks.length,
|
|
518
|
+
qualified: true,
|
|
519
|
+
order: state.order++
|
|
345
520
|
});
|
|
346
|
-
currentBlocks = [];
|
|
347
521
|
continue;
|
|
348
522
|
}
|
|
349
|
-
if (node.tag === "w:
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
blocks: currentBlocks
|
|
360
|
-
});
|
|
361
|
-
currentBlocks = [];
|
|
362
|
-
}
|
|
523
|
+
if (node.tag === "w:bookmarkEnd") {
|
|
524
|
+
const id = attr(node, "w:id");
|
|
525
|
+
if (id !== void 0) state.bookmarkEvents.push({
|
|
526
|
+
id,
|
|
527
|
+
name: void 0,
|
|
528
|
+
kind: "end",
|
|
529
|
+
index: state.blocks.length,
|
|
530
|
+
qualified: true,
|
|
531
|
+
order: state.order++
|
|
532
|
+
});
|
|
363
533
|
continue;
|
|
364
534
|
}
|
|
365
|
-
|
|
535
|
+
if (node.tag === "w:sectPr") state.sectionBreaks.push({
|
|
536
|
+
index: state.blocks.length,
|
|
537
|
+
sectPr: node
|
|
538
|
+
});
|
|
366
539
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
540
|
+
}
|
|
541
|
+
function readBlockScope(nodes, ctx, carryDeletions) {
|
|
542
|
+
const state = newFlowState();
|
|
543
|
+
collectFlowNodes(nodes, ctx, state, carryDeletions);
|
|
544
|
+
return insertConstructMarkers(state.blocks, [...state.extents, ...resolveBookmarkExtents(state.bookmarkEvents)]);
|
|
545
|
+
}
|
|
546
|
+
function readSections(body, ctx) {
|
|
547
|
+
const state = newFlowState();
|
|
548
|
+
collectFlowNodes(body.children, ctx, state, false);
|
|
549
|
+
const extents = [...state.extents, ...resolveBookmarkExtents(state.bookmarkEvents)];
|
|
550
|
+
function sliceSection(pageSize, margins, from, to) {
|
|
551
|
+
const contained = extents.filter((extent) => extent.startIndex >= from && extent.endIndex <= to).map((extent) => ({
|
|
552
|
+
...extent,
|
|
553
|
+
startIndex: extent.startIndex - from,
|
|
554
|
+
endIndex: extent.endIndex - from
|
|
555
|
+
}));
|
|
556
|
+
return {
|
|
557
|
+
pageSize,
|
|
558
|
+
margins,
|
|
559
|
+
blocks: insertConstructMarkers(state.blocks.slice(from, to), contained)
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
const sections = [];
|
|
563
|
+
let from = 0;
|
|
564
|
+
for (const sectionBreak of state.sectionBreaks) {
|
|
565
|
+
sections.push(sliceSection(readPageSize(sectionBreak.sectPr), readMargins(sectionBreak.sectPr), from, sectionBreak.index));
|
|
566
|
+
from = sectionBreak.index;
|
|
567
|
+
}
|
|
568
|
+
if (from < state.blocks.length || sections.length === 0) sections.push(sliceSection(PAGE_SIZE_LETTER, DEFAULT_MARGINS, from, state.blocks.length));
|
|
372
569
|
sections.forEach((section, sectionIndex) => assignSourcePaths(section.blocks, `sections[${sectionIndex}]`));
|
|
373
570
|
return sections;
|
|
374
571
|
}
|
|
@@ -423,13 +620,17 @@ function readDocx(pkg) {
|
|
|
423
620
|
const body = childrenWithTag(documentRoot, "w:body")[0];
|
|
424
621
|
if (body === void 0) throw new Error(`readDocx: ${DOCUMENT_PART_PATH} has no w:body element`);
|
|
425
622
|
const docRels = resolveRelationships(pkg, DOCUMENT_PART_PATH);
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
623
|
+
const ctx = {
|
|
624
|
+
styles: {
|
|
625
|
+
stylesRoot: rootElement(pkg.parts[STYLES_PART_PATH]),
|
|
626
|
+
theme: readDocumentTheme(pkg, docRels)
|
|
627
|
+
},
|
|
628
|
+
rels: docRels,
|
|
629
|
+
pkg
|
|
429
630
|
};
|
|
430
631
|
return {
|
|
431
632
|
metadata: readCoreProperties(pkg),
|
|
432
|
-
sections: readSections(body,
|
|
633
|
+
sections: readSections(body, ctx),
|
|
433
634
|
comments: readComments(pkg),
|
|
434
635
|
footnotes: readFootnotes(pkg),
|
|
435
636
|
headers: readHeaderFooterText(pkg, "word/header"),
|