@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.
- package/dist/ai-edits/apply.js +275 -88
- package/dist/ai-edits/clean-text.js +12 -1
- package/dist/ai-edits/headless.d.ts +110 -0
- package/dist/ai-edits/headless.js +569 -40
- package/dist/ai-edits/index.d.ts +2 -1
- package/dist/ai-edits/snapshot.d.ts +24 -1
- package/dist/ai-edits/snapshot.js +206 -9
- package/dist/ai-edits/table-geometry.d.ts +7 -7
- package/dist/ai-edits/table-geometry.js +43 -27
- package/dist/ai-edits/table-template.d.ts +2 -1
- package/dist/ai-edits/table-template.js +9 -3
- package/dist/ai-edits/types.d.ts +38 -16
- package/dist/compare/__fixtures__/body-sequence.d.ts +4 -0
- package/dist/compare/__fixtures__/body-sequence.js +5 -3
- package/dist/compare/compare.d.ts +26 -2
- package/dist/compare/compare.js +444 -16
- package/dist/compare/content-alignment.js +216 -137
- package/dist/compare/content-types.d.ts +36 -2
- package/dist/compare/content.d.ts +13 -10
- package/dist/compare/content.js +69 -23
- package/dist/compare/formatting.d.ts +4 -22
- package/dist/compare/formatting.js +8 -112
- package/dist/compare/inline-atom-resources.d.ts +6 -0
- package/dist/compare/inline-atom-resources.js +26 -0
- package/dist/compare/inline-atoms.d.ts +35 -0
- package/dist/compare/inline-atoms.js +383 -0
- package/dist/compare/inline-provenance.d.ts +36 -0
- package/dist/compare/inline-provenance.js +334 -0
- package/dist/compare/plan.d.ts +4 -1
- package/dist/compare/plan.js +32 -4
- package/dist/compare/scenario.d.ts +4 -6
- package/dist/compare/section-boundary-properties.d.ts +63 -0
- package/dist/compare/section-boundary-properties.js +235 -0
- package/dist/compare/style-resources.d.ts +30 -0
- package/dist/compare/style-resources.js +404 -0
- package/dist/compare/types.d.ts +50 -11
- package/dist/compare/types.js +3 -1
- package/dist/compare/verification.d.ts +3 -5
- package/dist/compare/verification.js +8 -39
- package/dist/compat/eigenpal.d.ts +4 -4
- package/dist/compat/eigenpal.js +3 -3
- package/dist/document-operations.d.ts +5 -3
- package/dist/document-operations.js +112 -5
- package/dist/docx/blockContentParser.js +14 -2
- package/dist/docx/drawingIdNormalization.js +43 -2
- package/dist/docx/drawingRelationships.d.ts +10 -0
- package/dist/docx/drawingRelationships.js +28 -0
- package/dist/docx/fieldParser.js +1 -1
- package/dist/docx/hyperlinkParser.js +3 -5
- package/dist/docx/imageRawXml.d.ts +8 -0
- package/dist/docx/imageRawXml.js +13 -0
- package/dist/docx/newImage.d.ts +2 -2
- package/dist/docx/newImage.js +3 -3
- package/dist/docx/numberingParser.d.ts +1 -13
- package/dist/docx/numberingParser.js +31 -37
- package/dist/docx/paragraphParser.js +12 -9
- package/dist/docx/paragraphPropertySource.d.ts +8 -5
- package/dist/docx/paragraphPropertySource.js +16 -4
- package/dist/docx/removeHeaderFooterParts.d.ts +14 -0
- package/dist/docx/removeHeaderFooterParts.js +87 -0
- package/dist/docx/rezip.d.ts +3 -1
- package/dist/docx/rezip.js +143 -41
- package/dist/docx/runParser.js +16 -5
- package/dist/docx/sectionParser.js +3 -0
- package/dist/docx/sectionReferenceHistory.d.ts +17 -0
- package/dist/docx/sectionReferenceHistory.js +59 -0
- package/dist/docx/selectiveSave.js +11 -31
- package/dist/docx/selectiveXmlPatch.d.ts +8 -1
- package/dist/docx/selectiveXmlPatch.js +62 -2
- package/dist/docx/serializer/borderSerializer.d.ts +4 -1
- package/dist/docx/serializer/borderSerializer.js +20 -18
- package/dist/docx/serializer/commentSerializer.js +1 -1
- package/dist/docx/serializer/numberingSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +13 -177
- package/dist/docx/serializer/partNamespaces.d.ts +1 -1
- package/dist/docx/serializer/partNamespaces.js +4 -0
- package/dist/docx/serializer/runSerializer.d.ts +1 -5
- package/dist/docx/serializer/runSerializer.js +4 -130
- package/dist/docx/serializer/sectionPropertiesSerializer.js +5 -2
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/textFormattingSerializer.d.ts +17 -0
- package/dist/docx/serializer/textFormattingSerializer.js +144 -0
- package/dist/docx/tableParser.js +21 -11
- package/dist/docx/xmlParser.d.ts +10 -1
- package/dist/docx/xmlParser.js +23 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/internal/compare/inline-presentation.d.ts +20 -0
- package/dist/internal/compare/inline-presentation.js +222 -0
- package/dist/internal/paragraphFormattingSerialization.d.ts +25 -0
- package/dist/internal/paragraphFormattingSerialization.js +164 -0
- package/dist/internal/sectionReferenceResolution.d.ts +21 -0
- package/dist/internal/sectionReferenceResolution.js +72 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
- package/dist/markdown/renderRuns.js +1 -0
- package/dist/markdown/renderTable.js +1 -0
- package/dist/prosemirror/attrs/index.js +20 -1
- package/dist/prosemirror/commands/comments.d.ts +11 -1
- package/dist/prosemirror/commands/comments.js +68 -6
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +9 -3
- package/dist/prosemirror/commands/propertyChangeScope.js +4 -10
- package/dist/prosemirror/conversion/fromProseDoc.js +22 -22
- package/dist/prosemirror/conversion/toProseDoc.js +16 -57
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +3 -0
- package/dist/prosemirror/imageCommit.js +7 -9
- package/dist/prosemirror/paragraphIndentation.d.ts +21 -0
- package/dist/prosemirror/paragraphIndentation.js +72 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +3 -1
- package/dist/prosemirror/plugins/documentNumbering.js +7 -1
- package/dist/prosemirror/plugins/documentStyles.d.ts +3 -1
- package/dist/prosemirror/plugins/documentStyles.js +7 -1
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +3 -1
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +2 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +15 -2
- package/dist/prosemirror/runFormattingInlineCarriers.js +33 -3
- package/dist/prosemirror/runStyleFormatting.d.ts +15 -2
- package/dist/prosemirror/runStyleFormatting.js +76 -2
- package/dist/prosemirror/schema/marks.d.ts +3 -1
- package/dist/prosemirror/schema/marks.js +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +3 -0
- package/dist/prosemirror/tableCellRevisionVisibility.d.ts +6 -0
- package/dist/prosemirror/tableCellRevisionVisibility.js +14 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
- package/dist/redline.js +15 -2
- package/dist/server.d.ts +3 -2
- package/dist/server.js +2 -2
- package/dist/version-comparison.d.ts +2 -0
- package/dist/version-comparison.js +30 -29
- package/package.json +2 -2
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { sectionReferenceHistory } from "../docx/sectionReferenceHistory.js";
|
|
2
|
+
import { expectParagraphAttrs } from "../prosemirror/attrs/index.js";
|
|
3
|
+
import { resolveAllChangesInHeadlessStateWithMapping } from "../prosemirror/commands/comments.js";
|
|
4
|
+
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
5
|
+
//#region src/compare/section-boundary-properties.ts
|
|
6
|
+
const withoutChangeHistory = (properties) => {
|
|
7
|
+
const { propertyChanges: _propertyChanges, ...result } = properties;
|
|
8
|
+
return result;
|
|
9
|
+
};
|
|
10
|
+
const boundaryChildrenOf = (document) => {
|
|
11
|
+
const children = [];
|
|
12
|
+
let hasChangeHistory = false;
|
|
13
|
+
document.forEach((node, position) => {
|
|
14
|
+
if (node.type.name !== "paragraph") {
|
|
15
|
+
children.push({
|
|
16
|
+
type: "other",
|
|
17
|
+
nodeType: node.type.name
|
|
18
|
+
});
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const sectionProperties = expectParagraphAttrs(node)._sectionProperties;
|
|
22
|
+
if (sectionProperties?.propertyChanges !== void 0) {
|
|
23
|
+
hasChangeHistory = true;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
children.push({
|
|
27
|
+
type: "paragraph",
|
|
28
|
+
paragraph: {
|
|
29
|
+
position,
|
|
30
|
+
text: node.textContent,
|
|
31
|
+
sectionProperties
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return hasChangeHistory ? null : children;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Compare section properties attached to retained top-level paragraph endpoints.
|
|
39
|
+
* A section endpoint cannot be added to or removed from a retained paragraph
|
|
40
|
+
* with `sectPrChange`: its previous payload is still a section endpoint.
|
|
41
|
+
*/
|
|
42
|
+
const compareSectionBoundaryProperties = ({ current, target, mapTargetProperties }) => {
|
|
43
|
+
const currentChildren = boundaryChildrenOf(current);
|
|
44
|
+
const targetChildren = boundaryChildrenOf(target);
|
|
45
|
+
if (!currentChildren || !targetChildren) return {
|
|
46
|
+
status: "unalignable",
|
|
47
|
+
detail: "section boundary revision history is unsupported"
|
|
48
|
+
};
|
|
49
|
+
if (currentChildren.length !== targetChildren.length) return {
|
|
50
|
+
status: "unalignable",
|
|
51
|
+
detail: "section boundary topology differs"
|
|
52
|
+
};
|
|
53
|
+
const changes = [];
|
|
54
|
+
for (const [index, currentChild] of currentChildren.entries()) {
|
|
55
|
+
const targetChild = targetChildren[index];
|
|
56
|
+
if (!targetChild || currentChild.type !== targetChild.type) return {
|
|
57
|
+
status: "unalignable",
|
|
58
|
+
detail: "section boundary topology differs"
|
|
59
|
+
};
|
|
60
|
+
if (currentChild.type === "other" && targetChild.type === "other") {
|
|
61
|
+
if (currentChild.nodeType !== targetChild.nodeType) return {
|
|
62
|
+
status: "unalignable",
|
|
63
|
+
detail: "section boundary topology differs"
|
|
64
|
+
};
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (currentChild.type !== "paragraph" || targetChild.type !== "paragraph") return {
|
|
68
|
+
status: "unalignable",
|
|
69
|
+
detail: "section boundary topology differs"
|
|
70
|
+
};
|
|
71
|
+
const currentParagraph = currentChild.paragraph;
|
|
72
|
+
const targetParagraph = targetChild.paragraph;
|
|
73
|
+
if (currentParagraph.text !== targetParagraph.text) return {
|
|
74
|
+
status: "unalignable",
|
|
75
|
+
detail: "retained paragraph text differs"
|
|
76
|
+
};
|
|
77
|
+
const currentProperties = currentParagraph.sectionProperties;
|
|
78
|
+
const targetProperties = targetParagraph.sectionProperties;
|
|
79
|
+
if (currentProperties === void 0 || targetProperties === void 0) {
|
|
80
|
+
if (currentProperties !== targetProperties) return {
|
|
81
|
+
status: "unalignable",
|
|
82
|
+
detail: "section endpoint presence differs"
|
|
83
|
+
};
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const currentWithoutHistory = withoutChangeHistory(currentProperties);
|
|
87
|
+
const mappedTarget = mapTargetProperties ? mapTargetProperties(targetProperties) : targetProperties;
|
|
88
|
+
if (mappedTarget === null) return {
|
|
89
|
+
status: "unalignable",
|
|
90
|
+
detail: "section references cannot be mapped"
|
|
91
|
+
};
|
|
92
|
+
const targetWithoutHistory = withoutChangeHistory(mappedTarget);
|
|
93
|
+
if (canonicalJson(currentWithoutHistory) === canonicalJson(targetWithoutHistory)) continue;
|
|
94
|
+
changes.push({
|
|
95
|
+
position: currentParagraph.position,
|
|
96
|
+
current: currentWithoutHistory,
|
|
97
|
+
target: targetWithoutHistory
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
status: "matched",
|
|
102
|
+
changes
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
const boundaryParagraphEntriesOf = (document) => {
|
|
106
|
+
const children = boundaryChildrenOf(document);
|
|
107
|
+
if (!children) return null;
|
|
108
|
+
return children.flatMap((child) => child.type === "paragraph" ? [child.paragraph] : []);
|
|
109
|
+
};
|
|
110
|
+
/** Stage section deltas after document operations, against the accepted projection. */
|
|
111
|
+
const stageSectionBoundaryProperties = ({ state, target, originalRevisionIdSeed, revisionStamp, author, maxRanges, mapTargetProperties }) => {
|
|
112
|
+
if (!Number.isSafeInteger(maxRanges) || maxRanges < 0) return { status: "budget-exceeded" };
|
|
113
|
+
const reviewedState = resolveAllChangesInHeadlessStateWithMapping(state, "accept");
|
|
114
|
+
const reviewed = boundaryParagraphEntriesOf(reviewedState.state.doc);
|
|
115
|
+
const targets = boundaryParagraphEntriesOf(target);
|
|
116
|
+
if (!reviewed || !targets) return {
|
|
117
|
+
status: "unalignable",
|
|
118
|
+
detail: "section boundary revision history is unsupported"
|
|
119
|
+
};
|
|
120
|
+
if (reviewed.length !== targets.length) return {
|
|
121
|
+
status: "unalignable",
|
|
122
|
+
detail: "retained paragraph count differs"
|
|
123
|
+
};
|
|
124
|
+
const updates = [];
|
|
125
|
+
const inverse = reviewedState.mapping.invert();
|
|
126
|
+
for (const [index, reviewedParagraph] of reviewed.entries()) {
|
|
127
|
+
const targetParagraph = targets[index];
|
|
128
|
+
if (!targetParagraph || reviewedParagraph.text !== targetParagraph.text) return {
|
|
129
|
+
status: "unalignable",
|
|
130
|
+
detail: `retained paragraph text differs at ${index}`
|
|
131
|
+
};
|
|
132
|
+
if (targetParagraph.sectionProperties === void 0) {
|
|
133
|
+
if (reviewedParagraph.sectionProperties !== void 0) return {
|
|
134
|
+
status: "unalignable",
|
|
135
|
+
detail: "section endpoint presence differs"
|
|
136
|
+
};
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const targetProperties = withoutChangeHistory(targetParagraph.sectionProperties);
|
|
140
|
+
if (reviewedParagraph.sectionProperties !== void 0 && canonicalJson(withoutChangeHistory(reviewedParagraph.sectionProperties)) === canonicalJson(targetProperties)) continue;
|
|
141
|
+
const mapped = inverse.mapResult(reviewedParagraph.position, 1);
|
|
142
|
+
if (mapped.deleted) return {
|
|
143
|
+
status: "unalignable",
|
|
144
|
+
detail: "boundary has no source position"
|
|
145
|
+
};
|
|
146
|
+
const current = state.doc.nodeAt(mapped.pos);
|
|
147
|
+
if (!current || current.type.name !== "paragraph") return {
|
|
148
|
+
status: "unalignable",
|
|
149
|
+
detail: "mapped boundary is not a paragraph"
|
|
150
|
+
};
|
|
151
|
+
const attrs = expectParagraphAttrs(current);
|
|
152
|
+
const currentProperties = attrs._sectionProperties;
|
|
153
|
+
const marker = attrs.pPrMark;
|
|
154
|
+
if (marker?.kind === "ins" && marker.info.id >= originalRevisionIdSeed) {
|
|
155
|
+
if (currentProperties !== void 0) return {
|
|
156
|
+
status: "unalignable",
|
|
157
|
+
detail: "inserted endpoint already has section properties"
|
|
158
|
+
};
|
|
159
|
+
const staged = mapTargetProperties({
|
|
160
|
+
kind: "inserted",
|
|
161
|
+
current: void 0,
|
|
162
|
+
target: targetProperties
|
|
163
|
+
});
|
|
164
|
+
if (!staged || staged.kind !== "inserted") return {
|
|
165
|
+
status: "unalignable",
|
|
166
|
+
detail: "inserted section references cannot be mapped"
|
|
167
|
+
};
|
|
168
|
+
updates.push({
|
|
169
|
+
position: mapped.pos,
|
|
170
|
+
target: staged.target
|
|
171
|
+
});
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (currentProperties === void 0 || currentProperties.propertyChanges !== void 0) return {
|
|
175
|
+
status: "unalignable",
|
|
176
|
+
detail: "retained endpoint cannot carry a section change"
|
|
177
|
+
};
|
|
178
|
+
const staged = mapTargetProperties({
|
|
179
|
+
kind: "retained",
|
|
180
|
+
current: withoutChangeHistory(currentProperties),
|
|
181
|
+
target: targetProperties
|
|
182
|
+
});
|
|
183
|
+
if (!staged || staged.kind !== "retained") return {
|
|
184
|
+
status: "unalignable",
|
|
185
|
+
detail: "retained section references cannot be mapped"
|
|
186
|
+
};
|
|
187
|
+
updates.push({
|
|
188
|
+
position: mapped.pos,
|
|
189
|
+
previous: staged.previous,
|
|
190
|
+
target: staged.target
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (updates.length > maxRanges) return { status: "budget-exceeded" };
|
|
194
|
+
let nextRevisionId = revisionStamp.idSeed;
|
|
195
|
+
let transaction = state.tr;
|
|
196
|
+
for (const update of updates.toSorted((left, right) => right.position - left.position)) {
|
|
197
|
+
const position = transaction.mapping.map(update.position, 1);
|
|
198
|
+
const node = transaction.doc.nodeAt(position);
|
|
199
|
+
if (!node || node.type.name !== "paragraph") return {
|
|
200
|
+
status: "unalignable",
|
|
201
|
+
detail: "boundary moved while staging"
|
|
202
|
+
};
|
|
203
|
+
const previousReferences = update.previous === void 0 ? void 0 : sectionReferenceHistory({
|
|
204
|
+
previous: update.previous,
|
|
205
|
+
target: update.target
|
|
206
|
+
});
|
|
207
|
+
const propertyChanges = update.previous === void 0 ? void 0 : [{
|
|
208
|
+
type: "sectionPropertyChange",
|
|
209
|
+
info: {
|
|
210
|
+
id: nextRevisionId++,
|
|
211
|
+
author,
|
|
212
|
+
date: revisionStamp.date
|
|
213
|
+
},
|
|
214
|
+
previousProperties: update.previous,
|
|
215
|
+
...previousReferences !== void 0 && { previousReferences },
|
|
216
|
+
currentProperties: update.target
|
|
217
|
+
}];
|
|
218
|
+
transaction = transaction.setNodeMarkup(position, void 0, {
|
|
219
|
+
...node.attrs,
|
|
220
|
+
_sectionProperties: {
|
|
221
|
+
...update.target,
|
|
222
|
+
...propertyChanges === void 0 ? {} : { propertyChanges }
|
|
223
|
+
},
|
|
224
|
+
sectionBreakType: update.target.sectionStart ?? null
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
status: "matched",
|
|
229
|
+
transaction,
|
|
230
|
+
nextRevisionId,
|
|
231
|
+
rangeCount: updates.length
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
//#endregion
|
|
235
|
+
export { compareSectionBoundaryProperties, stageSectionBoundaryProperties };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/compare/style-resources.d.ts
|
|
3
|
+
type ImportReferencedStyleDefinitionsOptions = {
|
|
4
|
+
sourceStyles: document_d_exports.StyleDefinitions | undefined;
|
|
5
|
+
destinationStyles: document_d_exports.StyleDefinitions | undefined;
|
|
6
|
+
sourceTheme: document_d_exports.Theme | undefined;
|
|
7
|
+
destinationTheme: document_d_exports.Theme | undefined;
|
|
8
|
+
referencedStyleIds: readonly string[];
|
|
9
|
+
reservedStyleIds?: readonly string[];
|
|
10
|
+
materializeDefaultParagraphStyle?: boolean;
|
|
11
|
+
};
|
|
12
|
+
type ImportReferencedStyleDefinitionsResult = {
|
|
13
|
+
status: "unchanged" | "imported";
|
|
14
|
+
styles: document_d_exports.StyleDefinitions | undefined;
|
|
15
|
+
styleIdMap: ReadonlyMap<string, string>;
|
|
16
|
+
importedStyleIds: readonly string[];
|
|
17
|
+
defaultParagraphStyleId?: string;
|
|
18
|
+
} | {
|
|
19
|
+
status: "unalignable";
|
|
20
|
+
detail: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Add the target style definitions required by a comparison without changing
|
|
24
|
+
* existing package resources. A referenced style is only portable when both
|
|
25
|
+
* packages have the same document defaults and theme: those resources take
|
|
26
|
+
* part in OOXML style resolution even when a style definition itself is new.
|
|
27
|
+
*/
|
|
28
|
+
declare const importReferencedStyleDefinitions: ({ sourceStyles, destinationStyles, sourceTheme, destinationTheme, referencedStyleIds, reservedStyleIds, materializeDefaultParagraphStyle }: ImportReferencedStyleDefinitionsOptions) => ImportReferencedStyleDefinitionsResult;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { ImportReferencedStyleDefinitionsOptions, ImportReferencedStyleDefinitionsResult, importReferencedStyleDefinitions };
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { createStyleResolver } from "../prosemirror/styles/styleResolver.js";
|
|
2
|
+
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
3
|
+
import { resolveColorToHex } from "../utils/colorResolver.js";
|
|
4
|
+
import { resolveThemeFont } from "../utils/fontResolver.js";
|
|
5
|
+
//#region src/compare/style-resources.ts
|
|
6
|
+
const styleDependencies = ({ basedOn, link, next }) => [
|
|
7
|
+
basedOn,
|
|
8
|
+
link,
|
|
9
|
+
next
|
|
10
|
+
].filter((styleId) => styleId !== void 0);
|
|
11
|
+
const themesMatch = (sourceTheme, destinationTheme) => canonicalJson(sourceTheme) === canonicalJson(destinationTheme);
|
|
12
|
+
const hasThemeReference = (value) => {
|
|
13
|
+
if (Array.isArray(value)) return value.some(hasThemeReference);
|
|
14
|
+
if (typeof value !== "object" || value === null) return false;
|
|
15
|
+
return Object.entries(value).some(([key, nested]) => key.toLowerCase().includes("theme") || hasThemeReference(nested));
|
|
16
|
+
};
|
|
17
|
+
const materializeThemeColor = (color, theme) => {
|
|
18
|
+
if (!color || !color.themeColor) return color;
|
|
19
|
+
const rgb = resolveColorToHex(color, theme);
|
|
20
|
+
if (!rgb) return void 0;
|
|
21
|
+
const { themeColor: _themeColor, themeTint: _themeTint, themeShade: _themeShade, ...plain } = color;
|
|
22
|
+
return {
|
|
23
|
+
...plain,
|
|
24
|
+
rgb
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
const languageForThemeFontSlot = ({ formatting, slot }) => {
|
|
28
|
+
if (slot === "eastAsia") return formatting.language?.eastAsia ?? formatting.language?.val;
|
|
29
|
+
if (slot === "cs") return formatting.language?.bidi ?? formatting.language?.val;
|
|
30
|
+
return formatting.language?.val;
|
|
31
|
+
};
|
|
32
|
+
const scriptForLanguage = (language) => {
|
|
33
|
+
if (!language || typeof Intl.Locale !== "function") return void 0;
|
|
34
|
+
try {
|
|
35
|
+
return new Intl.Locale(language).maximize().script;
|
|
36
|
+
} catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const resolveThemeFontForFormatting = ({ formatting, slot, theme, themeRef }) => {
|
|
41
|
+
const script = scriptForLanguage(languageForThemeFontSlot({
|
|
42
|
+
formatting,
|
|
43
|
+
slot
|
|
44
|
+
}));
|
|
45
|
+
const themeFont = themeRef.toLowerCase().startsWith("major") ? theme?.fontScheme?.majorFont : theme?.fontScheme?.minorFont;
|
|
46
|
+
return (script ? themeFont?.fonts?.[script] : void 0) || resolveThemeFont(themeRef, theme?.fontScheme);
|
|
47
|
+
};
|
|
48
|
+
const materializeThemeTextFormatting = (formatting, theme, materializeThemeReferences) => {
|
|
49
|
+
if (!formatting) return {
|
|
50
|
+
status: "ok",
|
|
51
|
+
formatting
|
|
52
|
+
};
|
|
53
|
+
if (!materializeThemeReferences) return {
|
|
54
|
+
status: "ok",
|
|
55
|
+
formatting
|
|
56
|
+
};
|
|
57
|
+
if (hasThemeReference(formatting.shading)) return { status: "unalignable" };
|
|
58
|
+
const color = materializeThemeColor(formatting.color, theme);
|
|
59
|
+
if (formatting.color?.themeColor && !color) return { status: "unalignable" };
|
|
60
|
+
const underlineColor = materializeThemeColor(formatting.underline?.color, theme);
|
|
61
|
+
if (formatting.underline?.color?.themeColor && !underlineColor) return { status: "unalignable" };
|
|
62
|
+
const { asciiTheme: _asciiTheme, hAnsiTheme: _hAnsiTheme, eastAsiaTheme: _eastAsiaTheme, csTheme: _csTheme, ...fontFamily } = formatting.fontFamily ?? {};
|
|
63
|
+
const themeFonts = formatting.fontFamily;
|
|
64
|
+
const resolvedAscii = themeFonts?.asciiTheme ? resolveThemeFontForFormatting({
|
|
65
|
+
formatting,
|
|
66
|
+
slot: "ascii",
|
|
67
|
+
theme,
|
|
68
|
+
themeRef: themeFonts.asciiTheme
|
|
69
|
+
}) : null;
|
|
70
|
+
const resolvedHAnsi = themeFonts?.hAnsiTheme ? resolveThemeFontForFormatting({
|
|
71
|
+
formatting,
|
|
72
|
+
slot: "hAnsi",
|
|
73
|
+
theme,
|
|
74
|
+
themeRef: themeFonts.hAnsiTheme
|
|
75
|
+
}) : null;
|
|
76
|
+
const resolvedEastAsia = themeFonts?.eastAsiaTheme ? resolveThemeFontForFormatting({
|
|
77
|
+
formatting,
|
|
78
|
+
slot: "eastAsia",
|
|
79
|
+
theme,
|
|
80
|
+
themeRef: themeFonts.eastAsiaTheme
|
|
81
|
+
}) : null;
|
|
82
|
+
const resolvedCs = themeFonts?.csTheme ? resolveThemeFontForFormatting({
|
|
83
|
+
formatting,
|
|
84
|
+
slot: "cs",
|
|
85
|
+
theme,
|
|
86
|
+
themeRef: themeFonts.csTheme
|
|
87
|
+
}) : null;
|
|
88
|
+
if (themeFonts?.asciiTheme && !resolvedAscii || themeFonts?.hAnsiTheme && !resolvedHAnsi || themeFonts?.eastAsiaTheme && !resolvedEastAsia || themeFonts?.csTheme && !resolvedCs) return { status: "unalignable" };
|
|
89
|
+
return {
|
|
90
|
+
status: "ok",
|
|
91
|
+
formatting: {
|
|
92
|
+
...formatting,
|
|
93
|
+
...formatting.color && color && { color },
|
|
94
|
+
...formatting.underline && { underline: {
|
|
95
|
+
...formatting.underline,
|
|
96
|
+
...underlineColor && { color: underlineColor }
|
|
97
|
+
} },
|
|
98
|
+
...formatting.fontFamily && { fontFamily: {
|
|
99
|
+
...fontFamily,
|
|
100
|
+
...resolvedAscii && { ascii: resolvedAscii },
|
|
101
|
+
...resolvedHAnsi && { hAnsi: resolvedHAnsi },
|
|
102
|
+
...resolvedEastAsia && { eastAsia: resolvedEastAsia },
|
|
103
|
+
...resolvedCs && { cs: resolvedCs }
|
|
104
|
+
} }
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const materializeEffectiveStyle = ({ style, styles, theme, materializeThemeReferences }) => {
|
|
109
|
+
if (style.type === "numbering") return { status: "unalignable" };
|
|
110
|
+
const resolver = createStyleResolver(styles);
|
|
111
|
+
const resolved = style.type === "character" ? {
|
|
112
|
+
paragraphFormatting: void 0,
|
|
113
|
+
runFormatting: resolver.resolveRunStyle(style.styleId)
|
|
114
|
+
} : resolver.resolveParagraphStyle(style.styleId);
|
|
115
|
+
if (materializeThemeReferences && hasThemeReference(resolved.paragraphFormatting)) return { status: "unalignable" };
|
|
116
|
+
const runFormatting = materializeThemeTextFormatting(resolved.runFormatting, theme, materializeThemeReferences);
|
|
117
|
+
if (runFormatting.status === "unalignable") return runFormatting;
|
|
118
|
+
const conditionalStyles = [];
|
|
119
|
+
for (const conditional of style.tblStylePr ?? []) {
|
|
120
|
+
if (materializeThemeReferences && hasThemeReference(conditional.pPr)) return { status: "unalignable" };
|
|
121
|
+
const conditionalRunFormatting = materializeThemeTextFormatting(conditional.rPr, theme, materializeThemeReferences);
|
|
122
|
+
if (conditionalRunFormatting.status === "unalignable") return { status: "unalignable" };
|
|
123
|
+
conditionalStyles.push({
|
|
124
|
+
...conditional,
|
|
125
|
+
...conditionalRunFormatting.formatting && { rPr: conditionalRunFormatting.formatting }
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const { basedOn: _basedOn, ...independent } = style;
|
|
129
|
+
return {
|
|
130
|
+
status: "ok",
|
|
131
|
+
style: {
|
|
132
|
+
...independent,
|
|
133
|
+
...(style.type === "paragraph" || style.type === "table") && resolved.paragraphFormatting && { pPr: resolved.paragraphFormatting },
|
|
134
|
+
...runFormatting.formatting && { rPr: runFormatting.formatting },
|
|
135
|
+
...style.tblStylePr && { tblStylePr: conditionalStyles }
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
const materializeEffectiveDefaultParagraphStyle = ({ styles, destinationStyles, theme, styleId, materializeThemeReferences }) => {
|
|
140
|
+
const resolved = createStyleResolver(styles).resolveParagraphStyle(void 0);
|
|
141
|
+
const destinationResolved = createStyleResolver(destinationStyles).resolveParagraphStyle(void 0);
|
|
142
|
+
if (materializeThemeReferences && hasThemeReference(resolved.paragraphFormatting)) return { status: "unalignable" };
|
|
143
|
+
const runFormatting = materializeThemeTextFormatting(resolved.runFormatting, theme, materializeThemeReferences);
|
|
144
|
+
if (runFormatting.status === "unalignable") return runFormatting;
|
|
145
|
+
const sourceParagraphFormatting = resolved.paragraphFormatting;
|
|
146
|
+
const destinationParagraphFormatting = destinationResolved.paragraphFormatting;
|
|
147
|
+
const materializedSpacing = {
|
|
148
|
+
...sourceParagraphFormatting?.spaceBefore === void 0 && destinationParagraphFormatting?.spaceBefore !== void 0 && { spaceBefore: 0 },
|
|
149
|
+
...sourceParagraphFormatting?.spaceAfter === void 0 && destinationParagraphFormatting?.spaceAfter !== void 0 && { spaceAfter: 0 },
|
|
150
|
+
...sourceParagraphFormatting?.lineSpacing === void 0 && destinationParagraphFormatting?.lineSpacing !== void 0 && { lineSpacing: 240 },
|
|
151
|
+
...sourceParagraphFormatting?.lineSpacingRule === void 0 && destinationParagraphFormatting?.lineSpacingRule !== void 0 && { lineSpacingRule: "auto" },
|
|
152
|
+
...sourceParagraphFormatting?.beforeAutospacing === void 0 && destinationParagraphFormatting?.beforeAutospacing !== void 0 && { beforeAutospacing: false },
|
|
153
|
+
...sourceParagraphFormatting?.afterAutospacing === void 0 && destinationParagraphFormatting?.afterAutospacing !== void 0 && { afterAutospacing: false }
|
|
154
|
+
};
|
|
155
|
+
const paragraphFormatting = sourceParagraphFormatting || Object.keys(materializedSpacing).length > 0 ? {
|
|
156
|
+
...sourceParagraphFormatting,
|
|
157
|
+
...materializedSpacing
|
|
158
|
+
} : void 0;
|
|
159
|
+
return {
|
|
160
|
+
status: "ok",
|
|
161
|
+
style: {
|
|
162
|
+
styleId,
|
|
163
|
+
type: "paragraph",
|
|
164
|
+
...paragraphFormatting && { pPr: paragraphFormatting },
|
|
165
|
+
...runFormatting.formatting && { rPr: runFormatting.formatting }
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
const effectiveDefaultParagraphFormattingMatches = ({ sourceStyles, destinationStyles, sourceTheme, destinationTheme, materializeThemeReferences }) => {
|
|
170
|
+
const sourceResolved = createStyleResolver(sourceStyles).resolveParagraphStyle(void 0);
|
|
171
|
+
const destinationResolved = createStyleResolver(destinationStyles).resolveParagraphStyle(void 0);
|
|
172
|
+
const sourceRunFormatting = materializeThemeTextFormatting(sourceResolved.runFormatting, sourceTheme, materializeThemeReferences);
|
|
173
|
+
const destinationRunFormatting = materializeThemeTextFormatting(destinationResolved.runFormatting, destinationTheme, materializeThemeReferences);
|
|
174
|
+
if (sourceRunFormatting.status === "unalignable" || destinationRunFormatting.status === "unalignable" || materializeThemeReferences && hasThemeReference(sourceResolved.paragraphFormatting) || materializeThemeReferences && hasThemeReference(destinationResolved.paragraphFormatting)) return false;
|
|
175
|
+
return canonicalJson({
|
|
176
|
+
pPr: sourceResolved.paragraphFormatting,
|
|
177
|
+
rPr: sourceRunFormatting.formatting
|
|
178
|
+
}) === canonicalJson({
|
|
179
|
+
pPr: destinationResolved.paragraphFormatting,
|
|
180
|
+
rPr: destinationRunFormatting.formatting
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
const nextAvailableStyleAlias = ({ taken, sequence }) => {
|
|
184
|
+
let candidate = `FolioImportedStyle${sequence}`;
|
|
185
|
+
let suffix = sequence;
|
|
186
|
+
while (taken.has(candidate)) {
|
|
187
|
+
suffix += 1;
|
|
188
|
+
candidate = `FolioImportedStyle${suffix}`;
|
|
189
|
+
}
|
|
190
|
+
return candidate;
|
|
191
|
+
};
|
|
192
|
+
const remapImportedStyle = ({ style, styleIdMap, isolatedDefaultStyleIds }) => {
|
|
193
|
+
const { default: _default, ...withoutDefault } = style;
|
|
194
|
+
return {
|
|
195
|
+
...isolatedDefaultStyleIds.has(style.styleId) ? withoutDefault : style,
|
|
196
|
+
styleId: styleIdMap.get(style.styleId) ?? style.styleId,
|
|
197
|
+
...style.basedOn !== void 0 && { basedOn: styleIdMap.get(style.basedOn) ?? style.basedOn },
|
|
198
|
+
...style.link !== void 0 && { link: styleIdMap.get(style.link) ?? style.link },
|
|
199
|
+
...style.next !== void 0 && { next: styleIdMap.get(style.next) ?? style.next }
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Add the target style definitions required by a comparison without changing
|
|
204
|
+
* existing package resources. A referenced style is only portable when both
|
|
205
|
+
* packages have the same document defaults and theme: those resources take
|
|
206
|
+
* part in OOXML style resolution even when a style definition itself is new.
|
|
207
|
+
*/
|
|
208
|
+
const importReferencedStyleDefinitions = ({ sourceStyles, destinationStyles, sourceTheme, destinationTheme, referencedStyleIds, reservedStyleIds = [], materializeDefaultParagraphStyle = false }) => {
|
|
209
|
+
const requested = [...new Set(referencedStyleIds)].toSorted();
|
|
210
|
+
if (requested.length === 0 && !materializeDefaultParagraphStyle) return {
|
|
211
|
+
status: "unchanged",
|
|
212
|
+
styles: destinationStyles,
|
|
213
|
+
styleIdMap: /* @__PURE__ */ new Map(),
|
|
214
|
+
importedStyleIds: []
|
|
215
|
+
};
|
|
216
|
+
if (!sourceStyles) return {
|
|
217
|
+
status: "unalignable",
|
|
218
|
+
detail: "the target has no style definitions"
|
|
219
|
+
};
|
|
220
|
+
if (!destinationStyles) return {
|
|
221
|
+
status: "unalignable",
|
|
222
|
+
detail: "the base has no style definitions"
|
|
223
|
+
};
|
|
224
|
+
const sourceById = new Map(sourceStyles.styles.map((style) => [style.styleId, style]));
|
|
225
|
+
const destinationById = new Map(destinationStyles.styles.map((style) => [style.styleId, style]));
|
|
226
|
+
const reserved = new Set(reservedStyleIds);
|
|
227
|
+
const required = /* @__PURE__ */ new Set();
|
|
228
|
+
const pending = [...requested];
|
|
229
|
+
while (pending.length > 0) {
|
|
230
|
+
const styleId = pending.pop();
|
|
231
|
+
if (!styleId || required.has(styleId)) continue;
|
|
232
|
+
const source = sourceById.get(styleId);
|
|
233
|
+
if (!source) return {
|
|
234
|
+
status: "unalignable",
|
|
235
|
+
detail: "a referenced target style is missing"
|
|
236
|
+
};
|
|
237
|
+
required.add(styleId);
|
|
238
|
+
pending.push(...styleDependencies(source));
|
|
239
|
+
}
|
|
240
|
+
const imported = [...required].toSorted();
|
|
241
|
+
const taken = /* @__PURE__ */ new Set([
|
|
242
|
+
...sourceById.keys(),
|
|
243
|
+
...destinationById.keys(),
|
|
244
|
+
...reserved
|
|
245
|
+
]);
|
|
246
|
+
const styleIdMap = /* @__PURE__ */ new Map();
|
|
247
|
+
const isolatedDefaultStyleIds = /* @__PURE__ */ new Set();
|
|
248
|
+
let aliasSequence = 1;
|
|
249
|
+
for (const styleId of imported) {
|
|
250
|
+
const source = sourceById.get(styleId);
|
|
251
|
+
const destination = destinationById.get(styleId);
|
|
252
|
+
if (!source) return {
|
|
253
|
+
status: "unalignable",
|
|
254
|
+
detail: "a referenced target style is missing"
|
|
255
|
+
};
|
|
256
|
+
if (destination !== void 0 && canonicalJson(source) !== canonicalJson(destination) || !destination && (reserved.has(styleId) || source.default)) {
|
|
257
|
+
const alias = nextAvailableStyleAlias({
|
|
258
|
+
taken,
|
|
259
|
+
sequence: aliasSequence
|
|
260
|
+
});
|
|
261
|
+
aliasSequence += 1;
|
|
262
|
+
taken.add(alias);
|
|
263
|
+
styleIdMap.set(styleId, alias);
|
|
264
|
+
if (source.default) isolatedDefaultStyleIds.add(styleId);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
styleIdMap.set(styleId, styleId);
|
|
268
|
+
}
|
|
269
|
+
const contextMatches = canonicalJson(sourceStyles.docDefaults) === canonicalJson(destinationStyles.docDefaults) && themesMatch(sourceTheme, destinationTheme);
|
|
270
|
+
const materializeThemeReferences = !themesMatch(sourceTheme, destinationTheme);
|
|
271
|
+
const additions = sourceStyles.styles.filter(({ styleId }) => required.has(styleId) && (!destinationById.has(styleId) || styleIdMap.get(styleId) !== styleId));
|
|
272
|
+
if (contextMatches) {
|
|
273
|
+
if (additions.length === 0) return {
|
|
274
|
+
status: "unchanged",
|
|
275
|
+
styles: destinationStyles,
|
|
276
|
+
styleIdMap,
|
|
277
|
+
importedStyleIds: []
|
|
278
|
+
};
|
|
279
|
+
return {
|
|
280
|
+
status: "imported",
|
|
281
|
+
styles: {
|
|
282
|
+
...destinationStyles,
|
|
283
|
+
styles: [...destinationStyles.styles, ...additions.map((style) => remapImportedStyle({
|
|
284
|
+
style,
|
|
285
|
+
styleIdMap,
|
|
286
|
+
isolatedDefaultStyleIds
|
|
287
|
+
}))]
|
|
288
|
+
},
|
|
289
|
+
styleIdMap,
|
|
290
|
+
importedStyleIds: additions.map(({ styleId }) => styleId)
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const materializedStyles = [];
|
|
294
|
+
for (const style of additions) {
|
|
295
|
+
const result = materializeEffectiveStyle({
|
|
296
|
+
style,
|
|
297
|
+
styles: sourceStyles,
|
|
298
|
+
theme: sourceTheme,
|
|
299
|
+
materializeThemeReferences
|
|
300
|
+
});
|
|
301
|
+
if (result.status === "unalignable") return {
|
|
302
|
+
status: "unalignable",
|
|
303
|
+
detail: "a referenced style has formatting that cannot be materialized"
|
|
304
|
+
};
|
|
305
|
+
materializedStyles.push(remapImportedStyle({
|
|
306
|
+
style: result.style,
|
|
307
|
+
styleIdMap,
|
|
308
|
+
isolatedDefaultStyleIds
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
let defaultParagraphStyleId;
|
|
312
|
+
let materializedDefaultParagraphStyle;
|
|
313
|
+
if (materializeDefaultParagraphStyle && !effectiveDefaultParagraphFormattingMatches({
|
|
314
|
+
sourceStyles,
|
|
315
|
+
destinationStyles,
|
|
316
|
+
sourceTheme,
|
|
317
|
+
destinationTheme,
|
|
318
|
+
materializeThemeReferences
|
|
319
|
+
})) {
|
|
320
|
+
defaultParagraphStyleId = nextAvailableStyleAlias({
|
|
321
|
+
taken,
|
|
322
|
+
sequence: aliasSequence
|
|
323
|
+
});
|
|
324
|
+
const result = materializeEffectiveDefaultParagraphStyle({
|
|
325
|
+
styles: sourceStyles,
|
|
326
|
+
destinationStyles,
|
|
327
|
+
theme: sourceTheme,
|
|
328
|
+
styleId: defaultParagraphStyleId,
|
|
329
|
+
materializeThemeReferences
|
|
330
|
+
});
|
|
331
|
+
if (result.status === "unalignable") return {
|
|
332
|
+
status: "unalignable",
|
|
333
|
+
detail: "default paragraph formatting cannot be isolated from the base formatting context"
|
|
334
|
+
};
|
|
335
|
+
materializedDefaultParagraphStyle = result.style;
|
|
336
|
+
materializedStyles.push(result.style);
|
|
337
|
+
}
|
|
338
|
+
if (materializedStyles.length === 0) return {
|
|
339
|
+
status: "unchanged",
|
|
340
|
+
styles: destinationStyles,
|
|
341
|
+
styleIdMap,
|
|
342
|
+
importedStyleIds: []
|
|
343
|
+
};
|
|
344
|
+
const candidateStyles = {
|
|
345
|
+
...destinationStyles,
|
|
346
|
+
styles: [...destinationStyles.styles, ...materializedStyles]
|
|
347
|
+
};
|
|
348
|
+
const sourceResolver = createStyleResolver(sourceStyles);
|
|
349
|
+
const candidateResolver = createStyleResolver(candidateStyles);
|
|
350
|
+
for (const style of additions) {
|
|
351
|
+
const candidateStyleId = styleIdMap.get(style.styleId) ?? style.styleId;
|
|
352
|
+
const sourceResolved = style.type === "character" ? {
|
|
353
|
+
paragraphFormatting: void 0,
|
|
354
|
+
runFormatting: sourceResolver.resolveRunStyle(style.styleId)
|
|
355
|
+
} : sourceResolver.resolveParagraphStyle(style.styleId);
|
|
356
|
+
const candidateResolved = style.type === "character" ? {
|
|
357
|
+
paragraphFormatting: void 0,
|
|
358
|
+
runFormatting: candidateResolver.resolveRunStyle(candidateStyleId)
|
|
359
|
+
} : candidateResolver.resolveParagraphStyle(candidateStyleId);
|
|
360
|
+
const sourceRunFormatting = materializeThemeTextFormatting(sourceResolved.runFormatting, sourceTheme, materializeThemeReferences);
|
|
361
|
+
const candidateRunFormatting = materializeThemeTextFormatting(candidateResolved.runFormatting, destinationTheme, materializeThemeReferences);
|
|
362
|
+
if (sourceRunFormatting.status === "unalignable" || candidateRunFormatting.status === "unalignable" || materializeThemeReferences && hasThemeReference(sourceResolved.paragraphFormatting) || materializeThemeReferences && hasThemeReference(candidateResolved.paragraphFormatting) || canonicalJson({
|
|
363
|
+
pPr: sourceResolved.paragraphFormatting,
|
|
364
|
+
rPr: sourceRunFormatting.formatting
|
|
365
|
+
}) !== canonicalJson({
|
|
366
|
+
pPr: candidateResolved.paragraphFormatting,
|
|
367
|
+
rPr: candidateRunFormatting.formatting
|
|
368
|
+
})) return {
|
|
369
|
+
status: "unalignable",
|
|
370
|
+
detail: "a referenced style differs after materializing its formatting"
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
if (defaultParagraphStyleId !== void 0) {
|
|
374
|
+
const sourceResolved = {
|
|
375
|
+
paragraphFormatting: materializedDefaultParagraphStyle?.pPr,
|
|
376
|
+
runFormatting: materializedDefaultParagraphStyle?.rPr
|
|
377
|
+
};
|
|
378
|
+
const candidateResolved = candidateResolver.resolveParagraphStyle(defaultParagraphStyleId);
|
|
379
|
+
const sourceRunFormatting = {
|
|
380
|
+
status: "ok",
|
|
381
|
+
formatting: sourceResolved.runFormatting
|
|
382
|
+
};
|
|
383
|
+
const candidateRunFormatting = materializeThemeTextFormatting(candidateResolved.runFormatting, destinationTheme, materializeThemeReferences);
|
|
384
|
+
if (candidateRunFormatting.status === "unalignable" || materializeThemeReferences && hasThemeReference(candidateResolved.paragraphFormatting) || canonicalJson({
|
|
385
|
+
pPr: sourceResolved.paragraphFormatting,
|
|
386
|
+
rPr: sourceRunFormatting.formatting
|
|
387
|
+
}) !== canonicalJson({
|
|
388
|
+
pPr: candidateResolved.paragraphFormatting,
|
|
389
|
+
rPr: candidateRunFormatting.formatting
|
|
390
|
+
})) return {
|
|
391
|
+
status: "unalignable",
|
|
392
|
+
detail: "default paragraph formatting cannot be isolated from the base formatting context"
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
status: "imported",
|
|
397
|
+
styles: candidateStyles,
|
|
398
|
+
styleIdMap,
|
|
399
|
+
importedStyleIds: materializedStyles.map(({ styleId }) => styleId),
|
|
400
|
+
...defaultParagraphStyleId !== void 0 && { defaultParagraphStyleId }
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
//#endregion
|
|
404
|
+
export { importReferencedStyleDefinitions };
|