@stll/folio-core 0.23.1 → 0.24.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/docx/numberingParser.d.ts +2 -1
- package/dist/docx/numberingParser.js +24 -80
- package/dist/docx/paragraphParser.js +3 -4
- package/dist/layout-bridge/convert/headerFooterLayout.js +1 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +11 -16
- package/dist/layout-engine/index.d.ts +2 -2
- 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/types.d.ts +5 -5
- package/dist/layout-painter/renderParagraph.js +8 -17
- package/dist/prosemirror/attrs/index.js +2 -6
- package/dist/prosemirror/conversion/fromProseDoc.js +1 -3
- package/dist/prosemirror/conversion/toProseDoc.js +1 -3
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -3
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -3
- package/dist/prosemirror/schema/nodes.d.ts +3 -7
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -3
- 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) {
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -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, 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, scheduleSectionBreak, tableColumnsArePinned };
|
|
@@ -186,6 +186,10 @@ function hashParagraphBlock(block) {
|
|
|
186
186
|
if (attrs.reserveEmptyOutlineHeight) parts.push("outline-empty-reserve");
|
|
187
187
|
if (attrs.documentGridLinePitch !== void 0) parts.push(`documentGrid:${attrs.documentGridLinePitch}|${attrs.snapToGrid !== false}`);
|
|
188
188
|
if (attrs.justificationCompatibility) parts.push(`justify-compat:${attrs.justificationCompatibility.type}`);
|
|
189
|
+
if (attrs.listMarker !== void 0) {
|
|
190
|
+
const marker = attrs.listMarkerFormatting;
|
|
191
|
+
parts.push(`marker:${attrs.listMarker}|${attrs.listMarkerHidden}|${attrs.listMarkerAlignment}|${attrs.listMarkerSuffix}|${marker?.fontFamily}|${marker?.eastAsiaFontFamily}|${marker?.complexScriptFontFamily}|${marker?.fontSize}|${marker?.complexScriptFontSize}|${marker?.bold}|${marker?.complexScriptBold}|${marker?.italic}|${marker?.complexScriptItalic}|${marker?.rtl}|${marker?.forceComplexScript}`);
|
|
192
|
+
}
|
|
189
193
|
parts.push(...lineBreakPolicyCacheParts(attrs));
|
|
190
194
|
const borders = attrs.borders;
|
|
191
195
|
if (borders) {
|
|
@@ -8,7 +8,7 @@ import { ParagraphBlock } from "../types.js";
|
|
|
8
8
|
declare const DEFAULT_TAB_STOP_TWIPS = 720;
|
|
9
9
|
/**
|
|
10
10
|
* Marker font resolution per ECMA-376 §17.9.6:
|
|
11
|
-
* 1. explicit numbering-level rPr (`attrs.
|
|
11
|
+
* 1. explicit numbering-level rPr (`attrs.listMarkerFormatting`),
|
|
12
12
|
* 2. first body text run's font,
|
|
13
13
|
* 3. paragraph defaults, then document defaults.
|
|
14
14
|
*/
|
|
@@ -16,6 +16,8 @@ declare function resolveListMarkerFont(block: ParagraphBlock): {
|
|
|
16
16
|
fontFamily: string;
|
|
17
17
|
fontSize: number;
|
|
18
18
|
bold?: boolean;
|
|
19
|
+
italic?: boolean;
|
|
20
|
+
rtl?: boolean;
|
|
19
21
|
};
|
|
20
22
|
/**
|
|
21
23
|
* Compute the marker's inline-block width in pixels, or 0 if the paragraph
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { hasCjk, hasComplexScript } from "../../utils/scriptSegments.js";
|
|
2
|
+
import { hasComplexScriptFormatting, resolveComplexScriptFormatting } from "./complexScriptFormatting.js";
|
|
1
3
|
import { ptToPx } from "./measureHelpers.js";
|
|
2
4
|
import { measureTextWidth } from "./measureProvider.js";
|
|
3
5
|
//#region src/layout-engine/measure/listMarkerWidth.ts
|
|
@@ -12,21 +14,33 @@ const DEFAULT_TAB_STOP_TWIPS = 720;
|
|
|
12
14
|
const TWIPS_TO_PX = 96 / 1440;
|
|
13
15
|
/**
|
|
14
16
|
* Marker font resolution per ECMA-376 §17.9.6:
|
|
15
|
-
* 1. explicit numbering-level rPr (`attrs.
|
|
17
|
+
* 1. explicit numbering-level rPr (`attrs.listMarkerFormatting`),
|
|
16
18
|
* 2. first body text run's font,
|
|
17
19
|
* 3. paragraph defaults, then document defaults.
|
|
18
20
|
*/
|
|
19
21
|
function resolveListMarkerFont(block) {
|
|
20
22
|
const attrs = block.attrs;
|
|
21
23
|
const firstTextRun = block.runs.find((r) => r.kind === "text");
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
fontFamily,
|
|
27
|
-
fontSize,
|
|
28
|
-
...bold !== void 0 ? { bold } : {}
|
|
24
|
+
const markerFormatting = attrs?.listMarkerFormatting;
|
|
25
|
+
const bold = markerFormatting?.bold ?? firstTextRun?.bold;
|
|
26
|
+
const italic = markerFormatting?.italic ?? firstTextRun?.italic;
|
|
27
|
+
const base = {
|
|
28
|
+
fontFamily: markerFormatting?.fontFamily ?? firstTextRun?.fontFamily ?? attrs?.defaultFontFamily ?? DEFAULT_FONT_FAMILY,
|
|
29
|
+
fontSize: markerFormatting?.fontSize ?? firstTextRun?.fontSize ?? attrs?.defaultFontSize ?? DEFAULT_FONT_SIZE,
|
|
30
|
+
...bold !== void 0 ? { bold } : {},
|
|
31
|
+
...italic !== void 0 ? { italic } : {},
|
|
32
|
+
...markerFormatting?.rtl !== void 0 ? { rtl: markerFormatting.rtl } : {}
|
|
29
33
|
};
|
|
34
|
+
const marker = attrs?.listMarker ?? "";
|
|
35
|
+
if (markerFormatting && hasComplexScriptFormatting(markerFormatting) && (markerFormatting.forceComplexScript || hasComplexScript(marker))) return {
|
|
36
|
+
...base,
|
|
37
|
+
...resolveComplexScriptFormatting(markerFormatting)
|
|
38
|
+
};
|
|
39
|
+
if (markerFormatting?.eastAsiaFontFamily && hasCjk(marker)) return {
|
|
40
|
+
...base,
|
|
41
|
+
fontFamily: markerFormatting.eastAsiaFontFamily
|
|
42
|
+
};
|
|
43
|
+
return base;
|
|
30
44
|
}
|
|
31
45
|
/**
|
|
32
46
|
* Compute the marker's inline-block width in pixels, or 0 if the paragraph
|
|
@@ -49,12 +63,7 @@ function resolveListMarkerFont(block) {
|
|
|
49
63
|
function getListMarkerInlineWidth(block) {
|
|
50
64
|
const attrs = block.attrs;
|
|
51
65
|
if (!attrs?.listMarker || attrs.listMarkerHidden) return 0;
|
|
52
|
-
const
|
|
53
|
-
const style = {
|
|
54
|
-
fontFamily,
|
|
55
|
-
fontSize,
|
|
56
|
-
...bold !== void 0 ? { bold } : {}
|
|
57
|
-
};
|
|
66
|
+
const style = resolveListMarkerFont(block);
|
|
58
67
|
const naturalWidth = measureTextWidth(attrs.listMarker, style);
|
|
59
68
|
const markerEndOffset = getMarkerEndOffset(naturalWidth, attrs.listMarkerAlignment);
|
|
60
69
|
const suffix = attrs.listMarkerSuffix ?? "tab";
|
|
@@ -75,19 +84,14 @@ function getListMarkerInlineWidth(block) {
|
|
|
75
84
|
let bodyStart;
|
|
76
85
|
if (firstCustomPast !== void 0 && firstGridPast !== void 0) bodyStart = Math.min(firstCustomPast, firstGridPast);
|
|
77
86
|
else bodyStart = firstCustomPast ?? firstGridPast;
|
|
78
|
-
if (bodyStart === void 0) return naturalWidth + ptToPx(fontSize) * .5;
|
|
87
|
+
if (bodyStart === void 0) return naturalWidth + ptToPx(style.fontSize ?? DEFAULT_FONT_SIZE) * .5;
|
|
79
88
|
return bodyStart - markerStartPx;
|
|
80
89
|
}
|
|
81
90
|
/** Paint-only offset that places the marker around its authored list anchor. */
|
|
82
91
|
function getListMarkerVisualOffset(block) {
|
|
83
92
|
const attrs = block.attrs;
|
|
84
93
|
if (!attrs?.listMarker || attrs.listMarkerHidden) return 0;
|
|
85
|
-
const
|
|
86
|
-
const naturalWidth = measureTextWidth(attrs.listMarker, {
|
|
87
|
-
fontFamily,
|
|
88
|
-
fontSize,
|
|
89
|
-
...bold !== void 0 ? { bold } : {}
|
|
90
|
-
});
|
|
94
|
+
const naturalWidth = measureTextWidth(attrs.listMarker, resolveListMarkerFont(block));
|
|
91
95
|
if (attrs.listMarkerAlignment === "right") return -naturalWidth;
|
|
92
96
|
if (attrs.listMarkerAlignment === "center") return -naturalWidth / 2;
|
|
93
97
|
return 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OutlineStyleAttr } from "../types/documentEnumValues.js";
|
|
2
2
|
import { ImagePosition, ImageWrap, SdtProperties, SdtType, ShapeTextBody, TableCellFormatting, TableWidthType } from "@stll/docx-core/model";
|
|
3
3
|
declare namespace types_d_exports {
|
|
4
|
-
export { 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 };
|
|
4
|
+
export { 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, tableColumnsArePinned };
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Unique identifier for a block in the document.
|
|
@@ -127,6 +127,7 @@ type RunFormatting = {
|
|
|
127
127
|
/** Groups a suggestion's runs for accept/reject and scroll-to. */
|
|
128
128
|
suggestionId?: string;
|
|
129
129
|
};
|
|
130
|
+
type ListMarkerFormatting = Pick<RunFormatting, "fontFamily" | "eastAsiaFontFamily" | "complexScriptFontFamily" | "fontSize" | "complexScriptFontSize" | "bold" | "complexScriptBold" | "italic" | "complexScriptItalic" | "rtl" | "forceComplexScript">;
|
|
130
131
|
/**
|
|
131
132
|
* Hyperlink information for a run.
|
|
132
133
|
*/
|
|
@@ -461,15 +462,14 @@ type ParagraphAttrs = {
|
|
|
461
462
|
listMarker?: string;
|
|
462
463
|
listIsBullet?: boolean;
|
|
463
464
|
listMarkerHidden?: boolean;
|
|
464
|
-
|
|
465
|
-
|
|
465
|
+
/** Canonical numbering-level marker typography, resolved for layout. */
|
|
466
|
+
listMarkerFormatting?: ListMarkerFormatting;
|
|
466
467
|
/**
|
|
467
468
|
* Effective paragraph-mark size used only to measure a visible list
|
|
468
469
|
* paragraph's final line. Word lets the inherited complex-script size raise
|
|
469
470
|
* that line box without enlarging the marker or Western text glyphs.
|
|
470
471
|
*/
|
|
471
472
|
listParagraphMarkFontSize?: number;
|
|
472
|
-
listMarkerBold?: boolean;
|
|
473
473
|
/** Horizontal alignment of the marker around the paragraph's list anchor. */
|
|
474
474
|
listMarkerAlignment?: "left" | "center" | "right";
|
|
475
475
|
/**
|
|
@@ -1380,4 +1380,4 @@ declare function tableColumnsArePinned(table: TableBlock): boolean;
|
|
|
1380
1380
|
/** Return the leading visual offset for a row with omitted grid columns. */
|
|
1381
1381
|
declare const getTableRowLeadingWidth: (row: TableRow, columnWidths: readonly number[]) => number;
|
|
1382
1382
|
//#endregion
|
|
1383
|
-
export { 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, types_d_exports };
|
|
1383
|
+
export { 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, tableColumnsArePinned, types_d_exports };
|
|
@@ -2,7 +2,7 @@ import { ommlToMathml } from "../docx/mathToMathml.js";
|
|
|
2
2
|
import { parseXmlDocument } from "../docx/xmlParser.js";
|
|
3
3
|
import { evaluateFieldInstruction } from "../fields/evaluateField.js";
|
|
4
4
|
import { hasComplexScriptFormatting, resolveComplexScriptFormatting } from "../layout-engine/measure/complexScriptFormatting.js";
|
|
5
|
-
import { getListMarkerInlineWidth, getListMarkerVisualOffset } from "../layout-engine/measure/listMarkerWidth.js";
|
|
5
|
+
import { getListMarkerInlineWidth, getListMarkerVisualOffset, resolveListMarkerFont } from "../layout-engine/measure/listMarkerWidth.js";
|
|
6
6
|
import { DOCX_SCRIPT_FONT_SCALE } from "../layout-engine/measure/measureHelpers.js";
|
|
7
7
|
import { FONT_KERNING_MODE, countCompressibleSpaces, getFontKerningMode, getRunFontKerningMode, toPaintedText } from "../layout-engine/measure/textMeasurementPolicy.js";
|
|
8
8
|
import { isFloatingImageRun } from "../layout-engine/types.js";
|
|
@@ -1463,18 +1463,7 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1463
1463
|
const markerStart = hanging > 0 ? indentLeft - hanging : indentLeft + firstLine;
|
|
1464
1464
|
lineEl.style.paddingLeft = `${Math.max(0, markerStart)}px`;
|
|
1465
1465
|
lineEl.style.textIndent = "0";
|
|
1466
|
-
|
|
1467
|
-
if (!block.attrs.listMarkerFontFamily || !block.attrs.listMarkerFontSize || block.attrs.listMarkerBold === void 0) for (let ri = line.fromRun; ri <= line.toRun; ri++) {
|
|
1468
|
-
const r = block.runs[ri];
|
|
1469
|
-
if (r && r.kind === "text") {
|
|
1470
|
-
firstTextRun = r;
|
|
1471
|
-
break;
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
const markerFontFamily = block.attrs.listMarkerFontFamily ?? firstTextRun?.fontFamily ?? block.attrs.defaultFontFamily;
|
|
1475
|
-
const markerFontSize = block.attrs.listMarkerFontSize ?? firstTextRun?.fontSize ?? block.attrs.defaultFontSize;
|
|
1476
|
-
const markerBold = block.attrs.listMarkerBold ?? firstTextRun?.bold;
|
|
1477
|
-
const marker = renderListMarker(block.attrs.listMarker, getListMarkerInlineWidth(block), getListMarkerVisualOffset(block), doc, markerFontFamily, markerFontSize, markerBold, block.attrs.listMarkerRevision, block.attrs.listMarkerSecondSlotOffsetTwips);
|
|
1466
|
+
const marker = renderListMarker(block.attrs.listMarker, getListMarkerInlineWidth(block), getListMarkerVisualOffset(block), doc, resolveListMarkerFont(block), block.attrs.listMarkerRevision, block.attrs.listMarkerSecondSlotOffsetTwips);
|
|
1478
1467
|
const markerMarginLeft = markerStart - Math.min(indentLeft, 0);
|
|
1479
1468
|
if (markerMarginLeft < 0) marker.style.marginLeft = `${markerMarginLeft}px`;
|
|
1480
1469
|
lineEl.prepend(marker);
|
|
@@ -1491,13 +1480,15 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1491
1480
|
* tab grid. Long markers like "1.1.1." therefore grow to the next stop
|
|
1492
1481
|
* instead of butting against the body text.
|
|
1493
1482
|
*/
|
|
1494
|
-
function renderListMarker(marker, inlineWidth, visualOffset, doc,
|
|
1483
|
+
function renderListMarker(marker, inlineWidth, visualOffset, doc, formatting, revision, secondSlotOffsetTwips) {
|
|
1495
1484
|
const span = doc.createElement("span");
|
|
1496
1485
|
span.className = "layout-list-marker";
|
|
1497
1486
|
span.style.display = "inline-block";
|
|
1498
|
-
|
|
1499
|
-
if (fontSize) span.style.fontSize = `${fontSize * 96 / 72}px`;
|
|
1500
|
-
if (bold !== void 0) span.style.fontWeight = bold ? "700" : "normal";
|
|
1487
|
+
span.style.fontFamily = resolveFontFamily(formatting.fontFamily).cssFallback;
|
|
1488
|
+
if (formatting.fontSize) span.style.fontSize = `${formatting.fontSize * 96 / 72}px`;
|
|
1489
|
+
if (formatting.bold !== void 0) span.style.fontWeight = formatting.bold ? "700" : "normal";
|
|
1490
|
+
if (formatting.italic !== void 0) span.style.fontStyle = formatting.italic ? "italic" : "normal";
|
|
1491
|
+
if (formatting.rtl !== void 0) span.dir = formatting.rtl ? "rtl" : "ltr";
|
|
1501
1492
|
span.style.textAlign = "left";
|
|
1502
1493
|
span.style.textAlignLast = "left";
|
|
1503
1494
|
span.style.boxSizing = "border-box";
|
|
@@ -162,9 +162,7 @@ const readParagraphAttrs = (node) => {
|
|
|
162
162
|
optionalBoolean(attrs, "listIsLegal", "paragraph.attrs.listIsLegal", issues);
|
|
163
163
|
optionalString(attrs, "listMarker", "paragraph.attrs.listMarker", issues);
|
|
164
164
|
optionalBoolean(attrs, "listMarkerHidden", "paragraph.attrs.listMarkerHidden", issues);
|
|
165
|
-
|
|
166
|
-
optionalNumber(attrs, "listMarkerFontSize", "paragraph.attrs.listMarkerFontSize", issues);
|
|
167
|
-
optionalBoolean(attrs, "listMarkerBold", "paragraph.attrs.listMarkerBold", issues);
|
|
165
|
+
optionalTextFormatting(attrs, "listMarkerFormatting", "paragraph.attrs.listMarkerFormatting", issues);
|
|
168
166
|
optionalOneOf(attrs, "listMarkerAlignment", "paragraph.attrs.listMarkerAlignment", issues, [
|
|
169
167
|
"left",
|
|
170
168
|
"center",
|
|
@@ -1397,12 +1395,10 @@ const validateParagraphFormatting = (value, path, issues) => {
|
|
|
1397
1395
|
"listIsBullet",
|
|
1398
1396
|
"listIsLegal",
|
|
1399
1397
|
"listMarkerHidden",
|
|
1400
|
-
"listMarkerBold",
|
|
1401
1398
|
"listMarkerAllCaps"
|
|
1402
1399
|
]) optionalBoolean(value, key, `${path}.${key}`, issues);
|
|
1403
1400
|
for (const key of PARAGRAPH_FORMATTING_NUMBER_KEYS) optionalNumber(value, key, `${path}.${key}`, issues);
|
|
1404
1401
|
for (const key of [
|
|
1405
|
-
"listMarkerFontSize",
|
|
1406
1402
|
"listImplicitChildLevelAdvances",
|
|
1407
1403
|
"listMarkerSecondSlotOffsetTwips",
|
|
1408
1404
|
"listAbstractNumId",
|
|
@@ -1412,7 +1408,7 @@ const validateParagraphFormatting = (value, path, issues) => {
|
|
|
1412
1408
|
optionalString(value, "styleId", `${path}.styleId`, issues);
|
|
1413
1409
|
optionalOneOf(value, "listNumFmt", `${path}.listNumFmt`, issues, NUMBER_FORMAT_VALUES);
|
|
1414
1410
|
optionalString(value, "listMarker", `${path}.listMarker`, issues);
|
|
1415
|
-
|
|
1411
|
+
optionalTextFormatting(value, "listMarkerFormatting", `${path}.listMarkerFormatting`, issues);
|
|
1416
1412
|
optionalOneOf(value, "listMarkerAlignment", `${path}.listMarkerAlignment`, issues, [
|
|
1417
1413
|
"left",
|
|
1418
1414
|
"center",
|
|
@@ -421,9 +421,7 @@ function listRenderingFromAttrs(attrs) {
|
|
|
421
421
|
...attrs.listIsLegal != null && { isLegal: attrs.listIsLegal },
|
|
422
422
|
...attrs.listNumFmt != null && { numFmt: attrs.listNumFmt },
|
|
423
423
|
...attrs.listMarkerHidden != null && { markerHidden: attrs.listMarkerHidden },
|
|
424
|
-
...attrs.
|
|
425
|
-
...attrs.listMarkerFontSize != null && { markerFontSize: attrs.listMarkerFontSize },
|
|
426
|
-
...attrs.listMarkerBold != null && { markerBold: attrs.listMarkerBold },
|
|
424
|
+
...attrs.listMarkerFormatting != null && { markerFormatting: attrs.listMarkerFormatting },
|
|
427
425
|
...attrs.listMarkerAlignment != null && { markerAlignment: attrs.listMarkerAlignment },
|
|
428
426
|
...attrs.listMarkerSuffix != null && { markerSuffix: attrs.listMarkerSuffix },
|
|
429
427
|
...attrs.listMarkerAllCaps != null && { markerAllCaps: attrs.listMarkerAllCaps },
|
|
@@ -290,9 +290,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
290
290
|
if (paragraph.listRendering?.isLegal) attrs.listIsLegal = paragraph.listRendering.isLegal;
|
|
291
291
|
if (paragraph.listRendering?.marker) attrs.listMarker = paragraph.listRendering.marker;
|
|
292
292
|
if (paragraph.listRendering?.markerHidden) attrs.listMarkerHidden = paragraph.listRendering.markerHidden;
|
|
293
|
-
if (paragraph.listRendering?.
|
|
294
|
-
if (paragraph.listRendering?.markerFontSize) attrs.listMarkerFontSize = paragraph.listRendering.markerFontSize;
|
|
295
|
-
if (paragraph.listRendering?.markerBold !== void 0) attrs.listMarkerBold = paragraph.listRendering.markerBold;
|
|
293
|
+
if (paragraph.listRendering?.markerFormatting) attrs.listMarkerFormatting = paragraph.listRendering.markerFormatting;
|
|
296
294
|
if (paragraph.listRendering?.markerAlignment) attrs.listMarkerAlignment = paragraph.listRendering.markerAlignment;
|
|
297
295
|
if (paragraph.listRendering?.markerSuffix) attrs.listMarkerSuffix = paragraph.listRendering.markerSuffix;
|
|
298
296
|
if (paragraph.listRendering?.markerAllCaps) attrs.listMarkerAllCaps = paragraph.listRendering.markerAllCaps;
|
|
@@ -204,9 +204,7 @@ const paragraphNodeSpec = {
|
|
|
204
204
|
listIsLegal: { default: null },
|
|
205
205
|
listMarker: { default: null },
|
|
206
206
|
listMarkerHidden: { default: null },
|
|
207
|
-
|
|
208
|
-
listMarkerFontSize: { default: null },
|
|
209
|
-
listMarkerBold: { default: null },
|
|
207
|
+
listMarkerFormatting: { default: null },
|
|
210
208
|
listMarkerAlignment: { default: null },
|
|
211
209
|
listMarkerSuffix: { default: null },
|
|
212
210
|
listMarkerAllCaps: { default: null },
|
|
@@ -32,9 +32,7 @@ const LIST_FORMATTING_ATTRS = [
|
|
|
32
32
|
"listNumFmt",
|
|
33
33
|
"listMarker",
|
|
34
34
|
"listMarkerHidden",
|
|
35
|
-
"
|
|
36
|
-
"listMarkerFontSize",
|
|
37
|
-
"listMarkerBold",
|
|
35
|
+
"listMarkerFormatting",
|
|
38
36
|
"listMarkerAlignment",
|
|
39
37
|
"listMarkerSuffix",
|
|
40
38
|
"listLevelNumFmts",
|
|
@@ -69,12 +69,8 @@ type ParagraphAttrs = {
|
|
|
69
69
|
listMarker?: string;
|
|
70
70
|
/** Whether the list marker is hidden (w:vanish on numbering level rPr) */
|
|
71
71
|
listMarkerHidden?: boolean;
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
/** Marker font size from numbering level rPr, in points */
|
|
75
|
-
listMarkerFontSize?: number;
|
|
76
|
-
/** Marker bold state from numbering level rPr */
|
|
77
|
-
listMarkerBold?: boolean;
|
|
72
|
+
/** Canonical numbering-level marker typography, in OOXML units. */
|
|
73
|
+
listMarkerFormatting?: document_d_exports.ListMarkerFormatting;
|
|
78
74
|
/** Horizontal alignment of the marker around the paragraph's list anchor. */
|
|
79
75
|
listMarkerAlignment?: "left" | "center" | "right";
|
|
80
76
|
/**
|
|
@@ -200,7 +196,7 @@ type ParagraphAttrs = {
|
|
|
200
196
|
type ParagraphPropertyChangeAttrs = Omit<document_d_exports.ParagraphPropertyChange, "previousFormatting" | "currentFormatting"> & {
|
|
201
197
|
previousFormatting?: Omit<document_d_exports.ParagraphFormatting, "numPr"> & {
|
|
202
198
|
numPr?: document_d_exports.ParagraphFormatting["numPr"] | null;
|
|
203
|
-
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerHidden" | "
|
|
199
|
+
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerHidden" | "listMarkerFormatting" | "listMarkerAlignment" | "listMarkerSuffix" | "listLevelNumFmts" | "listLevelStarts" | "listAbstractNumId" | "listStartOverride" | "lineSpacingExplicit" | "direction" | "_autospacingBase">>;
|
|
204
200
|
currentFormatting?: document_d_exports.ParagraphFormatting;
|
|
205
201
|
};
|
|
206
202
|
/**
|
|
@@ -86,9 +86,7 @@ function listAttrsFromResolvedStyle(resolved, numbering) {
|
|
|
86
86
|
listIsLegal: rendering?.isLegal ?? null,
|
|
87
87
|
listMarker: rendering?.marker ?? null,
|
|
88
88
|
listMarkerHidden: rendering?.markerHidden ?? null,
|
|
89
|
-
|
|
90
|
-
listMarkerFontSize: rendering?.markerFontSize ?? null,
|
|
91
|
-
listMarkerBold: rendering?.markerBold ?? null,
|
|
89
|
+
listMarkerFormatting: rendering?.markerFormatting ?? null,
|
|
92
90
|
listMarkerAlignment: rendering?.markerAlignment ?? null,
|
|
93
91
|
listMarkerSuffix: rendering?.markerSuffix ?? null,
|
|
94
92
|
listMarkerAllCaps: rendering?.markerAllCaps ?? null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"perf": "bun scripts/profile-editor.ts"
|
|
114
114
|
},
|
|
115
115
|
"dependencies": {
|
|
116
|
-
"@stll/docx-core": "^0.
|
|
116
|
+
"@stll/docx-core": "^0.16.0",
|
|
117
117
|
"@stll/docx-utils": "^0.1.0",
|
|
118
118
|
"@stll/template-conditions": "^0.1.0",
|
|
119
119
|
"better-result": "3.0.1",
|