@stll/folio-core 0.49.0 → 0.51.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/headless.d.ts +37 -1
- package/dist/ai-edits/headless.js +47 -16
- package/dist/ai-edits/word-diff.js +134 -1
- package/dist/compare/content-alignment.js +220 -5
- package/dist/compare/content.d.ts +1 -0
- package/dist/compare/content.js +51 -20
- package/dist/display-list/dom/renderDisplayListToDom.d.ts +10 -1
- package/dist/display-list/dom/renderDisplayListToDom.js +8 -7
- package/dist/display-list/html/renderDisplayListToHtml.d.ts +21 -0
- package/dist/display-list/html/renderDisplayListToHtml.js +126 -0
- package/dist/display-list/selectDisplayPages.d.ts +6 -0
- package/dist/display-list/selectDisplayPages.js +44 -0
- package/dist/docx/selectiveSave.d.ts +1 -1
- package/dist/docx/selectiveSave.js +16 -6
- package/dist/docx/structuralXmlPatch.d.ts +14 -0
- package/dist/docx/structuralXmlPatch.js +209 -0
- package/dist/export-pdf.d.ts +35 -2
- package/dist/export-pdf.js +51 -20
- package/dist/fonts/fontsourceFaces.d.ts +47 -0
- package/dist/fonts/fontsourceFaces.js +230 -0
- package/dist/layout-bridge/convert/flowBlockPostprocessing.d.ts +8 -0
- package/dist/layout-bridge/convert/flowBlockPostprocessing.js +106 -0
- package/dist/layout-bridge/convert/flowBorders.d.ts +17 -0
- package/dist/layout-bridge/convert/flowBorders.js +31 -0
- package/dist/layout-bridge/convert/flowConversionShared.d.ts +111 -0
- package/dist/layout-bridge/convert/flowConversionShared.js +23 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +2 -1
- package/dist/layout-bridge/convert/footnoteLayout.js +2 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +2 -1
- package/dist/layout-bridge/convert/imageConversion.d.ts +33 -0
- package/dist/layout-bridge/convert/imageConversion.js +118 -0
- package/dist/layout-bridge/convert/listMarkers.d.ts +28 -0
- package/dist/layout-bridge/convert/listMarkers.js +98 -0
- package/dist/layout-bridge/convert/noteReferences.d.ts +14 -0
- package/dist/layout-bridge/convert/noteReferences.js +29 -0
- package/dist/layout-bridge/convert/pageBreakSplitting.d.ts +16 -0
- package/dist/layout-bridge/convert/pageBreakSplitting.js +140 -0
- package/dist/layout-bridge/convert/paragraphAttrs.d.ts +20 -0
- package/dist/layout-bridge/convert/paragraphAttrs.js +234 -0
- package/dist/layout-bridge/convert/paragraphConversion.d.ts +12 -0
- package/dist/layout-bridge/convert/paragraphConversion.js +112 -0
- package/dist/layout-bridge/convert/paragraphRuns.d.ts +15 -0
- package/dist/layout-bridge/convert/paragraphRuns.js +281 -0
- package/dist/layout-bridge/convert/runFormattingMerge.d.ts +19 -0
- package/dist/layout-bridge/convert/runFormattingMerge.js +167 -0
- package/dist/layout-bridge/convert/runMarkFormatting.d.ts +11 -0
- package/dist/layout-bridge/convert/runMarkFormatting.js +291 -0
- package/dist/layout-bridge/convert/sectionBoundaries.d.ts +35 -0
- package/dist/layout-bridge/convert/sectionBoundaries.js +114 -0
- package/dist/layout-bridge/convert/tableConversion.d.ts +12 -0
- package/dist/layout-bridge/convert/tableConversion.js +303 -0
- package/dist/layout-bridge/convert/textBoxFill.d.ts +20 -0
- package/dist/layout-bridge/convert/textBoxFill.js +42 -0
- package/dist/layout-bridge/convert/textFormattingConversion.d.ts +22 -0
- package/dist/layout-bridge/convert/textFormattingConversion.js +120 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +5 -113
- package/dist/layout-bridge/convert/toFlowBlocks.js +11 -2082
- package/dist/layout-bridge/engine/hitTest.js +1 -1
- package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
- package/dist/layout-bridge/engine/measuring/index.js +2 -1
- package/dist/layout-bridge/engine/selectionRects.js +1 -1
- package/dist/layout-engine/imageLayout.d.ts +9 -0
- package/dist/layout-engine/imageLayout.js +48 -0
- package/dist/layout-engine/index.d.ts +3 -18
- package/dist/layout-engine/index.js +12 -937
- package/dist/layout-engine/layoutFlowShared.d.ts +6 -0
- package/dist/layout-engine/layoutFlowShared.js +8 -0
- package/dist/layout-engine/measure/crossRunWords.d.ts +45 -0
- package/dist/layout-engine/measure/crossRunWords.js +172 -0
- package/dist/layout-engine/measure/floatingLineClearance.d.ts +24 -0
- package/dist/layout-engine/measure/floatingLineClearance.js +44 -0
- package/dist/layout-engine/measure/inlineObjectMetrics.d.ts +6 -0
- package/dist/layout-engine/measure/inlineObjectMetrics.js +52 -0
- package/dist/layout-engine/measure/justification.d.ts +32 -0
- package/dist/layout-engine/measure/justification.js +83 -0
- package/dist/layout-engine/measure/lineFitting.d.ts +48 -0
- package/dist/layout-engine/measure/lineFitting.js +145 -0
- package/dist/layout-engine/measure/lineTypography.d.ts +44 -0
- package/dist/layout-engine/measure/lineTypography.js +124 -0
- package/dist/layout-engine/measure/measureBlocks.js +2 -1
- package/dist/layout-engine/measure/measureParagraph.d.ts +1 -20
- package/dist/layout-engine/measure/measureParagraph.js +32 -734
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +109 -0
- package/dist/layout-engine/measure/paragraphMeasureShared.js +82 -0
- package/dist/layout-engine/measure/paragraphTabs.d.ts +18 -0
- package/dist/layout-engine/measure/paragraphTabs.js +78 -0
- package/dist/layout-engine/paragraphLayout.d.ts +23 -0
- package/dist/layout-engine/paragraphLayout.js +204 -0
- package/dist/layout-engine/sectionLayout.d.ts +45 -0
- package/dist/layout-engine/sectionLayout.js +216 -0
- package/dist/layout-engine/tableLayout.d.ts +17 -0
- package/dist/layout-engine/tableLayout.js +369 -0
- package/dist/layout-engine/textBoxLayout.d.ts +15 -0
- package/dist/layout-engine/textBoxLayout.js +137 -0
- package/dist/layout-painter/renderPage.js +1 -0
- package/dist/managers/editorShortcuts.d.ts +16 -3
- package/dist/managers/editorShortcuts.js +6 -4
- package/dist/paged-layout/sectionBlockWidths.d.ts +2 -1
- package/dist/paged-layout/sectionBlockWidths.js +1 -1
- package/dist/prosemirror/extensions/StarterKit.d.ts +3 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -1
- package/dist/prosemirror/extensions/core/HistoryExtension.d.ts +9 -1
- package/dist/prosemirror/extensions/core/HistoryExtension.js +4 -3
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +12 -5
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +91 -33
- package/dist/server.d.ts +3 -2
- package/package.json +2 -2
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { getFontAlternate } from "../../fonts/fontAlternates.js";
|
|
2
|
+
import { expectFieldAttrs, expectImageAttrs, expectMathAttrs, expectParagraphAttrs, expectPreservedXmlAttrs, expectSymbolAttrs } from "../../prosemirror/attrs/index.js";
|
|
3
|
+
import { decodeOoxmlSymbolCharacter } from "../../utils/ooxmlSymbol.js";
|
|
4
|
+
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
5
|
+
import { buildImageRun, constrainImageToPage, hasPaintableImageSource, hasRelationshipBackedImageBox } from "./imageConversion.js";
|
|
6
|
+
import { isNoteReferenceMarkXml } from "./noteReferences.js";
|
|
7
|
+
import { applyCharacterStyleToggleFormatting, markDefaultBlackTextColorSource, mergeRunFormatting } from "./runFormattingMerge.js";
|
|
8
|
+
import { extractRunFormatting } from "./runMarkFormatting.js";
|
|
9
|
+
import { paragraphRunDefaults } from "./textFormattingConversion.js";
|
|
10
|
+
//#region src/layout-bridge/convert/paragraphRuns.ts
|
|
11
|
+
/**
|
|
12
|
+
* In TOC paragraphs, strip the resolved Hyperlink character-style colour and
|
|
13
|
+
* underline so the painter's link fallback doesn't fire. The PM doc keeps the
|
|
14
|
+
* original marks so copy/paste out of a TOC still carries the Hyperlink
|
|
15
|
+
* styling like Word does. Applies to both text and field runs — a TOC entry's
|
|
16
|
+
* page number is a PAGEREF field inside the entry's hyperlink.
|
|
17
|
+
*
|
|
18
|
+
* Mutates `formatting` in place; cheaper than re-cloning per run.
|
|
19
|
+
*/
|
|
20
|
+
function stripTocHyperlinkStyle(formatting) {
|
|
21
|
+
if (!formatting.hyperlink) return;
|
|
22
|
+
formatting.hyperlink.noDefaultStyle = true;
|
|
23
|
+
delete formatting.color;
|
|
24
|
+
delete formatting.underline;
|
|
25
|
+
}
|
|
26
|
+
const isTrackedRunMark = ({ type }) => type.name === "insertion" || type.name === "deletion";
|
|
27
|
+
/**
|
|
28
|
+
* Inline wrappers own marks that apply to every projected descendant. A
|
|
29
|
+
* descendant's mark of the same type is more specific, and any descendant
|
|
30
|
+
* revision replaces (rather than combines with) an inherited revision.
|
|
31
|
+
*/
|
|
32
|
+
const mergeProjectedInlineMarks = (inheritedMarks, ownMarks) => {
|
|
33
|
+
if (inheritedMarks.length === 0) return ownMarks;
|
|
34
|
+
const ownMarkTypes = new Set(ownMarks.map(({ type }) => type));
|
|
35
|
+
const hasOwnTrackedMark = ownMarks.some(isTrackedRunMark);
|
|
36
|
+
return [...inheritedMarks.filter((mark) => !ownMarkTypes.has(mark.type) && !(hasOwnTrackedMark && isTrackedRunMark(mark))), ...ownMarks];
|
|
37
|
+
};
|
|
38
|
+
function paragraphToRuns(node, startPos, _options, pageBreaks) {
|
|
39
|
+
const runs = [];
|
|
40
|
+
const offset = startPos + 1;
|
|
41
|
+
const theme = _options.theme;
|
|
42
|
+
const fontAlternates = _options.fontAlternates;
|
|
43
|
+
const pmAttrs = expectParagraphAttrs(node);
|
|
44
|
+
const paraDefaults = paragraphRunDefaults(pmAttrs, theme, fontAlternates);
|
|
45
|
+
const paragraphStyleId = pmAttrs.styleId;
|
|
46
|
+
const inTocParagraph = pmAttrs._tableOfContentsLevel !== void 0 || tableOfContentsStyleLevel({ styleId: paragraphStyleId }) !== void 0;
|
|
47
|
+
let leadingRenderedPageBreakPending = pmAttrs.renderedPageBreakBefore === true;
|
|
48
|
+
function pushRunsForChild(child, childPos, inheritedMarks = []) {
|
|
49
|
+
if (child.type.name === "bookmarkBoundary") return;
|
|
50
|
+
if (child.type.name === "renderedPageBreak") {
|
|
51
|
+
if (leadingRenderedPageBreakPending) {
|
|
52
|
+
leadingRenderedPageBreakPending = false;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
runs.push({
|
|
56
|
+
kind: "renderedPageBreak",
|
|
57
|
+
pmStart: childPos,
|
|
58
|
+
pmEnd: childPos + child.nodeSize
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const effectiveMarks = mergeProjectedInlineMarks(inheritedMarks, child.marks);
|
|
63
|
+
if (child.type.name === "pageBreakRun") {
|
|
64
|
+
const trackedChange = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
65
|
+
if (trackedChange.isDeletion) {
|
|
66
|
+
runs.push({
|
|
67
|
+
kind: "text",
|
|
68
|
+
text: "",
|
|
69
|
+
isDeletion: true,
|
|
70
|
+
...trackedChange.changeAuthor !== void 0 ? { changeAuthor: trackedChange.changeAuthor } : {},
|
|
71
|
+
...trackedChange.changeDate !== void 0 ? { changeDate: trackedChange.changeDate } : {},
|
|
72
|
+
...trackedChange.changeRevisionId !== void 0 ? { changeRevisionId: trackedChange.changeRevisionId } : {},
|
|
73
|
+
...trackedChange.isSuggestion === true ? { isSuggestion: true } : {},
|
|
74
|
+
...trackedChange.suggestionId !== void 0 ? { suggestionId: trackedChange.suggestionId } : {},
|
|
75
|
+
pmStart: childPos,
|
|
76
|
+
pmEnd: childPos + child.nodeSize
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
pageBreaks?.push({
|
|
81
|
+
pmStart: childPos,
|
|
82
|
+
pmEnd: childPos + child.nodeSize,
|
|
83
|
+
...trackedChange.isInsertion ? { trackedChange: {
|
|
84
|
+
isInsertion: true,
|
|
85
|
+
...trackedChange.changeAuthor !== void 0 ? { changeAuthor: trackedChange.changeAuthor } : {},
|
|
86
|
+
...trackedChange.changeDate !== void 0 ? { changeDate: trackedChange.changeDate } : {},
|
|
87
|
+
...trackedChange.changeRevisionId !== void 0 ? { changeRevisionId: trackedChange.changeRevisionId } : {},
|
|
88
|
+
...trackedChange.isSuggestion === true ? { isSuggestion: true } : {},
|
|
89
|
+
...trackedChange.suggestionId !== void 0 ? { suggestionId: trackedChange.suggestionId } : {}
|
|
90
|
+
} } : {}
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (child.type.name !== "sdt") leadingRenderedPageBreakPending = false;
|
|
95
|
+
if (child.isText && child.text) {
|
|
96
|
+
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
97
|
+
applyCharacterStyleToggleFormatting({
|
|
98
|
+
formatting,
|
|
99
|
+
marks: effectiveMarks,
|
|
100
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
101
|
+
styleResolver: _options.styleResolver
|
|
102
|
+
});
|
|
103
|
+
if (inTocParagraph) stripTocHyperlinkStyle(formatting);
|
|
104
|
+
const run = {
|
|
105
|
+
kind: "text",
|
|
106
|
+
text: child.text,
|
|
107
|
+
...mergeRunFormatting(paraDefaults, formatting),
|
|
108
|
+
pmStart: childPos,
|
|
109
|
+
pmEnd: childPos + child.nodeSize
|
|
110
|
+
};
|
|
111
|
+
runs.push(run);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (child.type.name === "symbol") {
|
|
115
|
+
const attrs = expectSymbolAttrs(child);
|
|
116
|
+
const text = decodeOoxmlSymbolCharacter(attrs.char);
|
|
117
|
+
if (text === null) return;
|
|
118
|
+
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
119
|
+
applyCharacterStyleToggleFormatting({
|
|
120
|
+
formatting,
|
|
121
|
+
marks: effectiveMarks,
|
|
122
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
123
|
+
styleResolver: _options.styleResolver
|
|
124
|
+
});
|
|
125
|
+
if (inTocParagraph) stripTocHyperlinkStyle(formatting);
|
|
126
|
+
const alternateFontFamily = getFontAlternate(attrs.font, fontAlternates);
|
|
127
|
+
formatting.fontFamily = attrs.font;
|
|
128
|
+
if (alternateFontFamily) formatting.alternateFontFamily = alternateFontFamily;
|
|
129
|
+
runs.push({
|
|
130
|
+
kind: "text",
|
|
131
|
+
text,
|
|
132
|
+
...mergeRunFormatting(paraDefaults, formatting),
|
|
133
|
+
pmStart: childPos,
|
|
134
|
+
pmEnd: childPos + child.nodeSize
|
|
135
|
+
});
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (child.type.name === "preservedXml") {
|
|
139
|
+
const { xml, text: capturedText } = expectPreservedXmlAttrs(child);
|
|
140
|
+
const text = capturedText === "" && _options.noteReferenceMarkText !== void 0 && isNoteReferenceMarkXml(xml) ? _options.noteReferenceMarkText : capturedText;
|
|
141
|
+
if (text === "") return;
|
|
142
|
+
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
143
|
+
applyCharacterStyleToggleFormatting({
|
|
144
|
+
formatting,
|
|
145
|
+
marks: effectiveMarks,
|
|
146
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
147
|
+
styleResolver: _options.styleResolver
|
|
148
|
+
});
|
|
149
|
+
runs.push({
|
|
150
|
+
kind: "text",
|
|
151
|
+
text,
|
|
152
|
+
...mergeRunFormatting(paraDefaults, formatting),
|
|
153
|
+
pmStart: childPos,
|
|
154
|
+
pmEnd: childPos + child.nodeSize
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (child.type.name === "hardBreak") {
|
|
159
|
+
runs.push({
|
|
160
|
+
kind: "lineBreak",
|
|
161
|
+
pmStart: childPos,
|
|
162
|
+
pmEnd: childPos + child.nodeSize
|
|
163
|
+
});
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (child.type.name === "tab") {
|
|
167
|
+
const formatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
168
|
+
applyCharacterStyleToggleFormatting({
|
|
169
|
+
formatting,
|
|
170
|
+
marks: effectiveMarks,
|
|
171
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
172
|
+
styleResolver: _options.styleResolver
|
|
173
|
+
});
|
|
174
|
+
const run = {
|
|
175
|
+
kind: "tab",
|
|
176
|
+
...mergeRunFormatting(paraDefaults, formatting),
|
|
177
|
+
pmStart: childPos,
|
|
178
|
+
pmEnd: childPos + child.nodeSize
|
|
179
|
+
};
|
|
180
|
+
runs.push(run);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (child.type.name === "image") {
|
|
184
|
+
const attrs = expectImageAttrs(child);
|
|
185
|
+
if (!hasPaintableImageSource(attrs) && !hasRelationshipBackedImageBox(attrs)) return;
|
|
186
|
+
const constrained = constrainImageToPage(attrs.width ?? 100, attrs.height ?? 100, _options.pageContentHeight);
|
|
187
|
+
const trackedFmt = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
188
|
+
const run = buildImageRun(attrs, constrained, childPos, childPos + child.nodeSize, trackedFmt, _options.forceAnchorLayoutInCell);
|
|
189
|
+
runs.push(run);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (child.type.name === "structuredField") {
|
|
193
|
+
let containsPageBreak = false;
|
|
194
|
+
child.descendants((descendant) => {
|
|
195
|
+
if (descendant.type.name === "pageBreakRun") {
|
|
196
|
+
containsPageBreak = true;
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return true;
|
|
200
|
+
});
|
|
201
|
+
if (containsPageBreak) {
|
|
202
|
+
const fieldContentStart = childPos + 1;
|
|
203
|
+
child.forEach((fieldChild, fieldChildOffset) => {
|
|
204
|
+
pushRunsForChild(fieldChild, fieldContentStart + fieldChildOffset, effectiveMarks);
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (child.type.name === "field" || child.type.name === "structuredField") {
|
|
210
|
+
const attrs = expectFieldAttrs(child);
|
|
211
|
+
const ft = attrs.fieldType;
|
|
212
|
+
let mappedType = "OTHER";
|
|
213
|
+
if (ft === "PAGE") mappedType = "PAGE";
|
|
214
|
+
else if (ft === "NUMPAGES") mappedType = "NUMPAGES";
|
|
215
|
+
else if (ft === "DATE") mappedType = "DATE";
|
|
216
|
+
else if (ft === "TIME") mappedType = "TIME";
|
|
217
|
+
const extractedFieldFormatting = extractRunFormatting(effectiveMarks, theme, fontAlternates);
|
|
218
|
+
applyCharacterStyleToggleFormatting({
|
|
219
|
+
formatting: extractedFieldFormatting,
|
|
220
|
+
marks: effectiveMarks,
|
|
221
|
+
paragraphFormatting: pmAttrs.defaultTextFormatting,
|
|
222
|
+
styleResolver: _options.styleResolver
|
|
223
|
+
});
|
|
224
|
+
if (inTocParagraph) stripTocHyperlinkStyle(extractedFieldFormatting);
|
|
225
|
+
const fieldFormatting = markDefaultBlackTextColorSource(extractedFieldFormatting, paraDefaults);
|
|
226
|
+
const run = {
|
|
227
|
+
kind: "field",
|
|
228
|
+
fieldType: mappedType,
|
|
229
|
+
instruction: attrs.instruction,
|
|
230
|
+
fallback: _options.numberedRefResults?.get(child) ?? attrs.displayText ?? "",
|
|
231
|
+
...attrs.fldLock ? { fldLock: true } : {},
|
|
232
|
+
pmStart: childPos,
|
|
233
|
+
pmEnd: childPos + child.nodeSize,
|
|
234
|
+
...fieldFormatting
|
|
235
|
+
};
|
|
236
|
+
runs.push(run);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (child.type.name === "math") {
|
|
240
|
+
const attrs = expectMathAttrs(child);
|
|
241
|
+
const plainText = attrs.plainText || "[equation]";
|
|
242
|
+
runs.push({
|
|
243
|
+
kind: "math",
|
|
244
|
+
display: attrs.display ?? "inline",
|
|
245
|
+
ommlXml: attrs.ommlXml,
|
|
246
|
+
plainText,
|
|
247
|
+
italic: true,
|
|
248
|
+
fontFamily: "Cambria Math",
|
|
249
|
+
pmStart: childPos,
|
|
250
|
+
pmEnd: childPos + child.nodeSize
|
|
251
|
+
});
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (child.type.name === "sdt") {
|
|
255
|
+
const sdtInnerOffset = childPos + 1;
|
|
256
|
+
child.forEach((sdtChild, sdtChildOffset) => {
|
|
257
|
+
pushRunsForChild(sdtChild, sdtInnerOffset + sdtChildOffset, effectiveMarks);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
node.forEach((child, childOffset) => {
|
|
262
|
+
pushRunsForChild(child, offset + childOffset);
|
|
263
|
+
});
|
|
264
|
+
const { defaultFont, defaultSize } = _options;
|
|
265
|
+
if (defaultFont !== void 0 || defaultSize !== void 0) for (const run of runs) switch (run.kind) {
|
|
266
|
+
case "text":
|
|
267
|
+
case "tab":
|
|
268
|
+
case "renderedPageBreak":
|
|
269
|
+
case "field":
|
|
270
|
+
case "math":
|
|
271
|
+
if (defaultFont !== void 0) run.fontFamily ??= defaultFont;
|
|
272
|
+
if (defaultSize !== void 0) run.fontSize ??= defaultSize;
|
|
273
|
+
break;
|
|
274
|
+
case "image":
|
|
275
|
+
case "lineBreak": break;
|
|
276
|
+
default:
|
|
277
|
+
}
|
|
278
|
+
return runs;
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
export { paragraphToRuns };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
2
|
+
import { RunFormattingOverrideAttrs } from "../../prosemirror/schema/marks.js";
|
|
3
|
+
import { RunStyleResolver } from "../../prosemirror/runStyleFormatting.js";
|
|
4
|
+
import { RunFormatting } from "../../layout-engine/types.js";
|
|
5
|
+
import { Mark } from "prosemirror-model";
|
|
6
|
+
//#region src/layout-bridge/convert/runFormattingMerge.d.ts
|
|
7
|
+
declare function markDefaultBlackTextColorSource(formatting: RunFormatting, paraDefaults: RunFormatting): RunFormatting;
|
|
8
|
+
declare function mergeRunFormatting(paraDefaults: RunFormatting, formatting: RunFormatting): RunFormatting;
|
|
9
|
+
type ApplyCharacterStyleToggleFormattingOptions = {
|
|
10
|
+
formatting: RunFormatting;
|
|
11
|
+
marks: readonly Mark[];
|
|
12
|
+
paragraphFormatting: document_d_exports.TextFormatting | undefined;
|
|
13
|
+
styleResolver: RunStyleResolver;
|
|
14
|
+
};
|
|
15
|
+
/** Restore character-style toggle values that plain visual marks cannot represent. */
|
|
16
|
+
declare function applyCharacterStyleToggleFormatting({ formatting, marks, paragraphFormatting, styleResolver }: ApplyCharacterStyleToggleFormattingOptions): void;
|
|
17
|
+
declare function applyRunFormattingOverrides(formatting: RunFormatting, attrs: RunFormattingOverrideAttrs): void;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { applyCharacterStyleToggleFormatting, applyRunFormattingOverrides, markDefaultBlackTextColorSource, mergeRunFormatting };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { expectCharacterStyleMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
2
|
+
import { resolveEffectiveRunStyleFormatting } from "../../prosemirror/runStyleFormatting.js";
|
|
3
|
+
import { STYLE_TOGGLE_KEYS } from "../../utils/textFormattingMerge.js";
|
|
4
|
+
//#region src/layout-bridge/convert/runFormattingMerge.ts
|
|
5
|
+
const DEFAULT_BLACK_TEXT_COLOR_VALUES = /* @__PURE__ */ new Set(["000000", "000"]);
|
|
6
|
+
function normalizeResolvedTextColor(color) {
|
|
7
|
+
return color.trim().toLowerCase().replace(/^#/u, "");
|
|
8
|
+
}
|
|
9
|
+
function isDefaultBlackResolvedTextColor(color) {
|
|
10
|
+
return DEFAULT_BLACK_TEXT_COLOR_VALUES.has(normalizeResolvedTextColor(color));
|
|
11
|
+
}
|
|
12
|
+
function areResolvedTextColorsEqual(left, right) {
|
|
13
|
+
return normalizeResolvedTextColor(left) === normalizeResolvedTextColor(right);
|
|
14
|
+
}
|
|
15
|
+
function markDefaultBlackTextColorSource(formatting, paraDefaults) {
|
|
16
|
+
if (formatting.textColorSource === "direct" || formatting.color === void 0 || paraDefaults.color === void 0 || !isDefaultBlackResolvedTextColor(formatting.color) || !areResolvedTextColorsEqual(formatting.color, paraDefaults.color)) return formatting;
|
|
17
|
+
return {
|
|
18
|
+
...formatting,
|
|
19
|
+
textColorSource: "paragraphDefault"
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function mergeRunFormatting(paraDefaults, formatting) {
|
|
23
|
+
if (formatting.isDeletion && formatting.usesHistoricalFormatting) return formatting;
|
|
24
|
+
const merged = {
|
|
25
|
+
...paraDefaults,
|
|
26
|
+
...markDefaultBlackTextColorSource(formatting, paraDefaults)
|
|
27
|
+
};
|
|
28
|
+
if (formatting.fontFamily !== void 0 && formatting.alternateFontFamily === void 0) delete merged.alternateFontFamily;
|
|
29
|
+
if (formatting.eastAsiaFontFamily !== void 0 && formatting.eastAsiaAlternateFontFamily === void 0) delete merged.eastAsiaAlternateFontFamily;
|
|
30
|
+
if (formatting.complexScriptFontFamily !== void 0 && formatting.complexScriptAlternateFontFamily === void 0) delete merged.complexScriptAlternateFontFamily;
|
|
31
|
+
if (merged.letterSpacing === 0) delete merged.letterSpacing;
|
|
32
|
+
if (formatting.horizontalScale === 100 && paraDefaults.horizontalScale === void 0) delete merged.horizontalScale;
|
|
33
|
+
return merged;
|
|
34
|
+
}
|
|
35
|
+
const CHARACTER_STYLE_TOGGLE_LAYOUT_PROPERTIES = {
|
|
36
|
+
allCaps: "allCaps",
|
|
37
|
+
bold: "bold",
|
|
38
|
+
boldCs: "complexScriptBold",
|
|
39
|
+
emboss: "emboss",
|
|
40
|
+
hidden: "hidden",
|
|
41
|
+
imprint: "imprint",
|
|
42
|
+
italic: "italic",
|
|
43
|
+
italicCs: "complexScriptItalic",
|
|
44
|
+
outline: "textOutline",
|
|
45
|
+
shadow: "textShadow",
|
|
46
|
+
smallCaps: "smallCaps",
|
|
47
|
+
strike: "strike"
|
|
48
|
+
};
|
|
49
|
+
/** Restore character-style toggle values that plain visual marks cannot represent. */
|
|
50
|
+
function applyCharacterStyleToggleFormatting({ formatting, marks, paragraphFormatting, styleResolver }) {
|
|
51
|
+
const characterStyleMark = marks.find((mark) => mark.type.name === "characterStyle");
|
|
52
|
+
const styleRPr = characterStyleMark ? styleResolver.getRunStyleOwnProperties(expectCharacterStyleMarkAttrs(characterStyleMark).styleId) : styleResolver.getDefaultCharacterStyle()?.rPr;
|
|
53
|
+
if (!styleRPr) return;
|
|
54
|
+
const effectiveStyleFormatting = resolveEffectiveRunStyleFormatting({
|
|
55
|
+
marks,
|
|
56
|
+
paragraphFormatting,
|
|
57
|
+
styleResolver
|
|
58
|
+
});
|
|
59
|
+
for (const property of STYLE_TOGGLE_KEYS) {
|
|
60
|
+
if (styleRPr[property] === void 0) continue;
|
|
61
|
+
const layoutProperty = CHARACTER_STYLE_TOGGLE_LAYOUT_PROPERTIES[property];
|
|
62
|
+
if (formatting[layoutProperty] === void 0) Reflect.set(formatting, layoutProperty, effectiveStyleFormatting?.[property] ?? false);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const suppressInheritedRunFormatting = (formatting, property) => {
|
|
66
|
+
Reflect.set(formatting, property, void 0);
|
|
67
|
+
};
|
|
68
|
+
const RUN_FORMATTING_OVERRIDE_HANDLER_ENTRIES = Object.entries({
|
|
69
|
+
_authoredOff() {},
|
|
70
|
+
_authoredOn() {},
|
|
71
|
+
_authoredValues() {},
|
|
72
|
+
allCaps(formatting, value) {
|
|
73
|
+
if (typeof value === "boolean") formatting.allCaps = value;
|
|
74
|
+
},
|
|
75
|
+
bold(formatting, value) {
|
|
76
|
+
if (typeof value === "boolean") formatting.bold = value;
|
|
77
|
+
},
|
|
78
|
+
boldCs(formatting, value) {
|
|
79
|
+
if (typeof value === "boolean") formatting.complexScriptBold = value;
|
|
80
|
+
},
|
|
81
|
+
color(formatting, value) {
|
|
82
|
+
if (value === "auto") {
|
|
83
|
+
suppressInheritedRunFormatting(formatting, "color");
|
|
84
|
+
suppressInheritedRunFormatting(formatting, "textColorSource");
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
complexScriptPropertyAbsences() {},
|
|
88
|
+
cs(formatting, value) {
|
|
89
|
+
if (typeof value === "boolean") formatting.forceComplexScript = value;
|
|
90
|
+
},
|
|
91
|
+
directFontProperties() {},
|
|
92
|
+
doubleStrike(formatting, value) {
|
|
93
|
+
if (value === false && formatting.strike === void 0) formatting.strike = false;
|
|
94
|
+
},
|
|
95
|
+
effect(formatting, value) {
|
|
96
|
+
if (value === "none") suppressInheritedRunFormatting(formatting, "textEffect");
|
|
97
|
+
},
|
|
98
|
+
emboss(formatting, value) {
|
|
99
|
+
if (typeof value === "boolean") formatting.emboss = value;
|
|
100
|
+
},
|
|
101
|
+
emphasisMark(formatting, value) {
|
|
102
|
+
if (value === "none") suppressInheritedRunFormatting(formatting, "emphasisMark");
|
|
103
|
+
},
|
|
104
|
+
fontSizeCs(formatting, value) {
|
|
105
|
+
if (typeof value === "number") formatting.complexScriptFontSize = value / 2;
|
|
106
|
+
},
|
|
107
|
+
noProof() {},
|
|
108
|
+
hidden(formatting, value) {
|
|
109
|
+
if (typeof value === "boolean") formatting.hidden = value;
|
|
110
|
+
},
|
|
111
|
+
highlight(formatting, value) {
|
|
112
|
+
if (value === "none") suppressInheritedRunFormatting(formatting, "highlight");
|
|
113
|
+
},
|
|
114
|
+
imprint(formatting, value) {
|
|
115
|
+
if (typeof value === "boolean") formatting.imprint = value;
|
|
116
|
+
},
|
|
117
|
+
italic(formatting, value) {
|
|
118
|
+
if (typeof value === "boolean") formatting.italic = value;
|
|
119
|
+
},
|
|
120
|
+
italicCs(formatting, value) {
|
|
121
|
+
if (typeof value === "boolean") formatting.complexScriptItalic = value;
|
|
122
|
+
},
|
|
123
|
+
kerning(formatting, value) {
|
|
124
|
+
if (value === 0) formatting.kerningMinPt = 0;
|
|
125
|
+
},
|
|
126
|
+
outline(formatting, value) {
|
|
127
|
+
if (typeof value === "boolean") formatting.textOutline = value;
|
|
128
|
+
},
|
|
129
|
+
position(formatting, value) {
|
|
130
|
+
if (value === 0) formatting.positionPx = 0;
|
|
131
|
+
},
|
|
132
|
+
rtl(formatting, value) {
|
|
133
|
+
if (value === false) formatting.rtl = false;
|
|
134
|
+
},
|
|
135
|
+
scale(formatting, value) {
|
|
136
|
+
if (value === 100) formatting.horizontalScale = 100;
|
|
137
|
+
},
|
|
138
|
+
shading(formatting, value) {
|
|
139
|
+
if (typeof value === "object" && value !== null && Reflect.get(value, "pattern") === "nil") suppressInheritedRunFormatting(formatting, "shading");
|
|
140
|
+
},
|
|
141
|
+
shadow(formatting, value) {
|
|
142
|
+
if (typeof value === "boolean") formatting.textShadow = value;
|
|
143
|
+
},
|
|
144
|
+
smallCaps(formatting, value) {
|
|
145
|
+
if (typeof value === "boolean") formatting.smallCaps = value;
|
|
146
|
+
},
|
|
147
|
+
spacing(formatting, value) {
|
|
148
|
+
if (value === 0) formatting.letterSpacing = 0;
|
|
149
|
+
},
|
|
150
|
+
strike(formatting, value) {
|
|
151
|
+
if (typeof value === "boolean") formatting.strike = value;
|
|
152
|
+
},
|
|
153
|
+
underline(formatting, value) {
|
|
154
|
+
if (value === "none") formatting.underline = false;
|
|
155
|
+
},
|
|
156
|
+
vertAlign(formatting, value) {
|
|
157
|
+
if (value === "baseline") {
|
|
158
|
+
formatting.superscript = false;
|
|
159
|
+
formatting.subscript = false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
function applyRunFormattingOverrides(formatting, attrs) {
|
|
164
|
+
for (const [key, handler] of RUN_FORMATTING_OVERRIDE_HANDLER_ENTRIES) handler(formatting, Reflect.get(attrs, key));
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
export { applyCharacterStyleToggleFormatting, applyRunFormattingOverrides, markDefaultBlackTextColorSource, mergeRunFormatting };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
2
|
+
import { RunFormatting } from "../../layout-engine/types.js";
|
|
3
|
+
import { FontAlternates } from "../../fonts/fontAlternates.js";
|
|
4
|
+
import { Mark } from "prosemirror-model";
|
|
5
|
+
//#region src/layout-bridge/convert/runMarkFormatting.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Extract run formatting from ProseMirror marks.
|
|
8
|
+
*/
|
|
9
|
+
declare function extractRunFormatting(marks: readonly Mark[], theme?: document_d_exports.Theme | null, fontAlternates?: FontAlternates): RunFormatting;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { extractRunFormatting };
|