@stll/folio-core 0.37.4 → 0.38.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 (131) hide show
  1. package/dist/ai-edits/apply.js +275 -88
  2. package/dist/ai-edits/clean-text.js +12 -1
  3. package/dist/ai-edits/headless.d.ts +110 -0
  4. package/dist/ai-edits/headless.js +569 -40
  5. package/dist/ai-edits/index.d.ts +2 -1
  6. package/dist/ai-edits/snapshot.d.ts +24 -1
  7. package/dist/ai-edits/snapshot.js +206 -9
  8. package/dist/ai-edits/table-geometry.d.ts +7 -7
  9. package/dist/ai-edits/table-geometry.js +43 -27
  10. package/dist/ai-edits/table-template.d.ts +2 -1
  11. package/dist/ai-edits/table-template.js +9 -3
  12. package/dist/ai-edits/types.d.ts +38 -16
  13. package/dist/compare/__fixtures__/body-sequence.d.ts +4 -0
  14. package/dist/compare/__fixtures__/body-sequence.js +5 -3
  15. package/dist/compare/compare.d.ts +26 -2
  16. package/dist/compare/compare.js +444 -16
  17. package/dist/compare/content-alignment.js +216 -137
  18. package/dist/compare/content-types.d.ts +36 -2
  19. package/dist/compare/content.d.ts +13 -10
  20. package/dist/compare/content.js +69 -23
  21. package/dist/compare/formatting.d.ts +4 -22
  22. package/dist/compare/formatting.js +8 -112
  23. package/dist/compare/inline-atom-resources.d.ts +6 -0
  24. package/dist/compare/inline-atom-resources.js +26 -0
  25. package/dist/compare/inline-atoms.d.ts +35 -0
  26. package/dist/compare/inline-atoms.js +383 -0
  27. package/dist/compare/inline-provenance.d.ts +36 -0
  28. package/dist/compare/inline-provenance.js +334 -0
  29. package/dist/compare/plan.d.ts +4 -1
  30. package/dist/compare/plan.js +32 -4
  31. package/dist/compare/scenario.d.ts +4 -6
  32. package/dist/compare/section-boundary-properties.d.ts +63 -0
  33. package/dist/compare/section-boundary-properties.js +235 -0
  34. package/dist/compare/style-resources.d.ts +30 -0
  35. package/dist/compare/style-resources.js +404 -0
  36. package/dist/compare/types.d.ts +50 -11
  37. package/dist/compare/types.js +3 -1
  38. package/dist/compare/verification.d.ts +3 -5
  39. package/dist/compare/verification.js +8 -39
  40. package/dist/compat/eigenpal.d.ts +4 -4
  41. package/dist/compat/eigenpal.js +3 -3
  42. package/dist/document-operations.d.ts +5 -3
  43. package/dist/document-operations.js +112 -5
  44. package/dist/docx/blockContentParser.js +14 -2
  45. package/dist/docx/drawingIdNormalization.js +43 -2
  46. package/dist/docx/drawingRelationships.d.ts +10 -0
  47. package/dist/docx/drawingRelationships.js +28 -0
  48. package/dist/docx/fieldParser.js +1 -1
  49. package/dist/docx/hyperlinkParser.js +3 -5
  50. package/dist/docx/imageRawXml.d.ts +8 -0
  51. package/dist/docx/imageRawXml.js +13 -0
  52. package/dist/docx/newImage.d.ts +2 -2
  53. package/dist/docx/newImage.js +3 -3
  54. package/dist/docx/numberingParser.d.ts +1 -13
  55. package/dist/docx/numberingParser.js +31 -37
  56. package/dist/docx/paragraphParser.js +12 -9
  57. package/dist/docx/paragraphPropertySource.d.ts +8 -5
  58. package/dist/docx/paragraphPropertySource.js +16 -4
  59. package/dist/docx/removeHeaderFooterParts.d.ts +14 -0
  60. package/dist/docx/removeHeaderFooterParts.js +87 -0
  61. package/dist/docx/rezip.d.ts +3 -1
  62. package/dist/docx/rezip.js +143 -41
  63. package/dist/docx/runParser.js +16 -5
  64. package/dist/docx/sectionParser.js +3 -0
  65. package/dist/docx/sectionReferenceHistory.d.ts +17 -0
  66. package/dist/docx/sectionReferenceHistory.js +59 -0
  67. package/dist/docx/selectiveSave.js +11 -31
  68. package/dist/docx/selectiveXmlPatch.d.ts +8 -1
  69. package/dist/docx/selectiveXmlPatch.js +62 -2
  70. package/dist/docx/serializer/borderSerializer.d.ts +4 -1
  71. package/dist/docx/serializer/borderSerializer.js +20 -18
  72. package/dist/docx/serializer/commentSerializer.js +1 -1
  73. package/dist/docx/serializer/numberingSerializer.js +1 -1
  74. package/dist/docx/serializer/paragraphSerializer.js +13 -177
  75. package/dist/docx/serializer/partNamespaces.d.ts +1 -1
  76. package/dist/docx/serializer/partNamespaces.js +4 -0
  77. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  78. package/dist/docx/serializer/runSerializer.js +4 -130
  79. package/dist/docx/serializer/sectionPropertiesSerializer.js +5 -2
  80. package/dist/docx/serializer/stylesSerializer.js +1 -1
  81. package/dist/docx/serializer/textFormattingSerializer.d.ts +17 -0
  82. package/dist/docx/serializer/textFormattingSerializer.js +144 -0
  83. package/dist/docx/tableParser.js +21 -11
  84. package/dist/docx/xmlParser.d.ts +10 -1
  85. package/dist/docx/xmlParser.js +23 -1
  86. package/dist/index.d.ts +4 -4
  87. package/dist/index.js +3 -3
  88. package/dist/internal/compare/inline-presentation.d.ts +20 -0
  89. package/dist/internal/compare/inline-presentation.js +222 -0
  90. package/dist/internal/paragraphFormattingSerialization.d.ts +25 -0
  91. package/dist/internal/paragraphFormattingSerialization.js +164 -0
  92. package/dist/internal/sectionReferenceResolution.d.ts +21 -0
  93. package/dist/internal/sectionReferenceResolution.js +72 -0
  94. package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
  95. package/dist/markdown/renderRuns.js +1 -0
  96. package/dist/markdown/renderTable.js +1 -0
  97. package/dist/prosemirror/attrs/index.js +20 -1
  98. package/dist/prosemirror/commands/comments.d.ts +11 -1
  99. package/dist/prosemirror/commands/comments.js +68 -6
  100. package/dist/prosemirror/commands/propertyChangeScope.d.ts +9 -3
  101. package/dist/prosemirror/commands/propertyChangeScope.js +4 -10
  102. package/dist/prosemirror/conversion/fromProseDoc.js +22 -22
  103. package/dist/prosemirror/conversion/toProseDoc.js +16 -57
  104. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
  105. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +3 -0
  106. package/dist/prosemirror/imageCommit.js +7 -9
  107. package/dist/prosemirror/paragraphIndentation.d.ts +21 -0
  108. package/dist/prosemirror/paragraphIndentation.js +72 -0
  109. package/dist/prosemirror/plugins/documentNumbering.d.ts +3 -1
  110. package/dist/prosemirror/plugins/documentNumbering.js +7 -1
  111. package/dist/prosemirror/plugins/documentStyles.d.ts +3 -1
  112. package/dist/prosemirror/plugins/documentStyles.js +7 -1
  113. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +3 -1
  114. package/dist/prosemirror/rebaseParagraphRunFormatting.js +2 -1
  115. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +15 -2
  116. package/dist/prosemirror/runFormattingInlineCarriers.js +33 -3
  117. package/dist/prosemirror/runStyleFormatting.d.ts +15 -2
  118. package/dist/prosemirror/runStyleFormatting.js +76 -2
  119. package/dist/prosemirror/schema/marks.d.ts +3 -1
  120. package/dist/prosemirror/schema/marks.js +2 -0
  121. package/dist/prosemirror/schema/nodes.d.ts +3 -0
  122. package/dist/prosemirror/tableCellRevisionVisibility.d.ts +6 -0
  123. package/dist/prosemirror/tableCellRevisionVisibility.js +14 -0
  124. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
  125. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
  126. package/dist/redline.js +15 -2
  127. package/dist/server.d.ts +3 -2
  128. package/dist/server.js +2 -2
  129. package/dist/version-comparison.d.ts +2 -0
  130. package/dist/version-comparison.js +30 -29
  131. package/package.json +2 -2
@@ -2,13 +2,12 @@ import { parseCommentsExtended } from "./commentParser.js";
2
2
  import { withoutOrphanCommentRanges } from "./commentRangeIntegrity.js";
3
3
  import { hasUnsynthesizedReplyRanges } from "./commentReplyMarkers.js";
4
4
  import { validateFolioDocumentModel } from "./modelValidation.js";
5
- import { isNewDataUrlDrawing } from "./newImage.js";
6
5
  import { parseNumbering } from "./numberingParser.js";
7
6
  import { isUnsafePackagePath } from "./packageParts.js";
8
7
  import { RELATIONSHIP_TYPES } from "./relsParser.js";
9
- import { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_PART_LOWER, addCommentsExtendedOverride, addCommentsExtendedRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, updateCoreProperties, withoutAttachedTemplate } from "./rezip.js";
8
+ import { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_PART_LOWER, addCommentsExtendedOverride, addCommentsExtendedRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedInlineResources, updateCoreProperties, withoutAttachedTemplate } from "./rezip.js";
10
9
  import "./selectiveSaveFlags.js";
11
- import { buildPatchedDocumentXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectChangedNumberingDefs, collectParaIds } from "./selectiveXmlPatch.js";
10
+ import { buildPatchedDocumentXml, buildPatchedNoteXml, collectParaIds, patchNumberingDefinitions } from "./selectiveXmlPatch.js";
12
11
  import { ensureThreadedCommentParaIds, serializeComments, serializeCommentsExtended } from "./serializer/commentSerializer.js";
13
12
  import { serializeDocument } from "./serializer/documentSerializer.js";
14
13
  import { serializeEndnotes, serializeFootnotes } from "./serializer/noteSerializer.js";
@@ -16,25 +15,6 @@ import { serializeNumberingXml } from "./serializer/numberingSerializer.js";
16
15
  import { readRootNamespaceBindings } from "./serializer/partNamespaces.js";
17
16
  //#region src/docx/selectiveSave.ts
18
17
  /**
19
- * Check if document content has new images (data: URL without rId) or
20
- * new hyperlinks (href without rId). Combined into a single traversal
21
- * to avoid walking the block tree twice.
22
- */
23
- function hasNewImagesOrHyperlinks(blocks) {
24
- const runHasNewImage = (run) => run.content.some(isNewDataUrlDrawing);
25
- for (const block of blocks) if (block.type === "paragraph") {
26
- for (const item of block.content) if (item.type === "run") {
27
- if (runHasNewImage(item)) return true;
28
- } else if (item.type === "hyperlink" && item.href && !item.rId && !item.anchor) return true;
29
- else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
30
- for (const sub of item.content) if (sub.type === "run" && runHasNewImage(sub)) return true;
31
- }
32
- } else if (block.type === "table") {
33
- for (const row of block.rows) for (const cell of row.cells) if (hasNewImagesOrHyperlinks(cell.content)) return true;
34
- }
35
- return false;
36
- }
37
- /**
38
18
  * Splice edited footnote/endnote paragraphs into their parts and return the
39
19
  * candidate ids that could NOT be routed to a note part (an id that is neither
40
20
  * a body nor a note paragraph — the caller bails on those).
@@ -139,7 +119,7 @@ async function ensureCommentsExtendedPackaging(zip, updates) {
139
119
  * Numbering definitions carry no `paraId`, so this is NOT keyed off
140
120
  * `changedParaIds` — it always runs (like the comments/header updates) and uses
141
121
  * a re-parse+re-serialize baseline to detect which `w:abstractNum` / `w:num`
142
- * definitions actually changed. The model omits parts of numbering.xml
122
+ * definitions changed or were minted. The model omits parts of numbering.xml
143
123
  * (`w:nsid`/`w:tmpl`, custom formats, level sub-elements), so only the changed
144
124
  * definitions are spliced by id; every other definition stays byte-exact.
145
125
  *
@@ -159,12 +139,12 @@ async function patchNumberingPart(zip, doc, updates) {
159
139
  }
160
140
  if (!file) return;
161
141
  const originalXml = await file.async("text");
162
- const baselineXml = serializeNumberingXml(parseNumbering(originalXml).definitions);
163
- const currentXml = serializeNumberingXml(numbering);
164
- const changed = collectChangedNumberingDefs(baselineXml, currentXml);
165
- if (changed.abstractNums.size === 0 && changed.nums.size === 0) return;
166
- const patched = buildPatchedNumberingXml(originalXml, currentXml, changed);
167
- if (patched === null) return;
142
+ const patched = patchNumberingDefinitions({
143
+ originalXml,
144
+ baselineXml: serializeNumberingXml(parseNumbering(originalXml).definitions),
145
+ currentXml: serializeNumberingXml(numbering)
146
+ });
147
+ if (patched === null || patched === originalXml) return;
168
148
  updates.set(file.name, patched);
169
149
  }
170
150
  /**
@@ -196,13 +176,13 @@ async function attemptSelectiveSave(doc, originalBuffer, options) {
196
176
  if (hasUntrackedChanges) return null;
197
177
  if (originalBuffer.byteLength > maxBytes) return null;
198
178
  const content = doc.package.document.content;
199
- if (hasNewImagesOrHyperlinks(content)) return null;
179
+ if (hasUnmaterializedInlineResources(content)) return null;
200
180
  for (const part of [
201
181
  ...doc.package.headers?.values() ?? [],
202
182
  ...doc.package.footers?.values() ?? [],
203
183
  ...doc.package.footnotes ?? [],
204
184
  ...doc.package.endnotes ?? []
205
- ]) if (hasNewImagesOrHyperlinks(part.content)) return null;
185
+ ]) if (hasUnmaterializedInlineResources(part.content)) return null;
206
186
  if (hasUnmaterializedHeaderFooter(doc)) return null;
207
187
  if (hasModelDrivenPictureWatermark(doc)) return null;
208
188
  if (withoutOrphanCommentRanges(doc) !== doc) return null;
@@ -159,6 +159,13 @@ declare function buildPatchedNumberingXml(originalXml: string, currentXml: strin
159
159
  * because they cannot be spliced by id; they are appended instead.
160
160
  */
161
161
  declare function collectAddedNumberingDefs(baselineXml: string, currentXml: string): ChangedNumberingDefs;
162
+ type PatchNumberingDefinitionsOptions = {
163
+ originalXml: string;
164
+ baselineXml: string;
165
+ currentXml: string;
166
+ };
167
+ /** Both save paths must write changed definitions and newly referenced instances together. */
168
+ declare const patchNumberingDefinitions: ({ originalXml, baselineXml, currentXml }: PatchNumberingDefinitionsOptions) => string | null;
162
169
  /**
163
170
  * Append added `w:abstractNum` / `w:num` definitions from `currentXml` to
164
171
  * `xml`. ECMA-376 §17.9 orders every `w:abstractNum` before the first `w:num`,
@@ -171,4 +178,4 @@ declare function collectAddedNumberingDefs(baselineXml: string, currentXml: stri
171
178
  */
172
179
  declare function appendNumberingDefs(xml: string, currentXml: string, added: ChangedNumberingDefs): string | null;
173
180
  //#endregion
174
- export { ChangedNumberingDefs, ParagraphOffsets, PatchSafetyOptions, PatchValidationResult, appendNumberingDefs, buildParagraphOffsetIndex, buildPatchedDocumentXml, buildPatchedNotePartXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectAddedNumberingDefs, collectChangedNoteParaIds, collectChangedNumberingDefs, collectParaIds, countParagraphElements, extractParagraphXml, findParagraphOffsets, isXmlNameBoundary, validatePatchSafety };
181
+ export { ChangedNumberingDefs, ParagraphOffsets, PatchSafetyOptions, PatchValidationResult, appendNumberingDefs, buildParagraphOffsetIndex, buildPatchedDocumentXml, buildPatchedNotePartXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectAddedNumberingDefs, collectChangedNoteParaIds, collectChangedNumberingDefs, collectParaIds, countParagraphElements, extractParagraphXml, findParagraphOffsets, isXmlNameBoundary, patchNumberingDefinitions, validatePatchSafety };
@@ -1,4 +1,5 @@
1
- import { WORDPROCESSINGML_NAMESPACE_URIS, findAttributeByNamespaceUri, getChildElements, getLocalName, getNamespacePrefix, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
1
+ import { captureVerbatimXml } from "./verbatimCapture.js";
2
+ import { WORDPROCESSINGML_NAMESPACE_URIS, cloneElement, findAttributeByNamespaceUri, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespacePrefix, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
2
3
  //#region src/docx/selectiveXmlPatch.ts
3
4
  /**
4
5
  * Selective XML Patch Module
@@ -757,6 +758,65 @@ function collectAddedNumberingDefs(baselineXml, currentXml) {
757
758
  };
758
759
  }
759
760
  const NUMBERING_CLOSE_ROOT = "</w:numbering>";
761
+ const numberingDefinitionIdentity = (element) => {
762
+ if (!WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(element) ?? "")) return null;
763
+ const kind = getLocalName(element.name);
764
+ if (kind !== "abstractNum" && kind !== "num") return null;
765
+ const id = getAttributeByNamespaceUri(element, WORDPROCESSINGML_NAMESPACE_URIS, kind === "num" ? "numId" : "abstractNumId");
766
+ return id === null ? null : {
767
+ kind,
768
+ id
769
+ };
770
+ };
771
+ const patchNumberingByNamespace = ({ original, currentXml, changed, added }) => {
772
+ const current = parseXmlDocument(currentXml);
773
+ if (!current) return null;
774
+ const replacements = /* @__PURE__ */ new Map();
775
+ const namespaceDeclarations = Object.fromEntries(Object.entries(current.attributes ?? {}).filter(([name]) => name === "xmlns" || name.startsWith("xmlns:")));
776
+ for (const child of getChildElements(current)) {
777
+ const identity = numberingDefinitionIdentity(child);
778
+ if (!identity) continue;
779
+ const detached = parseXmlDocument(captureVerbatimXml(cloneElement(child, { attributes: {
780
+ ...namespaceDeclarations,
781
+ ...child.attributes
782
+ } })));
783
+ if (!detached) return null;
784
+ replacements.set(`${identity.kind}:${identity.id}`, detached);
785
+ }
786
+ const elements = [];
787
+ for (const child of original.elements ?? []) {
788
+ const identity = numberingDefinitionIdentity(child);
789
+ if (!identity || !changed[identity.kind === "num" ? "nums" : "abstractNums"].has(identity.id)) {
790
+ elements.push(child);
791
+ continue;
792
+ }
793
+ const replacement = replacements.get(`${identity.kind}:${identity.id}`);
794
+ if (!replacement) return null;
795
+ elements.push(replacement);
796
+ }
797
+ for (const [kind, ids] of [["abstractNum", added.abstractNums], ["num", added.nums]]) for (const id of ids) {
798
+ const replacement = replacements.get(`${kind}:${id}`);
799
+ if (!replacement) return null;
800
+ const firstNum = kind === "abstractNum" ? elements.findIndex((child) => numberingDefinitionIdentity(child)?.kind === "num") : -1;
801
+ elements.splice(firstNum < 0 ? elements.length : firstNum, 0, replacement);
802
+ }
803
+ return captureVerbatimXml(cloneElement(original, { elements }));
804
+ };
805
+ /** Both save paths must write changed definitions and newly referenced instances together. */
806
+ const patchNumberingDefinitions = ({ originalXml, baselineXml, currentXml }) => {
807
+ const changed = collectChangedNumberingDefs(baselineXml, currentXml);
808
+ const added = collectAddedNumberingDefs(baselineXml, currentXml);
809
+ const original = parseXmlDocument(originalXml);
810
+ if (!original || getLocalName(original.name) !== "numbering" || !WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(original) ?? "")) return null;
811
+ if (getNamespacePrefix(original.name ?? "") !== "w") return patchNumberingByNamespace({
812
+ original,
813
+ currentXml,
814
+ changed,
815
+ added
816
+ });
817
+ const spliced = buildPatchedNumberingXml(originalXml, currentXml, changed);
818
+ return spliced === null ? null : appendNumberingDefs(spliced, currentXml, added);
819
+ };
760
820
  /**
761
821
  * Append added `w:abstractNum` / `w:num` definitions from `currentXml` to
762
822
  * `xml`. ECMA-376 §17.9 orders every `w:abstractNum` before the first `w:num`,
@@ -812,4 +872,4 @@ function escapeRegExp(str) {
812
872
  return str.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
813
873
  }
814
874
  //#endregion
815
- export { appendNumberingDefs, buildParagraphOffsetIndex, buildPatchedDocumentXml, buildPatchedNotePartXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectAddedNumberingDefs, collectChangedNoteParaIds, collectChangedNumberingDefs, collectParaIds, countParagraphElements, extractParagraphXml, findParagraphOffsets, isXmlNameBoundary, validatePatchSafety };
875
+ export { appendNumberingDefs, buildParagraphOffsetIndex, buildPatchedDocumentXml, buildPatchedNotePartXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectAddedNumberingDefs, collectChangedNoteParaIds, collectChangedNumberingDefs, collectParaIds, countParagraphElements, extractParagraphXml, findParagraphOffsets, isXmlNameBoundary, patchNumberingDefinitions, validatePatchSafety };
@@ -1,5 +1,8 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
2
  //#region src/docx/serializer/borderSerializer.d.ts
3
+ type ExhaustiveFields<Source, Classified extends keyof Source> = Exclude<keyof Source, Classified> extends never ? Source : never;
4
+ type ClassifiedBorderField = "style" | "color" | "size" | "space" | "shadow" | "frame" | "artRelationshipId" | "topLeftArtRelationshipId" | "topRightArtRelationshipId" | "bottomLeftArtRelationshipId" | "bottomRightArtRelationshipId";
5
+ type ExhaustiveBorder = ExhaustiveFields<document_d_exports.BorderSpec, ClassifiedBorderField>;
3
6
  /**
4
7
  * Serialize a single border element (`<w:top .../>`, `<w:left .../>`, ...).
5
8
  *
@@ -19,6 +22,6 @@ import { document_d_exports } from "../../types/document.js";
19
22
  * untrusted and are `escapeXml`'d before re-entering XML attributes; for valid
20
23
  * documents these are enum/hex values, so escaping is a no-op.
21
24
  */
22
- declare function serializeBorder(border: document_d_exports.BorderSpec | undefined, elementName: string): string;
25
+ declare function serializeBorder(input: ExhaustiveBorder | undefined, elementName: string): string;
23
26
  //#endregion
24
27
  export { serializeBorder };
@@ -19,25 +19,27 @@ import { escapeXml, intAttr } from "./xmlUtils.js";
19
19
  * untrusted and are `escapeXml`'d before re-entering XML attributes; for valid
20
20
  * documents these are enum/hex values, so escaping is a no-op.
21
21
  */
22
- function serializeBorder(border, elementName) {
23
- if (!border) return "";
24
- const attrs = [`w:val="${escapeXml(border.style)}"`];
25
- if (border.size !== void 0) attrs.push(`w:sz="${intAttr(border.size)}"`);
26
- if (border.space !== void 0) attrs.push(`w:space="${intAttr(border.space)}"`);
27
- if (border.color) {
28
- if (border.color.auto) attrs.push("w:color=\"auto\"");
29
- else if (border.color.rgb) attrs.push(`w:color="${escapeXml(border.color.rgb)}"`);
30
- if (border.color.themeColor) attrs.push(`w:themeColor="${escapeXml(border.color.themeColor)}"`);
31
- if (border.color.themeTint) attrs.push(`w:themeTint="${escapeXml(border.color.themeTint)}"`);
32
- if (border.color.themeShade) attrs.push(`w:themeShade="${escapeXml(border.color.themeShade)}"`);
22
+ function serializeBorder(input, elementName) {
23
+ if (!input) return "";
24
+ const { style, color, size, space, shadow, frame, artRelationshipId, topLeftArtRelationshipId, topRightArtRelationshipId, bottomLeftArtRelationshipId, bottomRightArtRelationshipId } = input;
25
+ const attrs = [`w:val="${escapeXml(style)}"`];
26
+ if (size !== void 0) attrs.push(`w:sz="${intAttr(size)}"`);
27
+ if (space !== void 0) attrs.push(`w:space="${intAttr(space)}"`);
28
+ if (color) {
29
+ const { auto, rgb, themeColor, themeTint, themeShade } = color;
30
+ if (auto) attrs.push("w:color=\"auto\"");
31
+ else if (rgb) attrs.push(`w:color="${escapeXml(rgb)}"`);
32
+ if (themeColor) attrs.push(`w:themeColor="${escapeXml(themeColor)}"`);
33
+ if (themeTint) attrs.push(`w:themeTint="${escapeXml(themeTint)}"`);
34
+ if (themeShade) attrs.push(`w:themeShade="${escapeXml(themeShade)}"`);
33
35
  }
34
- if (border.shadow) attrs.push("w:shadow=\"true\"");
35
- if (border.frame) attrs.push("w:frame=\"true\"");
36
- if (border.artRelationshipId) attrs.push(`w:id="${escapeXml(border.artRelationshipId)}"`);
37
- if (border.topLeftArtRelationshipId) attrs.push(`w:topLeft="${escapeXml(border.topLeftArtRelationshipId)}"`);
38
- if (border.topRightArtRelationshipId) attrs.push(`w:topRight="${escapeXml(border.topRightArtRelationshipId)}"`);
39
- if (border.bottomLeftArtRelationshipId) attrs.push(`w:bottomLeft="${escapeXml(border.bottomLeftArtRelationshipId)}"`);
40
- if (border.bottomRightArtRelationshipId) attrs.push(`w:bottomRight="${escapeXml(border.bottomRightArtRelationshipId)}"`);
36
+ if (shadow) attrs.push("w:shadow=\"true\"");
37
+ if (frame) attrs.push("w:frame=\"true\"");
38
+ if (artRelationshipId) attrs.push(`w:id="${escapeXml(artRelationshipId)}"`);
39
+ if (topLeftArtRelationshipId) attrs.push(`w:topLeft="${escapeXml(topLeftArtRelationshipId)}"`);
40
+ if (topRightArtRelationshipId) attrs.push(`w:topRight="${escapeXml(topRightArtRelationshipId)}"`);
41
+ if (bottomLeftArtRelationshipId) attrs.push(`w:bottomLeft="${escapeXml(bottomLeftArtRelationshipId)}"`);
42
+ if (bottomRightArtRelationshipId) attrs.push(`w:bottomRight="${escapeXml(bottomRightArtRelationshipId)}"`);
41
43
  return `<w:${elementName} ${attrs.join(" ")}/>`;
42
44
  }
43
45
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { deterministicHexId } from "../../utils/hexId.js";
2
2
  import { serializeParagraph } from "./paragraphSerializer.js";
3
3
  import { serializePartElement } from "./partNamespaces.js";
4
- import { serializeTextFormatting } from "./runSerializer.js";
4
+ import { serializeTextFormatting } from "./textFormattingSerializer.js";
5
5
  import { escapeXml } from "./xmlUtils.js";
6
6
  //#region src/docx/serializer/commentSerializer.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import { serializePartElement } from "./partNamespaces.js";
2
- import { serializeTextFormatting } from "./runSerializer.js";
2
+ import { serializeTextFormatting } from "./textFormattingSerializer.js";
3
3
  import { escapeXml, intAttr } from "./xmlUtils.js";
4
4
  //#region src/docx/serializer/numberingSerializer.ts
5
5
  /**
@@ -1,142 +1,19 @@
1
- import { canonicalJson } from "../../utils/canonicalJson.js";
2
- import { isValidHexColor } from "../../utils/colorResolver.js";
3
- import { numPrEqual } from "../numberingParser.js";
4
- import { getParagraphPropertySource } from "../paragraphPropertySource.js";
1
+ import { modelParagraphFormattingEmission } from "../../internal/paragraphFormattingSerialization.js";
2
+ import { getParagraphPropertySource, paragraphPropertySourceMatchesEmission } from "../paragraphPropertySource.js";
5
3
  import { reconcileRawSdtPr } from "../sdtPropertiesPatch.js";
6
4
  import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
7
5
  import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
8
6
  import { captureVerbatimXml, sanitizeCapturedXmlElement } from "../verbatimCapture.js";
9
7
  import { NAMESPACES, OOXML_NAMESPACE_SCOPE, cloneElement, getChildElements, getLocalName, parseXml } from "../xmlParser.js";
10
- import { serializeBorder } from "./borderSerializer.js";
11
- import { serializeRun, serializeTextFormatting } from "./runSerializer.js";
8
+ import { serializeRun } from "./runSerializer.js";
12
9
  import { serializeSectionProperties } from "./sectionPropertiesSerializer.js";
10
+ import { serializeTextFormatting } from "./textFormattingSerializer.js";
13
11
  import { serializeTrackedChangeAttributes, trackedChangeAttributeRecord } from "./trackedChangeAttributes.js";
14
- import { escapeXml, intAttr, isSingleWellFormedElement } from "./xmlUtils.js";
12
+ import { escapeXml, isSingleWellFormedElement } from "./xmlUtils.js";
15
13
  import { panic } from "better-result";
16
14
  import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
17
15
  //#region src/docx/serializer/paragraphSerializer.ts
18
16
  /**
19
- * Serialize paragraph borders (w:pBdr)
20
- */
21
- function serializeParagraphBorders(borders) {
22
- if (!borders) return "";
23
- const parts = [];
24
- if (borders.top) {
25
- const topXml = serializeBorder(borders.top, "top");
26
- if (topXml) parts.push(topXml);
27
- }
28
- if (borders.left) {
29
- const leftXml = serializeBorder(borders.left, "left");
30
- if (leftXml) parts.push(leftXml);
31
- }
32
- if (borders.bottom) {
33
- const bottomXml = serializeBorder(borders.bottom, "bottom");
34
- if (bottomXml) parts.push(bottomXml);
35
- }
36
- if (borders.right) {
37
- const rightXml = serializeBorder(borders.right, "right");
38
- if (rightXml) parts.push(rightXml);
39
- }
40
- if (borders.between) {
41
- const betweenXml = serializeBorder(borders.between, "between");
42
- if (betweenXml) parts.push(betweenXml);
43
- }
44
- if (borders.bar) {
45
- const barXml = serializeBorder(borders.bar, "bar");
46
- if (barXml) parts.push(barXml);
47
- }
48
- if (parts.length === 0) return "";
49
- return `<w:pBdr>${parts.join("")}</w:pBdr>`;
50
- }
51
- /**
52
- * Serialize shading properties (w:shd)
53
- */
54
- function serializeShading(shading) {
55
- if (!shading) return "";
56
- const attrs = [];
57
- if (shading.pattern) attrs.push(`w:val="${escapeXml(shading.pattern)}"`);
58
- else attrs.push("w:val=\"clear\"");
59
- if (shading.color?.rgb && isValidHexColor(shading.color.rgb)) attrs.push(`w:color="${escapeXml(shading.color.rgb)}"`);
60
- else if (shading.color?.auto) attrs.push("w:color=\"auto\"");
61
- if (shading.fill?.rgb && isValidHexColor(shading.fill.rgb)) attrs.push(`w:fill="${escapeXml(shading.fill.rgb)}"`);
62
- else if (shading.fill?.auto) attrs.push("w:fill=\"auto\"");
63
- if (shading.fill?.themeColor) attrs.push(`w:themeFill="${escapeXml(shading.fill.themeColor)}"`);
64
- if (shading.fill?.themeTint) attrs.push(`w:themeFillTint="${escapeXml(shading.fill.themeTint)}"`);
65
- if (shading.fill?.themeShade) attrs.push(`w:themeFillShade="${escapeXml(shading.fill.themeShade)}"`);
66
- if (attrs.length === 0) return "";
67
- return `<w:shd ${attrs.join(" ")}/>`;
68
- }
69
- /**
70
- * Serialize tab stops (w:tabs)
71
- */
72
- function serializeTabStops(tabs) {
73
- if (!tabs || tabs.length === 0) return "";
74
- return `<w:tabs>${tabs.map((tab) => {
75
- const attrs = [`w:val="${tab.alignment}"`, `w:pos="${intAttr(tab.position)}"`];
76
- if (tab.leader && tab.leader !== "none") attrs.push(`w:leader="${tab.leader}"`);
77
- return `<w:tab ${attrs.join(" ")}/>`;
78
- }).join("")}</w:tabs>`;
79
- }
80
- /**
81
- * Serialize spacing properties (w:spacing)
82
- */
83
- function serializeSpacing(formatting) {
84
- const attrs = [];
85
- if (formatting.spaceBefore !== void 0) attrs.push(`w:before="${intAttr(formatting.spaceBefore)}"`);
86
- if (formatting.spaceAfter !== void 0) attrs.push(`w:after="${intAttr(formatting.spaceAfter)}"`);
87
- if (formatting.lineSpacing !== void 0) attrs.push(`w:line="${intAttr(formatting.lineSpacing)}"`);
88
- if (formatting.lineSpacingRule) attrs.push(`w:lineRule="${formatting.lineSpacingRule}"`);
89
- if (formatting.beforeAutospacing !== void 0) attrs.push(`w:beforeAutospacing="${formatting.beforeAutospacing ? "1" : "0"}"`);
90
- if (formatting.afterAutospacing !== void 0) attrs.push(`w:afterAutospacing="${formatting.afterAutospacing ? "1" : "0"}"`);
91
- if (attrs.length === 0) return "";
92
- return `<w:spacing ${attrs.join(" ")}/>`;
93
- }
94
- /**
95
- * Serialize indentation properties (w:ind)
96
- */
97
- function serializeIndentation(formatting) {
98
- const attrs = [];
99
- if (formatting.indentLeft !== void 0) attrs.push(`w:left="${intAttr(formatting.indentLeft)}"`);
100
- if (formatting.indentRight !== void 0) attrs.push(`w:right="${intAttr(formatting.indentRight)}"`);
101
- if (formatting.indentFirstLine !== void 0) if (formatting.hangingIndent) attrs.push(`w:hanging="${intAttr(Math.abs(formatting.indentFirstLine))}"`);
102
- else attrs.push(`w:firstLine="${intAttr(formatting.indentFirstLine)}"`);
103
- if (attrs.length === 0) return "";
104
- return `<w:ind ${attrs.join(" ")}/>`;
105
- }
106
- /**
107
- * Serialize numbering properties (w:numPr)
108
- */
109
- function serializeNumbering(numPr) {
110
- if (!numPr) return "";
111
- const parts = [];
112
- if (numPr.ilvl !== void 0) parts.push(`<w:ilvl w:val="${intAttr(numPr.ilvl)}"/>`);
113
- if (numPr.numId !== void 0) parts.push(`<w:numId w:val="${intAttr(numPr.numId)}"/>`);
114
- if (parts.length === 0) return "";
115
- return `<w:numPr>${parts.join("")}</w:numPr>`;
116
- }
117
- /**
118
- * Serialize frame properties (w:framePr)
119
- */
120
- function serializeFrameProperties(frame) {
121
- if (!frame) return "";
122
- const attrs = [];
123
- if (frame.dropCap) attrs.push(`w:dropCap="${frame.dropCap}"`);
124
- if (frame.lines !== void 0) attrs.push(`w:lines="${intAttr(frame.lines)}"`);
125
- if (frame.width !== void 0) attrs.push(`w:w="${intAttr(frame.width)}"`);
126
- if (frame.height !== void 0) attrs.push(`w:h="${intAttr(frame.height)}"`);
127
- if (frame.hSpace !== void 0) attrs.push(`w:hSpace="${intAttr(frame.hSpace)}"`);
128
- if (frame.vSpace !== void 0) attrs.push(`w:vSpace="${intAttr(frame.vSpace)}"`);
129
- if (frame.hAnchor) attrs.push(`w:hAnchor="${frame.hAnchor}"`);
130
- if (frame.vAnchor) attrs.push(`w:vAnchor="${frame.vAnchor}"`);
131
- if (frame.x !== void 0) attrs.push(`w:x="${frame.x}"`);
132
- if (frame.y !== void 0) attrs.push(`w:y="${frame.y}"`);
133
- if (frame.xAlign) attrs.push(`w:xAlign="${frame.xAlign}"`);
134
- if (frame.yAlign) attrs.push(`w:yAlign="${frame.yAlign}"`);
135
- if (frame.wrap) attrs.push(`w:wrap="${frame.wrap}"`);
136
- if (attrs.length === 0) return "";
137
- return `<w:framePr ${attrs.join(" ")}/>`;
138
- }
139
- /**
140
17
  * Serialize paragraph formatting properties to w:pPr XML
141
18
  */
142
19
  function serializeParagraphMarkChange(mark) {
@@ -361,7 +238,7 @@ const verifiedParagraphPropertySource = (formatting, source) => {
361
238
  if (!source) return null;
362
239
  const replayableSource = replayableParagraphPropertySourceXml(source.xml);
363
240
  if (replayableSource === null) return null;
364
- return canonicalJson(formatting ?? {}) === source.formattingJson ? replayableSource : null;
241
+ return paragraphPropertySourceMatchesEmission(source, formatting) ? replayableSource : null;
365
242
  };
366
243
  const withTrailingParagraphPropertyChildren = (sourceXml, children) => {
367
244
  const written = children.join("");
@@ -398,6 +275,7 @@ const withParagraphMarkChange = (sourceXml, mark) => {
398
275
  return captureVerbatimXml(cloneElement(root, { elements }));
399
276
  };
400
277
  const serializeParagraphFormattingWithOptions = (formatting, { propertyChanges, paragraphMarkChange, propertySource, sectionProperties } = {}) => {
278
+ const modeledFormatting = modelParagraphFormattingEmission(formatting);
401
279
  const serializablePropertyChangeCount = propertyChanges?.length ?? 0;
402
280
  if (serializablePropertyChangeCount > 1) panic("A paragraph cannot serialize more than one w:pPrChange", { count: serializablePropertyChangeCount });
403
281
  const paragraphMarkXml = paragraphMarkChange ? serializeParagraphMarkChange(paragraphMarkChange) : "";
@@ -408,50 +286,15 @@ const serializeParagraphFormattingWithOptions = (formatting, { propertyChanges,
408
286
  sectionPropertiesXml,
409
287
  ...propertyChangesXml
410
288
  ].some((xml) => xml.includes(`${DATE_UTC_ATTRIBUTE}=`));
411
- const verifiedSource = verifiedParagraphPropertySource(formatting, propertySource);
289
+ const verifiedSource = verifiedParagraphPropertySource(modeledFormatting, propertySource);
412
290
  if (verifiedSource !== null && (!composedChildrenUseDateUtc || !sourceShadowsDateUtcPrefix(verifiedSource))) {
413
291
  const sourceWithMark = paragraphMarkChange ? withParagraphMarkChange(verifiedSource, paragraphMarkChange) : verifiedSource;
414
292
  return withTrailingParagraphPropertyChildren(sourceWithMark, [sectionPropertiesXml, ...propertyChangesXml]);
415
293
  }
416
294
  const parts = [];
417
- const pushToggle = (name, value) => {
418
- if (value === true) parts.push(`<w:${name}/>`);
419
- else if (value === false) parts.push(`<w:${name} w:val="0"/>`);
420
- };
421
- if (formatting) {
422
- if (formatting.styleId) parts.push(`<w:pStyle w:val="${escapeXml(formatting.styleId)}"/>`);
423
- pushToggle("keepNext", formatting.keepNext);
424
- pushToggle("keepLines", formatting.keepLines);
425
- pushToggle("pageBreakBefore", formatting.pageBreakBefore);
426
- const frameXml = serializeFrameProperties(formatting.frame);
427
- if (frameXml) parts.push(frameXml);
428
- pushToggle("widowControl", formatting.widowControl);
429
- const numPrXml = formatting.numPrFromStyle != null && numPrEqual(formatting.numPr, formatting.numPrFromStyle) ? "" : serializeNumbering(formatting.numPr);
430
- if (numPrXml) parts.push(numPrXml);
431
- pushToggle("suppressLineNumbers", formatting.suppressLineNumbers);
432
- const bordersXml = serializeParagraphBorders(formatting.borders);
433
- if (bordersXml) parts.push(bordersXml);
434
- const shadingXml = serializeShading(formatting.shading);
435
- if (shadingXml) parts.push(shadingXml);
436
- const tabsXml = serializeTabStops(formatting.tabs);
437
- if (tabsXml) parts.push(tabsXml);
438
- pushToggle("suppressAutoHyphens", formatting.suppressAutoHyphens);
439
- pushToggle("kinsoku", formatting.kinsoku);
440
- pushToggle("overflowPunct", formatting.overflowPunctuation);
441
- pushToggle("bidi", formatting.bidi);
442
- pushToggle("snapToGrid", formatting.snapToGrid);
443
- const spacingXml = serializeSpacing(formatting);
444
- if (spacingXml) parts.push(spacingXml);
445
- const indXml = serializeIndentation(formatting);
446
- if (indXml) parts.push(indXml);
447
- pushToggle("contextualSpacing", formatting.contextualSpacing);
448
- if (formatting.alignment) parts.push(`<w:jc w:val="${formatting.alignment}"/>`);
449
- if (formatting.outlineLevel !== void 0) parts.push(`<w:outlineLvl w:val="${formatting.outlineLevel}"/>`);
450
- if (paragraphMarkChange || formatting.runProperties || formatting.runInWithNext) {
451
- const fullInner = `${paragraphMarkChange ? paragraphMarkXml : ""}${formatting.runProperties ? extractRPrInner(serializeTextFormatting(formatting.runProperties)) : ""}${formatting.runInWithNext ? "<w:specVanish/>" : ""}`;
452
- if (fullInner.length > 0) parts.push(`<w:rPr>${fullInner}</w:rPr>`);
453
- }
454
- } else if (paragraphMarkChange) parts.push(`<w:rPr>${paragraphMarkXml}</w:rPr>`);
295
+ if (modeledFormatting.propertiesXml) parts.push(modeledFormatting.propertiesXml);
296
+ const paragraphMarkPropertiesInnerXml = `${paragraphMarkXml}${modeledFormatting.paragraphMarkPropertiesInnerXml ?? ""}`;
297
+ if (paragraphMarkPropertiesInnerXml) parts.push(`<w:rPr>${paragraphMarkPropertiesInnerXml}</w:rPr>`);
455
298
  parts.push(sectionPropertiesXml);
456
299
  if (propertyChangesXml.length > 0) parts.push(...propertyChangesXml);
457
300
  const inner = parts.join("");
@@ -468,15 +311,6 @@ function extractPPrInner(pPrXml) {
468
311
  if (!pPrXml.startsWith("<w:pPr>") || !pPrXml.endsWith("</w:pPr>")) return "";
469
312
  return pPrXml.slice(7, -8);
470
313
  }
471
- /**
472
- * Strip the outer `<w:rPr>...</w:rPr>` wrapper so callers can splice
473
- * additional rPr children (e.g. `<w:specVanish/>`) and re-emit a
474
- * single rPr element.
475
- */
476
- function extractRPrInner(rPrXml) {
477
- if (!rPrXml.startsWith("<w:rPr>") || !rPrXml.endsWith("</w:rPr>")) return "";
478
- return rPrXml.slice(7, -8);
479
- }
480
314
  function serializeParagraphPropertyChange(change) {
481
315
  const previousPPrInner = extractPPrInner(serializeParagraphFormatting(change.previousFormatting) || "<w:pPr/>");
482
316
  const normalizedPreviousPPr = previousPPrInner.length > 0 ? `<w:pPr>${previousPPrInner}</w:pPr>` : "<w:pPr/>";
@@ -675,6 +509,7 @@ function serializeTrackedChange(tag, change) {
675
509
  const xml = item.type === "simpleField" ? serializeSimpleField(item) : serializeComplexField(item);
676
510
  return tag === "del" || tag === "moveFrom" ? rewriteRunTextAsDeleted(xml) : xml;
677
511
  }
512
+ if (item.type === "mathEquation") return item.ommlXml;
678
513
  if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") return serializeTrackedChange(trackedChangeTag(item), item);
679
514
  return item.type === "bookmarkStart" ? serializeBookmarkStart(item) : serializeBookmarkEnd(item);
680
515
  };
@@ -751,6 +586,7 @@ function serializeParagraph(paragraph) {
751
586
  const attrs = [];
752
587
  if (paragraph.paraId) attrs.push(`w14:paraId="${escapeXml(paragraph.paraId)}"`);
753
588
  if (paragraph.textId) attrs.push(`w14:textId="${escapeXml(paragraph.textId)}"`);
589
+ if (paragraph.reviewCarrier) attrs.push(`folio:reviewCarrier="${paragraph.reviewCarrier}"`);
754
590
  const attrsStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
755
591
  parts.push(serializeParagraphFormattingWithOptions(paragraph.formatting, {
756
592
  propertyChanges: paragraph.propertyChanges,
@@ -25,7 +25,7 @@ type PackagingPrefix = "ct" | "pr";
25
25
  * over the union: a member with no entry, or an entry with no member, does not
26
26
  * compile.
27
27
  */
28
- type OoxmlNamespacePrefix = Exclude<OoxmlPrefix, PackagingPrefix> | "cx" | "cx1" | "cx2" | "cx3" | "cx4" | "cx5" | "cx6" | "cx7" | "cx8" | "aink" | "am3d" | "oel" | "w10" | "w16" | "w16cex" | "w16cid" | "w16du" | "w16sdtdh" | "w16se" | "wpi" | "wne";
28
+ type OoxmlNamespacePrefix = Exclude<OoxmlPrefix, PackagingPrefix> | "cx" | "cx1" | "cx2" | "cx3" | "cx4" | "cx5" | "cx6" | "cx7" | "cx8" | "aink" | "am3d" | "oel" | "w10" | "w16" | "w16cex" | "w16cid" | "w16du" | "w16sdtdh" | "w16se" | "folio" | "wpi" | "wne";
29
29
  /**
30
30
  * Every namespace a rebuilt part can declare, in the order producers write them.
31
31
  *
@@ -143,6 +143,10 @@ const OOXML_NAMESPACES = {
143
143
  uri: "http://schemas.microsoft.com/office/word/2015/wordml/symex",
144
144
  ignorable: true
145
145
  },
146
+ folio: {
147
+ uri: "urn:stella:folio:review-history:1",
148
+ ignorable: true
149
+ },
146
150
  wpg: {
147
151
  uri: OOXML_NS.wpg,
148
152
  ignorable: false
@@ -5,10 +5,6 @@ import { document_d_exports } from "../../types/document.js";
5
5
  * to keep IDs deterministic across saves.
6
6
  */
7
7
  declare function resetAutoIdCounter(): void;
8
- /**
9
- * Serialize text formatting properties to w:rPr XML
10
- */
11
- declare function serializeTextFormatting(formatting: document_d_exports.TextFormatting | undefined): string;
12
8
  /**
13
9
  * Serialize a run to OOXML XML (w:r)
14
10
  *
@@ -52,4 +48,4 @@ declare function createBreakRun(breakType?: "page" | "column" | "textWrapping",
52
48
  */
53
49
  declare function createTabRun(formatting?: document_d_exports.TextFormatting): document_d_exports.Run;
54
50
  //#endregion
55
- export { createBreakRun, createEmptyRun, createTabRun, createTextRun, getRunPlainText, hasRunContent, hasRunFormatting, resetAutoIdCounter, serializeRun, serializeRuns, serializeTextFormatting };
51
+ export { createBreakRun, createEmptyRun, createTabRun, createTextRun, getRunPlainText, hasRunContent, hasRunFormatting, resetAutoIdCounter, serializeRun, serializeRuns };