ooxml-core 0.4.0 → 0.6.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 (104) hide show
  1. package/NOTICE +2 -0
  2. package/README.md +1 -0
  3. package/dist/digest/algorithm-names.d.ts +20 -0
  4. package/dist/digest/algorithm-names.d.ts.map +1 -0
  5. package/dist/digest/base64.d.ts +8 -0
  6. package/dist/digest/base64.d.ts.map +1 -0
  7. package/dist/digest/digest.d.ts +13 -0
  8. package/dist/digest/digest.d.ts.map +1 -0
  9. package/dist/digest/index.cjs +594 -0
  10. package/dist/digest/index.d.ts +8 -0
  11. package/dist/digest/index.d.ts.map +1 -0
  12. package/dist/digest/index.mjs +581 -0
  13. package/dist/digest/password-hash.d.ts +30 -0
  14. package/dist/digest/password-hash.d.ts.map +1 -0
  15. package/dist/digest/sha1.d.ts +3 -0
  16. package/dist/digest/sha1.d.ts.map +1 -0
  17. package/dist/digest/sha256.d.ts +10 -0
  18. package/dist/digest/sha256.d.ts.map +1 -0
  19. package/dist/digest/sha512.d.ts +5 -0
  20. package/dist/digest/sha512.d.ts.map +1 -0
  21. package/dist/docx/block-parser.d.ts.map +1 -1
  22. package/dist/docx/embedded.cjs +153 -59
  23. package/dist/docx/embedded.mjs +153 -59
  24. package/dist/docx/equation.d.ts +8 -0
  25. package/dist/docx/equation.d.ts.map +1 -0
  26. package/dist/docx/index.cjs +153 -59
  27. package/dist/docx/index.mjs +153 -59
  28. package/dist/docx/layout/adapter.d.ts.map +1 -1
  29. package/dist/docx/layout/index.cjs +3 -1
  30. package/dist/docx/layout/index.mjs +3 -1
  31. package/dist/docx/load/index.cjs +155 -61
  32. package/dist/docx/load/index.mjs +155 -61
  33. package/dist/docx/model-run.d.ts +5 -0
  34. package/dist/docx/model-run.d.ts.map +1 -1
  35. package/dist/docx/parse-revisions.d.ts.map +1 -1
  36. package/dist/docx/parse-table.d.ts.map +1 -1
  37. package/dist/docx/write-inline.d.ts.map +1 -1
  38. package/dist/docx/write-table-margins.d.ts +5 -0
  39. package/dist/docx/write-table-margins.d.ts.map +1 -0
  40. package/dist/docx/write-table-properties.d.ts +6 -2
  41. package/dist/docx/write-table-properties.d.ts.map +1 -1
  42. package/dist/docx/write-table.d.ts.map +1 -1
  43. package/dist/index.cjs +2640 -13
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.mjs +2639 -14
  47. package/dist/math/index.cjs +2050 -0
  48. package/dist/math/index.d.ts +15 -0
  49. package/dist/math/index.d.ts.map +1 -0
  50. package/dist/math/index.mjs +1985 -0
  51. package/dist/math/latex-omml-siblings.d.ts +21 -0
  52. package/dist/math/latex-omml-siblings.d.ts.map +1 -0
  53. package/dist/math/latex-omml-symbols.d.ts +42 -0
  54. package/dist/math/latex-omml-symbols.d.ts.map +1 -0
  55. package/dist/math/latex-to-omml-commands.d.ts +9 -0
  56. package/dist/math/latex-to-omml-commands.d.ts.map +1 -0
  57. package/dist/math/latex-to-omml-constructs.d.ts +39 -0
  58. package/dist/math/latex-to-omml-constructs.d.ts.map +1 -0
  59. package/dist/math/latex-to-omml-environments.d.ts +28 -0
  60. package/dist/math/latex-to-omml-environments.d.ts.map +1 -0
  61. package/dist/math/latex-to-omml.d.ts +9 -0
  62. package/dist/math/latex-to-omml.d.ts.map +1 -0
  63. package/dist/math/omml-color.d.ts +11 -0
  64. package/dist/math/omml-color.d.ts.map +1 -0
  65. package/dist/math/omml-dom.d.ts +7 -0
  66. package/dist/math/omml-dom.d.ts.map +1 -0
  67. package/dist/math/omml-mathml-converters.d.ts +39 -0
  68. package/dist/math/omml-mathml-converters.d.ts.map +1 -0
  69. package/dist/math/omml-mathml-helpers.d.ts +23 -0
  70. package/dist/math/omml-mathml-helpers.d.ts.map +1 -0
  71. package/dist/math/omml-node.d.ts +7 -0
  72. package/dist/math/omml-node.d.ts.map +1 -0
  73. package/dist/math/omml-to-latex-helpers.d.ts +41 -0
  74. package/dist/math/omml-to-latex-helpers.d.ts.map +1 -0
  75. package/dist/math/omml-to-latex-layout.d.ts +18 -0
  76. package/dist/math/omml-to-latex-layout.d.ts.map +1 -0
  77. package/dist/math/omml-to-latex.d.ts +6 -0
  78. package/dist/math/omml-to-latex.d.ts.map +1 -0
  79. package/dist/math/omml-to-mathml.d.ts +21 -0
  80. package/dist/math/omml-to-mathml.d.ts.map +1 -0
  81. package/dist/xlsx/edit/history.d.ts +1 -1
  82. package/dist/xlsx/edit/history.d.ts.map +1 -1
  83. package/dist/xlsx/edit/index.d.ts +1 -1
  84. package/dist/xlsx/edit/index.d.ts.map +1 -1
  85. package/dist/xlsx/edit/protection.d.ts +18 -6
  86. package/dist/xlsx/edit/protection.d.ts.map +1 -1
  87. package/dist/xlsx/edit/types.d.ts +2 -2
  88. package/dist/xlsx/index.cjs +671 -28
  89. package/dist/xlsx/index.mjs +670 -29
  90. package/dist/xlsx/load/index.cjs +56 -19
  91. package/dist/xlsx/load/index.mjs +56 -19
  92. package/dist/xlsx/model.d.ts +21 -0
  93. package/dist/xlsx/model.d.ts.map +1 -1
  94. package/dist/xlsx/read/load.d.ts.map +1 -1
  95. package/dist/xlsx/read/password-hash.d.ts +15 -0
  96. package/dist/xlsx/read/password-hash.d.ts.map +1 -0
  97. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  98. package/dist/xlsx/read/workbook-part.d.ts +3 -1
  99. package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
  100. package/dist/xlsx/write/password-hash.d.ts +8 -0
  101. package/dist/xlsx/write/password-hash.d.ts.map +1 -0
  102. package/dist/xlsx/write/sheet-props.d.ts.map +1 -1
  103. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  104. package/package.json +11 -1
@@ -1653,6 +1653,46 @@ function orderSectionProperties(sectPr) {
1653
1653
  orderChildren(sectPr, SECTPR_ORDER);
1654
1654
  }
1655
1655
 
1656
+ // src/docx/write-table-margins.ts
1657
+ var SIDES2 = ["top", "left", "bottom", "right"];
1658
+ var ORDER = ["top", "start", "left", "bottom", "end", "right"];
1659
+ function patchMarginProperties(doc, host, propertiesTag, marginTag, propertiesOrder, next, base) {
1660
+ const changed = SIDES2.filter((side) => next?.[side] !== base?.[side]);
1661
+ if (!changed.length) return;
1662
+ for (const side of changed) {
1663
+ const value = next?.[side];
1664
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
1665
+ throw new Error("Table cell margins must be nonnegative whole twips.");
1666
+ }
1667
+ let properties = first2(host, propertiesTag);
1668
+ if (!properties) {
1669
+ properties = makeW(doc, propertiesTag);
1670
+ host.insertBefore(properties, host.firstChild);
1671
+ }
1672
+ let margins = first2(properties, marginTag);
1673
+ if (!margins) {
1674
+ margins = makeW(doc, marginTag);
1675
+ properties.appendChild(margins);
1676
+ }
1677
+ for (const side of changed) {
1678
+ const logical = side === "left" ? "start" : side === "right" ? "end" : side;
1679
+ const edge = first2(margins, logical) ?? first2(margins, side) ?? makeW(doc, side);
1680
+ for (const alias of /* @__PURE__ */ new Set([side, logical]))
1681
+ for (const old of children2(margins, alias)) margins.removeChild(old);
1682
+ const value = next?.[side];
1683
+ if (value === void 0) continue;
1684
+ edge.setAttributeNS(WORD_NS, "w:w", String(value));
1685
+ edge.setAttributeNS(WORD_NS, "w:type", "dxa");
1686
+ margins.appendChild(edge);
1687
+ }
1688
+ if (!Array.from(margins.childNodes).some((node) => node.nodeType === 1) && !margins.attributes.length)
1689
+ properties.removeChild(margins);
1690
+ else orderChildren(margins, ORDER);
1691
+ orderChildren(properties, propertiesOrder);
1692
+ if (!Array.from(properties.childNodes).some((node) => node.nodeType === 1) && !properties.attributes.length)
1693
+ host.removeChild(properties);
1694
+ }
1695
+
1656
1696
  // src/docx/write-table-properties.ts
1657
1697
  var ROW_ORDER = [
1658
1698
  "cnfStyle",
@@ -1712,26 +1752,15 @@ function patchRowProperties(doc, tr, next, base) {
1712
1752
  orderChildren(props, ROW_ORDER);
1713
1753
  }
1714
1754
  function patchTableMargins(doc, table, node, base) {
1715
- if (JSON.stringify(table.cellMargins ?? {}) === JSON.stringify(base?.cellMargins ?? {})) return;
1716
- let props = first2(node, "tblPr");
1717
- if (!props) {
1718
- props = makeW(doc, "tblPr");
1719
- node.insertBefore(props, node.firstChild);
1720
- }
1721
- let margins = first2(props, "tblCellMar");
1722
- if (!margins) {
1723
- margins = makeW(doc, "tblCellMar");
1724
- props.appendChild(margins);
1725
- }
1726
- const built = buildMargins(doc, table.cellMargins ?? {}, "tblCellMar");
1727
- for (const side of ["top", "left", "bottom", "right"]) {
1728
- if (table.cellMargins?.[side] === base?.cellMargins?.[side]) continue;
1729
- for (const old of children2(margins, side)) margins.removeChild(old);
1730
- const replacement = first2(built, side);
1731
- if (replacement) margins.appendChild(replacement);
1732
- }
1733
- orderChildren(margins, ["top", "left", "start", "bottom", "right", "end"]);
1734
- orderChildren(props, TABLE_ORDER);
1755
+ patchMarginProperties(
1756
+ doc,
1757
+ node,
1758
+ "tblPr",
1759
+ "tblCellMar",
1760
+ TABLE_ORDER,
1761
+ table.cellMargins,
1762
+ base?.cellMargins
1763
+ );
1735
1764
  }
1736
1765
  var CELL_ORDER = [
1737
1766
  "cnfStyle",
@@ -1755,6 +1784,9 @@ var CELL_ORDER = [
1755
1784
  ];
1756
1785
  var CELL_BORDER_ORDER = ["top", "start", "left", "bottom", "end", "right", "insideH", "insideV"];
1757
1786
  var CELL_SIDES = ["top", "left", "bottom", "right"];
1787
+ function patchCellMargins(doc, tc, next, base) {
1788
+ patchMarginProperties(doc, tc, "tcPr", "tcMar", CELL_ORDER, next, base);
1789
+ }
1758
1790
  function patchCellBorders(doc, tc, next, base) {
1759
1791
  const changed = CELL_SIDES.filter(
1760
1792
  (side) => JSON.stringify(next?.[side]) !== JSON.stringify(base?.[side])
@@ -1782,6 +1814,23 @@ function patchCellBorders(doc, tc, next, base) {
1782
1814
  orderChildren(props, CELL_ORDER);
1783
1815
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1784
1816
  }
1817
+ function patchCellShading(doc, tc, next, base) {
1818
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
1819
+ return;
1820
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
1821
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
1822
+ let props = first2(tc, "tcPr");
1823
+ if (!props) {
1824
+ props = makeW(doc, "tcPr");
1825
+ tc.insertBefore(props, tc.firstChild);
1826
+ }
1827
+ for (const old of children2(props, "shd")) props.removeChild(old);
1828
+ const built = buildCellProperties(doc, next);
1829
+ const replacement = built && first2(built, "shd");
1830
+ if (replacement) props.appendChild(replacement);
1831
+ orderChildren(props, CELL_ORDER);
1832
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1833
+ }
1785
1834
 
1786
1835
  // src/docx/write-table.ts
1787
1836
  function canEditTableStructure(table) {
@@ -1825,15 +1874,7 @@ var TABLE_DESCRIPTOR_KEYS = [
1825
1874
  "style",
1826
1875
  "look"
1827
1876
  ];
1828
- var CELL_DESCRIPTOR_KEYS = [
1829
- "gridSpan",
1830
- "verticalMerge",
1831
- "widthTwips",
1832
- "verticalAlign",
1833
- "shadingFill",
1834
- "shadingThemeFill",
1835
- "margins"
1836
- ];
1877
+ var CELL_DESCRIPTOR_KEYS = ["gridSpan", "verticalMerge", "widthTwips", "verticalAlign"];
1837
1878
  function pick(source, keys) {
1838
1879
  const record = source;
1839
1880
  const result = {};
@@ -1859,7 +1900,7 @@ function assertNoDescriptorEdits(table, base) {
1859
1900
  if (!source) continue;
1860
1901
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1861
1902
  throw new Error(
1862
- "Cannot edit table cell width, merge, vertical alignment, shading, or margins on an existing cell; only cell text and borders are supported. The original DOCX package remains unchanged."
1903
+ "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."
1863
1904
  );
1864
1905
  }
1865
1906
  }
@@ -1928,6 +1969,8 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1928
1969
  throw new Error("Moving paragraphs between table cells is not supported.");
1929
1970
  const tc = source?.cell ?? makeW(doc, "tc");
1930
1971
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1972
+ patchCellShading(doc, tc, cell, source?.model);
1973
+ patchCellMargins(doc, tc, cell.margins, source?.model.margins);
1931
1974
  const oldParagraphs = children2(tc, "p");
1932
1975
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1933
1976
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -1958,13 +2001,13 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1958
2001
  }
1959
2002
 
1960
2003
  // src/docx/page-borders.ts
1961
- var SIDES2 = ["top", "left", "bottom", "right"];
2004
+ var SIDES3 = ["top", "left", "bottom", "right"];
1962
2005
  var ATTRIBUTES = ["offsetFrom", "display", "zOrder"];
1963
2006
  var setW4 = (element, name, value) => element.setAttributeNS(WORD_NS, `w:${name}`, value);
1964
2007
  function parsePageBorders(element) {
1965
2008
  if (!element) return void 0;
1966
2009
  const result = {};
1967
- for (const side of SIDES2) {
2010
+ for (const side of SIDES3) {
1968
2011
  const source = first2(element, side);
1969
2012
  const value = borderSide(source);
1970
2013
  const art = getW(source, "art");
@@ -2002,7 +2045,7 @@ function patchPageBorders(doc, sectPr, next, base, create) {
2002
2045
  return;
2003
2046
  }
2004
2047
  const element = create(doc, sectPr, "pgBorders");
2005
- for (const side of SIDES2) {
2048
+ for (const side of SIDES3) {
2006
2049
  if (JSON.stringify(next[side]) === JSON.stringify(base?.[side])) continue;
2007
2050
  for (const old of children2(element, side)) element.removeChild(old);
2008
2051
  const value = next[side];
@@ -2327,7 +2370,7 @@ function applySectionEdits(doc, body, blocks, sections, base, references = /* @_
2327
2370
  }
2328
2371
 
2329
2372
  // src/docx/write-paragraph-decoration.ts
2330
- var SIDES3 = ["top", "left", "bottom", "right", "between"];
2373
+ var SIDES4 = ["top", "left", "bottom", "right", "between"];
2331
2374
  function wordColor(color) {
2332
2375
  const hex = /^#?([0-9a-f]{6})$/i.exec(color ?? "")?.[1];
2333
2376
  return hex ? hex.toUpperCase() : "auto";
@@ -2361,7 +2404,7 @@ function updateBorders(doc, props, paragraph, base) {
2361
2404
  const borders = paragraph.borders;
2362
2405
  if (!borders) return;
2363
2406
  const pBdr = makeW(doc, "pBdr");
2364
- for (const side of SIDES3) {
2407
+ for (const side of SIDES4) {
2365
2408
  const value = borders[side];
2366
2409
  if (value) pBdr.appendChild(borderElement(doc, side, value));
2367
2410
  }
@@ -4648,6 +4691,30 @@ function createRun(doc, run, base, old, allocator) {
4648
4691
  if (!run.text) node.appendChild(makeW(doc, "t"));
4649
4692
  return node;
4650
4693
  }
4694
+ var MATH_NAMESPACES = /* @__PURE__ */ new Set([
4695
+ "http://schemas.openxmlformats.org/officeDocument/2006/math",
4696
+ "http://purl.oclc.org/ooxml/officeDocument/math"
4697
+ ]);
4698
+ function isEquationElement(element) {
4699
+ return MATH_NAMESPACES.has(element.namespaceURI ?? "") && (element.localName === "oMath" || element.localName === "oMathPara");
4700
+ }
4701
+ function parseEquation(element) {
4702
+ if (!isEquationElement(element)) return void 0;
4703
+ return {
4704
+ text: "",
4705
+ equation: {
4706
+ omml: new XMLSerializer().serializeToString(element),
4707
+ display: element.localName === "oMathPara"
4708
+ }
4709
+ };
4710
+ }
4711
+ function preserveEquation(run, base, old) {
4712
+ if (!old || !isEquationElement(old) || !base?.equation || run.text !== "" || run.equation?.omml !== base.equation.omml || run.equation?.display !== base.equation.display)
4713
+ throw new Error(
4714
+ "Equation editing or insertion is unsupported; imported OMML must remain unchanged."
4715
+ );
4716
+ return old.cloneNode(true);
4717
+ }
4651
4718
 
4652
4719
  // src/docx/breaks.ts
4653
4720
  function hasSpecialBreak(element) {
@@ -4746,10 +4813,11 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
4746
4813
  if (!isCommentReferenceRun(item)) push(parseRun3(item));
4747
4814
  } else if (named2(item, "hyperlink")) {
4748
4815
  const link = resolveLink?.(item);
4749
- for (const run of children2(item, "r")) {
4750
- const parsed = parseRun3(run);
4751
- if (link) parsed.link = link;
4752
- push(parsed);
4816
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
4817
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3)] : parseOther?.(child3) ?? []) {
4818
+ if (link) parsed.link = link;
4819
+ push(parsed);
4820
+ }
4753
4821
  }
4754
4822
  } else if ((!item.namespaceURI || item.namespaceURI === WORD_NS) && Object.hasOwn(REVISION_WRAPPERS, item.localName)) {
4755
4823
  const kind = expectDefined(
@@ -4760,7 +4828,12 @@ function collectParagraphRuns(node, parseRun3, parseOther, resolveLink, active =
4760
4828
  const revision = revisionFrom(item, kind);
4761
4829
  const range = kind === "moveFrom" || kind === "moveTo" ? moves[kind].at(-1) : void 0;
4762
4830
  if (range) revision.move = { name: range.name, rangeId: range.id };
4763
- for (const run of children2(item, "r")) push(parseRun3(run, revision));
4831
+ for (const child3 of Array.from(item.childNodes).filter(isElement)) {
4832
+ for (const parsed of named2(child3, "r") ? [parseRun3(child3, revision)] : parseOther?.(child3) ?? []) {
4833
+ parsed.revision = revision;
4834
+ push(parsed);
4835
+ }
4836
+ }
4764
4837
  } else if (trackMoveRange(item, moves)) {
4765
4838
  continue;
4766
4839
  } else if (named2(item, "commentRangeStart")) {
@@ -4807,7 +4880,9 @@ function runsOf(parent, container, slots) {
4807
4880
  if (child3.nodeType === 3 && child3.textContent?.trim()) return false;
4808
4881
  continue;
4809
4882
  }
4810
- if (named2(child3, "r")) {
4883
+ if (isEquationElement(child3)) {
4884
+ slots.push({ element: child3, ...container && { container } });
4885
+ } else if (named2(child3, "r")) {
4811
4886
  if (isCommentReferenceRun(child3)) continue;
4812
4887
  if (!runIsSafe(child3)) return false;
4813
4888
  slots.push({ element: child3, ...container && { container } });
@@ -4831,7 +4906,9 @@ function collectInlineSlots(paragraph) {
4831
4906
  if (child3.nodeType === 3 && child3.textContent?.trim()) return void 0;
4832
4907
  continue;
4833
4908
  }
4834
- if (named2(child3, "r")) {
4909
+ if (isEquationElement(child3)) {
4910
+ slots.push({ element: child3 });
4911
+ } else if (named2(child3, "r")) {
4835
4912
  if (isCommentReferenceRun(child3)) continue;
4836
4913
  if (!runIsSafe(child3)) return void 0;
4837
4914
  slots.push({ element: child3 });
@@ -4847,7 +4924,7 @@ function collectInlineSlots(paragraph) {
4847
4924
  }
4848
4925
  function replaceableInlineChildren(paragraph) {
4849
4926
  return Array.from(paragraph.childNodes).filter(
4850
- (child3) => isElement(child3) && (named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
4927
+ (child3) => isElement(child3) && (isEquationElement(child3) || named2(child3, "r") || named2(child3, "hyperlink") || named2(child3, "fldSimple") || isRevisionWrapperElement(child3) || isCommentAnchorElement(child3))
4851
4928
  );
4852
4929
  }
4853
4930
  function sameLink(a, b) {
@@ -4872,7 +4949,7 @@ function newHyperlink(doc, link, allocator) {
4872
4949
  }
4873
4950
  function runNodes(doc, run, base, old, opens, closes, allocator) {
4874
4951
  const nodes = opens.flatMap((edge) => rangeStartNodes(doc, edge));
4875
- const node = createRun(doc, run, base, old, allocator);
4952
+ const node = run.equation ? preserveEquation(run, base, old) : createRun(doc, run, base, old, allocator);
4876
4953
  const revision = run.revision;
4877
4954
  if (revision && ["insert", "delete", "moveFrom", "moveTo"].includes(revision.kind)) {
4878
4955
  if (revision.kind === "delete" || revision.kind === "moveFrom") convertToDeleteText(doc, node);
@@ -4884,15 +4961,23 @@ function runNodes(doc, run, base, old, opens, closes, allocator) {
4884
4961
  function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
4885
4962
  const { opens, closes } = rangeEdges(runs, ranges);
4886
4963
  const runAt = (at) => expectDefined(runs[at], `run ${at}`);
4887
- const nodesFor = (index2) => runNodes(
4888
- doc,
4889
- runAt(index2),
4890
- base?.[index2],
4891
- slots[index2]?.element,
4892
- opens.get(index2) ?? [],
4893
- closes.get(index2) ?? [],
4894
- allocator
4895
- );
4964
+ const nodesFor = (index2) => {
4965
+ const run = runAt(index2);
4966
+ const sourceIndex = run.equation ? base?.findIndex(
4967
+ (source2) => source2.equation?.omml === run.equation?.omml && source2.equation?.display === run.equation?.display
4968
+ ) : index2;
4969
+ const source = sourceIndex === void 0 ? void 0 : base?.[sourceIndex];
4970
+ const old = sourceIndex === void 0 ? void 0 : slots[sourceIndex]?.element;
4971
+ return runNodes(
4972
+ doc,
4973
+ run,
4974
+ !run.equation && source?.equation ? void 0 : source,
4975
+ !run.equation && old && isEquationElement(old) ? void 0 : old,
4976
+ opens.get(index2) ?? [],
4977
+ closes.get(index2) ?? [],
4978
+ allocator
4979
+ );
4980
+ };
4896
4981
  const output = [];
4897
4982
  let index = 0;
4898
4983
  while (index < runs.length) {
@@ -6547,14 +6632,14 @@ function parseCell(cell, parseParagraph3, id) {
6547
6632
  const vMerge = first2(props, "vMerge");
6548
6633
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
6549
6634
  const tcW = first2(props, "tcW");
6550
- if (getW(tcW, "type") !== "nil") {
6635
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
6551
6636
  const width = dxa(getW(tcW, "w"));
6552
6637
  if (width !== void 0) result.widthTwips = width;
6553
6638
  }
6554
6639
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
6555
6640
  if (vAlign) result.verticalAlign = vAlign;
6556
6641
  const shd = first2(props, "shd");
6557
- const fill = parseShadingFill(shd);
6642
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
6558
6643
  if (fill) result.shadingFill = fill;
6559
6644
  const themeFill = parseShadingThemeFill(shd);
6560
6645
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -6593,7 +6678,9 @@ function parseMargins(element) {
6593
6678
  ["left", "start"],
6594
6679
  ["right", "end"]
6595
6680
  ]) {
6596
- const value = dxa(getW(first2(element, side) ?? first2(element, logical), "w"));
6681
+ const edge = first2(element, logical) ?? first2(element, side);
6682
+ const type = getW(edge, "type") ?? "dxa";
6683
+ const value = type === "nil" ? parseSignedTwips("0") : type === "dxa" ? parseSignedTwips(getW(edge, "w")) : void 0;
6597
6684
  if (value !== void 0) parsed[side] = value;
6598
6685
  }
6599
6686
  return Object.keys(parsed).length ? parsed : void 0;
@@ -6623,7 +6710,8 @@ function parseTable(node, id, parseParagraph3) {
6623
6710
  }) : [];
6624
6711
  if (grid.length) table.grid = grid;
6625
6712
  const tblPr = first2(node, "tblPr");
6626
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
6713
+ const tableWidth = first2(tblPr, "tblW");
6714
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
6627
6715
  if (width !== void 0) table.widthTwips = width;
6628
6716
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
6629
6717
  if (justification) {
@@ -6797,13 +6885,19 @@ function parseParagraph2(node, id) {
6797
6885
  node,
6798
6886
  (element, revision) => trackField(element, parseRun2(element, revision)),
6799
6887
  (item) => {
6888
+ const equation = parseEquation(item);
6889
+ if (equation) return [equation];
6800
6890
  if (!named2(item, "fldSimple")) return void 0;
6801
6891
  const instr = getW(item, "instr") ?? "";
6802
6892
  const link = parseSimpleHyperlinkField(instr);
6803
- const results = children2(item, "r").map((run) => parseRun2(run));
6893
+ const results = Array.from(item.childNodes).filter(isElement).flatMap((child3) => {
6894
+ const equation2 = parseEquation(child3);
6895
+ return equation2 ? [equation2] : named2(child3, "r") ? [parseRun2(child3)] : [];
6896
+ });
6804
6897
  if (link) return results.map((run) => ({ ...run, link }));
6805
6898
  const field = { instr: instr.trim(), simple: true };
6806
- if (!results.some((run) => run.text)) return [{ text: fieldPlaceholderText(instr), field }];
6899
+ if (!results.some((run) => run.text || run.equation))
6900
+ return [{ text: fieldPlaceholderText(instr), field }];
6807
6901
  return results.map((run) => ({ ...run, field }));
6808
6902
  },
6809
6903
  (hyperlink) => {
@@ -0,0 +1,8 @@
1
+ import type { TextRun } from './model.js';
2
+ import type { XmlElement } from './xml.js';
3
+ export declare function isEquationElement(element: XmlElement): boolean;
4
+ /** Serializing the subtree supplies inherited namespaces, so consumers can parse it independently. */
5
+ export declare function parseEquation(element: XmlElement): TextRun | undefined;
6
+ /** Equation source may be relocated within its paragraph, but cannot be created or changed. */
7
+ export declare function preserveEquation(run: TextRun, base: TextRun | undefined, old: XmlElement | undefined): XmlElement;
8
+ //# sourceMappingURL=equation.d.ts.map
@@ -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"}