ooxml-core 0.5.0 → 0.7.0

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 (95) hide show
  1. package/README.md +1 -0
  2. package/dist/digest/algorithm-names.d.ts +20 -0
  3. package/dist/digest/algorithm-names.d.ts.map +1 -0
  4. package/dist/digest/base64.d.ts +8 -0
  5. package/dist/digest/base64.d.ts.map +1 -0
  6. package/dist/digest/digest.d.ts +13 -0
  7. package/dist/digest/digest.d.ts.map +1 -0
  8. package/dist/digest/index.cjs +594 -0
  9. package/dist/digest/index.d.ts +8 -0
  10. package/dist/digest/index.d.ts.map +1 -0
  11. package/dist/digest/index.mjs +581 -0
  12. package/dist/digest/password-hash.d.ts +30 -0
  13. package/dist/digest/password-hash.d.ts.map +1 -0
  14. package/dist/digest/sha1.d.ts +3 -0
  15. package/dist/digest/sha1.d.ts.map +1 -0
  16. package/dist/digest/sha256.d.ts +10 -0
  17. package/dist/digest/sha256.d.ts.map +1 -0
  18. package/dist/digest/sha512.d.ts +5 -0
  19. package/dist/digest/sha512.d.ts.map +1 -0
  20. package/dist/docx/block-parser.d.ts.map +1 -1
  21. package/dist/docx/embedded.cjs +131 -54
  22. package/dist/docx/embedded.mjs +131 -54
  23. package/dist/docx/equation.d.ts +8 -0
  24. package/dist/docx/equation.d.ts.map +1 -0
  25. package/dist/docx/index.cjs +131 -54
  26. package/dist/docx/index.mjs +131 -54
  27. package/dist/docx/layout/adapter.d.ts.map +1 -1
  28. package/dist/docx/layout/index.cjs +3 -1
  29. package/dist/docx/layout/index.mjs +3 -1
  30. package/dist/docx/load/index.cjs +133 -56
  31. package/dist/docx/load/index.mjs +133 -56
  32. package/dist/docx/model-run.d.ts +5 -0
  33. package/dist/docx/model-run.d.ts.map +1 -1
  34. package/dist/docx/parse-revisions.d.ts.map +1 -1
  35. package/dist/docx/parse-table.d.ts.map +1 -1
  36. package/dist/docx/write-inline.d.ts.map +1 -1
  37. package/dist/docx/write-table-margins.d.ts +5 -0
  38. package/dist/docx/write-table-margins.d.ts.map +1 -0
  39. package/dist/docx/write-table-properties.d.ts +3 -1
  40. package/dist/docx/write-table-properties.d.ts.map +1 -1
  41. package/dist/docx/write-table.d.ts.map +1 -1
  42. package/dist/index.cjs +598 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.mjs +598 -1
  46. package/dist/visio/cell-formula.d.ts +9 -0
  47. package/dist/visio/cell-formula.d.ts.map +1 -0
  48. package/dist/visio/edit-commands.d.ts +33 -0
  49. package/dist/visio/edit-commands.d.ts.map +1 -0
  50. package/dist/visio/edit-geometry-admission.d.ts +10 -0
  51. package/dist/visio/edit-geometry-admission.d.ts.map +1 -0
  52. package/dist/visio/edit-geometry.d.ts +3 -0
  53. package/dist/visio/edit-geometry.d.ts.map +1 -0
  54. package/dist/visio/edit-recalculate-index.d.ts +25 -0
  55. package/dist/visio/edit-recalculate-index.d.ts.map +1 -0
  56. package/dist/visio/edit-recalculate.d.ts +11 -0
  57. package/dist/visio/edit-recalculate.d.ts.map +1 -0
  58. package/dist/visio/edit-scope.d.ts +5 -0
  59. package/dist/visio/edit-scope.d.ts.map +1 -0
  60. package/dist/visio/edit.d.ts +4 -8
  61. package/dist/visio/edit.d.ts.map +1 -1
  62. package/dist/visio/formula-evaluate.d.ts +10 -0
  63. package/dist/visio/formula-evaluate.d.ts.map +1 -0
  64. package/dist/visio/formula-theme.d.ts +2 -0
  65. package/dist/visio/formula-theme.d.ts.map +1 -0
  66. package/dist/visio/formula.d.ts +52 -0
  67. package/dist/visio/formula.d.ts.map +1 -0
  68. package/dist/visio/index.cjs +1605 -232
  69. package/dist/visio/index.d.ts +2 -1
  70. package/dist/visio/index.d.ts.map +1 -1
  71. package/dist/visio/index.mjs +1601 -233
  72. package/dist/xlsx/edit/history.d.ts +1 -1
  73. package/dist/xlsx/edit/history.d.ts.map +1 -1
  74. package/dist/xlsx/edit/index.d.ts +1 -1
  75. package/dist/xlsx/edit/index.d.ts.map +1 -1
  76. package/dist/xlsx/edit/protection.d.ts +18 -6
  77. package/dist/xlsx/edit/protection.d.ts.map +1 -1
  78. package/dist/xlsx/edit/types.d.ts +2 -2
  79. package/dist/xlsx/index.cjs +671 -28
  80. package/dist/xlsx/index.mjs +670 -29
  81. package/dist/xlsx/load/index.cjs +56 -19
  82. package/dist/xlsx/load/index.mjs +56 -19
  83. package/dist/xlsx/model.d.ts +21 -0
  84. package/dist/xlsx/model.d.ts.map +1 -1
  85. package/dist/xlsx/read/load.d.ts.map +1 -1
  86. package/dist/xlsx/read/password-hash.d.ts +15 -0
  87. package/dist/xlsx/read/password-hash.d.ts.map +1 -0
  88. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  89. package/dist/xlsx/read/workbook-part.d.ts +3 -1
  90. package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
  91. package/dist/xlsx/write/password-hash.d.ts +8 -0
  92. package/dist/xlsx/write/password-hash.d.ts.map +1 -0
  93. package/dist/xlsx/write/sheet-props.d.ts.map +1 -1
  94. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  95. package/package.json +6 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equation.d.ts","sourceRoot":"","sources":["../../src/docx/equation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAQ3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAK9D;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAStE;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,OAAO,GAAG,SAAS,EACzB,GAAG,EAAE,UAAU,GAAG,SAAS,GACzB,UAAU,CAaZ"}
@@ -2304,6 +2304,46 @@ function orderSectionProperties(sectPr) {
2304
2304
  orderChildren(sectPr, SECTPR_ORDER);
2305
2305
  }
2306
2306
 
2307
+ // src/docx/write-table-margins.ts
2308
+ var SIDES2 = ["top", "left", "bottom", "right"];
2309
+ var ORDER = ["top", "start", "left", "bottom", "end", "right"];
2310
+ function patchMarginProperties(doc, host, propertiesTag, marginTag, propertiesOrder, next, base) {
2311
+ const changed = SIDES2.filter((side) => next?.[side] !== base?.[side]);
2312
+ if (!changed.length) return;
2313
+ for (const side of changed) {
2314
+ const value = next?.[side];
2315
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
2316
+ throw new Error("Table cell margins must be nonnegative whole twips.");
2317
+ }
2318
+ let properties = first2(host, propertiesTag);
2319
+ if (!properties) {
2320
+ properties = makeW(doc, propertiesTag);
2321
+ host.insertBefore(properties, host.firstChild);
2322
+ }
2323
+ let margins = first2(properties, marginTag);
2324
+ if (!margins) {
2325
+ margins = makeW(doc, marginTag);
2326
+ properties.appendChild(margins);
2327
+ }
2328
+ for (const side of changed) {
2329
+ const logical = side === "left" ? "start" : side === "right" ? "end" : side;
2330
+ const edge = first2(margins, logical) ?? first2(margins, side) ?? makeW(doc, side);
2331
+ for (const alias of /* @__PURE__ */ new Set([side, logical]))
2332
+ for (const old of children2(margins, alias)) margins.removeChild(old);
2333
+ const value = next?.[side];
2334
+ if (value === void 0) continue;
2335
+ edge.setAttributeNS(WORD_NS, "w:w", String(value));
2336
+ edge.setAttributeNS(WORD_NS, "w:type", "dxa");
2337
+ margins.appendChild(edge);
2338
+ }
2339
+ if (!Array.from(margins.childNodes).some((node) => node.nodeType === 1) && !margins.attributes.length)
2340
+ properties.removeChild(margins);
2341
+ else orderChildren(margins, ORDER);
2342
+ orderChildren(properties, propertiesOrder);
2343
+ if (!Array.from(properties.childNodes).some((node) => node.nodeType === 1) && !properties.attributes.length)
2344
+ host.removeChild(properties);
2345
+ }
2346
+
2307
2347
  // src/docx/write-table-properties.ts
2308
2348
  var ROW_ORDER = [
2309
2349
  "cnfStyle",
@@ -2363,26 +2403,15 @@ function patchRowProperties(doc, tr, next, base) {
2363
2403
  orderChildren(props, ROW_ORDER);
2364
2404
  }
2365
2405
  function patchTableMargins(doc, table, node, base) {
2366
- if (JSON.stringify(table.cellMargins ?? {}) === JSON.stringify(base?.cellMargins ?? {})) return;
2367
- let props = first2(node, "tblPr");
2368
- if (!props) {
2369
- props = makeW(doc, "tblPr");
2370
- node.insertBefore(props, node.firstChild);
2371
- }
2372
- let margins = first2(props, "tblCellMar");
2373
- if (!margins) {
2374
- margins = makeW(doc, "tblCellMar");
2375
- props.appendChild(margins);
2376
- }
2377
- const built = buildMargins(doc, table.cellMargins ?? {}, "tblCellMar");
2378
- for (const side of ["top", "left", "bottom", "right"]) {
2379
- if (table.cellMargins?.[side] === base?.cellMargins?.[side]) continue;
2380
- for (const old of children2(margins, side)) margins.removeChild(old);
2381
- const replacement = first2(built, side);
2382
- if (replacement) margins.appendChild(replacement);
2383
- }
2384
- orderChildren(margins, ["top", "left", "start", "bottom", "right", "end"]);
2385
- orderChildren(props, TABLE_ORDER);
2406
+ patchMarginProperties(
2407
+ doc,
2408
+ node,
2409
+ "tblPr",
2410
+ "tblCellMar",
2411
+ TABLE_ORDER,
2412
+ table.cellMargins,
2413
+ base?.cellMargins
2414
+ );
2386
2415
  }
2387
2416
  var CELL_ORDER = [
2388
2417
  "cnfStyle",
@@ -2406,6 +2435,9 @@ var CELL_ORDER = [
2406
2435
  ];
2407
2436
  var CELL_BORDER_ORDER = ["top", "start", "left", "bottom", "end", "right", "insideH", "insideV"];
2408
2437
  var CELL_SIDES = ["top", "left", "bottom", "right"];
2438
+ function patchCellMargins(doc, tc, next, base) {
2439
+ patchMarginProperties(doc, tc, "tcPr", "tcMar", CELL_ORDER, next, base);
2440
+ }
2409
2441
  function patchCellBorders(doc, tc, next, base) {
2410
2442
  const changed = CELL_SIDES.filter(
2411
2443
  (side) => JSON.stringify(next?.[side]) !== JSON.stringify(base?.[side])
@@ -2493,13 +2525,7 @@ var TABLE_DESCRIPTOR_KEYS = [
2493
2525
  "style",
2494
2526
  "look"
2495
2527
  ];
2496
- var CELL_DESCRIPTOR_KEYS = [
2497
- "gridSpan",
2498
- "verticalMerge",
2499
- "widthTwips",
2500
- "verticalAlign",
2501
- "margins"
2502
- ];
2528
+ var CELL_DESCRIPTOR_KEYS = ["gridSpan", "verticalMerge", "widthTwips", "verticalAlign"];
2503
2529
  function pick(source, keys) {
2504
2530
  const record = source;
2505
2531
  const result = {};
@@ -2525,7 +2551,7 @@ function assertNoDescriptorEdits(table, base) {
2525
2551
  if (!source) continue;
2526
2552
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
2527
2553
  throw new Error(
2528
- "Cannot edit table cell width, merge, vertical alignment, or margins on an existing cell; only cell text, borders and shading are supported. The original DOCX package remains unchanged."
2554
+ "Cannot edit table cell width, merge or vertical alignment on an existing cell; only cell text, borders, shading and margins are supported. The original DOCX package remains unchanged."
2529
2555
  );
2530
2556
  }
2531
2557
  }
@@ -2595,6 +2621,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2595
2621
  const tc = source?.cell ?? makeW(doc, "tc");
2596
2622
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
2597
2623
  patchCellShading(doc, tc, cell, source?.model);
2624
+ patchCellMargins(doc, tc, cell.margins, source?.model.margins);
2598
2625
  const oldParagraphs = children2(tc, "p");
2599
2626
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
2600
2627
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -2625,13 +2652,13 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2625
2652
  }
2626
2653
 
2627
2654
  // src/docx/page-borders.ts
2628
- var SIDES2 = ["top", "left", "bottom", "right"];
2655
+ var SIDES3 = ["top", "left", "bottom", "right"];
2629
2656
  var ATTRIBUTES = ["offsetFrom", "display", "zOrder"];
2630
2657
  var setW4 = (element, name, value) => element.setAttributeNS(WORD_NS, `w:${name}`, value);
2631
2658
  function parsePageBorders(element) {
2632
2659
  if (!element) return void 0;
2633
2660
  const result = {};
2634
- for (const side of SIDES2) {
2661
+ for (const side of SIDES3) {
2635
2662
  const source = first2(element, side);
2636
2663
  const value = borderSide(source);
2637
2664
  const art = getW(source, "art");
@@ -2669,7 +2696,7 @@ function patchPageBorders(doc, sectPr, next, base, create) {
2669
2696
  return;
2670
2697
  }
2671
2698
  const element = create(doc, sectPr, "pgBorders");
2672
- for (const side of SIDES2) {
2699
+ for (const side of SIDES3) {
2673
2700
  if (JSON.stringify(next[side]) === JSON.stringify(base?.[side])) continue;
2674
2701
  for (const old of children2(element, side)) element.removeChild(old);
2675
2702
  const value = next[side];
@@ -2994,7 +3021,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
2994
3021
  }
2995
3022
 
2996
3023
  // src/docx/write-paragraph-decoration.ts
2997
- var SIDES3 = ["top", "left", "bottom", "right", "between"];
3024
+ var SIDES4 = ["top", "left", "bottom", "right", "between"];
2998
3025
  function wordColor(color) {
2999
3026
  const hex = /^#?([0-9a-f]{6})$/i.exec(color ?? "")?.[1];
3000
3027
  return hex ? hex.toUpperCase() : "auto";
@@ -3028,7 +3055,7 @@ function updateBorders(doc, props, paragraph, base) {
3028
3055
  const borders = paragraph.borders;
3029
3056
  if (!borders) return;
3030
3057
  const pBdr = makeW(doc, "pBdr");
3031
- for (const side of SIDES3) {
3058
+ for (const side of SIDES4) {
3032
3059
  const value = borders[side];
3033
3060
  if (value) pBdr.appendChild(borderElement(doc, side, value));
3034
3061
  }
@@ -5559,6 +5586,30 @@ function createRun(doc, run, base, old, allocator) {
5559
5586
  if (!run.text) node.appendChild(makeW(doc, "t"));
5560
5587
  return node;
5561
5588
  }
5589
+ var MATH_NAMESPACES = /* @__PURE__ */ new Set([
5590
+ "http://schemas.openxmlformats.org/officeDocument/2006/math",
5591
+ "http://purl.oclc.org/ooxml/officeDocument/math"
5592
+ ]);
5593
+ function isEquationElement(element) {
5594
+ return MATH_NAMESPACES.has(element.namespaceURI ?? "") && (element.localName === "oMath" || element.localName === "oMathPara");
5595
+ }
5596
+ function parseEquation(element) {
5597
+ if (!isEquationElement(element)) return void 0;
5598
+ return {
5599
+ text: "",
5600
+ equation: {
5601
+ omml: new xmldom.XMLSerializer().serializeToString(element),
5602
+ display: element.localName === "oMathPara"
5603
+ }
5604
+ };
5605
+ }
5606
+ function preserveEquation(run, base, old) {
5607
+ if (!old || !isEquationElement(old) || !base?.equation || run.text !== "" || run.equation?.omml !== base.equation.omml || run.equation?.display !== base.equation.display)
5608
+ throw new Error(
5609
+ "Equation editing or insertion is unsupported; imported OMML must remain unchanged."
5610
+ );
5611
+ return old.cloneNode(true);
5612
+ }
5562
5613
 
5563
5614
  // src/docx/breaks.ts
5564
5615
  function hasSpecialBreak(element) {
@@ -5657,10 +5708,11 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
5657
5708
  if (!isCommentReferenceRun(item)) push(parseRun3(item));
5658
5709
  } else if (named2(item, "hyperlink")) {
5659
5710
  const link = resolveLink?.(item);
5660
- for (const run of children2(item, "r")) {
5661
- const parsed = parseRun3(run);
5662
- if (link) parsed.link = link;
5663
- push(parsed);
5711
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
5712
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3)] : parseOther?.(child3) ?? []) {
5713
+ if (link) parsed.link = link;
5714
+ push(parsed);
5715
+ }
5664
5716
  }
5665
5717
  } else if ((!item.namespaceURI || item.namespaceURI === WORD_NS) && Object.hasOwn(REVISION_WRAPPERS, item.localName)) {
5666
5718
  const kind = expectDefined(
@@ -5671,7 +5723,12 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
5671
5723
  const revision = revisionFrom(item, kind);
5672
5724
  const range = kind === "moveFrom" || kind === "moveTo" ? moves[kind].at(-1) : void 0;
5673
5725
  if (range) revision.move = { name: range.name, rangeId: range.id };
5674
- for (const run of children2(item, "r")) push(parseRun3(run, revision));
5726
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
5727
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3, revision)] : parseOther?.(child3) ?? []) {
5728
+ parsed.revision = revision;
5729
+ push(parsed);
5730
+ }
5731
+ }
5675
5732
  } else if (trackMoveRange(item, moves)) {
5676
5733
  continue;
5677
5734
  } else if (named2(item, "commentRangeStart")) {
@@ -5718,7 +5775,9 @@ function runsOf(parent, container, slots) {
5718
5775
  if (child3.nodeType === 3 && child3.textContent?.trim()) return false;
5719
5776
  continue;
5720
5777
  }
5721
- if (named2(child3, "r")) {
5778
+ if (isEquationElement(child3)) {
5779
+ slots.push({ element: child3, ...container && { container } });
5780
+ } else if (named2(child3, "r")) {
5722
5781
  if (isCommentReferenceRun(child3)) continue;
5723
5782
  if (!runIsSafe(child3)) return false;
5724
5783
  slots.push({ element: child3, ...container && { container } });
@@ -5742,7 +5801,9 @@ function collectInlineSlots(paragraph) {
5742
5801
  if (child3.nodeType === 3 && child3.textContent?.trim()) return void 0;
5743
5802
  continue;
5744
5803
  }
5745
- if (named2(child3, "r")) {
5804
+ if (isEquationElement(child3)) {
5805
+ slots.push({ element: child3 });
5806
+ } else if (named2(child3, "r")) {
5746
5807
  if (isCommentReferenceRun(child3)) continue;
5747
5808
  if (!runIsSafe(child3)) return void 0;
5748
5809
  slots.push({ element: child3 });
@@ -5758,7 +5819,7 @@ function collectInlineSlots(paragraph) {
5758
5819
  }
5759
5820
  function replaceableInlineChildren(paragraph) {
5760
5821
  return Array.from(paragraph.childNodes).filter(
5761
- (child3) => isElement(child3) && (named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
5822
+ (child3) => isElement(child3) && (isEquationElement(child3) || named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
5762
5823
  );
5763
5824
  }
5764
5825
  function sameLink(a, b) {
@@ -5783,7 +5844,7 @@ function newHyperlink(doc, link, allocator) {
5783
5844
  }
5784
5845
  function runNodes(doc, run, base, old, opens, closes, allocator) {
5785
5846
  const nodes = opens.flatMap((edge) => rangeStartNodes(doc, edge));
5786
- const node = createRun(doc, run, base, old, allocator);
5847
+ const node = run.equation ? preserveEquation(run, base, old) : createRun(doc, run, base, old, allocator);
5787
5848
  const revision = run.revision;
5788
5849
  if (revision && ["insert", "delete", "moveFrom", "moveTo"].includes(revision.kind)) {
5789
5850
  if (revision.kind === "delete" || revision.kind === "moveFrom") convertToDeleteText(doc, node);
@@ -5795,15 +5856,23 @@ function runNodes(doc, run, base, old, opens, closes, allocator) {
5795
5856
  function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
5796
5857
  const { opens, closes } = rangeEdges(runs, ranges);
5797
5858
  const runAt = (at) => expectDefined(runs[at], `run ${at}`);
5798
- const nodesFor = (index2) => runNodes(
5799
- doc,
5800
- runAt(index2),
5801
- base?.[index2],
5802
- slots[index2]?.element,
5803
- opens.get(index2) ?? [],
5804
- closes.get(index2) ?? [],
5805
- allocator
5806
- );
5859
+ const nodesFor = (index2) => {
5860
+ const run = runAt(index2);
5861
+ const sourceIndex = run.equation ? base?.findIndex(
5862
+ (source2) => source2.equation?.omml === run.equation?.omml && source2.equation?.display === run.equation?.display
5863
+ ) : index2;
5864
+ const source = sourceIndex === void 0 ? void 0 : base?.[sourceIndex];
5865
+ const old = sourceIndex === void 0 ? void 0 : slots[sourceIndex]?.element;
5866
+ return runNodes(
5867
+ doc,
5868
+ run,
5869
+ !run.equation && source?.equation ? void 0 : source,
5870
+ !run.equation && old && isEquationElement(old) ? void 0 : old,
5871
+ opens.get(index2) ?? [],
5872
+ closes.get(index2) ?? [],
5873
+ allocator
5874
+ );
5875
+ };
5807
5876
  const output = [];
5808
5877
  let index = 0;
5809
5878
  while (index < runs.length) {
@@ -7504,7 +7573,9 @@ function parseMargins(element) {
7504
7573
  ["left", "start"],
7505
7574
  ["right", "end"]
7506
7575
  ]) {
7507
- const value = dxa(getW(first2(element, side) ?? first2(element, logical), "w"));
7576
+ const edge = first2(element, logical) ?? first2(element, side);
7577
+ const type = getW(edge, "type") ?? "dxa";
7578
+ const value = type === "nil" ? parseSignedTwips("0") : type === "dxa" ? parseSignedTwips(getW(edge, "w")) : void 0;
7508
7579
  if (value !== void 0) parsed[side] = value;
7509
7580
  }
7510
7581
  return Object.keys(parsed).length ? parsed : void 0;
@@ -7712,13 +7783,19 @@ function parseParagraph2(node, id) {
7712
7783
  node,
7713
7784
  (element, revision) => trackField(element, parseRun2(element, revision)),
7714
7785
  (item) => {
7786
+ const equation = parseEquation(item);
7787
+ if (equation) return [equation];
7715
7788
  if (!named2(item, "fldSimple")) return void 0;
7716
7789
  const instr = getW(item, "instr") ?? "";
7717
7790
  const link = parseSimpleHyperlinkField(instr);
7718
- const results = children2(item, "r").map((run) => parseRun2(run));
7791
+ const results = Array.from(item.childNodes).filter(isElement).flatMap((child3) => {
7792
+ const equation2 = parseEquation(child3);
7793
+ return equation2 ? [equation2] : named2(child3, "r") ? [parseRun2(child3)] : [];
7794
+ });
7719
7795
  if (link) return results.map((run) => ({ ...run, link }));
7720
7796
  const field = { instr: instr.trim(), simple: true };
7721
- if (!results.some((run) => run.text)) return [{ text: fieldPlaceholderText(instr), field }];
7797
+ if (!results.some((run) => run.text || run.equation))
7798
+ return [{ text: fieldPlaceholderText(instr), field }];
7722
7799
  return results.map((run) => ({ ...run, field }));
7723
7800
  },
7724
7801
  (hyperlink) => {
@@ -2298,6 +2298,46 @@ function orderSectionProperties(sectPr) {
2298
2298
  orderChildren(sectPr, SECTPR_ORDER);
2299
2299
  }
2300
2300
 
2301
+ // src/docx/write-table-margins.ts
2302
+ var SIDES2 = ["top", "left", "bottom", "right"];
2303
+ var ORDER = ["top", "start", "left", "bottom", "end", "right"];
2304
+ function patchMarginProperties(doc, host, propertiesTag, marginTag, propertiesOrder, next, base) {
2305
+ const changed = SIDES2.filter((side) => next?.[side] !== base?.[side]);
2306
+ if (!changed.length) return;
2307
+ for (const side of changed) {
2308
+ const value = next?.[side];
2309
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
2310
+ throw new Error("Table cell margins must be nonnegative whole twips.");
2311
+ }
2312
+ let properties = first2(host, propertiesTag);
2313
+ if (!properties) {
2314
+ properties = makeW(doc, propertiesTag);
2315
+ host.insertBefore(properties, host.firstChild);
2316
+ }
2317
+ let margins = first2(properties, marginTag);
2318
+ if (!margins) {
2319
+ margins = makeW(doc, marginTag);
2320
+ properties.appendChild(margins);
2321
+ }
2322
+ for (const side of changed) {
2323
+ const logical = side === "left" ? "start" : side === "right" ? "end" : side;
2324
+ const edge = first2(margins, logical) ?? first2(margins, side) ?? makeW(doc, side);
2325
+ for (const alias of /* @__PURE__ */ new Set([side, logical]))
2326
+ for (const old of children2(margins, alias)) margins.removeChild(old);
2327
+ const value = next?.[side];
2328
+ if (value === void 0) continue;
2329
+ edge.setAttributeNS(WORD_NS, "w:w", String(value));
2330
+ edge.setAttributeNS(WORD_NS, "w:type", "dxa");
2331
+ margins.appendChild(edge);
2332
+ }
2333
+ if (!Array.from(margins.childNodes).some((node) => node.nodeType === 1) && !margins.attributes.length)
2334
+ properties.removeChild(margins);
2335
+ else orderChildren(margins, ORDER);
2336
+ orderChildren(properties, propertiesOrder);
2337
+ if (!Array.from(properties.childNodes).some((node) => node.nodeType === 1) && !properties.attributes.length)
2338
+ host.removeChild(properties);
2339
+ }
2340
+
2301
2341
  // src/docx/write-table-properties.ts
2302
2342
  var ROW_ORDER = [
2303
2343
  "cnfStyle",
@@ -2357,26 +2397,15 @@ function patchRowProperties(doc, tr, next, base) {
2357
2397
  orderChildren(props, ROW_ORDER);
2358
2398
  }
2359
2399
  function patchTableMargins(doc, table, node, base) {
2360
- if (JSON.stringify(table.cellMargins ?? {}) === JSON.stringify(base?.cellMargins ?? {})) return;
2361
- let props = first2(node, "tblPr");
2362
- if (!props) {
2363
- props = makeW(doc, "tblPr");
2364
- node.insertBefore(props, node.firstChild);
2365
- }
2366
- let margins = first2(props, "tblCellMar");
2367
- if (!margins) {
2368
- margins = makeW(doc, "tblCellMar");
2369
- props.appendChild(margins);
2370
- }
2371
- const built = buildMargins(doc, table.cellMargins ?? {}, "tblCellMar");
2372
- for (const side of ["top", "left", "bottom", "right"]) {
2373
- if (table.cellMargins?.[side] === base?.cellMargins?.[side]) continue;
2374
- for (const old of children2(margins, side)) margins.removeChild(old);
2375
- const replacement = first2(built, side);
2376
- if (replacement) margins.appendChild(replacement);
2377
- }
2378
- orderChildren(margins, ["top", "left", "start", "bottom", "right", "end"]);
2379
- orderChildren(props, TABLE_ORDER);
2400
+ patchMarginProperties(
2401
+ doc,
2402
+ node,
2403
+ "tblPr",
2404
+ "tblCellMar",
2405
+ TABLE_ORDER,
2406
+ table.cellMargins,
2407
+ base?.cellMargins
2408
+ );
2380
2409
  }
2381
2410
  var CELL_ORDER = [
2382
2411
  "cnfStyle",
@@ -2400,6 +2429,9 @@ var CELL_ORDER = [
2400
2429
  ];
2401
2430
  var CELL_BORDER_ORDER = ["top", "start", "left", "bottom", "end", "right", "insideH", "insideV"];
2402
2431
  var CELL_SIDES = ["top", "left", "bottom", "right"];
2432
+ function patchCellMargins(doc, tc, next, base) {
2433
+ patchMarginProperties(doc, tc, "tcPr", "tcMar", CELL_ORDER, next, base);
2434
+ }
2403
2435
  function patchCellBorders(doc, tc, next, base) {
2404
2436
  const changed = CELL_SIDES.filter(
2405
2437
  (side) => JSON.stringify(next?.[side]) !== JSON.stringify(base?.[side])
@@ -2487,13 +2519,7 @@ var TABLE_DESCRIPTOR_KEYS = [
2487
2519
  "style",
2488
2520
  "look"
2489
2521
  ];
2490
- var CELL_DESCRIPTOR_KEYS = [
2491
- "gridSpan",
2492
- "verticalMerge",
2493
- "widthTwips",
2494
- "verticalAlign",
2495
- "margins"
2496
- ];
2522
+ var CELL_DESCRIPTOR_KEYS = ["gridSpan", "verticalMerge", "widthTwips", "verticalAlign"];
2497
2523
  function pick(source, keys) {
2498
2524
  const record = source;
2499
2525
  const result = {};
@@ -2519,7 +2545,7 @@ function assertNoDescriptorEdits(table, base) {
2519
2545
  if (!source) continue;
2520
2546
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
2521
2547
  throw new Error(
2522
- "Cannot edit table cell width, merge, vertical alignment, or margins on an existing cell; only cell text, borders and shading are supported. The original DOCX package remains unchanged."
2548
+ "Cannot edit table cell width, merge or vertical alignment on an existing cell; only cell text, borders, shading and margins are supported. The original DOCX package remains unchanged."
2523
2549
  );
2524
2550
  }
2525
2551
  }
@@ -2589,6 +2615,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2589
2615
  const tc = source?.cell ?? makeW(doc, "tc");
2590
2616
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
2591
2617
  patchCellShading(doc, tc, cell, source?.model);
2618
+ patchCellMargins(doc, tc, cell.margins, source?.model.margins);
2592
2619
  const oldParagraphs = children2(tc, "p");
2593
2620
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
2594
2621
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -2619,13 +2646,13 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2619
2646
  }
2620
2647
 
2621
2648
  // src/docx/page-borders.ts
2622
- var SIDES2 = ["top", "left", "bottom", "right"];
2649
+ var SIDES3 = ["top", "left", "bottom", "right"];
2623
2650
  var ATTRIBUTES = ["offsetFrom", "display", "zOrder"];
2624
2651
  var setW4 = (element, name, value) => element.setAttributeNS(WORD_NS, `w:${name}`, value);
2625
2652
  function parsePageBorders(element) {
2626
2653
  if (!element) return void 0;
2627
2654
  const result = {};
2628
- for (const side of SIDES2) {
2655
+ for (const side of SIDES3) {
2629
2656
  const source = first2(element, side);
2630
2657
  const value = borderSide(source);
2631
2658
  const art = getW(source, "art");
@@ -2663,7 +2690,7 @@ function patchPageBorders(doc, sectPr, next, base, create) {
2663
2690
  return;
2664
2691
  }
2665
2692
  const element = create(doc, sectPr, "pgBorders");
2666
- for (const side of SIDES2) {
2693
+ for (const side of SIDES3) {
2667
2694
  if (JSON.stringify(next[side]) === JSON.stringify(base?.[side])) continue;
2668
2695
  for (const old of children2(element, side)) element.removeChild(old);
2669
2696
  const value = next[side];
@@ -2988,7 +3015,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
2988
3015
  }
2989
3016
 
2990
3017
  // src/docx/write-paragraph-decoration.ts
2991
- var SIDES3 = ["top", "left", "bottom", "right", "between"];
3018
+ var SIDES4 = ["top", "left", "bottom", "right", "between"];
2992
3019
  function wordColor(color) {
2993
3020
  const hex = /^#?([0-9a-f]{6})$/i.exec(color ?? "")?.[1];
2994
3021
  return hex ? hex.toUpperCase() : "auto";
@@ -3022,7 +3049,7 @@ function updateBorders(doc, props, paragraph, base) {
3022
3049
  const borders = paragraph.borders;
3023
3050
  if (!borders) return;
3024
3051
  const pBdr = makeW(doc, "pBdr");
3025
- for (const side of SIDES3) {
3052
+ for (const side of SIDES4) {
3026
3053
  const value = borders[side];
3027
3054
  if (value) pBdr.appendChild(borderElement(doc, side, value));
3028
3055
  }
@@ -5553,6 +5580,30 @@ function createRun(doc, run, base, old, allocator) {
5553
5580
  if (!run.text) node.appendChild(makeW(doc, "t"));
5554
5581
  return node;
5555
5582
  }
5583
+ var MATH_NAMESPACES = /* @__PURE__ */ new Set([
5584
+ "http://schemas.openxmlformats.org/officeDocument/2006/math",
5585
+ "http://purl.oclc.org/ooxml/officeDocument/math"
5586
+ ]);
5587
+ function isEquationElement(element) {
5588
+ return MATH_NAMESPACES.has(element.namespaceURI ?? "") && (element.localName === "oMath" || element.localName === "oMathPara");
5589
+ }
5590
+ function parseEquation(element) {
5591
+ if (!isEquationElement(element)) return void 0;
5592
+ return {
5593
+ text: "",
5594
+ equation: {
5595
+ omml: new XMLSerializer().serializeToString(element),
5596
+ display: element.localName === "oMathPara"
5597
+ }
5598
+ };
5599
+ }
5600
+ function preserveEquation(run, base, old) {
5601
+ if (!old || !isEquationElement(old) || !base?.equation || run.text !== "" || run.equation?.omml !== base.equation.omml || run.equation?.display !== base.equation.display)
5602
+ throw new Error(
5603
+ "Equation editing or insertion is unsupported; imported OMML must remain unchanged."
5604
+ );
5605
+ return old.cloneNode(true);
5606
+ }
5556
5607
 
5557
5608
  // src/docx/breaks.ts
5558
5609
  function hasSpecialBreak(element) {
@@ -5651,10 +5702,11 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
5651
5702
  if (!isCommentReferenceRun(item)) push(parseRun3(item));
5652
5703
  } else if (named2(item, "hyperlink")) {
5653
5704
  const link = resolveLink?.(item);
5654
- for (const run of children2(item, "r")) {
5655
- const parsed = parseRun3(run);
5656
- if (link) parsed.link = link;
5657
- push(parsed);
5705
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
5706
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3)] : parseOther?.(child3) ?? []) {
5707
+ if (link) parsed.link = link;
5708
+ push(parsed);
5709
+ }
5658
5710
  }
5659
5711
  } else if ((!item.namespaceURI || item.namespaceURI === WORD_NS) && Object.hasOwn(REVISION_WRAPPERS, item.localName)) {
5660
5712
  const kind = expectDefined(
@@ -5665,7 +5717,12 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
5665
5717
  const revision = revisionFrom(item, kind);
5666
5718
  const range = kind === "moveFrom" || kind === "moveTo" ? moves[kind].at(-1) : void 0;
5667
5719
  if (range) revision.move = { name: range.name, rangeId: range.id };
5668
- for (const run of children2(item, "r")) push(parseRun3(run, revision));
5720
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
5721
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3, revision)] : parseOther?.(child3) ?? []) {
5722
+ parsed.revision = revision;
5723
+ push(parsed);
5724
+ }
5725
+ }
5669
5726
  } else if (trackMoveRange(item, moves)) {
5670
5727
  continue;
5671
5728
  } else if (named2(item, "commentRangeStart")) {
@@ -5712,7 +5769,9 @@ function runsOf(parent, container, slots) {
5712
5769
  if (child3.nodeType === 3 && child3.textContent?.trim()) return false;
5713
5770
  continue;
5714
5771
  }
5715
- if (named2(child3, "r")) {
5772
+ if (isEquationElement(child3)) {
5773
+ slots.push({ element: child3, ...container && { container } });
5774
+ } else if (named2(child3, "r")) {
5716
5775
  if (isCommentReferenceRun(child3)) continue;
5717
5776
  if (!runIsSafe(child3)) return false;
5718
5777
  slots.push({ element: child3, ...container && { container } });
@@ -5736,7 +5795,9 @@ function collectInlineSlots(paragraph) {
5736
5795
  if (child3.nodeType === 3 && child3.textContent?.trim()) return void 0;
5737
5796
  continue;
5738
5797
  }
5739
- if (named2(child3, "r")) {
5798
+ if (isEquationElement(child3)) {
5799
+ slots.push({ element: child3 });
5800
+ } else if (named2(child3, "r")) {
5740
5801
  if (isCommentReferenceRun(child3)) continue;
5741
5802
  if (!runIsSafe(child3)) return void 0;
5742
5803
  slots.push({ element: child3 });
@@ -5752,7 +5813,7 @@ function collectInlineSlots(paragraph) {
5752
5813
  }
5753
5814
  function replaceableInlineChildren(paragraph) {
5754
5815
  return Array.from(paragraph.childNodes).filter(
5755
- (child3) => isElement(child3) && (named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
5816
+ (child3) => isElement(child3) && (isEquationElement(child3) || named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
5756
5817
  );
5757
5818
  }
5758
5819
  function sameLink(a, b) {
@@ -5777,7 +5838,7 @@ function newHyperlink(doc, link, allocator) {
5777
5838
  }
5778
5839
  function runNodes(doc, run, base, old, opens, closes, allocator) {
5779
5840
  const nodes = opens.flatMap((edge) => rangeStartNodes(doc, edge));
5780
- const node = createRun(doc, run, base, old, allocator);
5841
+ const node = run.equation ? preserveEquation(run, base, old) : createRun(doc, run, base, old, allocator);
5781
5842
  const revision = run.revision;
5782
5843
  if (revision && ["insert", "delete", "moveFrom", "moveTo"].includes(revision.kind)) {
5783
5844
  if (revision.kind === "delete" || revision.kind === "moveFrom") convertToDeleteText(doc, node);
@@ -5789,15 +5850,23 @@ function runNodes(doc, run, base, old, opens, closes, allocator) {
5789
5850
  function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
5790
5851
  const { opens, closes } = rangeEdges(runs, ranges);
5791
5852
  const runAt = (at) => expectDefined(runs[at], `run ${at}`);
5792
- const nodesFor = (index2) => runNodes(
5793
- doc,
5794
- runAt(index2),
5795
- base?.[index2],
5796
- slots[index2]?.element,
5797
- opens.get(index2) ?? [],
5798
- closes.get(index2) ?? [],
5799
- allocator
5800
- );
5853
+ const nodesFor = (index2) => {
5854
+ const run = runAt(index2);
5855
+ const sourceIndex = run.equation ? base?.findIndex(
5856
+ (source2) => source2.equation?.omml === run.equation?.omml && source2.equation?.display === run.equation?.display
5857
+ ) : index2;
5858
+ const source = sourceIndex === void 0 ? void 0 : base?.[sourceIndex];
5859
+ const old = sourceIndex === void 0 ? void 0 : slots[sourceIndex]?.element;
5860
+ return runNodes(
5861
+ doc,
5862
+ run,
5863
+ !run.equation && source?.equation ? void 0 : source,
5864
+ !run.equation && old && isEquationElement(old) ? void 0 : old,
5865
+ opens.get(index2) ?? [],
5866
+ closes.get(index2) ?? [],
5867
+ allocator
5868
+ );
5869
+ };
5801
5870
  const output = [];
5802
5871
  let index = 0;
5803
5872
  while (index < runs.length) {
@@ -7498,7 +7567,9 @@ function parseMargins(element) {
7498
7567
  ["left", "start"],
7499
7568
  ["right", "end"]
7500
7569
  ]) {
7501
- const value = dxa(getW(first2(element, side) ?? first2(element, logical), "w"));
7570
+ const edge = first2(element, logical) ?? first2(element, side);
7571
+ const type = getW(edge, "type") ?? "dxa";
7572
+ const value = type === "nil" ? parseSignedTwips("0") : type === "dxa" ? parseSignedTwips(getW(edge, "w")) : void 0;
7502
7573
  if (value !== void 0) parsed[side] = value;
7503
7574
  }
7504
7575
  return Object.keys(parsed).length ? parsed : void 0;
@@ -7706,13 +7777,19 @@ function parseParagraph2(node, id) {
7706
7777
  node,
7707
7778
  (element, revision) => trackField(element, parseRun2(element, revision)),
7708
7779
  (item) => {
7780
+ const equation = parseEquation(item);
7781
+ if (equation) return [equation];
7709
7782
  if (!named2(item, "fldSimple")) return void 0;
7710
7783
  const instr = getW(item, "instr") ?? "";
7711
7784
  const link = parseSimpleHyperlinkField(instr);
7712
- const results = children2(item, "r").map((run) => parseRun2(run));
7785
+ const results = Array.from(item.childNodes).filter(isElement).flatMap((child3) => {
7786
+ const equation2 = parseEquation(child3);
7787
+ return equation2 ? [equation2] : named2(child3, "r") ? [parseRun2(child3)] : [];
7788
+ });
7713
7789
  if (link) return results.map((run) => ({ ...run, link }));
7714
7790
  const field = { instr: instr.trim(), simple: true };
7715
- if (!results.some((run) => run.text)) return [{ text: fieldPlaceholderText(instr), field }];
7791
+ if (!results.some((run) => run.text || run.equation))
7792
+ return [{ text: fieldPlaceholderText(instr), field }];
7716
7793
  return results.map((run) => ({ ...run, field }));
7717
7794
  },
7718
7795
  (hyperlink) => {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/docx/layout/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,aAAa,EAKb,MAAM,aAAa,CAAC;AAmBrB,OAAO,KAAK,EAEX,mBAAmB,EAMnB,MAAM,YAAY,CAAC;AAyBpB,oFAAoF;AACpF,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GACxC,mBAAmB,CA2PrB"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/docx/layout/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,aAAa,EAKb,MAAM,aAAa,CAAC;AAmBrB,OAAO,KAAK,EAEX,mBAAmB,EAMnB,MAAM,YAAY,CAAC;AA2BpB,oFAAoF;AACpF,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GACxC,mBAAmB,CA8PrB"}