@stll/folio-core 0.43.0 → 0.44.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 (183) hide show
  1. package/dist/ai-edits/headless.js +6 -5
  2. package/dist/ai-edits/index.d.ts +2 -2
  3. package/dist/ai-edits/index.js +2 -2
  4. package/dist/ai-edits/snapshot.js +13 -9
  5. package/dist/compare/content-alignment.js +16 -1
  6. package/dist/compare/inline-atoms.js +1 -1
  7. package/dist/compare/style-resources.js +6 -0
  8. package/dist/docx/appVersionNormalization.d.ts +0 -18
  9. package/dist/docx/blockContentParser.js +8 -0
  10. package/dist/docx/blockRangeMarkers.d.ts +36 -0
  11. package/dist/docx/blockRangeMarkers.js +59 -0
  12. package/dist/docx/bookmarkParser.d.ts +2 -20
  13. package/dist/docx/bookmarkParser.js +6 -30
  14. package/dist/docx/borderParser.d.ts +13 -0
  15. package/dist/docx/borderParser.js +71 -0
  16. package/dist/docx/builtInStyles.d.ts +165 -0
  17. package/dist/docx/builtInStyles.js +239 -0
  18. package/dist/docx/commentIdNormalization.d.ts +3 -1
  19. package/dist/docx/commentIdNormalization.js +18 -1
  20. package/dist/docx/commentParser.d.ts +2 -1
  21. package/dist/docx/commentParser.js +34 -7
  22. package/dist/docx/commentReferenceNormalization.d.ts +4 -1
  23. package/dist/docx/commentReferenceNormalization.js +23 -14
  24. package/dist/docx/danglingRelationshipReferences.d.ts +15 -0
  25. package/dist/docx/danglingRelationshipReferences.js +30 -0
  26. package/dist/docx/defaultParagraphStyle.d.ts +18 -1
  27. package/dist/docx/defaultParagraphStyle.js +23 -1
  28. package/dist/docx/documentParser.d.ts +2 -1
  29. package/dist/docx/documentParser.js +2 -2
  30. package/dist/docx/drawingUtils.d.ts +8 -1
  31. package/dist/docx/drawingUtils.js +12 -3
  32. package/dist/docx/fieldParser.js +3 -5
  33. package/dist/docx/footnoteParser.d.ts +3 -2
  34. package/dist/docx/footnoteParser.js +19 -4
  35. package/dist/docx/groupDrawingParser.js +1 -1
  36. package/dist/docx/headerFooterRefParser.d.ts +4 -3
  37. package/dist/docx/headerFooterRefParser.js +42 -12
  38. package/dist/docx/headerFooterReferenceNormalization.d.ts +4 -1
  39. package/dist/docx/headerFooterReferenceNormalization.js +5 -1
  40. package/dist/docx/hyperlinkParser.js +11 -15
  41. package/dist/docx/imageParser.d.ts +1 -1
  42. package/dist/docx/imageParser.js +22 -18
  43. package/dist/docx/imageRawXml.js +5 -5
  44. package/dist/docx/markupRangeMarker.d.ts +15 -0
  45. package/dist/docx/markupRangeMarker.js +44 -0
  46. package/dist/docx/noteReferenceStyles.d.ts +29 -0
  47. package/dist/docx/noteReferenceStyles.js +70 -0
  48. package/dist/docx/numberingReferenceNormalization.d.ts +4 -1
  49. package/dist/docx/numberingReferenceNormalization.js +20 -1
  50. package/dist/docx/paraIdRangeNormalization.d.ts +0 -19
  51. package/dist/docx/paragraphParser.js +66 -99
  52. package/dist/docx/paragraphPropertySource.js +1 -0
  53. package/dist/docx/paragraphTraversal.d.ts +37 -1
  54. package/dist/docx/paragraphTraversal.js +84 -1
  55. package/dist/docx/parseContext.d.ts +37 -0
  56. package/dist/docx/parseContext.js +67 -0
  57. package/dist/docx/parseWarningMessage.d.ts +6 -0
  58. package/dist/docx/parseWarningMessage.js +44 -0
  59. package/dist/docx/parser.js +81 -27
  60. package/dist/docx/relsParser.d.ts +28 -11
  61. package/dist/docx/relsParser.js +26 -13
  62. package/dist/docx/revisionIdNormalization.js +81 -7
  63. package/dist/docx/rezip.js +63 -22
  64. package/dist/docx/runConsolidator.js +1 -2
  65. package/dist/docx/runParser.d.ts +8 -1
  66. package/dist/docx/runParser.js +30 -48
  67. package/dist/docx/sectionParser.d.ts +2 -1
  68. package/dist/docx/sectionParser.js +21 -65
  69. package/dist/docx/serializer/borderSerializer.d.ts +1 -2
  70. package/dist/docx/serializer/commentSerializer.js +22 -9
  71. package/dist/docx/serializer/documentSerializer.d.ts +1 -5
  72. package/dist/docx/serializer/documentSerializer.js +6 -16
  73. package/dist/docx/serializer/headerFooterSerializer.js +5 -0
  74. package/dist/docx/serializer/markupRangeAttributes.d.ts +8 -0
  75. package/dist/docx/serializer/markupRangeAttributes.js +24 -0
  76. package/dist/docx/serializer/noteSerializer.js +5 -0
  77. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -5
  78. package/dist/docx/serializer/paragraphSerializer.js +29 -35
  79. package/dist/docx/serializer/runSerializer.js +13 -7
  80. package/dist/docx/serializer/tableSerializer.js +28 -13
  81. package/dist/docx/serializer/textFormattingSerializer.d.ts +2 -3
  82. package/dist/docx/server/build.js +8 -1
  83. package/dist/docx/server/createBilingualDocument.js +10 -18
  84. package/dist/docx/server/extractDocxText.js +3 -4
  85. package/dist/docx/shadingParser.d.ts +6 -0
  86. package/dist/docx/shadingParser.js +32 -0
  87. package/dist/docx/shapeParser.js +3 -3
  88. package/dist/docx/styleParser.js +13 -87
  89. package/dist/docx/styleReferenceResolution.d.ts +36 -0
  90. package/dist/docx/styleReferenceResolution.js +51 -0
  91. package/dist/docx/tableLook.d.ts +57 -0
  92. package/dist/docx/tableLook.js +63 -0
  93. package/dist/docx/tableParser.d.ts +7 -9
  94. package/dist/docx/tableParser.js +64 -110
  95. package/dist/docx/textBoxParser.js +4 -4
  96. package/dist/docx/trackedMoveRangeNormalization.d.ts +3 -1
  97. package/dist/docx/trackedMoveRangeNormalization.js +11 -21
  98. package/dist/docx/transitionalSpelling.d.ts +13 -2
  99. package/dist/docx/transitionalSpelling.js +23 -1
  100. package/dist/docx/verbatimCapture.js +4 -11
  101. package/dist/docx/vmlImageParser.js +2 -2
  102. package/dist/docx/watermarkParser.js +2 -2
  103. package/dist/docx/xmlParser.d.ts +22 -32
  104. package/dist/docx/xmlParser.js +36 -21
  105. package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
  106. package/dist/internal/paragraphFormattingSerialization.d.ts +2 -3
  107. package/dist/internal/paragraphFormattingSerialization.js +26 -6
  108. package/dist/layout-bridge/convert/footnoteLayout.js +2 -7
  109. package/dist/layout-engine/index.d.ts +2 -2
  110. package/dist/layout-engine/index.js +2 -2
  111. package/dist/layout-engine/measure/measureBlocks.js +1 -6
  112. package/dist/layout-engine/types.d.ts +8 -2
  113. package/dist/layout-engine/types.js +35 -2
  114. package/dist/markdown/index.js +1 -1
  115. package/dist/markdown/internals.d.ts +6 -1
  116. package/dist/markdown/internals.js +14 -1
  117. package/dist/markdown/renderBlock.js +35 -21
  118. package/dist/markdown/renderParagraph.js +14 -5
  119. package/dist/markdown/renderRuns.js +4 -3
  120. package/dist/markdown/renderTable.js +4 -3
  121. package/dist/markdown/trailers.js +41 -7
  122. package/dist/markdown/types.d.ts +3 -7
  123. package/dist/prosemirror/attrs/index.js +2 -5
  124. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +11 -1
  125. package/dist/prosemirror/bookmarkBoundaryAttrs.js +18 -3
  126. package/dist/prosemirror/commands/index.d.ts +3 -3
  127. package/dist/prosemirror/commands/index.js +2 -2
  128. package/dist/prosemirror/commands/paragraph.d.ts +3 -3
  129. package/dist/prosemirror/commands/paragraph.js +2 -2
  130. package/dist/prosemirror/commentIdAllocator.js +2 -7
  131. package/dist/prosemirror/conversion/fromProseDoc.js +129 -40
  132. package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -14
  133. package/dist/prosemirror/conversion/toProseDoc.js +375 -316
  134. package/dist/prosemirror/extensions/core/ParagraphExtension.d.ts +14 -1
  135. package/dist/prosemirror/extensions/core/ParagraphExtension.js +11 -6
  136. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -3
  137. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +4 -1
  138. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +6 -2
  139. package/dist/prosemirror/extensions/features/pastedHeadingStyles.d.ts +7 -0
  140. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +74 -0
  141. package/dist/prosemirror/extensions/marks/markUtils.d.ts +11 -3
  142. package/dist/prosemirror/extensions/marks/markUtils.js +98 -19
  143. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +7 -3
  144. package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
  145. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
  146. package/dist/prosemirror/extensions/nodes/TableExtension.js +15 -1
  147. package/dist/prosemirror/extensions/types.d.ts +2 -2
  148. package/dist/prosemirror/index.d.ts +3 -3
  149. package/dist/prosemirror/index.js +3 -3
  150. package/dist/prosemirror/insertOperations.d.ts +9 -2
  151. package/dist/prosemirror/insertOperations.js +9 -4
  152. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +159 -0
  153. package/dist/prosemirror/paragraphFormattingProvenance.js +106 -0
  154. package/dist/prosemirror/plugins/documentStyles.d.ts +9 -1
  155. package/dist/prosemirror/plugins/documentStyles.js +11 -1
  156. package/dist/prosemirror/plugins/index.d.ts +2 -2
  157. package/dist/prosemirror/plugins/index.js +2 -2
  158. package/dist/prosemirror/plugins/revisionIds.d.ts +11 -2
  159. package/dist/prosemirror/plugins/revisionIds.js +21 -6
  160. package/dist/prosemirror/runFormattingReconciliation.js +3 -2
  161. package/dist/prosemirror/runStyleFormatting.d.ts +1 -1
  162. package/dist/prosemirror/schema/nodes.d.ts +31 -0
  163. package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -0
  164. package/dist/prosemirror/styles/styleResolver.d.ts +9 -0
  165. package/dist/prosemirror/styles/styleResolver.js +12 -0
  166. package/dist/style-engine/styleEngine.d.ts +3 -0
  167. package/dist/style-engine/styleEngine.js +3 -0
  168. package/dist/style-sets/extract.js +1 -23
  169. package/dist/style-sets/stellaStyle.js +46 -39
  170. package/dist/style-sets/styleSetNormalization.d.ts +19 -0
  171. package/dist/style-sets/styleSetNormalization.js +99 -0
  172. package/dist/types/content.d.ts +2 -2
  173. package/dist/utils/createDocument.js +145 -20
  174. package/dist/utils/headingCollector.d.ts +8 -5
  175. package/dist/utils/headingCollector.js +23 -25
  176. package/dist/utils/tableOfContentsStyle.js +9 -2
  177. package/package.json +2 -2
  178. package/dist/docx/textWhitespace.d.ts +0 -4
  179. package/dist/docx/textWhitespace.js +0 -4
  180. package/dist/layout-bridge/engine/tableWidthUtils.d.ts +0 -6
  181. package/dist/layout-bridge/engine/tableWidthUtils.js +0 -25
  182. package/dist/markdown/headings.d.ts +0 -13
  183. package/dist/markdown/headings.js +0 -20
@@ -1,11 +1,16 @@
1
+ import { attachPendingRangeMarkers, attachTrailingRangeMarkers, isBlockRangeMarker } from "./blockRangeMarkers.js";
1
2
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
2
3
  import { appendBookmarkMarkerToLastParagraphInBlocks, appendBookmarkMarkerToLastParagraphInCells, prependBookmarkMarkersToFirstParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInCell } from "./bookmarkPlacement.js";
4
+ import { parseBorderSpec } from "./borderParser.js";
3
5
  import { parseParagraph } from "./paragraphParser.js";
4
6
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
5
- import { BorderStyleSchema, FloatingTableXSpecSchema, FloatingTableYSpecSchema, ShadingPatternSchema, TableCellTextDirectionSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
7
+ import { FloatingTableXSpecSchema, FloatingTableYSpecSchema, TableCellTextDirectionSchema, narrowEnum } from "./parserEnums.js";
8
+ import { parseShading } from "./shadingParser.js";
9
+ import { TABLE_LOOK_FLAGS } from "./tableLook.js";
6
10
  import { parsePropertyChangeInfo, parseTrackedChangeInfo } from "./trackedChangeInfo.js";
11
+ import { percentageSpelling, transitionalSlotEncoding } from "./transitionalSpelling.js";
7
12
  import { captureVerbatimXml } from "./verbatimCapture.js";
8
- import { cloneElement, findChild, findChildByLocalName, findChildren, getAttribute, getChildElements, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
13
+ import { cloneElement, findChild, findChildByLocalName, findChildren, getAttribute, getChildElements, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseOnOffAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
9
14
  //#region src/docx/tableParser.ts
10
15
  /**
11
16
  * Sanity cap on `w:gridSpan` (and the derived table column count). Word's
@@ -22,15 +27,32 @@ const MAX_TABLE_COLUMNS = 63;
22
27
  */
23
28
  function parseTableMeasurement(element) {
24
29
  if (!element) return;
25
- const typeStr = getAttribute(element, "w", "type") ?? "dxa";
26
- let type = "dxa";
27
- if (typeStr === "auto" || typeStr === "dxa" || typeStr === "nil" || typeStr === "pct") type = typeStr;
30
+ const declared = getAttribute(element, "w", "type");
31
+ const type = tableWidthType(element, declared === "auto" || declared === "dxa" || declared === "nil" || declared === "pct" ? declared : void 0);
28
32
  return {
29
33
  value: parseTableMeasurementValue(element, type) ?? 0,
30
34
  type
31
35
  };
32
36
  }
33
37
  /**
38
+ * What unit `w:w` counts in.
39
+ *
40
+ * `w:type` is optional on `CT_TblWidth` and the schema gives it no default, so
41
+ * reading an absent one as `dxa` turned `w:w="50%"` into 50 twips: a
42
+ * full-width table became a hairline. `w:w` is `ST_MeasurementOrPercent`, so a
43
+ * value spelled with a `%` is a percentage whatever `w:type` says — the
44
+ * spelling carries its own unit, and no number of twips is ever written that
45
+ * way. `auto` and `nil` are left alone: neither reads `w:w` as a width at all.
46
+ */
47
+ const tableWidthType = (element, declared) => {
48
+ if (declared === "auto" || declared === "nil") return declared;
49
+ const raw = getAttribute(element, "w", "w");
50
+ const spelledAsPercent = raw !== null && percentageSpelling(raw) !== void 0;
51
+ const slotTakesPercent = transitionalSlotEncoding(element.namespaceUri, getLocalName(element.name), "w")?.percent !== void 0;
52
+ if (spelledAsPercent && slotTakesPercent) return "pct";
53
+ return declared ?? "dxa";
54
+ };
55
+ /**
34
56
  * Parse width from an element (shorthand for common case)
35
57
  */
36
58
  function parseWidth(element) {
@@ -42,34 +64,6 @@ function parseWidth(element) {
42
64
  * @param element - Border element (w:top, w:bottom, etc.)
43
65
  * @returns Parsed border or undefined
44
66
  */
45
- function parseBorderSpec(element) {
46
- if (!element) return;
47
- const rawStyle = getAttribute(element, "w", "val") ?? "none";
48
- const border = { style: narrowEnum(rawStyle, BorderStyleSchema) ?? rawStyle };
49
- const sz = parseNumericAttribute(element, "w", "sz");
50
- if (sz !== void 0) border.size = sz;
51
- const space = parseNumericAttribute(element, "w", "space");
52
- if (space !== void 0) border.space = space;
53
- const color = getAttribute(element, "w", "color");
54
- const themeColor = getAttribute(element, "w", "themeColor");
55
- const themeTint = getAttribute(element, "w", "themeTint");
56
- const themeShade = getAttribute(element, "w", "themeShade");
57
- if (color || themeColor || themeTint || themeShade) {
58
- const colorVal = {};
59
- if (color === "auto") colorVal.auto = true;
60
- else if (color !== null) colorVal.rgb = color;
61
- const validatedThemeColor = narrowEnum(themeColor, ThemeColorSlotSchema);
62
- if (validatedThemeColor) colorVal.themeColor = validatedThemeColor;
63
- if (themeTint !== null) colorVal.themeTint = themeTint;
64
- if (themeShade !== null) colorVal.themeShade = themeShade;
65
- border.color = colorVal;
66
- }
67
- const shadow = getAttribute(element, "w", "shadow");
68
- if (shadow === "1" || shadow === "true") border.shadow = true;
69
- const frame = getAttribute(element, "w", "frame");
70
- if (frame === "1" || frame === "true") border.frame = true;
71
- return border;
72
- }
73
67
  /**
74
68
  * Parse table borders (w:tblBorders or w:tcBorders)
75
69
  *
@@ -125,33 +119,13 @@ function parseCellMargins(marginsElement) {
125
119
  return margins;
126
120
  }
127
121
  /**
128
- * Parse shading properties (w:shd)
122
+ * Read a `w:tblLook` (the only reader; `styleParser` calls this one).
129
123
  *
130
- * @param shdElement - The w:shd element
131
- * @returns Parsed shading or undefined
132
- */
133
- function parseShading(shdElement) {
134
- if (!shdElement) return;
135
- const shading = {};
136
- const fillStr = getAttribute(shdElement, "w", "fill");
137
- if (fillStr && fillStr !== "auto") shading.fill = { rgb: fillStr };
138
- const themeFill = narrowEnum(getAttribute(shdElement, "w", "themeFill"), ThemeColorSlotSchema);
139
- if (themeFill) {
140
- shading.fill = { themeColor: themeFill };
141
- const themeFillTint = getAttribute(shdElement, "w", "themeFillTint");
142
- if (themeFillTint) shading.fill.themeTint = themeFillTint;
143
- const themeFillShade = getAttribute(shdElement, "w", "themeFillShade");
144
- if (themeFillShade) shading.fill.themeShade = themeFillShade;
145
- }
146
- const colorStr = getAttribute(shdElement, "w", "color");
147
- if (colorStr && colorStr !== "auto") shading.color = { rgb: colorStr };
148
- const pattern = narrowEnum(getAttribute(shdElement, "w", "val"), ShadingPatternSchema);
149
- if (pattern) shading.pattern = pattern;
150
- if (Object.keys(shading).length === 0) return;
151
- return shading;
152
- }
153
- /**
154
- * Parse table look flags (w:tblLook)
124
+ * What the author wrote, and nothing more: `w:val` verbatim and each flag as
125
+ * stated, absent, `false` or `true`. Folding `w:val`'s bits into the flags here
126
+ * would forget which of the two the document said, and writing the result back
127
+ * would invent attributes the author never had. `resolveTableLook` owns the
128
+ * other direction.
155
129
  *
156
130
  * @param lookElement - The w:tblLook element
157
131
  * @returns Parsed table look or undefined
@@ -159,29 +133,11 @@ function parseShading(shdElement) {
159
133
  function parseTableLook(lookElement) {
160
134
  if (!lookElement) return;
161
135
  const look = {};
162
- const firstRow = getAttribute(lookElement, "w", "firstRow");
163
- if (firstRow === "1" || firstRow === "true") look.firstRow = true;
164
- const lastRow = getAttribute(lookElement, "w", "lastRow");
165
- if (lastRow === "1" || lastRow === "true") look.lastRow = true;
166
- const firstColumn = getAttribute(lookElement, "w", "firstColumn");
167
- if (firstColumn === "1" || firstColumn === "true") look.firstColumn = true;
168
- const lastColumn = getAttribute(lookElement, "w", "lastColumn");
169
- if (lastColumn === "1" || lastColumn === "true") look.lastColumn = true;
170
- const noHBand = getAttribute(lookElement, "w", "noHBand");
171
- if (noHBand === "1" || noHBand === "true") look.noHBand = true;
172
- const noVBand = getAttribute(lookElement, "w", "noVBand");
173
- if (noVBand === "1" || noVBand === "true") look.noVBand = true;
174
136
  const val = getAttribute(lookElement, "w", "val");
175
- if (val) {
176
- const flags = Number.parseInt(val, 16);
177
- if (!Number.isNaN(flags)) {
178
- if (flags & 32) look.firstRow = true;
179
- if (flags & 64) look.lastRow = true;
180
- if (flags & 128) look.firstColumn = true;
181
- if (flags & 256) look.lastColumn = true;
182
- if (flags & 512) look.noHBand = true;
183
- if (flags & 1024) look.noVBand = true;
184
- }
137
+ if (val !== null && val !== "") look.val = val;
138
+ for (const flag of TABLE_LOOK_FLAGS) {
139
+ const stated = parseOnOffAttribute(lookElement, "w", flag);
140
+ if (stated !== void 0) look[flag] = stated;
185
141
  }
186
142
  if (Object.keys(look).length === 0) return;
187
143
  return look;
@@ -430,30 +386,18 @@ function parseTableRowProperties(trPrElement) {
430
386
  function parseConditionalFormatStyle(cnfElement) {
431
387
  if (!cnfElement) return;
432
388
  const style = {};
433
- const firstRow = getAttribute(cnfElement, "w", "firstRow");
434
- if (firstRow === "1" || firstRow === "true") style.firstRow = true;
435
- const lastRow = getAttribute(cnfElement, "w", "lastRow");
436
- if (lastRow === "1" || lastRow === "true") style.lastRow = true;
437
- const firstColumn = getAttribute(cnfElement, "w", "firstColumn");
438
- if (firstColumn === "1" || firstColumn === "true") style.firstColumn = true;
439
- const lastColumn = getAttribute(cnfElement, "w", "lastColumn");
440
- if (lastColumn === "1" || lastColumn === "true") style.lastColumn = true;
441
- const oddHBand = getAttribute(cnfElement, "w", "oddHBand");
442
- if (oddHBand === "1" || oddHBand === "true") style.oddHBand = true;
443
- const evenHBand = getAttribute(cnfElement, "w", "evenHBand");
444
- if (evenHBand === "1" || evenHBand === "true") style.evenHBand = true;
445
- const oddVBand = getAttribute(cnfElement, "w", "oddVBand");
446
- if (oddVBand === "1" || oddVBand === "true") style.oddVBand = true;
447
- const evenVBand = getAttribute(cnfElement, "w", "evenVBand");
448
- if (evenVBand === "1" || evenVBand === "true") style.evenVBand = true;
449
- const nwCell = getAttribute(cnfElement, "w", "firstRowFirstColumn");
450
- if (nwCell === "1" || nwCell === "true") style.nwCell = true;
451
- const neCell = getAttribute(cnfElement, "w", "firstRowLastColumn");
452
- if (neCell === "1" || neCell === "true") style.neCell = true;
453
- const swCell = getAttribute(cnfElement, "w", "lastRowFirstColumn");
454
- if (swCell === "1" || swCell === "true") style.swCell = true;
455
- const seCell = getAttribute(cnfElement, "w", "lastRowLastColumn");
456
- if (seCell === "1" || seCell === "true") style.seCell = true;
389
+ if (parseOnOffAttribute(cnfElement, "w", "firstRow") === true) style.firstRow = true;
390
+ if (parseOnOffAttribute(cnfElement, "w", "lastRow") === true) style.lastRow = true;
391
+ if (parseOnOffAttribute(cnfElement, "w", "firstColumn") === true) style.firstColumn = true;
392
+ if (parseOnOffAttribute(cnfElement, "w", "lastColumn") === true) style.lastColumn = true;
393
+ if (parseOnOffAttribute(cnfElement, "w", "oddHBand") === true) style.oddHBand = true;
394
+ if (parseOnOffAttribute(cnfElement, "w", "evenHBand") === true) style.evenHBand = true;
395
+ if (parseOnOffAttribute(cnfElement, "w", "oddVBand") === true) style.oddVBand = true;
396
+ if (parseOnOffAttribute(cnfElement, "w", "evenVBand") === true) style.evenVBand = true;
397
+ if (parseOnOffAttribute(cnfElement, "w", "firstRowFirstColumn") === true) style.nwCell = true;
398
+ if (parseOnOffAttribute(cnfElement, "w", "firstRowLastColumn") === true) style.neCell = true;
399
+ if (parseOnOffAttribute(cnfElement, "w", "lastRowFirstColumn") === true) style.swCell = true;
400
+ if (parseOnOffAttribute(cnfElement, "w", "lastRowLastColumn") === true) style.seCell = true;
457
401
  const val = getAttribute(cnfElement, "w", "val");
458
402
  if (val && val.length === 12) {
459
403
  if (val[0] === "1") style.firstRow = true;
@@ -530,6 +474,7 @@ function withContainerXmlns(options, element) {
530
474
  function parseCellContent(tcElement, styles, theme, numbering, rels, media, options) {
531
475
  const content = [];
532
476
  const pendingBookmarkMarkers = [];
477
+ const pendingRangeMarkers = [];
533
478
  const elements = getChildElements(tcElement);
534
479
  const parseCellChild = (child, childOptions = options) => {
535
480
  if (!child.name) return;
@@ -538,6 +483,7 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
538
483
  const para = parseParagraph(child, styles, theme, numbering, rels, media, childOptions);
539
484
  enrichParagraphTextBoxes(para, child, styles, theme, numbering, rels, media, parseTable);
540
485
  prependPendingBookmarkMarkers(para, pendingBookmarkMarkers);
486
+ attachPendingRangeMarkers(para, pendingRangeMarkers);
541
487
  content.push(para);
542
488
  return;
543
489
  }
@@ -545,6 +491,7 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
545
491
  const table = parseTable(child, styles, theme, numbering, rels, media, childOptions);
546
492
  if (!table) return;
547
493
  if (prependBookmarkMarkersToFirstParagraphInBlocks([table], pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
494
+ attachPendingRangeMarkers(table, pendingRangeMarkers);
548
495
  content.push(table);
549
496
  return;
550
497
  }
@@ -565,7 +512,9 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
565
512
  if (localName === "bookmarkStart" || localName === "bookmarkEnd") {
566
513
  const marker = parseBookmarkMarker(child, localName);
567
514
  if (!appendBookmarkMarkerToLastParagraphInBlocks(content, marker)) pendingBookmarkMarkers.push(marker);
515
+ return;
568
516
  }
517
+ if (isBlockRangeMarker(localName)) pendingRangeMarkers.push(captureVerbatimXml(child));
569
518
  };
570
519
  for (const child of elements) parseCellChild(child);
571
520
  if (content.length === 0) content.push({
@@ -573,6 +522,7 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
573
522
  content: [...pendingBookmarkMarkers]
574
523
  });
575
524
  else if (pendingBookmarkMarkers.length > 0) appendBookmarkMarkersToLastParagraphInBlocks(content, pendingBookmarkMarkers);
525
+ attachTrailingRangeMarkers(content, pendingRangeMarkers);
576
526
  return content;
577
527
  }
578
528
  /**
@@ -747,10 +697,14 @@ function parseTable(tblElement, styles, theme, numbering, rels, media, options)
747
697
  const gridElement = findChild(tblElement, "w", "tblGrid");
748
698
  const columnWidths = parseTableGrid(gridElement);
749
699
  if (columnWidths) table.columnWidths = columnWidths;
750
- if (gridElement) table.formatting = {
751
- ...table.formatting,
752
- gridSourceXml: captureVerbatimXml(gridElement)
753
- };
700
+ if (gridElement) {
701
+ const gridChange = findChild(gridElement, "w", "tblGridChange");
702
+ table.formatting = {
703
+ ...table.formatting,
704
+ gridSourceXml: captureVerbatimXml(gridElement),
705
+ ...gridChange ? { gridChangeXml: captureVerbatimXml(gridChange) } : {}
706
+ };
707
+ }
754
708
  const tableOptions = withContainerXmlns(options, tblElement);
755
709
  const rowsWithGridOffsets = /* @__PURE__ */ new Set();
756
710
  const parseTableChild = (child, childOptions = tableOptions) => {
@@ -878,4 +832,4 @@ function isFloatingTable(table) {
878
832
  return table.formatting?.floating !== void 0;
879
833
  }
880
834
  //#endregion
881
- export { MAX_TABLE_COLUMNS, getHeaderRows, getTableColumnCount, getTableRowCount, getTableText, hasHeaderRow, isCellHorizontallyMerged, isCellMergeContinuation, isCellMergeStart, isFloatingTable, parseBorderSpec, parseCellMargins, parseConditionalFormatStyle, parseFloatingTableProperties, parseShading, parseTable, parseTableBorders, parseTableCell, parseTableCellProperties, parseTableGrid, parseTableLook, parseTableMeasurement, parseTableProperties, parseTableRow, parseTableRowProperties };
835
+ export { MAX_TABLE_COLUMNS, getHeaderRows, getTableColumnCount, getTableRowCount, getTableText, hasHeaderRow, isCellHorizontallyMerged, isCellMergeContinuation, isCellMergeStart, isFloatingTable, parseCellMargins, parseConditionalFormatStyle, parseFloatingTableProperties, parseTable, parseTableBorders, parseTableCell, parseTableCellProperties, parseTableGrid, parseTableLook, parseTableMeasurement, parseTableProperties, parseTableRow, parseTableRowProperties };
@@ -1,6 +1,6 @@
1
1
  import { emuToPixels } from "../utils/units.js";
2
2
  import { parseAnchorPosition, parseAnchorWrap, parseFill, parseOutline, resolveColorValueToHex } from "./drawingUtils.js";
3
- import { findByFullName, findChildByLocalName, findChildByNamespaceUri, findChildrenByLocalName, findChildrenByNamespaceUri, getAttribute, getChildElements, parseNumericAttribute } from "./xmlParser.js";
3
+ import { findByFullName, findChildByLocalName, findChildByNamespaceUri, findChildrenByLocalName, findChildrenByNamespaceUri, getAttribute, getChildElements, parseNumericAttribute, parseOnOffAttribute } from "./xmlParser.js";
4
4
  //#region src/docx/textBoxParser.ts
5
5
  const DRAWINGML_MAIN_NAMESPACE_URIS = /* @__PURE__ */ new Set(["http://schemas.openxmlformats.org/drawingml/2006/main", "http://purl.oclc.org/ooxml/drawingml/main"]);
6
6
  const WORDPROCESSING_SHAPE_NAMESPACE_URIS = /* @__PURE__ */ new Set(["http://schemas.microsoft.com/office/word/2010/wordprocessingShape"]);
@@ -30,9 +30,9 @@ function parseBodyProperties(bodyPr) {
30
30
  else if (findChildByLocalName(bodyPr, "noAutofit")) result.autoFit = "none";
31
31
  const verticalAlign = parseTextBoxVerticalAlign(getAttribute(bodyPr, null, "anchor"));
32
32
  if (verticalAlign) result.verticalAlign = verticalAlign;
33
- const fromWordArt = getAttribute(bodyPr, null, "fromWordArt");
33
+ const fromWordArt = parseOnOffAttribute(bodyPr, null, "fromWordArt");
34
34
  const warp = findChildByNamespaceUri(bodyPr, DRAWINGML_MAIN_NAMESPACE_URIS, "prstTxWarp");
35
- if (fromWordArt !== null || warp) {
35
+ if (fromWordArt !== void 0 || warp) {
36
36
  const adjustments = warp ? findChildrenByNamespaceUri(findChildByNamespaceUri(warp, DRAWINGML_MAIN_NAMESPACE_URIS, "avLst"), DRAWINGML_MAIN_NAMESPACE_URIS, "gd").map((adjustment) => {
37
37
  const name = getAttribute(adjustment, null, "name");
38
38
  const formula = getAttribute(adjustment, null, "fmla");
@@ -43,7 +43,7 @@ function parseBodyProperties(bodyPr) {
43
43
  }).filter((adjustment) => adjustment !== void 0) : [];
44
44
  const preset = warp ? getAttribute(warp, null, "prst") : null;
45
45
  result.wordArt = {
46
- ...fromWordArt !== null ? { fromWordArt: fromWordArt === "1" || fromWordArt === "true" || fromWordArt === "on" } : {},
46
+ ...fromWordArt !== void 0 ? { fromWordArt } : {},
47
47
  ...preset !== null ? { preset } : {},
48
48
  ...adjustments.length > 0 ? { adjustments } : {}
49
49
  };
@@ -1,5 +1,7 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  //#region src/docx/trackedMoveRangeNormalization.d.ts
3
+ /** The code this normalisation is reported under, owned here, not at the caller. */
4
+ declare const UNBALANCED_MOVE_RANGE_WARNING: "unbalanced-move-range";
3
5
  type NormalizeTrackedMoveRangesInput = {
4
6
  documentBody: document_d_exports.DocumentBody;
5
7
  headers?: Map<string, document_d_exports.HeaderFooter>;
@@ -12,4 +14,4 @@ type NormalizeTrackedMoveRangesResult = {
12
14
  };
13
15
  declare const normalizeTrackedMoveRanges: ({ documentBody, headers, footers, footnotes, endnotes }: NormalizeTrackedMoveRangesInput) => NormalizeTrackedMoveRangesResult;
14
16
  //#endregion
15
- export { normalizeTrackedMoveRanges };
17
+ export { UNBALANCED_MOVE_RANGE_WARNING, normalizeTrackedMoveRanges };
@@ -1,5 +1,8 @@
1
- import { visitDocxParagraphs } from "./paragraphTraversal.js";
1
+ import { InlineContentRemovals, visitDocxParagraphs, visitInlineContentSlots } from "./paragraphTraversal.js";
2
+ import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
2
3
  //#region src/docx/trackedMoveRangeNormalization.ts
4
+ /** The code this normalisation is reported under, owned here, not at the caller. */
5
+ const UNBALANCED_MOVE_RANGE_WARNING = PARSE_WARNING_CODES.unbalancedMoveRange;
3
6
  const normalizeTrackedMoveRanges = ({ documentBody, headers, footers, footnotes, endnotes }) => {
4
7
  const rangeMarkers = [];
5
8
  visitDocxParagraphs({
@@ -9,10 +12,10 @@ const normalizeTrackedMoveRanges = ({ documentBody, headers, footers, footnotes,
9
12
  footnotes,
10
13
  endnotes
11
14
  }, (paragraph) => {
12
- for (const [index, content] of paragraph.content.entries()) {
13
- const marker = toMoveRangeMarkerRef(paragraph.content, index, content);
15
+ visitInlineContentSlots(paragraph, ({ content, index, item }) => {
16
+ const marker = toMoveRangeMarkerRef(content, index, item);
14
17
  if (marker) rangeMarkers.push(marker);
15
- }
18
+ });
16
19
  });
17
20
  return { removedUnbalancedMoveRangeMarkers: removeUnbalancedMoveRangeMarkers(rangeMarkers) };
18
21
  };
@@ -27,14 +30,9 @@ const removeUnbalancedMoveRangeMarkers = (rangeMarkers) => {
27
30
  }
28
31
  byRange.set(key, [marker]);
29
32
  }
30
- const removals = /* @__PURE__ */ new Map();
33
+ const removals = new InlineContentRemovals();
31
34
  const markForRemoval = (marker) => {
32
- const indexes = removals.get(marker.content);
33
- if (indexes) {
34
- indexes.add(marker.index);
35
- return;
36
- }
37
- removals.set(marker.content, /* @__PURE__ */ new Set([marker.index]));
35
+ removals.mark(marker);
38
36
  };
39
37
  for (const markers of byRange.values()) {
40
38
  let openStart = null;
@@ -55,15 +53,7 @@ const removeUnbalancedMoveRangeMarkers = (rangeMarkers) => {
55
53
  }
56
54
  if (openStart) markForRemoval(openStart);
57
55
  }
58
- let removedCount = 0;
59
- for (const [content, indexes] of removals.entries()) {
60
- if (indexes.size === 0) continue;
61
- const nextContent = content.filter((_, index) => !indexes.has(index));
62
- removedCount += content.length - nextContent.length;
63
- content.length = 0;
64
- content.push(...nextContent);
65
- }
66
- return removedCount;
56
+ return removals.apply();
67
57
  };
68
58
  const toMoveRangeMarkerRef = (content, index, marker) => {
69
59
  if (marker.type === "moveFromRangeStart") return {
@@ -97,4 +87,4 @@ const toMoveRangeMarkerRef = (content, index, marker) => {
97
87
  return null;
98
88
  };
99
89
  //#endregion
100
- export { normalizeTrackedMoveRanges };
90
+ export { UNBALANCED_MOVE_RANGE_WARNING, normalizeTrackedMoveRanges };
@@ -1,4 +1,4 @@
1
- import { SlotEncoding } from "./strictValueEncodings.gen.js";
1
+ import { PercentUnit, SlotEncoding } from "./strictValueEncodings.gen.js";
2
2
  //#region src/docx/transitionalSpelling.d.ts
3
3
  /**
4
4
  * The Transitional URI a Strict one stands for, or the URI unchanged.
@@ -12,6 +12,17 @@ declare const toTransitionalNamespaceUri: (uri: string) => string;
12
12
  declare const isStrictNamespaceUri: (uri: string) => boolean;
13
13
  /** Namespaces ECMA-376 Part 4 republished; nothing else starts with this. */
14
14
  declare const STRICT_URI_PREFIX = "http://purl.oclc.org/ooxml/";
15
+ /** How many of a unit's numbers make one whole percent. */
16
+ declare const NUMBERS_PER_PERCENT: Readonly<Record<PercentUnit, number>>;
17
+ /**
18
+ * The percent a value spells out, or undefined when it is not spelled as one.
19
+ *
20
+ * A value written `50%` says what it is; a value written `2500` needs its
21
+ * slot's unit to be read. Callers that must tell the two apart — the
22
+ * verbatim-capture conversion, and `CT_TblWidth`, whose `w:type` is optional —
23
+ * ask here rather than testing for a `%` themselves.
24
+ */
25
+ declare const percentageSpelling: (value: string) => number | undefined;
15
26
  /**
16
27
  * How one slot's Transitional type spells its value as a number.
17
28
  *
@@ -20,4 +31,4 @@ declare const STRICT_URI_PREFIX = "http://purl.oclc.org/ooxml/";
20
31
  */
21
32
  declare const transitionalSlotEncoding: (namespaceUri: string | undefined, elementLocalName: string, attributeLocalName?: string) => SlotEncoding | undefined;
22
33
  //#endregion
23
- export { STRICT_URI_PREFIX, isStrictNamespaceUri, toTransitionalNamespaceUri, transitionalSlotEncoding };
34
+ export { NUMBERS_PER_PERCENT, STRICT_URI_PREFIX, isStrictNamespaceUri, percentageSpelling, toTransitionalNamespaceUri, transitionalSlotEncoding };
@@ -21,6 +21,28 @@ const toTransitionalNamespaceUri = (uri) => TRANSITIONAL_NAMESPACE_BY_STRICT_URI
21
21
  const isStrictNamespaceUri = (uri) => TRANSITIONAL_NAMESPACE_BY_STRICT_URI.has(uri);
22
22
  /** Namespaces ECMA-376 Part 4 republished; nothing else starts with this. */
23
23
  const STRICT_URI_PREFIX = "http://purl.oclc.org/ooxml/";
24
+ /** `-?12.5%`: the one shape ECMA-376 gives a percentage that carries its unit. */
25
+ const PERCENTAGE = /^(-?[0-9]+(?:\.[0-9]+)?)%$/u;
26
+ /** How many of a unit's numbers make one whole percent. */
27
+ const NUMBERS_PER_PERCENT = {
28
+ fiftiethPercent: 50,
29
+ thousandthPercent: 1e3,
30
+ wholePercent: 1
31
+ };
32
+ /**
33
+ * The percent a value spells out, or undefined when it is not spelled as one.
34
+ *
35
+ * A value written `50%` says what it is; a value written `2500` needs its
36
+ * slot's unit to be read. Callers that must tell the two apart — the
37
+ * verbatim-capture conversion, and `CT_TblWidth`, whose `w:type` is optional —
38
+ * ask here rather than testing for a `%` themselves.
39
+ */
40
+ const percentageSpelling = (value) => {
41
+ const match = PERCENTAGE.exec(value.trim());
42
+ if (match === null) return;
43
+ const percent = Number(match[1]);
44
+ return Number.isNaN(percent) ? void 0 : percent;
45
+ };
24
46
  /**
25
47
  * How one slot's Transitional type spells its value as a number.
26
48
  *
@@ -33,4 +55,4 @@ const transitionalSlotEncoding = (namespaceUri, elementLocalName, attributeLocal
33
55
  return TRANSITIONAL_SLOT_ENCODINGS.get(attributeLocalName === void 0 ? slot : `${slot} @${attributeLocalName}`);
34
56
  };
35
57
  //#endregion
36
- export { STRICT_URI_PREFIX, isStrictNamespaceUri, toTransitionalNamespaceUri, transitionalSlotEncoding };
58
+ export { NUMBERS_PER_PERCENT, STRICT_URI_PREFIX, isStrictNamespaceUri, percentageSpelling, toTransitionalNamespaceUri, transitionalSlotEncoding };
@@ -1,5 +1,5 @@
1
1
  import { TRANSITIONAL_NAMESPACE_BY_STRICT_URI } from "./strictValueEncodings.gen.js";
2
- import { isStrictNamespaceUri, toTransitionalNamespaceUri, transitionalSlotEncoding } from "./transitionalSpelling.js";
2
+ import { NUMBERS_PER_PERCENT, isStrictNamespaceUri, percentageSpelling, toTransitionalNamespaceUri, transitionalSlotEncoding } from "./transitionalSpelling.js";
3
3
  import { roundHalfAwayFromZero, universalMeasureAs } from "./universalMeasure.js";
4
4
  import { NAMESPACES, OOXML_NAMESPACE_SCOPE, cloneElement, elementToXml, getChildElements, getLocalName, getNamespacePrefix, parseXml } from "./xmlParser.js";
5
5
  import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
@@ -52,13 +52,6 @@ const DRAWING_EXTENSION_MARKERS = [
52
52
  "/wordprocessingShape"
53
53
  ];
54
54
  const isUnschemadDrawingNamespace = (uri) => !TRANSITIONAL_URIS.has(uri) && DRAWING_EXTENSION_MARKERS.some((marker) => uri.includes(marker));
55
- /** `-?12.5%`: the one shape ECMA-376 gives a percentage that carries its unit. */
56
- const PERCENTAGE = /^(-?[0-9]+(?:\.[0-9]+)?)%$/u;
57
- const NUMBERS_PER_PERCENT = {
58
- fiftiethPercent: 50,
59
- thousandthPercent: 1e3,
60
- wholePercent: 1
61
- };
62
55
  /** The Transitional spelling of one Strict-produced value, or the value unchanged. */
63
56
  const transitionalValue = (value, namespaceUri, encoding) => {
64
57
  const measureUnit = encoding?.measure;
@@ -66,11 +59,11 @@ const transitionalValue = (value, namespaceUri, encoding) => {
66
59
  const measure = universalMeasureAs(value, measureUnit);
67
60
  if (measure !== void 0) return String(measure);
68
61
  }
69
- const percentage = PERCENTAGE.exec(value);
70
- if (percentage === null) return value;
62
+ const percentage = percentageSpelling(value);
63
+ if (percentage === void 0) return value;
71
64
  const percentUnit = encoding?.percent ?? (isUnschemadDrawingNamespace(namespaceUri) ? "thousandthPercent" : void 0);
72
65
  if (percentUnit === void 0) return value;
73
- return String(roundHalfAwayFromZero(Number(percentage[1]) * NUMBERS_PER_PERCENT[percentUnit]));
66
+ return String(roundHalfAwayFromZero(percentage * NUMBERS_PER_PERCENT[percentUnit]));
74
67
  };
75
68
  const originOf = (element, inherited) => {
76
69
  const uri = element.namespaceUri;
@@ -135,7 +135,7 @@ function shouldPreserveRawVmlPict(pictElement) {
135
135
  * `o:relid` instead, so fall back through those before the bare `id`.
136
136
  */
137
137
  function readImageDataRId(imagedata) {
138
- return getAttribute(imagedata, "r", "id") ?? getAttribute(imagedata, "r", "embed") ?? getAttribute(imagedata, "o", "relid") ?? getAttribute(imagedata, null, "id") ?? "";
138
+ return getAttribute(imagedata, "r", "id") ?? getAttribute(imagedata, "r", "embed") ?? getAttribute(imagedata, "o", "relid") ?? getAttribute(imagedata, null, "id") ?? void 0;
139
139
  }
140
140
  /**
141
141
  * Parse a `w:pict` element into an inline image, or null when it carries no
@@ -157,7 +157,7 @@ function parseVmlImageContent(pictElement, rels, media, rootXmlns = {}) {
157
157
  const imagedata = findChild(shape, "v", "imagedata");
158
158
  if (!imagedata) continue;
159
159
  const rId = readImageDataRId(imagedata);
160
- if (!rId) continue;
160
+ if (rId === void 0 || rId.length === 0) continue;
161
161
  if (isWatermarkShape(shape)) continue;
162
162
  const { src, mimeType, filename } = resolveImageData(rId, rels ?? void 0, media ?? void 0);
163
163
  const shapeStyle = parseVmlStyle(getAttribute(shape, null, "style"));
@@ -1,3 +1,4 @@
1
+ import { parseAnchorBehindDoc } from "./drawingUtils.js";
1
2
  import { captureVerbatimXml } from "./verbatimCapture.js";
2
3
  import { cloneWithXmlnsDeclarations, collectXmlnsDeclarations, findChild, findChildren, findDeep, getAttribute, getLocalName, getTextContent } from "./xmlParser.js";
3
4
  //#region src/docx/watermarkParser.ts
@@ -258,8 +259,7 @@ function collectDrawingMlBehindContentAnchors(header) {
258
259
  for (const drawing of collectByLocalName(header, "drawing")) {
259
260
  const anchor = findDeep(drawing, "wp", "anchor");
260
261
  if (!anchor) continue;
261
- const behindDoc = getAttribute(anchor, null, "behindDoc");
262
- if (behindDoc === "1" || behindDoc === "true") out.push(anchor);
262
+ if (parseAnchorBehindDoc(anchor)) out.push(anchor);
263
263
  }
264
264
  return out;
265
265
  }
@@ -1,24 +1,5 @@
1
+ import { ParseContext } from "./parseContext.js";
1
2
  //#region src/docx/xmlParser.d.ts
2
- /**
3
- * XML Parser Utilities for OOXML
4
- *
5
- * Provides helper functions for parsing Office Open XML (OOXML) content
6
- * with proper namespace handling.
7
- *
8
- * OOXML uses many namespaces:
9
- * - w: WordprocessingML (main document content)
10
- * - a: DrawingML (graphics)
11
- * - r: Relationships
12
- * - wp: Word Drawing positioning
13
- * - wps: Word Drawing shapes
14
- * - wpc: Word Drawing canvas
15
- * - wpg: Word Drawing group
16
- * - m: Math
17
- * - mc: Markup Compatibility
18
- * - v: VML (legacy vector graphics)
19
- * - o: Office (extensions)
20
- * - pic: Pictures
21
- */
22
3
  /**
23
4
  * XML element tree node — drop-in replacement for the `Element` type
24
5
  * previously imported from `xml-js`. Every consumer imports this from
@@ -249,14 +230,18 @@ declare function getAttributes(element: XmlElement | null | undefined): Record<s
249
230
  */
250
231
  declare function getTextContent(element: XmlElement | null | undefined): string;
251
232
  /**
252
- * Check if an element has a specific attribute with value "true" or "1"
233
+ * Read an `ST_OnOff` attribute.
253
234
  *
254
- * @param element - Element to check
255
- * @param namespace - Attribute namespace
256
- * @param name - Attribute name
257
- * @returns true if attribute exists and is truthy
235
+ * The type has three spellings per polarity — `1`/`true`/`on` and
236
+ * `0`/`false`/`off` — and producers use all of them. `undefined` means the
237
+ * author said nothing (absent, or a value outside the type), so the caller
238
+ * still owns what absence means for its own slot.
239
+ *
240
+ * Every on/off attribute goes through here: a hand-rolled `=== "1"` reads
241
+ * `w:beforeAutospacing="on"` as false, and the save path then writes `"0"`,
242
+ * inverting what the document said.
258
243
  */
259
- declare function hasFlag(element: XmlElement | null | undefined, namespace: string | null, name: string): boolean;
244
+ declare function parseOnOffAttribute(element: XmlElement | null | undefined, namespace: string | null, name: string, context?: ParseContext): boolean | undefined;
260
245
  /**
261
246
  * Check if a child element exists (used for boolean flags in OOXML)
262
247
  *
@@ -297,15 +282,20 @@ declare function parseNumericAttribute(element: XmlElement | null | undefined, n
297
282
  */
298
283
  declare function parseNumberingLevelAttribute(element: XmlElement | null | undefined): number | undefined;
299
284
  /**
300
- * Parse `w:w` on a table width/height element. For `w:type="pct"`, producers
301
- * sometimes emit human-readable percentages (`100%`) instead of 50ths-of-percent
302
- * (`5000`); normalize those to the ECMA-376 unit the layout engine expects.
285
+ * Parse `w:w` on a table width/height element. A percentage may be spelled the
286
+ * way it reads (`100%`) or as the number its slot counts in
287
+ * (50ths-of-percent, `5000`); the generated slot table says which unit that
288
+ * is, so the two spellings are not decided here.
303
289
  */
304
290
  declare function parseTableMeasurementValue(element: XmlElement | null | undefined, widthType: string): number | undefined;
305
291
  /**
306
292
  * Parse an OOXML `ST_OnOff` lexical value.
293
+ *
294
+ * `context` is optional and trailing on purpose: every call site that has one
295
+ * reports the value folio declined to read, and the hundred that do not yet
296
+ * thread one keep compiling and keep their behaviour.
307
297
  */
308
- declare function parseOnOffValue(value: string | null | undefined): boolean | undefined;
298
+ declare function parseOnOffValue(value: string | null | undefined, context?: ParseContext, element?: string): boolean | undefined;
309
299
  /**
310
300
  * Parse a boolean value from an attribute or element presence
311
301
  *
@@ -318,7 +308,7 @@ declare function parseOnOffValue(value: string | null | undefined): boolean | un
318
308
  * @param namespace - Namespace for val attribute
319
309
  * @returns boolean value
320
310
  */
321
- declare function parseBooleanElement(element: XmlElement | null | undefined, namespace?: string): boolean;
311
+ declare function parseBooleanElement(element: XmlElement | null | undefined, namespace?: string, context?: ParseContext): boolean;
322
312
  /**
323
313
  * Deep find - search recursively for an element
324
314
  *
@@ -378,4 +368,4 @@ declare function cloneWithXmlnsDeclarations(element: XmlElement, xmlnsDecls: Rec
378
368
  */
379
369
  declare function cloneElement(element: XmlElement, overrides: Partial<XmlElement>): XmlElement;
380
370
  //#endregion
381
- export { NAMESPACES, OFFICE_RELATIONSHIP_NAMESPACE_URIS, OOXML_NAMESPACE_SCOPE, WORDPROCESSINGML_NAMESPACE_URIS, XmlAttributeMatch, XmlElement, XmlNamespaceScope, attachXmlNamespaceContext, cloneElement, cloneWithXmlnsDeclarations, collectXmlnsDeclarations, elementToXml, findAllDeep, findAttributeByNamespaceUri, findByFullName, findChild, findChildByLocalName, findChildByNamespaceUri, findChildren, findChildrenByLocalName, findChildrenByNamespaceUri, findDeep, getAttribute, getAttributeAny, getAttributeAnyPrefix, getAttributeByNamespaceUri, getAttributes, getChildElements, getLocalName, getNamespacePrefix, getNamespaceUri, getTextContent, hasChild, hasFlag, matchesName, mergeXmlnsDeclarations, parseBooleanElement, parseColorElement, parseNumberingLevelAttribute, parseNumericAttribute, parseOnOffValue, parseTableMeasurementValue, parseXml, parseXmlDocument, selectAlternateContentBranch };
371
+ export { NAMESPACES, OFFICE_RELATIONSHIP_NAMESPACE_URIS, OOXML_NAMESPACE_SCOPE, WORDPROCESSINGML_NAMESPACE_URIS, XmlAttributeMatch, XmlElement, XmlNamespaceScope, attachXmlNamespaceContext, cloneElement, cloneWithXmlnsDeclarations, collectXmlnsDeclarations, elementToXml, findAllDeep, findAttributeByNamespaceUri, findByFullName, findChild, findChildByLocalName, findChildByNamespaceUri, findChildren, findChildrenByLocalName, findChildrenByNamespaceUri, findDeep, getAttribute, getAttributeAny, getAttributeAnyPrefix, getAttributeByNamespaceUri, getAttributes, getChildElements, getLocalName, getNamespacePrefix, getNamespaceUri, getTextContent, hasChild, matchesName, mergeXmlnsDeclarations, parseBooleanElement, parseColorElement, parseNumberingLevelAttribute, parseNumericAttribute, parseOnOffAttribute, parseOnOffValue, parseTableMeasurementValue, parseXml, parseXmlDocument, selectAlternateContentBranch };