docxmlater 11.0.9 → 12.0.1
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 +51 -13
- package/dist/core/Document.d.ts +28 -2
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +725 -170
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts +1 -0
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +77 -25
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +7 -3
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +431 -85
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +2 -2
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/Comment.d.ts +15 -1
- package/dist/elements/Comment.d.ts.map +1 -1
- package/dist/elements/Comment.js +67 -12
- package/dist/elements/Comment.js.map +1 -1
- package/dist/elements/CommentManager.d.ts +4 -0
- package/dist/elements/CommentManager.d.ts.map +1 -1
- package/dist/elements/CommentManager.js +74 -16
- package/dist/elements/CommentManager.js.map +1 -1
- package/dist/elements/EndnoteManager.d.ts.map +1 -1
- package/dist/elements/EndnoteManager.js.map +1 -1
- package/dist/elements/Field.d.ts +10 -1
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +76 -34
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/FieldHelpers.d.ts +1 -0
- package/dist/elements/FieldHelpers.d.ts.map +1 -1
- package/dist/elements/FieldHelpers.js +8 -4
- package/dist/elements/FieldHelpers.js.map +1 -1
- package/dist/elements/Footer.d.ts +3 -1
- package/dist/elements/Footer.d.ts.map +1 -1
- package/dist/elements/Footer.js +39 -53
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/FootnoteManager.d.ts.map +1 -1
- package/dist/elements/FootnoteManager.js.map +1 -1
- package/dist/elements/Header.d.ts +3 -1
- package/dist/elements/Header.d.ts.map +1 -1
- package/dist/elements/Header.js +39 -53
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/HeaderFooterManager.d.ts +4 -2
- package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
- package/dist/elements/HeaderFooterManager.js +36 -6
- package/dist/elements/HeaderFooterManager.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +6 -1
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +69 -44
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +33 -6
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/ImageManager.d.ts +1 -0
- package/dist/elements/ImageManager.d.ts.map +1 -1
- package/dist/elements/ImageManager.js +11 -0
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +3 -0
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +91 -26
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Revision.d.ts +4 -0
- package/dist/elements/Revision.d.ts.map +1 -1
- package/dist/elements/Revision.js +369 -29
- package/dist/elements/Revision.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 +24 -4
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +17 -7
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Shape.d.ts.map +1 -1
- package/dist/elements/Shape.js +50 -42
- package/dist/elements/Shape.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +9 -1
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
- package/dist/elements/StructuredDocumentTag.js +46 -6
- package/dist/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/elements/Table.d.ts +2 -0
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +90 -42
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +1 -0
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +32 -13
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +5 -7
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableRow.d.ts +1 -0
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +16 -1
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/elements/TextBox.d.ts.map +1 -1
- package/dist/elements/TextBox.js +55 -42
- package/dist/elements/TextBox.js.map +1 -1
- package/dist/esm/core/Document.js +726 -171
- package/dist/esm/core/Document.js.map +1 -1
- package/dist/esm/core/DocumentGenerator.js +77 -25
- package/dist/esm/core/DocumentGenerator.js.map +1 -1
- package/dist/esm/core/DocumentParser.js +431 -85
- package/dist/esm/core/DocumentParser.js.map +1 -1
- package/dist/esm/core/RelationshipManager.js +2 -2
- package/dist/esm/core/RelationshipManager.js.map +1 -1
- package/dist/esm/elements/Comment.js +67 -12
- package/dist/esm/elements/Comment.js.map +1 -1
- package/dist/esm/elements/CommentManager.js +74 -16
- package/dist/esm/elements/CommentManager.js.map +1 -1
- package/dist/esm/elements/EndnoteManager.js.map +1 -1
- package/dist/esm/elements/Field.js +77 -35
- package/dist/esm/elements/Field.js.map +1 -1
- package/dist/esm/elements/FieldHelpers.js +7 -4
- package/dist/esm/elements/FieldHelpers.js.map +1 -1
- package/dist/esm/elements/Footer.js +39 -53
- package/dist/esm/elements/Footer.js.map +1 -1
- package/dist/esm/elements/FootnoteManager.js.map +1 -1
- package/dist/esm/elements/Header.js +39 -53
- package/dist/esm/elements/Header.js.map +1 -1
- package/dist/esm/elements/HeaderFooterManager.js +36 -6
- package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
- package/dist/esm/elements/Hyperlink.js +69 -44
- package/dist/esm/elements/Hyperlink.js.map +1 -1
- package/dist/esm/elements/Image.js +33 -6
- package/dist/esm/elements/Image.js.map +1 -1
- package/dist/esm/elements/ImageManager.js +11 -0
- package/dist/esm/elements/ImageManager.js.map +1 -1
- package/dist/esm/elements/Paragraph.js +91 -26
- package/dist/esm/elements/Paragraph.js.map +1 -1
- package/dist/esm/elements/Revision.js +369 -29
- package/dist/esm/elements/Revision.js.map +1 -1
- package/dist/esm/elements/Run.js +24 -4
- package/dist/esm/elements/Run.js.map +1 -1
- package/dist/esm/elements/Section.js +17 -7
- package/dist/esm/elements/Section.js.map +1 -1
- package/dist/esm/elements/Shape.js +50 -42
- package/dist/esm/elements/Shape.js.map +1 -1
- package/dist/esm/elements/StructuredDocumentTag.js +46 -6
- package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/esm/elements/Table.js +90 -42
- package/dist/esm/elements/Table.js.map +1 -1
- package/dist/esm/elements/TableCell.js +32 -13
- package/dist/esm/elements/TableCell.js.map +1 -1
- package/dist/esm/elements/TableOfContents.js +5 -7
- package/dist/esm/elements/TableOfContents.js.map +1 -1
- package/dist/esm/elements/TableRow.js +16 -1
- package/dist/esm/elements/TableRow.js.map +1 -1
- package/dist/esm/elements/TextBox.js +55 -42
- package/dist/esm/elements/TextBox.js.map +1 -1
- package/dist/esm/formatting/AbstractNumbering.js +1 -1
- package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
- package/dist/esm/formatting/NumberingLevel.js +8 -6
- package/dist/esm/formatting/NumberingLevel.js.map +1 -1
- package/dist/esm/formatting/NumberingManager.js +16 -1
- package/dist/esm/formatting/NumberingManager.js.map +1 -1
- package/dist/esm/formatting/Style.js +14 -0
- package/dist/esm/formatting/Style.js.map +1 -1
- package/dist/esm/formatting/StylesManager.js +14 -2
- package/dist/esm/formatting/StylesManager.js.map +1 -1
- package/dist/esm/helpers/CleanupHelper.js +103 -26
- package/dist/esm/helpers/CleanupHelper.js.map +1 -1
- package/dist/esm/images/ImageOptimizer.js +52 -4
- package/dist/esm/images/ImageOptimizer.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal.js +1 -1
- package/dist/esm/internal.js.map +1 -1
- package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
- package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
- package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
- package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
- package/dist/esm/processors/RevisionWalker.js +58 -8
- package/dist/esm/processors/RevisionWalker.js.map +1 -1
- package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
- package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
- package/dist/esm/processors/cnfStyleDecoder.js +7 -7
- package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
- package/dist/esm/processors/stripTrackedChanges.js +16 -5
- package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
- package/dist/esm/utils/deepClone.js +24 -11
- package/dist/esm/utils/deepClone.js.map +1 -1
- package/dist/esm/utils/units.js +1 -1
- package/dist/esm/utils/units.js.map +1 -1
- package/dist/esm/utils/validation.js +11 -23
- package/dist/esm/utils/validation.js.map +1 -1
- package/dist/esm/utils/xmlSanitization.js +131 -7
- package/dist/esm/utils/xmlSanitization.js.map +1 -1
- package/dist/esm/validation/RevisionAutoFixer.js +69 -55
- package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/esm/validation/RevisionValidator.js +24 -20
- package/dist/esm/validation/RevisionValidator.js.map +1 -1
- package/dist/esm/xml/XMLBuilder.js +52 -20
- package/dist/esm/xml/XMLBuilder.js.map +1 -1
- package/dist/esm/xml/XMLParser.js +55 -13
- package/dist/esm/xml/XMLParser.js.map +1 -1
- package/dist/esm/zip/ZipHandler.js +37 -13
- package/dist/esm/zip/ZipHandler.js.map +1 -1
- package/dist/esm/zip/ZipReader.js +53 -6
- package/dist/esm/zip/ZipReader.js.map +1 -1
- package/dist/esm/zip/errors.js +7 -0
- package/dist/esm/zip/errors.js.map +1 -1
- package/dist/esm/zip/types.js +4 -0
- package/dist/esm/zip/types.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +1 -1
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +1 -1
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +8 -6
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +16 -1
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +14 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +2 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +14 -2
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/helpers/CleanupHelper.d.ts.map +1 -1
- package/dist/helpers/CleanupHelper.js +103 -26
- package/dist/helpers/CleanupHelper.js.map +1 -1
- package/dist/images/ImageOptimizer.d.ts.map +1 -1
- package/dist/images/ImageOptimizer.js +52 -4
- package/dist/images/ImageOptimizer.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -1
- package/dist/internal.js.map +1 -1
- package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
- package/dist/processors/CompatibilityUpgrader.js +7 -1
- package/dist/processors/CompatibilityUpgrader.js.map +1 -1
- package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
- package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
- package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
- package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
- package/dist/processors/RevisionWalker.d.ts +2 -0
- package/dist/processors/RevisionWalker.d.ts.map +1 -1
- package/dist/processors/RevisionWalker.js +58 -8
- package/dist/processors/RevisionWalker.js.map +1 -1
- package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
- package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
- package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
- package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
- package/dist/processors/cnfStyleDecoder.js +7 -7
- package/dist/processors/cnfStyleDecoder.js.map +1 -1
- package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
- package/dist/processors/stripTrackedChanges.js +16 -5
- package/dist/processors/stripTrackedChanges.js.map +1 -1
- package/dist/utils/deepClone.d.ts.map +1 -1
- package/dist/utils/deepClone.js +24 -11
- package/dist/utils/deepClone.js.map +1 -1
- package/dist/utils/units.d.ts.map +1 -1
- package/dist/utils/units.js +1 -1
- package/dist/utils/units.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +11 -23
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/xmlSanitization.d.ts +2 -0
- package/dist/utils/xmlSanitization.d.ts.map +1 -1
- package/dist/utils/xmlSanitization.js +133 -7
- package/dist/utils/xmlSanitization.js.map +1 -1
- package/dist/validation/RevisionAutoFixer.d.ts +6 -2
- package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
- package/dist/validation/RevisionAutoFixer.js +68 -54
- package/dist/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/validation/RevisionValidator.d.ts +2 -0
- package/dist/validation/RevisionValidator.d.ts.map +1 -1
- package/dist/validation/RevisionValidator.js +26 -21
- package/dist/validation/RevisionValidator.js.map +1 -1
- package/dist/xml/XMLBuilder.d.ts +1 -0
- package/dist/xml/XMLBuilder.d.ts.map +1 -1
- package/dist/xml/XMLBuilder.js +52 -20
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/xml/XMLParser.d.ts +1 -0
- package/dist/xml/XMLParser.d.ts.map +1 -1
- package/dist/xml/XMLParser.js +55 -13
- package/dist/xml/XMLParser.js.map +1 -1
- package/dist/zip/ZipHandler.d.ts.map +1 -1
- package/dist/zip/ZipHandler.js +37 -13
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.d.ts.map +1 -1
- package/dist/zip/ZipReader.js +52 -5
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/errors.d.ts +3 -0
- package/dist/zip/errors.d.ts.map +1 -1
- package/dist/zip/errors.js +9 -1
- package/dist/zip/errors.js.map +1 -1
- package/dist/zip/types.d.ts +4 -0
- package/dist/zip/types.d.ts.map +1 -1
- package/dist/zip/types.js +4 -0
- package/dist/zip/types.js.map +1 -1
- package/package.json +2 -2
- package/src/core/Document.ts +1159 -240
- package/src/core/DocumentGenerator.ts +106 -26
- package/src/core/DocumentParser.ts +692 -120
- package/src/core/RelationshipManager.ts +446 -442
- package/src/elements/Comment.ts +123 -18
- package/src/elements/CommentManager.ts +121 -22
- package/src/elements/EndnoteManager.ts +4 -1
- package/src/elements/Field.ts +134 -43
- package/src/elements/FieldHelpers.ts +20 -4
- package/src/elements/Footer.ts +62 -67
- package/src/elements/FootnoteManager.ts +4 -1
- package/src/elements/Header.ts +62 -67
- package/src/elements/HeaderFooterManager.ts +56 -8
- package/src/elements/Hyperlink.ts +150 -55
- package/src/elements/Image.ts +51 -7
- package/src/elements/ImageManager.ts +24 -0
- package/src/elements/Paragraph.ts +161 -40
- package/src/elements/Revision.ts +446 -47
- package/src/elements/Run.ts +44 -6
- package/src/elements/Section.ts +25 -9
- package/src/elements/Shape.ts +52 -44
- package/src/elements/StructuredDocumentTag.ts +83 -8
- package/src/elements/Table.ts +151 -50
- package/src/elements/TableCell.ts +57 -17
- package/src/elements/TableOfContents.ts +10 -9
- package/src/elements/TableRow.ts +35 -3
- package/src/elements/TextBox.ts +58 -43
- package/src/formatting/AbstractNumbering.ts +4 -2
- package/src/formatting/NumberingLevel.ts +50 -12
- package/src/formatting/NumberingManager.ts +32 -3
- package/src/formatting/Style.ts +14 -0
- package/src/formatting/StylesManager.ts +29 -2
- package/src/helpers/CleanupHelper.ts +122 -30
- package/src/images/ImageOptimizer.ts +64 -5
- package/src/index.ts +7 -0
- package/src/internal.ts +1 -0
- package/src/processors/CompatibilityUpgrader.ts +15 -2
- package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
- package/src/processors/RevisionWalker.ts +83 -7
- package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
- package/src/processors/cnfStyleDecoder.ts +18 -12
- package/src/processors/stripTrackedChanges.ts +47 -10
- package/src/utils/deepClone.ts +48 -14
- package/src/utils/units.ts +3 -1
- package/src/utils/validation.ts +30 -32
- package/src/utils/xmlSanitization.ts +218 -22
- package/src/validation/RevisionAutoFixer.ts +109 -65
- package/src/validation/RevisionValidator.ts +48 -23
- package/src/xml/XMLBuilder.ts +82 -22
- package/src/xml/XMLParser.ts +87 -20
- package/src/zip/ZipHandler.ts +61 -21
- package/src/zip/ZipReader.ts +135 -13
- package/src/zip/errors.ts +15 -0
- package/src/zip/types.ts +44 -2
package/dist/core/Document.js
CHANGED
|
@@ -75,6 +75,7 @@ const acceptRevisions_js_1 = require("../processors/acceptRevisions.js");
|
|
|
75
75
|
const InMemoryRevisionAcceptor_js_1 = require("../processors/InMemoryRevisionAcceptor.js");
|
|
76
76
|
const stripTrackedChanges_js_1 = require("../processors/stripTrackedChanges.js");
|
|
77
77
|
const textDiff_js_1 = require("../utils/textDiff.js");
|
|
78
|
+
const xmlSanitization_js_1 = require("../utils/xmlSanitization.js");
|
|
78
79
|
const XMLBuilder_js_1 = require("../xml/XMLBuilder.js");
|
|
79
80
|
const XMLParser_js_1 = require("../xml/XMLParser.js");
|
|
80
81
|
const DocumentTrackingContext_js_1 = require("../tracking/DocumentTrackingContext.js");
|
|
@@ -111,6 +112,9 @@ class Document {
|
|
|
111
112
|
this.bookmarkManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
|
|
112
113
|
this.revisionManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
|
|
113
114
|
this.commentManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
|
|
115
|
+
this.commentManager.setModifiedNotifier(() => {
|
|
116
|
+
this._commentsModified = true;
|
|
117
|
+
});
|
|
114
118
|
this.trackingContext = new DocumentTrackingContext_js_1.DocumentTrackingContext(this.revisionManager);
|
|
115
119
|
this.parser = new DocumentParser_js_1.DocumentParser();
|
|
116
120
|
this.generator = new DocumentGenerator_js_1.DocumentGenerator();
|
|
@@ -165,6 +169,7 @@ class Document {
|
|
|
165
169
|
_originalNumberingXml;
|
|
166
170
|
_originalSettingsXml;
|
|
167
171
|
_originalAppPropsXml;
|
|
172
|
+
_originalCorePropsXml;
|
|
168
173
|
_originalFootnotesXml;
|
|
169
174
|
_originalEndnotesXml;
|
|
170
175
|
_originalCommentsXml;
|
|
@@ -174,6 +179,7 @@ class Document {
|
|
|
174
179
|
_saveQueue = Promise.resolve();
|
|
175
180
|
_removedParts = new Set();
|
|
176
181
|
_appPropsModified = false;
|
|
182
|
+
_corePropsModified = false;
|
|
177
183
|
_footnotesModified = false;
|
|
178
184
|
_endnotesModified = false;
|
|
179
185
|
_settingsModified = false;
|
|
@@ -373,7 +379,7 @@ class Document {
|
|
|
373
379
|
const logger = getLogger();
|
|
374
380
|
logger.info('Loading document from file', { path: filePath });
|
|
375
381
|
const zipHandler = new ZipHandler_js_1.ZipHandler();
|
|
376
|
-
await zipHandler.load(filePath);
|
|
382
|
+
await zipHandler.load(filePath, { sizeLimits: options?.sizeLimits });
|
|
377
383
|
const doc = await Document.initializeFromZip(zipHandler, options);
|
|
378
384
|
doc._events.emit('afterLoad', { source: 'file', path: filePath });
|
|
379
385
|
return doc;
|
|
@@ -382,7 +388,7 @@ class Document {
|
|
|
382
388
|
const logger = getLogger();
|
|
383
389
|
logger.info('Loading document from buffer', { bufferSize: buffer.length });
|
|
384
390
|
const zipHandler = new ZipHandler_js_1.ZipHandler();
|
|
385
|
-
await zipHandler.loadFromBuffer(buffer);
|
|
391
|
+
await zipHandler.loadFromBuffer(buffer, { sizeLimits: options?.sizeLimits });
|
|
386
392
|
const doc = await Document.initializeFromZip(zipHandler, options);
|
|
387
393
|
doc._events.emit('afterLoad', { source: 'buffer' });
|
|
388
394
|
return doc;
|
|
@@ -422,7 +428,7 @@ class Document {
|
|
|
422
428
|
}
|
|
423
429
|
const numberingXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.NUMBERING);
|
|
424
430
|
if (numberingXml) {
|
|
425
|
-
doc._originalNumberingXml = numberingXml;
|
|
431
|
+
doc._originalNumberingXml = (0, xmlSanitization_js_1.reorderRunPropertyChildren)(numberingXml);
|
|
426
432
|
}
|
|
427
433
|
const settingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.SETTINGS);
|
|
428
434
|
if (settingsXml) {
|
|
@@ -433,6 +439,10 @@ class Document {
|
|
|
433
439
|
if (appPropsXml) {
|
|
434
440
|
doc._originalAppPropsXml = appPropsXml;
|
|
435
441
|
}
|
|
442
|
+
const corePropsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.CORE_PROPS);
|
|
443
|
+
if (corePropsXml) {
|
|
444
|
+
doc._originalCorePropsXml = corePropsXml;
|
|
445
|
+
}
|
|
436
446
|
const webSettingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.WEB_SETTINGS);
|
|
437
447
|
if (webSettingsXml) {
|
|
438
448
|
doc._originalWebSettingsXml = webSettingsXml;
|
|
@@ -695,17 +705,17 @@ class Document {
|
|
|
695
705
|
try {
|
|
696
706
|
const headersFooters = await this.parser.parseHeadersAndFooters(this.zipHandler, result.section, this.relationshipManager, this.imageManager);
|
|
697
707
|
const registeredHeaderRIds = new Set();
|
|
698
|
-
for (const { header, relationshipId } of headersFooters.headers) {
|
|
708
|
+
for (const { header, relationshipId, filename } of headersFooters.headers) {
|
|
699
709
|
if (registeredHeaderRIds.has(relationshipId))
|
|
700
710
|
continue;
|
|
701
|
-
this.headerFooterManager.registerHeader(header, relationshipId);
|
|
711
|
+
this.headerFooterManager.registerHeader(header, relationshipId, filename);
|
|
702
712
|
registeredHeaderRIds.add(relationshipId);
|
|
703
713
|
}
|
|
704
714
|
const registeredFooterRIds = new Set();
|
|
705
|
-
for (const { footer, relationshipId } of headersFooters.footers) {
|
|
715
|
+
for (const { footer, relationshipId, filename } of headersFooters.footers) {
|
|
706
716
|
if (registeredFooterRIds.has(relationshipId))
|
|
707
717
|
continue;
|
|
708
|
-
this.headerFooterManager.registerFooter(footer, relationshipId);
|
|
718
|
+
this.headerFooterManager.registerFooter(footer, relationshipId, filename);
|
|
709
719
|
registeredFooterRIds.add(relationshipId);
|
|
710
720
|
}
|
|
711
721
|
}
|
|
@@ -748,7 +758,7 @@ class Document {
|
|
|
748
758
|
}
|
|
749
759
|
}
|
|
750
760
|
const parser = new DocumentParser_js_1.DocumentParser();
|
|
751
|
-
const comments = parser.parseCommentsXml(commentsXml);
|
|
761
|
+
const comments = parser.parseCommentsXml(commentsXml, this._originalCommentCompanionFiles.get(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED));
|
|
752
762
|
for (const comment of comments) {
|
|
753
763
|
this.commentManager.registerExisting(comment);
|
|
754
764
|
}
|
|
@@ -762,7 +772,9 @@ class Document {
|
|
|
762
772
|
this._originalFootnotesXml = footnotesXml;
|
|
763
773
|
try {
|
|
764
774
|
const parser = new DocumentParser_js_1.DocumentParser();
|
|
765
|
-
const
|
|
775
|
+
const relsXml = this.zipHandler.getFileAsString('word/_rels/footnotes.xml.rels');
|
|
776
|
+
const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
|
|
777
|
+
const footnotes = parser.parseFootnotesXml(footnotesXml, partRels);
|
|
766
778
|
for (const footnote of footnotes) {
|
|
767
779
|
const id = footnote.getId();
|
|
768
780
|
if (!this.footnoteManager.hasFootnote(id)) {
|
|
@@ -784,7 +796,9 @@ class Document {
|
|
|
784
796
|
this._originalEndnotesXml = endnotesXml;
|
|
785
797
|
try {
|
|
786
798
|
const parser = new DocumentParser_js_1.DocumentParser();
|
|
787
|
-
const
|
|
799
|
+
const relsXml = this.zipHandler.getFileAsString('word/_rels/endnotes.xml.rels');
|
|
800
|
+
const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
|
|
801
|
+
const endnotes = parser.parseEndnotesXml(endnotesXml, partRels);
|
|
788
802
|
for (const endnote of endnotes) {
|
|
789
803
|
const id = endnote.getId();
|
|
790
804
|
if (!this.endnoteManager.hasEndnote(id)) {
|
|
@@ -876,12 +890,13 @@ class Document {
|
|
|
876
890
|
paragraph._setStylesManager(this.stylesManager);
|
|
877
891
|
if (this.trackChangesEnabled && this.trackingContext.isEnabled()) {
|
|
878
892
|
this.bindTrackingToElement(paragraph);
|
|
879
|
-
const
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
893
|
+
const author = this.trackingContext.getAuthor();
|
|
894
|
+
for (const item of paragraph.getContent()) {
|
|
895
|
+
if (item instanceof Run_js_1.Run || item instanceof Hyperlink_js_1.Hyperlink) {
|
|
896
|
+
const insertion = Revision_js_1.Revision.createInsertion(author, item);
|
|
897
|
+
this.trackingContext.getRevisionManager().register(insertion);
|
|
898
|
+
paragraph.replaceContent(item, [insertion]);
|
|
899
|
+
}
|
|
885
900
|
}
|
|
886
901
|
}
|
|
887
902
|
this.bodyElements.push(paragraph);
|
|
@@ -1097,14 +1112,17 @@ class Document {
|
|
|
1097
1112
|
}
|
|
1098
1113
|
setTitle(title) {
|
|
1099
1114
|
this.properties.title = title;
|
|
1115
|
+
this._corePropsModified = true;
|
|
1100
1116
|
return this;
|
|
1101
1117
|
}
|
|
1102
1118
|
setSubject(subject) {
|
|
1103
1119
|
this.properties.subject = subject;
|
|
1120
|
+
this._corePropsModified = true;
|
|
1104
1121
|
return this;
|
|
1105
1122
|
}
|
|
1106
1123
|
setCreator(creator) {
|
|
1107
1124
|
this.properties.creator = creator;
|
|
1125
|
+
this._corePropsModified = true;
|
|
1108
1126
|
return this;
|
|
1109
1127
|
}
|
|
1110
1128
|
setAuthor(author) {
|
|
@@ -1112,18 +1130,22 @@ class Document {
|
|
|
1112
1130
|
}
|
|
1113
1131
|
setKeywords(keywords) {
|
|
1114
1132
|
this.properties.keywords = keywords;
|
|
1133
|
+
this._corePropsModified = true;
|
|
1115
1134
|
return this;
|
|
1116
1135
|
}
|
|
1117
1136
|
setDescription(description) {
|
|
1118
1137
|
this.properties.description = description;
|
|
1138
|
+
this._corePropsModified = true;
|
|
1119
1139
|
return this;
|
|
1120
1140
|
}
|
|
1121
1141
|
setCategory(category) {
|
|
1122
1142
|
this.properties.category = category;
|
|
1143
|
+
this._corePropsModified = true;
|
|
1123
1144
|
return this;
|
|
1124
1145
|
}
|
|
1125
1146
|
setContentStatus(status) {
|
|
1126
1147
|
this.properties.contentStatus = status;
|
|
1148
|
+
this._corePropsModified = true;
|
|
1127
1149
|
return this;
|
|
1128
1150
|
}
|
|
1129
1151
|
setApplication(application) {
|
|
@@ -1570,8 +1592,48 @@ class Document {
|
|
|
1570
1592
|
if (this._removedParts.has(types_js_1.DOCX_PATHS.CORE_PROPS) ||
|
|
1571
1593
|
this._removedParts.has('docProps/core.xml'))
|
|
1572
1594
|
return;
|
|
1573
|
-
|
|
1574
|
-
|
|
1595
|
+
if (this._originalCorePropsXml && !this._corePropsModified) {
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
if (this._originalCorePropsXml && this._corePropsModified) {
|
|
1599
|
+
const mergedXml = this.mergeCorePropsWithOriginal();
|
|
1600
|
+
this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, mergedXml);
|
|
1601
|
+
}
|
|
1602
|
+
else {
|
|
1603
|
+
const xml = this.generator.generateCoreProps(this.properties);
|
|
1604
|
+
this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, xml);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
mergeCorePropsWithOriginal() {
|
|
1608
|
+
if (!this._originalCorePropsXml) {
|
|
1609
|
+
return this.generator.generateCoreProps(this.properties);
|
|
1610
|
+
}
|
|
1611
|
+
let xml = this._originalCorePropsXml;
|
|
1612
|
+
const mergeField = (tag, value) => {
|
|
1613
|
+
if (value === undefined)
|
|
1614
|
+
return;
|
|
1615
|
+
const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(value);
|
|
1616
|
+
const openClose = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?</${tag}>`);
|
|
1617
|
+
const selfClosing = new RegExp(`<${tag}\\b[^>]*/>`);
|
|
1618
|
+
if (openClose.test(xml)) {
|
|
1619
|
+
xml = xml.replace(openClose, `<${tag}>${escaped}</${tag}>`);
|
|
1620
|
+
}
|
|
1621
|
+
else if (selfClosing.test(xml)) {
|
|
1622
|
+
xml = xml.replace(selfClosing, `<${tag}>${escaped}</${tag}>`);
|
|
1623
|
+
}
|
|
1624
|
+
else {
|
|
1625
|
+
xml = xml.replace(/<\/cp:coreProperties>/, ` <${tag}>${escaped}</${tag}>\n</cp:coreProperties>`);
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1628
|
+
mergeField('dc:title', this.properties.title);
|
|
1629
|
+
mergeField('dc:subject', this.properties.subject);
|
|
1630
|
+
mergeField('dc:creator', this.properties.creator);
|
|
1631
|
+
mergeField('cp:keywords', this.properties.keywords);
|
|
1632
|
+
mergeField('dc:description', this.properties.description);
|
|
1633
|
+
mergeField('cp:category', this.properties.category);
|
|
1634
|
+
mergeField('cp:contentStatus', this.properties.contentStatus);
|
|
1635
|
+
mergeField('dc:language', this.properties.language);
|
|
1636
|
+
return xml;
|
|
1575
1637
|
}
|
|
1576
1638
|
updateAppProps() {
|
|
1577
1639
|
if (this._removedParts.has(types_js_1.DOCX_PATHS.APP_PROPS) || this._removedParts.has('docProps/app.xml'))
|
|
@@ -1601,24 +1663,36 @@ class Document {
|
|
|
1601
1663
|
else if (xml.includes('<Company/>')) {
|
|
1602
1664
|
xml = xml.replace(/<Company\/>/, `<Company>${escaped}</Company>`);
|
|
1603
1665
|
}
|
|
1666
|
+
else {
|
|
1667
|
+
xml = xml.replace(/<\/Properties>/, ` <Company>${escaped}</Company>\n</Properties>`);
|
|
1668
|
+
}
|
|
1604
1669
|
}
|
|
1605
1670
|
if (this.properties.application !== undefined) {
|
|
1606
1671
|
const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.application);
|
|
1607
1672
|
if (xml.includes('<Application>')) {
|
|
1608
1673
|
xml = xml.replace(/<Application>[^<]*<\/Application>/, `<Application>${escaped}</Application>`);
|
|
1609
1674
|
}
|
|
1675
|
+
else {
|
|
1676
|
+
xml = xml.replace(/<\/Properties>/, ` <Application>${escaped}</Application>\n</Properties>`);
|
|
1677
|
+
}
|
|
1610
1678
|
}
|
|
1611
1679
|
if (this.properties.appVersion !== undefined) {
|
|
1612
1680
|
const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.appVersion);
|
|
1613
1681
|
if (xml.includes('<AppVersion>')) {
|
|
1614
1682
|
xml = xml.replace(/<AppVersion>[^<]*<\/AppVersion>/, `<AppVersion>${escaped}</AppVersion>`);
|
|
1615
1683
|
}
|
|
1684
|
+
else {
|
|
1685
|
+
xml = xml.replace(/<\/Properties>/, ` <AppVersion>${escaped}</AppVersion>\n</Properties>`);
|
|
1686
|
+
}
|
|
1616
1687
|
}
|
|
1617
1688
|
if (this.properties.manager !== undefined) {
|
|
1618
1689
|
const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.manager);
|
|
1619
1690
|
if (xml.includes('<Manager>')) {
|
|
1620
1691
|
xml = xml.replace(/<Manager>[^<]*<\/Manager>/, `<Manager>${escaped}</Manager>`);
|
|
1621
1692
|
}
|
|
1693
|
+
else {
|
|
1694
|
+
xml = xml.replace(/<\/Properties>/, ` <Manager>${escaped}</Manager>\n</Properties>`);
|
|
1695
|
+
}
|
|
1622
1696
|
}
|
|
1623
1697
|
return xml;
|
|
1624
1698
|
}
|
|
@@ -1744,7 +1818,8 @@ class Document {
|
|
|
1744
1818
|
return this.stylesManager.generateStylesXml();
|
|
1745
1819
|
}
|
|
1746
1820
|
const modifiedStyleIds = this.stylesManager.getModifiedStyleIds();
|
|
1747
|
-
|
|
1821
|
+
const removedStyleIds = this.stylesManager.getRemovedStyleIds();
|
|
1822
|
+
if (modifiedStyleIds.size === 0 && removedStyleIds.size === 0) {
|
|
1748
1823
|
return this._originalStylesXml;
|
|
1749
1824
|
}
|
|
1750
1825
|
const modifiedStyles = new Map();
|
|
@@ -1766,6 +1841,11 @@ class Document {
|
|
|
1766
1841
|
resultXml = resultXml.replace('</w:styles>', `${newStyleXml}\n</w:styles>`);
|
|
1767
1842
|
}
|
|
1768
1843
|
}
|
|
1844
|
+
for (const styleId of removedStyleIds) {
|
|
1845
|
+
const escapedStyleId = styleId.replace(/[.*+?^${}()|[\]\\"]/g, '\\$&');
|
|
1846
|
+
const removedPattern = new RegExp(`\\s*<w:style[^>]*\\sw:styleId="${escapedStyleId}"[^>]*>[\\s\\S]*?</w:style>`);
|
|
1847
|
+
resultXml = resultXml.replace(removedPattern, '');
|
|
1848
|
+
}
|
|
1769
1849
|
return resultXml;
|
|
1770
1850
|
}
|
|
1771
1851
|
updateNumberingXml() {
|
|
@@ -1964,8 +2044,14 @@ class Document {
|
|
|
1964
2044
|
xml = xml.replace(/<w:revisionView\b[^>]*>[\s\S]*?<\/w:revisionView>/g, '');
|
|
1965
2045
|
let trackBlock = '';
|
|
1966
2046
|
const view = this.revisionViewSettings;
|
|
1967
|
-
if (!view.showInsertionsAndDeletions ||
|
|
1968
|
-
|
|
2047
|
+
if (!view.showInsertionsAndDeletions ||
|
|
2048
|
+
!view.showFormatting ||
|
|
2049
|
+
!view.showInkAnnotations ||
|
|
2050
|
+
view.showMarkup === false ||
|
|
2051
|
+
view.showComments === false) {
|
|
2052
|
+
const markupAttr = view.showMarkup === false ? ' w:markup="0"' : '';
|
|
2053
|
+
const commentsAttr = view.showComments === false ? ' w:comments="0"' : '';
|
|
2054
|
+
trackBlock += `\n <w:revisionView w:insDel="${view.showInsertionsAndDeletions ? '1' : '0'}" w:formatting="${view.showFormatting ? '1' : '0'}" w:inkAnnotations="${view.showInkAnnotations ? '1' : '0'}"${markupAttr}${commentsAttr}/>`;
|
|
1969
2055
|
}
|
|
1970
2056
|
if (this.trackChangesEnabled) {
|
|
1971
2057
|
trackBlock += '\n <w:trackRevisions/>';
|
|
@@ -2001,6 +2087,8 @@ class Document {
|
|
|
2001
2087
|
const prot = this.documentProtection;
|
|
2002
2088
|
const esc = XMLBuilder_js_1.XMLBuilder.escapeXmlAttribute;
|
|
2003
2089
|
let protXml = `\n <w:documentProtection w:edit="${esc(prot.edit)}" w:enforcement="${prot.enforcement ? '1' : '0'}"`;
|
|
2090
|
+
if (prot.formatting !== undefined)
|
|
2091
|
+
protXml += ` w:formatting="${prot.formatting ? '1' : '0'}"`;
|
|
2004
2092
|
if (prot.cryptProviderType)
|
|
2005
2093
|
protXml += ` w:cryptProviderType="${esc(prot.cryptProviderType)}"`;
|
|
2006
2094
|
if (prot.cryptAlgorithmClass)
|
|
@@ -2015,6 +2103,12 @@ class Document {
|
|
|
2015
2103
|
protXml += ` w:hash="${esc(prot.hash)}"`;
|
|
2016
2104
|
if (prot.salt)
|
|
2017
2105
|
protXml += ` w:salt="${esc(prot.salt)}"`;
|
|
2106
|
+
if (prot.algorithmName)
|
|
2107
|
+
protXml += ` w:algorithmName="${esc(prot.algorithmName)}"`;
|
|
2108
|
+
if (prot.hashValue)
|
|
2109
|
+
protXml += ` w:hashValue="${esc(prot.hashValue)}"`;
|
|
2110
|
+
if (prot.saltValue)
|
|
2111
|
+
protXml += ` w:saltValue="${esc(prot.saltValue)}"`;
|
|
2018
2112
|
protXml += '/>';
|
|
2019
2113
|
if (/<w:autoFormatOverride\b/.test(xml)) {
|
|
2020
2114
|
xml = xml.replace(/<w:autoFormatOverride\b/, protXml + '\n <w:autoFormatOverride');
|
|
@@ -2768,6 +2862,18 @@ class Document {
|
|
|
2768
2862
|
}
|
|
2769
2863
|
}
|
|
2770
2864
|
}
|
|
2865
|
+
for (const style of this.stylesManager.getAllStyles()) {
|
|
2866
|
+
const styleNumId = style.getProperties().numPr?.numId;
|
|
2867
|
+
if (styleNumId !== undefined) {
|
|
2868
|
+
usedNumIds.add(styleNumId);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
for (const filePath of [types_js_1.DOCX_PATHS.STYLES, 'word/comments.xml']) {
|
|
2872
|
+
const xml = this.zipHandler.getFileAsString(filePath);
|
|
2873
|
+
if (xml) {
|
|
2874
|
+
this.collectNumIdsFromXml(xml, usedNumIds);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2771
2877
|
this.numberingManager.cleanupUnusedNumbering(usedNumIds);
|
|
2772
2878
|
}
|
|
2773
2879
|
validateNumberingReferences() {
|
|
@@ -2869,7 +2975,67 @@ class Document {
|
|
|
2869
2975
|
maxRevId = rev.getId();
|
|
2870
2976
|
}
|
|
2871
2977
|
const registeredSet = new Set(existingRevisions);
|
|
2872
|
-
let
|
|
2978
|
+
let maxPreservedDocPrId = 0;
|
|
2979
|
+
const collectPreservedDocPrIds = (rawXml) => {
|
|
2980
|
+
if (!rawXml || !rawXml.includes('wp:docPr'))
|
|
2981
|
+
return;
|
|
2982
|
+
const docPrPattern = /<wp:docPr\b[^>]*\bid="(\d+)"/g;
|
|
2983
|
+
let match;
|
|
2984
|
+
while ((match = docPrPattern.exec(rawXml)) !== null) {
|
|
2985
|
+
const id = parseInt(match[1], 10);
|
|
2986
|
+
if (id > maxPreservedDocPrId)
|
|
2987
|
+
maxPreservedDocPrId = id;
|
|
2988
|
+
}
|
|
2989
|
+
};
|
|
2990
|
+
const collectFromRun = (run) => {
|
|
2991
|
+
if (run instanceof ImageRun_js_1.ImageRun) {
|
|
2992
|
+
collectPreservedDocPrIds(run.getRawRunXml());
|
|
2993
|
+
return;
|
|
2994
|
+
}
|
|
2995
|
+
for (const contentItem of run.getContent()) {
|
|
2996
|
+
collectPreservedDocPrIds(contentItem.rawXml);
|
|
2997
|
+
}
|
|
2998
|
+
};
|
|
2999
|
+
const collectFromParagraph = (para) => {
|
|
3000
|
+
for (const item of para.getContent()) {
|
|
3001
|
+
if (item instanceof Revision_js_1.Revision) {
|
|
3002
|
+
for (const revItem of item.getContent()) {
|
|
3003
|
+
if (revItem instanceof Run_js_1.Run)
|
|
3004
|
+
collectFromRun(revItem);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
else if (item instanceof Run_js_1.Run) {
|
|
3008
|
+
collectFromRun(item);
|
|
3009
|
+
}
|
|
3010
|
+
else if (item instanceof PreservedElement_js_1.PreservedElement) {
|
|
3011
|
+
collectPreservedDocPrIds(item.getRawXml());
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
};
|
|
3015
|
+
for (const element of this.bodyElements) {
|
|
3016
|
+
if (element instanceof Paragraph_js_1.Paragraph) {
|
|
3017
|
+
collectFromParagraph(element);
|
|
3018
|
+
}
|
|
3019
|
+
else if (element instanceof Table_js_1.Table) {
|
|
3020
|
+
for (const row of element.getRows()) {
|
|
3021
|
+
for (const cell of row.getCells()) {
|
|
3022
|
+
for (const para of cell.getParagraphs()) {
|
|
3023
|
+
collectFromParagraph(para);
|
|
3024
|
+
}
|
|
3025
|
+
for (const nested of cell.getRawNestedContent()) {
|
|
3026
|
+
collectPreservedDocPrIds(nested.xml);
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
else {
|
|
3032
|
+
const passthrough = element;
|
|
3033
|
+
if (typeof passthrough.getRawXml === 'function') {
|
|
3034
|
+
collectPreservedDocPrIds(passthrough.getRawXml());
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
let docPrId = maxPreservedDocPrId + 1;
|
|
2873
3039
|
const existingParaIds = new Set();
|
|
2874
3040
|
const paragraphsNeedingIds = [];
|
|
2875
3041
|
const generateUniqueParaId = () => {
|
|
@@ -2901,6 +3067,13 @@ class Document {
|
|
|
2901
3067
|
else if (item instanceof ImageRun_js_1.ImageRun) {
|
|
2902
3068
|
item.getImageElement().setDocPrId(docPrId++);
|
|
2903
3069
|
}
|
|
3070
|
+
else if (item instanceof Revision_js_1.Revision) {
|
|
3071
|
+
for (const revItem of item.getContent()) {
|
|
3072
|
+
if (revItem instanceof ImageRun_js_1.ImageRun) {
|
|
3073
|
+
revItem.getImageElement().setDocPrId(docPrId++);
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
2904
3077
|
}
|
|
2905
3078
|
if (para.formatting.paraId) {
|
|
2906
3079
|
existingParaIds.add(para.formatting.paraId);
|
|
@@ -3190,6 +3363,7 @@ class Document {
|
|
|
3190
3363
|
numLevel.setLeftIndent(720 * (levelIndex + 1));
|
|
3191
3364
|
numLevel.setHangingIndent(360);
|
|
3192
3365
|
}
|
|
3366
|
+
this.numberingManager.markAbstractNumberingModified(abstractNumId);
|
|
3193
3367
|
this.applyFormattingToListParagraphs(instance.getNumId());
|
|
3194
3368
|
count++;
|
|
3195
3369
|
}
|
|
@@ -3216,6 +3390,7 @@ class Document {
|
|
|
3216
3390
|
numLevel.setHangingIndent(360);
|
|
3217
3391
|
numLevel.setAlignment('left');
|
|
3218
3392
|
}
|
|
3393
|
+
this.numberingManager.markAbstractNumberingModified(abstractNumId);
|
|
3219
3394
|
this.applyFormattingToListParagraphs(instance.getNumId());
|
|
3220
3395
|
count++;
|
|
3221
3396
|
}
|
|
@@ -5038,39 +5213,39 @@ class Document {
|
|
|
5038
5213
|
return this;
|
|
5039
5214
|
}
|
|
5040
5215
|
setHeader(header) {
|
|
5041
|
-
const relationship = this.relationshipManager.addHeader(
|
|
5216
|
+
const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
|
|
5042
5217
|
this.headerFooterManager.registerHeader(header, relationship.getId());
|
|
5043
5218
|
this.section.setHeaderReference('default', relationship.getId());
|
|
5044
5219
|
return this;
|
|
5045
5220
|
}
|
|
5046
5221
|
setFirstPageHeader(header) {
|
|
5047
5222
|
this.section.setTitlePage(true);
|
|
5048
|
-
const relationship = this.relationshipManager.addHeader(
|
|
5223
|
+
const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
|
|
5049
5224
|
this.headerFooterManager.registerHeader(header, relationship.getId());
|
|
5050
5225
|
this.section.setHeaderReference('first', relationship.getId());
|
|
5051
5226
|
return this;
|
|
5052
5227
|
}
|
|
5053
5228
|
setEvenPageHeader(header) {
|
|
5054
|
-
const relationship = this.relationshipManager.addHeader(
|
|
5229
|
+
const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
|
|
5055
5230
|
this.headerFooterManager.registerHeader(header, relationship.getId());
|
|
5056
5231
|
this.section.setHeaderReference('even', relationship.getId());
|
|
5057
5232
|
return this;
|
|
5058
5233
|
}
|
|
5059
5234
|
setFooter(footer) {
|
|
5060
|
-
const relationship = this.relationshipManager.addFooter(
|
|
5235
|
+
const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
|
|
5061
5236
|
this.headerFooterManager.registerFooter(footer, relationship.getId());
|
|
5062
5237
|
this.section.setFooterReference('default', relationship.getId());
|
|
5063
5238
|
return this;
|
|
5064
5239
|
}
|
|
5065
5240
|
setFirstPageFooter(footer) {
|
|
5066
5241
|
this.section.setTitlePage(true);
|
|
5067
|
-
const relationship = this.relationshipManager.addFooter(
|
|
5242
|
+
const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
|
|
5068
5243
|
this.headerFooterManager.registerFooter(footer, relationship.getId());
|
|
5069
5244
|
this.section.setFooterReference('first', relationship.getId());
|
|
5070
5245
|
return this;
|
|
5071
5246
|
}
|
|
5072
5247
|
setEvenPageFooter(footer) {
|
|
5073
|
-
const relationship = this.relationshipManager.addFooter(
|
|
5248
|
+
const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
|
|
5074
5249
|
this.headerFooterManager.registerFooter(footer, relationship.getId());
|
|
5075
5250
|
this.section.setFooterReference('even', relationship.getId());
|
|
5076
5251
|
return this;
|
|
@@ -5216,6 +5391,20 @@ class Document {
|
|
|
5216
5391
|
}
|
|
5217
5392
|
}
|
|
5218
5393
|
this.removeCommentCompanionFiles();
|
|
5394
|
+
const extendedXml = this.commentManager.generateCommentsExtendedXml();
|
|
5395
|
+
if (extendedXml) {
|
|
5396
|
+
this.zipHandler.addFile(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED, extendedXml);
|
|
5397
|
+
const hasExtendedRel = this.relationshipManager
|
|
5398
|
+
.getAllRelationships()
|
|
5399
|
+
.some((rel) => rel.getTarget() === 'commentsExtended.xml');
|
|
5400
|
+
if (!hasExtendedRel) {
|
|
5401
|
+
this.relationshipManager.addRelationship(Relationship_js_1.Relationship.create({
|
|
5402
|
+
id: this.relationshipManager.generateId(),
|
|
5403
|
+
type: 'http://schemas.microsoft.com/office/2011/relationships/commentsExtended',
|
|
5404
|
+
target: 'commentsExtended.xml',
|
|
5405
|
+
}));
|
|
5406
|
+
}
|
|
5407
|
+
}
|
|
5219
5408
|
}
|
|
5220
5409
|
else if (this._originalCommentsXml) {
|
|
5221
5410
|
this.zipHandler.addFile('word/comments.xml', this._originalCommentsXml);
|
|
@@ -5253,7 +5442,8 @@ class Document {
|
|
|
5253
5442
|
}
|
|
5254
5443
|
}
|
|
5255
5444
|
saveFootnotes() {
|
|
5256
|
-
if (this._footnotesModified ||
|
|
5445
|
+
if (this._footnotesModified ||
|
|
5446
|
+
(!this._originalFootnotesXml && this.footnoteManager.getCount() > 0)) {
|
|
5257
5447
|
const xml = this.footnoteManager.generateFootnotesXml();
|
|
5258
5448
|
this.zipHandler.addFile(types_js_1.DOCX_PATHS.FOOTNOTES, xml);
|
|
5259
5449
|
const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.FOOTNOTES);
|
|
@@ -5271,7 +5461,8 @@ class Document {
|
|
|
5271
5461
|
}
|
|
5272
5462
|
}
|
|
5273
5463
|
saveEndnotes() {
|
|
5274
|
-
if (this._endnotesModified ||
|
|
5464
|
+
if (this._endnotesModified ||
|
|
5465
|
+
(!this._originalEndnotesXml && this.endnoteManager.getCount() > 0)) {
|
|
5275
5466
|
const xml = this.endnoteManager.generateEndnotesXml();
|
|
5276
5467
|
this.zipHandler.addFile(types_js_1.DOCX_PATHS.ENDNOTES, xml);
|
|
5277
5468
|
const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.ENDNOTES);
|
|
@@ -5340,7 +5531,12 @@ class Document {
|
|
|
5340
5531
|
xml += '</Relationships>';
|
|
5341
5532
|
this.zipHandler.addFile(relsPath, xml);
|
|
5342
5533
|
for (const rel of hyperlinkRels) {
|
|
5343
|
-
this.relationshipManager.
|
|
5534
|
+
const mainRel = this.relationshipManager.getRelationship(rel.id);
|
|
5535
|
+
if (mainRel &&
|
|
5536
|
+
mainRel.getType() === Relationship_js_1.RelationshipType.HYPERLINK &&
|
|
5537
|
+
mainRel.getTarget() === rel.url) {
|
|
5538
|
+
this.relationshipManager.removeRelationship(rel.id);
|
|
5539
|
+
}
|
|
5344
5540
|
}
|
|
5345
5541
|
}
|
|
5346
5542
|
}
|
|
@@ -5458,13 +5654,25 @@ class Document {
|
|
|
5458
5654
|
parseContentTypes(xml) {
|
|
5459
5655
|
const defaults = new Set();
|
|
5460
5656
|
const overrides = new Set();
|
|
5461
|
-
const
|
|
5462
|
-
|
|
5463
|
-
|
|
5657
|
+
const readAttr = (tag, name) => {
|
|
5658
|
+
const match = tag.match(new RegExp(`(?:^|\\s)${name}\\s*=\\s*("([^"]*)"|'([^']*)')`));
|
|
5659
|
+
if (!match)
|
|
5660
|
+
return undefined;
|
|
5661
|
+
return XMLBuilder_js_1.XMLBuilder.unescapeXml(match[2] ?? match[3] ?? '');
|
|
5662
|
+
};
|
|
5663
|
+
for (const tagMatch of xml.matchAll(/<Default\b[^>]*>/g)) {
|
|
5664
|
+
const ext = readAttr(tagMatch[0], 'Extension');
|
|
5665
|
+
const contentType = readAttr(tagMatch[0], 'ContentType');
|
|
5666
|
+
if (ext && contentType) {
|
|
5667
|
+
defaults.add(`${ext}|${contentType}`);
|
|
5668
|
+
}
|
|
5464
5669
|
}
|
|
5465
|
-
const
|
|
5466
|
-
|
|
5467
|
-
|
|
5670
|
+
for (const tagMatch of xml.matchAll(/<Override\b[^>]*>/g)) {
|
|
5671
|
+
const partName = readAttr(tagMatch[0], 'PartName');
|
|
5672
|
+
const contentType = readAttr(tagMatch[0], 'ContentType');
|
|
5673
|
+
if (partName && contentType) {
|
|
5674
|
+
overrides.add(`${partName}|${contentType}`);
|
|
5675
|
+
}
|
|
5468
5676
|
}
|
|
5469
5677
|
return { defaults, overrides };
|
|
5470
5678
|
}
|
|
@@ -5784,9 +5992,7 @@ class Document {
|
|
|
5784
5992
|
}
|
|
5785
5993
|
if (element && typeof element.getContent === 'function') {
|
|
5786
5994
|
for (const item of element.getContent()) {
|
|
5787
|
-
if (item &&
|
|
5788
|
-
typeof item._setTrackingContext === 'function' &&
|
|
5789
|
-
typeof item.getInstruction === 'function') {
|
|
5995
|
+
if (item && typeof item._setTrackingContext === 'function') {
|
|
5790
5996
|
item._setTrackingContext(this.trackingContext);
|
|
5791
5997
|
}
|
|
5792
5998
|
}
|
|
@@ -5953,6 +6159,7 @@ class Document {
|
|
|
5953
6159
|
updated.size = sizeInPoints;
|
|
5954
6160
|
}
|
|
5955
6161
|
normalStyle.setRunFormatting(updated);
|
|
6162
|
+
this.stylesManager.addStyle(normalStyle);
|
|
5956
6163
|
return this;
|
|
5957
6164
|
}
|
|
5958
6165
|
setDefaultFontSize(sizeInPoints) {
|
|
@@ -5968,6 +6175,7 @@ class Document {
|
|
|
5968
6175
|
}
|
|
5969
6176
|
const existing = normalStyle.getRunFormatting() ?? {};
|
|
5970
6177
|
normalStyle.setRunFormatting({ ...existing, size: sizeInPoints });
|
|
6178
|
+
this.stylesManager.addStyle(normalStyle);
|
|
5971
6179
|
return this;
|
|
5972
6180
|
}
|
|
5973
6181
|
getUpdateFields() {
|
|
@@ -6159,6 +6367,40 @@ class Document {
|
|
|
6159
6367
|
this.endnoteManager.clear();
|
|
6160
6368
|
this._endnotesModified = true;
|
|
6161
6369
|
}
|
|
6370
|
+
removeFootnote(id) {
|
|
6371
|
+
const removed = this.footnoteManager.removeFootnote(id);
|
|
6372
|
+
if (removed) {
|
|
6373
|
+
this._footnotesModified = true;
|
|
6374
|
+
this.removeNoteReferenceRuns('footnoteReference', id);
|
|
6375
|
+
}
|
|
6376
|
+
return removed;
|
|
6377
|
+
}
|
|
6378
|
+
removeEndnote(id) {
|
|
6379
|
+
const removed = this.endnoteManager.removeEndnote(id);
|
|
6380
|
+
if (removed) {
|
|
6381
|
+
this._endnotesModified = true;
|
|
6382
|
+
this.removeNoteReferenceRuns('endnoteReference', id);
|
|
6383
|
+
}
|
|
6384
|
+
return removed;
|
|
6385
|
+
}
|
|
6386
|
+
removeNoteReferenceRuns(refType, id) {
|
|
6387
|
+
for (const para of this.getAllParagraphs()) {
|
|
6388
|
+
const content = para.getContent();
|
|
6389
|
+
for (let i = content.length - 1; i >= 0; i--) {
|
|
6390
|
+
const item = content[i];
|
|
6391
|
+
if (!(item instanceof Run_js_1.Run)) {
|
|
6392
|
+
continue;
|
|
6393
|
+
}
|
|
6394
|
+
const matches = item
|
|
6395
|
+
.getContent()
|
|
6396
|
+
.some((c) => c.type === refType &&
|
|
6397
|
+
(refType === 'footnoteReference' ? c.footnoteId === id : c.endnoteId === id));
|
|
6398
|
+
if (matches) {
|
|
6399
|
+
para.removeContentAt(i);
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6162
6404
|
addCommentToParagraph(paragraph, commentOrAuthor, content, initials) {
|
|
6163
6405
|
const comment = typeof commentOrAuthor === 'string'
|
|
6164
6406
|
? this.createComment(commentOrAuthor, content, initials)
|
|
@@ -6209,12 +6451,52 @@ class Document {
|
|
|
6209
6451
|
return this.commentManager.hasReplies(commentId);
|
|
6210
6452
|
}
|
|
6211
6453
|
removeComment(id) {
|
|
6454
|
+
const replyIds = this.commentManager.getReplies(id).map((reply) => reply.getId());
|
|
6212
6455
|
const removed = this.commentManager.removeComment(id);
|
|
6213
6456
|
if (removed) {
|
|
6457
|
+
this.removeCommentAnchors([id, ...replyIds]);
|
|
6214
6458
|
this._commentsModified = true;
|
|
6215
6459
|
}
|
|
6216
6460
|
return removed;
|
|
6217
6461
|
}
|
|
6462
|
+
removeCommentAnchors(commentIds) {
|
|
6463
|
+
const strip = (paragraphs) => {
|
|
6464
|
+
let removed = false;
|
|
6465
|
+
for (const paragraph of paragraphs) {
|
|
6466
|
+
for (const commentId of commentIds) {
|
|
6467
|
+
if (paragraph.removeCommentAnchor(commentId)) {
|
|
6468
|
+
removed = true;
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
return removed;
|
|
6473
|
+
};
|
|
6474
|
+
strip(this.getAllParagraphs());
|
|
6475
|
+
for (const entry of this.headerFooterManager.getAllHeaders()) {
|
|
6476
|
+
strip(this.extractParagraphsFromElements(entry.header.getElements()));
|
|
6477
|
+
}
|
|
6478
|
+
for (const entry of this.headerFooterManager.getAllFooters()) {
|
|
6479
|
+
strip(this.extractParagraphsFromElements(entry.footer.getElements()));
|
|
6480
|
+
}
|
|
6481
|
+
let footnotesChanged = false;
|
|
6482
|
+
for (const footnote of this.footnoteManager.getAllFootnotes()) {
|
|
6483
|
+
if (strip(footnote.getParagraphs())) {
|
|
6484
|
+
footnotesChanged = true;
|
|
6485
|
+
}
|
|
6486
|
+
}
|
|
6487
|
+
if (footnotesChanged) {
|
|
6488
|
+
this._footnotesModified = true;
|
|
6489
|
+
}
|
|
6490
|
+
let endnotesChanged = false;
|
|
6491
|
+
for (const endnote of this.endnoteManager.getAllEndnotes()) {
|
|
6492
|
+
if (strip(endnote.getParagraphs())) {
|
|
6493
|
+
endnotesChanged = true;
|
|
6494
|
+
}
|
|
6495
|
+
}
|
|
6496
|
+
if (endnotesChanged) {
|
|
6497
|
+
this._endnotesModified = true;
|
|
6498
|
+
}
|
|
6499
|
+
}
|
|
6218
6500
|
hasNoRevisions() {
|
|
6219
6501
|
return this.revisionManager.isEmpty();
|
|
6220
6502
|
}
|
|
@@ -6470,8 +6752,8 @@ class Document {
|
|
|
6470
6752
|
this.parser.clearParseErrors();
|
|
6471
6753
|
this.stylesManager.clear();
|
|
6472
6754
|
this.numberingManager.clear();
|
|
6473
|
-
this.imageManager.clear();
|
|
6474
6755
|
this.imageManager.releaseAllImageData();
|
|
6756
|
+
this.imageManager.clear();
|
|
6475
6757
|
this.relationshipManager.clear();
|
|
6476
6758
|
this.headerFooterManager.clear();
|
|
6477
6759
|
this.bookmarkManager.clear();
|
|
@@ -6485,6 +6767,7 @@ class Document {
|
|
|
6485
6767
|
this._originalNumberingXml = undefined;
|
|
6486
6768
|
this._originalSettingsXml = undefined;
|
|
6487
6769
|
this._originalAppPropsXml = undefined;
|
|
6770
|
+
this._originalCorePropsXml = undefined;
|
|
6488
6771
|
this._originalFootnotesXml = undefined;
|
|
6489
6772
|
this._originalEndnotesXml = undefined;
|
|
6490
6773
|
this._originalCommentsXml = undefined;
|
|
@@ -6493,6 +6776,7 @@ class Document {
|
|
|
6493
6776
|
this._originalContentTypes = undefined;
|
|
6494
6777
|
this._settingsModified = false;
|
|
6495
6778
|
this._appPropsModified = false;
|
|
6779
|
+
this._corePropsModified = false;
|
|
6496
6780
|
this._footnotesModified = false;
|
|
6497
6781
|
this._endnotesModified = false;
|
|
6498
6782
|
this._originalWebSettingsXml = undefined;
|
|
@@ -7050,7 +7334,7 @@ class Document {
|
|
|
7050
7334
|
const matches = originalText.match(wordPattern);
|
|
7051
7335
|
if (matches) {
|
|
7052
7336
|
replacementCount += matches.length;
|
|
7053
|
-
newText = originalText.replace(wordPattern, replace);
|
|
7337
|
+
newText = originalText.replace(wordPattern, () => replace);
|
|
7054
7338
|
}
|
|
7055
7339
|
}
|
|
7056
7340
|
else {
|
|
@@ -7058,7 +7342,7 @@ class Document {
|
|
|
7058
7342
|
const matches = originalText.match(searchPattern);
|
|
7059
7343
|
if (matches) {
|
|
7060
7344
|
replacementCount += matches.length;
|
|
7061
|
-
newText = originalText.replace(searchPattern, replace);
|
|
7345
|
+
newText = originalText.replace(searchPattern, () => replace);
|
|
7062
7346
|
}
|
|
7063
7347
|
}
|
|
7064
7348
|
if (newText !== originalText) {
|
|
@@ -7338,90 +7622,303 @@ class Document {
|
|
|
7338
7622
|
}
|
|
7339
7623
|
toPlainText(separator = '\n') {
|
|
7340
7624
|
const paragraphs = this.getAllParagraphs();
|
|
7341
|
-
return paragraphs.map((p) => p.
|
|
7342
|
-
}
|
|
7343
|
-
toMarkdown() {
|
|
7625
|
+
return paragraphs.map((p) => p.getTextIncludingRevisions()).join(separator);
|
|
7626
|
+
}
|
|
7627
|
+
toMarkdown(options) {
|
|
7628
|
+
const ctx = {
|
|
7629
|
+
opts: {
|
|
7630
|
+
htmlFallback: options?.htmlFallback ?? true,
|
|
7631
|
+
footnotes: options?.footnotes ?? true,
|
|
7632
|
+
images: options?.images ?? true,
|
|
7633
|
+
},
|
|
7634
|
+
notes: [],
|
|
7635
|
+
noteMarkers: new Set(),
|
|
7636
|
+
};
|
|
7344
7637
|
const lines = [];
|
|
7345
7638
|
for (const element of this.bodyElements) {
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7639
|
+
this.bodyElementToMarkdown(element, ctx, lines);
|
|
7640
|
+
}
|
|
7641
|
+
while (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
7642
|
+
lines.pop();
|
|
7643
|
+
}
|
|
7644
|
+
let out = lines.join('\n');
|
|
7645
|
+
if (ctx.opts.footnotes && ctx.notes.length > 0) {
|
|
7646
|
+
const defs = ctx.notes.map((n) => `[^${n.marker}]: ${n.text}`).join('\n');
|
|
7647
|
+
out = out ? `${out}\n\n${defs}` : defs;
|
|
7648
|
+
}
|
|
7649
|
+
return out;
|
|
7650
|
+
}
|
|
7651
|
+
bodyElementToMarkdown(element, ctx, lines) {
|
|
7652
|
+
if (element instanceof Paragraph_js_1.Paragraph) {
|
|
7653
|
+
const md = this.paragraphToMarkdown(element, ctx);
|
|
7654
|
+
if (md !== null) {
|
|
7655
|
+
lines.push(md);
|
|
7656
|
+
lines.push('');
|
|
7352
7657
|
}
|
|
7353
|
-
|
|
7354
|
-
|
|
7658
|
+
}
|
|
7659
|
+
else if (element instanceof Table_js_1.Table) {
|
|
7660
|
+
const tableLines = this.tableToMarkdown(element, ctx);
|
|
7661
|
+
if (tableLines.length > 0) {
|
|
7662
|
+
lines.push(...tableLines);
|
|
7355
7663
|
lines.push('');
|
|
7356
7664
|
}
|
|
7357
7665
|
}
|
|
7358
|
-
|
|
7359
|
-
|
|
7666
|
+
else if (element instanceof StructuredDocumentTag_js_1.StructuredDocumentTag) {
|
|
7667
|
+
for (const child of element.getContent()) {
|
|
7668
|
+
this.bodyElementToMarkdown(child, ctx, lines);
|
|
7669
|
+
}
|
|
7670
|
+
}
|
|
7671
|
+
else if (element instanceof PreservedElement_js_1.PreservedElement) {
|
|
7672
|
+
const text = this.extractTextFromRawXml(element.getRawXml());
|
|
7673
|
+
if (text) {
|
|
7674
|
+
lines.push(this.escapeMarkdown(text));
|
|
7675
|
+
lines.push('');
|
|
7676
|
+
}
|
|
7360
7677
|
}
|
|
7361
|
-
return lines.join('\n');
|
|
7362
7678
|
}
|
|
7363
|
-
paragraphToMarkdown(para) {
|
|
7364
|
-
const
|
|
7365
|
-
|
|
7679
|
+
paragraphToMarkdown(para, ctx) {
|
|
7680
|
+
const inline = this.paragraphContentToMarkdown(para, ctx);
|
|
7681
|
+
const hasNumbering = para.hasNumbering();
|
|
7682
|
+
if (!inline && !hasNumbering)
|
|
7366
7683
|
return null;
|
|
7367
7684
|
const headingLevel = para.detectHeadingLevel();
|
|
7368
7685
|
if (headingLevel !== null && headingLevel >= 1 && headingLevel <= 6) {
|
|
7369
|
-
return '#'.repeat(headingLevel) + ' ' +
|
|
7370
|
-
}
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7686
|
+
return '#'.repeat(headingLevel) + ' ' + this.toSingleLine(inline);
|
|
7687
|
+
}
|
|
7688
|
+
const style = (para.getStyle() ?? '').toLowerCase();
|
|
7689
|
+
const isListStyle = style.includes('listbullet') ||
|
|
7690
|
+
style.includes('list bullet') ||
|
|
7691
|
+
style.includes('listnumber') ||
|
|
7692
|
+
style.includes('list number');
|
|
7693
|
+
if (hasNumbering || isListStyle) {
|
|
7694
|
+
const level = para.getNumbering()?.level ?? 0;
|
|
7695
|
+
const indent = ' '.repeat(Math.max(0, level));
|
|
7696
|
+
const marker = this.isOrderedList(para) ? '1.' : '-';
|
|
7697
|
+
return `${indent}${marker} ${this.toSingleLine(inline)}`;
|
|
7698
|
+
}
|
|
7699
|
+
if (style.includes('quote')) {
|
|
7700
|
+
return this.toSingleLine(inline)
|
|
7701
|
+
.split('\n')
|
|
7702
|
+
.map((l) => `> ${l}`)
|
|
7703
|
+
.join('\n');
|
|
7704
|
+
}
|
|
7705
|
+
return inline;
|
|
7706
|
+
}
|
|
7707
|
+
isOrderedList(para) {
|
|
7708
|
+
const numbering = para.getNumbering();
|
|
7709
|
+
if (numbering) {
|
|
7710
|
+
const instance = this.numberingManager.getInstance(numbering.numId);
|
|
7711
|
+
if (instance) {
|
|
7712
|
+
const abstract = this.numberingManager.getAbstractNumbering(instance.getAbstractNumId());
|
|
7713
|
+
const levelDef = abstract?.getLevel(numbering.level);
|
|
7714
|
+
const format = levelDef?.getFormat();
|
|
7715
|
+
if (format)
|
|
7716
|
+
return format !== 'bullet';
|
|
7717
|
+
}
|
|
7375
7718
|
}
|
|
7376
|
-
|
|
7719
|
+
const style = (para.getStyle() ?? '').toLowerCase();
|
|
7720
|
+
if (style.includes('bullet'))
|
|
7721
|
+
return false;
|
|
7722
|
+
if (style.includes('number'))
|
|
7723
|
+
return true;
|
|
7724
|
+
return true;
|
|
7377
7725
|
}
|
|
7378
|
-
paragraphContentToMarkdown(para) {
|
|
7726
|
+
paragraphContentToMarkdown(para, ctx) {
|
|
7727
|
+
return this.inlineContentToMarkdown(para.getContent(), ctx);
|
|
7728
|
+
}
|
|
7729
|
+
inlineContentToMarkdown(items, ctx) {
|
|
7379
7730
|
const parts = [];
|
|
7380
|
-
for (const item of
|
|
7381
|
-
if (item instanceof
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
if (fmt.bold && fmt.italic) {
|
|
7388
|
-
md = `***${md}***`;
|
|
7389
|
-
}
|
|
7390
|
-
else if (fmt.bold) {
|
|
7391
|
-
md = `**${md}**`;
|
|
7392
|
-
}
|
|
7393
|
-
else if (fmt.italic) {
|
|
7394
|
-
md = `*${md}*`;
|
|
7731
|
+
for (const item of items) {
|
|
7732
|
+
if (item instanceof ImageRun_js_1.ImageRun) {
|
|
7733
|
+
if (ctx.opts.images) {
|
|
7734
|
+
const image = item.getImageElement();
|
|
7735
|
+
const alt = this.escapeMarkdown(image.getAltText() || 'image');
|
|
7736
|
+
const src = image.getRelationshipId() ?? 'image';
|
|
7737
|
+
parts.push(``);
|
|
7395
7738
|
}
|
|
7396
|
-
|
|
7397
|
-
|
|
7739
|
+
}
|
|
7740
|
+
else if (item instanceof Run_js_1.Run) {
|
|
7741
|
+
parts.push(this.runToMarkdown(item, ctx));
|
|
7742
|
+
}
|
|
7743
|
+
else if (item instanceof Hyperlink_js_1.Hyperlink) {
|
|
7744
|
+
const runs = item.getRuns();
|
|
7745
|
+
let label = runs.length > 0
|
|
7746
|
+
? runs.map((r) => this.runToMarkdown(r, ctx, true)).join('')
|
|
7747
|
+
: this.escapeMarkdown(item.getText());
|
|
7748
|
+
if (!label)
|
|
7749
|
+
label = this.escapeMarkdown(item.getText());
|
|
7750
|
+
let url = item.getUrl() ?? '';
|
|
7751
|
+
const anchor = item.getAnchor();
|
|
7752
|
+
if (anchor)
|
|
7753
|
+
url = url ? `${url}#${anchor}` : `#${anchor}`;
|
|
7754
|
+
parts.push(`[${label}](${url})`);
|
|
7755
|
+
}
|
|
7756
|
+
else if (item instanceof Revision_js_1.Revision) {
|
|
7757
|
+
const inner = this.inlineContentToMarkdown(item.getContent(), ctx);
|
|
7758
|
+
if (!inner)
|
|
7759
|
+
continue;
|
|
7760
|
+
const type = item.getType();
|
|
7761
|
+
if (type === 'delete' || type === 'moveFrom') {
|
|
7762
|
+
parts.push(ctx.opts.htmlFallback ? `<del>${inner}</del>` : `~~${inner}~~`);
|
|
7398
7763
|
}
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
md = `\`${runText}\``;
|
|
7764
|
+
else {
|
|
7765
|
+
parts.push(inner);
|
|
7402
7766
|
}
|
|
7403
|
-
parts.push(md);
|
|
7404
7767
|
}
|
|
7405
|
-
else if (item instanceof
|
|
7406
|
-
const
|
|
7407
|
-
|
|
7408
|
-
|
|
7768
|
+
else if (item instanceof Field_js_1.ComplexField) {
|
|
7769
|
+
const result = item.getResult();
|
|
7770
|
+
if (result)
|
|
7771
|
+
parts.push(this.escapeMarkdown(result));
|
|
7772
|
+
}
|
|
7773
|
+
else if (item instanceof Field_js_1.Field) {
|
|
7774
|
+
const result = item.getCachedResult();
|
|
7775
|
+
if (result)
|
|
7776
|
+
parts.push(this.escapeMarkdown(result));
|
|
7777
|
+
}
|
|
7778
|
+
else if (item instanceof TextBox_js_1.TextBox) {
|
|
7779
|
+
const text = item
|
|
7780
|
+
.getParagraphs()
|
|
7781
|
+
.map((p) => this.paragraphContentToMarkdown(p, ctx))
|
|
7782
|
+
.filter((s) => s !== '')
|
|
7783
|
+
.join(' ');
|
|
7784
|
+
if (text)
|
|
7785
|
+
parts.push(text);
|
|
7786
|
+
}
|
|
7787
|
+
else if (item instanceof Shape_js_1.Shape) {
|
|
7788
|
+
const text = item.getText();
|
|
7789
|
+
if (text)
|
|
7790
|
+
parts.push(this.escapeMarkdown(text));
|
|
7791
|
+
}
|
|
7792
|
+
else if (item instanceof PreservedElement_js_1.PreservedElement) {
|
|
7793
|
+
const type = item.getElementType();
|
|
7794
|
+
if (!type.startsWith('w:comment')) {
|
|
7795
|
+
const text = this.extractTextFromRawXml(item.getRawXml());
|
|
7796
|
+
if (text)
|
|
7797
|
+
parts.push(this.escapeMarkdown(text));
|
|
7798
|
+
}
|
|
7409
7799
|
}
|
|
7410
7800
|
}
|
|
7411
7801
|
return parts.join('');
|
|
7412
7802
|
}
|
|
7413
|
-
|
|
7414
|
-
const
|
|
7415
|
-
|
|
7803
|
+
runToMarkdown(run, ctx, inLink = false) {
|
|
7804
|
+
const fmt = run.getFormatting();
|
|
7805
|
+
const isMono = !!(fmt.font &&
|
|
7806
|
+
/^(courier|consolas|monaco|menlo|source code|fira code|jetbrains mono)/i.test(fmt.font));
|
|
7807
|
+
const escape = (s) => (isMono ? s : this.escapeMarkdown(s));
|
|
7808
|
+
const segments = [];
|
|
7809
|
+
const markers = [];
|
|
7810
|
+
for (const content of run.getContent()) {
|
|
7811
|
+
switch (content.type) {
|
|
7812
|
+
case 'text':
|
|
7813
|
+
case 'instructionText':
|
|
7814
|
+
segments.push(escape(content.value ?? ''));
|
|
7815
|
+
break;
|
|
7816
|
+
case 'tab':
|
|
7817
|
+
segments.push('\t');
|
|
7818
|
+
break;
|
|
7819
|
+
case 'carriageReturn':
|
|
7820
|
+
segments.push('\n');
|
|
7821
|
+
break;
|
|
7822
|
+
case 'break':
|
|
7823
|
+
if (content.breakType !== 'page' && content.breakType !== 'column') {
|
|
7824
|
+
segments.push(ctx.opts.htmlFallback ? '<br>' : '\n');
|
|
7825
|
+
}
|
|
7826
|
+
break;
|
|
7827
|
+
case 'noBreakHyphen':
|
|
7828
|
+
segments.push('‑');
|
|
7829
|
+
break;
|
|
7830
|
+
case 'symbol':
|
|
7831
|
+
if (content.symbolChar) {
|
|
7832
|
+
const code = parseInt(content.symbolChar, 16);
|
|
7833
|
+
if (!Number.isNaN(code))
|
|
7834
|
+
segments.push(escape(String.fromCharCode(code)));
|
|
7835
|
+
}
|
|
7836
|
+
break;
|
|
7837
|
+
case 'footnoteReference':
|
|
7838
|
+
if (ctx.opts.footnotes && content.footnoteId !== undefined) {
|
|
7839
|
+
markers.push(this.noteMarker(content.footnoteId, 'fn', ctx));
|
|
7840
|
+
}
|
|
7841
|
+
break;
|
|
7842
|
+
case 'endnoteReference':
|
|
7843
|
+
if (ctx.opts.footnotes && content.endnoteId !== undefined) {
|
|
7844
|
+
markers.push(this.noteMarker(content.endnoteId, 'en', ctx));
|
|
7845
|
+
}
|
|
7846
|
+
break;
|
|
7847
|
+
default:
|
|
7848
|
+
break;
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
let text = segments.join('');
|
|
7852
|
+
if (text) {
|
|
7853
|
+
if (isMono) {
|
|
7854
|
+
text = `\`${text}\``;
|
|
7855
|
+
}
|
|
7856
|
+
if (fmt.bold && fmt.italic)
|
|
7857
|
+
text = `***${text}***`;
|
|
7858
|
+
else if (fmt.bold)
|
|
7859
|
+
text = `**${text}**`;
|
|
7860
|
+
else if (fmt.italic)
|
|
7861
|
+
text = `*${text}*`;
|
|
7862
|
+
if (fmt.strike || fmt.dstrike)
|
|
7863
|
+
text = `~~${text}~~`;
|
|
7864
|
+
if (ctx.opts.htmlFallback) {
|
|
7865
|
+
if (fmt.superscript)
|
|
7866
|
+
text = `<sup>${text}</sup>`;
|
|
7867
|
+
else if (fmt.subscript)
|
|
7868
|
+
text = `<sub>${text}</sub>`;
|
|
7869
|
+
if (fmt.highlight && fmt.highlight !== 'none')
|
|
7870
|
+
text = `<mark>${text}</mark>`;
|
|
7871
|
+
if (!inLink) {
|
|
7872
|
+
if (fmt.underline && fmt.underline !== 'none')
|
|
7873
|
+
text = `<u>${text}</u>`;
|
|
7874
|
+
if (fmt.color && fmt.color !== 'auto' && /^[0-9a-fA-F]{6}$/.test(fmt.color)) {
|
|
7875
|
+
text = `<span style="color:#${fmt.color}">${text}</span>`;
|
|
7876
|
+
}
|
|
7877
|
+
}
|
|
7878
|
+
}
|
|
7879
|
+
}
|
|
7880
|
+
return text + markers.join('');
|
|
7881
|
+
}
|
|
7882
|
+
noteMarker(id, kind, ctx) {
|
|
7883
|
+
const marker = `${kind}${id}`;
|
|
7884
|
+
if (!ctx.noteMarkers.has(marker)) {
|
|
7885
|
+
ctx.noteMarkers.add(marker);
|
|
7886
|
+
const note = kind === 'fn' ? this.footnoteManager.getFootnote(id) : this.endnoteManager.getEndnote(id);
|
|
7887
|
+
let text = '';
|
|
7888
|
+
if (note) {
|
|
7889
|
+
text = note
|
|
7890
|
+
.getParagraphs()
|
|
7891
|
+
.map((p) => this.paragraphContentToMarkdown(p, ctx))
|
|
7892
|
+
.filter((s) => s !== '')
|
|
7893
|
+
.join(' ')
|
|
7894
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
7895
|
+
.trim();
|
|
7896
|
+
}
|
|
7897
|
+
ctx.notes.push({ marker, text });
|
|
7898
|
+
}
|
|
7899
|
+
return `[^${marker}]`;
|
|
7900
|
+
}
|
|
7901
|
+
tableToMarkdown(table, ctx) {
|
|
7902
|
+
const rows = table.getRows();
|
|
7903
|
+
if (rows.length === 0)
|
|
7416
7904
|
return [];
|
|
7417
|
-
const
|
|
7905
|
+
const isComplex = rows.some((row) => row
|
|
7906
|
+
.getCells()
|
|
7907
|
+
.some((cell) => (cell.getColumnSpan() ?? 1) > 1 ||
|
|
7908
|
+
cell.getVerticalMerge() !== undefined ||
|
|
7909
|
+
cell.hasNestedTables()));
|
|
7910
|
+
if (isComplex && ctx.opts.htmlFallback) {
|
|
7911
|
+
return this.tableToHtmlBlock(table);
|
|
7912
|
+
}
|
|
7913
|
+
const matrix = rows.map((row) => row.getCells().map((cell) => this.cellToMarkdown(cell, ctx)));
|
|
7914
|
+
const colCount = Math.max(...matrix.map((row) => row.length));
|
|
7418
7915
|
if (colCount === 0)
|
|
7419
7916
|
return [];
|
|
7420
|
-
const normalized =
|
|
7917
|
+
const normalized = matrix.map((row) => {
|
|
7421
7918
|
const padded = [...row];
|
|
7422
7919
|
while (padded.length < colCount)
|
|
7423
7920
|
padded.push('');
|
|
7424
|
-
return padded
|
|
7921
|
+
return padded;
|
|
7425
7922
|
});
|
|
7426
7923
|
const lines = [];
|
|
7427
7924
|
lines.push('| ' + normalized[0].join(' | ') + ' |');
|
|
@@ -7431,6 +7928,88 @@ class Document {
|
|
|
7431
7928
|
}
|
|
7432
7929
|
return lines;
|
|
7433
7930
|
}
|
|
7931
|
+
cellToMarkdown(cell, ctx) {
|
|
7932
|
+
const text = cell
|
|
7933
|
+
.getParagraphs()
|
|
7934
|
+
.map((p) => this.paragraphContentToMarkdown(p, ctx))
|
|
7935
|
+
.filter((s) => s !== '')
|
|
7936
|
+
.join(' ');
|
|
7937
|
+
return text.replace(/\|/g, '\\|').replace(/<br>/g, ' ').replace(/\n/g, ' ').trim();
|
|
7938
|
+
}
|
|
7939
|
+
tableToHtmlBlock(table) {
|
|
7940
|
+
const rows = table.getRows();
|
|
7941
|
+
const rowCells = rows.map((row) => {
|
|
7942
|
+
let gridStart = 0;
|
|
7943
|
+
return row.getCells().map((cell) => {
|
|
7944
|
+
const span = cell.getColumnSpan() ?? 1;
|
|
7945
|
+
const entry = { cell, gridStart, span };
|
|
7946
|
+
gridStart += span;
|
|
7947
|
+
return entry;
|
|
7948
|
+
});
|
|
7949
|
+
});
|
|
7950
|
+
const html = ['<table>'];
|
|
7951
|
+
for (let ri = 0; ri < rowCells.length; ri++) {
|
|
7952
|
+
html.push('<tr>');
|
|
7953
|
+
for (const { cell, gridStart, span } of rowCells[ri]) {
|
|
7954
|
+
if (cell.getVerticalMerge() === 'continue')
|
|
7955
|
+
continue;
|
|
7956
|
+
let rowspan = 1;
|
|
7957
|
+
if (cell.getVerticalMerge() === 'restart') {
|
|
7958
|
+
for (let rj = ri + 1; rj < rowCells.length; rj++) {
|
|
7959
|
+
const below = rowCells[rj].find((e) => e.gridStart === gridStart);
|
|
7960
|
+
if (below?.cell.getVerticalMerge() === 'continue')
|
|
7961
|
+
rowspan++;
|
|
7962
|
+
else
|
|
7963
|
+
break;
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
const tag = ri === 0 ? 'th' : 'td';
|
|
7967
|
+
const attrs = (span > 1 ? ` colspan="${span}"` : '') + (rowspan > 1 ? ` rowspan="${rowspan}"` : '');
|
|
7968
|
+
let content = cell
|
|
7969
|
+
.getParagraphs()
|
|
7970
|
+
.map((p) => this.paragraphContentToHTML(p))
|
|
7971
|
+
.filter((s) => s !== '')
|
|
7972
|
+
.join('<br>') || this.escapeHTML(cell.getText());
|
|
7973
|
+
if (cell.hasNestedTables()) {
|
|
7974
|
+
const nestedText = cell
|
|
7975
|
+
.getRawNestedContent()
|
|
7976
|
+
.map((n) => this.extractTextFromRawXml(n.xml))
|
|
7977
|
+
.filter((s) => s)
|
|
7978
|
+
.join(' ');
|
|
7979
|
+
if (nestedText)
|
|
7980
|
+
content += `<br>${this.escapeHTML(nestedText)}`;
|
|
7981
|
+
}
|
|
7982
|
+
html.push(`<${tag}${attrs}>${content}</${tag}>`);
|
|
7983
|
+
}
|
|
7984
|
+
html.push('</tr>');
|
|
7985
|
+
}
|
|
7986
|
+
html.push('</table>');
|
|
7987
|
+
return html;
|
|
7988
|
+
}
|
|
7989
|
+
escapeMarkdown(text) {
|
|
7990
|
+
return text.replace(/([\\`*_[\]<>])/g, '\\$1');
|
|
7991
|
+
}
|
|
7992
|
+
toSingleLine(text) {
|
|
7993
|
+
return text.replace(/<br>/g, ' ').replace(/\s*\n\s*/g, ' ');
|
|
7994
|
+
}
|
|
7995
|
+
extractTextFromRawXml(xml) {
|
|
7996
|
+
if (!xml.includes('<w:t'))
|
|
7997
|
+
return '';
|
|
7998
|
+
const parts = [];
|
|
7999
|
+
const regex = /<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g;
|
|
8000
|
+
let match;
|
|
8001
|
+
while ((match = regex.exec(xml)) !== null) {
|
|
8002
|
+
parts.push(match[1] ?? '');
|
|
8003
|
+
}
|
|
8004
|
+
return parts
|
|
8005
|
+
.join('')
|
|
8006
|
+
.replace(/</g, '<')
|
|
8007
|
+
.replace(/>/g, '>')
|
|
8008
|
+
.replace(/"/g, '"')
|
|
8009
|
+
.replace(/'/g, "'")
|
|
8010
|
+
.replace(/&/g, '&')
|
|
8011
|
+
.trim();
|
|
8012
|
+
}
|
|
7434
8013
|
toHTML(options) {
|
|
7435
8014
|
const parts = [];
|
|
7436
8015
|
let inList = null;
|
|
@@ -7521,8 +8100,12 @@ class Document {
|
|
|
7521
8100
|
parts.push(html);
|
|
7522
8101
|
}
|
|
7523
8102
|
else if (item instanceof Hyperlink_js_1.Hyperlink) {
|
|
7524
|
-
|
|
7525
|
-
const
|
|
8103
|
+
let rawUrl = item.getUrl() ?? '';
|
|
8104
|
+
const anchor = item.getAnchor();
|
|
8105
|
+
if (anchor)
|
|
8106
|
+
rawUrl = rawUrl ? `${rawUrl}#${anchor}` : `#${anchor}`;
|
|
8107
|
+
const url = this.escapeHTML(rawUrl);
|
|
8108
|
+
const linkText = this.escapeHTML(item.getText() || rawUrl);
|
|
7526
8109
|
parts.push(`<a href="${url}">${linkText}</a>`);
|
|
7527
8110
|
}
|
|
7528
8111
|
}
|
|
@@ -7670,7 +8253,10 @@ class Document {
|
|
|
7670
8253
|
removeParagraph(paragraphOrIndex) {
|
|
7671
8254
|
let index;
|
|
7672
8255
|
if (typeof paragraphOrIndex === 'number') {
|
|
7673
|
-
|
|
8256
|
+
const para = this.getParagraphAt(paragraphOrIndex);
|
|
8257
|
+
if (!para)
|
|
8258
|
+
return false;
|
|
8259
|
+
index = this.bodyElements.indexOf(para);
|
|
7674
8260
|
}
|
|
7675
8261
|
else {
|
|
7676
8262
|
index = this.bodyElements.indexOf(paragraphOrIndex);
|
|
@@ -7679,13 +8265,8 @@ class Document {
|
|
|
7679
8265
|
const element = this.bodyElements[index];
|
|
7680
8266
|
if (element instanceof Paragraph_js_1.Paragraph) {
|
|
7681
8267
|
if (this.trackChangesEnabled && this.trackingContext.isEnabled()) {
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
const author = this.trackingContext.getAuthor();
|
|
7685
|
-
const deletion = Revision_js_1.Revision.createDeletion(author, runs);
|
|
7686
|
-
this.trackingContext.getRevisionManager().register(deletion);
|
|
7687
|
-
element.addRevision(deletion);
|
|
7688
|
-
}
|
|
8268
|
+
this.bindTrackingToElement(element);
|
|
8269
|
+
element.clearContent();
|
|
7689
8270
|
return true;
|
|
7690
8271
|
}
|
|
7691
8272
|
this.bodyElements.splice(index, 1);
|
|
@@ -7939,16 +8520,6 @@ class Document {
|
|
|
7939
8520
|
for (const paragraph of this.getAllParagraphs()) {
|
|
7940
8521
|
extractHyperlinksFromParagraph(paragraph);
|
|
7941
8522
|
}
|
|
7942
|
-
for (const table of this.getTables()) {
|
|
7943
|
-
for (const row of table.getRows()) {
|
|
7944
|
-
for (const cell of row.getCells()) {
|
|
7945
|
-
const cellParagraphs = cell instanceof TableCell_js_1.TableCell ? cell.getParagraphs() : [];
|
|
7946
|
-
for (const para of cellParagraphs) {
|
|
7947
|
-
extractHyperlinksFromParagraph(para);
|
|
7948
|
-
}
|
|
7949
|
-
}
|
|
7950
|
-
}
|
|
7951
|
-
}
|
|
7952
8523
|
return hyperlinks;
|
|
7953
8524
|
}
|
|
7954
8525
|
collectAllReferencedHyperlinkIds() {
|
|
@@ -8073,17 +8644,6 @@ class Document {
|
|
|
8073
8644
|
bookmarks.push({ bookmark, paragraph });
|
|
8074
8645
|
}
|
|
8075
8646
|
}
|
|
8076
|
-
for (const table of this.getTables()) {
|
|
8077
|
-
for (const row of table.getRows()) {
|
|
8078
|
-
for (const cell of row.getCells()) {
|
|
8079
|
-
for (const para of cell.getParagraphs()) {
|
|
8080
|
-
for (const bookmark of para.getBookmarksStart()) {
|
|
8081
|
-
bookmarks.push({ bookmark, paragraph: para });
|
|
8082
|
-
}
|
|
8083
|
-
}
|
|
8084
|
-
}
|
|
8085
|
-
}
|
|
8086
|
-
}
|
|
8087
8647
|
return bookmarks;
|
|
8088
8648
|
}
|
|
8089
8649
|
getFields() {
|
|
@@ -8093,18 +8653,6 @@ class Document {
|
|
|
8093
8653
|
results.push({ field, paragraph });
|
|
8094
8654
|
}
|
|
8095
8655
|
}
|
|
8096
|
-
for (const table of this.getTables()) {
|
|
8097
|
-
for (const row of table.getRows()) {
|
|
8098
|
-
for (const cell of row.getCells()) {
|
|
8099
|
-
const cellParagraphs = cell instanceof TableCell_js_1.TableCell ? cell.getParagraphs() : [];
|
|
8100
|
-
for (const para of cellParagraphs) {
|
|
8101
|
-
for (const field of para.getFields()) {
|
|
8102
|
-
results.push({ field, paragraph: para, table });
|
|
8103
|
-
}
|
|
8104
|
-
}
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
}
|
|
8108
8656
|
return results;
|
|
8109
8657
|
}
|
|
8110
8658
|
getImages() {
|
|
@@ -8143,7 +8691,7 @@ class Document {
|
|
|
8143
8691
|
await entry.image.updateImageData(result.data);
|
|
8144
8692
|
}
|
|
8145
8693
|
if (result.newExtension !== extension) {
|
|
8146
|
-
const newFilename = filename.replace(/\.[^.]+$/, `.${result.newExtension}`);
|
|
8694
|
+
const newFilename = this.resolveUniqueMediaFilename(filename.replace(/\.[^.]+$/, `.${result.newExtension}`), filename);
|
|
8147
8695
|
this.imageManager.updateEntryFilename(image, newFilename);
|
|
8148
8696
|
for (const entry of entries) {
|
|
8149
8697
|
this.updateImageRelationshipTarget(entry.relationshipId, filename, newFilename);
|
|
@@ -8154,6 +8702,20 @@ class Document {
|
|
|
8154
8702
|
}
|
|
8155
8703
|
return { optimizedCount, totalSavedBytes: totalSaved };
|
|
8156
8704
|
}
|
|
8705
|
+
resolveUniqueMediaFilename(candidate, currentFilename) {
|
|
8706
|
+
const dotIndex = candidate.lastIndexOf('.');
|
|
8707
|
+
const base = dotIndex === -1 ? candidate : candidate.slice(0, dotIndex);
|
|
8708
|
+
const ext = dotIndex === -1 ? '' : candidate.slice(dotIndex);
|
|
8709
|
+
const isTaken = (name) => this.zipHandler.hasFile(`word/media/${name}`) ||
|
|
8710
|
+
this.imageManager.isFilenameOwnedByOther(name, currentFilename);
|
|
8711
|
+
let name = candidate;
|
|
8712
|
+
let counter = 1;
|
|
8713
|
+
while (isTaken(name)) {
|
|
8714
|
+
name = `${base}-${counter}${ext}`;
|
|
8715
|
+
counter++;
|
|
8716
|
+
}
|
|
8717
|
+
return name;
|
|
8718
|
+
}
|
|
8157
8719
|
updateImageRelationshipTarget(relId, oldFilename, newFilename) {
|
|
8158
8720
|
const rel = this.relationshipManager.getRelationship(relId);
|
|
8159
8721
|
if (rel) {
|
|
@@ -8277,7 +8839,7 @@ class Document {
|
|
|
8277
8839
|
const toRemove = [];
|
|
8278
8840
|
this.bodyElements.forEach((element, index) => {
|
|
8279
8841
|
if (element instanceof Paragraph_js_1.Paragraph) {
|
|
8280
|
-
const isEmpty =
|
|
8842
|
+
const isEmpty = this.isParagraphRemovableBlank(element);
|
|
8281
8843
|
if (isEmpty && lastWasEmpty) {
|
|
8282
8844
|
toRemove.push(index);
|
|
8283
8845
|
}
|
|
@@ -8361,11 +8923,30 @@ class Document {
|
|
|
8361
8923
|
}
|
|
8362
8924
|
return { removed, normalized };
|
|
8363
8925
|
}
|
|
8926
|
+
isParagraphRemovableBlank(para) {
|
|
8927
|
+
if (para.getText().trim() !== '')
|
|
8928
|
+
return false;
|
|
8929
|
+
if (para.formatting.sectPr !== undefined)
|
|
8930
|
+
return false;
|
|
8931
|
+
if (para.getBookmarksStart().length > 0 || para.getBookmarksEnd().length > 0) {
|
|
8932
|
+
return false;
|
|
8933
|
+
}
|
|
8934
|
+
if (para.getCommentsStart().length > 0 || para.getCommentsEnd().length > 0) {
|
|
8935
|
+
return false;
|
|
8936
|
+
}
|
|
8937
|
+
for (const item of para.getContent()) {
|
|
8938
|
+
if (item instanceof ImageRun_js_1.ImageRun || item instanceof Shape_js_1.Shape || item instanceof RangeMarker_js_1.RangeMarker) {
|
|
8939
|
+
return false;
|
|
8940
|
+
}
|
|
8941
|
+
}
|
|
8942
|
+
return true;
|
|
8943
|
+
}
|
|
8364
8944
|
setLanguage(language) {
|
|
8365
8945
|
if (!this.properties) {
|
|
8366
8946
|
this.properties = {};
|
|
8367
8947
|
}
|
|
8368
8948
|
this.properties.language = language;
|
|
8949
|
+
this._corePropsModified = true;
|
|
8369
8950
|
return this;
|
|
8370
8951
|
}
|
|
8371
8952
|
getLanguage() {
|
|
@@ -8481,32 +9062,6 @@ class Document {
|
|
|
8481
9062
|
pattern.lastIndex = 0;
|
|
8482
9063
|
}
|
|
8483
9064
|
}
|
|
8484
|
-
for (const table of this.getTables()) {
|
|
8485
|
-
for (const row of table.getRows()) {
|
|
8486
|
-
for (const cell of row.getCells()) {
|
|
8487
|
-
for (const para of cell.getParagraphs()) {
|
|
8488
|
-
for (const run of para.getRuns()) {
|
|
8489
|
-
const text = run.getText();
|
|
8490
|
-
if (!text)
|
|
8491
|
-
continue;
|
|
8492
|
-
const runFormatting = run.getFormatting();
|
|
8493
|
-
if (matchBold && !runFormatting.bold)
|
|
8494
|
-
continue;
|
|
8495
|
-
if (matchItalic && !runFormatting.italic)
|
|
8496
|
-
continue;
|
|
8497
|
-
if (pattern.test(text)) {
|
|
8498
|
-
const newText = text.replace(pattern, replace);
|
|
8499
|
-
if (newText !== text) {
|
|
8500
|
-
run.setText(newText);
|
|
8501
|
-
replacedCount++;
|
|
8502
|
-
}
|
|
8503
|
-
}
|
|
8504
|
-
pattern.lastIndex = 0;
|
|
8505
|
-
}
|
|
8506
|
-
}
|
|
8507
|
-
}
|
|
8508
|
-
}
|
|
8509
|
-
}
|
|
8510
9065
|
return replacedCount;
|
|
8511
9066
|
}
|
|
8512
9067
|
static createEmpty() {
|