@stll/folio-core 0.47.7 → 0.49.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 (213) hide show
  1. package/dist/ai-edits/apply.js +565 -121
  2. package/dist/ai-edits/minimal-replacement.d.ts +64 -0
  3. package/dist/ai-edits/minimal-replacement.js +282 -0
  4. package/dist/controller/fontReadiness.js +3 -3
  5. package/dist/controller/hyphenationReadiness.d.ts +19 -0
  6. package/dist/controller/hyphenationReadiness.js +47 -0
  7. package/dist/controller/layoutPipeline.d.ts +3 -0
  8. package/dist/controller/layoutPipeline.js +70 -18
  9. package/dist/display-list/build/buildDisplayList.js +39 -12
  10. package/dist/display-list/build/pageFurniture.d.ts +7 -1
  11. package/dist/display-list/build/pageFurniture.js +21 -8
  12. package/dist/display-list/build/paragraphPrimitives.js +68 -11
  13. package/dist/display-list/build/tablePrimitives.js +10 -6
  14. package/dist/display-list/build/textBoxPrimitives.js +1 -1
  15. package/dist/display-list/build/unsupported.d.ts +2 -2
  16. package/dist/display-list/build/unsupported.js +0 -0
  17. package/dist/display-list/dom/renderDisplayListToDom.js +0 -1
  18. package/dist/docx/attributeRemainder.js +10 -2
  19. package/dist/docx/blockContentParser.d.ts +2 -0
  20. package/dist/docx/blockContentParser.js +79 -64
  21. package/dist/docx/bulletMarkers.d.ts +18 -2
  22. package/dist/docx/bulletMarkers.js +27 -2
  23. package/dist/docx/commentParser.d.ts +2 -1
  24. package/dist/docx/commentParser.js +57 -45
  25. package/dist/docx/containerChildren.d.ts +21 -8
  26. package/dist/docx/containerChildren.js +39 -9
  27. package/dist/docx/documentParser.d.ts +5 -1
  28. package/dist/docx/documentParser.js +8 -5
  29. package/dist/docx/documentSectionFacts.d.ts +22 -0
  30. package/dist/docx/documentSectionFacts.js +43 -0
  31. package/dist/docx/drawingGroupChildren.d.ts +60 -0
  32. package/dist/docx/drawingGroupChildren.js +176 -0
  33. package/dist/docx/drawingUtils.js +3 -0
  34. package/dist/docx/fieldParser.d.ts +8 -1
  35. package/dist/docx/fieldParser.js +47 -3
  36. package/dist/docx/fontTableParser.js +34 -27
  37. package/dist/docx/footnoteParser.d.ts +3 -2
  38. package/dist/docx/footnoteParser.js +15 -12
  39. package/dist/docx/groupDrawingParser.d.ts +9 -2
  40. package/dist/docx/groupDrawingParser.js +125 -37
  41. package/dist/docx/headerFooterParser.d.ts +7 -2
  42. package/dist/docx/headerFooterParser.js +15 -5
  43. package/dist/docx/hyperlinkParser.d.ts +48 -36
  44. package/dist/docx/hyperlinkParser.js +97 -82
  45. package/dist/docx/numberingParser.js +108 -84
  46. package/dist/docx/packageParts.d.ts +45 -1
  47. package/dist/docx/packageParts.js +93 -2
  48. package/dist/docx/paraIdAttribute.d.ts +3 -2
  49. package/dist/docx/paragraphParser.d.ts +5 -1
  50. package/dist/docx/paragraphParser.js +468 -365
  51. package/dist/docx/paragraphProperties.js +123 -109
  52. package/dist/docx/paragraphPropertySource.d.ts +6 -1
  53. package/dist/docx/paragraphPropertySource.js +9 -1
  54. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  55. package/dist/docx/paragraphTextBoxEnrichment.js +143 -10
  56. package/dist/docx/parser.d.ts +7 -1
  57. package/dist/docx/parser.js +33 -16
  58. package/dist/docx/previewBudget.d.ts +55 -33
  59. package/dist/docx/previewBudget.js +59 -65
  60. package/dist/docx/rezip.js +41 -58
  61. package/dist/docx/runParser.d.ts +4 -1
  62. package/dist/docx/runParser.js +182 -184
  63. package/dist/docx/sdtProperties.js +87 -84
  64. package/dist/docx/sectionParser.js +169 -160
  65. package/dist/docx/selectiveSaveFlags.d.ts +10 -3
  66. package/dist/docx/selectiveSaveFlags.js +1 -1
  67. package/dist/docx/selectiveXmlPatch.d.ts +56 -34
  68. package/dist/docx/selectiveXmlPatch.js +222 -115
  69. package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
  70. package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
  71. package/dist/docx/serializer/paragraphSerializer.js +47 -42
  72. package/dist/docx/serializer/runSerializer.d.ts +5 -1
  73. package/dist/docx/serializer/runSerializer.js +4 -3
  74. package/dist/docx/serializer/settingsSerializer.js +19 -1
  75. package/dist/docx/settingsParser.js +8 -0
  76. package/dist/docx/shapeAlternateContent.d.ts +25 -0
  77. package/dist/docx/shapeAlternateContent.js +52 -0
  78. package/dist/docx/streamingXmlParser.d.ts +6 -2
  79. package/dist/docx/streamingXmlParser.js +12 -7
  80. package/dist/docx/styleParser.js +34 -8
  81. package/dist/docx/tableParser.d.ts +21 -12
  82. package/dist/docx/tableParser.js +518 -441
  83. package/dist/docx/textBoxParser.d.ts +18 -5
  84. package/dist/docx/textBoxParser.js +12 -6
  85. package/dist/docx/verbatimCapture.d.ts +10 -8
  86. package/dist/docx/verbatimCapture.js +45 -2
  87. package/dist/docx/vmlImageParser.d.ts +15 -13
  88. package/dist/docx/vmlImageParser.js +75 -60
  89. package/dist/docx/vmlPreview.d.ts +3 -3
  90. package/dist/docx/vmlPreview.js +3 -4
  91. package/dist/docx/xmlNamespaceContext.d.ts +9 -0
  92. package/dist/docx/xmlNamespaceContext.js +54 -0
  93. package/dist/docx/xmlParser.d.ts +6 -3
  94. package/dist/docx/xmlParser.js +11 -41
  95. package/dist/docx/xmlResourceLimits.d.ts +2 -1
  96. package/dist/docx/xmlResourceLimits.js +4 -1
  97. package/dist/fonts/headlessMeasure.js +0 -0
  98. package/dist/headless-layout.d.ts +11 -2
  99. package/dist/headless-layout.js +153 -107
  100. package/dist/internal/headlessRevisionResolution.js +50 -13
  101. package/dist/internal/paragraphFormattingSerialization.js +3 -3
  102. package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
  103. package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
  104. package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
  105. package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
  106. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
  107. package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
  108. package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
  109. package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
  110. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
  111. package/dist/layout-bridge/convert/toFlowBlocks.js +284 -39
  112. package/dist/layout-bridge/engine/hitTest.js +5 -3
  113. package/dist/layout-bridge/engine/selectionRects.js +5 -3
  114. package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
  115. package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
  116. package/dist/layout-engine/index.d.ts +2 -2
  117. package/dist/layout-engine/index.js +102 -14
  118. package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
  119. package/dist/layout-engine/justificationCompatibility.js +9 -5
  120. package/dist/layout-engine/keep-together.d.ts +15 -6
  121. package/dist/layout-engine/keep-together.js +43 -16
  122. package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
  123. package/dist/layout-engine/layoutInstrumentation.js +8 -1
  124. package/dist/layout-engine/measure/advanceComposition.js +50 -7
  125. package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
  126. package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
  127. package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
  128. package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
  129. package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
  130. package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
  131. package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
  132. package/dist/layout-engine/measure/lineBreaks.js +10 -3
  133. package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
  134. package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
  135. package/dist/layout-engine/measure/measureBlocks.js +46 -10
  136. package/dist/layout-engine/measure/measureContainer.js +51 -8
  137. package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
  138. package/dist/layout-engine/measure/measureHelpers.js +34 -8
  139. package/dist/layout-engine/measure/measureParagraph.js +143 -101
  140. package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
  141. package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
  142. package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
  143. package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
  144. package/dist/layout-engine/measure/tabCalculator.js +2 -1
  145. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  146. package/dist/layout-engine/measure/tableCellFloating.js +51 -19
  147. package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
  148. package/dist/layout-engine/measure/tableCellGrid.js +45 -5
  149. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  150. package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
  151. package/dist/layout-engine/noteAreaFlow.js +83 -0
  152. package/dist/layout-engine/paginator.d.ts +12 -1
  153. package/dist/layout-engine/paginator.js +18 -2
  154. package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
  155. package/dist/layout-engine/paragraphSpacing.js +2 -1
  156. package/dist/layout-engine/tableRowBreak.d.ts +8 -1
  157. package/dist/layout-engine/tableRowBreak.js +25 -2
  158. package/dist/layout-engine/types.d.ts +108 -3
  159. package/dist/layout-engine/types.js +96 -1
  160. package/dist/layout-painter/index.d.ts +3 -0
  161. package/dist/layout-painter/renderPage.js +32 -83
  162. package/dist/layout-painter/renderParagraph.d.ts +6 -1
  163. package/dist/layout-painter/renderParagraph.js +75 -26
  164. package/dist/layout-painter/renderTable.js +26 -13
  165. package/dist/layout-painter/renderTextBox.d.ts +12 -2
  166. package/dist/layout-painter/renderTextBox.js +26 -2
  167. package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
  168. package/dist/prosemirror/alternateContentAttrs.js +35 -0
  169. package/dist/prosemirror/attrs/index.d.ts +9 -9
  170. package/dist/prosemirror/attrs/index.js +133 -11
  171. package/dist/prosemirror/commands/comments.js +51 -41
  172. package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
  173. package/dist/prosemirror/contentControlRevisions.js +84 -0
  174. package/dist/prosemirror/conversion/fromProseDoc.js +54 -23
  175. package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
  176. package/dist/prosemirror/conversion/markInterner.js +90 -0
  177. package/dist/prosemirror/conversion/toProseDoc.js +117 -58
  178. package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
  179. package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
  180. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
  181. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
  182. package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
  183. package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
  184. package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
  185. package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
  186. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
  187. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
  188. package/dist/prosemirror/listMarker.d.ts +1 -0
  189. package/dist/prosemirror/listMarker.js +4 -2
  190. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  191. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  192. package/dist/prosemirror/paragraphDirection.d.ts +29 -2
  193. package/dist/prosemirror/paragraphDirection.js +21 -2
  194. package/dist/prosemirror/plugins/suggestionMode.js +37 -8
  195. package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
  196. package/dist/prosemirror/rejoinRunCarriers.js +66 -0
  197. package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
  198. package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
  199. package/dist/prosemirror/schema/nodes.d.ts +50 -6
  200. package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
  201. package/dist/prosemirror/textBoxHostParagraph.js +21 -0
  202. package/dist/prosemirror/validation.js +91 -80
  203. package/dist/types/content.d.ts +2 -2
  204. package/dist/utils/createDocument.js +10 -1
  205. package/dist/utils/scriptSegments.d.ts +33 -4
  206. package/dist/utils/scriptSegments.js +39 -6
  207. package/dist/utils/textFormattingMerge.d.ts +17 -3
  208. package/dist/utils/textFormattingMerge.js +18 -12
  209. package/dist/utils/trailingText.d.ts +22 -0
  210. package/dist/utils/trailingText.js +32 -0
  211. package/package.json +2 -2
  212. package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
  213. package/dist/layout-engine/justifiedLineFit.js +0 -6
@@ -1,10 +1,10 @@
1
1
  import { isValidHexId } from "../utils/hexId.js";
2
2
  import { attributeRemainder } from "./attributeRemainder.js";
3
3
  import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBookmarkStart$1 } from "./bookmarkParser.js";
4
- import { CAPTURE, dispatchChildren, ownedElsewhere, transitionalNamespaceOf, withPreservedChildren } from "./containerChildren.js";
4
+ import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, transitionalNamespaceOf, withPreservedChildren } from "./containerChildren.js";
5
5
  import { parseFieldType } from "./fieldParser.js";
6
6
  import { fieldStateOf, parseFieldState } from "./fieldState.js";
7
- import { hyperlinkChildHandlers, parseHyperlink as parseHyperlink$1 } from "./hyperlinkParser.js";
7
+ import { HYPERLINK_CHILD_HANDLERS, parseHyperlink as parseHyperlink$1, parseHyperlinkShell } from "./hyperlinkParser.js";
8
8
  import { isHyperlinkContent, isInlineSdtContent, isTrackedChangeWrapperChild } from "./inlineWrapperContent.js";
9
9
  import { inlineWrapperOf } from "./inlineWrapperParser.js";
10
10
  import { parseMarkupRangeMarker, parseMoveBookmarkMarker } from "./markupRangeMarker.js";
@@ -15,6 +15,7 @@ import { paraIdInRange } from "./paraIdRangeNormalization.js";
15
15
  import { parseParagraphProperties } from "./paragraphProperties.js";
16
16
  import { assignParagraphPropertySource } from "./paragraphPropertySource.js";
17
17
  import { preserveInlineChild, preserveRunChild, preservedInlineCapture } from "./preservedRunContent.js";
18
+ import { standalonePreviewLedger } from "./previewBudget.js";
18
19
  import { consolidateParagraphContent } from "./runConsolidator.js";
19
20
  import { parseRun } from "./runParser.js";
20
21
  import { runHoldsPayload } from "./runPayload.js";
@@ -303,8 +304,8 @@ function pushInlineSdtSegments({ contents, properties, parsedContent }) {
303
304
  *
304
305
  * Delegates to hyperlinkParser module which resolves URLs via relationships.
305
306
  */
306
- function parseHyperlink(node, rels, styles, theme, media, rootXmlns = {}) {
307
- return parseHyperlink$1(node, rels, styles, theme, media, rootXmlns);
307
+ function parseHyperlink(node, rels, styles, theme, media, rootXmlns, previews) {
308
+ return parseHyperlink$1(node, rels, styles, theme, media, rootXmlns, previews);
308
309
  }
309
310
  /**
310
311
  * The four `CT_RunTrackChange` wrappers a `w:hyperlink` may hold.
@@ -342,6 +343,39 @@ const mathContentOf = (child) => {
342
343
  if (plainText) equation.plainText = plainText;
343
344
  return equation;
344
345
  };
346
+ const hoistRevision = (wrapper) => (child, { styles, theme, rels, media, previews, inScopeXmlns, items, linkOver }) => {
347
+ const wrapped = parseParagraphContents(child, styles, theme, null, rels, media, previews, wrapper === "deletion" || wrapper === "moveFrom" ? "deletion" : "default", inScopeXmlns);
348
+ const content = [];
349
+ let linked = [];
350
+ const flushLinked = () => {
351
+ if (linked.length > 0) {
352
+ content.push(linkOver(linked));
353
+ linked = [];
354
+ }
355
+ };
356
+ for (const item of wrapped) {
357
+ if (isHyperlinkContent(item)) {
358
+ linked.push(item);
359
+ continue;
360
+ }
361
+ flushLinked();
362
+ if (isTrackedChangeWrapperChild(item)) content.push(item);
363
+ }
364
+ flushLinked();
365
+ items.push({
366
+ type: "hoistedRevision",
367
+ wrapper,
368
+ info: parseTrackedChangeInfo(child),
369
+ content
370
+ });
371
+ };
372
+ const HYPERLINK_REVISION_HOISTING_HANDLERS = {
373
+ ...HYPERLINK_CHILD_HANDLERS,
374
+ ins: hoistRevision("insertion"),
375
+ del: hoistRevision("deletion"),
376
+ moveFrom: hoistRevision("moveFrom"),
377
+ moveTo: hoistRevision("moveTo")
378
+ };
345
379
  /**
346
380
  * A `w:hyperlink` as paragraph content, with any revision wrapper it holds
347
381
  * hoisted around it.
@@ -351,60 +385,32 @@ const mathContentOf = (child) => {
351
385
  * reads and a link that is half deleted is two links to it. This is the exact
352
386
  * inverse of what the serializer writes, so a package survives the round trip.
353
387
  */
354
- function parseHyperlinkParagraphContents(node, rels, styles, theme, media, rootXmlns) {
355
- if (!getChildElements(node).some((child) => HYPERLINK_REVISION_WRAPPERS.has(getLocalName(child.name)))) return [parseHyperlink(node, rels, styles, theme, media, rootXmlns)];
388
+ function parseHyperlinkParagraphContents(node, rels, styles, theme, media, rootXmlns, previews) {
389
+ if (!getChildElements(node).some((child) => HYPERLINK_REVISION_WRAPPERS.has(getLocalName(child.name)))) return [parseHyperlink(node, rels, styles, theme, media, rootXmlns, previews)];
356
390
  const inScopeXmlns = mergeXmlnsDeclarations(rootXmlns, node);
357
- const shell = parseHyperlink(node, rels, styles, theme, media, rootXmlns);
391
+ const shell = parseHyperlinkShell(node, rels);
358
392
  const linkOver = (linkChildren) => ({
359
393
  ...shell,
360
394
  children: [...linkChildren]
361
395
  });
362
396
  const items = [];
363
- const hoistRevision = (wrapper) => (child) => {
364
- const wrapped = parseParagraphContents(child, styles, theme, null, rels, media, wrapper === "deletion" || wrapper === "moveFrom" ? "deletion" : "default", inScopeXmlns);
365
- const content = [];
366
- let linked = [];
367
- const flushLinked = () => {
368
- if (linked.length > 0) {
369
- content.push(linkOver(linked));
370
- linked = [];
371
- }
372
- };
373
- for (const item of wrapped) {
374
- if (isHyperlinkContent(item)) {
375
- linked.push(item);
376
- continue;
377
- }
378
- flushLinked();
379
- if (isTrackedChangeWrapperChild(item)) content.push(item);
380
- }
381
- flushLinked();
382
- items.push({
383
- type: "hoistedRevision",
384
- wrapper,
385
- info: parseTrackedChangeInfo(child),
386
- content
387
- });
388
- };
389
- const preserved = dispatchChildren({
397
+ const preserved = dispatchChildrenWithContext({
390
398
  element: node,
391
399
  container: "w:hyperlink",
392
400
  capturePosition: () => items.length,
393
- handlers: {
394
- ...hyperlinkChildHandlers({
395
- push: (child) => {
396
- items.push(child);
397
- },
398
- styles,
399
- theme,
400
- rels,
401
- media,
402
- inScopeXmlns
403
- }),
404
- ins: hoistRevision("insertion"),
405
- del: hoistRevision("deletion"),
406
- moveFrom: hoistRevision("moveFrom"),
407
- moveTo: hoistRevision("moveTo")
401
+ handlers: HYPERLINK_REVISION_HOISTING_HANDLERS,
402
+ context: {
403
+ push: (child) => {
404
+ items.push(child);
405
+ },
406
+ styles,
407
+ theme,
408
+ rels,
409
+ media,
410
+ previews,
411
+ inScopeXmlns,
412
+ items,
413
+ linkOver
408
414
  }
409
415
  });
410
416
  const contents = [];
@@ -449,7 +455,7 @@ function parseBookmarkEnd(node) {
449
455
  /**
450
456
  * Parse simple field (w:fldSimple)
451
457
  */
452
- function parseSimpleField(node, styles, theme, rels, media, rootXmlns = {}) {
458
+ function parseSimpleField(node, styles, theme, rels, media, rootXmlns, previews) {
453
459
  const instruction = getAttribute(node, "w", "instr") ?? "";
454
460
  const field = {
455
461
  type: "simpleField",
@@ -460,11 +466,12 @@ function parseSimpleField(node, styles, theme, rels, media, rootXmlns = {}) {
460
466
  };
461
467
  const inScopeXmlns = mergeXmlnsDeclarations(rootXmlns, node);
462
468
  const content = [];
463
- field.content = withPreservedChildren(content, dispatchChildren({
469
+ field.content = withPreservedChildren(content, dispatchChildrenWithContext({
464
470
  element: node,
465
471
  container: "w:fldSimple",
466
472
  capturePosition: () => content.length,
467
- handlers: simpleFieldChildHandlers({
473
+ handlers: SIMPLE_FIELD_CHILD_HANDLERS,
474
+ context: {
468
475
  push: (child) => {
469
476
  content.push(child);
470
477
  },
@@ -472,11 +479,16 @@ function parseSimpleField(node, styles, theme, rels, media, rootXmlns = {}) {
472
479
  theme,
473
480
  rels,
474
481
  media,
482
+ previews,
475
483
  inScopeXmlns
476
- })
484
+ }
477
485
  }), preservedInlineCapture);
478
486
  return field;
479
487
  }
488
+ /** A transparent wrapper the field holds, read as the wrapper it is. */
489
+ const fieldInlineWrapper = (element) => (child, context) => {
490
+ context.push(parseFieldInlineWrapper(element, child, context));
491
+ };
480
492
  /**
481
493
  * What a `w:fldSimple` does with every child its content model declares.
482
494
  *
@@ -485,52 +497,46 @@ function parseSimpleField(node, styles, theme, rels, media, rootXmlns = {}) {
485
497
  * `CT_BdoContentRun` and its three siblings are the same `EG_PContent` the
486
498
  * field is, so the decision per child is the field's own.
487
499
  */
488
- const simpleFieldChildHandlers = (context) => {
489
- const { push, styles, theme, rels, media, inScopeXmlns } = context;
490
- const wrapper = (element) => (child) => {
491
- push(parseFieldInlineWrapper(element, child, context));
492
- };
493
- return {
494
- r: (child) => {
495
- push(parseRun(child, styles, theme, rels, media, inScopeXmlns));
496
- },
497
- hyperlink: (child) => {
498
- push(parseHyperlink(child, rels, styles, theme, media, inScopeXmlns));
499
- },
500
- bdo: wrapper("bdo"),
501
- dir: wrapper("dir"),
502
- customXml: wrapper("customXml"),
503
- smartTag: wrapper("smartTag"),
504
- bookmarkEnd: CAPTURE,
505
- bookmarkStart: CAPTURE,
506
- commentRangeEnd: CAPTURE,
507
- commentRangeStart: CAPTURE,
508
- customXmlDelRangeEnd: CAPTURE,
509
- customXmlDelRangeStart: CAPTURE,
510
- customXmlInsRangeEnd: CAPTURE,
511
- customXmlInsRangeStart: CAPTURE,
512
- customXmlMoveFromRangeEnd: CAPTURE,
513
- customXmlMoveFromRangeStart: CAPTURE,
514
- customXmlMoveToRangeEnd: CAPTURE,
515
- customXmlMoveToRangeStart: CAPTURE,
516
- del: CAPTURE,
517
- fldData: CAPTURE,
518
- fldSimple: (child) => {
519
- push(preserveInlineChild(child));
520
- },
521
- ins: CAPTURE,
522
- moveFrom: CAPTURE,
523
- moveFromRangeEnd: CAPTURE,
524
- moveFromRangeStart: CAPTURE,
525
- moveTo: CAPTURE,
526
- moveToRangeEnd: CAPTURE,
527
- moveToRangeStart: CAPTURE,
528
- permEnd: CAPTURE,
529
- permStart: CAPTURE,
530
- proofErr: CAPTURE,
531
- sdt: CAPTURE,
532
- subDoc: CAPTURE
533
- };
500
+ const SIMPLE_FIELD_CHILD_HANDLERS = {
501
+ r: (child, { push, styles, theme, rels, media, previews, inScopeXmlns }) => {
502
+ push(parseRun(child, styles, theme, rels, media, inScopeXmlns, previews));
503
+ },
504
+ hyperlink: (child, { push, styles, theme, rels, media, previews, inScopeXmlns }) => {
505
+ push(parseHyperlink(child, rels, styles, theme, media, inScopeXmlns, previews));
506
+ },
507
+ bdo: fieldInlineWrapper("bdo"),
508
+ dir: fieldInlineWrapper("dir"),
509
+ customXml: fieldInlineWrapper("customXml"),
510
+ smartTag: fieldInlineWrapper("smartTag"),
511
+ bookmarkEnd: CAPTURE,
512
+ bookmarkStart: CAPTURE,
513
+ commentRangeEnd: CAPTURE,
514
+ commentRangeStart: CAPTURE,
515
+ customXmlDelRangeEnd: CAPTURE,
516
+ customXmlDelRangeStart: CAPTURE,
517
+ customXmlInsRangeEnd: CAPTURE,
518
+ customXmlInsRangeStart: CAPTURE,
519
+ customXmlMoveFromRangeEnd: CAPTURE,
520
+ customXmlMoveFromRangeStart: CAPTURE,
521
+ customXmlMoveToRangeEnd: CAPTURE,
522
+ customXmlMoveToRangeStart: CAPTURE,
523
+ del: CAPTURE,
524
+ fldData: CAPTURE,
525
+ fldSimple: (child, { push }) => {
526
+ push(preserveInlineChild(child));
527
+ },
528
+ ins: CAPTURE,
529
+ moveFrom: CAPTURE,
530
+ moveFromRangeEnd: CAPTURE,
531
+ moveFromRangeStart: CAPTURE,
532
+ moveTo: CAPTURE,
533
+ moveToRangeEnd: CAPTURE,
534
+ moveToRangeStart: CAPTURE,
535
+ permEnd: CAPTURE,
536
+ permStart: CAPTURE,
537
+ proofErr: CAPTURE,
538
+ sdt: CAPTURE,
539
+ subDoc: CAPTURE
534
540
  };
535
541
  /**
536
542
  * A transparent wrapper a simple field holds, with the content the field holds.
@@ -543,21 +549,17 @@ const simpleFieldChildHandlers = (context) => {
543
549
  const parseFieldInlineWrapper = (element, node, context) => {
544
550
  const inScopeXmlns = mergeXmlnsDeclarations(context.inScopeXmlns, node);
545
551
  const content = [];
546
- return inlineWrapperOf(element, node, withPreservedChildren(content, dispatchChildren({
552
+ return inlineWrapperOf(element, node, withPreservedChildren(content, dispatchChildrenWithContext({
547
553
  element: node,
548
554
  container: "run-level-content",
549
555
  capturePosition: () => content.length,
550
- handlers: {
551
- ...simpleFieldChildHandlers({
552
- ...context,
553
- inScopeXmlns,
554
- push: (child) => {
555
- content.push(child);
556
- }
557
- }),
558
- customXmlPr: CUSTOM_XML_PROPERTIES_OWNER,
559
- smartTagPr: SMART_TAG_PROPERTIES_OWNER,
560
- pPr: CAPTURE
556
+ handlers: FIELD_INLINE_WRAPPER_HANDLERS,
557
+ context: {
558
+ ...context,
559
+ inScopeXmlns,
560
+ push: (child) => {
561
+ content.push(child);
562
+ }
561
563
  }
562
564
  }), preservedInlineCapture));
563
565
  };
@@ -666,267 +668,368 @@ const CUSTOM_XML_PROPERTIES_OWNER = ownedElsewhere({
666
668
  child: "customXmlPr",
667
669
  reader: "inlineWrapperParser#inlineWrapperOf"
668
670
  });
671
+ /** The field's own map over a transparent wrapper it holds; see `parseFieldInlineWrapper`. */
672
+ const FIELD_INLINE_WRAPPER_HANDLERS = {
673
+ ...SIMPLE_FIELD_CHILD_HANDLERS,
674
+ customXmlPr: CUSTOM_XML_PROPERTIES_OWNER,
675
+ smartTagPr: SMART_TAG_PROPERTIES_OWNER,
676
+ pPr: CAPTURE
677
+ };
678
+ /**
679
+ * The container children a complex field's result may hold and still be
680
+ * assembled into a `ComplexField`: its runs and the zero-width markers read
681
+ * beside them. Any other child is inline content (a hyperlink, a simple field,
682
+ * a content control, a revision, a wrapper, an equation) that `fieldResult`
683
+ * has no place for.
684
+ */
685
+ const FIELD_TRANSPARENT_CHILDREN = /* @__PURE__ */ new Set([
686
+ "r",
687
+ "pPr",
688
+ "smartTagPr",
689
+ "customXmlPr",
690
+ "bookmarkStart",
691
+ "bookmarkEnd",
692
+ "commentRangeStart",
693
+ "commentRangeEnd",
694
+ "moveFromRangeStart",
695
+ "moveFromRangeEnd",
696
+ "moveToRangeStart",
697
+ "moveToRangeEnd",
698
+ "proofErr",
699
+ "permStart",
700
+ "permEnd",
701
+ "customXmlDelRangeStart",
702
+ "customXmlDelRangeEnd",
703
+ "customXmlInsRangeStart",
704
+ "customXmlInsRangeEnd",
705
+ "customXmlMoveFromRangeStart",
706
+ "customXmlMoveFromRangeEnd",
707
+ "customXmlMoveToRangeStart",
708
+ "customXmlMoveToRangeEnd"
709
+ ]);
710
+ const isWordprocessingChild = (child) => {
711
+ const namespace = getNamespaceUri(child);
712
+ return namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace);
713
+ };
714
+ /**
715
+ * The `w:r` children whose `begin` opens a complex field that this container's
716
+ * walk closes.
717
+ *
718
+ * A field is assembled from the runs between its `begin` and its `end`, so it
719
+ * exists only when both are runs of this container with nothing between them
720
+ * that a `ComplexField` cannot hold. A TOC opened here and closed in a later
721
+ * paragraph, a field whose result holds a `w:hyperlink` (a TOC's `\h` entries),
722
+ * and an outer field whose result holds a nested field are none of these; their
723
+ * runs are ordinary content, read in source order alongside the siblings
724
+ * between them. Mirrors the `w:r` handler run by run: a run with a `begin`
725
+ * opens a field, and a run with an `end` closes the one open.
726
+ */
727
+ const assembledFieldBeginsOf = (container) => {
728
+ const assembled = /* @__PURE__ */ new Set();
729
+ let open;
730
+ for (const child of getChildElements(container)) {
731
+ const wordprocessing = isWordprocessingChild(child);
732
+ const localName = getLocalName(child.name);
733
+ if (!wordprocessing || localName !== "r") {
734
+ if (!wordprocessing || !FIELD_TRANSPARENT_CHILDREN.has(localName)) open = void 0;
735
+ continue;
736
+ }
737
+ let hasBegin = false;
738
+ let hasEnd = false;
739
+ for (const runChild of getChildElements(child)) {
740
+ if (getLocalName(runChild.name) !== "fldChar" || !isWordprocessingChild(runChild)) continue;
741
+ const charType = getAttribute(runChild, "w", "fldCharType");
742
+ if (charType === "end") hasEnd = true;
743
+ else if (charType !== "separate") hasBegin = true;
744
+ }
745
+ if (hasBegin) open = child;
746
+ if (hasEnd && open !== void 0) {
747
+ assembled.add(open);
748
+ open = void 0;
749
+ }
750
+ }
751
+ return assembled;
752
+ };
753
+ /**
754
+ * A transparent wrapper at paragraph level. All four hold ordinary inline
755
+ * content and say something about it rather than about the text, so the
756
+ * recursion is this same walk and `inlineWrapperOf` reads what the element
757
+ * adds.
758
+ */
759
+ const paragraphInlineWrapper = (element) => (child, { styles, theme, rels, media, previews, trackedContext, inScopeXmlns, contents }) => {
760
+ contents.push(inlineWrapperOf(element, child, parseParagraphContents(child, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child))));
761
+ };
762
+ const PARAGRAPH_CONTENT_UNDECLARED = { AlternateContent: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns }) => {
763
+ const selectedBranch = selectAlternateContentBranch(child);
764
+ if (selectedBranch) contents.push(...parseParagraphContents(selectedBranch, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child)));
765
+ } };
766
+ const PARAGRAPH_CONTENT_UNDECLARED_NAMESPACES = { [OMML_NAMESPACE]: (child, { contents }) => {
767
+ const equation = mathContentOf(child);
768
+ if (equation !== void 0) contents.push(equation);
769
+ } };
770
+ const PARAGRAPH_CONTENT_HANDLERS = {
771
+ r: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns, scan }) => {
772
+ const runElement = trackedContext === "deletion" ? normalizeDeletionContentElement(child) : child;
773
+ const run = parseRun(runElement, styles, theme, rels, media, inScopeXmlns, previews);
774
+ const commentReferenceId = getCommentReferenceId(runElement);
775
+ let hasFieldBegin = false;
776
+ let beginFieldState = {};
777
+ const beginFallbackDisplay = getLegacyFormCheckboxDisplay(runElement);
778
+ let hasFieldSeparate = false;
779
+ let hasFieldEnd = false;
780
+ let endOriginalValue;
781
+ let instrText = "";
782
+ for (const content of run.content) if (content.type === "fieldChar") if (content.charType === "begin") {
783
+ hasFieldBegin = true;
784
+ beginFieldState = fieldStateOf(content);
785
+ } else if (content.charType === "separate") hasFieldSeparate = true;
786
+ else {
787
+ hasFieldEnd = true;
788
+ if (content.originalValue !== void 0) endOriginalValue = content.originalValue;
789
+ }
790
+ else if (content.type === "instrText") instrText += content.text;
791
+ if (hasFieldBegin) {
792
+ scan.assembledFieldBegins ??= assembledFieldBeginsOf(scan.container);
793
+ if (!scan.assembledFieldBegins.has(child)) hasFieldBegin = false;
794
+ }
795
+ if (hasFieldBegin) {
796
+ if (scan.inComplexField) {
797
+ contents.push(...scan.complexFieldOpenRuns);
798
+ scan.inComplexField = false;
799
+ }
800
+ scan.inComplexField = true;
801
+ scan.afterSeparator = false;
802
+ scan.complexFieldInstr = "";
803
+ scan.complexFieldCodeRuns = [];
804
+ scan.complexFieldResultRuns = [];
805
+ scan.complexFieldOpenRuns = [];
806
+ scan.complexFieldState = beginFieldState;
807
+ scan.complexFieldFallbackDisplay = beginFallbackDisplay;
808
+ scan.complexFieldFormatting = run.formatting;
809
+ }
810
+ if (scan.inComplexField) {
811
+ scan.complexFieldOpenRuns.push(withOrphanFieldCharsPreserved(run, runElement));
812
+ if (instrText) scan.complexFieldInstr += instrText;
813
+ if ((!scan.complexFieldFormatting || Object.keys(scan.complexFieldFormatting).length === 0) && run.formatting && Object.keys(run.formatting).length > 0) scan.complexFieldFormatting = run.formatting;
814
+ let inFieldCodeRegion = !hasFieldBegin && !scan.afterSeparator;
815
+ const fieldCodeContent = [];
816
+ for (const content of run.content) {
817
+ if (content.type === "fieldChar") {
818
+ inFieldCodeRegion = content.charType === "begin";
819
+ continue;
820
+ }
821
+ if (inFieldCodeRegion) fieldCodeContent.push(content);
822
+ }
823
+ if (fieldCodeContent.length > 0) scan.complexFieldCodeRuns.push(fieldCodeContent.length === run.content.length ? run : {
824
+ ...run,
825
+ content: fieldCodeContent
826
+ });
827
+ if (hasFieldSeparate) scan.afterSeparator = true;
828
+ if (scan.afterSeparator && !hasFieldEnd) {
829
+ if (!hasFieldSeparate) scan.complexFieldResultRuns.push(run);
830
+ }
831
+ if (hasFieldEnd) {
832
+ let resultRuns = scan.complexFieldResultRuns;
833
+ let resultIsFallback = false;
834
+ if (resultRuns.length === 0 && scan.complexFieldFallbackDisplay !== void 0 && isLegacyFormCheckboxInstruction(scan.complexFieldInstr)) {
835
+ resultRuns = [createLegacyFormCheckboxResultRun(scan.complexFieldFallbackDisplay, scan.complexFieldFormatting)];
836
+ resultIsFallback = true;
837
+ }
838
+ if (resultRuns.length === 0 && !scan.afterSeparator && endOriginalValue !== void 0) resultRuns = [{
839
+ type: "run",
840
+ content: [{
841
+ type: "text",
842
+ text: endOriginalValue
843
+ }]
844
+ }];
845
+ const complexField = {
846
+ type: "complexField",
847
+ instruction: scan.complexFieldInstr,
848
+ fieldType: parseFieldType(scan.complexFieldInstr),
849
+ fieldCode: scan.complexFieldCodeRuns,
850
+ fieldResult: resultRuns,
851
+ ...scan.complexFieldState
852
+ };
853
+ if (resultIsFallback) complexField.fieldResultIsFallback = true;
854
+ if (scan.complexFieldFormatting) complexField.formatting = scan.complexFieldFormatting;
855
+ contents.push(complexField);
856
+ if (commentReferenceId !== null) contents.push({
857
+ type: "commentReference",
858
+ id: commentReferenceId
859
+ });
860
+ scan.inComplexField = false;
861
+ }
862
+ } else if (commentReferenceId !== null) {
863
+ if (runHoldsPayload(run)) contents.push(withOrphanFieldCharsPreserved(run, runElement));
864
+ contents.push({
865
+ type: "commentReference",
866
+ id: commentReferenceId
867
+ });
868
+ } else if (hasRunPayload({
869
+ run,
870
+ runElement,
871
+ rels,
872
+ media
873
+ })) contents.push(withOrphanFieldCharsPreserved(run, runElement));
874
+ },
875
+ hyperlink: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
876
+ contents.push(...parseHyperlinkParagraphContents(child, rels, styles, theme, media, inScopeXmlns, previews));
877
+ },
878
+ bookmarkStart: (child, { contents }) => {
879
+ contents.push(parseBookmarkStart(child));
880
+ },
881
+ bookmarkEnd: (child, { contents }) => {
882
+ contents.push(parseBookmarkEnd(child));
883
+ },
884
+ fldSimple: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
885
+ contents.push(parseSimpleField(child, styles, theme, rels, media, inScopeXmlns, previews));
886
+ },
887
+ pPr: PARAGRAPH_PROPERTIES_OWNER,
888
+ customXml: paragraphInlineWrapper("customXml"),
889
+ proofErr: CAPTURE,
890
+ permStart: CAPTURE,
891
+ permEnd: CAPTURE,
892
+ subDoc: CAPTURE,
893
+ customXmlDelRangeEnd: CAPTURE,
894
+ customXmlDelRangeStart: CAPTURE,
895
+ customXmlInsRangeEnd: CAPTURE,
896
+ customXmlInsRangeStart: CAPTURE,
897
+ customXmlMoveFromRangeEnd: CAPTURE,
898
+ customXmlMoveFromRangeStart: CAPTURE,
899
+ customXmlMoveToRangeEnd: CAPTURE,
900
+ customXmlMoveToRangeStart: CAPTURE,
901
+ smartTagPr: SMART_TAG_PROPERTIES_OWNER,
902
+ customXmlPr: CUSTOM_XML_PROPERTIES_OWNER,
903
+ sdt: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns }) => {
904
+ const sdtPr = findWordprocessingChild(child, "sdtPr");
905
+ const sdtEndPr = findWordprocessingChild(child, "sdtEndPr");
906
+ const sdtContentEl = findWordprocessingChild(child, "sdtContent");
907
+ if (sdtContentEl) {
908
+ const sdtParsed = parseParagraphContents(sdtContentEl, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child));
909
+ const properties = parseSdtProperties(sdtPr, sdtEndPr);
910
+ const captured = captureSdtSiblingMarkers(child);
911
+ if (captured.before.length > 0) properties.rawSdtChildrenBeforeContent = captured.before;
912
+ if (captured.after.length > 0) properties.rawSdtChildrenAfterContent = captured.after;
913
+ pushInlineSdtSegments({
914
+ contents,
915
+ properties,
916
+ parsedContent: sdtParsed
917
+ });
918
+ }
919
+ },
920
+ ins: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
921
+ pushTrackedChangeSegments({
922
+ contents,
923
+ type: "insertion",
924
+ info: parseTrackedChangeInfo(child),
925
+ parsedContent: parseParagraphContents(child, styles, theme, null, rels, media, previews, "default", inScopeXmlns)
926
+ });
927
+ },
928
+ del: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
929
+ pushTrackedChangeSegments({
930
+ contents,
931
+ type: "deletion",
932
+ info: parseTrackedChangeInfo(child),
933
+ parsedContent: parseParagraphContents(child, styles, theme, null, rels, media, previews, "deletion", inScopeXmlns)
934
+ });
935
+ },
936
+ moveFrom: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
937
+ pushTrackedChangeSegments({
938
+ contents,
939
+ type: "moveFrom",
940
+ info: parseTrackedChangeInfo(child),
941
+ parsedContent: parseParagraphContents(child, styles, theme, null, rels, media, previews, "deletion", inScopeXmlns)
942
+ });
943
+ },
944
+ moveTo: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
945
+ pushTrackedChangeSegments({
946
+ contents,
947
+ type: "moveTo",
948
+ info: parseTrackedChangeInfo(child),
949
+ parsedContent: parseParagraphContents(child, styles, theme, null, rels, media, previews, "default", inScopeXmlns)
950
+ });
951
+ },
952
+ smartTag: paragraphInlineWrapper("smartTag"),
953
+ moveFromRangeStart: (child, { contents }) => {
954
+ contents.push({
955
+ type: "moveFromRangeStart",
956
+ ...parseMoveBookmarkMarker(child)
957
+ });
958
+ },
959
+ moveFromRangeEnd: (child, { contents }) => {
960
+ contents.push({
961
+ type: "moveFromRangeEnd",
962
+ ...parseMarkupRangeMarker(child)
963
+ });
964
+ },
965
+ moveToRangeStart: (child, { contents }) => {
966
+ contents.push({
967
+ type: "moveToRangeStart",
968
+ ...parseMoveBookmarkMarker(child)
969
+ });
970
+ },
971
+ moveToRangeEnd: (child, { contents }) => {
972
+ contents.push({
973
+ type: "moveToRangeEnd",
974
+ ...parseMarkupRangeMarker(child)
975
+ });
976
+ },
977
+ commentRangeStart: (child, { contents }) => {
978
+ contents.push({
979
+ type: "commentRangeStart",
980
+ ...parseMarkupRangeMarker(child)
981
+ });
982
+ },
983
+ commentRangeEnd: (child, { contents }) => {
984
+ contents.push({
985
+ type: "commentRangeEnd",
986
+ ...parseMarkupRangeMarker(child)
987
+ });
988
+ },
989
+ bdo: paragraphInlineWrapper("bdo"),
990
+ dir: paragraphInlineWrapper("dir")
991
+ };
669
992
  /**
670
993
  * Parse all content within a paragraph
671
994
  *
672
995
  * Returns the parsed content and any complex fields that span multiple runs
673
996
  */
674
- function parseParagraphContents(paraElement, styles, theme, _numbering, rels, media, trackedContext = "default", rootXmlns = {}) {
997
+ function parseParagraphContents(paraElement, styles, theme, _numbering, rels, media, previews, trackedContext = "default", rootXmlns = {}) {
675
998
  const contents = [];
676
999
  const inScopeXmlns = mergeXmlnsDeclarations(rootXmlns, paraElement);
677
- let inComplexField = false;
678
- let complexFieldInstr = "";
679
- let complexFieldCodeRuns = [];
680
- let complexFieldResultRuns = [];
681
- let complexFieldOpenRuns = [];
682
- let afterSeparator = false;
683
- let complexFieldState = {};
684
- let complexFieldFallbackDisplay;
685
- let complexFieldFormatting;
686
- const parseInlineWrapper = (child, element) => inlineWrapperOf(element, child, parseParagraphContents(child, styles, theme, null, rels, media, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child)));
687
- const preserved = dispatchChildren({
1000
+ const scan = {
1001
+ inComplexField: false,
1002
+ complexFieldInstr: "",
1003
+ complexFieldCodeRuns: [],
1004
+ complexFieldResultRuns: [],
1005
+ complexFieldOpenRuns: [],
1006
+ afterSeparator: false,
1007
+ complexFieldState: {},
1008
+ complexFieldFallbackDisplay: void 0,
1009
+ complexFieldFormatting: void 0,
1010
+ container: paraElement,
1011
+ assembledFieldBegins: void 0
1012
+ };
1013
+ const preserved = dispatchChildrenWithContext({
688
1014
  element: paraElement,
689
1015
  container: "run-level-content",
690
1016
  capturePosition: () => contents.length,
691
- undeclared: { AlternateContent: (child) => {
692
- const selectedBranch = selectAlternateContentBranch(child);
693
- if (selectedBranch) contents.push(...parseParagraphContents(selectedBranch, styles, theme, null, rels, media, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child)));
694
- } },
695
- undeclaredNamespaces: { [OMML_NAMESPACE]: (child) => {
696
- const equation = mathContentOf(child);
697
- if (equation !== void 0) contents.push(equation);
698
- } },
699
- handlers: {
700
- r: (child) => {
701
- const runElement = trackedContext === "deletion" ? normalizeDeletionContentElement(child) : child;
702
- const run = parseRun(runElement, styles, theme, rels, media, inScopeXmlns);
703
- const commentReferenceId = getCommentReferenceId(runElement);
704
- let hasFieldBegin = false;
705
- let beginFieldState = {};
706
- const beginFallbackDisplay = getLegacyFormCheckboxDisplay(runElement);
707
- let hasFieldSeparate = false;
708
- let hasFieldEnd = false;
709
- let endOriginalValue;
710
- let instrText = "";
711
- for (const content of run.content) if (content.type === "fieldChar") if (content.charType === "begin") {
712
- hasFieldBegin = true;
713
- beginFieldState = fieldStateOf(content);
714
- } else if (content.charType === "separate") hasFieldSeparate = true;
715
- else {
716
- hasFieldEnd = true;
717
- if (content.originalValue !== void 0) endOriginalValue = content.originalValue;
718
- }
719
- else if (content.type === "instrText") instrText += content.text;
720
- if (hasFieldBegin) {
721
- if (inComplexField && afterSeparator) {
722
- contents.push(...complexFieldResultRuns);
723
- inComplexField = false;
724
- }
725
- inComplexField = true;
726
- afterSeparator = false;
727
- complexFieldInstr = "";
728
- complexFieldCodeRuns = [];
729
- complexFieldResultRuns = [];
730
- complexFieldOpenRuns = [];
731
- complexFieldState = beginFieldState;
732
- complexFieldFallbackDisplay = beginFallbackDisplay;
733
- complexFieldFormatting = run.formatting;
734
- }
735
- if (inComplexField) {
736
- complexFieldOpenRuns.push(withOrphanFieldCharsPreserved(run, runElement));
737
- if (instrText) complexFieldInstr += instrText;
738
- if ((!complexFieldFormatting || Object.keys(complexFieldFormatting).length === 0) && run.formatting && Object.keys(run.formatting).length > 0) complexFieldFormatting = run.formatting;
739
- let inFieldCodeRegion = !hasFieldBegin && !afterSeparator;
740
- const fieldCodeContent = [];
741
- for (const content of run.content) {
742
- if (content.type === "fieldChar") {
743
- inFieldCodeRegion = content.charType === "begin";
744
- continue;
745
- }
746
- if (inFieldCodeRegion) fieldCodeContent.push(content);
747
- }
748
- if (fieldCodeContent.length > 0) complexFieldCodeRuns.push(fieldCodeContent.length === run.content.length ? run : {
749
- ...run,
750
- content: fieldCodeContent
751
- });
752
- if (hasFieldSeparate) afterSeparator = true;
753
- if (afterSeparator && !hasFieldEnd) {
754
- if (!hasFieldSeparate) complexFieldResultRuns.push(run);
755
- }
756
- if (hasFieldEnd) {
757
- let resultRuns = complexFieldResultRuns;
758
- if (resultRuns.length === 0 && complexFieldFallbackDisplay !== void 0 && isLegacyFormCheckboxInstruction(complexFieldInstr)) resultRuns = [createLegacyFormCheckboxResultRun(complexFieldFallbackDisplay, complexFieldFormatting)];
759
- if (resultRuns.length === 0 && !afterSeparator && endOriginalValue !== void 0) resultRuns = [{
760
- type: "run",
761
- content: [{
762
- type: "text",
763
- text: endOriginalValue
764
- }]
765
- }];
766
- const complexField = {
767
- type: "complexField",
768
- instruction: complexFieldInstr,
769
- fieldType: parseFieldType(complexFieldInstr),
770
- fieldCode: complexFieldCodeRuns,
771
- fieldResult: resultRuns,
772
- ...complexFieldState
773
- };
774
- if (complexFieldFormatting) complexField.formatting = complexFieldFormatting;
775
- contents.push(complexField);
776
- if (commentReferenceId !== null) contents.push({
777
- type: "commentReference",
778
- id: commentReferenceId
779
- });
780
- inComplexField = false;
781
- }
782
- } else if (commentReferenceId !== null) {
783
- if (runHoldsPayload(run)) contents.push(withOrphanFieldCharsPreserved(run, runElement));
784
- contents.push({
785
- type: "commentReference",
786
- id: commentReferenceId
787
- });
788
- } else if (hasRunPayload({
789
- run,
790
- runElement,
791
- rels,
792
- media
793
- })) contents.push(withOrphanFieldCharsPreserved(run, runElement));
794
- },
795
- hyperlink: (child) => {
796
- contents.push(...parseHyperlinkParagraphContents(child, rels, styles, theme, media, inScopeXmlns));
797
- },
798
- bookmarkStart: (child) => {
799
- contents.push(parseBookmarkStart(child));
800
- },
801
- bookmarkEnd: (child) => {
802
- contents.push(parseBookmarkEnd(child));
803
- },
804
- fldSimple: (child) => {
805
- contents.push(parseSimpleField(child, styles, theme, rels, media, inScopeXmlns));
806
- },
807
- pPr: PARAGRAPH_PROPERTIES_OWNER,
808
- customXml: (child) => {
809
- contents.push(parseInlineWrapper(child, "customXml"));
810
- },
811
- proofErr: CAPTURE,
812
- permStart: CAPTURE,
813
- permEnd: CAPTURE,
814
- subDoc: CAPTURE,
815
- customXmlDelRangeEnd: CAPTURE,
816
- customXmlDelRangeStart: CAPTURE,
817
- customXmlInsRangeEnd: CAPTURE,
818
- customXmlInsRangeStart: CAPTURE,
819
- customXmlMoveFromRangeEnd: CAPTURE,
820
- customXmlMoveFromRangeStart: CAPTURE,
821
- customXmlMoveToRangeEnd: CAPTURE,
822
- customXmlMoveToRangeStart: CAPTURE,
823
- smartTagPr: SMART_TAG_PROPERTIES_OWNER,
824
- customXmlPr: CUSTOM_XML_PROPERTIES_OWNER,
825
- sdt: (child) => {
826
- const sdtPr = findWordprocessingChild(child, "sdtPr");
827
- const sdtEndPr = findWordprocessingChild(child, "sdtEndPr");
828
- const sdtContentEl = findWordprocessingChild(child, "sdtContent");
829
- if (sdtContentEl) {
830
- const sdtParsed = parseParagraphContents(sdtContentEl, styles, theme, null, rels, media, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child));
831
- const properties = parseSdtProperties(sdtPr, sdtEndPr);
832
- const captured = captureSdtSiblingMarkers(child);
833
- if (captured.before.length > 0) properties.rawSdtChildrenBeforeContent = captured.before;
834
- if (captured.after.length > 0) properties.rawSdtChildrenAfterContent = captured.after;
835
- pushInlineSdtSegments({
836
- contents,
837
- properties,
838
- parsedContent: sdtParsed
839
- });
840
- }
841
- },
842
- ins: (child) => {
843
- const insInfo = parseTrackedChangeInfo(child);
844
- const insContent = parseParagraphContents(child, styles, theme, null, rels, media, "default", inScopeXmlns);
845
- pushTrackedChangeSegments({
846
- contents,
847
- type: "insertion",
848
- info: insInfo,
849
- parsedContent: insContent
850
- });
851
- },
852
- del: (child) => {
853
- const delInfo = parseTrackedChangeInfo(child);
854
- const delContent = parseParagraphContents(child, styles, theme, null, rels, media, "deletion", inScopeXmlns);
855
- pushTrackedChangeSegments({
856
- contents,
857
- type: "deletion",
858
- info: delInfo,
859
- parsedContent: delContent
860
- });
861
- },
862
- moveFrom: (child) => {
863
- const moveFromInfo = parseTrackedChangeInfo(child);
864
- const moveFromContent = parseParagraphContents(child, styles, theme, null, rels, media, "deletion", inScopeXmlns);
865
- pushTrackedChangeSegments({
866
- contents,
867
- type: "moveFrom",
868
- info: moveFromInfo,
869
- parsedContent: moveFromContent
870
- });
871
- },
872
- moveTo: (child) => {
873
- const moveToInfo = parseTrackedChangeInfo(child);
874
- const moveToContent = parseParagraphContents(child, styles, theme, null, rels, media, "default", inScopeXmlns);
875
- pushTrackedChangeSegments({
876
- contents,
877
- type: "moveTo",
878
- info: moveToInfo,
879
- parsedContent: moveToContent
880
- });
881
- },
882
- smartTag: (child) => {
883
- contents.push(parseInlineWrapper(child, "smartTag"));
884
- },
885
- moveFromRangeStart: (child) => {
886
- contents.push({
887
- type: "moveFromRangeStart",
888
- ...parseMoveBookmarkMarker(child)
889
- });
890
- },
891
- moveFromRangeEnd: (child) => {
892
- contents.push({
893
- type: "moveFromRangeEnd",
894
- ...parseMarkupRangeMarker(child)
895
- });
896
- },
897
- moveToRangeStart: (child) => {
898
- contents.push({
899
- type: "moveToRangeStart",
900
- ...parseMoveBookmarkMarker(child)
901
- });
902
- },
903
- moveToRangeEnd: (child) => {
904
- contents.push({
905
- type: "moveToRangeEnd",
906
- ...parseMarkupRangeMarker(child)
907
- });
908
- },
909
- commentRangeStart: (child) => {
910
- contents.push({
911
- type: "commentRangeStart",
912
- ...parseMarkupRangeMarker(child)
913
- });
914
- },
915
- commentRangeEnd: (child) => {
916
- contents.push({
917
- type: "commentRangeEnd",
918
- ...parseMarkupRangeMarker(child)
919
- });
920
- },
921
- bdo: (child) => {
922
- contents.push(parseInlineWrapper(child, "bdo"));
923
- },
924
- dir: (child) => {
925
- contents.push(parseInlineWrapper(child, "dir"));
926
- }
1017
+ undeclared: PARAGRAPH_CONTENT_UNDECLARED,
1018
+ undeclaredNamespaces: PARAGRAPH_CONTENT_UNDECLARED_NAMESPACES,
1019
+ handlers: PARAGRAPH_CONTENT_HANDLERS,
1020
+ context: {
1021
+ styles,
1022
+ theme,
1023
+ rels,
1024
+ media,
1025
+ previews,
1026
+ trackedContext,
1027
+ inScopeXmlns,
1028
+ contents,
1029
+ scan
927
1030
  }
928
1031
  });
929
- if (inComplexField) contents.push(...complexFieldOpenRuns);
1032
+ if (scan.inComplexField) contents.push(...scan.complexFieldOpenRuns);
930
1033
  return withPreservedChildren(contents, preserved, preservedInlineCapture);
931
1034
  }
932
1035
  function getCommentReferenceId(runElement) {
@@ -956,7 +1059,8 @@ const PARAGRAPH_ATTRIBUTES = /* @__PURE__ */ new Set([
956
1059
  * @param numbering - Numbering definitions for list info
957
1060
  * @param rels - Relationship map for resolving hyperlink URLs
958
1061
  * @param media - Media files map for image data
959
- * @param options - Parsing options for context-specific body behavior
1062
+ * @param options - Parsing options for context-specific body behavior; a
1063
+ * paragraph read without them charges its previews to no package
960
1064
  * @returns Parsed Paragraph object
961
1065
  */
962
1066
  function parseParagraph(node, styles, theme, numbering, rels = null, media = null, options) {
@@ -986,7 +1090,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
986
1090
  const sectPr = findChild(pPr, "w", "sectPr");
987
1091
  if (sectPr) paragraph.sectionProperties = parseSectionProperties(sectPr);
988
1092
  }
989
- const rawContent = parseParagraphContents(node, styles, theme, numbering, rels, media, "default", options?.rootXmlns ?? {});
1093
+ const rawContent = parseParagraphContents(node, styles, theme, numbering, rels, media, options?.previews ?? standalonePreviewLedger(), "default", options?.rootXmlns ?? {});
990
1094
  paragraph.content = options?.runConsolidation === "deferred" ? rawContent : consolidateParagraphContent(rawContent);
991
1095
  const paragraphFormatting = paragraph.formatting;
992
1096
  const directNumPr = paragraphFormatting?.numPr;
@@ -1033,6 +1137,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
1033
1137
  const markerAlignment = markerAlignmentForLevel(level.lvlJc);
1034
1138
  if (markerAlignment !== void 0) listRendering.markerAlignment = markerAlignment;
1035
1139
  if (level.suffix) listRendering.markerSuffix = level.suffix;
1140
+ if (level.pPr?.tabs?.length) listRendering.levelTabs = level.pPr.tabs;
1036
1141
  let implicitChildLevelAdvances = 0;
1037
1142
  const foldedMarkerSuffix = [];
1038
1143
  const filteredContent = [];
@@ -1077,9 +1182,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
1077
1182
  if (!paragraph.formatting) paragraph.formatting = {};
1078
1183
  const directInd = pPr ? findChild(pPr, "w", "ind") : null;
1079
1184
  const hasDirectLeft = hasAttributeAnySpelling(directInd, "CT_Ind @left");
1080
- const directFirstLine = directInd ? parseNumericAttribute(directInd, "w", "firstLine") : void 0;
1081
- const directHanging = directInd ? parseNumericAttribute(directInd, "w", "hanging") : void 0;
1082
- const hasDirectFirstLineOrHanging = directFirstLine !== void 0 && directFirstLine !== 0 || directHanging !== void 0 && directHanging !== 0;
1185
+ const hasDirectFirstLineOrHanging = parseNumericAttribute(directInd, "w", "firstLine") !== void 0 || parseNumericAttribute(directInd, "w", "hanging") !== void 0;
1083
1186
  if (!hasDirectLeft && !chainInd.left && level.pPr.indentLeft !== void 0) paragraph.formatting.indentLeft = level.pPr.indentLeft;
1084
1187
  if (!hasDirectFirstLineOrHanging && !chainInd.firstLine && numberingLevelHasMarkerSlot(level)) {
1085
1188
  if (level.pPr.indentFirstLine !== void 0) paragraph.formatting.indentFirstLine = level.pPr.indentFirstLine;