ooxml-core 0.4.0 → 0.5.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 (50) hide show
  1. package/NOTICE +2 -0
  2. package/dist/docx/embedded.cjs +23 -6
  3. package/dist/docx/embedded.mjs +23 -6
  4. package/dist/docx/index.cjs +23 -6
  5. package/dist/docx/index.mjs +23 -6
  6. package/dist/docx/load/index.cjs +23 -6
  7. package/dist/docx/load/index.mjs +23 -6
  8. package/dist/docx/parse-table.d.ts.map +1 -1
  9. package/dist/docx/write-table-properties.d.ts +3 -1
  10. package/dist/docx/write-table-properties.d.ts.map +1 -1
  11. package/dist/docx/write-table.d.ts.map +1 -1
  12. package/dist/index.cjs +2042 -13
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.mjs +2042 -14
  16. package/dist/math/index.cjs +2050 -0
  17. package/dist/math/index.d.ts +15 -0
  18. package/dist/math/index.d.ts.map +1 -0
  19. package/dist/math/index.mjs +1985 -0
  20. package/dist/math/latex-omml-siblings.d.ts +21 -0
  21. package/dist/math/latex-omml-siblings.d.ts.map +1 -0
  22. package/dist/math/latex-omml-symbols.d.ts +42 -0
  23. package/dist/math/latex-omml-symbols.d.ts.map +1 -0
  24. package/dist/math/latex-to-omml-commands.d.ts +9 -0
  25. package/dist/math/latex-to-omml-commands.d.ts.map +1 -0
  26. package/dist/math/latex-to-omml-constructs.d.ts +39 -0
  27. package/dist/math/latex-to-omml-constructs.d.ts.map +1 -0
  28. package/dist/math/latex-to-omml-environments.d.ts +28 -0
  29. package/dist/math/latex-to-omml-environments.d.ts.map +1 -0
  30. package/dist/math/latex-to-omml.d.ts +9 -0
  31. package/dist/math/latex-to-omml.d.ts.map +1 -0
  32. package/dist/math/omml-color.d.ts +11 -0
  33. package/dist/math/omml-color.d.ts.map +1 -0
  34. package/dist/math/omml-dom.d.ts +7 -0
  35. package/dist/math/omml-dom.d.ts.map +1 -0
  36. package/dist/math/omml-mathml-converters.d.ts +39 -0
  37. package/dist/math/omml-mathml-converters.d.ts.map +1 -0
  38. package/dist/math/omml-mathml-helpers.d.ts +23 -0
  39. package/dist/math/omml-mathml-helpers.d.ts.map +1 -0
  40. package/dist/math/omml-node.d.ts +7 -0
  41. package/dist/math/omml-node.d.ts.map +1 -0
  42. package/dist/math/omml-to-latex-helpers.d.ts +41 -0
  43. package/dist/math/omml-to-latex-helpers.d.ts.map +1 -0
  44. package/dist/math/omml-to-latex-layout.d.ts +18 -0
  45. package/dist/math/omml-to-latex-layout.d.ts.map +1 -0
  46. package/dist/math/omml-to-latex.d.ts +6 -0
  47. package/dist/math/omml-to-latex.d.ts.map +1 -0
  48. package/dist/math/omml-to-mathml.d.ts +21 -0
  49. package/dist/math/omml-to-mathml.d.ts.map +1 -0
  50. package/package.json +6 -1
package/NOTICE CHANGED
@@ -1,3 +1,5 @@
1
1
  ooxml-core contains modern OOXML modules extracted from ChristopherVR/docx-viewer and ChristopherVR/pptx-viewer, Copyright ChristopherVR, licensed under the Apache License, Version 2.0. The Apache License text is included in LICENSE. PROVENANCE.md records where each module came from.
2
2
 
3
3
  The pptx area also contains PowerPoint glyph-advance measurements (font-advance-widths*.generated.ts: numeric widths measured through COM automation; no font software is included). Third-party runtime dependencies are listed in THIRD-PARTY-LICENSES.
4
+
5
+ The math area includes Apache-2.0 equation conversion modules extracted from ChristopherVR/pptx-viewer. Their source paths and modifications are recorded in PROVENANCE.md.
@@ -1788,6 +1788,23 @@ function patchCellBorders(doc, tc, next, base) {
1788
1788
  orderChildren(props, CELL_ORDER);
1789
1789
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1790
1790
  }
1791
+ function patchCellShading(doc, tc, next, base) {
1792
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
1793
+ return;
1794
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
1795
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
1796
+ let props = first2(tc, "tcPr");
1797
+ if (!props) {
1798
+ props = makeW(doc, "tcPr");
1799
+ tc.insertBefore(props, tc.firstChild);
1800
+ }
1801
+ for (const old of children2(props, "shd")) props.removeChild(old);
1802
+ const built = buildCellProperties(doc, next);
1803
+ const replacement = built && first2(built, "shd");
1804
+ if (replacement) props.appendChild(replacement);
1805
+ orderChildren(props, CELL_ORDER);
1806
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1807
+ }
1791
1808
 
1792
1809
  // src/docx/write-table.ts
1793
1810
  function canEditTableStructure(table) {
@@ -1836,8 +1853,6 @@ var CELL_DESCRIPTOR_KEYS = [
1836
1853
  "verticalMerge",
1837
1854
  "widthTwips",
1838
1855
  "verticalAlign",
1839
- "shadingFill",
1840
- "shadingThemeFill",
1841
1856
  "margins"
1842
1857
  ];
1843
1858
  function pick(source, keys) {
@@ -1865,7 +1880,7 @@ function assertNoDescriptorEdits(table, base) {
1865
1880
  if (!source) continue;
1866
1881
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1867
1882
  throw new Error(
1868
- "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."
1883
+ "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."
1869
1884
  );
1870
1885
  }
1871
1886
  }
@@ -1934,6 +1949,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1934
1949
  throw new Error("Moving paragraphs between table cells is not supported.");
1935
1950
  const tc = source?.cell ?? makeW(doc, "tc");
1936
1951
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1952
+ patchCellShading(doc, tc, cell, source?.model);
1937
1953
  const oldParagraphs = children2(tc, "p");
1938
1954
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1939
1955
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -6553,14 +6569,14 @@ function parseCell(cell, parseParagraph3, id) {
6553
6569
  const vMerge = first2(props, "vMerge");
6554
6570
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
6555
6571
  const tcW = first2(props, "tcW");
6556
- if (getW(tcW, "type") !== "nil") {
6572
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
6557
6573
  const width = dxa(getW(tcW, "w"));
6558
6574
  if (width !== void 0) result.widthTwips = width;
6559
6575
  }
6560
6576
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
6561
6577
  if (vAlign) result.verticalAlign = vAlign;
6562
6578
  const shd = first2(props, "shd");
6563
- const fill = parseShadingFill(shd);
6579
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
6564
6580
  if (fill) result.shadingFill = fill;
6565
6581
  const themeFill = parseShadingThemeFill(shd);
6566
6582
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -6629,7 +6645,8 @@ function parseTable(node, id, parseParagraph3) {
6629
6645
  }) : [];
6630
6646
  if (grid.length) table.grid = grid;
6631
6647
  const tblPr = first2(node, "tblPr");
6632
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
6648
+ const tableWidth = first2(tblPr, "tblW");
6649
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
6633
6650
  if (width !== void 0) table.widthTwips = width;
6634
6651
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
6635
6652
  if (justification) {
@@ -1782,6 +1782,23 @@ function patchCellBorders(doc, tc, next, base) {
1782
1782
  orderChildren(props, CELL_ORDER);
1783
1783
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1784
1784
  }
1785
+ function patchCellShading(doc, tc, next, base) {
1786
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
1787
+ return;
1788
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
1789
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
1790
+ let props = first2(tc, "tcPr");
1791
+ if (!props) {
1792
+ props = makeW(doc, "tcPr");
1793
+ tc.insertBefore(props, tc.firstChild);
1794
+ }
1795
+ for (const old of children2(props, "shd")) props.removeChild(old);
1796
+ const built = buildCellProperties(doc, next);
1797
+ const replacement = built && first2(built, "shd");
1798
+ if (replacement) props.appendChild(replacement);
1799
+ orderChildren(props, CELL_ORDER);
1800
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1801
+ }
1785
1802
 
1786
1803
  // src/docx/write-table.ts
1787
1804
  function canEditTableStructure(table) {
@@ -1830,8 +1847,6 @@ var CELL_DESCRIPTOR_KEYS = [
1830
1847
  "verticalMerge",
1831
1848
  "widthTwips",
1832
1849
  "verticalAlign",
1833
- "shadingFill",
1834
- "shadingThemeFill",
1835
1850
  "margins"
1836
1851
  ];
1837
1852
  function pick(source, keys) {
@@ -1859,7 +1874,7 @@ function assertNoDescriptorEdits(table, base) {
1859
1874
  if (!source) continue;
1860
1875
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1861
1876
  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."
1877
+ "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."
1863
1878
  );
1864
1879
  }
1865
1880
  }
@@ -1928,6 +1943,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1928
1943
  throw new Error("Moving paragraphs between table cells is not supported.");
1929
1944
  const tc = source?.cell ?? makeW(doc, "tc");
1930
1945
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1946
+ patchCellShading(doc, tc, cell, source?.model);
1931
1947
  const oldParagraphs = children2(tc, "p");
1932
1948
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1933
1949
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -6547,14 +6563,14 @@ function parseCell(cell, parseParagraph3, id) {
6547
6563
  const vMerge = first2(props, "vMerge");
6548
6564
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
6549
6565
  const tcW = first2(props, "tcW");
6550
- if (getW(tcW, "type") !== "nil") {
6566
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
6551
6567
  const width = dxa(getW(tcW, "w"));
6552
6568
  if (width !== void 0) result.widthTwips = width;
6553
6569
  }
6554
6570
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
6555
6571
  if (vAlign) result.verticalAlign = vAlign;
6556
6572
  const shd = first2(props, "shd");
6557
- const fill = parseShadingFill(shd);
6573
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
6558
6574
  if (fill) result.shadingFill = fill;
6559
6575
  const themeFill = parseShadingThemeFill(shd);
6560
6576
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -6623,7 +6639,8 @@ function parseTable(node, id, parseParagraph3) {
6623
6639
  }) : [];
6624
6640
  if (grid.length) table.grid = grid;
6625
6641
  const tblPr = first2(node, "tblPr");
6626
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
6642
+ const tableWidth = first2(tblPr, "tblW");
6643
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
6627
6644
  if (width !== void 0) table.widthTwips = width;
6628
6645
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
6629
6646
  if (justification) {
@@ -2433,6 +2433,23 @@ function patchCellBorders(doc, tc, next, base) {
2433
2433
  orderChildren(props, CELL_ORDER);
2434
2434
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
2435
2435
  }
2436
+ function patchCellShading(doc, tc, next, base) {
2437
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
2438
+ return;
2439
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
2440
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
2441
+ let props = first2(tc, "tcPr");
2442
+ if (!props) {
2443
+ props = makeW(doc, "tcPr");
2444
+ tc.insertBefore(props, tc.firstChild);
2445
+ }
2446
+ for (const old of children2(props, "shd")) props.removeChild(old);
2447
+ const built = buildCellProperties(doc, next);
2448
+ const replacement = built && first2(built, "shd");
2449
+ if (replacement) props.appendChild(replacement);
2450
+ orderChildren(props, CELL_ORDER);
2451
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
2452
+ }
2436
2453
 
2437
2454
  // src/docx/write-table.ts
2438
2455
  function canEditTableStructure(table) {
@@ -2481,8 +2498,6 @@ var CELL_DESCRIPTOR_KEYS = [
2481
2498
  "verticalMerge",
2482
2499
  "widthTwips",
2483
2500
  "verticalAlign",
2484
- "shadingFill",
2485
- "shadingThemeFill",
2486
2501
  "margins"
2487
2502
  ];
2488
2503
  function pick(source, keys) {
@@ -2510,7 +2525,7 @@ function assertNoDescriptorEdits(table, base) {
2510
2525
  if (!source) continue;
2511
2526
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
2512
2527
  throw new Error(
2513
- "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."
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."
2514
2529
  );
2515
2530
  }
2516
2531
  }
@@ -2579,6 +2594,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2579
2594
  throw new Error("Moving paragraphs between table cells is not supported.");
2580
2595
  const tc = source?.cell ?? makeW(doc, "tc");
2581
2596
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
2597
+ patchCellShading(doc, tc, cell, source?.model);
2582
2598
  const oldParagraphs = children2(tc, "p");
2583
2599
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
2584
2600
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -7442,14 +7458,14 @@ function parseCell(cell, parseParagraph3, id) {
7442
7458
  const vMerge = first2(props, "vMerge");
7443
7459
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
7444
7460
  const tcW = first2(props, "tcW");
7445
- if (getW(tcW, "type") !== "nil") {
7461
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
7446
7462
  const width = dxa(getW(tcW, "w"));
7447
7463
  if (width !== void 0) result.widthTwips = width;
7448
7464
  }
7449
7465
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
7450
7466
  if (vAlign) result.verticalAlign = vAlign;
7451
7467
  const shd = first2(props, "shd");
7452
- const fill = parseShadingFill(shd);
7468
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
7453
7469
  if (fill) result.shadingFill = fill;
7454
7470
  const themeFill = parseShadingThemeFill(shd);
7455
7471
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -7518,7 +7534,8 @@ function parseTable(node, id, parseParagraph3) {
7518
7534
  }) : [];
7519
7535
  if (grid.length) table.grid = grid;
7520
7536
  const tblPr = first2(node, "tblPr");
7521
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
7537
+ const tableWidth = first2(tblPr, "tblW");
7538
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
7522
7539
  if (width !== void 0) table.widthTwips = width;
7523
7540
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
7524
7541
  if (justification) {
@@ -2427,6 +2427,23 @@ function patchCellBorders(doc, tc, next, base) {
2427
2427
  orderChildren(props, CELL_ORDER);
2428
2428
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
2429
2429
  }
2430
+ function patchCellShading(doc, tc, next, base) {
2431
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
2432
+ return;
2433
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
2434
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
2435
+ let props = first2(tc, "tcPr");
2436
+ if (!props) {
2437
+ props = makeW(doc, "tcPr");
2438
+ tc.insertBefore(props, tc.firstChild);
2439
+ }
2440
+ for (const old of children2(props, "shd")) props.removeChild(old);
2441
+ const built = buildCellProperties(doc, next);
2442
+ const replacement = built && first2(built, "shd");
2443
+ if (replacement) props.appendChild(replacement);
2444
+ orderChildren(props, CELL_ORDER);
2445
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
2446
+ }
2430
2447
 
2431
2448
  // src/docx/write-table.ts
2432
2449
  function canEditTableStructure(table) {
@@ -2475,8 +2492,6 @@ var CELL_DESCRIPTOR_KEYS = [
2475
2492
  "verticalMerge",
2476
2493
  "widthTwips",
2477
2494
  "verticalAlign",
2478
- "shadingFill",
2479
- "shadingThemeFill",
2480
2495
  "margins"
2481
2496
  ];
2482
2497
  function pick(source, keys) {
@@ -2504,7 +2519,7 @@ function assertNoDescriptorEdits(table, base) {
2504
2519
  if (!source) continue;
2505
2520
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
2506
2521
  throw new Error(
2507
- "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."
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."
2508
2523
  );
2509
2524
  }
2510
2525
  }
@@ -2573,6 +2588,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
2573
2588
  throw new Error("Moving paragraphs between table cells is not supported.");
2574
2589
  const tc = source?.cell ?? makeW(doc, "tc");
2575
2590
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
2591
+ patchCellShading(doc, tc, cell, source?.model);
2576
2592
  const oldParagraphs = children2(tc, "p");
2577
2593
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
2578
2594
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -7436,14 +7452,14 @@ function parseCell(cell, parseParagraph3, id) {
7436
7452
  const vMerge = first2(props, "vMerge");
7437
7453
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
7438
7454
  const tcW = first2(props, "tcW");
7439
- if (getW(tcW, "type") !== "nil") {
7455
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
7440
7456
  const width = dxa(getW(tcW, "w"));
7441
7457
  if (width !== void 0) result.widthTwips = width;
7442
7458
  }
7443
7459
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
7444
7460
  if (vAlign) result.verticalAlign = vAlign;
7445
7461
  const shd = first2(props, "shd");
7446
- const fill = parseShadingFill(shd);
7462
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
7447
7463
  if (fill) result.shadingFill = fill;
7448
7464
  const themeFill = parseShadingThemeFill(shd);
7449
7465
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -7512,7 +7528,8 @@ function parseTable(node, id, parseParagraph3) {
7512
7528
  }) : [];
7513
7529
  if (grid.length) table.grid = grid;
7514
7530
  const tblPr = first2(node, "tblPr");
7515
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
7531
+ const tableWidth = first2(tblPr, "tblW");
7532
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
7516
7533
  if (width !== void 0) table.widthTwips = width;
7517
7534
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
7518
7535
  if (justification) {
@@ -1034,6 +1034,23 @@ function patchCellBorders(doc, tc, next, base) {
1034
1034
  orderChildren(props, CELL_ORDER);
1035
1035
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1036
1036
  }
1037
+ function patchCellShading(doc, tc, next, base) {
1038
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
1039
+ return;
1040
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
1041
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
1042
+ let props = first2(tc, "tcPr");
1043
+ if (!props) {
1044
+ props = makeW(doc, "tcPr");
1045
+ tc.insertBefore(props, tc.firstChild);
1046
+ }
1047
+ for (const old of children2(props, "shd")) props.removeChild(old);
1048
+ const built = buildCellProperties(doc, next);
1049
+ const replacement = built && first2(built, "shd");
1050
+ if (replacement) props.appendChild(replacement);
1051
+ orderChildren(props, CELL_ORDER);
1052
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1053
+ }
1037
1054
 
1038
1055
  // src/docx/write-table.ts
1039
1056
  function canEditTableStructure(table) {
@@ -1082,8 +1099,6 @@ var CELL_DESCRIPTOR_KEYS = [
1082
1099
  "verticalMerge",
1083
1100
  "widthTwips",
1084
1101
  "verticalAlign",
1085
- "shadingFill",
1086
- "shadingThemeFill",
1087
1102
  "margins"
1088
1103
  ];
1089
1104
  function pick(source, keys) {
@@ -1111,7 +1126,7 @@ function assertNoDescriptorEdits(table, base) {
1111
1126
  if (!source) continue;
1112
1127
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1113
1128
  throw new Error(
1114
- "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."
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."
1115
1130
  );
1116
1131
  }
1117
1132
  }
@@ -1180,6 +1195,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1180
1195
  throw new Error("Moving paragraphs between table cells is not supported.");
1181
1196
  const tc = source?.cell ?? makeW(doc, "tc");
1182
1197
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1198
+ patchCellShading(doc, tc, cell, source?.model);
1183
1199
  const oldParagraphs = children2(tc, "p");
1184
1200
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1185
1201
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -6464,14 +6480,14 @@ function parseCell(cell, parseParagraph3, id) {
6464
6480
  const vMerge = first2(props, "vMerge");
6465
6481
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
6466
6482
  const tcW = first2(props, "tcW");
6467
- if (getW(tcW, "type") !== "nil") {
6483
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
6468
6484
  const width = dxa(getW(tcW, "w"));
6469
6485
  if (width !== void 0) result.widthTwips = width;
6470
6486
  }
6471
6487
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
6472
6488
  if (vAlign) result.verticalAlign = vAlign;
6473
6489
  const shd = first2(props, "shd");
6474
- const fill = parseShadingFill(shd);
6490
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
6475
6491
  if (fill) result.shadingFill = fill;
6476
6492
  const themeFill = parseShadingThemeFill(shd);
6477
6493
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -6540,7 +6556,8 @@ function parseTable(node, id, parseParagraph3) {
6540
6556
  }) : [];
6541
6557
  if (grid.length) table.grid = grid;
6542
6558
  const tblPr = first2(node, "tblPr");
6543
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
6559
+ const tableWidth = first2(tblPr, "tblW");
6560
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
6544
6561
  if (width !== void 0) table.widthTwips = width;
6545
6562
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
6546
6563
  if (justification) {
@@ -1028,6 +1028,23 @@ function patchCellBorders(doc, tc, next, base) {
1028
1028
  orderChildren(props, CELL_ORDER);
1029
1029
  if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1030
1030
  }
1031
+ function patchCellShading(doc, tc, next, base) {
1032
+ if (next.shadingFill === base?.shadingFill && JSON.stringify(next.shadingThemeFill) === JSON.stringify(base?.shadingThemeFill))
1033
+ return;
1034
+ if (next.shadingFill && next.shadingFill !== "auto" && !/^#?[0-9a-f]{6}$/i.test(next.shadingFill))
1035
+ throw new Error("Cell shading must be a six-digit RGB color or auto.");
1036
+ let props = first2(tc, "tcPr");
1037
+ if (!props) {
1038
+ props = makeW(doc, "tcPr");
1039
+ tc.insertBefore(props, tc.firstChild);
1040
+ }
1041
+ for (const old of children2(props, "shd")) props.removeChild(old);
1042
+ const built = buildCellProperties(doc, next);
1043
+ const replacement = built && first2(built, "shd");
1044
+ if (replacement) props.appendChild(replacement);
1045
+ orderChildren(props, CELL_ORDER);
1046
+ if (!Array.from(props.childNodes).some((node) => node.nodeType === 1)) tc.removeChild(props);
1047
+ }
1031
1048
 
1032
1049
  // src/docx/write-table.ts
1033
1050
  function canEditTableStructure(table) {
@@ -1076,8 +1093,6 @@ var CELL_DESCRIPTOR_KEYS = [
1076
1093
  "verticalMerge",
1077
1094
  "widthTwips",
1078
1095
  "verticalAlign",
1079
- "shadingFill",
1080
- "shadingThemeFill",
1081
1096
  "margins"
1082
1097
  ];
1083
1098
  function pick(source, keys) {
@@ -1105,7 +1120,7 @@ function assertNoDescriptorEdits(table, base) {
1105
1120
  if (!source) continue;
1106
1121
  if (JSON.stringify(pick(cell, CELL_DESCRIPTOR_KEYS)) !== JSON.stringify(pick(source, CELL_DESCRIPTOR_KEYS)))
1107
1122
  throw new Error(
1108
- "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."
1123
+ "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."
1109
1124
  );
1110
1125
  }
1111
1126
  }
@@ -1174,6 +1189,7 @@ function writeTable(doc, table, node, base, writeParagraph, replaceSlots2) {
1174
1189
  throw new Error("Moving paragraphs between table cells is not supported.");
1175
1190
  const tc = source?.cell ?? makeW(doc, "tc");
1176
1191
  patchCellBorders(doc, tc, cell.borders, source?.model.borders);
1192
+ patchCellShading(doc, tc, cell, source?.model);
1177
1193
  const oldParagraphs = children2(tc, "p");
1178
1194
  const nextParagraphs = cell.paragraphs.map((paragraph) => {
1179
1195
  const index = source?.paragraphs.findIndex((p) => p.id === paragraph.id) ?? -1;
@@ -6458,14 +6474,14 @@ function parseCell(cell, parseParagraph3, id) {
6458
6474
  const vMerge = first2(props, "vMerge");
6459
6475
  if (vMerge) result.verticalMerge = getW(vMerge, "val") === "restart" ? "restart" : "continue";
6460
6476
  const tcW = first2(props, "tcW");
6461
- if (getW(tcW, "type") !== "nil") {
6477
+ if ((getW(tcW, "type") ?? "dxa") === "dxa") {
6462
6478
  const width = dxa(getW(tcW, "w"));
6463
6479
  if (width !== void 0) result.widthTwips = width;
6464
6480
  }
6465
6481
  const vAlign = enumValue(isStVerticalJc, getW(first2(props, "vAlign"), "val"), "w:tcPr/w:vAlign");
6466
6482
  if (vAlign) result.verticalAlign = vAlign;
6467
6483
  const shd = first2(props, "shd");
6468
- const fill = parseShadingFill(shd);
6484
+ const fill = parseShadingFill(shd) ?? (getW(shd, "fill") === "auto" && !getW(shd, "themeFill") ? "auto" : void 0);
6469
6485
  if (fill) result.shadingFill = fill;
6470
6486
  const themeFill = parseShadingThemeFill(shd);
6471
6487
  if (themeFill) result.shadingThemeFill = themeFill;
@@ -6534,7 +6550,8 @@ function parseTable(node, id, parseParagraph3) {
6534
6550
  }) : [];
6535
6551
  if (grid.length) table.grid = grid;
6536
6552
  const tblPr = first2(node, "tblPr");
6537
- const width = dxa(getW(first2(tblPr, "tblW"), "w"));
6553
+ const tableWidth = first2(tblPr, "tblW");
6554
+ const width = (getW(tableWidth, "type") ?? "dxa") === "dxa" ? dxa(getW(tableWidth, "w")) : void 0;
6538
6555
  if (width !== void 0) table.widthTwips = width;
6539
6556
  const justification = enumValue(isStJcTable, getW(first2(tblPr, "jc"), "val"), "w:tblPr/w:jc");
6540
6557
  if (justification) {
@@ -1 +1 @@
1
- {"version":3,"file":"parse-table.d.ts","sourceRoot":"","sources":["../../src/docx/parse-table.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAyB,KAAK,UAAU,EAAW,MAAM,UAAU,CAAC;AAgH3E,8FAA8F;AAC9F,wBAAgB,UAAU,CACzB,IAAI,EAAE,UAAU,EAChB,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,KAAK,SAAS,GACtD,KAAK,CA4CP"}
1
+ {"version":3,"file":"parse-table.d.ts","sourceRoot":"","sources":["../../src/docx/parse-table.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAyB,KAAK,UAAU,EAAW,MAAM,UAAU,CAAC;AAkH3E,8FAA8F;AAC9F,wBAAgB,UAAU,CACzB,IAAI,EAAE,UAAU,EAChB,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,KAAK,SAAS,GACtD,KAAK,CA8CP"}
@@ -1,4 +1,4 @@
1
- import type { Table } from './model.js';
1
+ import type { Table, TableCell } from './model.js';
2
2
  import type { TableBorders, TableRowProperties } from './table-model.js';
3
3
  import { type XmlDocument, type XmlElement } from './xml.js';
4
4
  /** Changes only modeled row fields, preserving unmodeled trPr children and attributes. */
@@ -10,4 +10,6 @@ export declare function patchTableMargins(doc: XmlDocument, table: Table, node:
10
10
  * (width, shading, margins, extensions) and untouched sides exactly as they were.
11
11
  */
12
12
  export declare function patchCellBorders(doc: XmlDocument, tc: XmlElement, next: TableBorders | undefined, base: TableBorders | undefined): void;
13
+ /** Replaces only changed cell shading, preserving widths, borders, margins and extension XML. */
14
+ export declare function patchCellShading(doc: XmlDocument, tc: XmlElement, next: TableCell, base?: TableCell): void;
13
15
  //# sourceMappingURL=write-table-properties.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-table-properties.d.ts","sourceRoot":"","sources":["../../src/docx/write-table-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIzE,OAAO,EAA0B,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAwCrF,0FAA0F;AAC1F,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,kBAAkB,GAAG,SAAS,EACpC,IAAI,EAAE,kBAAkB,GAAG,SAAS,GAClC,IAAI,CAmBN;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,CAAC,EAAE,KAAK,GACV,IAAI,CAqBN;AAyBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,IAAI,EAAE,YAAY,GAAG,SAAS,GAC5B,IAAI,CA0BN"}
1
+ {"version":3,"file":"write-table-properties.d.ts","sourceRoot":"","sources":["../../src/docx/write-table-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIzE,OAAO,EAA0B,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAwCrF,0FAA0F;AAC1F,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,kBAAkB,GAAG,SAAS,EACpC,IAAI,EAAE,kBAAkB,GAAG,SAAS,GAClC,IAAI,CAmBN;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,CAAC,EAAE,KAAK,GACV,IAAI,CAqBN;AAyBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,IAAI,EAAE,YAAY,GAAG,SAAS,GAC5B,IAAI,CA0BN;AAED,iGAAiG;AACjG,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,SAAS,EACf,IAAI,CAAC,EAAE,SAAS,GACd,IAAI,CAmBN"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-table.d.ts","sourceRoot":"","sources":["../../src/docx/write-table.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAa,MAAM,YAAY,CAAC;AAM9D,OAAO,EAMN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,MAAM,UAAU,CAAC;AAElB,KAAK,eAAe,GAAG,CACtB,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,UAAU,EAChB,IAAI,CAAC,EAAE,SAAS,KACZ,UAAU,CAAC;AAChB,KAAK,WAAW,GAAG,CAClB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,UAAU,EAAE,EACjB,IAAI,EAAE,UAAU,EAAE,KACd,IAAI,CAAC;AAEV,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAiChE;AAgED,wBAAgB,UAAU,CACzB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,KAAK,GAAG,SAAS,EACvB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,WAAW,GACvB,UAAU,CAqHZ"}
1
+ {"version":3,"file":"write-table.d.ts","sourceRoot":"","sources":["../../src/docx/write-table.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAa,MAAM,YAAY,CAAC;AAO9D,OAAO,EAMN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,MAAM,UAAU,CAAC;AAElB,KAAK,eAAe,GAAG,CACtB,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,UAAU,EAChB,IAAI,CAAC,EAAE,SAAS,KACZ,UAAU,CAAC;AAChB,KAAK,WAAW,GAAG,CAClB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,UAAU,EAAE,EACjB,IAAI,EAAE,UAAU,EAAE,KACd,IAAI,CAAC;AAEV,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAiChE;AA8DD,wBAAgB,UAAU,CACzB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,KAAK,GAAG,SAAS,EACvB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,WAAW,GACvB,UAAU,CAsHZ"}