docxmlater 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 (131) hide show
  1. package/README.md +477 -554
  2. package/dist/core/Document.d.ts +60 -0
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +537 -3
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentParser.d.ts.map +1 -1
  7. package/dist/core/DocumentParser.js +5 -1
  8. package/dist/core/DocumentParser.js.map +1 -1
  9. package/dist/core/DocumentValidator.js +3 -0
  10. package/dist/core/DocumentValidator.js.map +1 -1
  11. package/dist/core/Relationship.d.ts +5 -0
  12. package/dist/core/Relationship.d.ts.map +1 -1
  13. package/dist/core/Relationship.js +26 -0
  14. package/dist/core/Relationship.js.map +1 -1
  15. package/dist/core/RelationshipManager.d.ts +6 -0
  16. package/dist/core/RelationshipManager.d.ts.map +1 -1
  17. package/dist/core/RelationshipManager.js +47 -0
  18. package/dist/core/RelationshipManager.js.map +1 -1
  19. package/dist/elements/Bookmark.js +2 -0
  20. package/dist/elements/Bookmark.js.map +1 -1
  21. package/dist/elements/BookmarkManager.js +2 -4
  22. package/dist/elements/BookmarkManager.js.map +1 -1
  23. package/dist/elements/Comment.js +6 -0
  24. package/dist/elements/Comment.js.map +1 -1
  25. package/dist/elements/CommentManager.js +2 -4
  26. package/dist/elements/CommentManager.js.map +1 -1
  27. package/dist/elements/Endnote.d.ts +34 -0
  28. package/dist/elements/Endnote.d.ts.map +1 -0
  29. package/dist/elements/Endnote.js +99 -0
  30. package/dist/elements/Endnote.js.map +1 -0
  31. package/dist/elements/EndnoteManager.d.ts +26 -0
  32. package/dist/elements/EndnoteManager.d.ts.map +1 -0
  33. package/dist/elements/EndnoteManager.js +108 -0
  34. package/dist/elements/EndnoteManager.js.map +1 -0
  35. package/dist/elements/Field.js +3 -0
  36. package/dist/elements/Field.js.map +1 -1
  37. package/dist/elements/Footer.js +3 -1
  38. package/dist/elements/Footer.js.map +1 -1
  39. package/dist/elements/Footnote.d.ts +34 -0
  40. package/dist/elements/Footnote.d.ts.map +1 -0
  41. package/dist/elements/Footnote.js +99 -0
  42. package/dist/elements/Footnote.js.map +1 -0
  43. package/dist/elements/FootnoteManager.d.ts +26 -0
  44. package/dist/elements/FootnoteManager.d.ts.map +1 -0
  45. package/dist/elements/FootnoteManager.js +108 -0
  46. package/dist/elements/FootnoteManager.js.map +1 -0
  47. package/dist/elements/Header.js +3 -1
  48. package/dist/elements/Header.js.map +1 -1
  49. package/dist/elements/HeaderFooterManager.js +4 -0
  50. package/dist/elements/HeaderFooterManager.js.map +1 -1
  51. package/dist/elements/Hyperlink.d.ts.map +1 -1
  52. package/dist/elements/Hyperlink.js +19 -1
  53. package/dist/elements/Hyperlink.js.map +1 -1
  54. package/dist/elements/Image.d.ts +4 -0
  55. package/dist/elements/Image.d.ts.map +1 -1
  56. package/dist/elements/Image.js +30 -1
  57. package/dist/elements/Image.js.map +1 -1
  58. package/dist/elements/ImageManager.js +6 -0
  59. package/dist/elements/ImageManager.js.map +1 -1
  60. package/dist/elements/Paragraph.d.ts +41 -0
  61. package/dist/elements/Paragraph.d.ts.map +1 -1
  62. package/dist/elements/Paragraph.js +69 -5
  63. package/dist/elements/Paragraph.js.map +1 -1
  64. package/dist/elements/Revision.js +5 -0
  65. package/dist/elements/Revision.js.map +1 -1
  66. package/dist/elements/RevisionManager.js +2 -4
  67. package/dist/elements/RevisionManager.js.map +1 -1
  68. package/dist/elements/Run.d.ts +2 -0
  69. package/dist/elements/Run.d.ts.map +1 -1
  70. package/dist/elements/Run.js +29 -4
  71. package/dist/elements/Run.js.map +1 -1
  72. package/dist/elements/Section.js +1 -0
  73. package/dist/elements/Section.js.map +1 -1
  74. package/dist/elements/Table.d.ts +6 -0
  75. package/dist/elements/Table.d.ts.map +1 -1
  76. package/dist/elements/Table.js +69 -2
  77. package/dist/elements/Table.js.map +1 -1
  78. package/dist/elements/TableCell.d.ts +9 -0
  79. package/dist/elements/TableCell.d.ts.map +1 -1
  80. package/dist/elements/TableCell.js +29 -1
  81. package/dist/elements/TableCell.js.map +1 -1
  82. package/dist/elements/TableOfContents.d.ts.map +1 -1
  83. package/dist/elements/TableOfContents.js +11 -0
  84. package/dist/elements/TableOfContents.js.map +1 -1
  85. package/dist/elements/TableOfContentsElement.js +1 -0
  86. package/dist/elements/TableOfContentsElement.js.map +1 -1
  87. package/dist/elements/TableRow.js +2 -1
  88. package/dist/elements/TableRow.js.map +1 -1
  89. package/dist/formatting/AbstractNumbering.d.ts +5 -0
  90. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  91. package/dist/formatting/AbstractNumbering.js +42 -0
  92. package/dist/formatting/AbstractNumbering.js.map +1 -1
  93. package/dist/formatting/NumberingInstance.d.ts +4 -1
  94. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  95. package/dist/formatting/NumberingInstance.js +20 -3
  96. package/dist/formatting/NumberingInstance.js.map +1 -1
  97. package/dist/formatting/NumberingLevel.js +1 -0
  98. package/dist/formatting/NumberingLevel.js.map +1 -1
  99. package/dist/formatting/NumberingManager.d.ts +6 -0
  100. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  101. package/dist/formatting/NumberingManager.js +37 -0
  102. package/dist/formatting/NumberingManager.js.map +1 -1
  103. package/dist/formatting/Style.d.ts +1 -0
  104. package/dist/formatting/Style.d.ts.map +1 -1
  105. package/dist/formatting/Style.js +66 -0
  106. package/dist/formatting/Style.js.map +1 -1
  107. package/dist/formatting/StylesManager.d.ts +8 -0
  108. package/dist/formatting/StylesManager.d.ts.map +1 -1
  109. package/dist/formatting/StylesManager.js +107 -17
  110. package/dist/formatting/StylesManager.js.map +1 -1
  111. package/dist/index.d.ts +6 -2
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +11 -1
  114. package/dist/index.js.map +1 -1
  115. package/dist/types/formatting.d.ts +47 -0
  116. package/dist/types/formatting.d.ts.map +1 -0
  117. package/dist/types/formatting.js +3 -0
  118. package/dist/types/formatting.js.map +1 -0
  119. package/dist/utils/validation.d.ts +14 -0
  120. package/dist/utils/validation.d.ts.map +1 -1
  121. package/dist/utils/validation.js +74 -0
  122. package/dist/utils/validation.js.map +1 -1
  123. package/dist/xml/XMLBuilder.js +1 -3
  124. package/dist/xml/XMLBuilder.js.map +1 -1
  125. package/dist/zip/ZipHandler.js +3 -1
  126. package/dist/zip/ZipHandler.js.map +1 -1
  127. package/dist/zip/ZipReader.js +3 -5
  128. package/dist/zip/ZipReader.js.map +1 -1
  129. package/dist/zip/ZipWriter.js +2 -1
  130. package/dist/zip/ZipWriter.js.map +1 -1
  131. package/package.json +9 -9
@@ -38,6 +38,7 @@ const ZipHandler_1 = require("../zip/ZipHandler");
38
38
  const types_1 = require("../zip/types");
39
39
  const Paragraph_1 = require("../elements/Paragraph");
40
40
  const Table_1 = require("../elements/Table");
41
+ const TableCell_1 = require("../elements/TableCell");
41
42
  const Section_1 = require("../elements/Section");
42
43
  const ImageManager_1 = require("../elements/ImageManager");
43
44
  const HeaderFooterManager_1 = require("../elements/HeaderFooterManager");
@@ -47,15 +48,19 @@ const BookmarkManager_1 = require("../elements/BookmarkManager");
47
48
  const Revision_1 = require("../elements/Revision");
48
49
  const RevisionManager_1 = require("../elements/RevisionManager");
49
50
  const CommentManager_1 = require("../elements/CommentManager");
51
+ const FootnoteManager_1 = require("../elements/FootnoteManager");
52
+ const EndnoteManager_1 = require("../elements/EndnoteManager");
50
53
  const Run_1 = require("../elements/Run");
51
54
  const Hyperlink_1 = require("../elements/Hyperlink");
52
55
  const StylesManager_1 = require("../formatting/StylesManager");
56
+ const Style_1 = require("../formatting/Style");
53
57
  const NumberingManager_1 = require("../formatting/NumberingManager");
54
58
  const RelationshipManager_1 = require("./RelationshipManager");
55
59
  const DocumentParser_1 = require("./DocumentParser");
56
60
  const DocumentGenerator_1 = require("./DocumentGenerator");
57
61
  const DocumentValidator_1 = require("./DocumentValidator");
58
62
  class ImageRun extends Run_1.Run {
63
+ imageElement;
59
64
  constructor(image) {
60
65
  super('');
61
66
  this.imageElement = image;
@@ -69,8 +74,24 @@ class ImageRun extends Run_1.Run {
69
74
  }
70
75
  }
71
76
  class Document {
77
+ zipHandler;
78
+ bodyElements = [];
79
+ properties;
80
+ stylesManager;
81
+ numberingManager;
82
+ section;
83
+ imageManager;
84
+ relationshipManager;
85
+ headerFooterManager;
86
+ bookmarkManager;
87
+ revisionManager;
88
+ commentManager;
89
+ _footnoteManager;
90
+ _endnoteManager;
91
+ parser;
92
+ generator;
93
+ validator;
72
94
  constructor(zipHandler, options = {}, initDefaults = true) {
73
- this.bodyElements = [];
74
95
  this.zipHandler = zipHandler || new ZipHandler_1.ZipHandler();
75
96
  const strictParsing = options.strictParsing ?? false;
76
97
  const memoryPercent = options.maxMemoryUsagePercent ?? 80;
@@ -95,6 +116,8 @@ class Document {
95
116
  this.bookmarkManager = BookmarkManager_1.BookmarkManager.create();
96
117
  this.revisionManager = RevisionManager_1.RevisionManager.create();
97
118
  this.commentManager = CommentManager_1.CommentManager.create();
119
+ this._footnoteManager = FootnoteManager_1.FootnoteManager.create();
120
+ this._endnoteManager = EndnoteManager_1.EndnoteManager.create();
98
121
  if (initDefaults) {
99
122
  this.relationshipManager.addStyles();
100
123
  this.relationshipManager.addNumbering();
@@ -284,6 +307,7 @@ class Document {
284
307
  }
285
308
  addStyle(style) {
286
309
  this.stylesManager.addStyle(style);
310
+ this.updateStylesXml();
287
311
  return this;
288
312
  }
289
313
  getStyle(styleId) {
@@ -292,6 +316,31 @@ class Document {
292
316
  hasStyle(styleId) {
293
317
  return this.stylesManager.hasStyle(styleId);
294
318
  }
319
+ getStyles() {
320
+ return this.stylesManager.getAllStyles();
321
+ }
322
+ removeStyle(styleId) {
323
+ return this.stylesManager.removeStyle(styleId);
324
+ }
325
+ updateStyle(styleId, properties) {
326
+ const style = this.stylesManager.getStyle(styleId);
327
+ if (!style) {
328
+ return false;
329
+ }
330
+ const currentProps = style.getProperties();
331
+ const updatedProps = { ...currentProps, ...properties, styleId };
332
+ const updatedStyle = Style_1.Style.create(updatedProps);
333
+ this.stylesManager.addStyle(updatedStyle);
334
+ return true;
335
+ }
336
+ getStylesXml() {
337
+ const stylesFile = this.zipHandler.getFileAsString(types_1.DOCX_PATHS.STYLES);
338
+ return stylesFile || this.stylesManager.generateStylesXml();
339
+ }
340
+ setStylesXml(xml) {
341
+ this.zipHandler.updateFile(types_1.DOCX_PATHS.STYLES, xml);
342
+ this.stylesManager.clear();
343
+ }
295
344
  getZipHandler() {
296
345
  return this.zipHandler;
297
346
  }
@@ -555,13 +604,20 @@ class Document {
555
604
  const currentUrl = content.getUrl();
556
605
  if (currentUrl && urlMap.has(currentUrl)) {
557
606
  const newUrl = urlMap.get(currentUrl);
558
- updates.push({ hyperlink: content, newUrl });
607
+ updates.push({
608
+ hyperlink: content,
609
+ newUrl,
610
+ relationshipId: content.getRelationshipId()
611
+ });
559
612
  }
560
613
  }
561
614
  }
562
615
  }
563
- for (const { hyperlink, newUrl } of updates) {
616
+ for (const { hyperlink, newUrl, relationshipId } of updates) {
564
617
  hyperlink.setUrl(newUrl);
618
+ if (relationshipId) {
619
+ this.relationshipManager.updateHyperlinkTarget(relationshipId, newUrl);
620
+ }
565
621
  }
566
622
  return updates.length;
567
623
  }
@@ -584,6 +640,484 @@ class Document {
584
640
  getSizeStats() {
585
641
  return this.validator.getSizeStats(this.bodyElements, this.imageManager);
586
642
  }
643
+ async getPart(partName) {
644
+ try {
645
+ const file = this.zipHandler.getFile(partName);
646
+ if (!file) {
647
+ return null;
648
+ }
649
+ return {
650
+ name: partName,
651
+ content: file.content,
652
+ contentType: this.getContentTypeForPart(partName),
653
+ isBinary: file.isBinary,
654
+ size: file.size,
655
+ };
656
+ }
657
+ catch (error) {
658
+ return null;
659
+ }
660
+ }
661
+ async setPart(partName, content) {
662
+ const isBinary = Buffer.isBuffer(content);
663
+ this.zipHandler.addFile(partName, content, { binary: isBinary });
664
+ }
665
+ async removePart(partName) {
666
+ return this.zipHandler.removeFile(partName);
667
+ }
668
+ async listParts() {
669
+ return this.zipHandler.getFilePaths();
670
+ }
671
+ async partExists(partName) {
672
+ return this.zipHandler.hasFile(partName);
673
+ }
674
+ async getContentTypes() {
675
+ const contentTypes = new Map();
676
+ try {
677
+ const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
678
+ if (!contentTypesXml) {
679
+ return contentTypes;
680
+ }
681
+ const defaultPattern = /<Default\s+Extension="([^"]+)"\s+ContentType="([^"]+)"/g;
682
+ let match;
683
+ while ((match = defaultPattern.exec(contentTypesXml)) !== null) {
684
+ if (match[1] && match[2]) {
685
+ contentTypes.set(`.${match[1]}`, match[2]);
686
+ }
687
+ }
688
+ const overridePattern = /<Override\s+PartName="([^"]+)"\s+ContentType="([^"]+)"/g;
689
+ while ((match = overridePattern.exec(contentTypesXml)) !== null) {
690
+ if (match[1] && match[2]) {
691
+ contentTypes.set(match[1], match[2]);
692
+ }
693
+ }
694
+ }
695
+ catch (error) {
696
+ }
697
+ return contentTypes;
698
+ }
699
+ async addContentType(partNameOrExtension, contentType) {
700
+ try {
701
+ let contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
702
+ if (!contentTypesXml) {
703
+ return false;
704
+ }
705
+ const isExtension = partNameOrExtension.startsWith('.');
706
+ if (isExtension) {
707
+ const extension = partNameOrExtension.substring(1);
708
+ const existingPattern = new RegExp(`<Default\\s+Extension="${extension}"\\s+ContentType="[^"]+"/?>`, 'g');
709
+ if (existingPattern.test(contentTypesXml)) {
710
+ contentTypesXml = contentTypesXml.replace(existingPattern, `<Default Extension="${extension}" ContentType="${contentType}"/>`);
711
+ }
712
+ else {
713
+ contentTypesXml = contentTypesXml.replace('</Types>', ` <Default Extension="${extension}" ContentType="${contentType}"/>\n</Types>`);
714
+ }
715
+ }
716
+ else {
717
+ const partName = partNameOrExtension.startsWith('/') ? partNameOrExtension : `/${partNameOrExtension}`;
718
+ const existingPattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="[^"]+"/?>`, 'g');
719
+ if (existingPattern.test(contentTypesXml)) {
720
+ contentTypesXml = contentTypesXml.replace(existingPattern, `<Override PartName="${partName}" ContentType="${contentType}"/>`);
721
+ }
722
+ else {
723
+ contentTypesXml = contentTypesXml.replace('</Types>', ` <Override PartName="${partName}" ContentType="${contentType}"/>\n</Types>`);
724
+ }
725
+ }
726
+ this.zipHandler.updateFile('[Content_Types].xml', contentTypesXml);
727
+ return true;
728
+ }
729
+ catch (error) {
730
+ return false;
731
+ }
732
+ }
733
+ async getAllRelationships() {
734
+ const relationships = new Map();
735
+ try {
736
+ const relsPaths = this.zipHandler.getFilePaths().filter(path => path.endsWith('.rels'));
737
+ for (const relsPath of relsPaths) {
738
+ const relsContent = this.zipHandler.getFileAsString(relsPath);
739
+ if (relsContent) {
740
+ const rels = [];
741
+ const relPattern = /<Relationship\s+([^>]+)\/>/g;
742
+ let match;
743
+ while ((match = relPattern.exec(relsContent)) !== null) {
744
+ const attrs = match[1];
745
+ if (!attrs)
746
+ continue;
747
+ const rel = {};
748
+ const idMatch = attrs.match(/Id="([^"]+)"/);
749
+ const typeMatch = attrs.match(/Type="([^"]+)"/);
750
+ const targetMatch = attrs.match(/Target="([^"]+)"/);
751
+ const modeMatch = attrs.match(/TargetMode="([^"]+)"/);
752
+ if (idMatch)
753
+ rel.id = idMatch[1];
754
+ if (typeMatch)
755
+ rel.type = typeMatch[1];
756
+ if (targetMatch)
757
+ rel.target = targetMatch[1];
758
+ if (modeMatch)
759
+ rel.targetMode = modeMatch[1];
760
+ rels.push(rel);
761
+ }
762
+ relationships.set(relsPath, rels);
763
+ }
764
+ }
765
+ }
766
+ catch (error) {
767
+ }
768
+ return relationships;
769
+ }
770
+ getContentTypeForPart(partName) {
771
+ try {
772
+ const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
773
+ if (!contentTypesXml) {
774
+ return undefined;
775
+ }
776
+ const overridePattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="([^"]+)"`, 'i');
777
+ const overrideMatch = contentTypesXml.match(overridePattern);
778
+ if (overrideMatch) {
779
+ return overrideMatch[1];
780
+ }
781
+ const ext = partName.substring(partName.lastIndexOf('.'));
782
+ if (ext) {
783
+ const defaultPattern = new RegExp(`<Default\\s+Extension="${ext.substring(1)}"\\s+ContentType="([^"]+)"`, 'i');
784
+ const defaultMatch = contentTypesXml.match(defaultPattern);
785
+ if (defaultMatch) {
786
+ return defaultMatch[1];
787
+ }
788
+ }
789
+ }
790
+ catch (error) {
791
+ }
792
+ return undefined;
793
+ }
794
+ findText(text, options) {
795
+ const results = [];
796
+ const caseSensitive = options?.caseSensitive ?? false;
797
+ const wholeWord = options?.wholeWord ?? false;
798
+ const searchText = caseSensitive ? text : text.toLowerCase();
799
+ const paragraphs = this.getParagraphs();
800
+ for (let pIndex = 0; pIndex < paragraphs.length; pIndex++) {
801
+ const paragraph = paragraphs[pIndex];
802
+ if (!paragraph)
803
+ continue;
804
+ const runs = paragraph.getRuns();
805
+ for (let rIndex = 0; rIndex < runs.length; rIndex++) {
806
+ const run = runs[rIndex];
807
+ if (!run)
808
+ continue;
809
+ const runText = run.getText();
810
+ const compareText = caseSensitive ? runText : runText.toLowerCase();
811
+ if (wholeWord) {
812
+ const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
813
+ let match;
814
+ while ((match = wordPattern.exec(runText)) !== null) {
815
+ results.push({
816
+ paragraph,
817
+ paragraphIndex: pIndex,
818
+ run,
819
+ runIndex: rIndex,
820
+ text: match[0],
821
+ startIndex: match.index,
822
+ });
823
+ }
824
+ }
825
+ else {
826
+ let startIndex = 0;
827
+ while ((startIndex = compareText.indexOf(searchText, startIndex)) !== -1) {
828
+ results.push({
829
+ paragraph,
830
+ paragraphIndex: pIndex,
831
+ run,
832
+ runIndex: rIndex,
833
+ text: runText.substr(startIndex, text.length),
834
+ startIndex,
835
+ });
836
+ startIndex += text.length;
837
+ }
838
+ }
839
+ }
840
+ }
841
+ for (const table of this.getTables()) {
842
+ for (const row of table.getRows()) {
843
+ for (const cell of row.getCells()) {
844
+ if (cell instanceof TableCell_1.TableCell) {
845
+ const cellParagraphs = cell.getParagraphs();
846
+ for (let pIndex = 0; pIndex < cellParagraphs.length; pIndex++) {
847
+ const paragraph = cellParagraphs[pIndex];
848
+ if (!paragraph)
849
+ continue;
850
+ const runs = paragraph.getRuns();
851
+ for (let rIndex = 0; rIndex < runs.length; rIndex++) {
852
+ const run = runs[rIndex];
853
+ if (!run)
854
+ continue;
855
+ const runText = run.getText();
856
+ const compareText = caseSensitive ? runText : runText.toLowerCase();
857
+ if (wholeWord) {
858
+ const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
859
+ let match;
860
+ while ((match = wordPattern.exec(runText)) !== null) {
861
+ results.push({
862
+ paragraph,
863
+ paragraphIndex: -1,
864
+ run,
865
+ runIndex: rIndex,
866
+ text: match[0],
867
+ startIndex: match.index,
868
+ });
869
+ }
870
+ }
871
+ else {
872
+ let startIndex = 0;
873
+ while ((startIndex = compareText.indexOf(searchText, startIndex)) !== -1) {
874
+ results.push({
875
+ paragraph,
876
+ paragraphIndex: -1,
877
+ run,
878
+ runIndex: rIndex,
879
+ text: runText.substr(startIndex, text.length),
880
+ startIndex,
881
+ });
882
+ startIndex += text.length;
883
+ }
884
+ }
885
+ }
886
+ }
887
+ }
888
+ }
889
+ }
890
+ }
891
+ return results;
892
+ }
893
+ replaceText(find, replace, options) {
894
+ let replacementCount = 0;
895
+ const caseSensitive = options?.caseSensitive ?? false;
896
+ const wholeWord = options?.wholeWord ?? false;
897
+ const paragraphs = this.getParagraphs();
898
+ for (const paragraph of paragraphs) {
899
+ const runs = paragraph.getRuns();
900
+ for (const run of runs) {
901
+ const originalText = run.getText();
902
+ let newText = originalText;
903
+ if (wholeWord) {
904
+ const wordPattern = new RegExp(`\\b${find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
905
+ const matches = originalText.match(wordPattern);
906
+ if (matches) {
907
+ replacementCount += matches.length;
908
+ newText = originalText.replace(wordPattern, replace);
909
+ }
910
+ }
911
+ else {
912
+ const searchPattern = new RegExp(find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), caseSensitive ? 'g' : 'gi');
913
+ const matches = originalText.match(searchPattern);
914
+ if (matches) {
915
+ replacementCount += matches.length;
916
+ newText = originalText.replace(searchPattern, replace);
917
+ }
918
+ }
919
+ if (newText !== originalText) {
920
+ run.setText(newText);
921
+ }
922
+ }
923
+ }
924
+ return replacementCount;
925
+ }
926
+ getWordCount() {
927
+ let totalWords = 0;
928
+ const paragraphs = this.getParagraphs();
929
+ for (const paragraph of paragraphs) {
930
+ const text = paragraph.getText().trim();
931
+ if (text) {
932
+ const words = text.split(/\s+/).filter(word => word.length > 0);
933
+ totalWords += words.length;
934
+ }
935
+ }
936
+ const tables = this.getTables();
937
+ for (const table of tables) {
938
+ const rows = table.getRows();
939
+ for (const row of rows) {
940
+ const cells = row.getCells();
941
+ for (const cell of cells) {
942
+ const cellParas = cell.getParagraphs();
943
+ for (const para of cellParas) {
944
+ const text = para.getText().trim();
945
+ if (text) {
946
+ const words = text.split(/\s+/).filter(word => word.length > 0);
947
+ totalWords += words.length;
948
+ }
949
+ }
950
+ }
951
+ }
952
+ }
953
+ return totalWords;
954
+ }
955
+ getCharacterCount(includeSpaces = true) {
956
+ let totalChars = 0;
957
+ const paragraphs = this.getParagraphs();
958
+ for (const paragraph of paragraphs) {
959
+ const text = paragraph.getText();
960
+ if (includeSpaces) {
961
+ totalChars += text.length;
962
+ }
963
+ else {
964
+ totalChars += text.replace(/\s/g, '').length;
965
+ }
966
+ }
967
+ const tables = this.getTables();
968
+ for (const table of tables) {
969
+ const rows = table.getRows();
970
+ for (const row of rows) {
971
+ const cells = row.getCells();
972
+ for (const cell of cells) {
973
+ const cellParas = cell.getParagraphs();
974
+ for (const para of cellParas) {
975
+ const text = para.getText();
976
+ if (includeSpaces) {
977
+ totalChars += text.length;
978
+ }
979
+ else {
980
+ totalChars += text.replace(/\s/g, '').length;
981
+ }
982
+ }
983
+ }
984
+ }
985
+ }
986
+ return totalChars;
987
+ }
988
+ removeParagraph(paragraphOrIndex) {
989
+ let index;
990
+ if (typeof paragraphOrIndex === 'number') {
991
+ index = paragraphOrIndex;
992
+ }
993
+ else {
994
+ index = this.bodyElements.indexOf(paragraphOrIndex);
995
+ }
996
+ if (index >= 0 && index < this.bodyElements.length) {
997
+ const element = this.bodyElements[index];
998
+ if (element instanceof Paragraph_1.Paragraph) {
999
+ this.bodyElements.splice(index, 1);
1000
+ return true;
1001
+ }
1002
+ }
1003
+ return false;
1004
+ }
1005
+ removeTable(tableOrIndex) {
1006
+ let index;
1007
+ if (typeof tableOrIndex === 'number') {
1008
+ const tables = this.getTables();
1009
+ if (tableOrIndex >= 0 && tableOrIndex < tables.length) {
1010
+ const table = tables[tableOrIndex];
1011
+ if (!table)
1012
+ return false;
1013
+ index = this.bodyElements.indexOf(table);
1014
+ }
1015
+ else {
1016
+ return false;
1017
+ }
1018
+ }
1019
+ else {
1020
+ index = this.bodyElements.indexOf(tableOrIndex);
1021
+ }
1022
+ if (index >= 0 && index < this.bodyElements.length) {
1023
+ const element = this.bodyElements[index];
1024
+ if (element instanceof Table_1.Table) {
1025
+ this.bodyElements.splice(index, 1);
1026
+ return true;
1027
+ }
1028
+ }
1029
+ return false;
1030
+ }
1031
+ insertParagraphAt(index, paragraph) {
1032
+ if (index < 0) {
1033
+ index = 0;
1034
+ }
1035
+ else if (index > this.bodyElements.length) {
1036
+ index = this.bodyElements.length;
1037
+ }
1038
+ this.bodyElements.splice(index, 0, paragraph);
1039
+ return this;
1040
+ }
1041
+ getHyperlinks() {
1042
+ const hyperlinks = [];
1043
+ for (const paragraph of this.getParagraphs()) {
1044
+ for (const content of paragraph.getContent()) {
1045
+ if (content instanceof Hyperlink_1.Hyperlink) {
1046
+ hyperlinks.push({ hyperlink: content, paragraph });
1047
+ }
1048
+ }
1049
+ }
1050
+ for (const table of this.getTables()) {
1051
+ for (const row of table.getRows()) {
1052
+ for (const cell of row.getCells()) {
1053
+ const cellParagraphs = cell.getParagraphs?.() || [];
1054
+ for (const para of cellParagraphs) {
1055
+ for (const content of para.getContent()) {
1056
+ if (content instanceof Hyperlink_1.Hyperlink) {
1057
+ hyperlinks.push({ hyperlink: content, paragraph: para });
1058
+ }
1059
+ }
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+ return hyperlinks;
1065
+ }
1066
+ getBookmarks() {
1067
+ const bookmarks = [];
1068
+ for (const paragraph of this.getParagraphs()) {
1069
+ for (const bookmark of paragraph.getBookmarksStart()) {
1070
+ bookmarks.push({ bookmark, paragraph });
1071
+ }
1072
+ }
1073
+ for (const table of this.getTables()) {
1074
+ for (const row of table.getRows()) {
1075
+ for (const cell of row.getCells()) {
1076
+ for (const para of cell.getParagraphs()) {
1077
+ for (const bookmark of para.getBookmarksStart()) {
1078
+ bookmarks.push({ bookmark, paragraph: para });
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1083
+ }
1084
+ return bookmarks;
1085
+ }
1086
+ getImages() {
1087
+ return this.imageManager.getAllImages();
1088
+ }
1089
+ setLanguage(language) {
1090
+ if (!this.properties) {
1091
+ this.properties = {};
1092
+ }
1093
+ this.properties.language = language;
1094
+ this.stylesManager.setDefaultLanguage?.(language);
1095
+ return this;
1096
+ }
1097
+ getLanguage() {
1098
+ return this.properties?.language;
1099
+ }
1100
+ static createEmpty() {
1101
+ const doc = new Document(undefined, {}, false);
1102
+ const zipHandler = doc.getZipHandler();
1103
+ zipHandler.addFile('[Content_Types].xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1104
+ '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\n' +
1105
+ ' <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\n' +
1106
+ ' <Default Extension="xml" ContentType="application/xml"/>\n' +
1107
+ ' <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>\n' +
1108
+ '</Types>');
1109
+ zipHandler.addFile('_rels/.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1110
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\n' +
1111
+ ' <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>\n' +
1112
+ '</Relationships>');
1113
+ zipHandler.addFile('word/document.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1114
+ '<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">\n' +
1115
+ ' <w:body/>\n' +
1116
+ '</w:document>');
1117
+ zipHandler.addFile('word/_rels/document.xml.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1118
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"/>');
1119
+ return doc;
1120
+ }
587
1121
  }
588
1122
  exports.Document = Document;
589
1123
  //# sourceMappingURL=Document.js.map