docxmlater 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.
- package/README.md +484 -561
- package/dist/core/Document.d.ts +60 -0
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +526 -4
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +6 -3
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/Relationship.d.ts +5 -0
- package/dist/core/Relationship.d.ts.map +1 -1
- package/dist/core/Relationship.js +27 -1
- package/dist/core/Relationship.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts +6 -0
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +45 -0
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/Endnote.d.ts +34 -0
- package/dist/elements/Endnote.d.ts.map +1 -0
- package/dist/elements/Endnote.js +96 -0
- package/dist/elements/Endnote.js.map +1 -0
- package/dist/elements/EndnoteManager.d.ts +26 -0
- package/dist/elements/EndnoteManager.d.ts.map +1 -0
- package/dist/elements/EndnoteManager.js +108 -0
- package/dist/elements/EndnoteManager.js.map +1 -0
- package/dist/elements/Footnote.d.ts +34 -0
- package/dist/elements/Footnote.d.ts.map +1 -0
- package/dist/elements/Footnote.js +96 -0
- package/dist/elements/Footnote.js.map +1 -0
- package/dist/elements/FootnoteManager.d.ts +26 -0
- package/dist/elements/FootnoteManager.d.ts.map +1 -0
- package/dist/elements/FootnoteManager.js +108 -0
- package/dist/elements/FootnoteManager.js.map +1 -0
- package/dist/elements/Hyperlink.d.ts +1 -0
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +53 -1
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts +4 -0
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +21 -0
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +39 -0
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +81 -25
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Run.d.ts +1 -0
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +36 -24
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Table.d.ts +6 -0
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +67 -1
- package/dist/elements/Table.js.map +1 -1
- package/dist/formatting/Style.d.ts +1 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +65 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +8 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +89 -0
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/types/formatting.d.ts +47 -0
- package/dist/types/formatting.d.ts.map +1 -0
- package/dist/types/formatting.js +3 -0
- package/dist/types/formatting.js.map +1 -0
- package/dist/utils/validation.d.ts +14 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +88 -3
- package/dist/utils/validation.js.map +1 -1
- package/package.json +1 -1
package/dist/core/Document.js
CHANGED
|
@@ -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,9 +48,12 @@ 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");
|
|
@@ -95,6 +99,8 @@ class Document {
|
|
|
95
99
|
this.bookmarkManager = BookmarkManager_1.BookmarkManager.create();
|
|
96
100
|
this.revisionManager = RevisionManager_1.RevisionManager.create();
|
|
97
101
|
this.commentManager = CommentManager_1.CommentManager.create();
|
|
102
|
+
this._footnoteManager = FootnoteManager_1.FootnoteManager.create();
|
|
103
|
+
this._endnoteManager = EndnoteManager_1.EndnoteManager.create();
|
|
98
104
|
if (initDefaults) {
|
|
99
105
|
this.relationshipManager.addStyles();
|
|
100
106
|
this.relationshipManager.addNumbering();
|
|
@@ -284,6 +290,7 @@ class Document {
|
|
|
284
290
|
}
|
|
285
291
|
addStyle(style) {
|
|
286
292
|
this.stylesManager.addStyle(style);
|
|
293
|
+
this.updateStylesXml();
|
|
287
294
|
return this;
|
|
288
295
|
}
|
|
289
296
|
getStyle(styleId) {
|
|
@@ -292,6 +299,31 @@ class Document {
|
|
|
292
299
|
hasStyle(styleId) {
|
|
293
300
|
return this.stylesManager.hasStyle(styleId);
|
|
294
301
|
}
|
|
302
|
+
getStyles() {
|
|
303
|
+
return this.stylesManager.getAllStyles();
|
|
304
|
+
}
|
|
305
|
+
removeStyle(styleId) {
|
|
306
|
+
return this.stylesManager.removeStyle(styleId);
|
|
307
|
+
}
|
|
308
|
+
updateStyle(styleId, properties) {
|
|
309
|
+
const style = this.stylesManager.getStyle(styleId);
|
|
310
|
+
if (!style) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
const currentProps = style.getProperties();
|
|
314
|
+
const updatedProps = { ...currentProps, ...properties, styleId };
|
|
315
|
+
const updatedStyle = Style_1.Style.create(updatedProps);
|
|
316
|
+
this.stylesManager.addStyle(updatedStyle);
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
319
|
+
getStylesXml() {
|
|
320
|
+
const stylesFile = this.zipHandler.getFileAsString(types_1.DOCX_PATHS.STYLES);
|
|
321
|
+
return stylesFile || this.stylesManager.generateStylesXml();
|
|
322
|
+
}
|
|
323
|
+
setStylesXml(xml) {
|
|
324
|
+
this.zipHandler.updateFile(types_1.DOCX_PATHS.STYLES, xml);
|
|
325
|
+
this.stylesManager.clear();
|
|
326
|
+
}
|
|
295
327
|
getZipHandler() {
|
|
296
328
|
return this.zipHandler;
|
|
297
329
|
}
|
|
@@ -545,20 +577,32 @@ class Document {
|
|
|
545
577
|
return this.parser.getParseErrors();
|
|
546
578
|
}
|
|
547
579
|
updateHyperlinkUrls(urlMap) {
|
|
548
|
-
|
|
580
|
+
if (urlMap.size === 0) {
|
|
581
|
+
return 0;
|
|
582
|
+
}
|
|
583
|
+
const updates = [];
|
|
549
584
|
for (const para of this.getParagraphs()) {
|
|
550
585
|
for (const content of para.getContent()) {
|
|
551
586
|
if (content instanceof Hyperlink_1.Hyperlink && content.isExternal()) {
|
|
552
587
|
const currentUrl = content.getUrl();
|
|
553
588
|
if (currentUrl && urlMap.has(currentUrl)) {
|
|
554
589
|
const newUrl = urlMap.get(currentUrl);
|
|
555
|
-
|
|
556
|
-
|
|
590
|
+
updates.push({
|
|
591
|
+
hyperlink: content,
|
|
592
|
+
newUrl,
|
|
593
|
+
relationshipId: content.getRelationshipId()
|
|
594
|
+
});
|
|
557
595
|
}
|
|
558
596
|
}
|
|
559
597
|
}
|
|
560
598
|
}
|
|
561
|
-
|
|
599
|
+
for (const { hyperlink, newUrl, relationshipId } of updates) {
|
|
600
|
+
hyperlink.setUrl(newUrl);
|
|
601
|
+
if (relationshipId) {
|
|
602
|
+
this.relationshipManager.updateHyperlinkTarget(relationshipId, newUrl);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return updates.length;
|
|
562
606
|
}
|
|
563
607
|
estimateSize() {
|
|
564
608
|
return this.validator.estimateSize(this.bodyElements, this.imageManager);
|
|
@@ -579,6 +623,484 @@ class Document {
|
|
|
579
623
|
getSizeStats() {
|
|
580
624
|
return this.validator.getSizeStats(this.bodyElements, this.imageManager);
|
|
581
625
|
}
|
|
626
|
+
async getPart(partName) {
|
|
627
|
+
try {
|
|
628
|
+
const file = this.zipHandler.getFile(partName);
|
|
629
|
+
if (!file) {
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
return {
|
|
633
|
+
name: partName,
|
|
634
|
+
content: file.content,
|
|
635
|
+
contentType: this.getContentTypeForPart(partName),
|
|
636
|
+
isBinary: file.isBinary,
|
|
637
|
+
size: file.size,
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
return null;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
async setPart(partName, content) {
|
|
645
|
+
const isBinary = Buffer.isBuffer(content);
|
|
646
|
+
this.zipHandler.addFile(partName, content, { binary: isBinary });
|
|
647
|
+
}
|
|
648
|
+
async removePart(partName) {
|
|
649
|
+
return this.zipHandler.removeFile(partName);
|
|
650
|
+
}
|
|
651
|
+
async listParts() {
|
|
652
|
+
return this.zipHandler.getFilePaths();
|
|
653
|
+
}
|
|
654
|
+
async partExists(partName) {
|
|
655
|
+
return this.zipHandler.hasFile(partName);
|
|
656
|
+
}
|
|
657
|
+
async getContentTypes() {
|
|
658
|
+
const contentTypes = new Map();
|
|
659
|
+
try {
|
|
660
|
+
const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
|
|
661
|
+
if (!contentTypesXml) {
|
|
662
|
+
return contentTypes;
|
|
663
|
+
}
|
|
664
|
+
const defaultPattern = /<Default\s+Extension="([^"]+)"\s+ContentType="([^"]+)"/g;
|
|
665
|
+
let match;
|
|
666
|
+
while ((match = defaultPattern.exec(contentTypesXml)) !== null) {
|
|
667
|
+
if (match[1] && match[2]) {
|
|
668
|
+
contentTypes.set(`.${match[1]}`, match[2]);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
const overridePattern = /<Override\s+PartName="([^"]+)"\s+ContentType="([^"]+)"/g;
|
|
672
|
+
while ((match = overridePattern.exec(contentTypesXml)) !== null) {
|
|
673
|
+
if (match[1] && match[2]) {
|
|
674
|
+
contentTypes.set(match[1], match[2]);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
}
|
|
680
|
+
return contentTypes;
|
|
681
|
+
}
|
|
682
|
+
async addContentType(partNameOrExtension, contentType) {
|
|
683
|
+
try {
|
|
684
|
+
let contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
|
|
685
|
+
if (!contentTypesXml) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
const isExtension = partNameOrExtension.startsWith('.');
|
|
689
|
+
if (isExtension) {
|
|
690
|
+
const extension = partNameOrExtension.substring(1);
|
|
691
|
+
const existingPattern = new RegExp(`<Default\\s+Extension="${extension}"\\s+ContentType="[^"]+"/?>`, 'g');
|
|
692
|
+
if (existingPattern.test(contentTypesXml)) {
|
|
693
|
+
contentTypesXml = contentTypesXml.replace(existingPattern, `<Default Extension="${extension}" ContentType="${contentType}"/>`);
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
contentTypesXml = contentTypesXml.replace('</Types>', ` <Default Extension="${extension}" ContentType="${contentType}"/>\n</Types>`);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
const partName = partNameOrExtension.startsWith('/') ? partNameOrExtension : `/${partNameOrExtension}`;
|
|
701
|
+
const existingPattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="[^"]+"/?>`, 'g');
|
|
702
|
+
if (existingPattern.test(contentTypesXml)) {
|
|
703
|
+
contentTypesXml = contentTypesXml.replace(existingPattern, `<Override PartName="${partName}" ContentType="${contentType}"/>`);
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
contentTypesXml = contentTypesXml.replace('</Types>', ` <Override PartName="${partName}" ContentType="${contentType}"/>\n</Types>`);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
this.zipHandler.updateFile('[Content_Types].xml', contentTypesXml);
|
|
710
|
+
return true;
|
|
711
|
+
}
|
|
712
|
+
catch (error) {
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
async getAllRelationships() {
|
|
717
|
+
const relationships = new Map();
|
|
718
|
+
try {
|
|
719
|
+
const relsPaths = this.zipHandler.getFilePaths().filter(path => path.endsWith('.rels'));
|
|
720
|
+
for (const relsPath of relsPaths) {
|
|
721
|
+
const relsContent = this.zipHandler.getFileAsString(relsPath);
|
|
722
|
+
if (relsContent) {
|
|
723
|
+
const rels = [];
|
|
724
|
+
const relPattern = /<Relationship\s+([^>]+)\/>/g;
|
|
725
|
+
let match;
|
|
726
|
+
while ((match = relPattern.exec(relsContent)) !== null) {
|
|
727
|
+
const attrs = match[1];
|
|
728
|
+
if (!attrs)
|
|
729
|
+
continue;
|
|
730
|
+
const rel = {};
|
|
731
|
+
const idMatch = attrs.match(/Id="([^"]+)"/);
|
|
732
|
+
const typeMatch = attrs.match(/Type="([^"]+)"/);
|
|
733
|
+
const targetMatch = attrs.match(/Target="([^"]+)"/);
|
|
734
|
+
const modeMatch = attrs.match(/TargetMode="([^"]+)"/);
|
|
735
|
+
if (idMatch)
|
|
736
|
+
rel.id = idMatch[1];
|
|
737
|
+
if (typeMatch)
|
|
738
|
+
rel.type = typeMatch[1];
|
|
739
|
+
if (targetMatch)
|
|
740
|
+
rel.target = targetMatch[1];
|
|
741
|
+
if (modeMatch)
|
|
742
|
+
rel.targetMode = modeMatch[1];
|
|
743
|
+
rels.push(rel);
|
|
744
|
+
}
|
|
745
|
+
relationships.set(relsPath, rels);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
catch (error) {
|
|
750
|
+
}
|
|
751
|
+
return relationships;
|
|
752
|
+
}
|
|
753
|
+
getContentTypeForPart(partName) {
|
|
754
|
+
try {
|
|
755
|
+
const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
|
|
756
|
+
if (!contentTypesXml) {
|
|
757
|
+
return undefined;
|
|
758
|
+
}
|
|
759
|
+
const overridePattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="([^"]+)"`, 'i');
|
|
760
|
+
const overrideMatch = contentTypesXml.match(overridePattern);
|
|
761
|
+
if (overrideMatch) {
|
|
762
|
+
return overrideMatch[1];
|
|
763
|
+
}
|
|
764
|
+
const ext = partName.substring(partName.lastIndexOf('.'));
|
|
765
|
+
if (ext) {
|
|
766
|
+
const defaultPattern = new RegExp(`<Default\\s+Extension="${ext.substring(1)}"\\s+ContentType="([^"]+)"`, 'i');
|
|
767
|
+
const defaultMatch = contentTypesXml.match(defaultPattern);
|
|
768
|
+
if (defaultMatch) {
|
|
769
|
+
return defaultMatch[1];
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
catch (error) {
|
|
774
|
+
}
|
|
775
|
+
return undefined;
|
|
776
|
+
}
|
|
777
|
+
findText(text, options) {
|
|
778
|
+
const results = [];
|
|
779
|
+
const caseSensitive = options?.caseSensitive ?? false;
|
|
780
|
+
const wholeWord = options?.wholeWord ?? false;
|
|
781
|
+
const searchText = caseSensitive ? text : text.toLowerCase();
|
|
782
|
+
const paragraphs = this.getParagraphs();
|
|
783
|
+
for (let pIndex = 0; pIndex < paragraphs.length; pIndex++) {
|
|
784
|
+
const paragraph = paragraphs[pIndex];
|
|
785
|
+
if (!paragraph)
|
|
786
|
+
continue;
|
|
787
|
+
const runs = paragraph.getRuns();
|
|
788
|
+
for (let rIndex = 0; rIndex < runs.length; rIndex++) {
|
|
789
|
+
const run = runs[rIndex];
|
|
790
|
+
if (!run)
|
|
791
|
+
continue;
|
|
792
|
+
const runText = run.getText();
|
|
793
|
+
const compareText = caseSensitive ? runText : runText.toLowerCase();
|
|
794
|
+
if (wholeWord) {
|
|
795
|
+
const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
|
|
796
|
+
let match;
|
|
797
|
+
while ((match = wordPattern.exec(runText)) !== null) {
|
|
798
|
+
results.push({
|
|
799
|
+
paragraph,
|
|
800
|
+
paragraphIndex: pIndex,
|
|
801
|
+
run,
|
|
802
|
+
runIndex: rIndex,
|
|
803
|
+
text: match[0],
|
|
804
|
+
startIndex: match.index,
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
let startIndex = 0;
|
|
810
|
+
while ((startIndex = compareText.indexOf(searchText, startIndex)) !== -1) {
|
|
811
|
+
results.push({
|
|
812
|
+
paragraph,
|
|
813
|
+
paragraphIndex: pIndex,
|
|
814
|
+
run,
|
|
815
|
+
runIndex: rIndex,
|
|
816
|
+
text: runText.substr(startIndex, text.length),
|
|
817
|
+
startIndex,
|
|
818
|
+
});
|
|
819
|
+
startIndex += text.length;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
for (const table of this.getTables()) {
|
|
825
|
+
for (const row of table.getRows()) {
|
|
826
|
+
for (const cell of row.getCells()) {
|
|
827
|
+
if (cell instanceof TableCell_1.TableCell) {
|
|
828
|
+
const cellParagraphs = cell.getParagraphs();
|
|
829
|
+
for (let pIndex = 0; pIndex < cellParagraphs.length; pIndex++) {
|
|
830
|
+
const paragraph = cellParagraphs[pIndex];
|
|
831
|
+
if (!paragraph)
|
|
832
|
+
continue;
|
|
833
|
+
const runs = paragraph.getRuns();
|
|
834
|
+
for (let rIndex = 0; rIndex < runs.length; rIndex++) {
|
|
835
|
+
const run = runs[rIndex];
|
|
836
|
+
if (!run)
|
|
837
|
+
continue;
|
|
838
|
+
const runText = run.getText();
|
|
839
|
+
const compareText = caseSensitive ? runText : runText.toLowerCase();
|
|
840
|
+
if (wholeWord) {
|
|
841
|
+
const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
|
|
842
|
+
let match;
|
|
843
|
+
while ((match = wordPattern.exec(runText)) !== null) {
|
|
844
|
+
results.push({
|
|
845
|
+
paragraph,
|
|
846
|
+
paragraphIndex: -1,
|
|
847
|
+
run,
|
|
848
|
+
runIndex: rIndex,
|
|
849
|
+
text: match[0],
|
|
850
|
+
startIndex: match.index,
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
let startIndex = 0;
|
|
856
|
+
while ((startIndex = compareText.indexOf(searchText, startIndex)) !== -1) {
|
|
857
|
+
results.push({
|
|
858
|
+
paragraph,
|
|
859
|
+
paragraphIndex: -1,
|
|
860
|
+
run,
|
|
861
|
+
runIndex: rIndex,
|
|
862
|
+
text: runText.substr(startIndex, text.length),
|
|
863
|
+
startIndex,
|
|
864
|
+
});
|
|
865
|
+
startIndex += text.length;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return results;
|
|
875
|
+
}
|
|
876
|
+
replaceText(find, replace, options) {
|
|
877
|
+
let replacementCount = 0;
|
|
878
|
+
const caseSensitive = options?.caseSensitive ?? false;
|
|
879
|
+
const wholeWord = options?.wholeWord ?? false;
|
|
880
|
+
const paragraphs = this.getParagraphs();
|
|
881
|
+
for (const paragraph of paragraphs) {
|
|
882
|
+
const runs = paragraph.getRuns();
|
|
883
|
+
for (const run of runs) {
|
|
884
|
+
const originalText = run.getText();
|
|
885
|
+
let newText = originalText;
|
|
886
|
+
if (wholeWord) {
|
|
887
|
+
const wordPattern = new RegExp(`\\b${find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
|
|
888
|
+
const matches = originalText.match(wordPattern);
|
|
889
|
+
if (matches) {
|
|
890
|
+
replacementCount += matches.length;
|
|
891
|
+
newText = originalText.replace(wordPattern, replace);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
const searchPattern = new RegExp(find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), caseSensitive ? 'g' : 'gi');
|
|
896
|
+
const matches = originalText.match(searchPattern);
|
|
897
|
+
if (matches) {
|
|
898
|
+
replacementCount += matches.length;
|
|
899
|
+
newText = originalText.replace(searchPattern, replace);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
if (newText !== originalText) {
|
|
903
|
+
run.setText(newText);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return replacementCount;
|
|
908
|
+
}
|
|
909
|
+
getWordCount() {
|
|
910
|
+
let totalWords = 0;
|
|
911
|
+
const paragraphs = this.getParagraphs();
|
|
912
|
+
for (const paragraph of paragraphs) {
|
|
913
|
+
const text = paragraph.getText().trim();
|
|
914
|
+
if (text) {
|
|
915
|
+
const words = text.split(/\s+/).filter(word => word.length > 0);
|
|
916
|
+
totalWords += words.length;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
const tables = this.getTables();
|
|
920
|
+
for (const table of tables) {
|
|
921
|
+
const rows = table.getRows();
|
|
922
|
+
for (const row of rows) {
|
|
923
|
+
const cells = row.getCells();
|
|
924
|
+
for (const cell of cells) {
|
|
925
|
+
const cellParas = cell.getParagraphs();
|
|
926
|
+
for (const para of cellParas) {
|
|
927
|
+
const text = para.getText().trim();
|
|
928
|
+
if (text) {
|
|
929
|
+
const words = text.split(/\s+/).filter(word => word.length > 0);
|
|
930
|
+
totalWords += words.length;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
return totalWords;
|
|
937
|
+
}
|
|
938
|
+
getCharacterCount(includeSpaces = true) {
|
|
939
|
+
let totalChars = 0;
|
|
940
|
+
const paragraphs = this.getParagraphs();
|
|
941
|
+
for (const paragraph of paragraphs) {
|
|
942
|
+
const text = paragraph.getText();
|
|
943
|
+
if (includeSpaces) {
|
|
944
|
+
totalChars += text.length;
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
totalChars += text.replace(/\s/g, '').length;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const tables = this.getTables();
|
|
951
|
+
for (const table of tables) {
|
|
952
|
+
const rows = table.getRows();
|
|
953
|
+
for (const row of rows) {
|
|
954
|
+
const cells = row.getCells();
|
|
955
|
+
for (const cell of cells) {
|
|
956
|
+
const cellParas = cell.getParagraphs();
|
|
957
|
+
for (const para of cellParas) {
|
|
958
|
+
const text = para.getText();
|
|
959
|
+
if (includeSpaces) {
|
|
960
|
+
totalChars += text.length;
|
|
961
|
+
}
|
|
962
|
+
else {
|
|
963
|
+
totalChars += text.replace(/\s/g, '').length;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return totalChars;
|
|
970
|
+
}
|
|
971
|
+
removeParagraph(paragraphOrIndex) {
|
|
972
|
+
let index;
|
|
973
|
+
if (typeof paragraphOrIndex === 'number') {
|
|
974
|
+
index = paragraphOrIndex;
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
index = this.bodyElements.indexOf(paragraphOrIndex);
|
|
978
|
+
}
|
|
979
|
+
if (index >= 0 && index < this.bodyElements.length) {
|
|
980
|
+
const element = this.bodyElements[index];
|
|
981
|
+
if (element instanceof Paragraph_1.Paragraph) {
|
|
982
|
+
this.bodyElements.splice(index, 1);
|
|
983
|
+
return true;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
removeTable(tableOrIndex) {
|
|
989
|
+
let index;
|
|
990
|
+
if (typeof tableOrIndex === 'number') {
|
|
991
|
+
const tables = this.getTables();
|
|
992
|
+
if (tableOrIndex >= 0 && tableOrIndex < tables.length) {
|
|
993
|
+
const table = tables[tableOrIndex];
|
|
994
|
+
if (!table)
|
|
995
|
+
return false;
|
|
996
|
+
index = this.bodyElements.indexOf(table);
|
|
997
|
+
}
|
|
998
|
+
else {
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
index = this.bodyElements.indexOf(tableOrIndex);
|
|
1004
|
+
}
|
|
1005
|
+
if (index >= 0 && index < this.bodyElements.length) {
|
|
1006
|
+
const element = this.bodyElements[index];
|
|
1007
|
+
if (element instanceof Table_1.Table) {
|
|
1008
|
+
this.bodyElements.splice(index, 1);
|
|
1009
|
+
return true;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return false;
|
|
1013
|
+
}
|
|
1014
|
+
insertParagraphAt(index, paragraph) {
|
|
1015
|
+
if (index < 0) {
|
|
1016
|
+
index = 0;
|
|
1017
|
+
}
|
|
1018
|
+
else if (index > this.bodyElements.length) {
|
|
1019
|
+
index = this.bodyElements.length;
|
|
1020
|
+
}
|
|
1021
|
+
this.bodyElements.splice(index, 0, paragraph);
|
|
1022
|
+
return this;
|
|
1023
|
+
}
|
|
1024
|
+
getHyperlinks() {
|
|
1025
|
+
const hyperlinks = [];
|
|
1026
|
+
for (const paragraph of this.getParagraphs()) {
|
|
1027
|
+
for (const content of paragraph.getContent()) {
|
|
1028
|
+
if (content instanceof Hyperlink_1.Hyperlink) {
|
|
1029
|
+
hyperlinks.push({ hyperlink: content, paragraph });
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
for (const table of this.getTables()) {
|
|
1034
|
+
for (const row of table.getRows()) {
|
|
1035
|
+
for (const cell of row.getCells()) {
|
|
1036
|
+
const cellParagraphs = cell.getParagraphs?.() || [];
|
|
1037
|
+
for (const para of cellParagraphs) {
|
|
1038
|
+
for (const content of para.getContent()) {
|
|
1039
|
+
if (content instanceof Hyperlink_1.Hyperlink) {
|
|
1040
|
+
hyperlinks.push({ hyperlink: content, paragraph: para });
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
return hyperlinks;
|
|
1048
|
+
}
|
|
1049
|
+
getBookmarks() {
|
|
1050
|
+
const bookmarks = [];
|
|
1051
|
+
for (const paragraph of this.getParagraphs()) {
|
|
1052
|
+
for (const bookmark of paragraph.getBookmarksStart()) {
|
|
1053
|
+
bookmarks.push({ bookmark, paragraph });
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
for (const table of this.getTables()) {
|
|
1057
|
+
for (const row of table.getRows()) {
|
|
1058
|
+
for (const cell of row.getCells()) {
|
|
1059
|
+
for (const para of cell.getParagraphs()) {
|
|
1060
|
+
for (const bookmark of para.getBookmarksStart()) {
|
|
1061
|
+
bookmarks.push({ bookmark, paragraph: para });
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return bookmarks;
|
|
1068
|
+
}
|
|
1069
|
+
getImages() {
|
|
1070
|
+
return this.imageManager.getAllImages();
|
|
1071
|
+
}
|
|
1072
|
+
setLanguage(language) {
|
|
1073
|
+
if (!this.properties) {
|
|
1074
|
+
this.properties = {};
|
|
1075
|
+
}
|
|
1076
|
+
this.properties.language = language;
|
|
1077
|
+
this.stylesManager.setDefaultLanguage?.(language);
|
|
1078
|
+
return this;
|
|
1079
|
+
}
|
|
1080
|
+
getLanguage() {
|
|
1081
|
+
return this.properties?.language;
|
|
1082
|
+
}
|
|
1083
|
+
static createEmpty() {
|
|
1084
|
+
const doc = new Document(undefined, {}, false);
|
|
1085
|
+
const zipHandler = doc.getZipHandler();
|
|
1086
|
+
zipHandler.addFile('[Content_Types].xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
|
|
1087
|
+
'<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\n' +
|
|
1088
|
+
' <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\n' +
|
|
1089
|
+
' <Default Extension="xml" ContentType="application/xml"/>\n' +
|
|
1090
|
+
' <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>\n' +
|
|
1091
|
+
'</Types>');
|
|
1092
|
+
zipHandler.addFile('_rels/.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
|
|
1093
|
+
'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\n' +
|
|
1094
|
+
' <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>\n' +
|
|
1095
|
+
'</Relationships>');
|
|
1096
|
+
zipHandler.addFile('word/document.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
|
|
1097
|
+
'<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">\n' +
|
|
1098
|
+
' <w:body/>\n' +
|
|
1099
|
+
'</w:document>');
|
|
1100
|
+
zipHandler.addFile('word/_rels/document.xml.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
|
|
1101
|
+
'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"/>');
|
|
1102
|
+
return doc;
|
|
1103
|
+
}
|
|
582
1104
|
}
|
|
583
1105
|
exports.Document = Document;
|
|
584
1106
|
//# sourceMappingURL=Document.js.map
|