@stll/folio-core 0.23.1 → 0.25.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/controller/fontReadiness.js +12 -7
- package/dist/controller/layoutPipeline.js +3 -4
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +2 -9
- package/dist/docx/numberingParser.d.ts +2 -1
- package/dist/docx/numberingParser.js +24 -80
- package/dist/docx/paragraphParser.js +3 -4
- package/dist/docx/paragraphTextBoxEnrichment.js +1 -0
- package/dist/docx/sectionParser.js +2 -2
- package/dist/docx/serializer/runSerializer.js +1 -0
- package/dist/docx/textBoxParser.js +4 -0
- package/dist/fields/fieldContext.d.ts +2 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +9 -1
- package/dist/layout-bridge/convert/headerFooterLayout.js +27 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +12 -16
- package/dist/layout-bridge/engine/selectionRects.js +3 -5
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +3 -5
- package/dist/layout-engine/measure/cache.js +4 -0
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +3 -1
- package/dist/layout-engine/measure/listMarkerWidth.js +25 -21
- package/dist/layout-engine/measure/measureBlocks.js +27 -11
- package/dist/layout-engine/measure/measureParagraph.js +7 -1
- package/dist/layout-engine/measure/tableCellFloating.js +2 -3
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/tableRowBreak.js +2 -2
- package/dist/layout-engine/types.d.ts +16 -11
- package/dist/layout-engine/types.js +15 -1
- package/dist/layout-painter/renderParagraph.d.ts +9 -1
- package/dist/layout-painter/renderParagraph.js +65 -52
- package/dist/layout-painter/renderTable.js +2 -5
- package/dist/layout-painter/renderTextBox.js +1 -1
- package/dist/layout-painter/renderUtils.d.ts +2 -1
- package/dist/prosemirror/attrs/index.js +4 -6
- package/dist/prosemirror/conversion/fromProseDoc.js +2 -3
- package/dist/prosemirror/conversion/toProseDoc.js +3 -3
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -3
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -3
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
- package/dist/prosemirror/schema/nodes.d.ts +5 -7
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -3
- package/dist/utils/paragraphBaseDirection.d.ts +6 -0
- package/dist/utils/paragraphBaseDirection.js +12 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expectFontFamilyMarkAttrs } from "../prosemirror/attrs/index.js";
|
|
1
|
+
import { expectFontFamilyMarkAttrs, expectParagraphAttrs } from "../prosemirror/attrs/index.js";
|
|
2
2
|
import { parseFontFamilyList, resolveFontFamily } from "../utils/fontResolver.js";
|
|
3
3
|
//#region src/controller/fontReadiness.ts
|
|
4
4
|
function getDocumentFontSet() {
|
|
@@ -62,13 +62,15 @@ function collectInitialLayoutFontFaces(documentModel, pmDoc) {
|
|
|
62
62
|
return Array.from(faces.values());
|
|
63
63
|
}
|
|
64
64
|
function addTextFormattingFontFaces(faces, formatting) {
|
|
65
|
-
|
|
65
|
+
const standardDescriptor = layoutDescriptorFromFormatting(formatting);
|
|
66
|
+
const complexScriptDescriptor = layoutDescriptorFromEmphasis(formatting?.boldCs ?? formatting?.bold, formatting?.italicCs ?? formatting?.italic);
|
|
67
|
+
addLayoutFontFamilyFace(faces, formatting?.fontFamily, standardDescriptor, complexScriptDescriptor);
|
|
66
68
|
}
|
|
67
69
|
function collectProseMirrorFontFaces(faces, node, inheritedTextFormatting) {
|
|
68
70
|
const paragraphDefaults = readParagraphDefaultTextFormatting(node);
|
|
69
71
|
const textFormatting = paragraphDefaults ?? inheritedTextFormatting;
|
|
70
72
|
if (paragraphDefaults) addTextFormattingFontFaces(faces, paragraphDefaults);
|
|
71
|
-
if (node.
|
|
73
|
+
if (node.type.name === "paragraph") addTextFormattingFontFaces(faces, expectParagraphAttrs(node).listMarkerFormatting);
|
|
72
74
|
if (node.isText) {
|
|
73
75
|
const descriptor = layoutDescriptorFromFormattingAndMarks(textFormatting, node.marks);
|
|
74
76
|
addLayoutFontFamilyFace(faces, readFontFamilyMarkAttrs(node.marks) ?? textFormatting?.fontFamily ?? DEFAULT_LAYOUT_FONT_FAMILY, descriptor);
|
|
@@ -86,9 +88,12 @@ function readFontFamilyMarkAttrs(marks) {
|
|
|
86
88
|
for (const mark of marks) if (mark.type.name === "fontFamily") return expectFontFamilyMarkAttrs(mark);
|
|
87
89
|
}
|
|
88
90
|
function layoutDescriptorFromFormatting(formatting) {
|
|
91
|
+
return layoutDescriptorFromEmphasis(formatting?.bold, formatting?.italic);
|
|
92
|
+
}
|
|
93
|
+
function layoutDescriptorFromEmphasis(bold, italic) {
|
|
89
94
|
return {
|
|
90
|
-
style:
|
|
91
|
-
weight:
|
|
95
|
+
style: italic ? "italic" : "normal",
|
|
96
|
+
weight: bold ? 700 : 400
|
|
92
97
|
};
|
|
93
98
|
}
|
|
94
99
|
function layoutDescriptorFromFormattingAndMarks(formatting, marks) {
|
|
@@ -103,7 +108,7 @@ function layoutDescriptorFromFormattingAndMarks(formatting, marks) {
|
|
|
103
108
|
weight: bold ? 700 : 400
|
|
104
109
|
};
|
|
105
110
|
}
|
|
106
|
-
function addLayoutFontFamilyFace(faces, value, descriptor) {
|
|
111
|
+
function addLayoutFontFamilyFace(faces, value, descriptor, complexScriptDescriptor = descriptor) {
|
|
107
112
|
if (typeof value === "string") {
|
|
108
113
|
addLayoutFontFamilyNameFace(faces, value, descriptor);
|
|
109
114
|
return;
|
|
@@ -112,7 +117,7 @@ function addLayoutFontFamilyFace(faces, value, descriptor) {
|
|
|
112
117
|
const fontFamily = value;
|
|
113
118
|
addLayoutFontFamilyFace(faces, fontFamily.ascii, descriptor);
|
|
114
119
|
addLayoutFontFamilyFace(faces, fontFamily.hAnsi, descriptor);
|
|
115
|
-
addLayoutFontFamilyFace(faces, fontFamily.cs,
|
|
120
|
+
addLayoutFontFamilyFace(faces, fontFamily.cs, complexScriptDescriptor);
|
|
116
121
|
addLayoutFontFamilyFace(faces, fontFamily.eastAsia, descriptor);
|
|
117
122
|
}
|
|
118
123
|
function addLayoutFontFamilyNameFace(faces, family, descriptor) {
|
|
@@ -26,11 +26,12 @@ function bodyMarginsClearHeaderFooter({ authoredMargins, preparedHeader, prepare
|
|
|
26
26
|
const headerBottom = preparedHeader ? (authoredMargins.header ?? 0) + (preparedHeader.marginPushBottom ?? preparedHeader.height) : authoredMargins.top;
|
|
27
27
|
const footerClearance = preparedFooter ? (authoredMargins.footer ?? 0) + (preparedFooter.marginPushBottom ?? preparedFooter.height) : authoredMargins.bottom;
|
|
28
28
|
const top = Math.max(authoredMargins.top, headerBottom);
|
|
29
|
+
const clearedTop = Math.max(top, preparedHeader?.bodyTopClearance ?? 0);
|
|
29
30
|
const bottom = Math.max(authoredMargins.bottom, footerClearance);
|
|
30
|
-
if (
|
|
31
|
+
if (clearedTop === authoredMargins.top && bottom === authoredMargins.bottom) return authoredMargins;
|
|
31
32
|
return {
|
|
32
33
|
...authoredMargins,
|
|
33
|
-
top,
|
|
34
|
+
top: clearedTop,
|
|
34
35
|
bottom
|
|
35
36
|
};
|
|
36
37
|
}
|
|
@@ -255,7 +256,6 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
255
256
|
let newLayout;
|
|
256
257
|
let pageFootnoteMap = /* @__PURE__ */ new Map();
|
|
257
258
|
let footnoteContentMap = /* @__PURE__ */ new Map();
|
|
258
|
-
const bodyBreakType = finalSectionProperties?.sectionStart;
|
|
259
259
|
const buildLayoutOpts = () => {
|
|
260
260
|
const nextLayoutOpts = {
|
|
261
261
|
pageSize,
|
|
@@ -279,7 +279,6 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
279
279
|
nextLayoutOpts.finalPageNumbering = finalLayoutConfig.pageNumbering;
|
|
280
280
|
}
|
|
281
281
|
if (columns !== void 0) nextLayoutOpts.columns = columns;
|
|
282
|
-
if (bodyBreakType !== void 0) nextLayoutOpts.bodyBreakType = bodyBreakType;
|
|
283
282
|
if (sectionHeaderFooterRefs !== void 0) nextLayoutOpts.sectionHeaderFooterRefs = sectionHeaderFooterRefs;
|
|
284
283
|
if (sectionEvenPageMargins !== void 0) nextLayoutOpts.sectionEvenPageMargins = sectionEvenPageMargins;
|
|
285
284
|
return nextLayoutOpts;
|
|
@@ -188,7 +188,7 @@ declare function isTocField(field: document_d_exports.Field): boolean;
|
|
|
188
188
|
* @param instruction - Parsed instruction for format switches
|
|
189
189
|
* @returns Formatted page number string
|
|
190
190
|
*/
|
|
191
|
-
declare function computePageNumber(pageNumber: number, instruction?: ParsedFieldInstruction, sectionFormat?:
|
|
191
|
+
declare function computePageNumber(pageNumber: number, instruction?: ParsedFieldInstruction, sectionFormat?: document_d_exports.NumberFormat): string;
|
|
192
192
|
/**
|
|
193
193
|
* Format a date according to a format string
|
|
194
194
|
*
|
package/dist/docx/fieldParser.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatOoxmlCounter } from "./ooxmlCounterFormatter.js";
|
|
1
2
|
import { FieldTypeSchema, narrowEnum } from "./parserEnums.js";
|
|
2
3
|
import { parseRun } from "./runParser.js";
|
|
3
4
|
import { findChildren, getAttribute } from "./xmlParser.js";
|
|
@@ -354,15 +355,7 @@ function computePageNumber(pageNumber, instruction, sectionFormat) {
|
|
|
354
355
|
default: return String(pageNumber);
|
|
355
356
|
}
|
|
356
357
|
}
|
|
357
|
-
|
|
358
|
-
switch (format) {
|
|
359
|
-
case "upperRoman": return toRoman(pageNumber);
|
|
360
|
-
case "lowerRoman": return toRoman(pageNumber).toLowerCase();
|
|
361
|
-
case "upperLetter": return toLetter(pageNumber);
|
|
362
|
-
case "lowerLetter": return toLetter(pageNumber).toLowerCase();
|
|
363
|
-
default: return String(pageNumber);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
358
|
+
const formatSectionPageNumber = (pageNumber, format) => formatOoxmlCounter(pageNumber, format);
|
|
366
359
|
/**
|
|
367
360
|
* Convert number to uppercase Roman numerals
|
|
368
361
|
*/
|
|
@@ -24,6 +24,7 @@ type NumberingMap = {
|
|
|
24
24
|
* @returns NumberingMap with definitions and helper functions
|
|
25
25
|
*/
|
|
26
26
|
declare function parseNumbering(numberingXml: string | null): NumberingMap;
|
|
27
|
+
declare const markerFormattingFromLevel: (formatting: document_d_exports.TextFormatting | undefined) => document_d_exports.ListMarkerFormatting | undefined;
|
|
27
28
|
declare function getCachedNumberingMap(definitions: document_d_exports.NumberingDefinitions): NumberingMap;
|
|
28
29
|
/**
|
|
29
30
|
* Create a NumberingMap with helper functions
|
|
@@ -80,4 +81,4 @@ declare function getBulletCharacter(level: document_d_exports.ListLevel): string
|
|
|
80
81
|
*/
|
|
81
82
|
declare function isBulletLevel(level: document_d_exports.ListLevel): boolean;
|
|
82
83
|
//#endregion
|
|
83
|
-
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
84
|
+
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatOoxmlCounter, padDecimal } from "./ooxmlCounterFormatter.js";
|
|
2
|
-
import {
|
|
2
|
+
import { LevelSuffixSchema, narrowEnum } from "./parserEnums.js";
|
|
3
|
+
import { parseRunProperties } from "./runParser.js";
|
|
3
4
|
import { findChild, findChildren, getAttribute, parseBooleanElement, parseNumericAttribute, parseXmlDocument } from "./xmlParser.js";
|
|
4
5
|
//#region src/docx/numberingParser.ts
|
|
5
6
|
const NUMBER_FORMAT_MAP = {
|
|
@@ -315,7 +316,10 @@ function parseListLevel(element) {
|
|
|
315
316
|
};
|
|
316
317
|
}
|
|
317
318
|
if (pPrEl) level.pPr = parseLevelParagraphProps(pPrEl);
|
|
318
|
-
if (rPrEl)
|
|
319
|
+
if (rPrEl) {
|
|
320
|
+
const runProperties = parseRunProperties(rPrEl, null);
|
|
321
|
+
if (runProperties) level.rPr = runProperties;
|
|
322
|
+
}
|
|
319
323
|
return level;
|
|
320
324
|
}
|
|
321
325
|
/**
|
|
@@ -428,79 +432,21 @@ function parseTabLeader(val) {
|
|
|
428
432
|
default: return;
|
|
429
433
|
}
|
|
430
434
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
case "w:rFonts":
|
|
447
|
-
rFontsEl ??= child;
|
|
448
|
-
break;
|
|
449
|
-
case "w:sz":
|
|
450
|
-
szEl ??= child;
|
|
451
|
-
break;
|
|
452
|
-
case "w:color":
|
|
453
|
-
colorEl ??= child;
|
|
454
|
-
break;
|
|
455
|
-
case "w:b":
|
|
456
|
-
bEl ??= child;
|
|
457
|
-
break;
|
|
458
|
-
case "w:i":
|
|
459
|
-
iEl ??= child;
|
|
460
|
-
break;
|
|
461
|
-
case "w:vanish":
|
|
462
|
-
vanishEl ??= child;
|
|
463
|
-
break;
|
|
464
|
-
default: break;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
if (rFontsEl) {
|
|
468
|
-
const ascii = getAttribute(rFontsEl, "w", "ascii");
|
|
469
|
-
const hAnsi = getAttribute(rFontsEl, "w", "hAnsi");
|
|
470
|
-
const eastAsia = getAttribute(rFontsEl, "w", "eastAsia");
|
|
471
|
-
const cs = getAttribute(rFontsEl, "w", "cs");
|
|
472
|
-
const hint = narrowEnum(getAttribute(rFontsEl, "w", "hint"), FontHintSchema);
|
|
473
|
-
formatting.fontFamily = {
|
|
474
|
-
...ascii != null ? { ascii } : {},
|
|
475
|
-
...hAnsi != null ? { hAnsi } : {},
|
|
476
|
-
...eastAsia != null ? { eastAsia } : {},
|
|
477
|
-
...cs != null ? { cs } : {},
|
|
478
|
-
...hint !== void 0 ? { hint } : {}
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
if (szEl) {
|
|
482
|
-
const size = parseNumericAttribute(szEl, "w", "val");
|
|
483
|
-
if (size !== void 0) formatting.fontSize = size;
|
|
484
|
-
}
|
|
485
|
-
if (colorEl) {
|
|
486
|
-
const val = getAttribute(colorEl, "w", "val");
|
|
487
|
-
const validatedThemeColor = narrowEnum(getAttribute(colorEl, "w", "themeColor"), ThemeColorSlotSchema);
|
|
488
|
-
if (val === "auto") formatting.color = { auto: true };
|
|
489
|
-
else if (validatedThemeColor) {
|
|
490
|
-
const themeTint = getAttribute(colorEl, "w", "themeTint");
|
|
491
|
-
const themeShade = getAttribute(colorEl, "w", "themeShade");
|
|
492
|
-
formatting.color = {
|
|
493
|
-
themeColor: validatedThemeColor,
|
|
494
|
-
...themeTint != null ? { themeTint } : {},
|
|
495
|
-
...themeShade != null ? { themeShade } : {}
|
|
496
|
-
};
|
|
497
|
-
} else if (val) formatting.color = { rgb: val };
|
|
498
|
-
}
|
|
499
|
-
if (bEl) formatting.bold = parseBooleanElement(bEl);
|
|
500
|
-
if (iEl) formatting.italic = parseBooleanElement(iEl);
|
|
501
|
-
if (vanishEl) formatting.hidden = parseBooleanElement(vanishEl);
|
|
502
|
-
return formatting;
|
|
503
|
-
}
|
|
435
|
+
const markerFormattingFromLevel = (formatting) => {
|
|
436
|
+
if (!formatting) return;
|
|
437
|
+
const markerFormatting = {
|
|
438
|
+
...formatting.fontFamily !== void 0 ? { fontFamily: formatting.fontFamily } : {},
|
|
439
|
+
...formatting.fontSize !== void 0 ? { fontSize: formatting.fontSize } : {},
|
|
440
|
+
...formatting.fontSizeCs !== void 0 ? { fontSizeCs: formatting.fontSizeCs } : {},
|
|
441
|
+
...formatting.bold !== void 0 ? { bold: formatting.bold } : {},
|
|
442
|
+
...formatting.boldCs !== void 0 ? { boldCs: formatting.boldCs } : {},
|
|
443
|
+
...formatting.italic !== void 0 ? { italic: formatting.italic } : {},
|
|
444
|
+
...formatting.italicCs !== void 0 ? { italicCs: formatting.italicCs } : {},
|
|
445
|
+
...formatting.rtl !== void 0 ? { rtl: formatting.rtl } : {},
|
|
446
|
+
...formatting.cs !== void 0 ? { cs: formatting.cs } : {}
|
|
447
|
+
};
|
|
448
|
+
return Object.keys(markerFormatting).length > 0 ? markerFormatting : void 0;
|
|
449
|
+
};
|
|
504
450
|
/**
|
|
505
451
|
* Per-definitions cache for `createNumberingMap`. Style application rebuilds
|
|
506
452
|
* the lookup map on every picker click otherwise; the definitions object is
|
|
@@ -603,10 +549,8 @@ function computeListRendering(numPr, numbering) {
|
|
|
603
549
|
};
|
|
604
550
|
if (level.isLgl) rendering.isLegal = true;
|
|
605
551
|
if (level.rPr?.hidden) rendering.markerHidden = true;
|
|
606
|
-
const
|
|
607
|
-
if (
|
|
608
|
-
if (level.rPr?.fontSize) rendering.markerFontSize = level.rPr.fontSize / 2;
|
|
609
|
-
if (level.rPr?.bold !== void 0) rendering.markerBold = level.rPr.bold;
|
|
552
|
+
const markerFormatting = markerFormattingFromLevel(level.rPr);
|
|
553
|
+
if (markerFormatting) rendering.markerFormatting = markerFormatting;
|
|
610
554
|
if (level.rPr?.allCaps) rendering.markerAllCaps = true;
|
|
611
555
|
if (level.lvlJc) rendering.markerAlignment = level.lvlJc;
|
|
612
556
|
if (level.suffix) rendering.markerSuffix = level.suffix;
|
|
@@ -666,4 +610,4 @@ function isBulletLevel(level) {
|
|
|
666
610
|
return level.numFmt === "bullet" || level.numFmt === "none";
|
|
667
611
|
}
|
|
668
612
|
//#endregion
|
|
669
|
-
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
613
|
+
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -2,6 +2,7 @@ import { isValidHexId } from "../utils/hexId.js";
|
|
|
2
2
|
import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBookmarkStart$1 } from "./bookmarkParser.js";
|
|
3
3
|
import { parseFieldType } from "./fieldParser.js";
|
|
4
4
|
import { parseHyperlink as parseHyperlink$1 } from "./hyperlinkParser.js";
|
|
5
|
+
import { markerFormattingFromLevel } from "./numberingParser.js";
|
|
5
6
|
import { BorderStyleSchema, FrameWrapSchema, FrameXAlignSchema, FrameYAlignSchema, LineSpacingRuleSchema, ParagraphAlignmentSchema, ShadingPatternSchema, TabLeaderSchema, TabStopAlignmentSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
|
|
6
7
|
import { consolidateParagraphContent } from "./runConsolidator.js";
|
|
7
8
|
import { parseRun, parseRunProperties } from "./runParser.js";
|
|
@@ -1016,10 +1017,8 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
|
|
|
1016
1017
|
if (level.isLgl) listRendering.isLegal = true;
|
|
1017
1018
|
listRendering.numFmt = level.isLgl ? "decimal" : level.numFmt;
|
|
1018
1019
|
if (level.rPr?.hidden) listRendering.markerHidden = true;
|
|
1019
|
-
const
|
|
1020
|
-
if (
|
|
1021
|
-
if (level.rPr?.fontSize) listRendering.markerFontSize = level.rPr.fontSize / 2;
|
|
1022
|
-
if (level.rPr?.bold !== void 0) listRendering.markerBold = level.rPr.bold;
|
|
1020
|
+
const markerFormatting = markerFormattingFromLevel(level.rPr);
|
|
1021
|
+
if (markerFormatting) listRendering.markerFormatting = markerFormatting;
|
|
1023
1022
|
if (level.rPr?.allCaps) listRendering.markerAllCaps = true;
|
|
1024
1023
|
if (level.lvlJc) listRendering.markerAlignment = level.lvlJc;
|
|
1025
1024
|
if (level.suffix) listRendering.markerSuffix = level.suffix;
|
|
@@ -158,6 +158,7 @@ const enrichTextBoxRuns = ({ content, xmlChildren, styles, theme, numbering, rel
|
|
|
158
158
|
textBody: {
|
|
159
159
|
content: textBox.content,
|
|
160
160
|
...textBox.autoFit !== void 0 ? { autoFit: textBox.autoFit } : {},
|
|
161
|
+
...textBox.textWrap !== void 0 ? { textWrap: textBox.textWrap } : {},
|
|
161
162
|
...textBox.margins !== void 0 ? { margins: textBox.margins } : {}
|
|
162
163
|
}
|
|
163
164
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseFooterReference, parseHeaderReference } from "./headerFooterRefParser.js";
|
|
2
2
|
import { parseEndnoteProperties, parseFootnoteProperties } from "./notePropertiesParser.js";
|
|
3
|
-
import { BorderStyleSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
|
|
3
|
+
import { BorderStyleSchema, NumberFormatSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
|
|
4
4
|
import { findChild, findChildren, getAttribute, getChildElements, getLocalName, parseBooleanElement, parseNumericAttribute } from "./xmlParser.js";
|
|
5
5
|
import { normalizeRevisionId } from "@stll/docx-core/model";
|
|
6
6
|
//#region src/docx/sectionParser.ts
|
|
@@ -272,7 +272,7 @@ function parseSectionProperties(sectPr) {
|
|
|
272
272
|
const pgNumType = findChild(sectPr, "w", "pgNumType");
|
|
273
273
|
if (pgNumType) {
|
|
274
274
|
const pageNumbering = {};
|
|
275
|
-
const format = getAttribute(pgNumType, "w", "fmt");
|
|
275
|
+
const format = narrowEnum(getAttribute(pgNumType, "w", "fmt"), NumberFormatSchema);
|
|
276
276
|
if (format) pageNumbering.format = format;
|
|
277
277
|
const start = parseNumericAttribute(pgNumType, "w", "start");
|
|
278
278
|
if (start !== void 0) pageNumbering.start = start;
|
|
@@ -479,6 +479,7 @@ function serializeShapeContent(content) {
|
|
|
479
479
|
if (shape.textBody) {
|
|
480
480
|
const tb = shape.textBody;
|
|
481
481
|
const bpAttrs = ["rot=\"0\"", "vert=\"horz\""];
|
|
482
|
+
if (tb.textWrap) bpAttrs.push(`wrap="${tb.textWrap}"`);
|
|
482
483
|
if (tb.anchor) bpAttrs.push(`anchor="${tb.anchor === "middle" ? "ctr" : tb.anchor}"`);
|
|
483
484
|
if (tb.anchorCenter) bpAttrs.push("anchorCtr=\"1\"");
|
|
484
485
|
if (tb.margins) {
|
|
@@ -11,6 +11,8 @@ const DEFAULT_MARGIN_EMU = 91440;
|
|
|
11
11
|
function parseBodyProperties(bodyPr) {
|
|
12
12
|
if (!bodyPr) return {};
|
|
13
13
|
const result = {};
|
|
14
|
+
const textWrap = getAttribute(bodyPr, null, "wrap");
|
|
15
|
+
if (textWrap === "none" || textWrap === "square") result.textWrap = textWrap;
|
|
14
16
|
if (findChildByLocalName(bodyPr, "spAutoFit")) result.autoFit = "shape";
|
|
15
17
|
else if (findChildByLocalName(bodyPr, "normAutofit")) result.autoFit = "normal";
|
|
16
18
|
else if (findChildByLocalName(bodyPr, "noAutofit")) result.autoFit = "none";
|
|
@@ -128,6 +130,7 @@ function parseTextBox(drawingEl) {
|
|
|
128
130
|
if (outline) textBox.outline = outline;
|
|
129
131
|
if (bodyProps.margins) textBox.margins = bodyProps.margins;
|
|
130
132
|
if (bodyProps.autoFit) textBox.autoFit = bodyProps.autoFit;
|
|
133
|
+
if (bodyProps.textWrap) textBox.textWrap = bodyProps.textWrap;
|
|
131
134
|
if (isAnchor) {
|
|
132
135
|
const position = parseAnchorPosition(container);
|
|
133
136
|
if (position) textBox.position = position;
|
|
@@ -170,6 +173,7 @@ function parseTextBoxFromShape(wsp, size, position, wrap) {
|
|
|
170
173
|
if (outline) textBox.outline = outline;
|
|
171
174
|
if (bodyProps.margins) textBox.margins = bodyProps.margins;
|
|
172
175
|
if (bodyProps.autoFit) textBox.autoFit = bodyProps.autoFit;
|
|
176
|
+
if (bodyProps.textWrap) textBox.textWrap = bodyProps.textWrap;
|
|
173
177
|
if (position) textBox.position = position;
|
|
174
178
|
if (wrap) textBox.wrap = wrap;
|
|
175
179
|
return textBox;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
1
2
|
//#region src/fields/fieldContext.d.ts
|
|
2
3
|
/**
|
|
3
4
|
* Resolution context for evaluating dynamic DOCX fields against a laid-out
|
|
@@ -10,7 +11,7 @@ type FieldContext = {
|
|
|
10
11
|
/** 1-indexed page the field is on (PAGE). */
|
|
11
12
|
pageNumber: number;
|
|
12
13
|
/** OOXML section-level format used when PAGE has no explicit format switch. */
|
|
13
|
-
pageNumberFormat?:
|
|
14
|
+
pageNumberFormat?: document_d_exports.NumberFormat;
|
|
14
15
|
/** Total pages in the document (NUMPAGES). */
|
|
15
16
|
totalPages: number;
|
|
16
17
|
/** Pages in the field's current section (SECTIONPAGES); omit until the
|
|
@@ -30,6 +30,14 @@ declare function calculateHeaderFooterMarginPushBounds(blocks: FlowBlock[], meas
|
|
|
30
30
|
top: number;
|
|
31
31
|
bottom: number;
|
|
32
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Find the lower page edge of header `wrapTopAndBottom` artwork that overlaps
|
|
35
|
+
* the authored body start. Unlike ordinary anchored artwork, this wrap mode
|
|
36
|
+
* reserves a full-width horizontal band even when the drawing paints behind
|
|
37
|
+
* text. Bands wholly below the body start need page-local flow support and are
|
|
38
|
+
* intentionally not flattened into a top margin here.
|
|
39
|
+
*/
|
|
40
|
+
declare function calculateHeaderFooterBodyTopClearance(blocks: FlowBlock[], flowHeight: number, metrics: HeaderFooterMetrics): number | undefined;
|
|
33
41
|
type ConvertHeaderFooterOptions = {
|
|
34
42
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
35
43
|
theme?: document_d_exports.Theme | null;
|
|
@@ -74,4 +82,4 @@ declare function convertHeaderFooterToContent(headerFooter: document_d_exports.H
|
|
|
74
82
|
*/
|
|
75
83
|
declare function convertHeaderFooterPmDocToContent(pmDoc: Node | null | undefined, contentWidth: number, metrics: HeaderFooterMetrics, options: Omit<ConvertHeaderFooterOptions, "styles">): HeaderFooterContent | undefined;
|
|
76
84
|
//#endregion
|
|
77
|
-
export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
85
|
+
export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
@@ -290,6 +290,29 @@ function calculateHeaderFooterMarginPushBounds(blocks, measures, flowHeight, met
|
|
|
290
290
|
};
|
|
291
291
|
}
|
|
292
292
|
/**
|
|
293
|
+
* Find the lower page edge of header `wrapTopAndBottom` artwork that overlaps
|
|
294
|
+
* the authored body start. Unlike ordinary anchored artwork, this wrap mode
|
|
295
|
+
* reserves a full-width horizontal band even when the drawing paints behind
|
|
296
|
+
* text. Bands wholly below the body start need page-local flow support and are
|
|
297
|
+
* intentionally not flattened into a top margin here.
|
|
298
|
+
*/
|
|
299
|
+
function calculateHeaderFooterBodyTopClearance(blocks, flowHeight, metrics) {
|
|
300
|
+
if (metrics.section !== "header") return;
|
|
301
|
+
const flowTop = metrics.margins.header ?? 48;
|
|
302
|
+
let clearance = 0;
|
|
303
|
+
for (const block of blocks) {
|
|
304
|
+
if (block.kind !== "paragraph") continue;
|
|
305
|
+
for (const run of block.runs) {
|
|
306
|
+
if (run.kind !== "image" || run.wrapType !== "topAndBottom" || run.position?.vertical?.relativeTo !== "page" && run.position?.vertical?.relativeTo !== "margin") continue;
|
|
307
|
+
const pageTop = flowTop + resolveHeaderFooterVisualTop(run, 0, flowHeight, metrics) - (run.distTop ?? 0);
|
|
308
|
+
if (pageTop > metrics.margins.top) continue;
|
|
309
|
+
const pageBottom = Math.min(metrics.pageSize.h, pageTop + (run.distTop ?? 0) + run.height + (run.distBottom ?? 0));
|
|
310
|
+
clearance = Math.max(clearance, pageBottom);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return clearance > 0 ? clearance : void 0;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
293
316
|
* Convert HeaderFooter (document type) to HeaderFooterContent (render type).
|
|
294
317
|
*
|
|
295
318
|
* Routes through the same pipeline as the body: HF.content ->
|
|
@@ -350,6 +373,7 @@ function finalizeHeaderFooterContent(blocks, contentWidth, metrics, options) {
|
|
|
350
373
|
}
|
|
351
374
|
const { visualTop, visualBottom } = calculateHeaderFooterVisualBounds(blocks, measures, flowHeight, metrics);
|
|
352
375
|
const { top: marginPushTop, bottom: marginPushBottom } = calculateHeaderFooterMarginPushBounds(blocks, measures, flowHeight, metrics);
|
|
376
|
+
const bodyTopClearance = calculateHeaderFooterBodyTopClearance(blocks, flowHeight, metrics);
|
|
353
377
|
return {
|
|
354
378
|
blocks,
|
|
355
379
|
measures,
|
|
@@ -358,6 +382,7 @@ function finalizeHeaderFooterContent(blocks, contentWidth, metrics, options) {
|
|
|
358
382
|
visualBottom,
|
|
359
383
|
marginPushTop,
|
|
360
384
|
marginPushBottom,
|
|
385
|
+
...bodyTopClearance !== void 0 ? { bodyTopClearance } : {},
|
|
361
386
|
textSig: computeHeaderFooterTextSig(blocks),
|
|
362
387
|
...options.rId ? { rId: options.rId } : {}
|
|
363
388
|
};
|
|
@@ -442,7 +467,7 @@ function serializeParagraphAttrs(attrs) {
|
|
|
442
467
|
"listMarker",
|
|
443
468
|
"listIsBullet",
|
|
444
469
|
"listMarkerHidden",
|
|
445
|
-
"
|
|
470
|
+
"listMarkerFormatting",
|
|
446
471
|
"listMarkerAlignment",
|
|
447
472
|
"listMarkerSuffix",
|
|
448
473
|
"tabs"
|
|
@@ -489,4 +514,4 @@ function serializeRunFmt(run) {
|
|
|
489
514
|
return JSON.stringify(out);
|
|
490
515
|
}
|
|
491
516
|
//#endregion
|
|
492
|
-
export { calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
517
|
+
export { calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
@@ -362,8 +362,7 @@ function applyRunFormattingOverrides(formatting, attrs) {
|
|
|
362
362
|
if (attrs.fontSizeCs !== void 0) formatting.complexScriptFontSize = attrs.fontSizeCs / 2;
|
|
363
363
|
if (attrs.cs !== void 0) formatting.forceComplexScript = attrs.cs;
|
|
364
364
|
}
|
|
365
|
-
function
|
|
366
|
-
const defaultTextFormatting = pmAttrs.defaultTextFormatting;
|
|
365
|
+
function textFormattingToRunFormatting(defaultTextFormatting, theme) {
|
|
367
366
|
if (!defaultTextFormatting) return {};
|
|
368
367
|
const result = {};
|
|
369
368
|
const fontFamily = defaultTextFormatting.fontFamily ? resolveWesternThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
@@ -379,6 +378,7 @@ function paragraphRunDefaults(pmAttrs, theme) {
|
|
|
379
378
|
if (defaultTextFormatting.boldCs !== void 0) result.complexScriptBold = defaultTextFormatting.boldCs;
|
|
380
379
|
if (defaultTextFormatting.italic !== void 0) result.italic = defaultTextFormatting.italic;
|
|
381
380
|
if (defaultTextFormatting.italicCs !== void 0) result.complexScriptItalic = defaultTextFormatting.italicCs;
|
|
381
|
+
if (defaultTextFormatting.rtl !== void 0) result.rtl = defaultTextFormatting.rtl;
|
|
382
382
|
if (defaultTextFormatting.cs !== void 0) result.forceComplexScript = defaultTextFormatting.cs;
|
|
383
383
|
if (defaultTextFormatting.underline && defaultTextFormatting.underline.style !== "none") {
|
|
384
384
|
result.underline = { style: defaultTextFormatting.underline.style };
|
|
@@ -408,6 +408,9 @@ function paragraphRunDefaults(pmAttrs, theme) {
|
|
|
408
408
|
if (defaultTextFormatting.emphasisMark && defaultTextFormatting.emphasisMark !== "none") result.emphasisMark = defaultTextFormatting.emphasisMark;
|
|
409
409
|
return result;
|
|
410
410
|
}
|
|
411
|
+
function paragraphRunDefaults(pmAttrs, theme) {
|
|
412
|
+
return textFormattingToRunFormatting(pmAttrs.defaultTextFormatting, theme);
|
|
413
|
+
}
|
|
411
414
|
/**
|
|
412
415
|
* Build an ImageRun from ProseMirror node attrs, applying conditional property assignment
|
|
413
416
|
* to satisfy exactOptionalPropertyTypes.
|
|
@@ -653,12 +656,8 @@ function toPreviousListAttrs(previousFormatting) {
|
|
|
653
656
|
if (listStartOverride !== void 0) attrs.listStartOverride = listStartOverride;
|
|
654
657
|
const listMarkerHidden = previousFormatting.listMarkerHidden;
|
|
655
658
|
if (listMarkerHidden !== void 0) attrs.listMarkerHidden = listMarkerHidden;
|
|
656
|
-
const
|
|
657
|
-
if (
|
|
658
|
-
const listMarkerFontSize = previousFormatting.listMarkerFontSize;
|
|
659
|
-
if (listMarkerFontSize !== void 0) attrs.listMarkerFontSize = listMarkerFontSize;
|
|
660
|
-
const listMarkerBold = previousFormatting.listMarkerBold;
|
|
661
|
-
if (listMarkerBold !== void 0) attrs.listMarkerBold = listMarkerBold;
|
|
659
|
+
const listMarkerFormatting = previousFormatting.listMarkerFormatting;
|
|
660
|
+
if (listMarkerFormatting !== void 0) attrs.listMarkerFormatting = listMarkerFormatting;
|
|
662
661
|
const listMarkerAlignment = previousFormatting.listMarkerAlignment;
|
|
663
662
|
if (listMarkerAlignment !== void 0) attrs.listMarkerAlignment = listMarkerAlignment;
|
|
664
663
|
const listMarkerSuffix = previousFormatting.listMarkerSuffix;
|
|
@@ -674,7 +673,7 @@ function resolveDeletedListMarker(previousListAttrs, listCounters, listAbstractC
|
|
|
674
673
|
if (previousListAttrs.listIsBullet) return "•";
|
|
675
674
|
return null;
|
|
676
675
|
}
|
|
677
|
-
function applyDeletedListMarkerAttrs(attrs, change, listCounters, listAbstractCounters, listSeenNumIds) {
|
|
676
|
+
function applyDeletedListMarkerAttrs(attrs, change, listCounters, listAbstractCounters, listSeenNumIds, theme) {
|
|
678
677
|
const previousListAttrs = toPreviousListAttrs(change.previousFormatting);
|
|
679
678
|
const marker = resolveDeletedListMarker(previousListAttrs, listCounters, listAbstractCounters, listSeenNumIds);
|
|
680
679
|
if (!marker) return;
|
|
@@ -682,9 +681,7 @@ function applyDeletedListMarkerAttrs(attrs, change, listCounters, listAbstractCo
|
|
|
682
681
|
attrs.listMarkerRevision = toListMarkerRevision("del", change.info);
|
|
683
682
|
if (previousListAttrs.listIsBullet !== void 0) attrs.listIsBullet = previousListAttrs.listIsBullet;
|
|
684
683
|
if (previousListAttrs.listMarkerHidden !== void 0) attrs.listMarkerHidden = previousListAttrs.listMarkerHidden;
|
|
685
|
-
if (previousListAttrs.
|
|
686
|
-
if (previousListAttrs.listMarkerFontSize) attrs.listMarkerFontSize = previousListAttrs.listMarkerFontSize;
|
|
687
|
-
if (previousListAttrs.listMarkerBold !== void 0) attrs.listMarkerBold = previousListAttrs.listMarkerBold;
|
|
684
|
+
if (previousListAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(previousListAttrs.listMarkerFormatting, theme);
|
|
688
685
|
if (previousListAttrs.listMarkerAlignment) attrs.listMarkerAlignment = previousListAttrs.listMarkerAlignment;
|
|
689
686
|
if (previousListAttrs.listMarkerSuffix) attrs.listMarkerSuffix = previousListAttrs.listMarkerSuffix;
|
|
690
687
|
}
|
|
@@ -820,15 +817,13 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
820
817
|
else if (pmAttrs.listMarker) attrs.listMarker = pmAttrs.listIsBullet ? convertBulletToUnicode(pmAttrs.listMarker) : pmAttrs.listMarker;
|
|
821
818
|
if (pmAttrs.listIsBullet !== void 0) attrs.listIsBullet = pmAttrs.listIsBullet;
|
|
822
819
|
if (pmAttrs.listMarkerHidden) attrs.listMarkerHidden = true;
|
|
823
|
-
if (pmAttrs.
|
|
824
|
-
if (pmAttrs.listMarkerFontSize) attrs.listMarkerFontSize = pmAttrs.listMarkerFontSize;
|
|
825
|
-
if (pmAttrs.listMarkerBold !== null && pmAttrs.listMarkerBold !== void 0) attrs.listMarkerBold = pmAttrs.listMarkerBold;
|
|
820
|
+
if (pmAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(pmAttrs.listMarkerFormatting, theme);
|
|
826
821
|
if (pmAttrs.listMarkerAlignment) attrs.listMarkerAlignment = pmAttrs.listMarkerAlignment;
|
|
827
822
|
if (pmAttrs.listMarkerSuffix) attrs.listMarkerSuffix = pmAttrs.listMarkerSuffix;
|
|
828
823
|
if (pmAttrs.listMarkerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = pmAttrs.listMarkerSecondSlotOffsetTwips;
|
|
829
824
|
if (!pmAttrs.numPr) {
|
|
830
825
|
const numberingRemovedChange = propertyChanges.find(isRemovedNumberingChange);
|
|
831
|
-
if (numberingRemovedChange) applyDeletedListMarkerAttrs(attrs, numberingRemovedChange, originalListCounters, originalListAbstractCounters, originalListSeenNumIds);
|
|
826
|
+
if (numberingRemovedChange) applyDeletedListMarkerAttrs(attrs, numberingRemovedChange, originalListCounters, originalListAbstractCounters, originalListSeenNumIds, theme);
|
|
832
827
|
}
|
|
833
828
|
if (defaultTabStopTwips !== void 0) attrs.defaultTabStopTwips = defaultTabStopTwips;
|
|
834
829
|
const dtf = pmAttrs.defaultTextFormatting;
|
|
@@ -1226,6 +1221,7 @@ function convertTextBoxNode(node, startPos, opts) {
|
|
|
1226
1221
|
};
|
|
1227
1222
|
if (attrs.height !== void 0) textBox.height = attrs.height;
|
|
1228
1223
|
if (attrs.autoFit !== void 0) textBox.autoFit = attrs.autoFit;
|
|
1224
|
+
if (attrs.textWrap !== void 0) textBox.textWrap = attrs.textWrap;
|
|
1229
1225
|
if (attrs.fillColor !== void 0) textBox.fillColor = attrs.fillColor;
|
|
1230
1226
|
if (attrs.outlineWidth !== void 0) textBox.outlineWidth = attrs.outlineWidth;
|
|
1231
1227
|
if (attrs.outlineColor !== void 0) textBox.outlineColor = attrs.outlineColor;
|
|
@@ -4,7 +4,7 @@ import { buildRunFontStyle } from "../../layout-engine/measure/measureHelpers.js
|
|
|
4
4
|
import { measureParagraph } from "../../layout-engine/measure/measureParagraph.js";
|
|
5
5
|
import { measureRun } from "../../layout-engine/measure/measureProvider.js";
|
|
6
6
|
import { buildTableCellFloatingZones, getTableCellContentWidth, getTableCellFloatingImages } from "../../layout-engine/measure/tableCellFloating.js";
|
|
7
|
-
import { getTableRowLeadingWidth } from "../../layout-engine/types.js";
|
|
7
|
+
import { getTableRowLeadingWidth, resolveTableCellPadding } from "../../layout-engine/types.js";
|
|
8
8
|
import { inlineImageBoundingBox } from "../../utils/rotationBoundingBox.js";
|
|
9
9
|
import { getPageTop } from "./hitTest.js";
|
|
10
10
|
//#region src/layout-bridge/engine/selectionRects.ts
|
|
@@ -24,8 +24,6 @@ import { getPageTop } from "./hitTest.js";
|
|
|
24
24
|
* across blank lines visible (eigenpal/docx-editor#836).
|
|
25
25
|
*/
|
|
26
26
|
const EMPTY_PARAGRAPH_SLIVER_WIDTH = 4;
|
|
27
|
-
const DEFAULT_TABLE_CELL_PADDING_LEFT = 7;
|
|
28
|
-
const DEFAULT_TABLE_CELL_PADDING_TOP = 1;
|
|
29
27
|
/**
|
|
30
28
|
* Extract FontStyle from a run for measurement.
|
|
31
29
|
*/
|
|
@@ -49,14 +47,14 @@ function findBlockById(blocks, blockId) {
|
|
|
49
47
|
return blocks.findIndex((block) => block.id === blockId);
|
|
50
48
|
}
|
|
51
49
|
function getCellContentOffsetY(cell, cellMeasure, rowHeight) {
|
|
52
|
-
const padTop = cell
|
|
50
|
+
const { top: padTop } = resolveTableCellPadding(cell);
|
|
53
51
|
const spareHeight = Math.max(0, rowHeight - cellMeasure.height);
|
|
54
52
|
if (cell.verticalAlign === "bottom") return padTop + spareHeight;
|
|
55
53
|
if (cell.verticalAlign === "center") return padTop + spareHeight / 2;
|
|
56
54
|
return padTop;
|
|
57
55
|
}
|
|
58
56
|
function getCellContentOffsetX(cell) {
|
|
59
|
-
return cell.
|
|
57
|
+
return resolveTableCellPadding(cell).left;
|
|
60
58
|
}
|
|
61
59
|
function getMeasuredBlockHeight(measure) {
|
|
62
60
|
if (!measure) return 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionPageNumbering, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned } from "./types.js";
|
|
1
|
+
import { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListMarkerFormatting, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionPageNumbering, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, resolveTableCellPadding, tableColumnsArePinned } from "./types.js";
|
|
2
2
|
import { PageState, Paginator, PaginatorOptions, createPaginator } from "./paginator.js";
|
|
3
3
|
import { KeepNextChain, calculateChainHeight, computeKeepNextChains, getMidChainIndices, hasKeepLines, hasPageBreakBefore } from "./keep-together.js";
|
|
4
4
|
import { resolveSectionHeaderFooterRefs } from "./headerFooterRefs.js";
|
|
@@ -44,4 +44,4 @@ declare function layoutDocument(blocks: FlowBlock[], measures: Measure[], option
|
|
|
44
44
|
*/
|
|
45
45
|
declare function getHeaderRowsHeight(measure: TableMeasure, headerRowCount: number): number;
|
|
46
46
|
//#endregion
|
|
47
|
-
export { BlockId, BorderStyle, type BreakDecision, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, type KeepNextChain, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, type PageState, type Paginator, type PaginatorOptions, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionLayoutConfig, SectionPageNumbering, type SectionState, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, scheduleSectionBreak, tableColumnsArePinned };
|
|
47
|
+
export { BlockId, BorderStyle, type BreakDecision, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, type KeepNextChain, Layout, LayoutOptions, LineBreakRun, ListMarkerFormatting, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, type PageState, type Paginator, type PaginatorOptions, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionLayoutConfig, SectionPageNumbering, type SectionState, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, resolveTableCellPadding, scheduleSectionBreak, tableColumnsArePinned };
|
|
@@ -11,7 +11,7 @@ import { INITIAL_RENDERED_BREAK_STATE, reconcileAfterBlock, reconcileBreakBefore
|
|
|
11
11
|
import { applyPendingToActive, createInitialSectionState, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, scheduleSectionBreak } from "./section-breaks.js";
|
|
12
12
|
import { buildTableRowBreakInfo, getRowContinuationSkip, snapRowBreak } from "./tableRowBreak.js";
|
|
13
13
|
import { bandFragmentX, bandTopContentY, isPageFrameRelativeAnchor } from "./textBoxFlow.js";
|
|
14
|
-
import { DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned } from "./types.js";
|
|
14
|
+
import { DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, resolveTableCellPadding, tableColumnsArePinned } from "./types.js";
|
|
15
15
|
import { panic } from "better-result";
|
|
16
16
|
//#region src/layout-engine/index.ts
|
|
17
17
|
/**
|
|
@@ -257,9 +257,7 @@ function layoutDocument(blocks, measures, options) {
|
|
|
257
257
|
break;
|
|
258
258
|
case "sectionBreak": {
|
|
259
259
|
const nextSectionConfig = sectionConfigs[sectionIdx + 1] ?? initialConfig;
|
|
260
|
-
|
|
261
|
-
if (sectionIdx + 1 < sectionBreakTypes.length) nextType = sectionBreakTypes[sectionIdx + 1] ?? DEFAULT_SECTION_BREAK_TYPE;
|
|
262
|
-
handleSectionBreak(block, paginator, nextSectionConfig, nextType, sectionIdx + 1);
|
|
260
|
+
handleSectionBreak(block, paginator, nextSectionConfig, sectionBreakTypes[sectionIdx] ?? DEFAULT_SECTION_BREAK_TYPE, sectionIdx + 1);
|
|
263
261
|
const nextColumns = nextSectionConfig.columns;
|
|
264
262
|
const nextBreakIndex = breakIndices[sectionIdx + 1] ?? blocks.length;
|
|
265
263
|
const nextBreak = blocks[nextBreakIndex];
|
|
@@ -937,4 +935,4 @@ function handleSectionBreak(_block, paginator, nextSectionConfig, nextSectionTyp
|
|
|
937
935
|
paginator.updateColumns(nextSectionConfig.columns ?? DEFAULT_COLUMNS);
|
|
938
936
|
}
|
|
939
937
|
//#endregion
|
|
940
|
-
export { DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, scheduleSectionBreak, tableColumnsArePinned };
|
|
938
|
+
export { DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, resolveTableCellPadding, scheduleSectionBreak, tableColumnsArePinned };
|