docxmlater 10.4.1 → 11.0.4
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 +3 -3
- package/dist/constants/legacyCompatFlags.d.ts +1 -1
- package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
- package/dist/constants/legacyCompatFlags.js.map +1 -1
- package/dist/core/Document.d.ts +74 -67
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +605 -414
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentContent.d.ts +11 -10
- package/dist/core/DocumentContent.d.ts.map +1 -1
- package/dist/core/DocumentContent.js +19 -19
- package/dist/core/DocumentContent.js.map +1 -1
- package/dist/core/DocumentEvents.d.ts +39 -0
- package/dist/core/DocumentEvents.d.ts.map +1 -0
- package/dist/core/DocumentEvents.js +51 -0
- package/dist/core/DocumentEvents.js.map +1 -0
- package/dist/core/DocumentGenerator.d.ts +11 -11
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +72 -52
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +15 -15
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +2056 -1073
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/DocumentValidator.d.ts +3 -3
- package/dist/core/DocumentValidator.d.ts.map +1 -1
- package/dist/core/DocumentValidator.js +31 -31
- package/dist/core/DocumentValidator.js.map +1 -1
- package/dist/core/ElementRegistry.d.ts +22 -0
- package/dist/core/ElementRegistry.d.ts.map +1 -0
- package/dist/core/ElementRegistry.js +27 -0
- package/dist/core/ElementRegistry.js.map +1 -0
- package/dist/core/Relationship.js +4 -4
- package/dist/core/Relationship.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +32 -32
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/AlternateContent.d.ts +1 -1
- package/dist/elements/AlternateContent.d.ts.map +1 -1
- package/dist/elements/AlternateContent.js.map +1 -1
- package/dist/elements/Bookmark.d.ts +6 -1
- package/dist/elements/Bookmark.d.ts.map +1 -1
- package/dist/elements/Bookmark.js +19 -3
- package/dist/elements/Bookmark.js.map +1 -1
- package/dist/elements/BookmarkManager.d.ts +1 -1
- package/dist/elements/BookmarkManager.d.ts.map +1 -1
- package/dist/elements/BookmarkManager.js +7 -7
- package/dist/elements/BookmarkManager.js.map +1 -1
- package/dist/elements/Comment.d.ts +2 -2
- package/dist/elements/Comment.d.ts.map +1 -1
- package/dist/elements/Comment.js +4 -4
- package/dist/elements/Comment.js.map +1 -1
- package/dist/elements/CommentManager.d.ts +2 -2
- package/dist/elements/CommentManager.d.ts.map +1 -1
- package/dist/elements/CommentManager.js +9 -9
- package/dist/elements/CommentManager.js.map +1 -1
- package/dist/elements/CommonTypes.d.ts +9 -4
- package/dist/elements/CommonTypes.d.ts.map +1 -1
- package/dist/elements/CommonTypes.js +1 -0
- package/dist/elements/CommonTypes.js.map +1 -1
- package/dist/elements/CustomXml.d.ts +1 -1
- package/dist/elements/CustomXml.d.ts.map +1 -1
- package/dist/elements/CustomXml.js.map +1 -1
- package/dist/elements/Endnote.d.ts +2 -2
- package/dist/elements/Endnote.d.ts.map +1 -1
- package/dist/elements/Endnote.js +9 -9
- package/dist/elements/Endnote.js.map +1 -1
- package/dist/elements/EndnoteManager.d.ts +1 -1
- package/dist/elements/EndnoteManager.d.ts.map +1 -1
- package/dist/elements/EndnoteManager.js +11 -11
- package/dist/elements/EndnoteManager.js.map +1 -1
- package/dist/elements/Field.d.ts +9 -5
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +21 -9
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/FieldHelpers.d.ts +1 -1
- package/dist/elements/FieldHelpers.d.ts.map +1 -1
- package/dist/elements/FieldHelpers.js +10 -10
- package/dist/elements/FieldHelpers.js.map +1 -1
- package/dist/elements/Footer.d.ts +3 -3
- package/dist/elements/Footer.d.ts.map +1 -1
- package/dist/elements/Footer.js +5 -5
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/Footnote.d.ts +2 -2
- package/dist/elements/Footnote.d.ts.map +1 -1
- package/dist/elements/Footnote.js +9 -9
- package/dist/elements/Footnote.js.map +1 -1
- package/dist/elements/FootnoteManager.d.ts +1 -1
- package/dist/elements/FootnoteManager.d.ts.map +1 -1
- package/dist/elements/FootnoteManager.js +11 -11
- package/dist/elements/FootnoteManager.js.map +1 -1
- package/dist/elements/Header.d.ts +3 -3
- package/dist/elements/Header.d.ts.map +1 -1
- package/dist/elements/Header.js +5 -5
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/HeaderFooterManager.d.ts +2 -2
- package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
- package/dist/elements/HeaderFooterManager.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +5 -5
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +29 -29
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts +1 -1
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +67 -67
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/ImageManager.d.ts +1 -1
- package/dist/elements/ImageManager.d.ts.map +1 -1
- package/dist/elements/ImageManager.js +4 -4
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/ImageRun.d.ts +3 -3
- package/dist/elements/ImageRun.d.ts.map +1 -1
- package/dist/elements/ImageRun.js +2 -2
- package/dist/elements/ImageRun.js.map +1 -1
- package/dist/elements/MathElement.d.ts +1 -1
- package/dist/elements/MathElement.d.ts.map +1 -1
- package/dist/elements/MathElement.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +34 -19
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +286 -231
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/PreservedElement.d.ts +1 -1
- package/dist/elements/PreservedElement.d.ts.map +1 -1
- package/dist/elements/PreservedElement.js.map +1 -1
- package/dist/elements/PropertyChangeTypes.d.ts +2 -2
- package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
- package/dist/elements/PropertyChangeTypes.js.map +1 -1
- package/dist/elements/RangeMarker.d.ts +14 -1
- package/dist/elements/RangeMarker.d.ts.map +1 -1
- package/dist/elements/RangeMarker.js +46 -8
- package/dist/elements/RangeMarker.js.map +1 -1
- package/dist/elements/RegisteredBodyElement.d.ts +15 -0
- package/dist/elements/RegisteredBodyElement.d.ts.map +1 -0
- package/dist/elements/RegisteredBodyElement.js +44 -0
- package/dist/elements/RegisteredBodyElement.js.map +1 -0
- package/dist/elements/Revision.d.ts +8 -8
- package/dist/elements/Revision.d.ts.map +1 -1
- package/dist/elements/Revision.js +12 -12
- package/dist/elements/Revision.js.map +1 -1
- package/dist/elements/RevisionContent.d.ts +3 -3
- package/dist/elements/RevisionContent.d.ts.map +1 -1
- package/dist/elements/RevisionContent.js.map +1 -1
- package/dist/elements/RevisionManager.d.ts +2 -2
- package/dist/elements/RevisionManager.d.ts.map +1 -1
- package/dist/elements/RevisionManager.js +2 -2
- package/dist/elements/RevisionManager.js.map +1 -1
- package/dist/elements/Run.d.ts +16 -10
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +199 -173
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts +4 -2
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +152 -145
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Shape.d.ts +3 -3
- package/dist/elements/Shape.d.ts.map +1 -1
- package/dist/elements/Shape.js +12 -12
- package/dist/elements/Shape.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +3 -3
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
- package/dist/elements/StructuredDocumentTag.js +39 -39
- package/dist/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/elements/Table.d.ts +16 -10
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +118 -89
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +11 -11
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +108 -78
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableGridChange.d.ts +1 -1
- package/dist/elements/TableGridChange.d.ts.map +1 -1
- package/dist/elements/TableGridChange.js +3 -3
- package/dist/elements/TableGridChange.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts +1 -1
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +2 -2
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableOfContentsElement.d.ts +2 -2
- package/dist/elements/TableOfContentsElement.d.ts.map +1 -1
- package/dist/elements/TableOfContentsElement.js +5 -5
- package/dist/elements/TableOfContentsElement.js.map +1 -1
- package/dist/elements/TableRow.d.ts +18 -7
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +127 -74
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/elements/TextBox.d.ts +4 -4
- package/dist/elements/TextBox.d.ts.map +1 -1
- package/dist/elements/TextBox.js +6 -6
- package/dist/elements/TextBox.js.map +1 -1
- package/dist/esm/constants/legacyCompatFlags.js +97 -0
- package/dist/esm/constants/legacyCompatFlags.js.map +1 -0
- package/dist/esm/constants/limits.js +36 -0
- package/dist/esm/constants/limits.js.map +1 -0
- package/dist/esm/core/Document.js +8498 -0
- package/dist/esm/core/Document.js.map +1 -0
- package/dist/esm/core/DocumentContent.js +190 -0
- package/dist/esm/core/DocumentContent.js.map +1 -0
- package/dist/esm/core/DocumentEvents.js +47 -0
- package/dist/esm/core/DocumentEvents.js.map +1 -0
- package/dist/esm/core/DocumentGenerator.js +764 -0
- package/dist/esm/core/DocumentGenerator.js.map +1 -0
- package/dist/esm/core/DocumentIdManager.js +67 -0
- package/dist/esm/core/DocumentIdManager.js.map +1 -0
- package/dist/esm/core/DocumentParser.js +8760 -0
- package/dist/esm/core/DocumentParser.js.map +1 -0
- package/dist/esm/core/DocumentValidator.js +222 -0
- package/dist/esm/core/DocumentValidator.js.map +1 -0
- package/dist/esm/core/ElementRegistry.js +24 -0
- package/dist/esm/core/ElementRegistry.js.map +1 -0
- package/dist/esm/core/Relationship.js +177 -0
- package/dist/esm/core/Relationship.js.map +1 -0
- package/dist/esm/core/RelationshipManager.js +202 -0
- package/dist/esm/core/RelationshipManager.js.map +1 -0
- package/dist/esm/elements/AlternateContent.js +19 -0
- package/dist/esm/elements/AlternateContent.js.map +1 -0
- package/dist/esm/elements/Bookmark.js +115 -0
- package/dist/esm/elements/Bookmark.js.map +1 -0
- package/dist/esm/elements/BookmarkManager.js +99 -0
- package/dist/esm/elements/BookmarkManager.js.map +1 -0
- package/dist/esm/elements/Comment.js +181 -0
- package/dist/esm/elements/Comment.js.map +1 -0
- package/dist/esm/elements/CommentManager.js +233 -0
- package/dist/esm/elements/CommentManager.js.map +1 -0
- package/dist/esm/elements/CommonTypes.js +106 -0
- package/dist/esm/elements/CommonTypes.js.map +1 -0
- package/dist/esm/elements/CustomXml.js +19 -0
- package/dist/esm/elements/CustomXml.js.map +1 -0
- package/dist/esm/elements/Endnote.js +107 -0
- package/dist/esm/elements/Endnote.js.map +1 -0
- package/dist/esm/elements/EndnoteManager.js +119 -0
- package/dist/esm/elements/EndnoteManager.js.map +1 -0
- package/dist/esm/elements/Field.js +856 -0
- package/dist/esm/elements/Field.js.map +1 -0
- package/dist/esm/elements/FieldHelpers.js +134 -0
- package/dist/esm/elements/FieldHelpers.js.map +1 -0
- package/dist/esm/elements/FontManager.js +158 -0
- package/dist/esm/elements/FontManager.js.map +1 -0
- package/dist/esm/elements/Footer.js +141 -0
- package/dist/esm/elements/Footer.js.map +1 -0
- package/dist/esm/elements/Footnote.js +107 -0
- package/dist/esm/elements/Footnote.js.map +1 -0
- package/dist/esm/elements/FootnoteManager.js +119 -0
- package/dist/esm/elements/FootnoteManager.js.map +1 -0
- package/dist/esm/elements/Header.js +141 -0
- package/dist/esm/elements/Header.js.map +1 -0
- package/dist/esm/elements/HeaderFooterManager.js +87 -0
- package/dist/esm/elements/HeaderFooterManager.js.map +1 -0
- package/dist/esm/elements/Hyperlink.js +586 -0
- package/dist/esm/elements/Hyperlink.js.map +1 -0
- package/dist/esm/elements/Image.js +1288 -0
- package/dist/esm/elements/Image.js.map +1 -0
- package/dist/esm/elements/ImageManager.js +223 -0
- package/dist/esm/elements/ImageManager.js.map +1 -0
- package/dist/esm/elements/ImageRun.js +29 -0
- package/dist/esm/elements/ImageRun.js.map +1 -0
- package/dist/esm/elements/MathElement.js +37 -0
- package/dist/esm/elements/MathElement.js.map +1 -0
- package/dist/esm/elements/Paragraph.js +2308 -0
- package/dist/esm/elements/Paragraph.js.map +1 -0
- package/dist/esm/elements/PreservedElement.js +29 -0
- package/dist/esm/elements/PreservedElement.js.map +1 -0
- package/dist/esm/elements/PropertyChangeTypes.js +53 -0
- package/dist/esm/elements/PropertyChangeTypes.js.map +1 -0
- package/dist/esm/elements/RangeMarker.js +219 -0
- package/dist/esm/elements/RangeMarker.js.map +1 -0
- package/dist/esm/elements/RegisteredBodyElement.js +40 -0
- package/dist/esm/elements/RegisteredBodyElement.js.map +1 -0
- package/dist/esm/elements/Revision.js +498 -0
- package/dist/esm/elements/Revision.js.map +1 -0
- package/dist/esm/elements/RevisionContent.js +18 -0
- package/dist/esm/elements/RevisionContent.js.map +1 -0
- package/dist/esm/elements/RevisionManager.js +486 -0
- package/dist/esm/elements/RevisionManager.js.map +1 -0
- package/dist/esm/elements/Run.js +1465 -0
- package/dist/esm/elements/Run.js.map +1 -0
- package/dist/esm/elements/Section.js +978 -0
- package/dist/esm/elements/Section.js.map +1 -0
- package/dist/esm/elements/Shape.js +493 -0
- package/dist/esm/elements/Shape.js.map +1 -0
- package/dist/esm/elements/StructuredDocumentTag.js +471 -0
- package/dist/esm/elements/StructuredDocumentTag.js.map +1 -0
- package/dist/esm/elements/Table.js +1456 -0
- package/dist/esm/elements/Table.js.map +1 -0
- package/dist/esm/elements/TableCell.js +835 -0
- package/dist/esm/elements/TableCell.js.map +1 -0
- package/dist/esm/elements/TableGridChange.js +52 -0
- package/dist/esm/elements/TableGridChange.js.map +1 -0
- package/dist/esm/elements/TableOfContents.js +389 -0
- package/dist/esm/elements/TableOfContents.js.map +1 -0
- package/dist/esm/elements/TableOfContentsElement.js +29 -0
- package/dist/esm/elements/TableOfContentsElement.js.map +1 -0
- package/dist/esm/elements/TableRow.js +555 -0
- package/dist/esm/elements/TableRow.js.map +1 -0
- package/dist/esm/elements/TextBox.js +459 -0
- package/dist/esm/elements/TextBox.js.map +1 -0
- package/dist/esm/formatting/AbstractNumbering.js +325 -0
- package/dist/esm/formatting/AbstractNumbering.js.map +1 -0
- package/dist/esm/formatting/NumberingInstance.js +150 -0
- package/dist/esm/formatting/NumberingInstance.js.map +1 -0
- package/dist/esm/formatting/NumberingLevel.js +608 -0
- package/dist/esm/formatting/NumberingLevel.js.map +1 -0
- package/dist/esm/formatting/NumberingManager.js +423 -0
- package/dist/esm/formatting/NumberingManager.js.map +1 -0
- package/dist/esm/formatting/Style.js +1151 -0
- package/dist/esm/formatting/Style.js.map +1 -0
- package/dist/esm/formatting/StylesManager.js +557 -0
- package/dist/esm/formatting/StylesManager.js.map +1 -0
- package/dist/esm/helpers/CleanupHelper.js +350 -0
- package/dist/esm/helpers/CleanupHelper.js.map +1 -0
- package/dist/esm/images/ImageOptimizer.js +161 -0
- package/dist/esm/images/ImageOptimizer.js.map +1 -0
- package/dist/esm/index.js +75 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal.js +16 -0
- package/dist/esm/internal.js.map +1 -0
- package/dist/esm/managers/DrawingManager.js +163 -0
- package/dist/esm/managers/DrawingManager.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/processors/ChangelogGenerator.js +970 -0
- package/dist/esm/processors/ChangelogGenerator.js.map +1 -0
- package/dist/esm/processors/CompatibilityUpgrader.js +130 -0
- package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -0
- package/dist/esm/processors/InMemoryRevisionAcceptor.js +530 -0
- package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -0
- package/dist/esm/processors/MoveOperationHelper.js +57 -0
- package/dist/esm/processors/MoveOperationHelper.js.map +1 -0
- package/dist/esm/processors/RevisionAwareProcessor.js +232 -0
- package/dist/esm/processors/RevisionAwareProcessor.js.map +1 -0
- package/dist/esm/processors/RevisionWalker.js +278 -0
- package/dist/esm/processors/RevisionWalker.js.map +1 -0
- package/dist/{utils → esm/processors}/SelectiveRevisionAcceptor.js +81 -42
- package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -0
- package/dist/esm/processors/ShadingResolver.js +66 -0
- package/dist/esm/processors/ShadingResolver.js.map +1 -0
- package/dist/esm/processors/acceptRevisions.js +416 -0
- package/dist/esm/processors/acceptRevisions.js.map +1 -0
- package/dist/esm/processors/cnfStyleDecoder.js +89 -0
- package/dist/esm/processors/cnfStyleDecoder.js.map +1 -0
- package/dist/esm/processors/stripTrackedChanges.js +201 -0
- package/dist/esm/processors/stripTrackedChanges.js.map +1 -0
- package/dist/esm/tracking/DocumentTrackingContext.js +531 -0
- package/dist/esm/tracking/DocumentTrackingContext.js.map +1 -0
- package/dist/esm/tracking/TrackingContext.js +2 -0
- package/dist/esm/tracking/TrackingContext.js.map +1 -0
- package/dist/esm/types/compatibility-types.js +8 -0
- package/dist/esm/types/compatibility-types.js.map +1 -0
- package/dist/esm/types/document-types.js +2 -0
- package/dist/esm/types/document-types.js.map +1 -0
- package/dist/esm/types/formatting.js +2 -0
- package/dist/esm/types/formatting.js.map +1 -0
- package/dist/esm/types/list-types.js +2 -0
- package/dist/esm/types/list-types.js.map +1 -0
- package/dist/esm/types/settings-types.js +2 -0
- package/dist/esm/types/settings-types.js.map +1 -0
- package/dist/esm/types/styleConfig.js +2 -0
- package/dist/esm/types/styleConfig.js.map +1 -0
- package/dist/esm/utils/KeyedRegistry.js +32 -0
- package/dist/esm/utils/KeyedRegistry.js.map +1 -0
- package/dist/esm/utils/corruptionDetection.js +155 -0
- package/dist/esm/utils/corruptionDetection.js.map +1 -0
- package/dist/esm/utils/dateFormatting.js +4 -0
- package/dist/esm/utils/dateFormatting.js.map +1 -0
- package/dist/esm/utils/deepClone.js +40 -0
- package/dist/esm/utils/deepClone.js.map +1 -0
- package/dist/esm/utils/deepEqual.js +47 -0
- package/dist/esm/utils/deepEqual.js.map +1 -0
- package/dist/esm/utils/diagnostics.js +69 -0
- package/dist/esm/utils/diagnostics.js.map +1 -0
- package/dist/esm/utils/errorHandling.js +36 -0
- package/dist/esm/utils/errorHandling.js.map +1 -0
- package/dist/esm/utils/formatting.js +93 -0
- package/dist/esm/utils/formatting.js.map +1 -0
- package/dist/esm/utils/list-detection.js +148 -0
- package/dist/esm/utils/list-detection.js.map +1 -0
- package/dist/esm/utils/logger.js +205 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/parsingHelpers.js +56 -0
- package/dist/esm/utils/parsingHelpers.js.map +1 -0
- package/dist/esm/utils/textDiff.js +42 -0
- package/dist/esm/utils/textDiff.js.map +1 -0
- package/dist/esm/utils/units.js +152 -0
- package/dist/esm/utils/units.js.map +1 -0
- package/dist/esm/utils/validation.js +285 -0
- package/dist/esm/utils/validation.js.map +1 -0
- package/dist/esm/utils/xmlSanitization.js +54 -0
- package/dist/esm/utils/xmlSanitization.js.map +1 -0
- package/dist/esm/validation/RevisionAutoFixer.js +340 -0
- package/dist/esm/validation/RevisionAutoFixer.js.map +1 -0
- package/dist/esm/validation/RevisionValidator.js +240 -0
- package/dist/esm/validation/RevisionValidator.js.map +1 -0
- package/dist/esm/validation/ValidationRuleRegistry.js +40 -0
- package/dist/esm/validation/ValidationRuleRegistry.js.map +1 -0
- package/dist/esm/validation/ValidationRules.js +92 -0
- package/dist/esm/validation/ValidationRules.js.map +1 -0
- package/dist/esm/validation/index.js +4 -0
- package/dist/esm/validation/index.js.map +1 -0
- package/dist/esm/xml/XMLBuilder.js +434 -0
- package/dist/esm/xml/XMLBuilder.js.map +1 -0
- package/dist/esm/xml/XMLParser.js +486 -0
- package/dist/esm/xml/XMLParser.js.map +1 -0
- package/dist/esm/zip/ZipHandler.js +298 -0
- package/dist/esm/zip/ZipHandler.js.map +1 -0
- package/dist/esm/zip/ZipReader.js +147 -0
- package/dist/esm/zip/ZipReader.js.map +1 -0
- package/dist/esm/zip/ZipWriter.js +199 -0
- package/dist/esm/zip/ZipWriter.js.map +1 -0
- package/dist/esm/zip/errors.js +43 -0
- package/dist/esm/zip/errors.js.map +1 -0
- package/dist/esm/zip/types.js +31 -0
- package/dist/esm/zip/types.js.map +1 -0
- package/dist/formatting/AbstractNumbering.d.ts +2 -2
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +33 -33
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingInstance.d.ts +2 -2
- package/dist/formatting/NumberingInstance.d.ts.map +1 -1
- package/dist/formatting/NumberingInstance.js +7 -7
- package/dist/formatting/NumberingInstance.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +11 -2
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +111 -25
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts +4 -4
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +28 -28
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts +14 -7
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +309 -112
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +2 -2
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +52 -52
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/helpers/CleanupHelper.d.ts +1 -1
- package/dist/helpers/CleanupHelper.d.ts.map +1 -1
- package/dist/helpers/CleanupHelper.js +15 -15
- package/dist/helpers/CleanupHelper.js.map +1 -1
- package/dist/index.d.ts +81 -90
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +286 -317
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +16 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +42 -0
- package/dist/internal.js.map +1 -0
- package/dist/managers/DrawingManager.d.ts +3 -3
- package/dist/managers/DrawingManager.d.ts.map +1 -1
- package/dist/managers/DrawingManager.js +12 -12
- package/dist/managers/DrawingManager.js.map +1 -1
- package/dist/{utils → processors}/ChangelogGenerator.d.ts +2 -2
- package/dist/processors/ChangelogGenerator.d.ts.map +1 -0
- package/dist/{utils → processors}/ChangelogGenerator.js +2 -2
- package/dist/processors/ChangelogGenerator.js.map +1 -0
- package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -0
- package/dist/{utils → processors}/CompatibilityUpgrader.js +10 -10
- package/dist/processors/CompatibilityUpgrader.js.map +1 -0
- package/dist/{utils → processors}/InMemoryRevisionAcceptor.d.ts +3 -3
- package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -0
- package/dist/{utils → processors}/InMemoryRevisionAcceptor.js +84 -27
- package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -0
- package/dist/{utils → processors}/MoveOperationHelper.d.ts +4 -4
- package/dist/processors/MoveOperationHelper.d.ts.map +1 -0
- package/dist/{utils → processors}/MoveOperationHelper.js +10 -10
- package/dist/processors/MoveOperationHelper.js.map +1 -0
- package/dist/{utils → processors}/RevisionAwareProcessor.d.ts +3 -3
- package/dist/processors/RevisionAwareProcessor.d.ts.map +1 -0
- package/dist/{utils → processors}/RevisionAwareProcessor.js +2 -2
- package/dist/processors/RevisionAwareProcessor.js.map +1 -0
- package/dist/{utils → processors}/RevisionWalker.d.ts +2 -1
- package/dist/processors/RevisionWalker.d.ts.map +1 -0
- package/dist/{utils → processors}/RevisionWalker.js +28 -0
- package/dist/processors/RevisionWalker.js.map +1 -0
- package/dist/{utils → processors}/SelectiveRevisionAcceptor.d.ts +4 -3
- package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -0
- package/dist/processors/SelectiveRevisionAcceptor.js +402 -0
- package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -0
- package/dist/processors/ShadingResolver.d.ts +6 -0
- package/dist/processors/ShadingResolver.d.ts.map +1 -0
- package/dist/{utils → processors}/ShadingResolver.js +2 -2
- package/dist/processors/ShadingResolver.js.map +1 -0
- package/dist/{utils → processors}/acceptRevisions.d.ts +1 -1
- package/dist/processors/acceptRevisions.d.ts.map +1 -0
- package/dist/{utils → processors}/acceptRevisions.js +24 -4
- package/dist/processors/acceptRevisions.js.map +1 -0
- package/dist/{utils → processors}/cnfStyleDecoder.d.ts +1 -1
- package/dist/processors/cnfStyleDecoder.d.ts.map +1 -0
- package/dist/processors/cnfStyleDecoder.js.map +1 -0
- package/dist/processors/stripTrackedChanges.d.ts +3 -0
- package/dist/processors/stripTrackedChanges.d.ts.map +1 -0
- package/dist/{utils → processors}/stripTrackedChanges.js +16 -6
- package/dist/processors/stripTrackedChanges.js.map +1 -0
- package/dist/tracking/DocumentTrackingContext.d.ts +4 -4
- package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
- package/dist/tracking/DocumentTrackingContext.js +38 -43
- package/dist/tracking/DocumentTrackingContext.js.map +1 -1
- package/dist/tracking/TrackingContext.d.ts +8 -8
- package/dist/tracking/TrackingContext.d.ts.map +1 -1
- package/dist/tracking/TrackingContext.js.map +1 -1
- package/dist/types/document-types.d.ts +28 -0
- package/dist/types/document-types.d.ts.map +1 -0
- package/dist/types/document-types.js +3 -0
- package/dist/types/document-types.js.map +1 -0
- package/dist/types/formatting.d.ts +4 -4
- package/dist/types/formatting.d.ts.map +1 -1
- package/dist/types/formatting.js.map +1 -1
- package/dist/types/settings-types.d.ts +6 -0
- package/dist/types/settings-types.d.ts.map +1 -1
- package/dist/types/settings-types.js.map +1 -1
- package/dist/utils/KeyedRegistry.d.ts +13 -0
- package/dist/utils/KeyedRegistry.d.ts.map +1 -0
- package/dist/utils/KeyedRegistry.js +36 -0
- package/dist/utils/KeyedRegistry.js.map +1 -0
- package/dist/utils/corruptionDetection.d.ts +1 -1
- package/dist/utils/corruptionDetection.d.ts.map +1 -1
- package/dist/utils/corruptionDetection.js +4 -4
- package/dist/utils/corruptionDetection.js.map +1 -1
- package/dist/utils/deepEqual.d.ts +2 -0
- package/dist/utils/deepEqual.d.ts.map +1 -0
- package/dist/utils/deepEqual.js +50 -0
- package/dist/utils/deepEqual.js.map +1 -0
- package/dist/utils/list-detection.d.ts +2 -2
- package/dist/utils/list-detection.d.ts.map +1 -1
- package/dist/utils/list-detection.js.map +1 -1
- package/dist/utils/parsingHelpers.d.ts +1 -1
- package/dist/utils/parsingHelpers.d.ts.map +1 -1
- package/dist/utils/parsingHelpers.js +2 -2
- package/dist/utils/parsingHelpers.js.map +1 -1
- package/dist/utils/validation.js +7 -7
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/xmlSanitization.js +2 -2
- package/dist/utils/xmlSanitization.js.map +1 -1
- package/dist/validation/RevisionAutoFixer.d.ts +4 -4
- package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
- package/dist/validation/RevisionAutoFixer.js +11 -11
- package/dist/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/validation/RevisionValidator.d.ts +5 -4
- package/dist/validation/RevisionValidator.d.ts.map +1 -1
- package/dist/validation/RevisionValidator.js +29 -30
- package/dist/validation/RevisionValidator.js.map +1 -1
- package/dist/validation/ValidationRuleRegistry.d.ts +27 -0
- package/dist/validation/ValidationRuleRegistry.d.ts.map +1 -0
- package/dist/validation/ValidationRuleRegistry.js +43 -0
- package/dist/validation/ValidationRuleRegistry.js.map +1 -0
- package/dist/validation/index.d.ts +3 -3
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +10 -10
- package/dist/validation/index.js.map +1 -1
- package/dist/xml/XMLBuilder.d.ts +6 -1
- package/dist/xml/XMLBuilder.d.ts.map +1 -1
- package/dist/xml/XMLBuilder.js +11 -6
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/xml/XMLParser.js +6 -6
- package/dist/xml/XMLParser.js.map +1 -1
- package/dist/zip/ZipHandler.d.ts +1 -1
- package/dist/zip/ZipHandler.d.ts.map +1 -1
- package/dist/zip/ZipHandler.js +8 -8
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.d.ts +1 -1
- package/dist/zip/ZipReader.d.ts.map +1 -1
- package/dist/zip/ZipReader.js +14 -14
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/ZipWriter.d.ts +1 -1
- package/dist/zip/ZipWriter.d.ts.map +1 -1
- package/dist/zip/ZipWriter.js +10 -10
- package/dist/zip/ZipWriter.js.map +1 -1
- package/package.json +20 -4
- package/src/constants/legacyCompatFlags.ts +1 -1
- package/src/core/Document.ts +461 -167
- package/src/core/DocumentContent.ts +14 -11
- package/src/core/DocumentEvents.ts +90 -0
- package/src/core/DocumentGenerator.ts +49 -22
- package/src/core/DocumentParser.ts +2180 -617
- package/src/core/DocumentValidator.ts +7 -7
- package/src/core/ElementRegistry.ts +69 -0
- package/src/core/Relationship.ts +1 -1
- package/src/core/RelationshipManager.ts +4 -4
- package/src/elements/AlternateContent.ts +1 -1
- package/src/elements/Bookmark.ts +52 -4
- package/src/elements/BookmarkManager.ts +2 -2
- package/src/elements/Comment.ts +3 -3
- package/src/elements/CommentManager.ts +4 -4
- package/src/elements/CommonTypes.ts +45 -7
- package/src/elements/CustomXml.ts +1 -1
- package/src/elements/Endnote.ts +2 -2
- package/src/elements/EndnoteManager.ts +3 -3
- package/src/elements/Field.ts +44 -10
- package/src/elements/FieldHelpers.ts +2 -2
- package/src/elements/Footer.ts +4 -4
- package/src/elements/Footnote.ts +2 -2
- package/src/elements/FootnoteManager.ts +3 -3
- package/src/elements/Header.ts +4 -4
- package/src/elements/HeaderFooterManager.ts +2 -2
- package/src/elements/Hyperlink.ts +16 -12
- package/src/elements/Image.ts +3 -3
- package/src/elements/ImageManager.ts +2 -2
- package/src/elements/ImageRun.ts +3 -3
- package/src/elements/MathElement.ts +1 -1
- package/src/elements/Paragraph.ts +221 -88
- package/src/elements/PreservedElement.ts +1 -1
- package/src/elements/PropertyChangeTypes.ts +2 -2
- package/src/elements/RangeMarker.ts +153 -12
- package/src/elements/RegisteredBodyElement.ts +52 -0
- package/src/elements/Revision.ts +14 -14
- package/src/elements/RevisionContent.ts +3 -3
- package/src/elements/RevisionManager.ts +3 -3
- package/src/elements/Run.ts +221 -94
- package/src/elements/Section.ts +136 -69
- package/src/elements/Shape.ts +4 -4
- package/src/elements/StructuredDocumentTag.ts +3 -3
- package/src/elements/Table.ts +91 -27
- package/src/elements/TableCell.ts +62 -34
- package/src/elements/TableGridChange.ts +1 -1
- package/src/elements/TableOfContents.ts +1 -1
- package/src/elements/TableOfContentsElement.ts +2 -2
- package/src/elements/TableRow.ts +192 -48
- package/src/elements/TextBox.ts +5 -5
- package/src/formatting/AbstractNumbering.ts +3 -3
- package/src/formatting/NumberingInstance.ts +2 -2
- package/src/formatting/NumberingLevel.ts +201 -10
- package/src/formatting/NumberingManager.ts +5 -5
- package/src/formatting/Style.ts +382 -86
- package/src/formatting/StylesManager.ts +4 -4
- package/src/helpers/CleanupHelper.ts +6 -6
- package/src/index.ts +118 -127
- package/src/internal.ts +79 -0
- package/src/managers/DrawingManager.ts +3 -3
- package/src/{utils → processors}/ChangelogGenerator.ts +3 -3
- package/src/{utils → processors}/CompatibilityUpgrader.ts +2 -2
- package/src/{utils → processors}/InMemoryRevisionAcceptor.ts +100 -12
- package/src/{utils → processors}/MoveOperationHelper.ts +5 -5
- package/src/{utils → processors}/RevisionAwareProcessor.ts +3 -3
- package/src/{utils → processors}/RevisionWalker.ts +42 -1
- package/src/{utils → processors}/SelectiveRevisionAcceptor.ts +98 -39
- package/src/{utils → processors}/ShadingResolver.ts +5 -5
- package/src/{utils → processors}/acceptRevisions.ts +77 -9
- package/src/{utils → processors}/cnfStyleDecoder.ts +1 -1
- package/src/{utils → processors}/stripTrackedChanges.ts +35 -10
- package/src/tracking/DocumentTrackingContext.ts +12 -14
- package/src/tracking/TrackingContext.ts +8 -8
- package/src/types/document-types.ts +53 -0
- package/src/types/formatting.ts +4 -4
- package/src/types/settings-types.ts +32 -0
- package/src/utils/KeyedRegistry.ts +41 -0
- package/src/utils/corruptionDetection.ts +2 -2
- package/src/utils/deepEqual.ts +58 -0
- package/src/utils/list-detection.ts +2 -2
- package/src/utils/parsingHelpers.ts +11 -3
- package/src/utils/validation.ts +3 -3
- package/src/utils/xmlSanitization.ts +1 -1
- package/src/validation/RevisionAutoFixer.ts +5 -5
- package/src/validation/RevisionValidator.ts +39 -28
- package/src/validation/ValidationRuleRegistry.ts +86 -0
- package/src/validation/index.ts +3 -3
- package/src/xml/XMLBuilder.ts +13 -3
- package/src/xml/XMLParser.ts +2 -2
- package/src/zip/ZipHandler.ts +4 -4
- package/src/zip/ZipReader.ts +3 -3
- package/src/zip/ZipWriter.ts +3 -3
- package/dist/utils/ChangelogGenerator.d.ts.map +0 -1
- package/dist/utils/ChangelogGenerator.js.map +0 -1
- package/dist/utils/CompatibilityUpgrader.d.ts.map +0 -1
- package/dist/utils/CompatibilityUpgrader.js.map +0 -1
- package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +0 -1
- package/dist/utils/InMemoryRevisionAcceptor.js.map +0 -1
- package/dist/utils/MoveOperationHelper.d.ts.map +0 -1
- package/dist/utils/MoveOperationHelper.js.map +0 -1
- package/dist/utils/RevisionAwareProcessor.d.ts.map +0 -1
- package/dist/utils/RevisionAwareProcessor.js.map +0 -1
- package/dist/utils/RevisionWalker.d.ts.map +0 -1
- package/dist/utils/RevisionWalker.js.map +0 -1
- package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +0 -1
- package/dist/utils/SelectiveRevisionAcceptor.js.map +0 -1
- package/dist/utils/ShadingResolver.d.ts +0 -6
- package/dist/utils/ShadingResolver.d.ts.map +0 -1
- package/dist/utils/ShadingResolver.js.map +0 -1
- package/dist/utils/acceptRevisions.d.ts.map +0 -1
- package/dist/utils/acceptRevisions.js.map +0 -1
- package/dist/utils/cnfStyleDecoder.d.ts.map +0 -1
- package/dist/utils/cnfStyleDecoder.js.map +0 -1
- package/dist/utils/stripTrackedChanges.d.ts +0 -3
- package/dist/utils/stripTrackedChanges.d.ts.map +0 -1
- package/dist/utils/stripTrackedChanges.js.map +0 -1
- package/src/__tests__/helper-methods.test.ts +0 -512
- package/src/constants/CLAUDE.md +0 -28
- package/src/core/CLAUDE.md +0 -113
- package/src/elements/CLAUDE.md +0 -142
- package/src/formatting/CLAUDE.md +0 -78
- package/src/managers/CLAUDE.md +0 -47
- package/src/tracking/CLAUDE.md +0 -30
- package/src/types/CLAUDE.md +0 -39
- package/src/utils/CLAUDE.md +0 -168
- package/src/validation/CLAUDE.md +0 -40
- package/src/xml/CLAUDE.md +0 -65
- package/src/zip/CLAUDE.md +0 -55
- /package/dist/{utils → processors}/CompatibilityUpgrader.d.ts +0 -0
- /package/dist/{utils → processors}/cnfStyleDecoder.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export function mergeFormatting(base, override) {
|
|
2
|
+
const result = { ...base };
|
|
3
|
+
for (const [key, value] of Object.entries(override)) {
|
|
4
|
+
if (value === undefined)
|
|
5
|
+
continue;
|
|
6
|
+
if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
|
|
7
|
+
result[key] = mergeFormatting(result[key] || {}, value);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
result[key] = value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
export function cloneFormatting(formatting) {
|
|
16
|
+
return JSON.parse(JSON.stringify(formatting));
|
|
17
|
+
}
|
|
18
|
+
export function hasFormatting(formatting) {
|
|
19
|
+
for (const value of Object.values(formatting)) {
|
|
20
|
+
if (value !== undefined && value !== null) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
export function cleanFormatting(formatting) {
|
|
27
|
+
const cleaned = {};
|
|
28
|
+
for (const [key, value] of Object.entries(formatting)) {
|
|
29
|
+
if (value !== undefined && value !== null) {
|
|
30
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
31
|
+
const cleanedNested = cleanFormatting(value);
|
|
32
|
+
if (Object.keys(cleanedNested).length > 0) {
|
|
33
|
+
cleaned[key] = cleanedNested;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
cleaned[key] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return cleaned;
|
|
42
|
+
}
|
|
43
|
+
export function isEqualFormatting(format1, format2) {
|
|
44
|
+
if (format1 === format2)
|
|
45
|
+
return true;
|
|
46
|
+
if (!format1 || !format2)
|
|
47
|
+
return false;
|
|
48
|
+
const keys1 = Object.keys(format1);
|
|
49
|
+
const keys2 = Object.keys(format2);
|
|
50
|
+
if (keys1.length !== keys2.length)
|
|
51
|
+
return false;
|
|
52
|
+
for (const key of keys1) {
|
|
53
|
+
const val1 = format1[key];
|
|
54
|
+
const val2 = format2[key];
|
|
55
|
+
if ((val1 === undefined || val1 === null) && (val2 === undefined || val2 === null)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (typeof val1 === 'object' &&
|
|
62
|
+
val1 !== null &&
|
|
63
|
+
typeof val2 === 'object' &&
|
|
64
|
+
val2 !== null &&
|
|
65
|
+
!Array.isArray(val1) &&
|
|
66
|
+
!Array.isArray(val2)) {
|
|
67
|
+
if (!isEqualFormatting(val1, val2))
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
else if (val1 !== val2) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
export function applyDefaults(formatting, defaults) {
|
|
77
|
+
const result = { ...defaults };
|
|
78
|
+
for (const [key, value] of Object.entries(formatting)) {
|
|
79
|
+
if (value !== undefined) {
|
|
80
|
+
if (typeof value === 'object' &&
|
|
81
|
+
!Array.isArray(value) &&
|
|
82
|
+
value !== null &&
|
|
83
|
+
typeof defaults[key] === 'object') {
|
|
84
|
+
result[key] = applyDefaults(value, defaults[key]);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
result[key] = value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../../src/utils/formatting.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,eAAe,CAAgC,IAAO,EAAE,QAAoB;IAC1F,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAEzE,MAAM,CAAC,GAAc,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,GAAc,CAAC,IAAK,EAAU,EAAE,KAAK,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YAEN,MAAM,CAAC,GAAc,CAAC,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAgBD,MAAM,UAAU,eAAe,CAAI,UAAa;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;AAChD,CAAC;AAeD,MAAM,UAAU,aAAa,CAAC,UAAmC;IAC/D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAgBD,MAAM,UAAU,eAAe,CAAgC,UAAa;IAC1E,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAEvD,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;gBAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1C,OAAO,CAAC,GAAc,CAAC,GAAG,aAAoB,CAAC;gBACjD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAc,CAAC,GAAG,KAAK,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAmBD,MAAM,UAAU,iBAAiB,CAC/B,OAAgC,EAChC,OAAgC;IAGhC,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAGrC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAGvC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAGnC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAGhD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAG1B,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACnF,SAAS;QACX,CAAC;QAGD,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACpF,OAAO,KAAK,CAAC;QACf,CAAC;QAGD,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YACpB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EACpB,CAAC;YACD,IAAI,CAAC,iBAAiB,CAAC,IAA+B,EAAE,IAA+B,CAAC;gBACtF,OAAO,KAAK,CAAC;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAiBD,MAAM,UAAU,aAAa,CAC3B,UAAsB,EACtB,QAAW;IAEX,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IACE,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBACrB,KAAK,KAAK,IAAI;gBACd,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,EACjC,CAAC;gBAED,MAAM,CAAC,GAAc,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAc,CAAC,GAAG,KAAK,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Formatting utilities for deep merging and cloning formatting objects\n * Used for style inheritance and applying formatting\n */\n\n/**\n * Deep merges two formatting objects, with override taking precedence\n * Used for style inheritance and applying formatting\n *\n * @param base - Base formatting object\n * @param override - Override formatting object (takes precedence)\n * @returns Merged formatting object\n *\n * @example\n * ```typescript\n * const baseFormat = { bold: true, fontSize: 24 };\n * const overrideFormat = { fontSize: 28, italic: true };\n * const result = mergeFormatting(baseFormat, overrideFormat);\n * // Result: { bold: true, fontSize: 28, italic: true }\n * ```\n */\nexport function mergeFormatting<T extends Record<string, any>>(base: T, override: Partial<T>): T {\n const result = { ...base };\n\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n\n if (typeof value === 'object' && !Array.isArray(value) && value !== null) {\n // Deep merge nested objects\n result[key as keyof T] = mergeFormatting(result[key as keyof T] || ({} as any), value);\n } else {\n // Direct assignment for primitives\n result[key as keyof T] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Deep clones a formatting object\n * Creates a completely independent copy with no shared references\n *\n * @param formatting - Formatting object to clone\n * @returns Cloned formatting object\n *\n * @example\n * ```typescript\n * const original = { bold: true, indentation: { left: 100 } };\n * const cloned = cloneFormatting(original);\n * cloned.indentation.left = 200; // Doesn't affect original\n * ```\n */\nexport function cloneFormatting<T>(formatting: T): T {\n return JSON.parse(JSON.stringify(formatting));\n}\n\n/**\n * Checks if a formatting object has any defined properties\n *\n * @param formatting - Formatting object to check\n * @returns True if the object has at least one defined property\n *\n * @example\n * ```typescript\n * hasFormatting({}) // false\n * hasFormatting({ bold: true }) // true\n * hasFormatting({ bold: undefined }) // false\n * ```\n */\nexport function hasFormatting(formatting: Record<string, unknown>): boolean {\n for (const value of Object.values(formatting)) {\n if (value !== undefined && value !== null) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Removes undefined and null properties from a formatting object\n * Useful for cleaning up formatting before comparison or serialization\n *\n * @param formatting - Formatting object to clean\n * @returns Cleaned formatting object with no undefined/null values\n *\n * @example\n * ```typescript\n * const dirty = { bold: true, italic: undefined, fontSize: null, underline: false };\n * const clean = cleanFormatting(dirty);\n * // Result: { bold: true, underline: false }\n * ```\n */\nexport function cleanFormatting<T extends Record<string, any>>(formatting: T): Partial<T> {\n const cleaned: Partial<T> = {};\n\n for (const [key, value] of Object.entries(formatting)) {\n if (value !== undefined && value !== null) {\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Recursively clean nested objects\n const cleanedNested = cleanFormatting(value);\n if (Object.keys(cleanedNested).length > 0) {\n cleaned[key as keyof T] = cleanedNested as any;\n }\n } else {\n cleaned[key as keyof T] = value;\n }\n }\n }\n\n return cleaned;\n}\n\n/**\n * Compares two formatting objects for equality\n * Performs deep comparison of all properties\n *\n * @param format1 - First formatting object\n * @param format2 - Second formatting object\n * @returns True if the formatting objects are equal\n *\n * @example\n * ```typescript\n * const a = { bold: true, fontSize: 24 };\n * const b = { bold: true, fontSize: 24 };\n * const c = { bold: true, fontSize: 28 };\n * isEqualFormatting(a, b) // true\n * isEqualFormatting(a, c) // false\n * ```\n */\nexport function isEqualFormatting(\n format1: Record<string, unknown>,\n format2: Record<string, unknown>\n): boolean {\n // Quick reference check\n if (format1 === format2) return true;\n\n // Null/undefined checks\n if (!format1 || !format2) return false;\n\n // Get all keys from both objects\n const keys1 = Object.keys(format1);\n const keys2 = Object.keys(format2);\n\n // Check if they have the same number of properties\n if (keys1.length !== keys2.length) return false;\n\n // Check all properties\n for (const key of keys1) {\n const val1 = format1[key];\n const val2 = format2[key];\n\n // Both undefined/null - considered equal\n if ((val1 === undefined || val1 === null) && (val2 === undefined || val2 === null)) {\n continue;\n }\n\n // One is undefined/null and the other isn't\n if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {\n return false;\n }\n\n // Check nested objects\n if (\n typeof val1 === 'object' &&\n val1 !== null &&\n typeof val2 === 'object' &&\n val2 !== null &&\n !Array.isArray(val1) &&\n !Array.isArray(val2)\n ) {\n if (!isEqualFormatting(val1 as Record<string, unknown>, val2 as Record<string, unknown>))\n return false;\n } else if (val1 !== val2) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Applies default values to a formatting object for any undefined properties\n *\n * @param formatting - Formatting object to apply defaults to\n * @param defaults - Default values\n * @returns Formatting object with defaults applied\n *\n * @example\n * ```typescript\n * const format = { bold: true };\n * const defaults = { bold: false, italic: false, fontSize: 24 };\n * const result = applyDefaults(format, defaults);\n * // Result: { bold: true, italic: false, fontSize: 24 }\n * ```\n */\nexport function applyDefaults<T extends Record<string, any>>(\n formatting: Partial<T>,\n defaults: T\n): T {\n const result = { ...defaults };\n\n for (const [key, value] of Object.entries(formatting)) {\n if (value !== undefined) {\n if (\n typeof value === 'object' &&\n !Array.isArray(value) &&\n value !== null &&\n typeof defaults[key] === 'object'\n ) {\n // Deep merge nested objects\n result[key as keyof T] = applyDefaults(value, defaults[key]);\n } else {\n result[key as keyof T] = value;\n }\n }\n }\n\n return result;\n}\n"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export const TYPED_LIST_PATTERNS = {
|
|
2
|
+
decimal: /^(\d+)[.)]\s+/,
|
|
3
|
+
lowerLetter: /^([a-z])[.)]\s+/,
|
|
4
|
+
upperLetter: /^([A-Z])[.)]\s+/,
|
|
5
|
+
lowerRoman: /^((?:i{1,3}|iv|vi{0,3}|ix|x{1,3}))[.)]\s+/i,
|
|
6
|
+
bullet: /^[•●○◦▪■□]\s+/,
|
|
7
|
+
dash: /^[-–—]\s+/,
|
|
8
|
+
arrow: /^[►▸▶→]\s+/,
|
|
9
|
+
};
|
|
10
|
+
export const PATTERN_TO_CATEGORY = {
|
|
11
|
+
decimal: 'numbered',
|
|
12
|
+
lowerLetter: 'numbered',
|
|
13
|
+
upperLetter: 'numbered',
|
|
14
|
+
lowerRoman: 'numbered',
|
|
15
|
+
bullet: 'bullet',
|
|
16
|
+
dash: 'bullet',
|
|
17
|
+
arrow: 'bullet',
|
|
18
|
+
};
|
|
19
|
+
export const FORMAT_TO_LEVEL = {
|
|
20
|
+
decimal: 0,
|
|
21
|
+
lowerLetter: 1,
|
|
22
|
+
upperLetter: 1,
|
|
23
|
+
lowerRoman: 2,
|
|
24
|
+
upperRoman: 2,
|
|
25
|
+
bullet: 0,
|
|
26
|
+
dash: 0,
|
|
27
|
+
arrow: 0,
|
|
28
|
+
};
|
|
29
|
+
export function getLevelFromFormat(format) {
|
|
30
|
+
if (!format)
|
|
31
|
+
return 0;
|
|
32
|
+
return FORMAT_TO_LEVEL[format] ?? 0;
|
|
33
|
+
}
|
|
34
|
+
const WORD_BASE_INDENT = 720;
|
|
35
|
+
const INDENT_PER_LEVEL = 360;
|
|
36
|
+
export function inferLevelFromIndentation(indentTwips) {
|
|
37
|
+
if (indentTwips < WORD_BASE_INDENT)
|
|
38
|
+
return 0;
|
|
39
|
+
return Math.floor((indentTwips - WORD_BASE_INDENT) / INDENT_PER_LEVEL);
|
|
40
|
+
}
|
|
41
|
+
export function inferLevelFromRelativeIndentation(relativeIndentTwips) {
|
|
42
|
+
if (relativeIndentTwips <= 0)
|
|
43
|
+
return 0;
|
|
44
|
+
return Math.min(8, Math.floor(relativeIndentTwips / INDENT_PER_LEVEL));
|
|
45
|
+
}
|
|
46
|
+
export function detectTypedPrefix(text) {
|
|
47
|
+
for (const [format, regex] of Object.entries(TYPED_LIST_PATTERNS)) {
|
|
48
|
+
const match = text.match(regex);
|
|
49
|
+
if (match) {
|
|
50
|
+
if (format === 'lowerLetter' || format === 'upperLetter') {
|
|
51
|
+
const remaining = text.substring(match[0].length);
|
|
52
|
+
if (/^[A-Za-z]\./.test(remaining)) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
prefix: match[0],
|
|
58
|
+
format: format,
|
|
59
|
+
category: PATTERN_TO_CATEGORY[format] ?? 'none',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { prefix: null, format: null, category: 'none' };
|
|
64
|
+
}
|
|
65
|
+
export function getParagraphIndentation(paragraph) {
|
|
66
|
+
const formatting = paragraph.getFormatting();
|
|
67
|
+
return formatting?.indentation?.left ?? 0;
|
|
68
|
+
}
|
|
69
|
+
export function detectListType(paragraph) {
|
|
70
|
+
const text = paragraph.getText();
|
|
71
|
+
const indentation = getParagraphIndentation(paragraph);
|
|
72
|
+
const numbering = paragraph.getNumbering();
|
|
73
|
+
if (numbering?.numId !== undefined && numbering.numId !== 0) {
|
|
74
|
+
return {
|
|
75
|
+
category: 'numbered',
|
|
76
|
+
isWordList: true,
|
|
77
|
+
typedPrefix: null,
|
|
78
|
+
inferredLevel: numbering.level ?? 0,
|
|
79
|
+
format: null,
|
|
80
|
+
numId: numbering.numId,
|
|
81
|
+
ilvl: numbering.level ?? 0,
|
|
82
|
+
indentationTwips: indentation,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const typed = detectTypedPrefix(text);
|
|
86
|
+
if (typed.prefix) {
|
|
87
|
+
return {
|
|
88
|
+
category: typed.category,
|
|
89
|
+
isWordList: false,
|
|
90
|
+
typedPrefix: typed.prefix,
|
|
91
|
+
inferredLevel: getLevelFromFormat(typed.format),
|
|
92
|
+
format: typed.format,
|
|
93
|
+
numId: null,
|
|
94
|
+
ilvl: null,
|
|
95
|
+
indentationTwips: indentation,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
category: 'none',
|
|
100
|
+
isWordList: false,
|
|
101
|
+
typedPrefix: null,
|
|
102
|
+
inferredLevel: 0,
|
|
103
|
+
format: null,
|
|
104
|
+
numId: null,
|
|
105
|
+
ilvl: null,
|
|
106
|
+
indentationTwips: indentation,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export function validateListSequence(paragraphs) {
|
|
110
|
+
const warnings = [];
|
|
111
|
+
let lastDecimal = 0;
|
|
112
|
+
let lastLetter = '';
|
|
113
|
+
for (const { detection } of paragraphs) {
|
|
114
|
+
if (!detection.typedPrefix || detection.category !== 'numbered')
|
|
115
|
+
continue;
|
|
116
|
+
const match = /^(\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);
|
|
117
|
+
if (!match?.[1])
|
|
118
|
+
continue;
|
|
119
|
+
const marker = match[1];
|
|
120
|
+
if (/^\d+$/.test(marker)) {
|
|
121
|
+
const num = parseInt(marker, 10);
|
|
122
|
+
if (lastDecimal > 0 && num !== lastDecimal + 1 && num !== 1) {
|
|
123
|
+
warnings.push(`Unexpected number sequence: ${lastDecimal} → ${num}`);
|
|
124
|
+
}
|
|
125
|
+
lastDecimal = num;
|
|
126
|
+
}
|
|
127
|
+
if (/^[a-z]$/i.test(marker)) {
|
|
128
|
+
const letter = marker.toLowerCase();
|
|
129
|
+
if (lastLetter && letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 && letter !== 'a') {
|
|
130
|
+
warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);
|
|
131
|
+
}
|
|
132
|
+
lastLetter = letter;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { valid: warnings.length === 0, warnings };
|
|
136
|
+
}
|
|
137
|
+
export function getListCategoryFromFormat(format) {
|
|
138
|
+
if (!format)
|
|
139
|
+
return 'none';
|
|
140
|
+
if (['bullet', 'dash', 'arrow'].includes(format)) {
|
|
141
|
+
return 'bullet';
|
|
142
|
+
}
|
|
143
|
+
if (['decimal', 'lowerLetter', 'upperLetter', 'lowerRoman', 'upperRoman'].includes(format)) {
|
|
144
|
+
return 'numbered';
|
|
145
|
+
}
|
|
146
|
+
return 'none';
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=list-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-detection.js","sourceRoot":"","sources":["../../../src/utils/list-detection.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IAEzD,OAAO,EAAE,eAAe;IACxB,WAAW,EAAE,iBAAiB;IAC9B,WAAW,EAAE,iBAAiB;IAC9B,UAAU,EAAE,4CAA4C;IAGxD,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;CACpB,CAAC;AAGF,MAAM,CAAC,MAAM,mBAAmB,GAAiC;IAC/D,OAAO,EAAE,UAAU;IACnB,WAAW,EAAE,UAAU;IACvB,WAAW,EAAE,UAAU;IACvB,UAAU,EAAE,UAAU;IACtB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,QAAQ;CAChB,CAAC;AASF,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAMF,MAAM,UAAU,kBAAkB,CAAC,MAAqB;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AASD,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAU7B,MAAM,UAAU,yBAAyB,CAAC,WAAmB;IAC3D,IAAI,WAAW,GAAG,gBAAgB;QAAE,OAAO,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,CAAC;AACzE,CAAC;AAOD,MAAM,UAAU,iCAAiC,CAAC,mBAA2B;IAC3E,IAAI,mBAAmB,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,gBAAgB,CAAC,CAAC,CAAC;AACzE,CAAC;AAWD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAK5C,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,KAAK,EAAE,CAAC;YAGV,IAAI,MAAM,KAAK,aAAa,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;gBACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAGlD,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;oBAClC,SAAS;gBACX,CAAC;YACH,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;gBAChB,MAAM,EAAE,MAAqC;gBAC7C,QAAQ,EAAE,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM;aAChD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC;AAKD,MAAM,UAAU,uBAAuB,CAAC,SAAoB;IAC1D,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC;IAC7C,OAAO,UAAU,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC;AAC5C,CAAC;AAKD,MAAM,UAAU,cAAc,CAAC,SAAoB;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IACjC,MAAM,WAAW,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC;IAG3C,IAAI,SAAS,EAAE,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO;YACL,QAAQ,EAAE,UAAU;YACpB,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;YACnC,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,IAAI,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;YAC1B,gBAAgB,EAAE,WAAW;SAC9B,CAAC;IACJ,CAAC;IAGD,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,KAAK,CAAC,MAAM;YAGzB,aAAa,EAAE,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC;YAC/C,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;YACV,gBAAgB,EAAE,WAAW;SAC9B,CAAC;IACJ,CAAC;IAGD,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,WAAW;KAC9B,CAAC;AACJ,CAAC;AAMD,MAAM,UAAU,oBAAoB,CAClC,UAA8D;IAE9D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,UAAU,GAAG,EAAE,CAAC;IAEpB,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,QAAQ,KAAK,UAAU;YAAE,SAAS;QAE1E,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAAE,SAAS;QAE1B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAGxB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,WAAW,GAAG,CAAC,IAAI,GAAG,KAAK,WAAW,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;gBAC5D,QAAQ,CAAC,IAAI,CAAC,+BAA+B,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,WAAW,GAAG,GAAG,CAAC;QACpB,CAAC;QAGD,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YACpC,IAAI,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC1F,QAAQ,CAAC,IAAI,CAAC,+BAA+B,UAAU,MAAM,MAAM,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;AACpD,CAAC;AAMD,MAAM,UAAU,yBAAyB,CAAC,MAA0B;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3F,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * List Detection Utilities for docxmlater\n *\n * Provides functions to detect typed list prefixes and analyze\n * paragraph list properties.\n */\n\nimport type { Paragraph } from '../elements/Paragraph.js';\nimport type {\n ListCategory,\n ListDetectionResult,\n NumberFormat,\n BulletFormat,\n} from '../types/list-types.js';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Regex patterns for typed list prefixes.\n * Order matters: more specific patterns first.\n */\nexport const TYPED_LIST_PATTERNS: Record<string, RegExp> = {\n // Numbered patterns (capture the marker for validation)\n decimal: /^(\\d+)[.)]\\s+/,\n lowerLetter: /^([a-z])[.)]\\s+/,\n upperLetter: /^([A-Z])[.)]\\s+/,\n lowerRoman: /^((?:i{1,3}|iv|vi{0,3}|ix|x{1,3}))[.)]\\s+/i,\n\n // Bullet patterns\n bullet: /^[•●○◦▪■□]\\s+/,\n dash: /^[-–—]\\s+/,\n arrow: /^[►▸▶→]\\s+/,\n};\n\n/** Map pattern names to categories */\nexport const PATTERN_TO_CATEGORY: Record<string, ListCategory> = {\n decimal: 'numbered',\n lowerLetter: 'numbered',\n upperLetter: 'numbered',\n lowerRoman: 'numbered',\n bullet: 'bullet',\n dash: 'bullet',\n arrow: 'bullet',\n};\n\n/**\n * Map typed prefix format to Word numbering level.\n * Word's default multilevel list uses:\n * Level 0: 1., 2., 3. (decimal)\n * Level 1: a., b., c. (lowerLetter)\n * Level 2: i., ii., iii. (lowerRoman)\n */\nexport const FORMAT_TO_LEVEL: Record<string, number> = {\n decimal: 0, // 1., 2., 3.\n lowerLetter: 1, // a., b., c.\n upperLetter: 1, // A., B., C.\n lowerRoman: 2, // i., ii., iii.\n upperRoman: 2, // I., II., III.\n bullet: 0, // Top-level bullet (filled circle)\n dash: 0, // Top-level dash marker\n arrow: 0, // Top-level arrow marker\n};\n\n/**\n * Get the Word numbering level for a given format.\n * Returns 0 (top level) for decimal or unknown formats.\n */\nexport function getLevelFromFormat(format: string | null): number {\n if (!format) return 0;\n return FORMAT_TO_LEVEL[format] ?? 0;\n}\n\n/**\n * Word standard indentation values in twips.\n * Level 0: 720 twips (0.5 inch) left indent\n * Level 1: 1080 twips (0.75 inch) left indent\n * Level 2: 1440 twips (1 inch) left indent\n * Each subsequent level adds 360 twips.\n */\nconst WORD_BASE_INDENT = 720;\nconst INDENT_PER_LEVEL = 360;\n\n// =============================================================================\n// CORE DETECTION FUNCTIONS\n// =============================================================================\n\n/**\n * Infer list level from indentation.\n * Uses standard Word indentation: 720 twips for level 0, +360 per level.\n */\nexport function inferLevelFromIndentation(indentTwips: number): number {\n if (indentTwips < WORD_BASE_INDENT) return 0;\n return Math.floor((indentTwips - WORD_BASE_INDENT) / INDENT_PER_LEVEL);\n}\n\n/**\n * Infer list level from relative indentation (baseline already subtracted).\n * Used when normalizing lists within a table cell where the baseline\n * indentation varies per cell.\n */\nexport function inferLevelFromRelativeIndentation(relativeIndentTwips: number): number {\n if (relativeIndentTwips <= 0) return 0;\n return Math.min(8, Math.floor(relativeIndentTwips / INDENT_PER_LEVEL));\n}\n\n/**\n * Detect typed list prefix in text.\n * Returns the matched prefix and format type.\n *\n * Special handling for abbreviations:\n * - Single letter prefixes (A., B., P.) are NOT treated as list markers\n * if the remaining text also starts with a letter+period pattern,\n * indicating an abbreviation like \"P.O. Box\", \"U.S. Army\", etc.\n */\nexport function detectTypedPrefix(text: string): {\n prefix: string | null;\n format: NumberFormat | BulletFormat | null;\n category: ListCategory;\n} {\n for (const [format, regex] of Object.entries(TYPED_LIST_PATTERNS)) {\n const match = text.match(regex);\n if (match) {\n // Special check for single-letter patterns (lowerLetter, upperLetter)\n // to avoid false positives on abbreviations like \"P.O. Box\", \"U.S.\", \"A.M.\"\n if (format === 'lowerLetter' || format === 'upperLetter') {\n const remaining = text.substring(match[0].length);\n // If remaining text starts with another letter followed by period,\n // this is likely an abbreviation, not a list marker\n if (/^[A-Za-z]\\./.test(remaining)) {\n continue; // Skip this pattern, try others\n }\n }\n\n return {\n prefix: match[0],\n format: format as NumberFormat | BulletFormat,\n category: PATTERN_TO_CATEGORY[format] ?? 'none',\n };\n }\n }\n\n return { prefix: null, format: null, category: 'none' };\n}\n\n/**\n * Get the left indentation from a paragraph in twips.\n */\nexport function getParagraphIndentation(paragraph: Paragraph): number {\n const formatting = paragraph.getFormatting();\n return formatting?.indentation?.left ?? 0;\n}\n\n/**\n * Main detection function: analyze a single paragraph for list properties.\n */\nexport function detectListType(paragraph: Paragraph): ListDetectionResult {\n const text = paragraph.getText();\n const indentation = getParagraphIndentation(paragraph);\n const numbering = paragraph.getNumbering();\n\n // Priority 1: Real Word list with <w:numPr>\n if (numbering?.numId !== undefined && numbering.numId !== 0) {\n return {\n category: 'numbered', // Default, caller can refine with NumberingManager lookup\n isWordList: true,\n typedPrefix: null,\n inferredLevel: numbering.level ?? 0,\n format: null, // Would need numbering.xml lookup\n numId: numbering.numId,\n ilvl: numbering.level ?? 0,\n indentationTwips: indentation,\n };\n }\n\n // Priority 2: Typed prefix detection\n const typed = detectTypedPrefix(text);\n if (typed.prefix) {\n return {\n category: typed.category,\n isWordList: false,\n typedPrefix: typed.prefix,\n // Use FORMAT to determine level, not indentation!\n // decimal=0, lowerLetter=1, lowerRoman=2\n inferredLevel: getLevelFromFormat(typed.format),\n format: typed.format,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n }\n\n // Priority 3: Not a list\n return {\n category: 'none',\n isWordList: false,\n typedPrefix: null,\n inferredLevel: 0,\n format: null,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n}\n\n/**\n * Validate that a typed prefix sequence is reasonable.\n * E.g., \"1. 2. 3.\" is valid, \"1. 5. 2.\" is suspicious.\n */\nexport function validateListSequence(\n paragraphs: { detection: ListDetectionResult; text: string }[]\n): { valid: boolean; warnings: string[] } {\n const warnings: string[] = [];\n let lastDecimal = 0;\n let lastLetter = '';\n\n for (const { detection } of paragraphs) {\n if (!detection.typedPrefix || detection.category !== 'numbered') continue;\n\n const match = /^(\\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);\n if (!match?.[1]) continue;\n\n const marker = match[1];\n\n // Check decimal sequence\n if (/^\\d+$/.test(marker)) {\n const num = parseInt(marker, 10);\n if (lastDecimal > 0 && num !== lastDecimal + 1 && num !== 1) {\n warnings.push(`Unexpected number sequence: ${lastDecimal} → ${num}`);\n }\n lastDecimal = num;\n }\n\n // Check letter sequence\n if (/^[a-z]$/i.test(marker)) {\n const letter = marker.toLowerCase();\n if (lastLetter && letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 && letter !== 'a') {\n warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);\n }\n lastLetter = letter;\n }\n }\n\n return { valid: warnings.length === 0, warnings };\n}\n\n/**\n * Determine the list category for a given numId by checking the abstractNum.\n * This requires access to the NumberingManager.\n */\nexport function getListCategoryFromFormat(format: string | undefined): ListCategory {\n if (!format) return 'none';\n\n if (['bullet', 'dash', 'arrow'].includes(format)) {\n return 'bullet';\n }\n\n if (['decimal', 'lowerLetter', 'upperLetter', 'lowerRoman', 'upperRoman'].includes(format)) {\n return 'numbered';\n }\n\n return 'none';\n}\n"]}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export var LogLevel;
|
|
2
|
+
(function (LogLevel) {
|
|
3
|
+
LogLevel["DEBUG"] = "debug";
|
|
4
|
+
LogLevel["INFO"] = "info";
|
|
5
|
+
LogLevel["WARN"] = "warn";
|
|
6
|
+
LogLevel["ERROR"] = "error";
|
|
7
|
+
})(LogLevel || (LogLevel = {}));
|
|
8
|
+
export class ConsoleLogger {
|
|
9
|
+
minLevel;
|
|
10
|
+
showTimestamp;
|
|
11
|
+
constructor(minLevel = LogLevel.WARN, options) {
|
|
12
|
+
this.minLevel = minLevel;
|
|
13
|
+
this.showTimestamp = options?.showTimestamp ?? true;
|
|
14
|
+
}
|
|
15
|
+
debug(message, context) {
|
|
16
|
+
if (this.shouldLog(LogLevel.DEBUG)) {
|
|
17
|
+
console.debug(this.formatMessage(LogLevel.DEBUG, message, context));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
info(message, context) {
|
|
21
|
+
if (this.shouldLog(LogLevel.INFO)) {
|
|
22
|
+
console.info(this.formatMessage(LogLevel.INFO, message, context));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
warn(message, context) {
|
|
26
|
+
if (this.shouldLog(LogLevel.WARN)) {
|
|
27
|
+
console.warn(this.formatMessage(LogLevel.WARN, message, context));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
error(message, context) {
|
|
31
|
+
if (this.shouldLog(LogLevel.ERROR)) {
|
|
32
|
+
console.error(this.formatMessage(LogLevel.ERROR, message, context));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
shouldLog(level) {
|
|
36
|
+
const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];
|
|
37
|
+
const minIndex = levels.indexOf(this.minLevel);
|
|
38
|
+
const currentIndex = levels.indexOf(level);
|
|
39
|
+
return currentIndex >= minIndex;
|
|
40
|
+
}
|
|
41
|
+
formatMessage(level, message, context) {
|
|
42
|
+
const parts = [];
|
|
43
|
+
if (this.showTimestamp) {
|
|
44
|
+
const timestamp = new Date().toISOString().slice(11, 23);
|
|
45
|
+
parts.push(timestamp);
|
|
46
|
+
}
|
|
47
|
+
parts.push(`[${level.toUpperCase().padEnd(5)}]`);
|
|
48
|
+
if (context?.source) {
|
|
49
|
+
parts.push(`[${context.source}]`);
|
|
50
|
+
}
|
|
51
|
+
parts.push(message);
|
|
52
|
+
if (context && Object.keys(context).length > 0) {
|
|
53
|
+
const contextWithoutSource = { ...context };
|
|
54
|
+
delete contextWithoutSource.source;
|
|
55
|
+
if (Object.keys(contextWithoutSource).length > 0) {
|
|
56
|
+
const contextStr = this.formatContext(contextWithoutSource);
|
|
57
|
+
if (contextStr) {
|
|
58
|
+
parts.push(contextStr);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return parts.join(' ');
|
|
63
|
+
}
|
|
64
|
+
formatContext(context) {
|
|
65
|
+
const pairs = [];
|
|
66
|
+
for (const [key, value] of Object.entries(context)) {
|
|
67
|
+
if (value === undefined || value === null)
|
|
68
|
+
continue;
|
|
69
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
70
|
+
pairs.push(`${key}=${JSON.stringify(value)}`);
|
|
71
|
+
}
|
|
72
|
+
else if (Array.isArray(value)) {
|
|
73
|
+
pairs.push(`${key}=[${value.length}]`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
pairs.push(`${key}=${value}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return pairs.length > 0 ? pairs.join(' ') : '';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export class SilentLogger {
|
|
83
|
+
debug() {
|
|
84
|
+
}
|
|
85
|
+
info() {
|
|
86
|
+
}
|
|
87
|
+
warn() {
|
|
88
|
+
}
|
|
89
|
+
error() {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export class CollectingLogger {
|
|
93
|
+
logs = [];
|
|
94
|
+
debug(message, context) {
|
|
95
|
+
this.addLog(LogLevel.DEBUG, message, context);
|
|
96
|
+
}
|
|
97
|
+
info(message, context) {
|
|
98
|
+
this.addLog(LogLevel.INFO, message, context);
|
|
99
|
+
}
|
|
100
|
+
warn(message, context) {
|
|
101
|
+
this.addLog(LogLevel.WARN, message, context);
|
|
102
|
+
}
|
|
103
|
+
error(message, context) {
|
|
104
|
+
this.addLog(LogLevel.ERROR, message, context);
|
|
105
|
+
}
|
|
106
|
+
addLog(level, message, context) {
|
|
107
|
+
this.logs.push({
|
|
108
|
+
timestamp: new Date(),
|
|
109
|
+
level,
|
|
110
|
+
message,
|
|
111
|
+
context,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
getLogs() {
|
|
115
|
+
return [...this.logs];
|
|
116
|
+
}
|
|
117
|
+
getLogsByLevel(level) {
|
|
118
|
+
return this.logs.filter((log) => log.level === level);
|
|
119
|
+
}
|
|
120
|
+
clear() {
|
|
121
|
+
this.logs = [];
|
|
122
|
+
}
|
|
123
|
+
getCount(level) {
|
|
124
|
+
if (level) {
|
|
125
|
+
return this.logs.filter((log) => log.level === level).length;
|
|
126
|
+
}
|
|
127
|
+
return this.logs.length;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export const defaultLogger = {
|
|
131
|
+
debug(message, context) {
|
|
132
|
+
getGlobalLogger().debug(message, context);
|
|
133
|
+
},
|
|
134
|
+
info(message, context) {
|
|
135
|
+
getGlobalLogger().info(message, context);
|
|
136
|
+
},
|
|
137
|
+
warn(message, context) {
|
|
138
|
+
getGlobalLogger().warn(message, context);
|
|
139
|
+
},
|
|
140
|
+
error(message, context) {
|
|
141
|
+
getGlobalLogger().error(message, context);
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
export function createScopedLogger(logger, source) {
|
|
145
|
+
return {
|
|
146
|
+
debug(message, context) {
|
|
147
|
+
logger.debug(message, { ...context, source });
|
|
148
|
+
},
|
|
149
|
+
info(message, context) {
|
|
150
|
+
logger.info(message, { ...context, source });
|
|
151
|
+
},
|
|
152
|
+
warn(message, context) {
|
|
153
|
+
logger.warn(message, { ...context, source });
|
|
154
|
+
},
|
|
155
|
+
error(message, context) {
|
|
156
|
+
logger.error(message, { ...context, source });
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function parseLogLevel(level) {
|
|
161
|
+
if (!level)
|
|
162
|
+
return undefined;
|
|
163
|
+
const normalized = level.toLowerCase();
|
|
164
|
+
switch (normalized) {
|
|
165
|
+
case 'debug':
|
|
166
|
+
return LogLevel.DEBUG;
|
|
167
|
+
case 'info':
|
|
168
|
+
return LogLevel.INFO;
|
|
169
|
+
case 'warn':
|
|
170
|
+
return LogLevel.WARN;
|
|
171
|
+
case 'error':
|
|
172
|
+
return LogLevel.ERROR;
|
|
173
|
+
default:
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function createLoggerFromEnv() {
|
|
178
|
+
const debugEnv = process.env.DEBUG || '';
|
|
179
|
+
if (debugEnv.includes('docxmlater')) {
|
|
180
|
+
return new ConsoleLogger(LogLevel.DEBUG);
|
|
181
|
+
}
|
|
182
|
+
const envLevel = process.env.DOCXMLATER_LOG_LEVEL?.toLowerCase();
|
|
183
|
+
if (envLevel === 'silent') {
|
|
184
|
+
return new SilentLogger();
|
|
185
|
+
}
|
|
186
|
+
const parsedLevel = parseLogLevel(envLevel);
|
|
187
|
+
if (parsedLevel) {
|
|
188
|
+
return new ConsoleLogger(parsedLevel);
|
|
189
|
+
}
|
|
190
|
+
return new SilentLogger();
|
|
191
|
+
}
|
|
192
|
+
let globalLogger = createLoggerFromEnv();
|
|
193
|
+
export function setGlobalLogger(logger) {
|
|
194
|
+
globalLogger = logger;
|
|
195
|
+
}
|
|
196
|
+
export function getGlobalLogger() {
|
|
197
|
+
return globalLogger;
|
|
198
|
+
}
|
|
199
|
+
export function resetGlobalLogger() {
|
|
200
|
+
globalLogger = createLoggerFromEnv();
|
|
201
|
+
}
|
|
202
|
+
export function createComponentLogger(componentName) {
|
|
203
|
+
return createScopedLogger(getGlobalLogger(), componentName);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Logging interface for docXMLater\n * Allows library consumers to control logging behavior\n */\n\n/**\n * Log severity levels\n */\nexport enum LogLevel {\n /** Debugging information (most verbose) */\n DEBUG = 'debug',\n /** Informational messages */\n INFO = 'info',\n /** Warning messages - potential issues that don't prevent operation */\n WARN = 'warn',\n /** Error messages - serious issues that may cause failures */\n ERROR = 'error',\n}\n\n/**\n * Log entry structure\n */\nexport interface LogEntry {\n /** Timestamp when log was created */\n timestamp: Date;\n /** Severity level */\n level: LogLevel;\n /** Log message */\n message: string;\n /** Optional context data */\n context?: Record<string, any>;\n /** Source component that generated the log */\n source?: string;\n}\n\n/**\n * Logger interface that consumers can implement\n * Provides full control over how logs are handled\n */\nexport interface ILogger {\n /**\n * Log a debug message\n * @param message - Debug message\n * @param context - Optional context data\n */\n debug(message: string, context?: Record<string, any>): void;\n\n /**\n * Log an informational message\n * @param message - Info message\n * @param context - Optional context data\n */\n info(message: string, context?: Record<string, any>): void;\n\n /**\n * Log a warning message\n * @param message - Warning message\n * @param context - Optional context data\n */\n warn(message: string, context?: Record<string, any>): void;\n\n /**\n * Log an error message\n * @param message - Error message\n * @param context - Optional context data\n */\n error(message: string, context?: Record<string, any>): void;\n}\n\n/**\n * Console-based logger implementation\n * Uses standard console methods for output with timestamps and source prefixes\n */\nexport class ConsoleLogger implements ILogger {\n private showTimestamp: boolean;\n\n constructor(\n private minLevel: LogLevel = LogLevel.WARN,\n options?: { showTimestamp?: boolean }\n ) {\n this.showTimestamp = options?.showTimestamp ?? true;\n }\n\n debug(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.formatMessage(LogLevel.DEBUG, message, context));\n }\n }\n\n info(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.formatMessage(LogLevel.INFO, message, context));\n }\n }\n\n warn(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.WARN)) {\n console.warn(this.formatMessage(LogLevel.WARN, message, context));\n }\n }\n\n error(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.ERROR)) {\n console.error(this.formatMessage(LogLevel.ERROR, message, context));\n }\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];\n const minIndex = levels.indexOf(this.minLevel);\n const currentIndex = levels.indexOf(level);\n return currentIndex >= minIndex;\n }\n\n private formatMessage(level: LogLevel, message: string, context?: Record<string, any>): string {\n const parts: string[] = [];\n\n // Add timestamp if enabled\n if (this.showTimestamp) {\n const timestamp = new Date().toISOString().slice(11, 23); // HH:mm:ss.SSS\n parts.push(timestamp);\n }\n\n // Add level tag\n parts.push(`[${level.toUpperCase().padEnd(5)}]`);\n\n // Add source if present\n if (context?.source) {\n parts.push(`[${context.source}]`);\n }\n\n // Add message\n parts.push(message);\n\n // Add context (excluding source which is already shown)\n if (context && Object.keys(context).length > 0) {\n const contextWithoutSource = { ...context };\n delete contextWithoutSource.source;\n if (Object.keys(contextWithoutSource).length > 0) {\n // Format context as key=value pairs for readability\n const contextStr = this.formatContext(contextWithoutSource);\n if (contextStr) {\n parts.push(contextStr);\n }\n }\n }\n\n return parts.join(' ');\n }\n\n private formatContext(context: Record<string, any>): string {\n const pairs: string[] = [];\n for (const [key, value] of Object.entries(context)) {\n if (value === undefined || value === null) continue;\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Nested object - use compact JSON\n pairs.push(`${key}=${JSON.stringify(value)}`);\n } else if (Array.isArray(value)) {\n pairs.push(`${key}=[${value.length}]`);\n } else {\n pairs.push(`${key}=${value}`);\n }\n }\n return pairs.length > 0 ? pairs.join(' ') : '';\n }\n}\n\n/**\n * Silent logger that discards all log messages\n * Useful for testing or when logging is not desired\n */\nexport class SilentLogger implements ILogger {\n debug(): void {\n // No-op\n }\n\n info(): void {\n // No-op\n }\n\n warn(): void {\n // No-op\n }\n\n error(): void {\n // No-op\n }\n}\n\n/**\n * Collecting logger that stores log entries in memory\n * Useful for testing and diagnostics\n */\nexport class CollectingLogger implements ILogger {\n private logs: LogEntry[] = [];\n\n debug(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.DEBUG, message, context);\n }\n\n info(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.INFO, message, context);\n }\n\n warn(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.WARN, message, context);\n }\n\n error(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.ERROR, message, context);\n }\n\n private addLog(level: LogLevel, message: string, context?: Record<string, any>): void {\n this.logs.push({\n timestamp: new Date(),\n level,\n message,\n context,\n });\n }\n\n /**\n * Get all collected log entries\n */\n getLogs(): readonly LogEntry[] {\n return [...this.logs];\n }\n\n /**\n * Get logs filtered by level\n */\n getLogsByLevel(level: LogLevel): readonly LogEntry[] {\n return this.logs.filter((log) => log.level === level);\n }\n\n /**\n * Clear all collected logs\n */\n clear(): void {\n this.logs = [];\n }\n\n /**\n * Get count of logs by level\n */\n getCount(level?: LogLevel): number {\n if (level) {\n return this.logs.filter((log) => log.level === level).length;\n }\n return this.logs.length;\n }\n}\n\n/**\n * Default logger instance\n * Delegates to the global logger, respecting setGlobalLogger() and environment variables\n */\nexport const defaultLogger: ILogger = {\n debug(message: string, context?: Record<string, any>): void {\n getGlobalLogger().debug(message, context);\n },\n info(message: string, context?: Record<string, any>): void {\n getGlobalLogger().info(message, context);\n },\n warn(message: string, context?: Record<string, any>): void {\n getGlobalLogger().warn(message, context);\n },\n error(message: string, context?: Record<string, any>): void {\n getGlobalLogger().error(message, context);\n },\n};\n\n/**\n * Creates a scoped logger that adds source information\n * @param logger - Base logger\n * @param source - Source component name\n * @returns Scoped logger with source context\n */\nexport function createScopedLogger(logger: ILogger, source: string): ILogger {\n return {\n debug(message: string, context?: Record<string, any>): void {\n logger.debug(message, { ...context, source });\n },\n info(message: string, context?: Record<string, any>): void {\n logger.info(message, { ...context, source });\n },\n warn(message: string, context?: Record<string, any>): void {\n logger.warn(message, { ...context, source });\n },\n error(message: string, context?: Record<string, any>): void {\n logger.error(message, { ...context, source });\n },\n };\n}\n\n/**\n * Parse log level from string\n * @param level - Log level string (case-insensitive)\n * @returns LogLevel or undefined if invalid\n */\nfunction parseLogLevel(level: string | undefined): LogLevel | undefined {\n if (!level) return undefined;\n const normalized = level.toLowerCase();\n switch (normalized) {\n case 'debug':\n return LogLevel.DEBUG;\n case 'info':\n return LogLevel.INFO;\n case 'warn':\n return LogLevel.WARN;\n case 'error':\n return LogLevel.ERROR;\n default:\n return undefined;\n }\n}\n\n/**\n * Create a logger based on environment variables\n *\n * Environment variables (in order of precedence):\n * - DEBUG=docxmlater or DEBUG=docxmlater:* - Enables DEBUG level\n * - DOCXMLATER_LOG_LEVEL=debug|info|warn|error|silent - Sets specific level\n *\n * @returns Logger configured from environment, or SilentLogger if not configured\n */\nfunction createLoggerFromEnv(): ILogger {\n // Check DEBUG environment variable first (highest precedence for debug mode)\n const debugEnv = process.env.DEBUG || '';\n if (debugEnv.includes('docxmlater')) {\n return new ConsoleLogger(LogLevel.DEBUG);\n }\n\n // Check DOCXMLATER_LOG_LEVEL environment variable\n const envLevel = process.env.DOCXMLATER_LOG_LEVEL?.toLowerCase();\n if (envLevel === 'silent') {\n return new SilentLogger();\n }\n\n const parsedLevel = parseLogLevel(envLevel);\n if (parsedLevel) {\n return new ConsoleLogger(parsedLevel);\n }\n\n // Default: silent (no logging unless explicitly enabled)\n return new SilentLogger();\n}\n\n// Global logger instance - initialized from environment\nlet globalLogger: ILogger = createLoggerFromEnv();\n\n/**\n * Set the global logger instance\n * Use this to configure logging programmatically\n *\n * @example\n * ```typescript\n * import { setGlobalLogger, ConsoleLogger, LogLevel } from 'docxmlater';\n *\n * // Enable info-level logging\n * setGlobalLogger(new ConsoleLogger(LogLevel.INFO));\n * ```\n *\n * @param logger - Logger instance to use globally\n */\nexport function setGlobalLogger(logger: ILogger): void {\n globalLogger = logger;\n}\n\n/**\n * Get the global logger instance\n * Used internally by framework components\n *\n * @returns Current global logger\n */\nexport function getGlobalLogger(): ILogger {\n return globalLogger;\n}\n\n/**\n * Reset the global logger to its default (environment-based) configuration\n * Useful for testing cleanup\n */\nexport function resetGlobalLogger(): void {\n globalLogger = createLoggerFromEnv();\n}\n\n/**\n * Creates a component-scoped logger using the global logger.\n * This is a convenience function that combines getGlobalLogger() and createScopedLogger()\n * into a single call, reducing boilerplate in component files.\n *\n * @param componentName - Name of the component (appears in log output)\n * @returns Scoped logger instance\n *\n * @example\n * ```typescript\n * // Instead of:\n * function getLogger(): ILogger {\n * return createScopedLogger(getGlobalLogger(), 'MyComponent');\n * }\n *\n * // You can use:\n * const logger = createComponentLogger('MyComponent');\n *\n * // Or for lazy initialization:\n * const getLogger = () => createComponentLogger('MyComponent');\n * ```\n */\nexport function createComponentLogger(componentName: string): ILogger {\n return createScopedLogger(getGlobalLogger(), componentName);\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function safeParseInt(value, defaultValue = 0) {
|
|
2
|
+
if (value === undefined || value === null) {
|
|
3
|
+
return defaultValue;
|
|
4
|
+
}
|
|
5
|
+
if (typeof value === 'number') {
|
|
6
|
+
return isNaN(value) ? defaultValue : Math.floor(value);
|
|
7
|
+
}
|
|
8
|
+
const parsed = parseInt(String(value), 10);
|
|
9
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
10
|
+
}
|
|
11
|
+
export function parseOoxmlBoolean(prop, valAttr = '@_w:val') {
|
|
12
|
+
if (!prop) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const val = prop[valAttr];
|
|
16
|
+
if (val === undefined) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (typeof val === 'string') {
|
|
20
|
+
const lowerVal = val.toLowerCase();
|
|
21
|
+
return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';
|
|
22
|
+
}
|
|
23
|
+
if (typeof val === 'number') {
|
|
24
|
+
return val === 1;
|
|
25
|
+
}
|
|
26
|
+
if (typeof val === 'boolean') {
|
|
27
|
+
return val;
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
export function isExplicitlySet(value) {
|
|
32
|
+
return value !== undefined && value !== null;
|
|
33
|
+
}
|
|
34
|
+
export function parseNumericAttribute(value, defaultValue) {
|
|
35
|
+
if (!isExplicitlySet(value)) {
|
|
36
|
+
return defaultValue;
|
|
37
|
+
}
|
|
38
|
+
return safeParseInt(value, defaultValue);
|
|
39
|
+
}
|
|
40
|
+
export function parseOnOffAttribute(value, defaultValue = false) {
|
|
41
|
+
if (!isExplicitlySet(value)) {
|
|
42
|
+
return defaultValue;
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === 'string') {
|
|
45
|
+
const lowerVal = value.toLowerCase();
|
|
46
|
+
return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';
|
|
47
|
+
}
|
|
48
|
+
if (typeof value === 'number') {
|
|
49
|
+
return value === 1;
|
|
50
|
+
}
|
|
51
|
+
if (typeof value === 'boolean') {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
return defaultValue;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=parsingHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsingHelpers.js","sourceRoot":"","sources":["../../../src/utils/parsingHelpers.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,YAAY,GAAG,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,YAAY,CAAC;IACtB,CAAC;IAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AAsCD,MAAM,UAAU,iBAAiB,CAAC,IAAa,EAAE,OAAO,GAAG,SAAS;IAElE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAID,MAAM,GAAG,GAAI,IAAgC,CAAC,OAAO,CAAC,CAAC;IAIvD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,KAAK,CAAC,CAAC;IACnB,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAGD,OAAO,KAAK,CAAC;AACf,CAAC;AA0BD,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AAC/C,CAAC;AAkBD,MAAM,UAAU,qBAAqB,CAAC,KAAc,EAAE,YAAoB;IACxE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAeD,MAAM,UAAU,mBAAmB,CAAC,KAAc,EAAE,YAAY,GAAG,KAAK;IACtE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\n * Parsing Helper Functions\n *\n * Utility functions for safely parsing OOXML values from XML attributes.\n * These helpers address common parsing issues:\n * - Zero-value handling (0 should not be treated as falsy)\n * - NaN validation (malformed values should fall back to defaults)\n * - ECMA-376 boolean parsing (self-closing tags, val=\"1\", val=\"true\")\n *\n * @see https://ecma-international.org/publications-and-standards/standards/ecma-376/\n */\n\n/**\n * Safely parse an integer value with NaN handling.\n *\n * Addresses the issue where parseInt() can return NaN for malformed input,\n * which then propagates through the document model causing issues.\n *\n * @param value - The value to parse (string, number, or any)\n * @param defaultValue - Default value if parsing fails (default: 0)\n * @returns Parsed integer or default value\n *\n * @example\n * safeParseInt(\"42\") // 42\n * safeParseInt(\"invalid\") // 0\n * safeParseInt(undefined) // 0\n * safeParseInt(\"\", 100) // 100\n */\nexport function safeParseInt(value: unknown, defaultValue = 0): number {\n if (value === undefined || value === null) {\n return defaultValue;\n }\n\n // If already a number, return it (handle NaN case)\n if (typeof value === 'number') {\n return isNaN(value) ? defaultValue : Math.floor(value);\n }\n\n const parsed = parseInt(String(value), 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Parse OOXML boolean value per ECMA-376 specification.\n *\n * OOXML boolean properties follow these rules:\n * - Self-closing tag `<w:bold/>` (no w:val attribute) = true\n * - `<w:bold w:val=\"1\"/>` = true\n * - `<w:bold w:val=\"true\"/>` = true\n * - `<w:bold w:val=\"on\"/>` = true\n * - `<w:bold w:val=\"0\"/>` = false\n * - `<w:bold w:val=\"false\"/>` = false\n * - `<w:bold w:val=\"off\"/>` = false\n * - Absent element = false (handled by caller checking for property existence)\n *\n * @param prop - The parsed XML property object (e.g., pPrObj[\"w:bold\"])\n * @param valAttr - The attribute key that carries the ST_OnOff literal.\n * Defaults to `\"@_w:val\"` for the main WordprocessingML namespace.\n * Pass `\"@_w14:val\"` for w14 extension elements such as\n * `<w14:checked w14:val=\"1\"/>` (CT_OnOff in the Word 2010+ namespace).\n * @returns Boolean value\n *\n * @example\n * // For XML: <w:bold/>\n * parseOoxmlBoolean({}) // true (self-closing, no @_w:val)\n *\n * // For XML: <w:bold w:val=\"1\"/>\n * parseOoxmlBoolean({ \"@_w:val\": \"1\" }) // true\n *\n * // For XML: <w:bold w:val=\"0\"/>\n * parseOoxmlBoolean({ \"@_w:val\": \"0\" }) // false\n *\n * // For XML: <w14:checked w14:val=\"on\"/>\n * parseOoxmlBoolean({ \"@_w14:val\": \"on\" }, \"@_w14:val\") // true\n *\n * // For absent element\n * parseOoxmlBoolean(undefined) // false\n */\nexport function parseOoxmlBoolean(prop: unknown, valAttr = '@_w:val'): boolean {\n // Absent element = false\n if (!prop) {\n return false;\n }\n\n // Get the val attribute value (w:val by default, w14:val or similar for\n // extension namespaces).\n const val = (prop as Record<string, unknown>)[valAttr];\n\n // Self-closing tag without w:val attribute = true\n // Per ECMA-376, presence of element without val means \"on\"\n if (val === undefined) {\n return true;\n }\n\n // Handle string values\n if (typeof val === 'string') {\n const lowerVal = val.toLowerCase();\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\n }\n\n // Handle numeric values\n if (typeof val === 'number') {\n return val === 1;\n }\n\n // Handle boolean values (already parsed by XML parser)\n if (typeof val === 'boolean') {\n return val;\n }\n\n // Unknown type - default to false\n return false;\n}\n\n/**\n * Check if a value is explicitly set (not undefined or null).\n *\n * This helper addresses the zero-value handling bug where truthy checks\n * incorrectly treat 0 as falsy:\n *\n * ```typescript\n * // WRONG - treats 0 as falsy\n * const width = val ? parseInt(val) : defaultWidth;\n *\n * // CORRECT - only checks for undefined/null\n * const width = isExplicitlySet(val) ? parseInt(val) : defaultWidth;\n * ```\n *\n * @param value - The value to check\n * @returns true if value is not undefined and not null\n *\n * @example\n * isExplicitlySet(0) // true\n * isExplicitlySet(\"\") // true\n * isExplicitlySet(false) // true\n * isExplicitlySet(undefined) // false\n * isExplicitlySet(null) // false\n */\nexport function isExplicitlySet(value: unknown): boolean {\n return value !== undefined && value !== null;\n}\n\n/**\n * Parse an OOXML numeric attribute with proper handling of zero values.\n *\n * Combines isExplicitlySet() and safeParseInt() for common use case\n * of parsing numeric attributes from XML.\n *\n * @param value - The attribute value to parse\n * @param defaultValue - Default value if attribute is not set\n * @returns Parsed integer or default value\n *\n * @example\n * parseNumericAttribute(\"100\", 50) // 100\n * parseNumericAttribute(\"0\", 50) // 0 (not 50!)\n * parseNumericAttribute(undefined, 50) // 50\n * parseNumericAttribute(\"invalid\", 50) // 50\n */\nexport function parseNumericAttribute(value: unknown, defaultValue: number): number {\n if (!isExplicitlySet(value)) {\n return defaultValue;\n }\n return safeParseInt(value, defaultValue);\n}\n\n/**\n * Parse OOXML \"on/off\" attribute (ST_OnOff type).\n *\n * Some OOXML attributes use the ST_OnOff simple type which can be:\n * - \"on\", \"1\", \"true\" = true\n * - \"off\", \"0\", \"false\" = false\n *\n * This is similar to parseOoxmlBoolean but works on attribute values directly.\n *\n * @param value - The attribute value\n * @param defaultValue - Default if value is not set\n * @returns Boolean value\n */\nexport function parseOnOffAttribute(value: unknown, defaultValue = false): boolean {\n if (!isExplicitlySet(value)) {\n return defaultValue;\n }\n\n if (typeof value === 'string') {\n const lowerVal = value.toLowerCase();\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\n }\n\n if (typeof value === 'number') {\n return value === 1;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n return defaultValue;\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function diffText(oldText, newText) {
|
|
2
|
+
if (oldText === newText) {
|
|
3
|
+
return oldText.length > 0 ? [{ type: 'equal', text: oldText }] : [];
|
|
4
|
+
}
|
|
5
|
+
if (oldText.length === 0) {
|
|
6
|
+
return newText.length > 0 ? [{ type: 'insert', text: newText }] : [];
|
|
7
|
+
}
|
|
8
|
+
if (newText.length === 0) {
|
|
9
|
+
return [{ type: 'delete', text: oldText }];
|
|
10
|
+
}
|
|
11
|
+
let prefixLen = 0;
|
|
12
|
+
const minLen = Math.min(oldText.length, newText.length);
|
|
13
|
+
while (prefixLen < minLen && oldText[prefixLen] === newText[prefixLen]) {
|
|
14
|
+
prefixLen++;
|
|
15
|
+
}
|
|
16
|
+
let suffixLen = 0;
|
|
17
|
+
const maxSuffix = minLen - prefixLen;
|
|
18
|
+
while (suffixLen < maxSuffix &&
|
|
19
|
+
oldText[oldText.length - 1 - suffixLen] === newText[newText.length - 1 - suffixLen]) {
|
|
20
|
+
suffixLen++;
|
|
21
|
+
}
|
|
22
|
+
const segments = [];
|
|
23
|
+
if (prefixLen > 0) {
|
|
24
|
+
segments.push({ type: 'equal', text: oldText.slice(0, prefixLen) });
|
|
25
|
+
}
|
|
26
|
+
const oldMiddle = oldText.slice(prefixLen, oldText.length - suffixLen);
|
|
27
|
+
const newMiddle = newText.slice(prefixLen, newText.length - suffixLen);
|
|
28
|
+
if (oldMiddle.length > 0) {
|
|
29
|
+
segments.push({ type: 'delete', text: oldMiddle });
|
|
30
|
+
}
|
|
31
|
+
if (newMiddle.length > 0) {
|
|
32
|
+
segments.push({ type: 'insert', text: newMiddle });
|
|
33
|
+
}
|
|
34
|
+
if (suffixLen > 0) {
|
|
35
|
+
segments.push({ type: 'equal', text: oldText.slice(oldText.length - suffixLen) });
|
|
36
|
+
}
|
|
37
|
+
return segments;
|
|
38
|
+
}
|
|
39
|
+
export function diffHasUnchangedParts(segments) {
|
|
40
|
+
return segments.some((s) => s.type === 'equal');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=textDiff.js.map
|