@stll/folio-core 0.49.0 → 0.50.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/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/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/paged-layout/sectionBlockWidths.d.ts +2 -1
- package/dist/paged-layout/sectionBlockWidths.js +1 -1
- package/dist/server.d.ts +3 -2
- package/package.json +2 -2
|
@@ -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 };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { getFontAlternate } from "../../fonts/fontAlternates.js";
|
|
2
|
+
import { setHyperlinkInstanceIndex } from "../../layout-engine/measure/hyperlinkInstance.js";
|
|
3
|
+
import { expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
4
|
+
import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
|
|
5
|
+
import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
|
|
6
|
+
import { resolveShadingFill } from "../../utils/formatToStyle.js";
|
|
7
|
+
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
8
|
+
import { halfPointsToPixels, halfPointsToPoints } from "../../utils/units.js";
|
|
9
|
+
import { twipsToPixels } from "./flowConversionShared.js";
|
|
10
|
+
import { applyRunFormattingOverrides } from "./runFormattingMerge.js";
|
|
11
|
+
import { isAutomaticTextColorValue, resolveComplexScriptThemeFont, resolveEastAsiaThemeFont, resolveWesternThemeFont } from "./textFormattingConversion.js";
|
|
12
|
+
import { panic } from "better-result";
|
|
13
|
+
//#region src/layout-bridge/convert/runMarkFormatting.ts
|
|
14
|
+
/**
|
|
15
|
+
* What the painter does with each mark the schema declares.
|
|
16
|
+
*
|
|
17
|
+
* The switch below used to end in `default: break`, so a mark that reached it
|
|
18
|
+
* was silently not painted whether that was the decision or an omission. The
|
|
19
|
+
* table is total over {@link SchemaMarkName}: a mark added to the schema
|
|
20
|
+
* without a paint decision does not compile, and a mark this table says is
|
|
21
|
+
* painted but the switch does not handle panics rather than disappearing.
|
|
22
|
+
*/
|
|
23
|
+
const MARK_PAINT_DISPOSITIONS = {
|
|
24
|
+
bold: "runFormatting",
|
|
25
|
+
italic: "runFormatting",
|
|
26
|
+
underline: "runFormatting",
|
|
27
|
+
strike: "runFormatting",
|
|
28
|
+
textColor: "runFormatting",
|
|
29
|
+
runShading: "runFormatting",
|
|
30
|
+
highlight: "runFormatting",
|
|
31
|
+
fontSize: "runFormatting",
|
|
32
|
+
fontFamily: "runFormatting",
|
|
33
|
+
language: "runFormatting",
|
|
34
|
+
superscript: "runFormatting",
|
|
35
|
+
subscript: "runFormatting",
|
|
36
|
+
hyperlink: "runFormatting",
|
|
37
|
+
allCaps: "runFormatting",
|
|
38
|
+
smallCaps: "runFormatting",
|
|
39
|
+
footnoteRef: "runFormatting",
|
|
40
|
+
characterSpacing: "runFormatting",
|
|
41
|
+
emboss: "runFormatting",
|
|
42
|
+
imprint: "runFormatting",
|
|
43
|
+
hidden: "runFormatting",
|
|
44
|
+
textShadow: "runFormatting",
|
|
45
|
+
emphasisMark: "runFormatting",
|
|
46
|
+
textOutline: "runFormatting",
|
|
47
|
+
rtl: "runFormatting",
|
|
48
|
+
textEffect: "runFormatting",
|
|
49
|
+
runFormattingOverride: "runFormatting",
|
|
50
|
+
comment: "runFormatting",
|
|
51
|
+
insertion: "runFormatting",
|
|
52
|
+
deletion: "runFormatting",
|
|
53
|
+
inlineWrapper: "runFormatting",
|
|
54
|
+
characterStyle: "resolvedElsewhere",
|
|
55
|
+
runIdentity: "notPainted",
|
|
56
|
+
runPropertyChange: "notPainted"
|
|
57
|
+
};
|
|
58
|
+
const markPaintDisposition = (name) => {
|
|
59
|
+
return MARK_PAINT_DISPOSITIONS[name];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Whether a layer states how its content is laid out.
|
|
63
|
+
*
|
|
64
|
+
* A smart tag and a custom-XML wrapper name an element in another vocabulary
|
|
65
|
+
* and say nothing about layout, so the painter draws the text exactly as it
|
|
66
|
+
* would without them. The `switch` is here rather than inline so a kind added
|
|
67
|
+
* to the model has to answer the question.
|
|
68
|
+
*/
|
|
69
|
+
const paintedDirection = (layer) => {
|
|
70
|
+
switch (layer.kind) {
|
|
71
|
+
case "bidi": return layer.direction === void 0 ? { control: layer.control } : {
|
|
72
|
+
control: layer.control,
|
|
73
|
+
direction: layer.direction
|
|
74
|
+
};
|
|
75
|
+
case "smartTag":
|
|
76
|
+
case "customXml": return;
|
|
77
|
+
default: return;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* The direction the innermost bidirectional layer of a stack lays its content out in.
|
|
82
|
+
*
|
|
83
|
+
* Innermost wins: a bidirectional wrapper inside another is the one the text is
|
|
84
|
+
* laid out in, and the outer layers are what the save leg rebuilds the nesting
|
|
85
|
+
* from. The layers that state no direction are skipped rather than ending the
|
|
86
|
+
* search, so a smart tag inside a `w:dir` still reads right to left.
|
|
87
|
+
*/
|
|
88
|
+
const innermostBidiWrapper = (stack) => {
|
|
89
|
+
for (const layer of stack.toReversed()) {
|
|
90
|
+
const direction = paintedDirection(layer);
|
|
91
|
+
if (direction !== void 0) return direction;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Extract run formatting from ProseMirror marks.
|
|
96
|
+
*/
|
|
97
|
+
function extractRunFormatting(marks, theme, fontAlternates) {
|
|
98
|
+
const formatting = {};
|
|
99
|
+
let hasNoteRef = false;
|
|
100
|
+
let runFormattingOverride;
|
|
101
|
+
for (const mark of marks) switch (mark.type.name) {
|
|
102
|
+
case "bold":
|
|
103
|
+
formatting.bold = true;
|
|
104
|
+
break;
|
|
105
|
+
case "italic":
|
|
106
|
+
formatting.italic = true;
|
|
107
|
+
break;
|
|
108
|
+
case "underline": {
|
|
109
|
+
const attrs = expectUnderlineMarkAttrs(mark);
|
|
110
|
+
if (attrs.style || attrs.color) {
|
|
111
|
+
const underlineObj = {};
|
|
112
|
+
if (attrs.style) underlineObj.style = attrs.style;
|
|
113
|
+
if (attrs.color) underlineObj.color = resolveColor(attrs.color, theme);
|
|
114
|
+
formatting.underline = underlineObj;
|
|
115
|
+
} else formatting.underline = true;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "strike":
|
|
119
|
+
formatting.strike = true;
|
|
120
|
+
break;
|
|
121
|
+
case "textColor": {
|
|
122
|
+
const attrs = expectTextColorMarkAttrs(mark);
|
|
123
|
+
if (attrs.themeColor || attrs.rgb) {
|
|
124
|
+
const colorArg = {};
|
|
125
|
+
if (attrs.rgb) colorArg.rgb = attrs.rgb;
|
|
126
|
+
if (attrs.themeColor) colorArg.themeColor = attrs.themeColor;
|
|
127
|
+
if (attrs.themeTint) colorArg.themeTint = attrs.themeTint;
|
|
128
|
+
if (attrs.themeShade) colorArg.themeShade = attrs.themeShade;
|
|
129
|
+
if (!isAutomaticTextColorValue(colorArg)) {
|
|
130
|
+
formatting.color = resolveColor(colorArg, theme);
|
|
131
|
+
formatting.textColorSource = "direct";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case "highlight":
|
|
137
|
+
formatting.highlight = resolveHighlightToCss(expectHighlightMarkAttrs(mark).color);
|
|
138
|
+
break;
|
|
139
|
+
case "runShading": {
|
|
140
|
+
const shadingCss = resolveShadingFill(runShadingAttrsToShading(expectRunShadingMarkAttrs(mark)), theme);
|
|
141
|
+
if (shadingCss) formatting.shading = shadingCss;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "fontSize":
|
|
145
|
+
formatting.fontSize = expectFontSizeMarkAttrs(mark).size / 2;
|
|
146
|
+
break;
|
|
147
|
+
case "fontFamily": {
|
|
148
|
+
const attrs = expectFontFamilyMarkAttrs(mark);
|
|
149
|
+
const font = resolveWesternThemeFont(attrs, theme);
|
|
150
|
+
if (font) {
|
|
151
|
+
formatting.fontFamily = font;
|
|
152
|
+
const alternate = getFontAlternate(font, fontAlternates);
|
|
153
|
+
if (alternate) formatting.alternateFontFamily = alternate;
|
|
154
|
+
}
|
|
155
|
+
const eastAsiaFont = resolveEastAsiaThemeFont(attrs, theme);
|
|
156
|
+
if (eastAsiaFont) {
|
|
157
|
+
formatting.eastAsiaFontFamily = eastAsiaFont;
|
|
158
|
+
const alternate = getFontAlternate(eastAsiaFont, fontAlternates);
|
|
159
|
+
if (alternate) formatting.eastAsiaAlternateFontFamily = alternate;
|
|
160
|
+
}
|
|
161
|
+
if (attrs.hint) formatting.eastAsiaHint = attrs.hint === "eastAsia";
|
|
162
|
+
const complexScriptFont = resolveComplexScriptThemeFont(attrs, theme);
|
|
163
|
+
if (complexScriptFont) {
|
|
164
|
+
formatting.complexScriptFontFamily = complexScriptFont;
|
|
165
|
+
const alternate = getFontAlternate(complexScriptFont, fontAlternates);
|
|
166
|
+
if (alternate) formatting.complexScriptAlternateFontFamily = alternate;
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case "language": {
|
|
171
|
+
const attrs = expectLanguageMarkAttrs(mark);
|
|
172
|
+
formatting.language = {
|
|
173
|
+
...attrs.val ? { val: attrs.val } : {},
|
|
174
|
+
...attrs.eastAsia ? { eastAsia: attrs.eastAsia } : {},
|
|
175
|
+
...attrs.bidi ? { bidi: attrs.bidi } : {}
|
|
176
|
+
};
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case "characterSpacing": {
|
|
180
|
+
const attrs = expectCharacterSpacingMarkAttrs(mark);
|
|
181
|
+
if (attrs.spacing !== void 0) formatting.letterSpacing = twipsToPixels(attrs.spacing);
|
|
182
|
+
if (attrs.position !== void 0 && attrs.position !== 0) formatting.positionPx = halfPointsToPixels(attrs.position);
|
|
183
|
+
const horizontalScale = normalizeHorizontalScalePercent(attrs.scale);
|
|
184
|
+
if (horizontalScale !== void 0) formatting.horizontalScale = horizontalScale;
|
|
185
|
+
if (attrs.kerning !== void 0 && attrs.kerning > 0) formatting.kerningMinPt = halfPointsToPoints(attrs.kerning);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "allCaps":
|
|
189
|
+
formatting.allCaps = true;
|
|
190
|
+
break;
|
|
191
|
+
case "smallCaps":
|
|
192
|
+
formatting.smallCaps = true;
|
|
193
|
+
break;
|
|
194
|
+
case "emboss":
|
|
195
|
+
formatting.emboss = true;
|
|
196
|
+
break;
|
|
197
|
+
case "imprint":
|
|
198
|
+
formatting.imprint = true;
|
|
199
|
+
break;
|
|
200
|
+
case "hidden":
|
|
201
|
+
formatting.hidden = true;
|
|
202
|
+
break;
|
|
203
|
+
case "textShadow":
|
|
204
|
+
formatting.textShadow = true;
|
|
205
|
+
break;
|
|
206
|
+
case "textOutline":
|
|
207
|
+
formatting.textOutline = true;
|
|
208
|
+
break;
|
|
209
|
+
case "rtl":
|
|
210
|
+
formatting.rtl = true;
|
|
211
|
+
break;
|
|
212
|
+
case "textEffect":
|
|
213
|
+
formatting.textEffect = expectTextEffectMarkAttrs(mark).effect;
|
|
214
|
+
break;
|
|
215
|
+
case "runFormattingOverride":
|
|
216
|
+
runFormattingOverride = expectRunFormattingOverrideMarkAttrs(mark);
|
|
217
|
+
break;
|
|
218
|
+
case "emphasisMark":
|
|
219
|
+
formatting.emphasisMark = expectEmphasisMarkAttrs(mark).type ?? "dot";
|
|
220
|
+
break;
|
|
221
|
+
case "superscript":
|
|
222
|
+
formatting.superscript = true;
|
|
223
|
+
break;
|
|
224
|
+
case "subscript":
|
|
225
|
+
formatting.subscript = true;
|
|
226
|
+
break;
|
|
227
|
+
case "hyperlink": {
|
|
228
|
+
const attrs = expectHyperlinkMarkAttrs(mark);
|
|
229
|
+
const link = { href: attrs.href };
|
|
230
|
+
if (attrs.tooltip !== void 0) link.tooltip = attrs.tooltip;
|
|
231
|
+
if (attrs._docxHyperlinkIndex !== void 0) setHyperlinkInstanceIndex(link, attrs._docxHyperlinkIndex);
|
|
232
|
+
formatting.hyperlink = link;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case "footnoteRef": {
|
|
236
|
+
hasNoteRef = true;
|
|
237
|
+
const attrs = expectFootnoteRefMarkAttrs(mark);
|
|
238
|
+
if (attrs.vertAlign === "superscript") formatting.superscript = true;
|
|
239
|
+
const id = typeof attrs.id === "string" ? Number.parseInt(attrs.id, 10) : attrs.id;
|
|
240
|
+
if (attrs.noteType === "endnote") formatting.endnoteRefId = id;
|
|
241
|
+
else formatting.footnoteRefId = id;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
case "comment": {
|
|
245
|
+
const commentId = expectCommentMarkAttrs(mark).commentId;
|
|
246
|
+
if (commentId) {
|
|
247
|
+
if (!formatting.commentIds) formatting.commentIds = [];
|
|
248
|
+
formatting.commentIds.push(commentId);
|
|
249
|
+
}
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "insertion": {
|
|
253
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
254
|
+
formatting.isInsertion = true;
|
|
255
|
+
formatting.changeAuthor = attrs.author;
|
|
256
|
+
if (attrs.date !== void 0) formatting.changeDate = attrs.date;
|
|
257
|
+
formatting.changeRevisionId = attrs.revisionId;
|
|
258
|
+
if (attrs.provenance === "suggested") {
|
|
259
|
+
formatting.isSuggestion = true;
|
|
260
|
+
if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
|
|
261
|
+
}
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case "deletion": {
|
|
265
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
266
|
+
formatting.isDeletion = true;
|
|
267
|
+
if (attrs._historicalFormatting) formatting.usesHistoricalFormatting = true;
|
|
268
|
+
formatting.changeAuthor = attrs.author;
|
|
269
|
+
if (attrs.date !== void 0) formatting.changeDate = attrs.date;
|
|
270
|
+
formatting.changeRevisionId = attrs.revisionId;
|
|
271
|
+
if (attrs.provenance === "suggested") {
|
|
272
|
+
formatting.isSuggestion = true;
|
|
273
|
+
if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
case "inlineWrapper": {
|
|
278
|
+
const bidiWrapper = innermostBidiWrapper(expectInlineWrapperMarkAttrs(mark).stack);
|
|
279
|
+
if (bidiWrapper) formatting.bidiWrapper = bidiWrapper;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
default:
|
|
283
|
+
if (markPaintDisposition(mark.type.name) === "runFormatting") panic(`Mark ${mark.type.name} is painted as run formatting but has no branch here`);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
if (runFormattingOverride) applyRunFormattingOverrides(formatting, runFormattingOverride);
|
|
287
|
+
if (hasNoteRef && formatting.subscript) delete formatting.superscript;
|
|
288
|
+
return formatting;
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
export { extractRunFormatting };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FlowBlock, SectionBreakBlock } from "../../layout-engine/types.js";
|
|
2
|
+
import { Node } from "prosemirror-model";
|
|
3
|
+
//#region src/layout-bridge/convert/sectionBoundaries.d.ts
|
|
4
|
+
declare function getLastMapKey<K, V>(map: ReadonlyMap<K, V>): K | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Translate section-owned start modes into the boundary-owned values consumed
|
|
7
|
+
* by the paginator. Each flow section break carries the properties for the
|
|
8
|
+
* section it ends, so its start mode belongs on the preceding boundary.
|
|
9
|
+
*/
|
|
10
|
+
declare function applySectionStartsToBoundaries(blocks: readonly FlowBlock[], finalSectionStart: NonNullable<SectionBreakBlock["type"]> | undefined): FlowBlock[];
|
|
11
|
+
/**
|
|
12
|
+
* A trailing page break belongs to its section-ending paragraph. When the
|
|
13
|
+
* paragraph mark stays on the current page, an immediately following
|
|
14
|
+
* continuous section resumes there too. Accept both the legacy generated
|
|
15
|
+
* carrier and the inline atom's one-token paragraph-mark fragment; neither is
|
|
16
|
+
* a physical layout boundary.
|
|
17
|
+
*
|
|
18
|
+
* A section break in `breaksWithoutMarker` ends at an empty w:sectPr paragraph
|
|
19
|
+
* that projected no block, so a page break just before it ends an earlier
|
|
20
|
+
* paragraph and still starts the next page.
|
|
21
|
+
*/
|
|
22
|
+
declare function coalesceTrailingPageBreakBeforeContinuousSection(blocks: readonly FlowBlock[], splitPageBreakAndParagraphMark: boolean, breaksWithoutMarker: ReadonlySet<SectionBreakBlock["id"]>): FlowBlock[];
|
|
23
|
+
/**
|
|
24
|
+
* The last section's start mode, off a document attribute the schema types as
|
|
25
|
+
* `any`. `parseSectionBreakType` owns the enumeration, so a member added to
|
|
26
|
+
* `ST_SectionMark` reaches the paginator instead of being dropped here.
|
|
27
|
+
*/
|
|
28
|
+
declare function readFinalSectionStart(doc: Node): NonNullable<SectionBreakBlock["type"]> | undefined;
|
|
29
|
+
type SectionDocumentGridOptions = {
|
|
30
|
+
finalLinePitchTwips: number | undefined;
|
|
31
|
+
tableCellLinePitch: "sectionGrid" | undefined;
|
|
32
|
+
};
|
|
33
|
+
declare function applySectionDocumentGrid(blocks: FlowBlock[], { finalLinePitchTwips, tableCellLinePitch }: SectionDocumentGridOptions): FlowBlock[];
|
|
34
|
+
//#endregion
|
|
35
|
+
export { applySectionDocumentGrid, applySectionStartsToBoundaries, coalesceTrailingPageBreakBeforeContinuousSection, getLastMapKey, readFinalSectionStart };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { parseSectionBreakType } from "../../prosemirror/sectionCarrier.js";
|
|
2
|
+
import { twipsToPixels } from "./flowConversionShared.js";
|
|
3
|
+
//#region src/layout-bridge/convert/sectionBoundaries.ts
|
|
4
|
+
function getLastMapKey(map) {
|
|
5
|
+
let lastKey;
|
|
6
|
+
for (const key of map.keys()) lastKey = key;
|
|
7
|
+
return lastKey;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Translate section-owned start modes into the boundary-owned values consumed
|
|
11
|
+
* by the paginator. Each flow section break carries the properties for the
|
|
12
|
+
* section it ends, so its start mode belongs on the preceding boundary.
|
|
13
|
+
*/
|
|
14
|
+
function applySectionStartsToBoundaries(blocks, finalSectionStart) {
|
|
15
|
+
const breakIndexes = [];
|
|
16
|
+
for (let index = 0; index < blocks.length; index += 1) if (blocks[index]?.kind === "sectionBreak") breakIndexes.push(index);
|
|
17
|
+
if (breakIndexes.length === 0) return [...blocks];
|
|
18
|
+
const result = [...blocks];
|
|
19
|
+
for (let index = 0; index < breakIndexes.length; index += 1) {
|
|
20
|
+
const boundaryIndex = breakIndexes[index];
|
|
21
|
+
if (boundaryIndex === void 0) continue;
|
|
22
|
+
const boundary = blocks[boundaryIndex];
|
|
23
|
+
if (boundary?.kind !== "sectionBreak") continue;
|
|
24
|
+
const nextBoundaryIndex = breakIndexes[index + 1];
|
|
25
|
+
const nextBoundary = nextBoundaryIndex === void 0 ? void 0 : blocks[nextBoundaryIndex];
|
|
26
|
+
const nextStart = nextBoundary?.kind === "sectionBreak" ? nextBoundary.type : finalSectionStart;
|
|
27
|
+
const translated = { ...boundary };
|
|
28
|
+
if (nextStart === void 0) delete translated.type;
|
|
29
|
+
else translated.type = nextStart;
|
|
30
|
+
result[boundaryIndex] = translated;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A trailing page break belongs to its section-ending paragraph. When the
|
|
36
|
+
* paragraph mark stays on the current page, an immediately following
|
|
37
|
+
* continuous section resumes there too. Accept both the legacy generated
|
|
38
|
+
* carrier and the inline atom's one-token paragraph-mark fragment; neither is
|
|
39
|
+
* a physical layout boundary.
|
|
40
|
+
*
|
|
41
|
+
* A section break in `breaksWithoutMarker` ends at an empty w:sectPr paragraph
|
|
42
|
+
* that projected no block, so a page break just before it ends an earlier
|
|
43
|
+
* paragraph and still starts the next page.
|
|
44
|
+
*/
|
|
45
|
+
function coalesceTrailingPageBreakBeforeContinuousSection(blocks, splitPageBreakAndParagraphMark, breaksWithoutMarker) {
|
|
46
|
+
if (splitPageBreakAndParagraphMark) return [...blocks];
|
|
47
|
+
const result = [];
|
|
48
|
+
for (let index = 0; index < blocks.length; index += 1) {
|
|
49
|
+
const block = blocks[index];
|
|
50
|
+
const carrier = blocks[index + 1];
|
|
51
|
+
const section = blocks[index + 2];
|
|
52
|
+
const isLegacyGeneratedCarrier = block?.kind === "pageBreak" && carrier?.kind === "paragraph" && carrier.runs.length === 0 && block.pmStart !== void 0 && block.pmStart === carrier.pmStart && carrier.pmStart === carrier.pmEnd;
|
|
53
|
+
const isInlineParagraphMarkCarrier = block?.kind === "pageBreak" && carrier?.kind === "paragraph" && carrier.runs.length === 0 && block.pmEnd !== void 0 && carrier.pmStart === block.pmEnd && carrier.pmEnd === block.pmEnd + 1;
|
|
54
|
+
const isUnresolvedInsertion = block?.kind === "pageBreak" && block.isInsertion === true;
|
|
55
|
+
if (block?.kind === "pageBreak" && !isUnresolvedInsertion && carrier?.kind === "sectionBreak" && carrier.type === "continuous" && !breaksWithoutMarker.has(carrier.id)) continue;
|
|
56
|
+
if (block?.kind === "pageBreak" && !isUnresolvedInsertion && (isLegacyGeneratedCarrier || isInlineParagraphMarkCarrier) && section?.kind === "sectionBreak" && section.type === "continuous" && !breaksWithoutMarker.has(section.id)) {
|
|
57
|
+
index += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (block) result.push(block);
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The last section's start mode, off a document attribute the schema types as
|
|
66
|
+
* `any`. `parseSectionBreakType` owns the enumeration, so a member added to
|
|
67
|
+
* `ST_SectionMark` reaches the paginator instead of being dropped here.
|
|
68
|
+
*/
|
|
69
|
+
function readFinalSectionStart(doc) {
|
|
70
|
+
return parseSectionBreakType(doc.attrs["_finalSectionStart"]) ?? void 0;
|
|
71
|
+
}
|
|
72
|
+
function applySectionDocumentGrid(blocks, { finalLinePitchTwips, tableCellLinePitch }) {
|
|
73
|
+
const result = [...blocks];
|
|
74
|
+
let sectionStart = 0;
|
|
75
|
+
const stampSection = (end, linePitchTwips) => {
|
|
76
|
+
if (linePitchTwips === void 0 || linePitchTwips <= 0) return;
|
|
77
|
+
const linePitch = twipsToPixels(linePitchTwips);
|
|
78
|
+
const stampBlock = (block) => {
|
|
79
|
+
if (block.kind === "paragraph") return {
|
|
80
|
+
...block,
|
|
81
|
+
attrs: {
|
|
82
|
+
...block.attrs,
|
|
83
|
+
documentGridLinePitch: linePitch
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (block.kind !== "table" || tableCellLinePitch !== "sectionGrid") return block;
|
|
87
|
+
return {
|
|
88
|
+
...block,
|
|
89
|
+
rows: block.rows.map((row) => ({
|
|
90
|
+
...row,
|
|
91
|
+
cells: row.cells.map((cell) => ({
|
|
92
|
+
...cell,
|
|
93
|
+
blocks: cell.blocks.map(stampBlock)
|
|
94
|
+
}))
|
|
95
|
+
}))
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
for (let index = sectionStart; index < end; index += 1) {
|
|
99
|
+
const block = result[index];
|
|
100
|
+
if (!block) continue;
|
|
101
|
+
result[index] = stampBlock(block);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
for (let index = 0; index < blocks.length; index += 1) {
|
|
105
|
+
const block = blocks[index];
|
|
106
|
+
if (block?.kind !== "sectionBreak") continue;
|
|
107
|
+
stampSection(index, block.documentGridLinePitchTwips);
|
|
108
|
+
sectionStart = index + 1;
|
|
109
|
+
}
|
|
110
|
+
stampSection(blocks.length, finalLinePitchTwips);
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { applySectionDocumentGrid, applySectionStartsToBoundaries, coalesceTrailingPageBreakBeforeContinuousSection, getLastMapKey, readFinalSectionStart };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TableBlock, TextBoxBlock } from "../../layout-engine/types.js";
|
|
2
|
+
import { FlowConversionOptions } from "./flowConversionShared.js";
|
|
3
|
+
import { Node } from "prosemirror-model";
|
|
4
|
+
//#region src/layout-bridge/convert/tableConversion.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Convert a table node to a TableBlock.
|
|
7
|
+
*/
|
|
8
|
+
declare function convertTable(node: Node, startPos: number, options: FlowConversionOptions): TableBlock;
|
|
9
|
+
/** Convert a textBox PM node to a TextBoxBlock. */
|
|
10
|
+
declare function convertTextBoxNode(node: Node, startPos: number, opts: FlowConversionOptions): TextBoxBlock;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { convertTable, convertTextBoxNode };
|