@stll/folio-core 0.47.7 → 0.48.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 (160) hide show
  1. package/dist/controller/fontReadiness.js +3 -3
  2. package/dist/controller/hyphenationReadiness.d.ts +19 -0
  3. package/dist/controller/hyphenationReadiness.js +47 -0
  4. package/dist/controller/layoutPipeline.d.ts +3 -0
  5. package/dist/controller/layoutPipeline.js +59 -17
  6. package/dist/display-list/build/buildDisplayList.js +39 -12
  7. package/dist/display-list/build/pageFurniture.d.ts +7 -1
  8. package/dist/display-list/build/pageFurniture.js +21 -8
  9. package/dist/display-list/build/paragraphPrimitives.js +5 -4
  10. package/dist/display-list/build/tablePrimitives.js +10 -6
  11. package/dist/docx/attributeRemainder.js +10 -2
  12. package/dist/docx/blockContentParser.d.ts +2 -0
  13. package/dist/docx/blockContentParser.js +77 -62
  14. package/dist/docx/commentParser.d.ts +2 -1
  15. package/dist/docx/commentParser.js +57 -45
  16. package/dist/docx/containerChildren.d.ts +21 -8
  17. package/dist/docx/containerChildren.js +39 -9
  18. package/dist/docx/documentParser.d.ts +5 -1
  19. package/dist/docx/documentParser.js +8 -5
  20. package/dist/docx/documentSectionFacts.d.ts +22 -0
  21. package/dist/docx/documentSectionFacts.js +43 -0
  22. package/dist/docx/fieldParser.d.ts +8 -1
  23. package/dist/docx/fieldParser.js +47 -3
  24. package/dist/docx/fontTableParser.js +34 -27
  25. package/dist/docx/footnoteParser.d.ts +3 -2
  26. package/dist/docx/footnoteParser.js +15 -12
  27. package/dist/docx/groupDrawingParser.d.ts +2 -1
  28. package/dist/docx/groupDrawingParser.js +3 -6
  29. package/dist/docx/headerFooterParser.d.ts +7 -2
  30. package/dist/docx/headerFooterParser.js +15 -5
  31. package/dist/docx/hyperlinkParser.d.ts +48 -36
  32. package/dist/docx/hyperlinkParser.js +97 -82
  33. package/dist/docx/numberingParser.js +108 -84
  34. package/dist/docx/paragraphParser.d.ts +5 -1
  35. package/dist/docx/paragraphParser.js +381 -362
  36. package/dist/docx/paragraphProperties.js +123 -109
  37. package/dist/docx/paragraphPropertySource.d.ts +6 -1
  38. package/dist/docx/paragraphPropertySource.js +9 -1
  39. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  40. package/dist/docx/paragraphTextBoxEnrichment.js +17 -6
  41. package/dist/docx/parser.d.ts +7 -1
  42. package/dist/docx/parser.js +33 -16
  43. package/dist/docx/previewBudget.d.ts +55 -33
  44. package/dist/docx/previewBudget.js +59 -65
  45. package/dist/docx/rezip.js +41 -58
  46. package/dist/docx/runParser.d.ts +4 -1
  47. package/dist/docx/runParser.js +172 -184
  48. package/dist/docx/sdtProperties.js +87 -84
  49. package/dist/docx/sectionParser.js +169 -160
  50. package/dist/docx/serializer/paragraphSerializer.js +42 -38
  51. package/dist/docx/serializer/settingsSerializer.js +19 -1
  52. package/dist/docx/settingsParser.js +8 -0
  53. package/dist/docx/streamingXmlParser.d.ts +6 -2
  54. package/dist/docx/streamingXmlParser.js +12 -7
  55. package/dist/docx/styleParser.js +34 -8
  56. package/dist/docx/tableParser.d.ts +21 -12
  57. package/dist/docx/tableParser.js +518 -441
  58. package/dist/docx/textBoxParser.d.ts +8 -3
  59. package/dist/docx/textBoxParser.js +3 -3
  60. package/dist/docx/verbatimCapture.d.ts +10 -8
  61. package/dist/docx/verbatimCapture.js +45 -2
  62. package/dist/docx/vmlImageParser.d.ts +15 -13
  63. package/dist/docx/vmlImageParser.js +75 -60
  64. package/dist/docx/vmlPreview.d.ts +3 -3
  65. package/dist/docx/vmlPreview.js +3 -4
  66. package/dist/docx/xmlNamespaceContext.d.ts +9 -0
  67. package/dist/docx/xmlNamespaceContext.js +54 -0
  68. package/dist/docx/xmlParser.d.ts +6 -3
  69. package/dist/docx/xmlParser.js +11 -41
  70. package/dist/docx/xmlResourceLimits.d.ts +2 -1
  71. package/dist/docx/xmlResourceLimits.js +4 -1
  72. package/dist/fonts/headlessMeasure.js +0 -0
  73. package/dist/headless-layout.d.ts +11 -2
  74. package/dist/headless-layout.js +153 -107
  75. package/dist/internal/paragraphFormattingSerialization.js +3 -3
  76. package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
  77. package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
  78. package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
  79. package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
  80. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
  81. package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
  82. package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
  83. package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
  84. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
  85. package/dist/layout-bridge/convert/toFlowBlocks.js +258 -35
  86. package/dist/layout-bridge/engine/hitTest.js +5 -3
  87. package/dist/layout-bridge/engine/selectionRects.js +5 -3
  88. package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
  89. package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
  90. package/dist/layout-engine/index.d.ts +2 -2
  91. package/dist/layout-engine/index.js +70 -11
  92. package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
  93. package/dist/layout-engine/justificationCompatibility.js +9 -5
  94. package/dist/layout-engine/keep-together.d.ts +11 -5
  95. package/dist/layout-engine/keep-together.js +39 -16
  96. package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
  97. package/dist/layout-engine/layoutInstrumentation.js +8 -1
  98. package/dist/layout-engine/measure/advanceComposition.js +4 -7
  99. package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
  100. package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
  101. package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
  102. package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
  103. package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
  104. package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
  105. package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
  106. package/dist/layout-engine/measure/lineBreaks.js +10 -3
  107. package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
  108. package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
  109. package/dist/layout-engine/measure/measureBlocks.js +42 -8
  110. package/dist/layout-engine/measure/measureContainer.js +5 -5
  111. package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
  112. package/dist/layout-engine/measure/measureHelpers.js +21 -5
  113. package/dist/layout-engine/measure/measureParagraph.js +109 -30
  114. package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
  115. package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
  116. package/dist/layout-engine/measure/tabCalculator.js +2 -1
  117. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  118. package/dist/layout-engine/measure/tableCellFloating.js +51 -19
  119. package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
  120. package/dist/layout-engine/measure/tableCellGrid.js +45 -5
  121. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  122. package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
  123. package/dist/layout-engine/noteAreaFlow.js +83 -0
  124. package/dist/layout-engine/paginator.d.ts +10 -1
  125. package/dist/layout-engine/paginator.js +13 -1
  126. package/dist/layout-engine/tableRowBreak.js +3 -1
  127. package/dist/layout-engine/types.d.ts +89 -3
  128. package/dist/layout-engine/types.js +96 -1
  129. package/dist/layout-painter/index.d.ts +3 -0
  130. package/dist/layout-painter/renderPage.js +32 -83
  131. package/dist/layout-painter/renderParagraph.d.ts +6 -1
  132. package/dist/layout-painter/renderParagraph.js +34 -22
  133. package/dist/layout-painter/renderTable.js +26 -13
  134. package/dist/prosemirror/attrs/index.d.ts +9 -9
  135. package/dist/prosemirror/attrs/index.js +43 -11
  136. package/dist/prosemirror/conversion/fromProseDoc.js +8 -1
  137. package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
  138. package/dist/prosemirror/conversion/markInterner.js +90 -0
  139. package/dist/prosemirror/conversion/toProseDoc.js +77 -41
  140. package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
  141. package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
  142. package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
  143. package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
  144. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +2 -1
  145. package/dist/prosemirror/listMarker.d.ts +1 -0
  146. package/dist/prosemirror/listMarker.js +2 -0
  147. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  148. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  149. package/dist/prosemirror/schema/nodes.d.ts +13 -1
  150. package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
  151. package/dist/prosemirror/textBoxHostParagraph.js +21 -0
  152. package/dist/prosemirror/validation.js +91 -80
  153. package/dist/utils/createDocument.js +10 -1
  154. package/dist/utils/scriptSegments.d.ts +33 -4
  155. package/dist/utils/scriptSegments.js +39 -6
  156. package/dist/utils/textFormattingMerge.d.ts +17 -3
  157. package/dist/utils/textFormattingMerge.js +18 -12
  158. package/dist/utils/trailingText.d.ts +22 -0
  159. package/dist/utils/trailingText.js +32 -0
  160. package/package.json +2 -2
@@ -1,10 +1,11 @@
1
1
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
2
2
  import { convertBulletToUnicode } from "./bulletMarkers.js";
3
- import { CAPTURE, dispatchChildren, ownedElsewhere, withPreservedChildren } from "./containerChildren.js";
3
+ import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, withPreservedChildren } from "./containerChildren.js";
4
4
  import { isNumberingReference } from "./numberingReference.js";
5
5
  import { formatOoxmlCounter } from "./ooxmlCounterFormatter.js";
6
6
  import { parseParagraph } from "./paragraphParser.js";
7
7
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
8
+ import { standalonePreviewLedger } from "./previewBudget.js";
8
9
  import { captureSdtSiblingMarkers, parseSdtProperties } from "./sdtProperties.js";
9
10
  import { parseTable } from "./tableParser.js";
10
11
  import { findWordprocessingChild, mergeXmlnsDeclarations, selectAlternateContentBranch } from "./xmlParser.js";
@@ -84,7 +85,7 @@ const withContainerXmlns = (state, element) => ({
84
85
  ...state,
85
86
  options: {
86
87
  ...state.options,
87
- rootXmlns: mergeXmlnsDeclarations(state.options?.rootXmlns ?? {}, element)
88
+ rootXmlns: mergeXmlnsDeclarations(state.options.rootXmlns ?? {}, element)
88
89
  }
89
90
  });
90
91
  /**
@@ -121,74 +122,88 @@ const parseBlockContent = (parent, styles, theme, numbering, rels, media, option
121
122
  },
122
123
  options: {
123
124
  ...options,
124
- rootXmlns: mergeXmlnsDeclarations(options?.rootXmlns ?? {}, parent)
125
+ rootXmlns: mergeXmlnsDeclarations(options?.rootXmlns ?? {}, parent),
126
+ previews: options?.previews ?? standalonePreviewLedger()
125
127
  }
126
128
  });
129
+ const BLOCK_CONTENT_UNDECLARED = { AlternateContent: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
130
+ const selectedBranch = selectAlternateContentBranch(child);
131
+ if (!selectedBranch) return;
132
+ modelled.push(...parseBlockContentWithState(selectedBranch, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), selectedBranch)));
133
+ } };
134
+ const BLOCK_CONTENT_HANDLERS = {
135
+ p: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
136
+ const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, {
137
+ ...state.options,
138
+ runConsolidation: "deferred"
139
+ });
140
+ enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable, state.options.previews, state.options.context);
141
+ computeListMarker(paragraph, {
142
+ numbering,
143
+ listCounters: state.listCounters,
144
+ abstractCounters: state.abstractCounters,
145
+ restartedNumIds: state.restartedNumIds,
146
+ previousList: state.previousList
147
+ });
148
+ modelled.push(paragraph);
149
+ },
150
+ tbl: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
151
+ const table = parseTable(child, styles, theme, numbering, rels, media, state.options);
152
+ if (!table) return;
153
+ modelled.push(table);
154
+ },
155
+ sdt: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
156
+ modelled.push(parseBlockSdt(child, styles, theme, numbering, rels, media, state));
157
+ },
158
+ bookmarkStart: (child, { modelled }) => {
159
+ modelled.push(parseBookmarkStart(child));
160
+ },
161
+ bookmarkEnd: (child, { modelled }) => {
162
+ modelled.push(parseBookmarkEnd(child));
163
+ },
164
+ ...BLOCK_CHILD_OWNERS,
165
+ altChunk: CAPTURE,
166
+ commentRangeEnd: CAPTURE,
167
+ commentRangeStart: CAPTURE,
168
+ customXml: CAPTURE,
169
+ customXmlDelRangeEnd: CAPTURE,
170
+ customXmlDelRangeStart: CAPTURE,
171
+ customXmlInsRangeEnd: CAPTURE,
172
+ customXmlInsRangeStart: CAPTURE,
173
+ customXmlMoveFromRangeEnd: CAPTURE,
174
+ customXmlMoveFromRangeStart: CAPTURE,
175
+ customXmlMoveToRangeEnd: CAPTURE,
176
+ customXmlMoveToRangeStart: CAPTURE,
177
+ del: CAPTURE,
178
+ ins: CAPTURE,
179
+ moveFrom: CAPTURE,
180
+ moveFromRangeEnd: CAPTURE,
181
+ moveFromRangeStart: CAPTURE,
182
+ moveTo: CAPTURE,
183
+ moveToRangeEnd: CAPTURE,
184
+ moveToRangeStart: CAPTURE,
185
+ permEnd: CAPTURE,
186
+ permStart: CAPTURE,
187
+ proofErr: CAPTURE
188
+ };
127
189
  const parseBlockContentWithState = (parent, styles, theme, numbering, rels, media, state) => {
128
190
  const modelled = [];
129
- return withPreservedChildren(modelled, dispatchChildren({
191
+ return withPreservedChildren(modelled, dispatchChildrenWithContext({
130
192
  element: parent,
131
193
  container: "block-content",
132
194
  capturePosition: () => modelled.length,
133
- undeclared: { AlternateContent: (child) => {
134
- const selectedBranch = selectAlternateContentBranch(child);
135
- if (!selectedBranch) return;
136
- modelled.push(...parseBlockContentWithState(selectedBranch, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), selectedBranch)));
137
- } },
138
- handlers: {
139
- p: (child) => {
140
- const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, {
141
- ...state.options,
142
- runConsolidation: "deferred"
143
- });
144
- enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable, state.options?.context);
145
- computeListMarker(paragraph, {
146
- numbering,
147
- listCounters: state.listCounters,
148
- abstractCounters: state.abstractCounters,
149
- restartedNumIds: state.restartedNumIds,
150
- previousList: state.previousList
151
- });
152
- modelled.push(paragraph);
153
- },
154
- tbl: (child) => {
155
- const table = parseTable(child, styles, theme, numbering, rels, media, state.options);
156
- if (!table) return;
157
- modelled.push(table);
158
- },
159
- sdt: (child) => {
160
- modelled.push(parseBlockSdt(child, styles, theme, numbering, rels, media, state));
161
- },
162
- bookmarkStart: (child) => {
163
- modelled.push(parseBookmarkStart(child));
164
- },
165
- bookmarkEnd: (child) => {
166
- modelled.push(parseBookmarkEnd(child));
195
+ undeclared: BLOCK_CONTENT_UNDECLARED,
196
+ handlers: BLOCK_CONTENT_HANDLERS,
197
+ context: {
198
+ resources: {
199
+ styles,
200
+ theme,
201
+ numbering,
202
+ rels,
203
+ media
167
204
  },
168
- ...BLOCK_CHILD_OWNERS,
169
- altChunk: CAPTURE,
170
- commentRangeEnd: CAPTURE,
171
- commentRangeStart: CAPTURE,
172
- customXml: CAPTURE,
173
- customXmlDelRangeEnd: CAPTURE,
174
- customXmlDelRangeStart: CAPTURE,
175
- customXmlInsRangeEnd: CAPTURE,
176
- customXmlInsRangeStart: CAPTURE,
177
- customXmlMoveFromRangeEnd: CAPTURE,
178
- customXmlMoveFromRangeStart: CAPTURE,
179
- customXmlMoveToRangeEnd: CAPTURE,
180
- customXmlMoveToRangeStart: CAPTURE,
181
- del: CAPTURE,
182
- ins: CAPTURE,
183
- moveFrom: CAPTURE,
184
- moveFromRangeEnd: CAPTURE,
185
- moveFromRangeStart: CAPTURE,
186
- moveTo: CAPTURE,
187
- moveToRangeEnd: CAPTURE,
188
- moveToRangeStart: CAPTURE,
189
- permEnd: CAPTURE,
190
- permStart: CAPTURE,
191
- proofErr: CAPTURE
205
+ state,
206
+ modelled
192
207
  }
193
208
  }), (xml) => ({
194
209
  type: "preservedBlock",
@@ -1,5 +1,6 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { ParseContext } from "./parseContext.js";
3
+ import { PreviewLedger } from "./previewBudget.js";
3
4
  import { StyleMap } from "./styleParser.js";
4
5
  //#region src/docx/commentParser.d.ts
5
6
  type CommentExtendedInfo = {
@@ -29,6 +30,6 @@ declare function parseCommentsExtended(xml: string): Map<string, CommentExtended
29
30
  * local time. If `commentsExtendedXml` is provided, reply-thread
30
31
  * parent links (`parentId`) and resolved state (`done`) are populated.
31
32
  */
32
- declare function parseComments(commentsXml: string | null, styles: StyleMap | null, theme: document_d_exports.Theme | null, rels: document_d_exports.RelationshipMap, media: Map<string, document_d_exports.MediaFile>, commentsExtensibleXml?: string | null, commentsExtendedXml?: string | null, context?: ParseContext): document_d_exports.Comment[];
33
+ declare function parseComments(commentsXml: string | null, styles: StyleMap | null, theme: document_d_exports.Theme | null, rels: document_d_exports.RelationshipMap, media: Map<string, document_d_exports.MediaFile>, commentsExtensibleXml?: string | null, commentsExtendedXml?: string | null, context?: ParseContext, previews?: PreviewLedger): document_d_exports.Comment[];
33
34
  //#endregion
34
35
  export { CommentExtendedInfo, parseComments, parseCommentsExtended };
@@ -1,8 +1,9 @@
1
1
  import { commentThreadParaId } from "./commentThreadKey.js";
2
- import { CAPTURE, dispatchChildren } from "./containerChildren.js";
2
+ import { CAPTURE, dispatchChildrenWithContext } from "./containerChildren.js";
3
3
  import { PARA_ID_NAMESPACE_URIS, paraIdAttribute, paraIdParentAttribute } from "./paraIdAttribute.js";
4
4
  import { parseParagraph } from "./paragraphParser.js";
5
5
  import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
6
+ import { standalonePreviewLedger } from "./previewBudget.js";
6
7
  import { RUN_PROPERTY_OWNERS, parseRunProperties } from "./runParser.js";
7
8
  import { findChild, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, parseOnOffValue, parseXml } from "./xmlParser.js";
8
9
  import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
@@ -97,6 +98,46 @@ function parseCommentsExtended(xml) {
97
98
  }
98
99
  return infoByParaId;
99
100
  }
101
+ const COMMENT_BODY_HANDLERS = {
102
+ p: (contentChild, walk) => {
103
+ const { styles, theme, rels, media, previews, paragraphs } = walk;
104
+ const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media, { previews });
105
+ if (paragraphs.length > 0) {
106
+ paragraphs.push(paragraph);
107
+ return;
108
+ }
109
+ const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
110
+ walk.annotationReferenceFormatting = normalized.annotationReferenceFormatting;
111
+ paragraphs.push(normalized.paragraph);
112
+ },
113
+ altChunk: CAPTURE,
114
+ bookmarkEnd: CAPTURE,
115
+ bookmarkStart: CAPTURE,
116
+ commentRangeEnd: CAPTURE,
117
+ commentRangeStart: CAPTURE,
118
+ customXml: CAPTURE,
119
+ customXmlDelRangeEnd: CAPTURE,
120
+ customXmlDelRangeStart: CAPTURE,
121
+ customXmlInsRangeEnd: CAPTURE,
122
+ customXmlInsRangeStart: CAPTURE,
123
+ customXmlMoveFromRangeEnd: CAPTURE,
124
+ customXmlMoveFromRangeStart: CAPTURE,
125
+ customXmlMoveToRangeEnd: CAPTURE,
126
+ customXmlMoveToRangeStart: CAPTURE,
127
+ del: CAPTURE,
128
+ ins: CAPTURE,
129
+ moveFrom: CAPTURE,
130
+ moveFromRangeEnd: CAPTURE,
131
+ moveFromRangeStart: CAPTURE,
132
+ moveTo: CAPTURE,
133
+ moveToRangeEnd: CAPTURE,
134
+ moveToRangeStart: CAPTURE,
135
+ permEnd: CAPTURE,
136
+ permStart: CAPTURE,
137
+ proofErr: CAPTURE,
138
+ sdt: CAPTURE,
139
+ tbl: CAPTURE
140
+ };
100
141
  /**
101
142
  * Parse comments.xml into an array of Comment objects.
102
143
  *
@@ -105,7 +146,7 @@ function parseCommentsExtended(xml) {
105
146
  * local time. If `commentsExtendedXml` is provided, reply-thread
106
147
  * parent links (`parentId`) and resolved state (`done`) are populated.
107
148
  */
108
- function parseComments(commentsXml, styles, theme, rels, media, commentsExtensibleXml, commentsExtendedXml, context) {
149
+ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensibleXml, commentsExtendedXml, context, previews = standalonePreviewLedger()) {
109
150
  if (!commentsXml) return [];
110
151
  const root = parseXml(commentsXml);
111
152
  const dateUtcByParaId = commentsExtensibleXml ? parseCommentsExtensible(commentsExtensibleXml) : /* @__PURE__ */ new Map();
@@ -135,52 +176,23 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
135
176
  const paraId = rawParaId ? String(rawParaId).toUpperCase() : null;
136
177
  const date = (paraId ? dateUtcByParaId.get(paraId) : void 0) ?? localDate;
137
178
  const done = (paraId ? extendedByParaId.get(paraId) : void 0)?.done;
138
- const paragraphs = [];
139
- let annotationReferenceFormatting;
140
- const preserved = dispatchChildren({
179
+ const walk = {
180
+ styles,
181
+ theme,
182
+ rels,
183
+ media,
184
+ previews,
185
+ paragraphs: [],
186
+ annotationReferenceFormatting: void 0
187
+ };
188
+ const preserved = dispatchChildrenWithContext({
141
189
  element: child,
142
190
  container: "w:comment",
143
- capturePosition: () => paragraphs.length,
144
- handlers: {
145
- p: (contentChild) => {
146
- const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media);
147
- if (paragraphs.length > 0) {
148
- paragraphs.push(paragraph);
149
- return;
150
- }
151
- const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
152
- annotationReferenceFormatting = normalized.annotationReferenceFormatting;
153
- paragraphs.push(normalized.paragraph);
154
- },
155
- altChunk: CAPTURE,
156
- bookmarkEnd: CAPTURE,
157
- bookmarkStart: CAPTURE,
158
- commentRangeEnd: CAPTURE,
159
- commentRangeStart: CAPTURE,
160
- customXml: CAPTURE,
161
- customXmlDelRangeEnd: CAPTURE,
162
- customXmlDelRangeStart: CAPTURE,
163
- customXmlInsRangeEnd: CAPTURE,
164
- customXmlInsRangeStart: CAPTURE,
165
- customXmlMoveFromRangeEnd: CAPTURE,
166
- customXmlMoveFromRangeStart: CAPTURE,
167
- customXmlMoveToRangeEnd: CAPTURE,
168
- customXmlMoveToRangeStart: CAPTURE,
169
- del: CAPTURE,
170
- ins: CAPTURE,
171
- moveFrom: CAPTURE,
172
- moveFromRangeEnd: CAPTURE,
173
- moveFromRangeStart: CAPTURE,
174
- moveTo: CAPTURE,
175
- moveToRangeEnd: CAPTURE,
176
- moveToRangeStart: CAPTURE,
177
- permEnd: CAPTURE,
178
- permStart: CAPTURE,
179
- proofErr: CAPTURE,
180
- sdt: CAPTURE,
181
- tbl: CAPTURE
182
- }
191
+ capturePosition: () => walk.paragraphs.length,
192
+ handlers: COMMENT_BODY_HANDLERS,
193
+ context: walk
183
194
  });
195
+ const { paragraphs, annotationReferenceFormatting } = walk;
184
196
  if (paraId && !commentIdByParaId.has(paraId)) commentIdByParaId.set(paraId, id);
185
197
  parsed.push({
186
198
  comment: {
@@ -83,6 +83,12 @@ declare const ownedElsewhere: <Container extends DispatchedContainer, Child exte
83
83
  * difference between this and a `default` that says nothing.
84
84
  */
85
85
  declare const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
86
+ /**
87
+ * A handler that reads one child. `context` is the value the walk was given
88
+ * (see {@link dispatchChildrenWithContext}), so a handler table can be built
89
+ * once per module rather than as closures per element.
90
+ */
91
+ type ChildReader<Context = undefined> = (child: XmlElement, context: Context) => typeof CAPTURE | void;
86
92
  /**
87
93
  * What a container does with one declared child.
88
94
  *
@@ -94,7 +100,7 @@ declare const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
94
100
  * it by the outcome rather than by the name is what makes the decision total:
95
101
  * the map cannot list the values a reader will refuse.
96
102
  */
97
- type ChildDisposition<Container extends DispatchedContainer = DispatchedContainer, Child extends string = string> = ((child: XmlElement) => typeof CAPTURE | void) | typeof CAPTURE | typeof DROPPED_WITH_ITS_WRAPPER | OwnedElsewhere<Container, Child>;
103
+ type ChildDisposition<Container extends DispatchedContainer = DispatchedContainer, Child extends string = string, Context = undefined> = ChildReader<Context> | typeof CAPTURE | typeof DROPPED_WITH_ITS_WRAPPER | OwnedElsewhere<Container, Child>;
98
104
  /**
99
105
  * A total decision per declared child.
100
106
  *
@@ -103,13 +109,13 @@ type ChildDisposition<Container extends DispatchedContainer = DispatchedContaine
103
109
  * type is keyed by the child it is filed under, so an {@link ownedElsewhere}
104
110
  * entry cannot name a different child than the one it decides.
105
111
  */
106
- type ChildHandlers<Container extends DispatchedContainer> = Readonly<{ [Child in DeclaredChild<Container>]: ChildDisposition<Container, Child>; }>;
107
- type DispatchChildrenOptions<Container extends DispatchedContainer> = {
112
+ type ChildHandlers<Container extends DispatchedContainer, Context = undefined> = Readonly<{ [Child in DeclaredChild<Container>]: ChildDisposition<Container, Child, Context>; }>;
113
+ type DispatchChildrenOptions<Container extends DispatchedContainer, Context = undefined> = {
108
114
  /** The container element, as the source wrote it. */
109
115
  element: XmlElement;
110
116
  /** Which container's declared-child set the handler map must be total over. */
111
117
  container: Container;
112
- handlers: ChildHandlers<Container>;
118
+ handlers: ChildHandlers<Container, Context>;
113
119
  /**
114
120
  * Where a capture belongs among the caller's children, called once per
115
121
  * captured child.
@@ -135,7 +141,7 @@ type DispatchChildrenOptions<Container extends DispatchedContainer> = {
135
141
  *
136
142
  * Each entry is a claim that folio reads this name in this container.
137
143
  */
138
- undeclared?: Readonly<Record<string, ChildDisposition>>;
144
+ undeclared?: Readonly<Record<string, ChildDisposition<DispatchedContainer, string, Context>>>;
139
145
  /**
140
146
  * Dispositions for whole namespaces the declared set does not cover, by
141
147
  * namespace URI, consulted after {@link undeclared} and before the sink.
@@ -148,7 +154,7 @@ type DispatchChildrenOptions<Container extends DispatchedContainer> = {
148
154
  * not a `default` in disguise: a child from any *other* namespace still goes
149
155
  * to the sink, which is the branch a hand-written `default` gets wrong.
150
156
  */
151
- undeclaredNamespaces?: Readonly<Record<string, ChildDisposition>>;
157
+ undeclaredNamespaces?: Readonly<Record<string, ChildDisposition<DispatchedContainer, string, Context>>>;
152
158
  };
153
159
  /**
154
160
  * The Transitional spelling of a namespace, so one disposition covers both.
@@ -171,7 +177,14 @@ declare const transitionalNamespaceOf: (namespace: string) => string;
171
177
  * none — an empty record is never written, so a fully modelled container
172
178
  * stays byte-identical in the model.
173
179
  */
174
- declare const dispatchChildren: <Container extends DispatchedContainer>({ element, handlers, capturePosition, undeclared, undeclaredNamespaces }: DispatchChildrenOptions<Container>) => PreservedMarkup | undefined;
180
+ declare const dispatchChildren: <Container extends DispatchedContainer>(options: DispatchChildrenOptions<Container>) => PreservedMarkup | undefined;
181
+ /**
182
+ * {@link dispatchChildren} for a handler table that reads into a value it is
183
+ * handed rather than one it closes over, so the table is built once.
184
+ */
185
+ declare const dispatchChildrenWithContext: <Container extends DispatchedContainer, Context>({ element, handlers, capturePosition, undeclared, undeclaredNamespaces, context }: DispatchChildrenOptions<Container, Context> & {
186
+ context: Context;
187
+ }) => PreservedMarkup | undefined;
175
188
  /**
176
189
  * Put a container's modelled children back with its preserved ones between
177
190
  * them, in source position.
@@ -205,4 +218,4 @@ declare const serializeWithPreservedChildren: (modelled: readonly string[], pres
205
218
  */
206
219
  declare const sequencePositions: <Container extends SequenceContainer>(container: Container, element: XmlElement) => ((child: XmlElement) => number);
207
220
  //#endregion
208
- export { CAPTURE, ChildDisposition, ChildHandlers, ChildOwnerClaim, ChildOwnerRef, DROPPED_WITH_ITS_WRAPPER, OwnedElsewhere, dispatchChildren, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
221
+ export { CAPTURE, ChildDisposition, ChildHandlers, ChildOwnerClaim, ChildOwnerRef, ChildReader, DROPPED_WITH_ITS_WRAPPER, OwnedElsewhere, dispatchChildren, dispatchChildrenWithContext, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
@@ -59,6 +59,13 @@ const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
59
59
  */
60
60
  const transitionalNamespaceOf = (namespace) => TRANSITIONAL_NAMESPACE_BY_STRICT_URI.get(namespace) ?? namespace;
61
61
  /**
62
+ * A table's own entry for `key`. Read directly rather than copied into a `Map`
63
+ * per container: the tables are rebuilt per element, and the copy dominated the
64
+ * walk. `Object.hasOwn` keeps a name such as `constructor` from resolving to a
65
+ * prototype member.
66
+ */
67
+ const ownDisposition = (table, key) => table !== void 0 && Object.hasOwn(table, key) ? table[key] : void 0;
68
+ /**
62
69
  * Walk a container's children, handing each to its handler and the rest to the
63
70
  * sink.
64
71
  *
@@ -66,7 +73,15 @@ const transitionalNamespaceOf = (namespace) => TRANSITIONAL_NAMESPACE_BY_STRICT_
66
73
  * none — an empty record is never written, so a fully modelled container
67
74
  * stays byte-identical in the model.
68
75
  */
69
- const dispatchChildren = ({ element, handlers, capturePosition, undeclared, undeclaredNamespaces }) => {
76
+ const dispatchChildren = (options) => dispatchChildrenWithContext({
77
+ ...options,
78
+ context: void 0
79
+ });
80
+ /**
81
+ * {@link dispatchChildren} for a handler table that reads into a value it is
82
+ * handed rather than one it closes over, so the table is built once.
83
+ */
84
+ const dispatchChildrenWithContext = ({ element, handlers, capturePosition, undeclared, undeclaredNamespaces, context }) => {
70
85
  const children = [];
71
86
  const capture = (child) => {
72
87
  children.push({
@@ -74,19 +89,17 @@ const dispatchChildren = ({ element, handlers, capturePosition, undeclared, unde
74
89
  xml: captureVerbatimXml(child)
75
90
  });
76
91
  };
77
- const declared = new Map(Object.entries(handlers));
78
- const byName = new Map(Object.entries(undeclared ?? {}));
79
- const byNamespace = new Map(Object.entries(undeclaredNamespaces ?? {}));
92
+ const declared = handlers;
80
93
  for (const child of getChildElements(element)) {
81
94
  const localName = getLocalName(child.name);
82
95
  const namespace = getNamespaceUri(child);
83
- const disposition = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? declared.get(localName) ?? byName.get(localName) : byName.get(localName) ?? byNamespace.get(transitionalNamespaceOf(namespace));
96
+ const disposition = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? ownDisposition(declared, localName) ?? ownDisposition(undeclared, localName) : ownDisposition(undeclared, localName) ?? ownDisposition(undeclaredNamespaces, transitionalNamespaceOf(namespace));
84
97
  if (disposition === void 0 || disposition === "capture") {
85
98
  capture(child);
86
99
  continue;
87
100
  }
88
101
  if (typeof disposition !== "function") continue;
89
- if (disposition(child) === "capture") capture(child);
102
+ if (disposition(child, context) === "capture") capture(child);
90
103
  }
91
104
  return children.length === 0 ? void 0 : { children };
92
105
  };
@@ -138,16 +151,33 @@ const serializeWithPreservedChildren = (modelled, preserved) => withPreservedChi
138
151
  * ahead of the sequence's first slot.
139
152
  */
140
153
  const sequencePositions = (container, element) => {
154
+ let positions;
155
+ return (child) => {
156
+ positions ??= computeSequencePositions(container, element);
157
+ return positions.get(child) ?? -1;
158
+ };
159
+ };
160
+ const SEQUENCE_ORDINALS = /* @__PURE__ */ new Map();
161
+ const sequenceOrdinals = (container) => {
162
+ const cached = SEQUENCE_ORDINALS.get(container);
163
+ if (cached !== void 0) return cached;
164
+ const ordinals = /* @__PURE__ */ new Map();
141
165
  const declared = SEQUENCE_CHILDREN[container];
166
+ for (const [at, name] of declared.entries()) if (!ordinals.has(name)) ordinals.set(name, at);
167
+ SEQUENCE_ORDINALS.set(container, ordinals);
168
+ return ordinals;
169
+ };
170
+ const computeSequencePositions = (container, element) => {
171
+ const ordinals = sequenceOrdinals(container);
142
172
  const positions = /* @__PURE__ */ new Map();
143
173
  let previous = -1;
144
174
  for (const child of getChildElements(element)) {
145
175
  const namespace = getNamespaceUri(child);
146
- const at = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? declared.indexOf(getLocalName(child.name)) : -1;
176
+ const at = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? ordinals.get(getLocalName(child.name)) ?? -1 : -1;
147
177
  if (at !== -1) previous = at;
148
178
  positions.set(child, at === -1 ? previous : at);
149
179
  }
150
- return (child) => positions.get(child) ?? -1;
180
+ return positions;
151
181
  };
152
182
  //#endregion
153
- export { CAPTURE, DROPPED_WITH_ITS_WRAPPER, dispatchChildren, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
183
+ export { CAPTURE, DROPPED_WITH_ITS_WRAPPER, dispatchChildren, dispatchChildrenWithContext, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
@@ -1,6 +1,7 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { NumberingMap } from "./numberingParser.js";
3
3
  import { ParseContext } from "./parseContext.js";
4
+ import { PreviewLedger } from "./previewBudget.js";
4
5
  import { StyleMap } from "./styleParser.js";
5
6
  //#region src/docx/documentParser.d.ts
6
7
  /**
@@ -26,9 +27,12 @@ declare function extractAllTemplateVariables(content: document_d_exports.BlockCo
26
27
  * @param numbering - Parsed numbering definitions
27
28
  * @param rels - Document relationships
28
29
  * @param media - Media files
30
+ * @param context - Where normalisations are reported
31
+ * @param previews - The ledger of the package this body belongs to; a body
32
+ * read on its own charges its previews to no package
29
33
  * @returns DocumentBody with content, sections, and template variables
30
34
  */
31
- declare function parseDocumentBody(xml: string, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, context?: ParseContext): document_d_exports.DocumentBody;
35
+ declare function parseDocumentBody(xml: string, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, context?: ParseContext, previews?: PreviewLedger): document_d_exports.DocumentBody;
32
36
  /**
33
37
  * Get all paragraphs from document body (flattened)
34
38
  */
@@ -1,7 +1,7 @@
1
1
  import { parseBlockContent } from "./blockContentParser.js";
2
2
  import { getParagraphText } from "./paragraphParser.js";
3
+ import { standalonePreviewLedger } from "./previewBudget.js";
3
4
  import { getDefaultSectionProperties, parseSectionProperties } from "./sectionParser.js";
4
- import { parseStreamingXml } from "./streamingXmlParser.js";
5
5
  import { parseThemeColorAttribute } from "./themeColorAttribute.js";
6
6
  import { captureVerbatimXml } from "./verbatimCapture.js";
7
7
  import { WORDPROCESSINGML_NAMESPACE_URIS, collectXmlnsDeclarations, findChild, findChildByNamespaceUri, getAttributeByNamespaceUri, getLocalName, parseXml } from "./xmlParser.js";
@@ -145,13 +145,15 @@ function parseDocumentBackground(documentEl, context) {
145
145
  * @param numbering - Parsed numbering definitions
146
146
  * @param rels - Document relationships
147
147
  * @param media - Media files
148
+ * @param context - Where normalisations are reported
149
+ * @param previews - The ledger of the package this body belongs to; a body
150
+ * read on its own charges its previews to no package
148
151
  * @returns DocumentBody with content, sections, and template variables
149
152
  */
150
- function parseDocumentBody(xml, styles = null, theme = null, numbering = null, rels = null, media = null, context) {
153
+ function parseDocumentBody(xml, styles = null, theme = null, numbering = null, rels = null, media = null, context, previews = standalonePreviewLedger()) {
151
154
  const result = { content: [] };
152
155
  if (!xml) return result;
153
- const streamed = parseStreamingXml(xml);
154
- const documentEl = ((streamed.status === "parsed" ? streamed.value : parseXml(xml)).elements ?? []).find((el) => el.type === "element" && (el.name === "w:document" || el.name?.endsWith(":document")));
156
+ const documentEl = (parseXml(xml).elements ?? []).find((el) => el.type === "element" && (el.name === "w:document" || el.name?.endsWith(":document")));
155
157
  if (!documentEl) return result;
156
158
  const background = parseDocumentBackground(documentEl, context);
157
159
  if (background !== void 0) result.background = background;
@@ -159,7 +161,8 @@ function parseDocumentBody(xml, styles = null, theme = null, numbering = null, r
159
161
  if (!bodyEl) return result;
160
162
  result.content = parseBlockContent(bodyEl, styles, theme, numbering, rels, media, {
161
163
  rootXmlns: collectXmlnsDeclarations(documentEl),
162
- context
164
+ context,
165
+ previews
163
166
  });
164
167
  const finalSectPr = findChild(bodyEl, "w", "sectPr");
165
168
  if (finalSectPr) result.finalSectionProperties = parseSectionProperties(finalSectPr, context);
@@ -0,0 +1,22 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { XmlElement } from "./xmlParser.js";
3
+ //#region src/docx/documentSectionFacts.d.ts
4
+ type HeaderFooterReference = {
5
+ element: "headerReference" | "footerReference";
6
+ /** The parsed `ST_HdrFtr` value, never the raw attribute. */
7
+ type: document_d_exports.HeaderFooterType;
8
+ rId: string;
9
+ };
10
+ /** What a save must not lose from `word/document.xml`. */
11
+ type DocumentSectionFacts = {
12
+ /** `w:sectPr` elements, excluding the prior records inside `w:sectPrChange`. */
13
+ sectionCount: number;
14
+ /** Every header/footer reference, including those inside `w:sectPrChange`. */
15
+ headerFooterReferences: readonly HeaderFooterReference[];
16
+ };
17
+ /** Both facts from one walk of a parsed document tree. */
18
+ declare const collectDocumentSectionFacts: (root: XmlElement) => DocumentSectionFacts;
19
+ /** Read the section facts of a `word/document.xml` string under the shared resource limits. */
20
+ declare const readDocumentSectionFacts: (xml: string) => DocumentSectionFacts;
21
+ //#endregion
22
+ export { DocumentSectionFacts, HeaderFooterReference, collectDocumentSectionFacts, readDocumentSectionFacts };
@@ -0,0 +1,43 @@
1
+ import { parseHeaderFooterType } from "./headerFooterRefParser.js";
2
+ import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, WORDPROCESSINGML_NAMESPACE_URIS, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespaceUri, parseXml } from "./xmlParser.js";
3
+ import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
4
+ //#region src/docx/documentSectionFacts.ts
5
+ const isWordprocessingElement = (element, localName) => getLocalName(element.name) === localName && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(element) ?? "");
6
+ /** Both facts from one walk of a parsed document tree. */
7
+ const collectDocumentSectionFacts = (root) => {
8
+ let sectionCount = 0;
9
+ const headerFooterReferences = [];
10
+ const pending = [{
11
+ element: root,
12
+ insidePropertyChange: false
13
+ }];
14
+ for (let current = pending.pop(); current !== void 0; current = pending.pop()) {
15
+ const { element, insidePropertyChange } = current;
16
+ const localName = getLocalName(element.name);
17
+ if (!insidePropertyChange && isWordprocessingElement(element, "sectPr")) sectionCount += 1;
18
+ if ((localName === "headerReference" || localName === "footerReference") && isWordprocessingElement(element, localName)) {
19
+ const rId = getAttributeByNamespaceUri(element, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id");
20
+ if (rId) headerFooterReferences.push({
21
+ element: localName,
22
+ type: parseHeaderFooterType(getAttributeByNamespaceUri(element, WORDPROCESSINGML_NAMESPACE_URIS, "type")),
23
+ rId
24
+ });
25
+ }
26
+ const childrenInsidePropertyChange = insidePropertyChange || isWordprocessingElement(element, "sectPrChange");
27
+ for (const child of getChildElements(element)) pending.push({
28
+ element: child,
29
+ insidePropertyChange: childrenInsidePropertyChange
30
+ });
31
+ }
32
+ return {
33
+ sectionCount,
34
+ headerFooterReferences
35
+ };
36
+ };
37
+ /** Read the section facts of a `word/document.xml` string under the shared resource limits. */
38
+ const readDocumentSectionFacts = (xml) => {
39
+ assertXmlResourceLimits({ xml });
40
+ return collectDocumentSectionFacts(parseXml(xml));
41
+ };
42
+ //#endregion
43
+ export { collectDocumentSectionFacts, readDocumentSectionFacts };
@@ -64,6 +64,13 @@ declare function parseFieldInstruction(instruction: string): ParsedFieldInstruct
64
64
  * @returns Format string or undefined
65
65
  */
66
66
  declare function getFormatSwitch(instruction: ParsedFieldInstruction): string | undefined;
67
+ /**
68
+ * Get the numeric picture switch value (\#), e.g. `0#` in `PAGE \# 0#`.
69
+ *
70
+ * @param instruction - Parsed instruction
71
+ * @returns Picture string or undefined
72
+ */
73
+ declare function getNumericPictureSwitch(instruction: ParsedFieldInstruction): string | undefined;
67
74
  /**
68
75
  * Check if field has MERGEFORMAT switch (preserve formatting)
69
76
  *
@@ -237,4 +244,4 @@ declare function getMergeFields(fields: document_d_exports.Field[]): document_d_
237
244
  */
238
245
  declare function getMergeFieldNames(fields: document_d_exports.Field[]): string[];
239
246
  //#endregion
240
- export { ComplexFieldContext, ComplexFieldState, FieldSwitch, KNOWN_FIELD_TYPES, ParsedFieldInstruction, collectFields, computePageNumber, createComplexFieldContext, finalizeComplexField, formatDate, getFieldDisplayValue, getFieldsByType, getFormatSwitch, getMergeFieldNames, getMergeFields, getPageNumberFields, hasMergeFormat, isDateTimeField, isDocPropertyField, isHyperlinkField, isKnownFieldType, isMergeField, isPageNumberField, isReferenceField, isTocField, isTotalPagesField, parseFieldInstruction, parseFieldType, parseSimpleField, resetComplexFieldContext };
247
+ export { ComplexFieldContext, ComplexFieldState, FieldSwitch, KNOWN_FIELD_TYPES, ParsedFieldInstruction, collectFields, computePageNumber, createComplexFieldContext, finalizeComplexField, formatDate, getFieldDisplayValue, getFieldsByType, getFormatSwitch, getMergeFieldNames, getMergeFields, getNumericPictureSwitch, getPageNumberFields, hasMergeFormat, isDateTimeField, isDocPropertyField, isHyperlinkField, isKnownFieldType, isMergeField, isPageNumberField, isReferenceField, isTocField, isTotalPagesField, parseFieldInstruction, parseFieldType, parseSimpleField, resetComplexFieldContext };