@stll/folio-core 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +39 -0
  2. package/dist/ai-edits/apply.js +18 -4
  3. package/dist/ai-edits/headless.d.ts +31 -4
  4. package/dist/ai-edits/headless.js +148 -35
  5. package/dist/ai-edits/index.d.ts +3 -3
  6. package/dist/ai-edits/index.js +2 -1
  7. package/dist/ai-edits/snapshot.js +40 -3
  8. package/dist/ai-edits/types.d.ts +2 -1
  9. package/dist/compat/eigenpal.d.ts +6 -4
  10. package/dist/compat/eigenpal.js +5 -3
  11. package/dist/controller/latestRequestGate.d.ts +13 -0
  12. package/dist/controller/latestRequestGate.js +16 -0
  13. package/dist/controller/layoutPipeline.js +12 -1
  14. package/dist/document-operations.d.ts +10 -3
  15. package/dist/document-operations.js +29 -14
  16. package/dist/docx/blockContentParser.js +2 -2
  17. package/dist/docx/commentParser.js +1 -1
  18. package/dist/docx/compatibility.d.ts +3 -7
  19. package/dist/docx/compatibility.js +0 -11
  20. package/dist/docx/encryption/agileDecryption.js +1 -1
  21. package/dist/docx/encryption/encryptionInfo.js +1 -1
  22. package/dist/docx/encryption/openEncryptedDocx.js +1 -1
  23. package/dist/docx/fontTableParser.d.ts +6 -0
  24. package/dist/docx/fontTableParser.js +72 -0
  25. package/dist/docx/groupDrawingParser.js +7 -2
  26. package/dist/docx/headerFooterParser.js +1 -1
  27. package/dist/docx/normalizeBaseDirection.js +1 -1
  28. package/dist/docx/numberingParser.js +1 -0
  29. package/dist/docx/paragraphParser.js +12 -1
  30. package/dist/docx/parser.d.ts +1 -1
  31. package/dist/docx/parser.js +12 -9
  32. package/dist/docx/rezip.js +70 -5
  33. package/dist/docx/runConsolidator.js +4 -0
  34. package/dist/docx/runParser.js +19 -1
  35. package/dist/docx/selectiveSave.js +3 -3
  36. package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
  37. package/dist/docx/serializer/fontTableSerializer.js +26 -0
  38. package/dist/docx/serializer/headerFooterSerializer.js +1 -1
  39. package/dist/docx/serializer/paragraphSerializer.js +4 -0
  40. package/dist/docx/serializer/runSerializer.js +7 -0
  41. package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
  42. package/dist/docx/serializer/settingsSerializer.js +16 -0
  43. package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
  44. package/dist/docx/serializer/stylesSerializer.js +56 -0
  45. package/dist/docx/serializer/tableSerializer.js +25 -26
  46. package/dist/docx/serializer/themeSerializer.d.ts +6 -0
  47. package/dist/docx/serializer/themeSerializer.js +36 -0
  48. package/dist/docx/settingsParser.js +46 -0
  49. package/dist/docx/styleParser.js +26 -1
  50. package/dist/docx/tableParser.js +11 -1
  51. package/dist/docx/vmlImageParser.js +1 -0
  52. package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
  53. package/dist/i18n/messages/catalogs.gen.js +5910 -5910
  54. package/dist/index.d.ts +6 -4
  55. package/dist/index.js +5 -3
  56. package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
  57. package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
  58. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
  59. package/dist/layout-bridge/convert/headerFooterLayout.js +6 -1
  60. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
  61. package/dist/layout-bridge/convert/toFlowBlocks.js +51 -14
  62. package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
  63. package/dist/layout-bridge/engine/measuring/index.js +2 -1
  64. package/dist/layout-engine/index.js +36 -28
  65. package/dist/layout-engine/measure/cache.js +11 -3
  66. package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
  67. package/dist/layout-engine/measure/index.d.ts +2 -1
  68. package/dist/layout-engine/measure/index.js +2 -1
  69. package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
  70. package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
  71. package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
  72. package/dist/layout-engine/measure/lineBreaks.js +11 -18
  73. package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
  74. package/dist/layout-engine/measure/listMarkerWidth.js +12 -6
  75. package/dist/layout-engine/measure/measureBlocks.d.ts +1 -2
  76. package/dist/layout-engine/measure/measureBlocks.js +6 -36
  77. package/dist/layout-engine/measure/measureContainer.js +32 -9
  78. package/dist/layout-engine/measure/measureHelpers.js +5 -2
  79. package/dist/layout-engine/measure/measureParagraph.js +335 -72
  80. package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
  81. package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
  82. package/dist/layout-engine/measure/measureWorker.js +8 -19
  83. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
  84. package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
  85. package/dist/layout-engine/measure/tableCellFloating.js +37 -29
  86. package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
  87. package/dist/layout-engine/measure/tableCellFlow.js +73 -0
  88. package/dist/layout-engine/measure/tableCellGrid.js +1 -1
  89. package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
  90. package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
  91. package/dist/layout-engine/renderedBreakReconciliation.d.ts +6 -1
  92. package/dist/layout-engine/renderedBreakReconciliation.js +34 -11
  93. package/dist/layout-engine/tableRowBreak.d.ts +5 -2
  94. package/dist/layout-engine/tableRowBreak.js +62 -29
  95. package/dist/layout-engine/types.d.ts +40 -7
  96. package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
  97. package/dist/layout-painter/anchoredImagePosition.js +95 -0
  98. package/dist/layout-painter/borderStroke.d.ts +23 -0
  99. package/dist/layout-painter/borderStroke.js +39 -0
  100. package/dist/layout-painter/renderImage.d.ts +5 -4
  101. package/dist/layout-painter/renderImage.js +18 -4
  102. package/dist/layout-painter/renderPage.d.ts +2 -27
  103. package/dist/layout-painter/renderPage.js +13 -99
  104. package/dist/layout-painter/renderParagraph.js +41 -23
  105. package/dist/layout-painter/renderTable.d.ts +2 -0
  106. package/dist/layout-painter/renderTable.js +223 -43
  107. package/dist/managers/DocumentLoaderManager.d.ts +1 -1
  108. package/dist/managers/DocumentLoaderManager.js +2 -2
  109. package/dist/prosemirror/attrs/index.d.ts +4 -2
  110. package/dist/prosemirror/attrs/index.js +21 -2
  111. package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
  112. package/dist/prosemirror/conversion/fromProseDoc.js +33 -18
  113. package/dist/prosemirror/conversion/toProseDoc.js +50 -18
  114. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  115. package/dist/prosemirror/extensions/core/ParagraphExtension.js +7 -2
  116. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
  117. package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
  118. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
  119. package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
  120. package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
  121. package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
  122. package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
  123. package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
  124. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
  125. package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
  126. package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
  127. package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
  128. package/dist/prosemirror/schema/index.d.ts +2 -2
  129. package/dist/prosemirror/schema/marks.d.ts +6 -1
  130. package/dist/prosemirror/schema/nodes.d.ts +13 -11
  131. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  132. package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
  133. package/dist/prosemirror/utils/tabCalculator.js +12 -10
  134. package/dist/prosemirror/validation.js +4 -1
  135. package/dist/redline.js +13 -3
  136. package/dist/server.d.ts +6 -3
  137. package/dist/server.js +5 -2
  138. package/dist/style-sets/extract.d.ts +35 -0
  139. package/dist/style-sets/extract.js +123 -0
  140. package/dist/style-sets/stellaStyle.d.ts +13 -0
  141. package/dist/style-sets/stellaStyle.js +516 -0
  142. package/dist/style-sets/types.d.ts +31 -0
  143. package/dist/style-sets/types.js +5 -0
  144. package/dist/utils/createDocument.d.ts +12 -2
  145. package/dist/utils/createDocument.js +42 -31
  146. package/dist/utils/fontResolver.js +6 -6
  147. package/dist/utils/formatToStyle.js +1 -1
  148. package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
  149. package/dist/utils/paragraphFormattingMerge.js +14 -4
  150. package/package.json +5 -1
  151. package/dist/docx/capabilities.d.ts +0 -41
  152. package/dist/docx/capabilities.js +0 -322
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
2
2
  import { applyFolioAIEditOperations } from "./ai-edits/apply.js";
3
3
  import { document_d_exports } from "./types/document.js";
4
- import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
4
+ import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
5
5
  import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
6
6
  import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
7
7
  import { WordDiffSegment, diffWordSegments } from "./ai-edits/word-diff.js";
@@ -9,10 +9,12 @@ import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput,
9
9
  import { ApplyResult, applySuggestions } from "./ai-suggestions/apply.js";
10
10
  import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
11
11
  import { PositionalText, buildPositionalText } from "./ai-suggestions/text-positions.js";
12
+ import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DocumentPreset, DocumentStyleSet } from "./style-sets/types.js";
12
13
  import { CreateEmptyDocumentOptions, createEmptyDocument } from "./utils/createDocument.js";
14
+ import { DocumentStyleCatalog, DocumentStyleCatalogEntry, ExtractDocumentStyleSetOptions, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "./style-sets/extract.js";
15
+ import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "./style-sets/stellaStyle.js";
13
16
  import { createDocx } from "./docx/rezip.js";
14
- import { FOLIO_DOCX_CAPABILITY_HOSTS, FOLIO_DOCX_CAPABILITY_IDS, FOLIO_DOCX_CAPABILITY_MANIFEST, FOLIO_DOCX_CAPABILITY_MANIFEST_VERSION, FOLIO_DOCX_CAPABILITY_OPERATIONS, FOLIO_DOCX_COMPATIBILITY_HOSTS, FOLIO_DOCX_COMPATIBILITY_PROFILES, FOLIO_DOCX_PROFILES, FOLIO_DOCX_SUPPORT_STATES, FolioDocxCapabilityHost, FolioDocxCapabilityId, FolioDocxCapabilityManifest, FolioDocxCapabilityOperation, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, FolioDocxFeatureCapability, FolioDocxProfile, FolioDocxSupportState, InvalidFolioDocxCapabilityIdError, getFolioDocxCapability, isFolioDocxCapabilityId } from "./docx/capabilities.js";
15
- import { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, InspectDocxCompatibilityOptions, inspectDocxCompatibility } from "./docx/compatibility.js";
17
+ import { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility } from "./docx/compatibility.js";
16
18
  import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "./prosemirror/plugins/aiSuggestionDecorations.js";
17
19
  import { scrollFolioPositionIntoView } from "./paged-layout/scrollToPmPosition.js";
18
20
  import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "./paged-layout/selectionViewportRect.js";
@@ -30,4 +32,4 @@ import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "./utils/fontResolv
30
32
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
31
33
  type Document = document_d_exports.Document;
32
34
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
33
- export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_DOCX_CAPABILITY_HOSTS, FOLIO_DOCX_CAPABILITY_IDS, FOLIO_DOCX_CAPABILITY_MANIFEST, FOLIO_DOCX_CAPABILITY_MANIFEST_VERSION, FOLIO_DOCX_CAPABILITY_OPERATIONS, FOLIO_DOCX_COMPATIBILITY_HOSTS, FOLIO_DOCX_COMPATIBILITY_PROFILES, FOLIO_DOCX_PROFILES, FOLIO_DOCX_SUPPORT_STATES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCapabilityHost, type FolioDocxCapabilityId, type FolioDocxCapabilityManifest, type FolioDocxCapabilityOperation, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioDocxFeatureCapability, type FolioDocxProfile, type FolioDocxSupportState, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, InvalidFolioDocxCapabilityIdError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, deriveBlockId, diffWordSegments, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocxCapability, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isFolioDocxCapabilityId, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
35
+ export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
package/dist/index.js CHANGED
@@ -3,16 +3,18 @@ import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockT
3
3
  import { diffWordSegments } from "./ai-edits/word-diff.js";
4
4
  import { applyFolioAIEditOperations } from "./ai-edits/apply.js";
5
5
  import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
6
+ import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "./style-sets/types.js";
6
7
  import { createEmptyDocument } from "./utils/createDocument.js";
8
+ import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "./style-sets/extract.js";
9
+ import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "./style-sets/stellaStyle.js";
7
10
  import { createDocx } from "./docx/rezip.js";
8
- import { FOLIO_DOCX_CAPABILITY_HOSTS, FOLIO_DOCX_CAPABILITY_IDS, FOLIO_DOCX_CAPABILITY_MANIFEST, FOLIO_DOCX_CAPABILITY_MANIFEST_VERSION, FOLIO_DOCX_CAPABILITY_OPERATIONS, FOLIO_DOCX_COMPATIBILITY_HOSTS, FOLIO_DOCX_COMPATIBILITY_PROFILES, FOLIO_DOCX_PROFILES, FOLIO_DOCX_SUPPORT_STATES, InvalidFolioDocxCapabilityIdError, getFolioDocxCapability, isFolioDocxCapabilityId } from "./docx/capabilities.js";
9
11
  import { inspectDocxCompatibility } from "./docx/compatibility.js";
10
12
  import { DEFAULT_AI_SUGGESTION_PRESETS } from "./ai-suggestions/types.js";
11
13
  import { buildPositionalText } from "./ai-suggestions/text-positions.js";
12
14
  import { isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
13
15
  import { applySuggestions } from "./ai-suggestions/apply.js";
14
- import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "./prosemirror/plugins/aiSuggestionDecorations.js";
15
16
  import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "./utils/fontResolver.js";
17
+ import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "./prosemirror/plugins/aiSuggestionDecorations.js";
16
18
  import { scrollFolioPositionIntoView } from "./paged-layout/scrollToPmPosition.js";
17
19
  import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "./paged-layout/selectionViewportRect.js";
18
20
  import { createAICitationDecorationsPlugin, setAICitationsMeta, setActiveCitationMeta } from "./prosemirror/plugins/aiCitationDecorations.js";
@@ -25,4 +27,4 @@ import { fromMarkdown } from "./markdown/fromMarkdown.js";
25
27
  import { toMarkdown, toMarkdownResult } from "./markdown/index.js";
26
28
  import { extractEmbeddedFonts, getEmbeddedFontFaces } from "./fonts/embeddedFonts.js";
27
29
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
28
- export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_DOCX_CAPABILITY_HOSTS, FOLIO_DOCX_CAPABILITY_IDS, FOLIO_DOCX_CAPABILITY_MANIFEST, FOLIO_DOCX_CAPABILITY_MANIFEST_VERSION, FOLIO_DOCX_CAPABILITY_OPERATIONS, FOLIO_DOCX_COMPATIBILITY_HOSTS, FOLIO_DOCX_COMPATIBILITY_PROFILES, FOLIO_DOCX_PROFILES, FOLIO_DOCX_SUPPORT_STATES, InvalidFolioDocumentOperationBatchError, InvalidFolioDocxCapabilityIdError, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, deriveBlockId, diffWordSegments, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocxCapability, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isFolioDocxCapabilityId, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
30
+ export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -1,5 +1,6 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
2
  import { FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FlowBlock, FootnoteContent, Measure, Page } from "../../layout-engine/types.js";
3
+ import { ToFlowBlocksOptions } from "./toFlowBlocks.js";
3
4
 
4
5
  //#region src/layout-bridge/convert/footnoteLayout.d.ts
5
6
  type MeasureBlocksFn = (blocks: FlowBlock[], contentWidth: number) => Measure[];
@@ -8,6 +9,8 @@ type ConvertFootnoteOptions = {
8
9
  theme?: document_d_exports.Theme | null;
9
10
  measureBlocks?: MeasureBlocksFn; /** Document-wide `w:defaultTabStop` in twips — forwarded to toFlowBlocks. */
10
11
  defaultTabStopTwips?: number;
12
+ lineBreakRules?: ToFlowBlocksOptions["lineBreakRules"];
13
+ automaticHyphenation?: ToFlowBlocksOptions["automaticHyphenation"];
11
14
  };
12
15
  /**
13
16
  * Scan FlowBlocks for runs with footnoteRefId set.
@@ -1,7 +1,7 @@
1
+ import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
1
2
  import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT } from "../../layout-engine/types.js";
2
3
  import { measureParagraph } from "../../layout-engine/measure/measureParagraph.js";
3
4
  import { toFlowBlocks } from "./toFlowBlocks.js";
4
- import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
5
5
  //#region src/layout-bridge/convert/footnoteLayout.ts
6
6
  /** Default footnote font size in points */
7
7
  const FOOTNOTE_FONT_SIZE = 8;
@@ -196,6 +196,8 @@ function convertFootnoteToContent(footnote, displayNumber, contentWidth, options
196
196
  const flowOptions = {};
197
197
  if (options.theme !== void 0) flowOptions.theme = options.theme;
198
198
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
199
+ if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
200
+ if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
199
201
  const blocks = applyFootnotePresentation(toFlowBlocks(pmDoc, flowOptions), displayNumber);
200
202
  const measures = options.measureBlocks ? options.measureBlocks(blocks, contentWidth) : measureFootnoteBlocks(blocks, contentWidth);
201
203
  let totalHeight = 0;
@@ -1,5 +1,6 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
2
  import { FlowBlock, HeaderFooterContent, ImageRun, ImageRunPosition, Measure, PageMargins } from "../../layout-engine/types.js";
3
+ import { ToFlowBlocksOptions } from "./toFlowBlocks.js";
3
4
  import { MeasureBlocksFn } from "./footnoteLayout.js";
4
5
  import { Node } from "prosemirror-model";
5
6
 
@@ -35,6 +36,8 @@ type ConvertHeaderFooterOptions = {
35
36
  theme?: document_d_exports.Theme | null;
36
37
  measureBlocks: MeasureBlocksFn; /** Document-wide `w:defaultTabStop` in twips — forwarded to toFlowBlocks. */
37
38
  defaultTabStopTwips?: number;
39
+ lineBreakRules?: ToFlowBlocksOptions["lineBreakRules"];
40
+ automaticHyphenation?: ToFlowBlocksOptions["automaticHyphenation"];
38
41
  /**
39
42
  * Relationship id of the source HF part. Stamped onto the returned
40
43
  * `HeaderFooterContent.rId` so the painter can emit `data-rid` on the
@@ -1,7 +1,7 @@
1
1
  import { emuToPixels } from "../../utils/units.js";
2
+ import { headerFooterToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
2
3
  import { isFloatingImageRun, isFloatingTextBoxBlock } from "../../layout-engine/types.js";
3
4
  import { toFlowBlocks } from "./toFlowBlocks.js";
4
- import { headerFooterToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
5
5
  //#region src/layout-bridge/convert/headerFooterLayout.ts
6
6
  function isAnchoredImageRun(run) {
7
7
  if (run.kind !== "image") return false;
@@ -311,6 +311,8 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
311
311
  const flowOptions = {};
312
312
  if (options.theme !== void 0) flowOptions.theme = options.theme;
313
313
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
314
+ if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
315
+ if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
314
316
  return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
315
317
  }
316
318
  /**
@@ -329,6 +331,8 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
329
331
  const flowOptions = {};
330
332
  if (options.theme !== void 0) flowOptions.theme = options.theme;
331
333
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
334
+ if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
335
+ if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
332
336
  return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
333
337
  }
334
338
  function finalizeHeaderFooterContent(blocks, contentWidth, metrics, options) {
@@ -435,6 +439,7 @@ function serializeParagraphAttrs(attrs) {
435
439
  "listMarker",
436
440
  "listIsBullet",
437
441
  "listMarkerHidden",
442
+ "listMarkerBold",
438
443
  "listMarkerAlignment",
439
444
  "listMarkerSuffix",
440
445
  "tabs"
@@ -1,5 +1,5 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
- import { BorderStyle, FlowBlock } from "../../layout-engine/types.js";
2
+ import { BorderStyle, FlowBlock, ParagraphAttrs } from "../../layout-engine/types.js";
3
3
  import { Node } from "prosemirror-model";
4
4
 
5
5
  //#region src/layout-bridge/convert/toFlowBlocks.d.ts
@@ -31,7 +31,19 @@ type ToFlowBlocksOptions = {
31
31
  * tab-stop math) can read it without taking a `Document` reference.
32
32
  * Defaults to the OOXML 720-twip value when absent.
33
33
  */
34
- defaultTabStopTwips?: number;
34
+ defaultTabStopTwips?: number; /** Document-wide custom Word line-breaking settings. */
35
+ lineBreakRules?: {
36
+ noLineBreaksBefore?: {
37
+ language?: string;
38
+ characters: string;
39
+ };
40
+ noLineBreaksAfter?: {
41
+ language?: string;
42
+ characters: string;
43
+ };
44
+ useLegacyEthiopicAmharicRules?: boolean;
45
+ }; /** Document-wide automatic hyphenation policy. */
46
+ automaticHyphenation?: NonNullable<ParagraphAttrs["automaticHyphenation"]>;
35
47
  };
36
48
  declare function formatCounter(value: number, format: document_d_exports.NumberFormat | undefined): string;
37
49
  declare function resolveListTemplate(template: string, counters: number[], levelFormats: document_d_exports.NumberFormat[] | undefined, forceDecimal?: boolean): string;
@@ -1,18 +1,18 @@
1
1
  import { NUMBER_FORMAT_VALUES } from "../../types/documentEnumValues.js";
2
2
  import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
3
+ import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
3
4
  import { padDecimal } from "../../docx/numberingParser.js";
4
- import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
5
+ import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
6
+ import { directionIsRtl } from "../../prosemirror/paragraphDirection.js";
7
+ import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
8
+ import { assertValidProseMirrorDocument } from "../../prosemirror/validation.js";
9
+ import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
5
10
  import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
6
11
  import { resolveShadingFill } from "../../utils/formatToStyle.js";
7
- import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
12
+ import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
8
13
  import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
9
14
  import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
10
15
  import { getColumns } from "../sectionColumns.js";
11
- import { directionIsRtl } from "../../prosemirror/paragraphDirection.js";
12
- import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
13
- import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
14
- import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
15
- import { assertValidProseMirrorDocument } from "../../prosemirror/validation.js";
16
16
  import { groupParagraphFrames } from "./paragraphFrames.js";
17
17
  //#region src/layout-bridge/convert/toFlowBlocks.ts
18
18
  const DEFAULT_FONT = "Calibri";
@@ -244,6 +244,15 @@ function extractRunFormatting(marks, theme) {
244
244
  if (attrs.eastAsia) formatting.eastAsiaFontFamily = attrs.eastAsia;
245
245
  break;
246
246
  }
247
+ case "language": {
248
+ const attrs = expectLanguageMarkAttrs(mark);
249
+ formatting.language = {
250
+ ...attrs.val ? { val: attrs.val } : {},
251
+ ...attrs.eastAsia ? { eastAsia: attrs.eastAsia } : {},
252
+ ...attrs.bidi ? { bidi: attrs.bidi } : {}
253
+ };
254
+ break;
255
+ }
247
256
  case "characterSpacing": {
248
257
  const attrs = expectCharacterSpacingMarkAttrs(mark);
249
258
  if (attrs.spacing !== void 0) formatting.letterSpacing = twipsToPixels(attrs.spacing);
@@ -375,6 +384,7 @@ function paragraphRunDefaults(pmAttrs, theme) {
375
384
  const fontFamily = defaultTextFormatting.fontFamily?.ascii ?? defaultTextFormatting.fontFamily?.hAnsi;
376
385
  if (fontFamily) result.fontFamily = fontFamily;
377
386
  if (defaultTextFormatting.fontFamily?.eastAsia) result.eastAsiaFontFamily = defaultTextFormatting.fontFamily.eastAsia;
387
+ if (defaultTextFormatting.language) result.language = { ...defaultTextFormatting.language };
378
388
  if (defaultTextFormatting.fontSize !== void 0) result.fontSize = defaultTextFormatting.fontSize / 2;
379
389
  if (defaultTextFormatting.bold !== void 0) result.bold = defaultTextFormatting.bold;
380
390
  if (defaultTextFormatting.italic !== void 0) result.italic = defaultTextFormatting.italic;
@@ -429,6 +439,7 @@ function buildImageRun(attrs, constrained, pmStart, pmEnd, trackedChange) {
429
439
  if (attrs.distBottom !== void 0) run.distBottom = attrs.distBottom;
430
440
  if (attrs.distLeft !== void 0) run.distLeft = attrs.distLeft;
431
441
  if (attrs.distRight !== void 0) run.distRight = attrs.distRight;
442
+ if (attrs._docxObjectPreview === true) run.exactLineHeight = true;
432
443
  if (attrs.cropTop != null) run.cropTop = attrs.cropTop;
433
444
  if (attrs.cropRight != null) run.cropRight = attrs.cropRight;
434
445
  if (attrs.cropBottom != null) run.cropBottom = attrs.cropBottom;
@@ -644,6 +655,8 @@ function toPreviousListAttrs(previousFormatting) {
644
655
  if (typeof listMarkerFontFamily === "string") attrs.listMarkerFontFamily = listMarkerFontFamily;
645
656
  const listMarkerFontSize = previousFormatting["listMarkerFontSize"];
646
657
  if (typeof listMarkerFontSize === "number") attrs.listMarkerFontSize = listMarkerFontSize;
658
+ const listMarkerBold = previousFormatting["listMarkerBold"];
659
+ if (typeof listMarkerBold === "boolean") attrs.listMarkerBold = listMarkerBold;
647
660
  const listMarkerAlignment = readListMarkerAlignment(previousFormatting["listMarkerAlignment"]);
648
661
  if (listMarkerAlignment) attrs.listMarkerAlignment = listMarkerAlignment;
649
662
  const listMarkerSuffix = readListMarkerSuffix(previousFormatting["listMarkerSuffix"]);
@@ -669,6 +682,7 @@ function applyDeletedListMarkerAttrs(attrs, change, listCounters, listAbstractCo
669
682
  if (previousListAttrs.listMarkerHidden !== void 0) attrs.listMarkerHidden = previousListAttrs.listMarkerHidden;
670
683
  if (previousListAttrs.listMarkerFontFamily) attrs.listMarkerFontFamily = previousListAttrs.listMarkerFontFamily;
671
684
  if (previousListAttrs.listMarkerFontSize) attrs.listMarkerFontSize = previousListAttrs.listMarkerFontSize;
685
+ if (previousListAttrs.listMarkerBold !== void 0) attrs.listMarkerBold = previousListAttrs.listMarkerBold;
672
686
  if (previousListAttrs.listMarkerAlignment) attrs.listMarkerAlignment = previousListAttrs.listMarkerAlignment;
673
687
  if (previousListAttrs.listMarkerSuffix) attrs.listMarkerSuffix = previousListAttrs.listMarkerSuffix;
674
688
  }
@@ -760,6 +774,9 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
760
774
  return tabStop;
761
775
  });
762
776
  if (pmAttrs.pageBreakBefore) attrs.pageBreakBefore = true;
777
+ if (pmAttrs.kinsoku !== void 0 && pmAttrs.kinsoku !== null) attrs.kinsoku = pmAttrs.kinsoku;
778
+ if (pmAttrs.overflowPunctuation !== void 0 && pmAttrs.overflowPunctuation !== null) attrs.overflowPunctuation = pmAttrs.overflowPunctuation;
779
+ if (pmAttrs.suppressAutoHyphens !== void 0 && pmAttrs.suppressAutoHyphens !== null) attrs.suppressAutoHyphens = pmAttrs.suppressAutoHyphens;
763
780
  if (pmAttrs.renderedPageBreakBefore) attrs.renderedPageBreakBefore = true;
764
781
  if (pmAttrs.keepNext) attrs.keepNext = true;
765
782
  if (pmAttrs.keepLines) attrs.keepLines = true;
@@ -801,6 +818,7 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
801
818
  if (pmAttrs.listMarkerHidden) attrs.listMarkerHidden = true;
802
819
  if (pmAttrs.listMarkerFontFamily) attrs.listMarkerFontFamily = pmAttrs.listMarkerFontFamily;
803
820
  if (pmAttrs.listMarkerFontSize) attrs.listMarkerFontSize = pmAttrs.listMarkerFontSize;
821
+ if (pmAttrs.listMarkerBold !== null && pmAttrs.listMarkerBold !== void 0) attrs.listMarkerBold = pmAttrs.listMarkerBold;
804
822
  if (pmAttrs.listMarkerAlignment) attrs.listMarkerAlignment = pmAttrs.listMarkerAlignment;
805
823
  if (pmAttrs.listMarkerSuffix) attrs.listMarkerSuffix = pmAttrs.listMarkerSuffix;
806
824
  if (pmAttrs.listMarkerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = pmAttrs.listMarkerSecondSlotOffsetTwips;
@@ -841,6 +859,8 @@ function convertParagraph(node, startPos, options) {
841
859
  const pmAttrs = expectParagraphAttrs(node);
842
860
  const runs = paragraphToRuns(node, startPos, options);
843
861
  const attrs = convertParagraphAttrs(pmAttrs, options.theme, options.listCounters, options.listAbstractCounters, options.listSeenNumIds, options.defaultTabStopTwips, options.originalListCounters, options.originalListAbstractCounters, options.originalListSeenNumIds);
862
+ if (options.lineBreakRules) attrs.lineBreakRules = options.lineBreakRules;
863
+ if (options.automaticHyphenation) attrs.automaticHyphenation = options.automaticHyphenation;
844
864
  const defaultTextFormatting = pmAttrs.defaultTextFormatting;
845
865
  if (runs.length === 0) {
846
866
  if (pmAttrs._originalFormatting && Object.entries(pmAttrs._originalFormatting).some(([key, value]) => key !== "runProperties" && value !== void 0 && value !== null)) attrs.hasDirectParagraphFormatting = true;
@@ -854,6 +874,8 @@ function convertParagraph(node, startPos, options) {
854
874
  attrs.suppressEmptyParagraphHeight = true;
855
875
  if (attrs.listMarker !== void 0) attrs.listMarkerHidden = true;
856
876
  }
877
+ const hasVisibleParagraphPayload = attrs.listMarker !== void 0 && !attrs.listMarkerHidden || attrs.borders?.top !== void 0 || attrs.borders?.bottom !== void 0 || attrs.borders?.left !== void 0 || attrs.borders?.right !== void 0 || attrs.borders?.between !== void 0 || attrs.borders?.bar !== void 0 || attrs.shading !== void 0;
878
+ if (runs.length === 0 && pmAttrs._pageBreakCarrier === true && !hasVisibleParagraphPayload) attrs.suppressEmptyParagraphHeight = true;
857
879
  const bookmarkNames = pmAttrs.bookmarks?.map((b) => b.name);
858
880
  const block = {
859
881
  kind: "paragraph",
@@ -927,7 +949,7 @@ function reserveLeadingEmptyOutlineHeight(blocks) {
927
949
  * OOXML stores border widths in eighths of a point.
928
950
  */
929
951
  function borderWidthToPixels(eighthsOfPoint) {
930
- return Math.max(1, Math.round(eighthsOfPoint / 8 * 1.333));
952
+ return pointsToPixels(eighthsOfPoint / 8);
931
953
  }
932
954
  const OOXML_TO_CSS_BORDER = {
933
955
  single: "solid",
@@ -954,7 +976,7 @@ function convertBorderSpecToLayout(border, theme) {
954
976
  if (!border.style || border.style === "none" || border.style === "nil") return;
955
977
  const result = {
956
978
  style: OOXML_TO_CSS_BORDER[border.style] || "solid",
957
- width: borderWidthToPixels(border.size ?? 0),
979
+ width: border.size === void 0 ? 1 : borderWidthToPixels(border.size),
958
980
  color: border.color ? resolveColor(border.color, theme) : "#000000"
959
981
  };
960
982
  if (border.space !== void 0) result.space = pointsToPixels(border.space);
@@ -974,10 +996,23 @@ function extractCellBorders(borders, theme) {
974
996
  "right"
975
997
  ]) {
976
998
  const border = borders[side];
977
- result[side] = (border ? convertBorderSpecToLayout(border, theme) : void 0) ?? {
978
- width: 0,
979
- style: "none"
980
- };
999
+ const converted = border ? convertBorderSpecToLayout(border, theme) : void 0;
1000
+ if (!converted) {
1001
+ result[side] = {
1002
+ width: 0,
1003
+ style: "none"
1004
+ };
1005
+ continue;
1006
+ }
1007
+ result[side] = border?.size === 0 ? {
1008
+ ...converted,
1009
+ width: 0
1010
+ } : converted;
1011
+ }
1012
+ for (const side of ["topLeftToBottomRight", "topRightToBottomLeft"]) {
1013
+ const border = borders[side];
1014
+ const converted = border ? convertBorderSpecToLayout(border, theme) : void 0;
1015
+ if (converted) result[side] = converted;
981
1016
  }
982
1017
  return Object.keys(result).length > 0 ? result : void 0;
983
1018
  }
@@ -996,7 +1031,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
996
1031
  offset += child.nodeSize;
997
1032
  });
998
1033
  const trailingBlock = blocks.at(-1);
999
- if (blocks.length > 1 && trailingBlock?.kind === "paragraph" && trailingBlock.runs.every((run) => run.kind === "text" && run.text.length === 0)) trailingBlock.attrs = {
1034
+ if (blocks.at(-2)?.kind === "table" && trailingBlock?.kind === "paragraph" && trailingBlock.runs.every((run) => run.kind === "text" && run.text.length === 0)) trailingBlock.attrs = {
1000
1035
  ...trailingBlock.attrs,
1001
1036
  suppressEmptyParagraphHeight: true
1002
1037
  };
@@ -1025,6 +1060,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
1025
1060
  };
1026
1061
  if (attrs.width) cell.width = twipsToPixels(attrs.width);
1027
1062
  if (attrs.verticalAlign) cell.verticalAlign = attrs.verticalAlign;
1063
+ if (attrs.textDirection) cell.textDirection = attrs.textDirection;
1028
1064
  if (attrs.backgroundColor) cell.background = `#${attrs.backgroundColor}`;
1029
1065
  const cellBorders = extractCellBorders(attrs.borders, options.theme);
1030
1066
  if (cellBorders) cell.borders = cellBorders;
@@ -1051,6 +1087,7 @@ function convertTableRow(node, startPos, options, tableCellMargins) {
1051
1087
  if (attrs.height) row.height = twipsToPixels(attrs.height);
1052
1088
  if (attrs.heightRule) row.heightRule = attrs.heightRule;
1053
1089
  if (attrs.isHeader) row.isHeader = attrs.isHeader;
1090
+ if (attrs._originalFormatting?.cantSplit) row.cantSplit = true;
1054
1091
  if (attrs.hidden) row.hidden = attrs.hidden;
1055
1092
  return row;
1056
1093
  }
@@ -2,9 +2,10 @@ import { FontMetrics, FontStyle, RunMeasurement, TextMeasurement } from "../../.
2
2
  import { getFontMetrics, measureRun, measureText, measureTextWidth } from "../../../layout-engine/measure/measureProvider.js";
3
3
  import { getCanvasContext, resetCanvasContext } from "../../../layout-engine/measure/measureContainer.js";
4
4
  import { buildFontString, findCharacterAtX, getXForCharacter, halfPtToPx, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx } from "../../../layout-engine/measure/measureHelpers.js";
5
+ import { LineBreakPolicy, LineBreakProvider, defaultLineBreakProvider, getLineBreakProvider, getLineBreakProviderGeneration, resetLineBreakProvider, setLineBreakProvider } from "../../../layout-engine/measure/lineBreakProvider.js";
5
6
  import { FloatingExclusionRect, FloatingImageZone, FloatingLineMargins, FloatingLineSegmentZone, WrapTextDirection, getFloatingAvailableWidth, getFloatingMargins, rectsToFloatingZones } from "../../../layout-engine/measure/floatingZones.js";
6
7
  import { clampFloatingWrapMargins } from "../../../layout-engine/measure/clampFloatingWrapMargins.js";
7
8
  import { MIN_WRAP_SEGMENT_WIDTH, MeasureParagraphOptions, findClearLineY, getRunCharWidths, measureParagraph, measureParagraphs } from "../../../layout-engine/measure/measureParagraph.js";
8
9
  import { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTotalCacheSize, hashParagraphBlock, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize } from "../../../layout-engine/measure/cache.js";
9
10
  import { FolioMeasurementFeatureFlags, isWorkerFontMetricsEnabled, setFolioMeasurementFlags } from "../../../layout-engine/measure/featureFlags.js";
10
- export { type FloatingExclusionRect, type FloatingImageZone, type FloatingLineMargins, type FloatingLineSegmentZone, type FolioMeasurementFeatureFlags, type FontMetrics, type FontStyle, MIN_WRAP_SEGMENT_WIDTH, type MeasureParagraphOptions, type RunMeasurement, type TextMeasurement, type WrapTextDirection, buildFontString, clampFloatingWrapMargins, clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, findCharacterAtX, findClearLineY, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getCanvasContext, getFloatingAvailableWidth, getFloatingMargins, getFontCacheSize, getFontMetrics, getParagraphCacheSize, getRunCharWidths, getTextCacheSize, getTotalCacheSize, getXForCharacter, halfPtToPx, hashParagraphBlock, isWorkerFontMetricsEnabled, measureParagraph, measureParagraphs, measureRun, measureText, measureTextWidth, ptToPx, pxToHalfPt, pxToPt, pxToTwips, rectsToFloatingZones, resetCanvasContext, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFolioMeasurementFlags, setFontCacheSize, setParagraphCacheSize, setTextCacheSize, twipsToPx };
11
+ export { type FloatingExclusionRect, type FloatingImageZone, type FloatingLineMargins, type FloatingLineSegmentZone, type FolioMeasurementFeatureFlags, type FontMetrics, type FontStyle, type LineBreakPolicy, type LineBreakProvider, MIN_WRAP_SEGMENT_WIDTH, type MeasureParagraphOptions, type RunMeasurement, type TextMeasurement, type WrapTextDirection, buildFontString, clampFloatingWrapMargins, clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, defaultLineBreakProvider, findCharacterAtX, findClearLineY, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getCanvasContext, getFloatingAvailableWidth, getFloatingMargins, getFontCacheSize, getFontMetrics, getLineBreakProvider, getLineBreakProviderGeneration, getParagraphCacheSize, getRunCharWidths, getTextCacheSize, getTotalCacheSize, getXForCharacter, halfPtToPx, hashParagraphBlock, isWorkerFontMetricsEnabled, measureParagraph, measureParagraphs, measureRun, measureText, measureTextWidth, ptToPx, pxToHalfPt, pxToPt, pxToTwips, rectsToFloatingZones, resetCanvasContext, resetLineBreakProvider, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFolioMeasurementFlags, setFontCacheSize, setLineBreakProvider, setParagraphCacheSize, setTextCacheSize, twipsToPx };
@@ -1,9 +1,10 @@
1
1
  import { getFontMetrics, measureRun, measureText, measureTextWidth } from "../../../layout-engine/measure/measureProvider.js";
2
2
  import { buildFontString, findCharacterAtX, getXForCharacter, halfPtToPx, ptToPx, pxToHalfPt, pxToPt, pxToTwips, twipsToPx } from "../../../layout-engine/measure/measureHelpers.js";
3
+ import { defaultLineBreakProvider, getLineBreakProvider, getLineBreakProviderGeneration, resetLineBreakProvider, setLineBreakProvider } from "../../../layout-engine/measure/lineBreakProvider.js";
3
4
  import { clampFloatingWrapMargins } from "../../../layout-engine/measure/clampFloatingWrapMargins.js";
4
5
  import { getFloatingAvailableWidth, getFloatingMargins, rectsToFloatingZones } from "../../../layout-engine/measure/floatingZones.js";
5
6
  import { MIN_WRAP_SEGMENT_WIDTH, findClearLineY, getRunCharWidths, measureParagraph, measureParagraphs } from "../../../layout-engine/measure/measureParagraph.js";
6
7
  import { clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getFontCacheSize, getParagraphCacheSize, getTextCacheSize, getTotalCacheSize, hashParagraphBlock, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFontCacheSize, setParagraphCacheSize, setTextCacheSize } from "../../../layout-engine/measure/cache.js";
7
8
  import { isWorkerFontMetricsEnabled, setFolioMeasurementFlags } from "../../../layout-engine/measure/featureFlags.js";
8
9
  import { getCanvasContext, resetCanvasContext } from "../../../layout-engine/measure/measureContainer.js";
9
- export { MIN_WRAP_SEGMENT_WIDTH, buildFontString, clampFloatingWrapMargins, clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, findCharacterAtX, findClearLineY, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getCanvasContext, getFloatingAvailableWidth, getFloatingMargins, getFontCacheSize, getFontMetrics, getParagraphCacheSize, getRunCharWidths, getTextCacheSize, getTotalCacheSize, getXForCharacter, halfPtToPx, hashParagraphBlock, isWorkerFontMetricsEnabled, measureParagraph, measureParagraphs, measureRun, measureText, measureTextWidth, ptToPx, pxToHalfPt, pxToPt, pxToTwips, rectsToFloatingZones, resetCanvasContext, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFolioMeasurementFlags, setFontCacheSize, setParagraphCacheSize, setTextCacheSize, twipsToPx };
10
+ export { MIN_WRAP_SEGMENT_WIDTH, buildFontString, clampFloatingWrapMargins, clearAllCaches, clearFontMetricsCache, clearParagraphMeasureCache, clearTextWidthCache, defaultLineBreakProvider, findCharacterAtX, findClearLineY, getCachedFontMetrics, getCachedParagraphMeasure, getCachedTextWidth, getCanvasContext, getFloatingAvailableWidth, getFloatingMargins, getFontCacheSize, getFontMetrics, getLineBreakProvider, getLineBreakProviderGeneration, getParagraphCacheSize, getRunCharWidths, getTextCacheSize, getTotalCacheSize, getXForCharacter, halfPtToPx, hashParagraphBlock, isWorkerFontMetricsEnabled, measureParagraph, measureParagraphs, measureRun, measureText, measureTextWidth, ptToPx, pxToHalfPt, pxToPt, pxToTwips, rectsToFloatingZones, resetCanvasContext, resetLineBreakProvider, setCachedFontMetrics, setCachedParagraphMeasure, setCachedTextWidth, setFolioMeasurementFlags, setFontCacheSize, setLineBreakProvider, setParagraphCacheSize, setTextCacheSize, twipsToPx };
@@ -7,7 +7,7 @@ import { continuesNumberedSequence } from "./paragraphSequence.js";
7
7
  import { createPaginator } from "./paginator.js";
8
8
  import { getParagraphFragmentPmRange } from "./paragraphFragmentRange.js";
9
9
  import { INITIAL_RENDERED_BREAK_STATE, reconcileAfterBlock, reconcileBreakBeforeBlock, recordReflowBoundary } from "./renderedBreakReconciliation.js";
10
- import { buildTableRowBreakInfo, snapRowBreak } from "./tableRowBreak.js";
10
+ import { buildTableRowBreakInfo, getRowContinuationSkip, snapRowBreak } from "./tableRowBreak.js";
11
11
  import { bandFragmentX, bandTopContentY, isPageFrameRelativeAnchor } from "./textBoxFlow.js";
12
12
  import { resolveSectionHeaderFooterRefs } from "./headerFooterRefs.js";
13
13
  import { applyPendingToActive, createInitialSectionState, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, scheduleSectionBreak } from "./section-breaks.js";
@@ -23,6 +23,7 @@ const DEFAULT_COLUMNS = {
23
23
  count: 1,
24
24
  gap: 0
25
25
  };
26
+ const DEFAULT_SECTION_BREAK_TYPE = "nextPage";
26
27
  function collectSectionConfigs(blocks, initialConfig, finalConfig) {
27
28
  const configs = [];
28
29
  const breakIndices = [];
@@ -183,7 +184,7 @@ function layoutDocument(blocks, measures, options) {
183
184
  const finalColumns = options.finalColumns ?? options.columns;
184
185
  if (finalColumns !== void 0) finalConfig.columns = finalColumns;
185
186
  const { configs: sectionConfigs, breakIndices } = collectSectionConfigs(blocks, bodyConfig, finalConfig);
186
- const sectionBreakTypes = [...breakIndices.map((index) => blocks[index].type), options.bodyBreakType];
187
+ const sectionBreakTypes = breakIndices.map((index) => blocks[index].type);
187
188
  const initialConfig = sectionConfigs.at(0) ?? bodyConfig;
188
189
  const paginator = createPaginator({
189
190
  pageSize: initialConfig.pageSize,
@@ -210,13 +211,14 @@ function layoutDocument(blocks, measures, options) {
210
211
  const block = blocks[i];
211
212
  const measure = measures[i];
212
213
  const renderedBreakNeedsSnap = measure.kind === "paragraph" && !paginator.fits(measure.totalHeight);
214
+ const hasExplicitPageBreak = hasPageBreakBefore(block);
213
215
  const breakDecision = reconcileBreakBeforeBlock({
214
216
  state: renderedBreakState,
215
217
  block,
216
218
  previousBlock: blocks[i - 1],
217
219
  page: paginator.getCurrentState().page,
218
220
  blocksById,
219
- hasExplicitPageBreak: hasPageBreakBefore(block),
221
+ hasExplicitPageBreak,
220
222
  renderedBreakNeedsSnap
221
223
  });
222
224
  if (breakDecision.forcePageBreak) paginator.forcePageBreak();
@@ -231,7 +233,14 @@ function layoutDocument(blocks, measures, options) {
231
233
  const pageBeforeBlockLayout = paginator.getCurrentState().page.number;
232
234
  switch (block.kind) {
233
235
  case "paragraph":
234
- layoutParagraph(block, measure, paginator, paginator.columnWidth, options.footnoteHeightById);
236
+ layoutParagraph({
237
+ block,
238
+ measure,
239
+ paginator,
240
+ contentWidth: paginator.columnWidth,
241
+ footnoteHeightById: options.footnoteHeightById,
242
+ suppressSpaceBefore: breakDecision.suppressSpaceBefore
243
+ });
235
244
  break;
236
245
  case "table":
237
246
  if (block.floating) layoutFloatingTable(block, measure, paginator, paginator.getContentWidth());
@@ -256,7 +265,9 @@ function layoutDocument(blocks, measures, options) {
256
265
  break;
257
266
  case "sectionBreak": {
258
267
  const nextSectionConfig = sectionConfigs[sectionIdx + 1] ?? initialConfig;
259
- handleSectionBreak(block, paginator, nextSectionConfig, sectionBreakTypes[sectionIdx + 1] ?? sectionBreakTypes[sectionIdx], sectionIdx + 1);
268
+ let nextType = options.bodyBreakType ?? sectionBreakTypes[sectionIdx] ?? DEFAULT_SECTION_BREAK_TYPE;
269
+ if (sectionIdx + 1 < sectionBreakTypes.length) nextType = sectionBreakTypes[sectionIdx + 1] ?? DEFAULT_SECTION_BREAK_TYPE;
270
+ handleSectionBreak(block, paginator, nextSectionConfig, nextType, sectionIdx + 1);
260
271
  const nextColumns = nextSectionConfig.columns;
261
272
  const nextBreakIndex = breakIndices[sectionIdx + 1] ?? blocks.length;
262
273
  const nextBreak = blocks[nextBreakIndex];
@@ -331,20 +342,10 @@ function getLineFootnoteRefs(block, fromRun, toRun, fnHeights) {
331
342
  height
332
343
  };
333
344
  }
334
- /**
335
- * Layout a paragraph block onto pages.
336
- *
337
- * When `footnoteHeightById` is provided, each line carrying a footnote
338
- * ref additionally reserves space on its host page for the fn's
339
- * content. Pagination decisions look at the line's effective height
340
- * (`lineHeight + lineFnHeight`) so a line cannot land on a page that
341
- * lacks room for both — preventing footnote overflow without the
342
- * static-reservation iteration loop.
343
- */
344
- function layoutParagraph(block, measure, paginator, contentWidth, footnoteHeightById) {
345
+ function layoutParagraph({ block, measure, paginator, contentWidth, footnoteHeightById, suppressSpaceBefore }) {
345
346
  const lines = measure.lines;
346
347
  if (lines.length === 0) {
347
- const spaceBefore = getParagraphSpacingBefore(block);
348
+ const spaceBefore = suppressSpaceBefore ? 0 : getParagraphSpacingBefore(block);
348
349
  const spaceAfter = getParagraphSpacingAfter(block);
349
350
  const state = paginator.getCurrentState();
350
351
  const fragment = {
@@ -363,7 +364,7 @@ function layoutParagraph(block, measure, paginator, contentWidth, footnoteHeight
363
364
  paginator.addFragment(fragment, 0, spaceBefore, spaceAfter);
364
365
  return;
365
366
  }
366
- const spaceBefore = getParagraphSpacingBefore(block);
367
+ const spaceBefore = suppressSpaceBefore ? 0 : getParagraphSpacingBefore(block);
367
368
  const spaceAfter = getParagraphSpacingAfter(block);
368
369
  let currentLineIndex = 0;
369
370
  while (currentLineIndex < lines.length) {
@@ -479,6 +480,7 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
479
480
  const headerRowsHeight = getHeaderRowsHeight(measure, headerRowCount);
480
481
  let currentRowIndex = 0;
481
482
  const breakInfo = buildTableRowBreakInfo(block, measure);
483
+ const hasVerticalMerges = block.rows.some((row) => row.cells.some((cell) => (cell.rowSpan ?? 1) > 1));
482
484
  const computeTableX = (columnIndex) => {
483
485
  let x = paginator.getColumnX(columnIndex);
484
486
  if (block.justification === "center") x += (paginator.columnWidth - measure.totalWidth) / 2;
@@ -498,16 +500,21 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
498
500
  const shouldRepeatHeaderRows = (rowIndex, consumed, state = paginator.getCurrentState()) => headerRowCount > 0 && rowIndex >= headerRowCount && !(consumed === 0 && hasAdjacentPriorTableRows(rowIndex, state));
499
501
  const canSplitRow = (rowIndex, state = paginator.getCurrentState()) => {
500
502
  const row = rows[rowIndex];
501
- if (!row) return false;
503
+ const sourceRow = block.rows[rowIndex];
504
+ if (!row || !sourceRow || sourceRow.cantSplit || sourceRow.isHeader || hasVerticalMerges) return false;
502
505
  if ((breakInfo.breakOffsets[rowIndex]?.length ?? 0) <= 1) return false;
503
506
  const freshHeaderOverhead = headerRowCount > 0 && rowIndex >= headerRowCount ? headerRowsHeight : 0;
504
- return row.height + freshHeaderOverhead > getCurrentRowCapacity(state);
507
+ const oversized = row.height + freshHeaderOverhead > getCurrentRowCapacity(state);
508
+ if (!oversized && (state.footnoteHeight > 0 || (rowFootnoteIds[rowIndex]?.length ?? 0) > 0)) return false;
509
+ const currentHeaderOverhead = shouldRepeatHeaderRows(rowIndex, 0, state) ? headerRowsHeight : 0;
510
+ const currentAvailableHeight = paginator.getAvailableHeight() - currentHeaderOverhead - state.trailingSpacing;
511
+ return oversized || row.height > currentAvailableHeight;
505
512
  };
506
513
  while (currentRowIndex < rows.length) {
507
- const oversizedRow = rows[currentRowIndex];
514
+ const splittableRow = rows[currentRowIndex];
508
515
  if (canSplitRow(currentRowIndex)) {
509
516
  let consumed = 0;
510
- while (consumed < oversizedRow.height) {
517
+ while (consumed < splittableRow.height) {
511
518
  const sliceState = paginator.getCurrentState();
512
519
  const repeatHeaderRows = shouldRepeatHeaderRows(currentRowIndex, consumed, sliceState);
513
520
  const headerOverhead = repeatHeaderRows ? headerRowsHeight : 0;
@@ -519,11 +526,12 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
519
526
  continue;
520
527
  }
521
528
  const from = consumed;
522
- slice = (breakInfo.breakOffsets[currentRowIndex]?.find((o) => o > from) ?? oversizedRow.height) - consumed;
529
+ slice = (breakInfo.breakOffsets[currentRowIndex]?.find((o) => o > from) ?? splittableRow.height) - consumed;
523
530
  }
524
531
  const sliceBottom = consumed + slice;
525
- const reachesRowEnd = sliceBottom >= oversizedRow.height;
526
- const moreAfter = !reachesRowEnd || currentRowIndex + 1 < rows.length;
532
+ const continuationSkip = sliceBottom < splittableRow.height ? getRowContinuationSkip(breakInfo, currentRowIndex, sliceBottom) : 0;
533
+ const nextConsumed = Math.min(splittableRow.height, sliceBottom + continuationSkip);
534
+ const moreAfter = !(nextConsumed >= splittableRow.height) || currentRowIndex + 1 < rows.length;
527
535
  const fragmentHeight = headerOverhead + slice;
528
536
  const sliceFragment = {
529
537
  kind: "table",
@@ -540,14 +548,14 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
540
548
  ...moreAfter ? { continuesOnNext: true } : {},
541
549
  ...repeatHeaderRows ? { headerRowCount } : {},
542
550
  ...consumed > 0 ? { topClip: consumed } : {},
543
- ...reachesRowEnd ? {} : { bottomClip: sliceBottom },
551
+ ...sliceBottom >= splittableRow.height ? {} : { bottomClip: sliceBottom },
544
552
  ...block.sdtGroups ? { sdtGroups: block.sdtGroups } : {}
545
553
  };
546
554
  const sliceResult = paginator.addFragment(sliceFragment, fragmentHeight, 0, 0);
547
555
  sliceFragment.y = sliceResult.y;
548
556
  sliceFragment.x = computeTableX(sliceResult.state.columnIndex);
549
- consumed = sliceBottom;
550
- if (consumed < oversizedRow.height) paginator.forceColumnBreak();
557
+ consumed = nextConsumed;
558
+ if (consumed < splittableRow.height) paginator.forceColumnBreak();
551
559
  }
552
560
  currentRowIndex += 1;
553
561
  continue;