@stll/folio-core 0.47.6 → 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 (163) hide show
  1. package/dist/ai-edits/word-diff.d.ts +25 -6
  2. package/dist/ai-edits/word-diff.js +210 -38
  3. package/dist/controller/fontReadiness.js +3 -3
  4. package/dist/controller/hyphenationReadiness.d.ts +19 -0
  5. package/dist/controller/hyphenationReadiness.js +47 -0
  6. package/dist/controller/layoutPipeline.d.ts +3 -0
  7. package/dist/controller/layoutPipeline.js +59 -17
  8. package/dist/display-list/build/buildDisplayList.js +39 -12
  9. package/dist/display-list/build/pageFurniture.d.ts +7 -1
  10. package/dist/display-list/build/pageFurniture.js +21 -8
  11. package/dist/display-list/build/paragraphPrimitives.js +5 -4
  12. package/dist/display-list/build/tablePrimitives.js +10 -6
  13. package/dist/docx/attributeRemainder.js +10 -2
  14. package/dist/docx/blockContentParser.d.ts +2 -0
  15. package/dist/docx/blockContentParser.js +77 -62
  16. package/dist/docx/commentParser.d.ts +2 -1
  17. package/dist/docx/commentParser.js +57 -45
  18. package/dist/docx/containerChildren.d.ts +21 -8
  19. package/dist/docx/containerChildren.js +39 -9
  20. package/dist/docx/documentParser.d.ts +5 -1
  21. package/dist/docx/documentParser.js +8 -5
  22. package/dist/docx/documentSectionFacts.d.ts +22 -0
  23. package/dist/docx/documentSectionFacts.js +43 -0
  24. package/dist/docx/fieldParser.d.ts +8 -1
  25. package/dist/docx/fieldParser.js +47 -3
  26. package/dist/docx/fontTableParser.js +34 -27
  27. package/dist/docx/footnoteParser.d.ts +3 -2
  28. package/dist/docx/footnoteParser.js +15 -12
  29. package/dist/docx/groupDrawingParser.d.ts +2 -1
  30. package/dist/docx/groupDrawingParser.js +3 -6
  31. package/dist/docx/headerFooterParser.d.ts +7 -2
  32. package/dist/docx/headerFooterParser.js +15 -5
  33. package/dist/docx/hyperlinkParser.d.ts +48 -36
  34. package/dist/docx/hyperlinkParser.js +97 -82
  35. package/dist/docx/numberingParser.js +108 -84
  36. package/dist/docx/paragraphParser.d.ts +5 -1
  37. package/dist/docx/paragraphParser.js +381 -362
  38. package/dist/docx/paragraphProperties.js +123 -109
  39. package/dist/docx/paragraphPropertySource.d.ts +6 -1
  40. package/dist/docx/paragraphPropertySource.js +9 -1
  41. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  42. package/dist/docx/paragraphTextBoxEnrichment.js +17 -6
  43. package/dist/docx/parser.d.ts +7 -1
  44. package/dist/docx/parser.js +33 -16
  45. package/dist/docx/previewBudget.d.ts +55 -33
  46. package/dist/docx/previewBudget.js +59 -65
  47. package/dist/docx/relsParser.js +9 -1
  48. package/dist/docx/rezip.js +41 -58
  49. package/dist/docx/runParser.d.ts +4 -1
  50. package/dist/docx/runParser.js +172 -184
  51. package/dist/docx/sdtProperties.js +87 -84
  52. package/dist/docx/sectionParser.js +169 -160
  53. package/dist/docx/serializer/paragraphSerializer.js +42 -38
  54. package/dist/docx/serializer/settingsSerializer.js +19 -1
  55. package/dist/docx/settingsParser.js +8 -0
  56. package/dist/docx/streamingXmlParser.d.ts +6 -2
  57. package/dist/docx/streamingXmlParser.js +12 -7
  58. package/dist/docx/styleParser.js +34 -8
  59. package/dist/docx/tableParser.d.ts +21 -12
  60. package/dist/docx/tableParser.js +518 -441
  61. package/dist/docx/textBoxParser.d.ts +8 -3
  62. package/dist/docx/textBoxParser.js +3 -3
  63. package/dist/docx/verbatimCapture.d.ts +10 -8
  64. package/dist/docx/verbatimCapture.js +45 -2
  65. package/dist/docx/vmlImageParser.d.ts +15 -13
  66. package/dist/docx/vmlImageParser.js +75 -60
  67. package/dist/docx/vmlPreview.d.ts +3 -3
  68. package/dist/docx/vmlPreview.js +3 -4
  69. package/dist/docx/xmlNamespaceContext.d.ts +9 -0
  70. package/dist/docx/xmlNamespaceContext.js +54 -0
  71. package/dist/docx/xmlParser.d.ts +6 -3
  72. package/dist/docx/xmlParser.js +11 -41
  73. package/dist/docx/xmlResourceLimits.d.ts +2 -1
  74. package/dist/docx/xmlResourceLimits.js +4 -1
  75. package/dist/fonts/headlessMeasure.js +0 -0
  76. package/dist/headless-layout.d.ts +11 -2
  77. package/dist/headless-layout.js +153 -107
  78. package/dist/internal/paragraphFormattingSerialization.js +3 -3
  79. package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
  80. package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
  81. package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
  82. package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
  83. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
  84. package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
  85. package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
  86. package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
  87. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
  88. package/dist/layout-bridge/convert/toFlowBlocks.js +258 -35
  89. package/dist/layout-bridge/engine/hitTest.js +5 -3
  90. package/dist/layout-bridge/engine/selectionRects.js +5 -3
  91. package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
  92. package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
  93. package/dist/layout-engine/index.d.ts +2 -2
  94. package/dist/layout-engine/index.js +70 -11
  95. package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
  96. package/dist/layout-engine/justificationCompatibility.js +9 -5
  97. package/dist/layout-engine/keep-together.d.ts +11 -5
  98. package/dist/layout-engine/keep-together.js +39 -16
  99. package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
  100. package/dist/layout-engine/layoutInstrumentation.js +8 -1
  101. package/dist/layout-engine/measure/advanceComposition.js +4 -7
  102. package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
  103. package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
  104. package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
  105. package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
  106. package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
  107. package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
  108. package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
  109. package/dist/layout-engine/measure/lineBreaks.js +10 -3
  110. package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
  111. package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
  112. package/dist/layout-engine/measure/measureBlocks.js +42 -8
  113. package/dist/layout-engine/measure/measureContainer.js +5 -5
  114. package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
  115. package/dist/layout-engine/measure/measureHelpers.js +21 -5
  116. package/dist/layout-engine/measure/measureParagraph.js +109 -30
  117. package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
  118. package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
  119. package/dist/layout-engine/measure/tabCalculator.js +2 -1
  120. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  121. package/dist/layout-engine/measure/tableCellFloating.js +51 -19
  122. package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
  123. package/dist/layout-engine/measure/tableCellGrid.js +45 -5
  124. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  125. package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
  126. package/dist/layout-engine/noteAreaFlow.js +83 -0
  127. package/dist/layout-engine/paginator.d.ts +10 -1
  128. package/dist/layout-engine/paginator.js +13 -1
  129. package/dist/layout-engine/tableRowBreak.js +3 -1
  130. package/dist/layout-engine/types.d.ts +89 -3
  131. package/dist/layout-engine/types.js +96 -1
  132. package/dist/layout-painter/index.d.ts +3 -0
  133. package/dist/layout-painter/renderPage.js +32 -83
  134. package/dist/layout-painter/renderParagraph.d.ts +6 -1
  135. package/dist/layout-painter/renderParagraph.js +34 -22
  136. package/dist/layout-painter/renderTable.js +26 -13
  137. package/dist/prosemirror/attrs/index.d.ts +9 -9
  138. package/dist/prosemirror/attrs/index.js +43 -11
  139. package/dist/prosemirror/conversion/fromProseDoc.js +8 -1
  140. package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
  141. package/dist/prosemirror/conversion/markInterner.js +90 -0
  142. package/dist/prosemirror/conversion/toProseDoc.js +77 -41
  143. package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
  144. package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
  145. package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
  146. package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
  147. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +2 -1
  148. package/dist/prosemirror/listMarker.d.ts +1 -0
  149. package/dist/prosemirror/listMarker.js +2 -0
  150. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  151. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  152. package/dist/prosemirror/schema/nodes.d.ts +13 -1
  153. package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
  154. package/dist/prosemirror/textBoxHostParagraph.js +21 -0
  155. package/dist/prosemirror/validation.js +91 -80
  156. package/dist/utils/createDocument.js +10 -1
  157. package/dist/utils/scriptSegments.d.ts +33 -4
  158. package/dist/utils/scriptSegments.js +39 -6
  159. package/dist/utils/textFormattingMerge.d.ts +17 -3
  160. package/dist/utils/textFormattingMerge.js +18 -12
  161. package/dist/utils/trailingText.d.ts +22 -0
  162. package/dist/utils/trailingText.js +32 -0
  163. package/package.json +2 -2
@@ -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 };
@@ -141,6 +141,15 @@ function getFormatSwitch(instruction) {
141
141
  return instruction.switches.find((s) => s.switch === "*" || s.switch === "@")?.value;
142
142
  }
143
143
  /**
144
+ * Get the numeric picture switch value (\#), e.g. `0#` in `PAGE \# 0#`.
145
+ *
146
+ * @param instruction - Parsed instruction
147
+ * @returns Picture string or undefined
148
+ */
149
+ function getNumericPictureSwitch(instruction) {
150
+ return instruction.switches.find((s) => s.switch === "#")?.value;
151
+ }
152
+ /**
144
153
  * Check if field has MERGEFORMAT switch (preserve formatting)
145
154
  *
146
155
  * @param instruction - Parsed instruction
@@ -345,16 +354,51 @@ function isTocField(field) {
345
354
  * @returns Formatted page number string
346
355
  */
347
356
  function computePageNumber(pageNumber, instruction, sectionFormat) {
357
+ const picture = instruction ? getNumericPictureSwitch(instruction) : void 0;
358
+ if (picture !== void 0) return applyNumericPicture(pageNumber, picture);
348
359
  const format = instruction ? getFormatSwitch(instruction) : void 0;
349
360
  if (!format || format.toUpperCase() === "MERGEFORMAT") return formatSectionPageNumber(pageNumber, sectionFormat);
361
+ const isLowercaseSwitch = format === format.toLowerCase();
350
362
  switch (format.toUpperCase()) {
351
- case "ROMAN": return toRoman(pageNumber);
352
- case "ALPHABETIC": return toLetter(pageNumber);
363
+ case "ROMAN": {
364
+ const roman = toRoman(pageNumber);
365
+ return isLowercaseSwitch ? roman.toLowerCase() : roman;
366
+ }
367
+ case "ALPHABETIC": {
368
+ const letters = toLetter(pageNumber);
369
+ return isLowercaseSwitch ? letters.toLowerCase() : letters;
370
+ }
353
371
  default: return String(pageNumber);
354
372
  }
355
373
  }
356
374
  const formatSectionPageNumber = (pageNumber, format) => formatOoxmlCounter(pageNumber, format);
357
375
  /**
376
+ * Apply a `\#` numeric picture (ECMA-376 §17.16.4.2) to an integer field
377
+ * value. `0` is a mandatory digit placeholder that zero-pads once the value
378
+ * runs out of digits; `#` is an optional placeholder that is left blank
379
+ * instead; every other picture character (including a thousands separator)
380
+ * is copied through literally. Placeholders line up with the value's digits
381
+ * from the right; digits that reach past the leftmost placeholder are kept,
382
+ * not truncated.
383
+ */
384
+ function applyNumericPicture(value, picture) {
385
+ const negative = value < 0;
386
+ const digits = [...String(Math.trunc(Math.abs(value)))];
387
+ const pictureChars = [...picture];
388
+ const output = Array.from({ length: pictureChars.length });
389
+ let digitIndex = digits.length - 1;
390
+ for (let i = pictureChars.length - 1; i >= 0; i--) {
391
+ const char = pictureChars[i];
392
+ if (char === "0" || char === "#") if (digitIndex >= 0) {
393
+ output[i] = digits[digitIndex];
394
+ digitIndex--;
395
+ } else output[i] = char === "0" ? "0" : "";
396
+ else output[i] = char;
397
+ }
398
+ const overflow = digitIndex >= 0 ? digits.slice(0, digitIndex + 1).join("") : "";
399
+ return (negative ? "-" : "") + overflow + output.join("");
400
+ }
401
+ /**
358
402
  * Convert number to uppercase Roman numerals
359
403
  */
360
404
  function toRoman(num) {
@@ -555,4 +599,4 @@ function getMergeFieldNames(fields) {
555
599
  }).filter((name) => !!name);
556
600
  }
557
601
  //#endregion
558
- export { KNOWN_FIELD_TYPES, 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 };
602
+ export { KNOWN_FIELD_TYPES, 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 };
@@ -1,5 +1,5 @@
1
1
  import { DERIVED_PART_ROOT_ATTRIBUTES, attributeRemainder } from "./attributeRemainder.js";
2
- import { CAPTURE, dispatchChildren } from "./containerChildren.js";
2
+ import { CAPTURE, dispatchChildrenWithContext } from "./containerChildren.js";
3
3
  import { getAttribute, parseXmlDocument } from "./xmlParser.js";
4
4
  //#region src/docx/fontTableParser.ts
5
5
  const FONT_FAMILIES = [
@@ -22,14 +22,12 @@ const parseFontTable = (xml) => {
22
22
  const root = parseXmlDocument(xml);
23
23
  if (!root) return;
24
24
  const fonts = [];
25
- const preserved = dispatchChildren({
25
+ const preserved = dispatchChildrenWithContext({
26
26
  element: root,
27
27
  container: "w:fonts",
28
28
  capturePosition: () => fonts.length,
29
- handlers: { font: (element) => {
30
- const font = parseFont(element);
31
- if (font) fonts.push(font);
32
- } }
29
+ handlers: FONT_TABLE_HANDLERS,
30
+ context: fonts
33
31
  });
34
32
  const preservedAttributes = attributeRemainder({
35
33
  element: root,
@@ -45,31 +43,18 @@ const parseFontTable = (xml) => {
45
43
  const parseFont = (element) => {
46
44
  const name = getAttribute(element, "w", "name");
47
45
  if (!name) return;
48
- const font = { name };
49
- let modelled = 0;
50
- const read = (key, value) => {
51
- if (value === void 0) return;
52
- font[key] = value;
53
- modelled += 1;
46
+ const walk = {
47
+ font: { name },
48
+ modelled: 0
54
49
  };
55
- const preserved = dispatchChildren({
50
+ const preserved = dispatchChildrenWithContext({
56
51
  element,
57
52
  container: "w:font",
58
- capturePosition: () => modelled,
59
- handlers: {
60
- altName: (child) => read("altName", value(child)),
61
- panose1: (child) => read("panose1", value(child)),
62
- charset: (child) => read("charset", charsetOf(child)),
63
- family: (child) => read("family", narrow(value(child), FONT_FAMILIES)),
64
- notTrueType: CAPTURE,
65
- pitch: (child) => read("pitch", narrow(value(child), FONT_PITCHES)),
66
- sig: (child) => read("sig", signatureOf(child)),
67
- embedRegular: (child) => read("embedRegular", embedOf(child)),
68
- embedBold: (child) => read("embedBold", embedOf(child)),
69
- embedItalic: (child) => read("embedItalic", embedOf(child)),
70
- embedBoldItalic: (child) => read("embedBoldItalic", embedOf(child))
71
- }
53
+ capturePosition: () => walk.modelled,
54
+ handlers: FONT_HANDLERS,
55
+ context: walk
72
56
  });
57
+ const { font } = walk;
73
58
  if (preserved !== void 0) font.preserved = preserved;
74
59
  const preservedAttributes = attributeRemainder({
75
60
  element,
@@ -129,5 +114,27 @@ const signatureOf = (element) => {
129
114
  return Object.keys(signature).length === 0 ? void 0 : signature;
130
115
  };
131
116
  const narrow = (carried, members) => members.find((member) => member === carried);
117
+ const FONT_TABLE_HANDLERS = { font: (element, fonts) => {
118
+ const font = parseFont(element);
119
+ if (font) fonts.push(font);
120
+ } };
121
+ const read = (walk, key, carried) => {
122
+ if (carried === void 0) return;
123
+ walk.font[key] = carried;
124
+ walk.modelled += 1;
125
+ };
126
+ const FONT_HANDLERS = {
127
+ altName: (child, walk) => read(walk, "altName", value(child)),
128
+ panose1: (child, walk) => read(walk, "panose1", value(child)),
129
+ charset: (child, walk) => read(walk, "charset", charsetOf(child)),
130
+ family: (child, walk) => read(walk, "family", narrow(value(child), FONT_FAMILIES)),
131
+ notTrueType: CAPTURE,
132
+ pitch: (child, walk) => read(walk, "pitch", narrow(value(child), FONT_PITCHES)),
133
+ sig: (child, walk) => read(walk, "sig", signatureOf(child)),
134
+ embedRegular: (child, walk) => read(walk, "embedRegular", embedOf(child)),
135
+ embedBold: (child, walk) => read(walk, "embedBold", embedOf(child)),
136
+ embedItalic: (child, walk) => read(walk, "embedItalic", embedOf(child)),
137
+ embedBoldItalic: (child, walk) => read(walk, "embedBoldItalic", embedOf(child))
138
+ };
132
139
  //#endregion
133
140
  export { parseFontTable };
@@ -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
  import { parseEndnoteProperties, parseFootnoteProperties } from "./notePropertiesParser.js";
6
7
  //#region src/docx/footnoteParser.d.ts
@@ -53,7 +54,7 @@ type EndnoteMap = {
53
54
  * @param media - Media files for images
54
55
  * @returns FootnoteMap with all footnotes
55
56
  */
56
- declare function parseFootnotes(footnotesXml: string | null, 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): FootnoteMap;
57
+ declare function parseFootnotes(footnotesXml: string | null, 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): FootnoteMap;
57
58
  /**
58
59
  * Parse endnotes.xml
59
60
  *
@@ -65,7 +66,7 @@ declare function parseFootnotes(footnotesXml: string | null, styles?: StyleMap |
65
66
  * @param media - Media files for images
66
67
  * @returns EndnoteMap with all endnotes
67
68
  */
68
- declare function parseEndnotes(endnotesXml: string | null, 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): EndnoteMap;
69
+ declare function parseEndnotes(endnotesXml: string | null, 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): EndnoteMap;
69
70
  /**
70
71
  * Get plain text content of a footnote.
71
72
  *