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.
@@ -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, rels, pkg) {
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, rels, pkg) {
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, rels, pkg);
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, context, rels) {
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 fldChar = childrenWithTag(node, "w:fldChar")[0];
164
- if (fldChar !== void 0) {
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, context);
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, context, rels) {
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, context);
197
+ const props = resolveParagraphProperties(paragraph, ctx.styles);
192
198
  return {
193
199
  kind: "paragraph",
194
- runs: readParagraphRuns(paragraph, context, rels),
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, context, rels, pkg) {
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: readBodyBlocks(tc.children, context, rels, pkg)
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, context, rels, pkg) {
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, context, rels, pkg)));
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 readBodyBlocks(nodes, context, rels, pkg) {
316
- const blocks = [];
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
- if (hasPageBreakBefore(node)) blocks.push({ kind: "pageBreak" });
321
- blocks.push(readParagraph(node, context, rels));
322
- blocks.push(...readParagraphImages(node, rels, pkg));
323
- } else if (node.tag === "w:tbl") blocks.push(readTable(node, context, rels, pkg));
324
- else if (node.tag === "w:sdt") {
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) blocks.push(...readBodyBlocks(sdtContent.children, context, rels, pkg));
327
- } else if (node.tag === "w:ins") blocks.push(...readBodyBlocks(node.children, context, rels, pkg));
328
- else if (node.tag === "mc:AlternateContent") {
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) blocks.push(...readBodyBlocks(target.children, context, rels, pkg));
507
+ if (target !== void 0) collectFlowNodes(target.children, ctx, state, carryDeletions);
508
+ continue;
331
509
  }
332
- }
333
- return blocks;
334
- }
335
- function readSections(body, context, rels, pkg) {
336
- const sections = [];
337
- let currentBlocks = [];
338
- for (const node of body.children) {
339
- if (node.type !== "element") continue;
340
- if (node.tag === "w:sectPr") {
341
- sections.push({
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:p") {
350
- const pPr = childrenWithTag(node, "w:pPr")[0];
351
- const sectPr = pPr === void 0 ? void 0 : childrenWithTag(pPr, "w:sectPr")[0];
352
- if (hasPageBreakBefore(node)) currentBlocks.push({ kind: "pageBreak" });
353
- currentBlocks.push(readParagraph(node, context, rels));
354
- currentBlocks.push(...readParagraphImages(node, rels, pkg));
355
- if (sectPr !== void 0) {
356
- sections.push({
357
- pageSize: readPageSize(sectPr),
358
- margins: readMargins(sectPr),
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
- currentBlocks.push(...readBodyBlocks([node], context, rels, pkg));
535
+ if (node.tag === "w:sectPr") state.sectionBreaks.push({
536
+ index: state.blocks.length,
537
+ sectPr: node
538
+ });
366
539
  }
367
- if (currentBlocks.length > 0 || sections.length === 0) sections.push({
368
- pageSize: PAGE_SIZE_LETTER,
369
- margins: DEFAULT_MARGINS,
370
- blocks: currentBlocks
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 context = {
427
- stylesRoot: rootElement(pkg.parts[STYLES_PART_PATH]),
428
- theme: readDocumentTheme(pkg, docRels)
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, context, docRels, pkg),
633
+ sections: readSections(body, ctx),
433
634
  comments: readComments(pkg),
434
635
  footnotes: readFootnotes(pkg),
435
636
  headers: readHeaderFooterText(pkg, "word/header"),