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
@@ -2149,6 +2149,7 @@ var TABLE_ROW_NOTE = "Table rows with an exact height clip content that does not
2149
2149
  var VERTICAL_MERGE_NOTE = "Vertically merged table cells are drawn as one cell, but their text stays in the first row of the merge.";
2150
2150
  var DROP_CAP_NOTE = "Drop caps are laid out as an enlarged first letter (a raised cap), not as a dropped cap.";
2151
2151
  var TEXT_BOX_NOTE = "Text boxes are shown on the editing surface but are not drawn in Print Layout.";
2152
+ var EQUATION_NOTE = "Equations display on the editing surface; Print Layout shows markers rather than typeset equations.";
2152
2153
  var NEXT_COLUMN_NOTE = 'A "next column" section break is laid out as a continuous section break.';
2153
2154
  var twipsToPx3 = twipsToPixels;
2154
2155
  function sectionBreak(type, note) {
@@ -2184,9 +2185,10 @@ function adaptDocumentModel(model, note = () => {
2184
2185
  const noteLabel = noteLabels(model);
2185
2186
  function adaptRun(run, paragraphStyleId, markLabel) {
2186
2187
  const { formatting, family, color } = effective(run, paragraphStyleId);
2188
+ if (run.equation) reportOnce(EQUATION_NOTE);
2187
2189
  const name = run.field ? fieldName(run.field.instr) : "";
2188
2190
  const noteText = run.noteReference ? noteLabel(run.noteReference.kind, run.noteReference.id) : run.noteMark ? markLabel ?? "" : void 0;
2189
- const text = noteText ?? (run.field && (name === "DATE" || name === "TIME") ? dateFieldResult(name, run.field.instr, now) : run.text);
2191
+ const text = noteText ?? (run.field && (name === "DATE" || name === "TIME") ? dateFieldResult(name, run.field.instr, now) : run.equation ? "[Equation]" : run.text);
2190
2192
  const script = formatting.verticalAlign === "superscript" || noteText !== void 0 && formatting.verticalAlign === void 0 ? "super" : formatting.verticalAlign === "subscript" ? "sub" : void 0;
2191
2193
  const image = run.image;
2192
2194
  if (image?.unsupported === "Text box") reportOnce(TEXT_BOX_NOTE);
@@ -2147,6 +2147,7 @@ var TABLE_ROW_NOTE = "Table rows with an exact height clip content that does not
2147
2147
  var VERTICAL_MERGE_NOTE = "Vertically merged table cells are drawn as one cell, but their text stays in the first row of the merge.";
2148
2148
  var DROP_CAP_NOTE = "Drop caps are laid out as an enlarged first letter (a raised cap), not as a dropped cap.";
2149
2149
  var TEXT_BOX_NOTE = "Text boxes are shown on the editing surface but are not drawn in Print Layout.";
2150
+ var EQUATION_NOTE = "Equations display on the editing surface; Print Layout shows markers rather than typeset equations.";
2150
2151
  var NEXT_COLUMN_NOTE = 'A "next column" section break is laid out as a continuous section break.';
2151
2152
  var twipsToPx3 = twipsToPixels;
2152
2153
  function sectionBreak(type, note) {
@@ -2182,9 +2183,10 @@ function adaptDocumentModel(model, note = () => {
2182
2183
  const noteLabel = noteLabels(model);
2183
2184
  function adaptRun(run, paragraphStyleId, markLabel) {
2184
2185
  const { formatting, family, color } = effective(run, paragraphStyleId);
2186
+ if (run.equation) reportOnce(EQUATION_NOTE);
2185
2187
  const name = run.field ? fieldName(run.field.instr) : "";
2186
2188
  const noteText = run.noteReference ? noteLabel(run.noteReference.kind, run.noteReference.id) : run.noteMark ? markLabel ?? "" : void 0;
2187
- const text = noteText ?? (run.field && (name === "DATE" || name === "TIME") ? dateFieldResult(name, run.field.instr, now) : run.text);
2189
+ const text = noteText ?? (run.field && (name === "DATE" || name === "TIME") ? dateFieldResult(name, run.field.instr, now) : run.equation ? "[Equation]" : run.text);
2188
2190
  const script = formatting.verticalAlign === "superscript" || noteText !== void 0 && formatting.verticalAlign === void 0 ? "super" : formatting.verticalAlign === "subscript" ? "sub" : void 0;
2189
2191
  const image = run.image;
2190
2192
  if (image?.unsupported === "Text box") reportOnce(TEXT_BOX_NOTE);
@@ -905,6 +905,46 @@ function orderSectionProperties(sectPr) {
905
905
  orderChildren(sectPr, SECTPR_ORDER);
906
906
  }
907
907
 
908
+ // src/docx/write-table-margins.ts
909
+ var SIDES = ["top", "left", "bottom", "right"];
910
+ var ORDER = ["top", "start", "left", "bottom", "end", "right"];
911
+ function patchMarginProperties(doc, host, propertiesTag, marginTag, propertiesOrder, next, base) {
912
+ const changed = SIDES.filter((side) => next?.[side] !== base?.[side]);
913
+ if (!changed.length) return;
914
+ for (const side of changed) {
915
+ const value = next?.[side];
916
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
917
+ throw new Error("Table cell margins must be nonnegative whole twips.");
918
+ }
919
+ let properties = first2(host, propertiesTag);
920
+ if (!properties) {
921
+ properties = makeW(doc, propertiesTag);
922
+ host.insertBefore(properties, host.firstChild);
923
+ }
924
+ let margins = first2(properties, marginTag);
925
+ if (!margins) {
926
+ margins = makeW(doc, marginTag);
927
+ properties.appendChild(margins);
928
+ }
929
+ for (const side of changed) {
930
+ const logical = side === "left" ? "start" : side === "right" ? "end" : side;
931
+ const edge = first2(margins, logical) ?? first2(margins, side) ?? makeW(doc, side);
932
+ for (const alias of /* @__PURE__ */ new Set([side, logical]))
933
+ for (const old of children2(margins, alias)) margins.removeChild(old);
934
+ const value = next?.[side];
935
+ if (value === void 0) continue;
936
+ edge.setAttributeNS(WORD_NS, "w:w", String(value));
937
+ edge.setAttributeNS(WORD_NS, "w:type", "dxa");
938
+ margins.appendChild(edge);
939
+ }
940
+ if (!Array.from(margins.childNodes).some((node) => node.nodeType === 1) && !margins.attributes.length)
941
+ properties.removeChild(margins);
942
+ else orderChildren(margins, ORDER);
943
+ orderChildren(properties, propertiesOrder);
944
+ if (!Array.from(properties.childNodes).some((node) => node.nodeType === 1) && !properties.attributes.length)
945
+ host.removeChild(properties);
946
+ }
947
+
908
948
  // src/docx/write-table-properties.ts
909
949
  var ROW_ORDER = [
910
950
  "cnfStyle",
@@ -964,26 +1004,15 @@ function patchRowProperties(doc, tr, next, base) {
964
1004
  orderChildren(props, ROW_ORDER);
965
1005
  }
966
1006
  function patchTableMargins(doc, table, node, base) {
967
- if (JSON.stringify(table.cellMargins ?? {}) === JSON.stringify(base?.cellMargins ?? {})) return;
968
- let props = first2(node, "tblPr");
969
- if (!props) {
970
- props = makeW(doc, "tblPr");
971
- node.insertBefore(props, node.firstChild);
972
- }
973
- let margins = first2(props, "tblCellMar");
974
- if (!margins) {
975
- margins = makeW(doc, "tblCellMar");
976
- props.appendChild(margins);
977
- }
978
- const built = buildMargins(doc, table.cellMargins ?? {}, "tblCellMar");
979
- for (const side of ["top", "left", "bottom", "right"]) {
980
- if (table.cellMargins?.[side] === base?.cellMargins?.[side]) continue;
981
- for (const old of children2(margins, side)) margins.removeChild(old);
982
- const replacement = first2(built, side);
983
- if (replacement) margins.appendChild(replacement);
984
- }
985
- orderChildren(margins, ["top", "left", "start", "bottom", "right", "end"]);
986
- orderChildren(props, TABLE_ORDER);
1007
+ patchMarginProperties(
1008
+ doc,
1009
+ node,
1010
+ "tblPr",
1011
+ "tblCellMar",
1012
+ TABLE_ORDER,
1013
+ table.cellMargins,
1014
+ base?.cellMargins
1015
+ );
987
1016
  }
988
1017
  var CELL_ORDER = [
989
1018
  "cnfStyle",
@@ -1007,6 +1036,9 @@ var CELL_ORDER = [
1007
1036
  ];
1008
1037
  var CELL_BORDER_ORDER = ["top", "start", "left", "bottom", "end", "right", "insideH", "insideV"];
1009
1038
  var CELL_SIDES = ["top", "left", "bottom", "right"];
1039
+ function patchCellMargins(doc, tc, next, base) {
1040
+ patchMarginProperties(doc, tc, "tcPr", "tcMar", CELL_ORDER, next, base);
1041
+ }
1010
1042
  function patchCellBorders(doc, tc, next, base) {
1011
1043
  const changed = CELL_SIDES.filter(
1012
1044
  (side) => JSON.stringify(next?.[side]) !== JSON.stringify(base?.[side])
@@ -1094,13 +1126,7 @@ var TABLE_DESCRIPTOR_KEYS = [
1094
1126
  "style",
1095
1127
  "look"
1096
1128
  ];
1097
- var CELL_DESCRIPTOR_KEYS = [
1098
- "gridSpan",
1099
- "verticalMerge",
1100
- "widthTwips",
1101
- "verticalAlign",
1102
- "margins"
1103
- ];
1129
+ var CELL_DESCRIPTOR_KEYS = ["gridSpan", "verticalMerge", "widthTwips", "verticalAlign"];
1104
1130
  function pick(source, keys) {
1105
1131
  const record = source;
1106
1132
  const result = {};
@@ -1126,7 +1152,7 @@ function assertNoDescriptorEdits(table, base) {
1126
1152
  if (!source) continue;
1127
1153
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1128
1154
  throw new Error(
1129
- "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."
1155
+ "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."
1130
1156
  );
1131
1157
  }
1132
1158
  }
@@ -1196,6 +1222,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1196
1222
  const tc = source?.cell ?? makeW(doc, "tc");
1197
1223
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1198
1224
  patchCellShading(doc, tc, cell, source?.model);
1225
+ patchCellMargins(doc, tc, cell.margins, source?.model.margins);
1199
1226
  const oldParagraphs = children2(tc, "p");
1200
1227
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1201
1228
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -1338,7 +1365,7 @@ function parseTintShade(value) {
1338
1365
  }
1339
1366
 
1340
1367
  // src/docx/table-borders.ts
1341
- var SIDES = [
1368
+ var SIDES2 = [
1342
1369
  "top",
1343
1370
  "bottom",
1344
1371
  "left",
@@ -1364,7 +1391,7 @@ function parseTableBorders(bordersElement) {
1364
1391
  if (!bordersElement) return void 0;
1365
1392
  const result = {};
1366
1393
  const alias = { left: "start", right: "end" };
1367
- for (const side of SIDES) {
1394
+ for (const side of SIDES2) {
1368
1395
  const aliasName = alias[side];
1369
1396
  const value = borderSide(
1370
1397
  first2(bordersElement, side) ?? (aliasName ? first2(bordersElement, aliasName) : void 0)
@@ -1401,13 +1428,13 @@ function parseParagraphBorders(pBdr) {
1401
1428
  }
1402
1429
 
1403
1430
  // src/docx/page-borders.ts
1404
- var SIDES2 = ["top", "left", "bottom", "right"];
1431
+ var SIDES3 = ["top", "left", "bottom", "right"];
1405
1432
  var ATTRIBUTES = ["offsetFrom", "display", "zOrder"];
1406
1433
  var setW4 = (element, name, value) => element.setAttributeNS(WORD_NS, `w:${name}`, value);
1407
1434
  function parsePageBorders(element) {
1408
1435
  if (!element) return void 0;
1409
1436
  const result = {};
1410
- for (const side of SIDES2) {
1437
+ for (const side of SIDES3) {
1411
1438
  const source = first2(element, side);
1412
1439
  const value = borderSide(source);
1413
1440
  const art = getW(source, "art");
@@ -1445,7 +1472,7 @@ function patchPageBorders(doc, sectPr, next, base, create) {
1445
1472
  return;
1446
1473
  }
1447
1474
  const element = create(doc, sectPr, "pgBorders");
1448
- for (const side of SIDES2) {
1475
+ for (const side of SIDES3) {
1449
1476
  if (JSON.stringify(next[side]) === JSON.stringify(base?.[side])) continue;
1450
1477
  for (const old of children2(element, side)) element.removeChild(old);
1451
1478
  const value = next[side];
@@ -1770,7 +1797,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
1770
1797
  }
1771
1798
 
1772
1799
  // src/docx/write-paragraph-decoration.ts
1773
- var SIDES3 = ["top", "left", "bottom", "right", "between"];
1800
+ var SIDES4 = ["top", "left", "bottom", "right", "between"];
1774
1801
  function wordColor(color) {
1775
1802
  const hex = /^#?([0-9a-f]{6})$/i.exec(color ?? "")?.[1];
1776
1803
  return hex ? hex.toUpperCase() : "auto";
@@ -1804,7 +1831,7 @@ function updateBorders(doc, props, paragraph, base) {
1804
1831
  const borders = paragraph.borders;
1805
1832
  if (!borders) return;
1806
1833
  const pBdr = makeW(doc, "pBdr");
1807
- for (const side of SIDES3) {
1834
+ for (const side of SIDES4) {
1808
1835
  const value = borders[side];
1809
1836
  if (value) pBdr.appendChild(borderElement(doc, side, value));
1810
1837
  }
@@ -4235,6 +4262,30 @@ function createRun(doc, run, base, old, allocator) {
4235
4262
  if (!run.text) node.appendChild(makeW(doc, "t"));
4236
4263
  return node;
4237
4264
  }
4265
+ var MATH_NAMESPACES = /* @__PURE__ */ new Set([
4266
+ "http://schemas.openxmlformats.org/officeDocument/2006/math",
4267
+ "http://purl.oclc.org/ooxml/officeDocument/math"
4268
+ ]);
4269
+ function isEquationElement(element) {
4270
+ return MATH_NAMESPACES.has(element.namespaceURI ?? "") && (element.localName === "oMath" || element.localName === "oMathPara");
4271
+ }
4272
+ function parseEquation(element) {
4273
+ if (!isEquationElement(element)) return void 0;
4274
+ return {
4275
+ text: "",
4276
+ equation: {
4277
+ omml: new xmldom.XMLSerializer().serializeToString(element),
4278
+ display: element.localName === "oMathPara"
4279
+ }
4280
+ };
4281
+ }
4282
+ function preserveEquation(run, base, old) {
4283
+ if (!old || !isEquationElement(old) || !base?.equation || run.text !== "" || run.equation?.omml !== base.equation.omml || run.equation?.display !== base.equation.display)
4284
+ throw new Error(
4285
+ "Equation editing or insertion is unsupported; imported OMML must remain unchanged."
4286
+ );
4287
+ return old.cloneNode(true);
4288
+ }
4238
4289
 
4239
4290
  // src/docx/breaks.ts
4240
4291
  function hasSpecialBreak(element) {
@@ -4333,10 +4384,11 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
4333
4384
  if (!isCommentReferenceRun(item)) push(parseRun3(item));
4334
4385
  } else if (named2(item, "hyperlink")) {
4335
4386
  const link = resolveLink?.(item);
4336
- for (const run of children2(item, "r")) {
4337
- const parsed = parseRun3(run);
4338
- if (link) parsed.link = link;
4339
- push(parsed);
4387
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
4388
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3)] : parseOther?.(child3) ?? []) {
4389
+ if (link) parsed.link = link;
4390
+ push(parsed);
4391
+ }
4340
4392
  }
4341
4393
  } else if ((!item.namespaceURI || item.namespaceURI === WORD_NS) && Object.hasOwn(REVISION_WRAPPERS, item.localName)) {
4342
4394
  const kind = expectDefined(
@@ -4347,7 +4399,12 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
4347
4399
  const revision = revisionFrom(item, kind);
4348
4400
  const range = kind === "moveFrom" || kind === "moveTo" ? moves[kind].at(-1) : void 0;
4349
4401
  if (range) revision.move = { name: range.name, rangeId: range.id };
4350
- for (const run of children2(item, "r")) push(parseRun3(run, revision));
4402
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
4403
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3, revision)] : parseOther?.(child3) ?? []) {
4404
+ parsed.revision = revision;
4405
+ push(parsed);
4406
+ }
4407
+ }
4351
4408
  } else if (trackMoveRange(item, moves)) {
4352
4409
  continue;
4353
4410
  } else if (named2(item, "commentRangeStart")) {
@@ -4394,7 +4451,9 @@ function runsOf(parent, container, slots) {
4394
4451
  if (child3.nodeType === 3 && child3.textContent?.trim()) return false;
4395
4452
  continue;
4396
4453
  }
4397
- if (named2(child3, "r")) {
4454
+ if (isEquationElement(child3)) {
4455
+ slots.push({ element: child3, ...container && { container } });
4456
+ } else if (named2(child3, "r")) {
4398
4457
  if (isCommentReferenceRun(child3)) continue;
4399
4458
  if (!runIsSafe(child3)) return false;
4400
4459
  slots.push({ element: child3, ...container && { container } });
@@ -4418,7 +4477,9 @@ function collectInlineSlots(paragraph) {
4418
4477
  if (child3.nodeType === 3 && child3.textContent?.trim()) return void 0;
4419
4478
  continue;
4420
4479
  }
4421
- if (named2(child3, "r")) {
4480
+ if (isEquationElement(child3)) {
4481
+ slots.push({ element: child3 });
4482
+ } else if (named2(child3, "r")) {
4422
4483
  if (isCommentReferenceRun(child3)) continue;
4423
4484
  if (!runIsSafe(child3)) return void 0;
4424
4485
  slots.push({ element: child3 });
@@ -4434,7 +4495,7 @@ function collectInlineSlots(paragraph) {
4434
4495
  }
4435
4496
  function replaceableInlineChildren(paragraph) {
4436
4497
  return Array.from(paragraph.childNodes).filter(
4437
- (child3) => isElement(child3) && (named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
4498
+ (child3) => isElement(child3) && (isEquationElement(child3) || named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
4438
4499
  );
4439
4500
  }
4440
4501
  function sameLink(a, b) {
@@ -4459,7 +4520,7 @@ function newHyperlink(doc, link, allocator) {
4459
4520
  }
4460
4521
  function runNodes(doc, run, base, old, opens, closes, allocator) {
4461
4522
  const nodes = opens.flatMap((edge) => rangeStartNodes(doc, edge));
4462
- const node = createRun(doc, run, base, old, allocator);
4523
+ const node = run.equation ? preserveEquation(run, base, old) : createRun(doc, run, base, old, allocator);
4463
4524
  const revision = run.revision;
4464
4525
  if (revision && ["insert", "delete", "moveFrom", "moveTo"].includes(revision.kind)) {
4465
4526
  if (revision.kind === "delete" || revision.kind === "moveFrom") convertToDeleteText(doc, node);
@@ -4471,15 +4532,23 @@ function runNodes(doc, run, base, old, opens, closes, allocator) {
4471
4532
  function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
4472
4533
  const { opens, closes } = rangeEdges(runs, ranges);
4473
4534
  const runAt = (at) => expectDefined(runs[at], `run ${at}`);
4474
- const nodesFor = (index2) => runNodes(
4475
- doc,
4476
- runAt(index2),
4477
- base?.[index2],
4478
- slots[index2]?.element,
4479
- opens.get(index2) ?? [],
4480
- closes.get(index2) ?? [],
4481
- allocator
4482
- );
4535
+ const nodesFor = (index2) => {
4536
+ const run = runAt(index2);
4537
+ const sourceIndex = run.equation ? base?.findIndex(
4538
+ (source2) => source2.equation?.omml === run.equation?.omml && source2.equation?.display === run.equation?.display
4539
+ ) : index2;
4540
+ const source = sourceIndex === void 0 ? void 0 : base?.[sourceIndex];
4541
+ const old = sourceIndex === void 0 ? void 0 : slots[sourceIndex]?.element;
4542
+ return runNodes(
4543
+ doc,
4544
+ run,
4545
+ !run.equation && source?.equation ? void 0 : source,
4546
+ !run.equation && old && isEquationElement(old) ? void 0 : old,
4547
+ opens.get(index2) ?? [],
4548
+ closes.get(index2) ?? [],
4549
+ allocator
4550
+ );
4551
+ };
4483
4552
  const output = [];
4484
4553
  let index = 0;
4485
4554
  while (index < runs.length) {
@@ -6526,7 +6595,9 @@ function parseMargins(element) {
6526
6595
  ["left", "start"],
6527
6596
  ["right", "end"]
6528
6597
  ]) {
6529
- const value = dxa(getW(first2(element, side) ?? first2(element, logical), "w"));
6598
+ const edge = first2(element, logical) ?? first2(element, side);
6599
+ const type = getW(edge, "type") ?? "dxa";
6600
+ const value = type === "nil" ? parseSignedTwips("0") : type === "dxa" ? parseSignedTwips(getW(edge, "w")) : void 0;
6530
6601
  if (value !== void 0) parsed[side] = value;
6531
6602
  }
6532
6603
  return Object.keys(parsed).length ? parsed : void 0;
@@ -6731,13 +6802,19 @@ function parseParagraph2(node, id) {
6731
6802
  node,
6732
6803
  (element, revision) => trackField(element, parseRun2(element, revision)),
6733
6804
  (item) => {
6805
+ const equation = parseEquation(item);
6806
+ if (equation) return [equation];
6734
6807
  if (!named2(item, "fldSimple")) return void 0;
6735
6808
  const instr = getW(item, "instr") ?? "";
6736
6809
  const link = parseSimpleHyperlinkField(instr);
6737
- const results = children2(item, "r").map((run) => parseRun2(run));
6810
+ const results = Array.from(item.childNodes).filter(isElement).flatMap((child3) => {
6811
+ const equation2 = parseEquation(child3);
6812
+ return equation2 ? [equation2] : named2(child3, "r") ? [parseRun2(child3)] : [];
6813
+ });
6738
6814
  if (link) return results.map((run) => ({ ...run, link }));
6739
6815
  const field = { instr: instr.trim(), simple: true };
6740
- if (!results.some((run) => run.text)) return [{ text: fieldPlaceholderText(instr), field }];
6816
+ if (!results.some((run) => run.text || run.equation))
6817
+ return [{ text: fieldPlaceholderText(instr), field }];
6741
6818
  return results.map((run) => ({ ...run, field }));
6742
6819
  },
6743
6820
  (hyperlink) => {