docxmlater 8.7.1 → 9.0.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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/core/Document.d.ts.map +1 -1
  3. package/dist/core/Document.js +5 -0
  4. package/dist/core/Document.js.map +1 -1
  5. package/dist/core/DocumentParser.d.ts +1 -0
  6. package/dist/core/DocumentParser.d.ts.map +1 -1
  7. package/dist/core/DocumentParser.js +258 -63
  8. package/dist/core/DocumentParser.js.map +1 -1
  9. package/dist/elements/Field.d.ts +3 -0
  10. package/dist/elements/Field.d.ts.map +1 -1
  11. package/dist/elements/Field.js +5 -0
  12. package/dist/elements/Field.js.map +1 -1
  13. package/dist/elements/Image.d.ts +1 -0
  14. package/dist/elements/Image.d.ts.map +1 -1
  15. package/dist/elements/Image.js +5 -1
  16. package/dist/elements/Image.js.map +1 -1
  17. package/dist/elements/Paragraph.d.ts +1 -0
  18. package/dist/elements/Paragraph.d.ts.map +1 -1
  19. package/dist/elements/Paragraph.js +18 -0
  20. package/dist/elements/Paragraph.js.map +1 -1
  21. package/dist/elements/Revision.d.ts +13 -0
  22. package/dist/elements/Revision.d.ts.map +1 -1
  23. package/dist/elements/Revision.js +21 -0
  24. package/dist/elements/Revision.js.map +1 -1
  25. package/dist/elements/Run.d.ts +9 -0
  26. package/dist/elements/Run.d.ts.map +1 -1
  27. package/dist/elements/Run.js +59 -3
  28. package/dist/elements/Run.js.map +1 -1
  29. package/dist/elements/Table.d.ts +9 -1
  30. package/dist/elements/Table.d.ts.map +1 -1
  31. package/dist/elements/Table.js +19 -0
  32. package/dist/elements/Table.js.map +1 -1
  33. package/dist/elements/TableCell.d.ts +6 -0
  34. package/dist/elements/TableCell.d.ts.map +1 -1
  35. package/dist/elements/TableCell.js +39 -0
  36. package/dist/elements/TableCell.js.map +1 -1
  37. package/dist/formatting/NumberingLevel.d.ts +4 -1
  38. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  39. package/dist/formatting/NumberingLevel.js +20 -0
  40. package/dist/formatting/NumberingLevel.js.map +1 -1
  41. package/dist/formatting/Style.d.ts +1 -0
  42. package/dist/formatting/Style.d.ts.map +1 -1
  43. package/dist/formatting/Style.js +27 -0
  44. package/dist/formatting/Style.js.map +1 -1
  45. package/dist/formatting/StylesManager.d.ts.map +1 -1
  46. package/dist/formatting/StylesManager.js +9 -0
  47. package/dist/formatting/StylesManager.js.map +1 -1
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js.map +1 -1
  51. package/package.json +1 -1
@@ -39,6 +39,7 @@ export declare class DocumentParser {
39
39
  private extractBookmarkEndsFromContent;
40
40
  private findNextTag;
41
41
  private findNextTopLevelTag;
42
+ private countUnclosedTags;
42
43
  private isPositionInsideTable;
43
44
  private isPositionInsideDel;
44
45
  private findDelEndPosition;
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentParser.d.ts","sourceRoot":"","sources":["../../src/core/DocumentParser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DocumentParser.d.ts","sourceRoot":"","sources":["../../src/core/DocumentParser.ts"],"names":[],"mappings":"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"}
@@ -265,36 +265,18 @@ class DocumentParser {
265
265
  return bodyElements;
266
266
  }
267
267
  extractBodyLevelBookmarkEnds(content, startPos, endPos) {
268
- const bookmarks = [];
269
268
  const searchContent = endPos === -1
270
269
  ? content.slice(startPos)
271
270
  : content.slice(startPos, endPos);
272
- const bookmarkEndRegex = /<w:bookmarkEnd[^>]*w:id="(\d+)"[^>]*\/?>/g;
273
- let match;
274
- while ((match = bookmarkEndRegex.exec(searchContent)) !== null) {
275
- const idStr = match[1];
276
- if (idStr) {
277
- const id = parseInt(idStr, 10);
278
- if (!isNaN(id)) {
279
- const bookmark = new Bookmark_1.Bookmark({
280
- name: `_end_${id}`,
281
- id: id,
282
- skipNormalization: true,
283
- });
284
- bookmarks.push(bookmark);
285
- }
286
- }
287
- }
288
- return bookmarks;
271
+ return this.extractBookmarkEndsFromContent(searchContent);
289
272
  }
290
273
  extractBookmarkEndsFromContent(content) {
291
274
  const bookmarks = [];
292
- const bookmarkEndRegex = /<w:bookmarkEnd[^>]*w:id="(\d+)"[^>]*\/?>/g;
293
- let match;
294
- while ((match = bookmarkEndRegex.exec(content)) !== null) {
295
- const idStr = match[1];
296
- if (idStr) {
297
- const id = parseInt(idStr, 10);
275
+ const bookmarkEndXmls = XMLParser_1.XMLParser.extractElements(content, "w:bookmarkEnd");
276
+ for (const bookmarkEndXml of bookmarkEndXmls) {
277
+ const idAttr = XMLParser_1.XMLParser.extractAttribute(bookmarkEndXml, "w:id");
278
+ if (idAttr) {
279
+ const id = parseInt(idAttr, 10);
298
280
  if (!isNaN(id)) {
299
281
  const bookmark = new Bookmark_1.Bookmark({
300
282
  name: `_end_${id}`,
@@ -341,11 +323,44 @@ class DocumentParser {
341
323
  }
342
324
  return -1;
343
325
  }
326
+ countUnclosedTags(content, tagName) {
327
+ let opens = 0;
328
+ let closes = 0;
329
+ let pos = 0;
330
+ while (pos < content.length) {
331
+ const openPos = content.indexOf(`<${tagName}`, pos);
332
+ if (openPos === -1)
333
+ break;
334
+ const afterTagName = openPos + tagName.length + 1;
335
+ if (afterTagName < content.length) {
336
+ const charAfter = content.charAt(afterTagName);
337
+ if (charAfter === ' ' || charAfter === '>' || charAfter === '/' ||
338
+ charAfter === '\t' || charAfter === '\n' || charAfter === '\r') {
339
+ const tagEnd = content.indexOf('>', openPos);
340
+ if (tagEnd !== -1) {
341
+ const isSelfClosing = content.charAt(tagEnd - 1) === '/';
342
+ if (!isSelfClosing) {
343
+ opens++;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ pos = openPos + 1;
349
+ }
350
+ pos = 0;
351
+ const closeTag = `</${tagName}>`;
352
+ while (pos < content.length) {
353
+ const closePos = content.indexOf(closeTag, pos);
354
+ if (closePos === -1)
355
+ break;
356
+ closes++;
357
+ pos = closePos + closeTag.length;
358
+ }
359
+ return opens - closes;
360
+ }
344
361
  isPositionInsideTable(content, position) {
345
362
  const beforeContent = content.substring(0, position);
346
- const openTableTags = (beforeContent.match(/<w:tbl[\s>]/g) || []).length;
347
- const closeTableTags = (beforeContent.match(/<\/w:tbl>/g) || []).length;
348
- return openTableTags > closeTableTags;
363
+ return this.countUnclosedTags(beforeContent, "w:tbl") > 0;
349
364
  }
350
365
  isPositionInsideDel(content, position) {
351
366
  const beforeContent = content.substring(0, position);
@@ -359,20 +374,11 @@ class DocumentParser {
359
374
  if (tagEnd !== -1 && content.charAt(tagEnd - 1) === "/")
360
375
  return false;
361
376
  const contentBeforeDel = content.substring(0, lastDelOpen);
362
- const pOpens = (contentBeforeDel.match(/<w:p[\s>]/g) || []).length;
363
- const pCloses = (contentBeforeDel.match(/<\/w:p>/g) || []).length;
364
- const insideParagraph = pOpens > pCloses;
365
- if (insideParagraph)
377
+ if (this.countUnclosedTags(contentBeforeDel, "w:p") > 0)
366
378
  return false;
367
- const tblOpens = (contentBeforeDel.match(/<w:tbl[\s>]/g) || []).length;
368
- const tblCloses = (contentBeforeDel.match(/<\/w:tbl>/g) || []).length;
369
- const insideTable = tblOpens > tblCloses;
370
- if (insideTable)
379
+ if (this.countUnclosedTags(contentBeforeDel, "w:tbl") > 0)
371
380
  return false;
372
- const sdtOpens = (contentBeforeDel.match(/<w:sdt[\s>]/g) || []).length;
373
- const sdtCloses = (contentBeforeDel.match(/<\/w:sdt>/g) || []).length;
374
- const insideSdt = sdtOpens > sdtCloses;
375
- if (insideSdt)
381
+ if (this.countUnclosedTags(contentBeforeDel, "w:sdt") > 0)
376
382
  return false;
377
383
  return true;
378
384
  }
@@ -704,9 +710,15 @@ class DocumentParser {
704
710
  if (child.index < insXmls.length) {
705
711
  const revisionXml = insXmls[child.index];
706
712
  if (revisionXml) {
707
- const revision = await this.parseRevisionFromXml(revisionXml, "w:ins", relationshipManager, zipHandler, imageManager);
708
- if (revision) {
709
- paragraph.addRevision(revision);
713
+ const revResult = await this.parseRevisionFromXml(revisionXml, "w:ins", relationshipManager, zipHandler, imageManager);
714
+ if (revResult.revision) {
715
+ paragraph.addRevision(revResult.revision);
716
+ }
717
+ for (const bookmark of revResult.bookmarkStarts) {
718
+ paragraph.addBookmarkStart(bookmark);
719
+ }
720
+ for (const bookmark of revResult.bookmarkEnds) {
721
+ paragraph.addBookmarkEnd(bookmark);
710
722
  }
711
723
  }
712
724
  }
@@ -715,9 +727,15 @@ class DocumentParser {
715
727
  if (child.index < delXmls.length) {
716
728
  const revisionXml = delXmls[child.index];
717
729
  if (revisionXml) {
718
- const revision = await this.parseRevisionFromXml(revisionXml, "w:del", relationshipManager, zipHandler, imageManager);
719
- if (revision) {
720
- paragraph.addRevision(revision);
730
+ const revResult = await this.parseRevisionFromXml(revisionXml, "w:del", relationshipManager, zipHandler, imageManager);
731
+ if (revResult.revision) {
732
+ paragraph.addRevision(revResult.revision);
733
+ }
734
+ for (const bookmark of revResult.bookmarkStarts) {
735
+ paragraph.addBookmarkStart(bookmark);
736
+ }
737
+ for (const bookmark of revResult.bookmarkEnds) {
738
+ paragraph.addBookmarkEnd(bookmark);
721
739
  }
722
740
  }
723
741
  }
@@ -726,9 +744,15 @@ class DocumentParser {
726
744
  if (child.index < moveFromXmls.length) {
727
745
  const revisionXml = moveFromXmls[child.index];
728
746
  if (revisionXml) {
729
- const revision = await this.parseRevisionFromXml(revisionXml, "w:moveFrom", relationshipManager, zipHandler, imageManager);
730
- if (revision) {
731
- paragraph.addRevision(revision);
747
+ const revResult = await this.parseRevisionFromXml(revisionXml, "w:moveFrom", relationshipManager, zipHandler, imageManager);
748
+ if (revResult.revision) {
749
+ paragraph.addRevision(revResult.revision);
750
+ }
751
+ for (const bookmark of revResult.bookmarkStarts) {
752
+ paragraph.addBookmarkStart(bookmark);
753
+ }
754
+ for (const bookmark of revResult.bookmarkEnds) {
755
+ paragraph.addBookmarkEnd(bookmark);
732
756
  }
733
757
  }
734
758
  }
@@ -737,9 +761,15 @@ class DocumentParser {
737
761
  if (child.index < moveToXmls.length) {
738
762
  const revisionXml = moveToXmls[child.index];
739
763
  if (revisionXml) {
740
- const revision = await this.parseRevisionFromXml(revisionXml, "w:moveTo", relationshipManager, zipHandler, imageManager);
741
- if (revision) {
742
- paragraph.addRevision(revision);
764
+ const revResult = await this.parseRevisionFromXml(revisionXml, "w:moveTo", relationshipManager, zipHandler, imageManager);
765
+ if (revResult.revision) {
766
+ paragraph.addRevision(revResult.revision);
767
+ }
768
+ for (const bookmark of revResult.bookmarkStarts) {
769
+ paragraph.addBookmarkStart(bookmark);
770
+ }
771
+ for (const bookmark of revResult.bookmarkEnds) {
772
+ paragraph.addBookmarkEnd(bookmark);
743
773
  }
744
774
  }
745
775
  }
@@ -769,6 +799,7 @@ class DocumentParser {
769
799
  }
770
800
  }
771
801
  async parseRevisionFromXml(revisionXml, tagName, relationshipManager, zipHandler, imageManager) {
802
+ const result = { revision: null, bookmarkStarts: [], bookmarkEnds: [] };
772
803
  try {
773
804
  let revisionType;
774
805
  switch (tagName) {
@@ -785,21 +816,21 @@ class DocumentParser {
785
816
  revisionType = "moveTo";
786
817
  break;
787
818
  default:
788
- return null;
819
+ return result;
789
820
  }
790
821
  const idAttr = XMLParser_1.XMLParser.extractAttribute(revisionXml, "w:id");
791
822
  const author = XMLParser_1.XMLParser.extractAttribute(revisionXml, "w:author");
792
823
  const dateAttr = XMLParser_1.XMLParser.extractAttribute(revisionXml, "w:date");
793
824
  const moveId = XMLParser_1.XMLParser.extractAttribute(revisionXml, "w:moveId");
794
825
  if (!idAttr || !author) {
795
- return null;
826
+ return result;
796
827
  }
797
828
  const id = parseInt(idAttr, 10);
798
829
  const date = dateAttr ? new Date(dateAttr) : new Date();
799
830
  const hyperlinkXmls = XMLParser_1.XMLParser.extractElements(revisionXml, "w:hyperlink");
800
831
  let xmlWithoutHyperlinks = revisionXml;
801
832
  for (const hyperlinkXml of hyperlinkXmls) {
802
- xmlWithoutHyperlinks = xmlWithoutHyperlinks.replace(hyperlinkXml, '');
833
+ xmlWithoutHyperlinks = xmlWithoutHyperlinks.split(hyperlinkXml).join('');
803
834
  }
804
835
  const runXmls = XMLParser_1.XMLParser.extractElements(xmlWithoutHyperlinks, "w:r");
805
836
  const content = [];
@@ -823,14 +854,30 @@ class DocumentParser {
823
854
  }
824
855
  for (const hyperlinkXml of hyperlinkXmls) {
825
856
  const hyperlinkObj = XMLParser_1.XMLParser.parseToObject(hyperlinkXml, { trimValues: false });
826
- const result = this.parseHyperlinkFromObject(hyperlinkObj["w:hyperlink"], relationshipManager);
827
- if (result.hyperlink) {
828
- content.push(result.hyperlink);
857
+ const hyperlinkResult = this.parseHyperlinkFromObject(hyperlinkObj["w:hyperlink"], relationshipManager);
858
+ if (hyperlinkResult.hyperlink) {
859
+ content.push(hyperlinkResult.hyperlink);
860
+ }
861
+ result.bookmarkStarts.push(...hyperlinkResult.bookmarkStarts);
862
+ result.bookmarkEnds.push(...hyperlinkResult.bookmarkEnds);
863
+ }
864
+ const bookmarkStartXmls = XMLParser_1.XMLParser.extractElements(xmlWithoutHyperlinks, "w:bookmarkStart");
865
+ const bookmarkEndXmls = XMLParser_1.XMLParser.extractElements(xmlWithoutHyperlinks, "w:bookmarkEnd");
866
+ for (const bookmarkXml of bookmarkStartXmls) {
867
+ const bookmark = this.parseBookmarkStart(bookmarkXml);
868
+ if (bookmark) {
869
+ result.bookmarkStarts.push(bookmark);
870
+ }
871
+ }
872
+ for (const bookmarkXml of bookmarkEndXmls) {
873
+ const bookmark = this.parseBookmarkEnd(bookmarkXml);
874
+ if (bookmark) {
875
+ result.bookmarkEnds.push(bookmark);
829
876
  }
830
877
  }
831
878
  if (content.length === 0) {
832
879
  logger_1.defaultLogger.debug("[DocumentParser] Empty revision content skipped", { tagName, id: idAttr, author });
833
- return null;
880
+ return result;
834
881
  }
835
882
  const revision = new Revision_1.Revision({
836
883
  id,
@@ -840,13 +887,14 @@ class DocumentParser {
840
887
  content,
841
888
  moveId,
842
889
  });
843
- return revision;
890
+ result.revision = revision;
891
+ return result;
844
892
  }
845
893
  catch (error) {
846
894
  logger_1.defaultLogger.warn("[DocumentParser] Failed to parse revision:", error instanceof Error
847
895
  ? { message: error.message, stack: error.stack }
848
896
  : { error: String(error) });
849
- return null;
897
+ return result;
850
898
  }
851
899
  }
852
900
  parseCommentsXml(commentsXml) {
@@ -1107,6 +1155,8 @@ class DocumentParser {
1107
1155
  paragraph.setRightIndent((0, parsingHelpers_1.safeParseInt)(ind["@_w:right"]));
1108
1156
  if ((0, parsingHelpers_1.isExplicitlySet)(ind["@_w:firstLine"]))
1109
1157
  paragraph.setFirstLineIndent((0, parsingHelpers_1.safeParseInt)(ind["@_w:firstLine"]));
1158
+ if ((0, parsingHelpers_1.isExplicitlySet)(ind["@_w:hanging"]))
1159
+ paragraph.setHangingIndent((0, parsingHelpers_1.safeParseInt)(ind["@_w:hanging"]));
1110
1160
  }
1111
1161
  if (pPrObj["w:spacing"]) {
1112
1162
  const spacing = pPrObj["w:spacing"];
@@ -1598,6 +1648,13 @@ class DocumentParser {
1598
1648
  const complexField = this.createComplexFieldFromRuns(fieldRuns);
1599
1649
  if (complexField) {
1600
1650
  if (fieldRevisions.length > 0) {
1651
+ for (const rev of fieldRevisions) {
1652
+ rev.setFieldContext({
1653
+ field: complexField,
1654
+ instruction: complexField.getInstruction(),
1655
+ position: 'result',
1656
+ });
1657
+ }
1601
1658
  complexField.setResultRevisions(fieldRevisions);
1602
1659
  }
1603
1660
  groupedContent.push(complexField);
@@ -1632,6 +1689,13 @@ class DocumentParser {
1632
1689
  const complexField = this.createComplexFieldFromRuns(fieldRuns);
1633
1690
  if (complexField) {
1634
1691
  if (fieldRevisions.length > 0) {
1692
+ for (const rev of fieldRevisions) {
1693
+ rev.setFieldContext({
1694
+ field: complexField,
1695
+ instruction: complexField.getInstruction(),
1696
+ position: 'result',
1697
+ });
1698
+ }
1635
1699
  complexField.setResultRevisions(fieldRevisions);
1636
1700
  }
1637
1701
  groupedContent.push(complexField);
@@ -1685,11 +1749,13 @@ class DocumentParser {
1685
1749
  }
1686
1750
  else if (item instanceof Revision_1.Revision) {
1687
1751
  if (fieldState === "separate" || fieldState === "result") {
1752
+ item.setFieldContext({ position: 'result' });
1688
1753
  fieldRevisions.push(item);
1689
1754
  fieldState = "result";
1690
1755
  logger_1.defaultLogger.debug(`Found revision inside complex field result: type=${item.getType()}, id=${item.getId()}`);
1691
1756
  }
1692
1757
  else if (fieldState === "begin" || fieldState === "instruction") {
1758
+ item.setFieldContext({ position: 'instruction' });
1693
1759
  instructionRevisions.push(item);
1694
1760
  fieldState = "instruction";
1695
1761
  logger_1.defaultLogger.debug(`Found revision inside complex field instruction: type=${item.getType()}, id=${item.getId()}`);
@@ -2078,6 +2144,7 @@ class DocumentParser {
2078
2144
  instructionFormatting,
2079
2145
  resultFormatting,
2080
2146
  multiParagraph: false,
2147
+ hasResult: hasSeparate,
2081
2148
  };
2082
2149
  return new Field_1.ComplexField(properties);
2083
2150
  }
@@ -2211,7 +2278,7 @@ class DocumentParser {
2211
2278
  }
2212
2279
  }
2213
2280
  else {
2214
- console.warn('[DocumentParser] _orderedChildren missing - using fallback element ordering which may affect tab/break positions');
2281
+ logger_1.defaultLogger.warn('[DocumentParser] _orderedChildren missing - using fallback element ordering which may affect tab/break positions');
2215
2282
  const textElement = runObj["w:t"];
2216
2283
  if (textElement !== undefined && textElement !== null) {
2217
2284
  const textElements = toArray(textElement);
@@ -2420,6 +2487,31 @@ class DocumentParser {
2420
2487
  const content = paragraph.getContent();
2421
2488
  if (!content || content.length < 2)
2422
2489
  return;
2490
+ const trackingEnabled = paragraph.trackingContext?.isEnabled();
2491
+ if (trackingEnabled) {
2492
+ const hasFieldContent = content.some((item) => {
2493
+ if (item instanceof Run_1.Run) {
2494
+ const runContent = item.getContent();
2495
+ return runContent.some((c) => c.type === "fieldChar" || c.type === "instructionText");
2496
+ }
2497
+ if (item instanceof Revision_1.Revision) {
2498
+ const revContent = item.getContent();
2499
+ for (const inner of revContent) {
2500
+ if (inner instanceof Run_1.Run) {
2501
+ const innerRunContent = inner.getContent();
2502
+ if (innerRunContent.some((c) => c.type === "fieldChar" || c.type === "instructionText")) {
2503
+ return true;
2504
+ }
2505
+ }
2506
+ }
2507
+ }
2508
+ return false;
2509
+ });
2510
+ if (hasFieldContent) {
2511
+ logger_1.defaultLogger.debug("Skipping hyperlink merge: tracking enabled with field content present");
2512
+ return;
2513
+ }
2514
+ }
2423
2515
  const mergedContent = [];
2424
2516
  let i = 0;
2425
2517
  let contentChanged = false;
@@ -2676,11 +2768,28 @@ class DocumentParser {
2676
2768
  if (rPrObj["w:sz"]) {
2677
2769
  run.setSize(parseInt(rPrObj["w:sz"]["@_w:val"], 10) / 2);
2678
2770
  }
2771
+ if (rPrObj["w:szCs"]) {
2772
+ const szCsVal = parseInt(rPrObj["w:szCs"]["@_w:val"], 10) / 2;
2773
+ const sizeVal = rPrObj["w:sz"] ? parseInt(rPrObj["w:sz"]["@_w:val"], 10) / 2 : undefined;
2774
+ if (sizeVal === undefined || szCsVal !== sizeVal) {
2775
+ run.setSizeCs(szCsVal);
2776
+ }
2777
+ }
2679
2778
  if (rPrObj["w:color"]) {
2680
- const colorVal = rPrObj["w:color"]["@_w:val"];
2779
+ const colorObj = rPrObj["w:color"];
2780
+ const colorVal = colorObj["@_w:val"];
2681
2781
  if (colorVal && colorVal !== "auto") {
2682
2782
  run.setColor(colorVal);
2683
2783
  }
2784
+ if (colorObj["@_w:themeColor"]) {
2785
+ run.setThemeColor(colorObj["@_w:themeColor"]);
2786
+ }
2787
+ if (colorObj["@_w:themeTint"]) {
2788
+ run.setThemeTint(parseInt(colorObj["@_w:themeTint"], 16));
2789
+ }
2790
+ if (colorObj["@_w:themeShade"]) {
2791
+ run.setThemeShade(parseInt(colorObj["@_w:themeShade"], 16));
2792
+ }
2684
2793
  }
2685
2794
  if (rPrObj["w:highlight"]) {
2686
2795
  run.setHighlight(rPrObj["w:highlight"]["@_w:val"]);
@@ -2715,11 +2824,27 @@ class DocumentParser {
2715
2824
  if (prevRPr["w:sz"]) {
2716
2825
  prevProps.size = (0, parsingHelpers_1.safeParseInt)(prevRPr["w:sz"]["@_w:val"]) / 2;
2717
2826
  }
2827
+ if (prevRPr["w:szCs"]) {
2828
+ const szCsVal = (0, parsingHelpers_1.safeParseInt)(prevRPr["w:szCs"]["@_w:val"]) / 2;
2829
+ if (!prevRPr["w:sz"] || szCsVal !== prevProps.size) {
2830
+ prevProps.sizeCs = szCsVal;
2831
+ }
2832
+ }
2718
2833
  if (prevRPr["w:color"]) {
2719
- const colorVal = prevRPr["w:color"]["@_w:val"];
2834
+ const colorObj = prevRPr["w:color"];
2835
+ const colorVal = colorObj["@_w:val"];
2720
2836
  if (colorVal && colorVal !== "auto") {
2721
2837
  prevProps.color = colorVal;
2722
2838
  }
2839
+ if (colorObj["@_w:themeColor"]) {
2840
+ prevProps.themeColor = colorObj["@_w:themeColor"];
2841
+ }
2842
+ if (colorObj["@_w:themeTint"]) {
2843
+ prevProps.themeTint = parseInt(colorObj["@_w:themeTint"], 16);
2844
+ }
2845
+ if (colorObj["@_w:themeShade"]) {
2846
+ prevProps.themeShade = parseInt(colorObj["@_w:themeShade"], 16);
2847
+ }
2723
2848
  }
2724
2849
  if (prevRPr["w:highlight"]) {
2725
2850
  prevProps.highlight = prevRPr["w:highlight"]["@_w:val"];
@@ -2940,6 +3065,7 @@ class DocumentParser {
2940
3065
  const effects = this.parseImageEffects(blipObj);
2941
3066
  const spPrObj = picPicObj["pic:spPr"];
2942
3067
  let border = undefined;
3068
+ let rotation = 0;
2943
3069
  if (spPrObj) {
2944
3070
  const lnObj = spPrObj["a:ln"];
2945
3071
  if (lnObj) {
@@ -2948,6 +3074,10 @@ class DocumentParser {
2948
3074
  border = { width: widthEmu / 12700 };
2949
3075
  }
2950
3076
  }
3077
+ const xfrmObj = spPrObj["a:xfrm"];
3078
+ if (xfrmObj?.["@_rot"]) {
3079
+ rotation = parseInt(xfrmObj["@_rot"], 10) / 60000;
3080
+ }
2951
3081
  }
2952
3082
  const relationshipId = blipObj["@_r:embed"];
2953
3083
  if (!relationshipId) {
@@ -2985,6 +3115,7 @@ class DocumentParser {
2985
3115
  crop,
2986
3116
  effects,
2987
3117
  border,
3118
+ rotation,
2988
3119
  });
2989
3120
  imageManager.registerImage(image, relationshipId, originalFilename);
2990
3121
  image.setRelationshipId(relationshipId);
@@ -3280,6 +3411,19 @@ class DocumentParser {
3280
3411
  table.setAlignment(alignment);
3281
3412
  }
3282
3413
  }
3414
+ if (tblPrObj["w:shd"]) {
3415
+ const shd = tblPrObj["w:shd"];
3416
+ const shading = {};
3417
+ if (shd["@_w:val"])
3418
+ shading.pattern = shd["@_w:val"];
3419
+ if (shd["@_w:fill"])
3420
+ shading.fill = shd["@_w:fill"];
3421
+ if (shd["@_w:color"])
3422
+ shading.color = shd["@_w:color"];
3423
+ if (Object.keys(shading).length > 0) {
3424
+ table.setShading(shading);
3425
+ }
3426
+ }
3283
3427
  }
3284
3428
  async parseTableRowFromObject(rowObj, relationshipManager, zipHandler, imageManager, rawRowXml) {
3285
3429
  try {
@@ -3541,6 +3685,57 @@ class DocumentParser {
3541
3685
  cell.setVerticalMerge("continue");
3542
3686
  }
3543
3687
  }
3688
+ if (tcPr["w:cellIns"]) {
3689
+ const cellIns = tcPr["w:cellIns"];
3690
+ const id = parseInt(cellIns["@_w:id"] || "0", 10);
3691
+ const author = cellIns["@_w:author"] || "Unknown";
3692
+ const dateAttr = cellIns["@_w:date"];
3693
+ const date = dateAttr ? new Date(dateAttr) : new Date();
3694
+ const revision = new Revision_1.Revision({
3695
+ id,
3696
+ author,
3697
+ date,
3698
+ type: "tableCellInsert",
3699
+ content: [],
3700
+ });
3701
+ cell.setCellRevision(revision);
3702
+ }
3703
+ if (tcPr["w:cellDel"]) {
3704
+ const cellDel = tcPr["w:cellDel"];
3705
+ const id = parseInt(cellDel["@_w:id"] || "0", 10);
3706
+ const author = cellDel["@_w:author"] || "Unknown";
3707
+ const dateAttr = cellDel["@_w:date"];
3708
+ const date = dateAttr ? new Date(dateAttr) : new Date();
3709
+ const revision = new Revision_1.Revision({
3710
+ id,
3711
+ author,
3712
+ date,
3713
+ type: "tableCellDelete",
3714
+ content: [],
3715
+ });
3716
+ cell.setCellRevision(revision);
3717
+ }
3718
+ if (tcPr["w:cellMerge"]) {
3719
+ const cellMerge = tcPr["w:cellMerge"];
3720
+ const id = parseInt(cellMerge["@_w:id"] || "0", 10);
3721
+ const author = cellMerge["@_w:author"] || "Unknown";
3722
+ const dateAttr = cellMerge["@_w:date"];
3723
+ const date = dateAttr ? new Date(dateAttr) : new Date();
3724
+ const vMergeAttr = cellMerge["@_w:vMerge"];
3725
+ const vMergeOrigAttr = cellMerge["@_w:vMergeOrig"];
3726
+ const revision = new Revision_1.Revision({
3727
+ id,
3728
+ author,
3729
+ date,
3730
+ type: "tableCellMerge",
3731
+ content: [],
3732
+ previousProperties: {
3733
+ vMerge: vMergeAttr,
3734
+ vMergeOrig: vMergeOrigAttr,
3735
+ },
3736
+ });
3737
+ cell.setCellRevision(revision);
3738
+ }
3544
3739
  }
3545
3740
  if (rawCellXml) {
3546
3741
  const cellContent = this.extractCellContentInOrder(rawCellXml);