@stll/folio-core 0.23.0 → 0.23.1
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/layoutPipeline.js +7 -3
- package/dist/docx/blockContentParser.js +2 -47
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +12 -4
- package/dist/docx/numberingParser.d.ts +2 -11
- package/dist/docx/numberingParser.js +3 -79
- package/dist/docx/ooxmlCounterFormatter.d.ts +8 -0
- package/dist/docx/ooxmlCounterFormatter.js +134 -0
- package/dist/docx/serializer/tableSerializer.js +1 -1
- package/dist/docx/tableParser.js +2 -1
- package/dist/fields/bookmarkPages.js +1 -1
- package/dist/fields/evaluateField.js +1 -1
- package/dist/fields/fieldContext.d.ts +2 -0
- package/dist/fields/resolveFieldValues.js +5 -2
- package/dist/layout-bridge/convert/headerFooterLayout.js +6 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +16 -48
- package/dist/layout-engine/index.d.ts +3 -2
- package/dist/layout-engine/index.js +40 -16
- package/dist/layout-engine/measure/cache.js +1 -1
- package/dist/layout-engine/measure/complexScriptFormatting.d.ts +18 -0
- package/dist/layout-engine/measure/complexScriptFormatting.js +11 -0
- package/dist/layout-engine/measure/measureContainer.js +31 -16
- package/dist/layout-engine/measure/measureHelpers.js +4 -0
- package/dist/layout-engine/measure/measureParagraph.js +13 -3
- package/dist/layout-engine/measure/measureTypes.d.ts +4 -0
- package/dist/layout-engine/paginator.d.ts +5 -3
- package/dist/layout-engine/paginator.js +34 -13
- package/dist/layout-engine/types.d.ts +31 -4
- package/dist/layout-painter/index.js +2 -1
- package/dist/layout-painter/renderPage.js +9 -3
- package/dist/layout-painter/renderParagraph.js +42 -25
- package/dist/layout-painter/renderUtils.d.ts +2 -0
- package/dist/paged-layout/sectionGeometry.d.ts +3 -2
- package/dist/paged-layout/sectionGeometry.js +17 -1
- package/dist/prosemirror/attrs/index.js +5 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +4 -16
- package/dist/prosemirror/conversion/toProseDoc.js +4 -1
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +3 -2
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +31 -17
- package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -0
- package/dist/prosemirror/schema/marks.d.ts +8 -0
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/package.json +1 -1
|
@@ -601,6 +601,7 @@ function renderFootnoteContent(footnote, contentWidth, doc, context) {
|
|
|
601
601
|
wrapper.style.height = `${content.height}px`;
|
|
602
602
|
const renderContext = {
|
|
603
603
|
pageNumber: context?.pageNumber ?? 0,
|
|
604
|
+
...context?.pageNumberFormat === void 0 ? {} : { pageNumberFormat: context.pageNumberFormat },
|
|
604
605
|
totalPages: context?.totalPages ?? 0,
|
|
605
606
|
section: context?.section ?? "body",
|
|
606
607
|
contentWidth
|
|
@@ -1133,8 +1134,7 @@ function applySectionHeaderFooterOptions(page, pageOptions, options) {
|
|
|
1133
1134
|
if (!refs) return false;
|
|
1134
1135
|
const isFirstSectionPage = page.sectionPageNumber === 1;
|
|
1135
1136
|
const useFirst = refs.titlePg === true && isFirstSectionPage;
|
|
1136
|
-
const
|
|
1137
|
-
const useEven = refs.evenAndOddHeaders === true && sectionPageNumber % 2 === 0;
|
|
1137
|
+
const useEven = refs.evenAndOddHeaders === true && page.logicalNumber % 2 === 0;
|
|
1138
1138
|
const headerRId = (() => {
|
|
1139
1139
|
if (useFirst) return refs.headerFirst;
|
|
1140
1140
|
if (useEven) return refs.headerEven;
|
|
@@ -1176,7 +1176,8 @@ function sectionPagesContext(page, counts) {
|
|
|
1176
1176
|
*/
|
|
1177
1177
|
function buildPageRenderArgs(page, totalPages, options) {
|
|
1178
1178
|
const context = {
|
|
1179
|
-
pageNumber: page.
|
|
1179
|
+
pageNumber: page.logicalNumber,
|
|
1180
|
+
...page.logicalNumberFormat === void 0 ? {} : { pageNumberFormat: page.logicalNumberFormat },
|
|
1180
1181
|
totalPages,
|
|
1181
1182
|
section: "body",
|
|
1182
1183
|
...options.bookmarkPages ? { bookmarkPages: options.bookmarkPages } : {},
|
|
@@ -1224,6 +1225,7 @@ function computePageFingerprintInternal(page, blockLookup, options) {
|
|
|
1224
1225
|
parts.push(`m:${pageMarginsFingerprint(page.margins)}`);
|
|
1225
1226
|
if (page.authoredMargins) parts.push(`am:${pageMarginsFingerprint(page.authoredMargins)}`);
|
|
1226
1227
|
parts.push(`n:${page.number}`);
|
|
1228
|
+
parts.push(`ln:${page.logicalNumber},${page.logicalNumberFormat ?? ""}`);
|
|
1227
1229
|
if (page.sectionIndex !== void 0) parts.push(`si:${page.sectionIndex}`);
|
|
1228
1230
|
if (page.sectionPageNumber !== void 0) parts.push(`sp:${page.sectionPageNumber}`);
|
|
1229
1231
|
if (page.headerFooterRefs) parts.push(`hf:${JSON.stringify(page.headerFooterRefs)}`);
|
|
@@ -1334,6 +1336,10 @@ function runContentKey(run) {
|
|
|
1334
1336
|
if (run.highlight) parts.push(`hi:${run.highlight}`);
|
|
1335
1337
|
if (run.fontFamily) parts.push(`ff:${run.fontFamily}`);
|
|
1336
1338
|
if (run.complexScriptFontFamily) parts.push(`cs:${run.complexScriptFontFamily}`);
|
|
1339
|
+
if (run.complexScriptFontSize !== void 0) parts.push(`cs-size:${run.complexScriptFontSize}`);
|
|
1340
|
+
if (run.complexScriptBold !== void 0) parts.push(`cs-bold:${run.complexScriptBold}`);
|
|
1341
|
+
if (run.complexScriptItalic !== void 0) parts.push(`cs-italic:${run.complexScriptItalic}`);
|
|
1342
|
+
if (run.forceComplexScript !== void 0) parts.push(`cs-force:${run.forceComplexScript}`);
|
|
1337
1343
|
if (run.eastAsiaFontFamily) parts.push(`ea:${run.eastAsiaFontFamily}`);
|
|
1338
1344
|
if (run.fontSize !== void 0) parts.push(`fs:${run.fontSize}`);
|
|
1339
1345
|
if (run.letterSpacing !== void 0) parts.push(`ls:${run.letterSpacing}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ommlToMathml } from "../docx/mathToMathml.js";
|
|
2
2
|
import { parseXmlDocument } from "../docx/xmlParser.js";
|
|
3
3
|
import { evaluateFieldInstruction } from "../fields/evaluateField.js";
|
|
4
|
+
import { hasComplexScriptFormatting, resolveComplexScriptFormatting } from "../layout-engine/measure/complexScriptFormatting.js";
|
|
4
5
|
import { getListMarkerInlineWidth, getListMarkerVisualOffset } from "../layout-engine/measure/listMarkerWidth.js";
|
|
5
6
|
import { DOCX_SCRIPT_FONT_SCALE } from "../layout-engine/measure/measureHelpers.js";
|
|
6
7
|
import { FONT_KERNING_MODE, countCompressibleSpaces, getFontKerningMode, getRunFontKerningMode, toPaintedText } from "../layout-engine/measure/textMeasurementPolicy.js";
|
|
@@ -571,6 +572,7 @@ function resolveFieldText(run, context) {
|
|
|
571
572
|
if (!context) return fallback;
|
|
572
573
|
const fieldContext = {
|
|
573
574
|
pageNumber: context.pageNumber,
|
|
575
|
+
...context.pageNumberFormat === void 0 ? {} : { pageNumberFormat: context.pageNumberFormat },
|
|
574
576
|
totalPages: context.totalPages,
|
|
575
577
|
bookmarkPages: context.bookmarkPages ?? EMPTY_BOOKMARK_PAGES,
|
|
576
578
|
bookmarkText: context.bookmarkText ?? EMPTY_BOOKMARK_TEXT,
|
|
@@ -591,6 +593,10 @@ function renderFieldRun(run, doc, context) {
|
|
|
591
593
|
kind: "text",
|
|
592
594
|
text
|
|
593
595
|
};
|
|
596
|
+
if (resolvedRun.forceComplexScript && hasComplexScriptFormatting(resolvedRun)) return renderTextRun({
|
|
597
|
+
...resolvedRun,
|
|
598
|
+
...resolveComplexScriptFormatting(resolvedRun)
|
|
599
|
+
}, doc);
|
|
594
600
|
if (needsPerScriptSpans({
|
|
595
601
|
...resolvedRun,
|
|
596
602
|
text
|
|
@@ -607,7 +613,7 @@ function renderFieldRun(run, doc, context) {
|
|
|
607
613
|
const segmentRun = {
|
|
608
614
|
...segmentBase,
|
|
609
615
|
text: segment.text,
|
|
610
|
-
...
|
|
616
|
+
...scriptFormattingOverride(resolvedRun, segment.script)
|
|
611
617
|
};
|
|
612
618
|
wrapper.append(renderTextRun(segmentRun, doc));
|
|
613
619
|
}
|
|
@@ -725,9 +731,9 @@ function sliceRunsForLine(block, line) {
|
|
|
725
731
|
* The font a script segment paints with, mirroring the measurer's
|
|
726
732
|
* `scriptFontFamily`. Returning undefined leaves the run's own `fontFamily`.
|
|
727
733
|
*/
|
|
728
|
-
const
|
|
734
|
+
const scriptFormattingOverride = (run, script) => {
|
|
735
|
+
if (run.forceComplexScript || script === SCRIPT_CLASS.complex) return resolveComplexScriptFormatting(run);
|
|
729
736
|
if (script === SCRIPT_CLASS.eastAsia && run.eastAsiaFontFamily !== void 0) return { fontFamily: run.eastAsiaFontFamily };
|
|
730
|
-
if (script === SCRIPT_CLASS.complex && run.complexScriptFontFamily !== void 0) return { fontFamily: run.complexScriptFontFamily };
|
|
731
737
|
return {};
|
|
732
738
|
};
|
|
733
739
|
/**
|
|
@@ -739,7 +745,7 @@ const scriptFontOverride = (run, script) => {
|
|
|
739
745
|
const needsPerScriptSpans = (run) => {
|
|
740
746
|
if (run.letterSpacing) return false;
|
|
741
747
|
if (run.eastAsiaFontFamily !== void 0 && hasCjk(run.text)) return true;
|
|
742
|
-
return run
|
|
748
|
+
return hasComplexScriptFormatting(run) && hasComplexScript(run.text);
|
|
743
749
|
};
|
|
744
750
|
/**
|
|
745
751
|
* Split each text run carrying an East-Asian font into per-script sub-runs, so
|
|
@@ -753,6 +759,13 @@ const needsPerScriptSpans = (run) => {
|
|
|
753
759
|
function splitTextRunsByEastAsia(runs) {
|
|
754
760
|
const result = [];
|
|
755
761
|
for (const run of runs) {
|
|
762
|
+
if (isTextRun(run) && run.forceComplexScript && hasComplexScriptFormatting(run)) {
|
|
763
|
+
result.push({
|
|
764
|
+
...run,
|
|
765
|
+
...resolveComplexScriptFormatting(run)
|
|
766
|
+
});
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
756
769
|
if (!isTextRun(run) || !needsPerScriptSpans(run)) {
|
|
757
770
|
result.push(run);
|
|
758
771
|
continue;
|
|
@@ -762,7 +775,7 @@ function splitTextRunsByEastAsia(runs) {
|
|
|
762
775
|
result.push({
|
|
763
776
|
...run,
|
|
764
777
|
text: segment.text,
|
|
765
|
-
...
|
|
778
|
+
...scriptFormattingOverride(run, segment.script),
|
|
766
779
|
...run.pmStart !== void 0 ? {
|
|
767
780
|
pmStart: run.pmStart + offset,
|
|
768
781
|
pmEnd: run.pmStart + offset + segment.text.length
|
|
@@ -866,6 +879,10 @@ function runMeasureStyle(run) {
|
|
|
866
879
|
...run.smallCaps !== void 0 ? { smallCaps: run.smallCaps } : {},
|
|
867
880
|
...run.eastAsiaFontFamily !== void 0 ? { eastAsiaFontFamily: run.eastAsiaFontFamily } : {},
|
|
868
881
|
...run.complexScriptFontFamily !== void 0 ? { complexScriptFontFamily: run.complexScriptFontFamily } : {},
|
|
882
|
+
...run.complexScriptFontSize !== void 0 ? { complexScriptFontSize: run.complexScriptFontSize } : {},
|
|
883
|
+
...run.complexScriptBold !== void 0 ? { complexScriptBold: run.complexScriptBold } : {},
|
|
884
|
+
...run.complexScriptItalic !== void 0 ? { complexScriptItalic: run.complexScriptItalic } : {},
|
|
885
|
+
...run.forceComplexScript !== void 0 ? { forceComplexScript: run.forceComplexScript } : {},
|
|
869
886
|
kerning: getRunFontKerningMode(run, 11) === FONT_KERNING_MODE.enabled
|
|
870
887
|
};
|
|
871
888
|
}
|
|
@@ -972,27 +989,32 @@ function createTextMeasurer(doc) {
|
|
|
972
989
|
return (text, fontSize = 11, fontFamily = "Calibri", style = {}) => {
|
|
973
990
|
if (!ctx) return applyLetterSpacingToMeasuredWidth(text.length * 7, text, style.letterSpacing);
|
|
974
991
|
ctx.fontKerning = getFontKerningMode(style);
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
const fontPrefix = fontPrefixParts.join(" ");
|
|
983
|
-
const perScriptFallback = {
|
|
984
|
-
...style.eastAsiaFontFamily ? { [SCRIPT_CLASS.eastAsia]: resolveFontFamily(style.eastAsiaFontFamily).cssFallback } : {},
|
|
985
|
-
...style.complexScriptFontFamily ? { [SCRIPT_CLASS.complex]: resolveFontFamily(style.complexScriptFontFamily).cssFallback } : {}
|
|
992
|
+
const fontString = (family, size, bold, italic) => {
|
|
993
|
+
const fontPrefixParts = [];
|
|
994
|
+
if (italic) fontPrefixParts.push("italic");
|
|
995
|
+
if (style.smallCaps) fontPrefixParts.push("small-caps");
|
|
996
|
+
if (bold) fontPrefixParts.push("700");
|
|
997
|
+
fontPrefixParts.push(`${size * 96 / 72}px`);
|
|
998
|
+
return `${fontPrefixParts.join(" ")} ${resolveFontFamily(family).cssFallback}`;
|
|
986
999
|
};
|
|
987
|
-
|
|
1000
|
+
const baseFont = fontString(fontFamily, fontSize, style.bold, style.italic);
|
|
1001
|
+
const complex = resolveComplexScriptFormatting(style);
|
|
1002
|
+
const complexFont = fontString(complex.fontFamily ?? fontFamily, complex.fontSize ?? fontSize, complex.bold ?? style.bold, complex.italic ?? style.italic);
|
|
1003
|
+
if (style.forceComplexScript) {
|
|
1004
|
+
ctx.font = complexFont;
|
|
1005
|
+
return applyLetterSpacingToMeasuredWidth(ctx.measureText(text).width, text, style.letterSpacing);
|
|
1006
|
+
}
|
|
1007
|
+
if (!style.letterSpacing && (style.eastAsiaFontFamily && hasCjk(text) || hasComplexScriptFormatting(style) && hasComplexScript(text))) {
|
|
988
1008
|
let segmentedWidth = 0;
|
|
989
1009
|
for (const segment of segmentByScript(text)) {
|
|
990
|
-
ctx.font =
|
|
1010
|
+
if (segment.script === SCRIPT_CLASS.eastAsia && style.eastAsiaFontFamily) ctx.font = fontString(style.eastAsiaFontFamily, fontSize, style.bold, style.italic);
|
|
1011
|
+
else if (segment.script === SCRIPT_CLASS.complex) ctx.font = complexFont;
|
|
1012
|
+
else ctx.font = baseFont;
|
|
991
1013
|
segmentedWidth += ctx.measureText(segment.text).width;
|
|
992
1014
|
}
|
|
993
1015
|
return segmentedWidth;
|
|
994
1016
|
}
|
|
995
|
-
ctx.font =
|
|
1017
|
+
ctx.font = baseFont;
|
|
996
1018
|
return applyLetterSpacingToMeasuredWidth(ctx.measureText(text).width, text, style.letterSpacing);
|
|
997
1019
|
};
|
|
998
1020
|
}
|
|
@@ -1180,12 +1202,7 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
1180
1202
|
if (!measureText) continue;
|
|
1181
1203
|
const fontSize = run.fontSize || 11;
|
|
1182
1204
|
const fontFamily = run.fontFamily || "Calibri";
|
|
1183
|
-
const measuredWidth = measureText(run.allCaps ? run.text.toLocaleUpperCase() : run.text, fontSize, fontFamily,
|
|
1184
|
-
...run.bold !== void 0 ? { bold: run.bold } : {},
|
|
1185
|
-
...run.italic !== void 0 ? { italic: run.italic } : {},
|
|
1186
|
-
...run.letterSpacing !== void 0 ? { letterSpacing: run.letterSpacing } : {},
|
|
1187
|
-
...run.smallCaps !== void 0 ? { smallCaps: run.smallCaps } : {}
|
|
1188
|
-
});
|
|
1205
|
+
const measuredWidth = measureText(run.allCaps ? run.text.toLocaleUpperCase() : run.text, fontSize, fontFamily, runMeasureStyle(run));
|
|
1189
1206
|
reserveScaledAdvance(runEl, measuredWidth, run.horizontalScale);
|
|
1190
1207
|
currentX += measuredWidth * ((run.horizontalScale ?? 100) / 100);
|
|
1191
1208
|
} else if (isImageRun(run)) {
|
|
@@ -16,6 +16,8 @@ declare function resolveImageLineAlign(imageRun: ImageRun, paragraphAlignment: "
|
|
|
16
16
|
type RenderContext = {
|
|
17
17
|
/** Current page number (1-indexed) */
|
|
18
18
|
pageNumber: number;
|
|
19
|
+
/** OOXML section-level format for the current logical page number. */
|
|
20
|
+
pageNumberFormat?: string;
|
|
19
21
|
/** Total number of pages */
|
|
20
22
|
totalPages: number;
|
|
21
23
|
/** Which section is being rendered */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
-
import { PageMargins } from "../layout-engine/types.js";
|
|
2
|
+
import { PageMargins, SectionPageNumbering } from "../layout-engine/types.js";
|
|
3
3
|
//#region src/paged-layout/sectionGeometry.d.ts
|
|
4
4
|
declare const DEFAULT_PAGE_WIDTH_PX = 816;
|
|
5
5
|
declare const DEFAULT_PAGE_HEIGHT_PX = 1056;
|
|
@@ -16,5 +16,6 @@ declare const getPageSize: (sectionProps: document_d_exports.SectionProperties |
|
|
|
16
16
|
h: number;
|
|
17
17
|
};
|
|
18
18
|
declare const getMargins: (sectionProps: document_d_exports.SectionProperties | null | undefined) => PageMargins;
|
|
19
|
+
declare const getPageNumbering: (sectionProps: document_d_exports.SectionProperties | null | undefined) => SectionPageNumbering;
|
|
19
20
|
//#endregion
|
|
20
|
-
export { DEFAULT_BODY_MARGIN_PX, DEFAULT_HEADER_FOOTER_DISTANCE_PX, DEFAULT_PAGE_HEIGHT_PX, DEFAULT_PAGE_WIDTH_PX, getMargins, getPageSize, twipsToPixels, twipsToPxOr };
|
|
21
|
+
export { DEFAULT_BODY_MARGIN_PX, DEFAULT_HEADER_FOOTER_DISTANCE_PX, DEFAULT_PAGE_HEIGHT_PX, DEFAULT_PAGE_WIDTH_PX, getMargins, getPageNumbering, getPageSize, twipsToPixels, twipsToPxOr };
|
|
@@ -32,5 +32,21 @@ const getMargins = (sectionProps) => ({
|
|
|
32
32
|
header: twipsToPxOr(sectionProps?.headerDistance, 48),
|
|
33
33
|
footer: twipsToPxOr(sectionProps?.footerDistance, 48)
|
|
34
34
|
});
|
|
35
|
+
const getPageNumbering = (sectionProps) => {
|
|
36
|
+
const pageNumbering = sectionProps?.pageNumbering;
|
|
37
|
+
const format = pageNumbering?.format;
|
|
38
|
+
if (pageNumbering?.start === void 0) return format === void 0 ? { type: "continue" } : {
|
|
39
|
+
type: "continue",
|
|
40
|
+
format
|
|
41
|
+
};
|
|
42
|
+
return format === void 0 ? {
|
|
43
|
+
type: "restart",
|
|
44
|
+
start: pageNumbering.start
|
|
45
|
+
} : {
|
|
46
|
+
type: "restart",
|
|
47
|
+
start: pageNumbering.start,
|
|
48
|
+
format
|
|
49
|
+
};
|
|
50
|
+
};
|
|
35
51
|
//#endregion
|
|
36
|
-
export { DEFAULT_BODY_MARGIN_PX, DEFAULT_HEADER_FOOTER_DISTANCE_PX, DEFAULT_PAGE_HEIGHT_PX, DEFAULT_PAGE_WIDTH_PX, getMargins, getPageSize, twipsToPixels, twipsToPxOr };
|
|
52
|
+
export { DEFAULT_BODY_MARGIN_PX, DEFAULT_HEADER_FOOTER_DISTANCE_PX, DEFAULT_PAGE_HEIGHT_PX, DEFAULT_PAGE_WIDTH_PX, getMargins, getPageNumbering, getPageSize, twipsToPixels, twipsToPxOr };
|
|
@@ -276,6 +276,7 @@ const readTableAttrs = (node) => {
|
|
|
276
276
|
"insideH",
|
|
277
277
|
"insideV"
|
|
278
278
|
]);
|
|
279
|
+
optionalBoolean(attrs, "_resolvedBidi", "table.attrs._resolvedBidi", issues);
|
|
279
280
|
optionalRecord(attrs, "_originalFormatting", "table.attrs._originalFormatting", issues);
|
|
280
281
|
return attrsResult(attrs, issues);
|
|
281
282
|
};
|
|
@@ -651,6 +652,10 @@ const readRunFormattingOverrideMarkAttrs = (mark) => {
|
|
|
651
652
|
const issues = [];
|
|
652
653
|
expectMarkType(mark, "runFormattingOverride", issues);
|
|
653
654
|
for (const key of RUN_FORMATTING_OVERRIDE_FALSE_KEYS) optionalFalse(attrs, key, `runFormattingOverride.attrs.${key}`, issues);
|
|
655
|
+
optionalBoolean(attrs, "boldCs", "runFormattingOverride.attrs.boldCs", issues);
|
|
656
|
+
optionalBoolean(attrs, "italicCs", "runFormattingOverride.attrs.italicCs", issues);
|
|
657
|
+
optionalNumber(attrs, "fontSizeCs", "runFormattingOverride.attrs.fontSizeCs", issues);
|
|
658
|
+
optionalBoolean(attrs, "cs", "runFormattingOverride.attrs.cs", issues);
|
|
654
659
|
optionalOneOf(attrs, "underline", "runFormattingOverride.attrs.underline", issues, ["none"]);
|
|
655
660
|
return attrsResult(attrs, issues);
|
|
656
661
|
};
|
|
@@ -4,6 +4,7 @@ import { OUTLINE_STYLE_CSS_ALIASES } from "../../types/documentEnumValues.js";
|
|
|
4
4
|
import { pixelsToEmu } from "../../utils/units.js";
|
|
5
5
|
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
6
6
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
7
|
+
import { applyRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
7
8
|
import { directionToBidi } from "../paragraphDirection.js";
|
|
8
9
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
9
10
|
import { expectTextBoxAnchorAttrs } from "../textBoxAnchorAttrs.js";
|
|
@@ -1341,6 +1342,7 @@ function createShapeRun(node) {
|
|
|
1341
1342
|
function marksToTextFormatting(marks) {
|
|
1342
1343
|
const formatting = {};
|
|
1343
1344
|
let characterStyleRPr;
|
|
1345
|
+
let runFormattingOverrideMark;
|
|
1344
1346
|
for (const mark of marks) switch (mark.type.name) {
|
|
1345
1347
|
case "bold":
|
|
1346
1348
|
formatting.bold = true;
|
|
@@ -1453,7 +1455,7 @@ function marksToTextFormatting(marks) {
|
|
|
1453
1455
|
formatting.effect = expectTextEffectMarkAttrs(mark).effect;
|
|
1454
1456
|
break;
|
|
1455
1457
|
case "runFormattingOverride":
|
|
1456
|
-
|
|
1458
|
+
runFormattingOverrideMark = mark;
|
|
1457
1459
|
break;
|
|
1458
1460
|
case "characterStyle": {
|
|
1459
1461
|
const attrs = expectCharacterStyleMarkAttrs(mark);
|
|
@@ -1463,6 +1465,7 @@ function marksToTextFormatting(marks) {
|
|
|
1463
1465
|
}
|
|
1464
1466
|
default: break;
|
|
1465
1467
|
}
|
|
1468
|
+
if (runFormattingOverrideMark) applyRunFormattingOverrideAttrs(formatting, expectRunFormattingOverrideMarkAttrs(runFormattingOverrideMark));
|
|
1466
1469
|
if (characterStyleRPr) return subtractCharacterStyleFormatting(formatting, characterStyleRPr);
|
|
1467
1470
|
return formatting;
|
|
1468
1471
|
}
|
|
@@ -1522,21 +1525,6 @@ function subtractCharacterStyleFormatting(formatting, styleRPr) {
|
|
|
1522
1525
|
}
|
|
1523
1526
|
return result;
|
|
1524
1527
|
}
|
|
1525
|
-
function applyRunFormattingOverrideAttrs(formatting, attrs) {
|
|
1526
|
-
if (attrs.bold === false) formatting.bold = false;
|
|
1527
|
-
if (attrs.italic === false) formatting.italic = false;
|
|
1528
|
-
if (attrs.underline === "none") formatting.underline = { style: "none" };
|
|
1529
|
-
if (attrs.strike === false) formatting.strike = false;
|
|
1530
|
-
if (attrs.doubleStrike === false) formatting.doubleStrike = false;
|
|
1531
|
-
if (attrs.allCaps === false) formatting.allCaps = false;
|
|
1532
|
-
if (attrs.smallCaps === false) formatting.smallCaps = false;
|
|
1533
|
-
if (attrs.hidden === false) formatting.hidden = false;
|
|
1534
|
-
if (attrs.emboss === false) formatting.emboss = false;
|
|
1535
|
-
if (attrs.imprint === false) formatting.imprint = false;
|
|
1536
|
-
if (attrs.shadow === false) formatting.shadow = false;
|
|
1537
|
-
if (attrs.outline === false) formatting.outline = false;
|
|
1538
|
-
if (attrs.rtl === false) formatting.rtl = false;
|
|
1539
|
-
}
|
|
1540
1528
|
/**
|
|
1541
1529
|
* Convert a ProseMirror table node to our Table type
|
|
1542
1530
|
*/
|
|
@@ -645,7 +645,9 @@ function convertTable(table, styleResolver, context) {
|
|
|
645
645
|
const fallbackTableStyle = tableStyleId ? void 0 : defaultTableStyle;
|
|
646
646
|
const conditionalTableStyleId = tableStyle?.styleId ?? fallbackTableStyle?.styleId;
|
|
647
647
|
const resolvedTableBorders = table.formatting?.borders ?? tableStyle?.tblPr?.borders ?? fallbackTableStyle?.tblPr?.borders;
|
|
648
|
-
const
|
|
648
|
+
const fallbackTableIndent = fallbackTableStyle?.tblPr?.indent;
|
|
649
|
+
const resolvedTableIndent = table.formatting?.indent ?? tableStyle?.tblPr?.indent ?? (fallbackTableIndent?.value === 0 ? void 0 : fallbackTableIndent);
|
|
650
|
+
const resolvedTableBidi = table.formatting?.bidi ?? tableStyle?.tblPr?.bidi ?? fallbackTableStyle?.tblPr?.bidi;
|
|
649
651
|
const tableCellMargins = table.formatting?.cellMargins ?? tableStyle?.tblPr?.cellMargins ?? fallbackTableStyle?.tblPr?.cellMargins;
|
|
650
652
|
let cellMarginsAttr;
|
|
651
653
|
if (tableCellMargins) {
|
|
@@ -667,6 +669,7 @@ function convertTable(table, styleResolver, context) {
|
|
|
667
669
|
if (table.formatting?.look) attrs.look = table.formatting.look;
|
|
668
670
|
if (table.formatting?.borders) attrs.borders = table.formatting.borders;
|
|
669
671
|
if (resolvedTableIndent) attrs._resolvedIndent = resolvedTableIndent;
|
|
672
|
+
if (resolvedTableBidi !== void 0) attrs._resolvedBidi = resolvedTableBidi;
|
|
670
673
|
if (table.formatting) attrs._originalFormatting = table.formatting;
|
|
671
674
|
if (table.propertyChanges && table.propertyChanges.length > 0) attrs.tblPrChange = [...table.propertyChanges];
|
|
672
675
|
const conditionalStyles = {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { document_d_exports } from "../../../types/document.js";
|
|
2
|
+
import { RunFormattingOverrideAttrs } from "../../schema/marks.js";
|
|
2
3
|
import { MarkExtension } from "../types.js";
|
|
3
4
|
import { Mark } from "prosemirror-model";
|
|
4
5
|
//#region src/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts
|
|
5
|
-
type RunFormattingOverrideAttrs = Record<string, false | "none">;
|
|
6
6
|
declare function buildRunFormattingOverrideAttrs(formatting: document_d_exports.TextFormatting | undefined): RunFormattingOverrideAttrs | undefined;
|
|
7
|
+
declare function applyRunFormattingOverrideAttrs(formatting: document_d_exports.TextFormatting, attrs: RunFormattingOverrideAttrs): void;
|
|
7
8
|
declare function applyRunFormattingOverrideMark(formatting: document_d_exports.TextFormatting, mark: Mark): void;
|
|
8
9
|
declare const RunFormattingOverrideExtension: (options?: Partial<Record<string, unknown>> | undefined) => MarkExtension;
|
|
9
10
|
//#endregion
|
|
10
|
-
export { RunFormattingOverrideExtension, applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs };
|
|
11
|
+
export { RunFormattingOverrideExtension, applyRunFormattingOverrideAttrs, applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs };
|
|
@@ -4,23 +4,26 @@ import { createMarkExtension } from "../create.js";
|
|
|
4
4
|
function buildRunFormattingOverrideAttrs(formatting) {
|
|
5
5
|
if (!formatting) return;
|
|
6
6
|
const attrs = {};
|
|
7
|
-
if (formatting.bold === false) attrs
|
|
8
|
-
if (formatting.italic === false) attrs
|
|
9
|
-
if (formatting.underline?.style === "none") attrs
|
|
10
|
-
if (formatting.strike === false) attrs
|
|
11
|
-
if (formatting.doubleStrike === false) attrs
|
|
12
|
-
if (formatting.allCaps === false) attrs
|
|
13
|
-
if (formatting.smallCaps === false) attrs
|
|
14
|
-
if (formatting.hidden === false) attrs
|
|
15
|
-
if (formatting.emboss === false) attrs
|
|
16
|
-
if (formatting.imprint === false) attrs
|
|
17
|
-
if (formatting.shadow === false) attrs
|
|
18
|
-
if (formatting.outline === false) attrs
|
|
19
|
-
if (formatting.rtl === false) attrs
|
|
7
|
+
if (formatting.bold === false) attrs.bold = false;
|
|
8
|
+
if (formatting.italic === false) attrs.italic = false;
|
|
9
|
+
if (formatting.underline?.style === "none") attrs.underline = "none";
|
|
10
|
+
if (formatting.strike === false) attrs.strike = false;
|
|
11
|
+
if (formatting.doubleStrike === false) attrs.doubleStrike = false;
|
|
12
|
+
if (formatting.allCaps === false) attrs.allCaps = false;
|
|
13
|
+
if (formatting.smallCaps === false) attrs.smallCaps = false;
|
|
14
|
+
if (formatting.hidden === false) attrs.hidden = false;
|
|
15
|
+
if (formatting.emboss === false) attrs.emboss = false;
|
|
16
|
+
if (formatting.imprint === false) attrs.imprint = false;
|
|
17
|
+
if (formatting.shadow === false) attrs.shadow = false;
|
|
18
|
+
if (formatting.outline === false) attrs.outline = false;
|
|
19
|
+
if (formatting.rtl === false) attrs.rtl = false;
|
|
20
|
+
if (formatting.boldCs !== void 0 && formatting.boldCs !== formatting.bold) attrs.boldCs = formatting.boldCs;
|
|
21
|
+
if (formatting.italicCs !== void 0 && formatting.italicCs !== formatting.italic) attrs.italicCs = formatting.italicCs;
|
|
22
|
+
if (formatting.fontSizeCs !== void 0 && formatting.fontSizeCs !== formatting.fontSize) attrs.fontSizeCs = formatting.fontSizeCs;
|
|
23
|
+
if (formatting.cs !== void 0) attrs.cs = formatting.cs;
|
|
20
24
|
return Object.keys(attrs).length > 0 ? attrs : void 0;
|
|
21
25
|
}
|
|
22
|
-
function
|
|
23
|
-
const attrs = expectRunFormattingOverrideMarkAttrs(mark);
|
|
26
|
+
function applyRunFormattingOverrideAttrs(formatting, attrs) {
|
|
24
27
|
if (attrs.bold === false) formatting.bold = false;
|
|
25
28
|
if (attrs.italic === false) formatting.italic = false;
|
|
26
29
|
if (attrs.underline === "none") formatting.underline = { style: "none" };
|
|
@@ -34,6 +37,13 @@ function applyRunFormattingOverrideMark(formatting, mark) {
|
|
|
34
37
|
if (attrs.shadow === false) formatting.shadow = false;
|
|
35
38
|
if (attrs.outline === false) formatting.outline = false;
|
|
36
39
|
if (attrs.rtl === false) formatting.rtl = false;
|
|
40
|
+
if (attrs.boldCs !== void 0) formatting.boldCs = attrs.boldCs;
|
|
41
|
+
if (attrs.italicCs !== void 0) formatting.italicCs = attrs.italicCs;
|
|
42
|
+
if (attrs.fontSizeCs !== void 0) formatting.fontSizeCs = attrs.fontSizeCs;
|
|
43
|
+
if (attrs.cs !== void 0) formatting.cs = attrs.cs;
|
|
44
|
+
}
|
|
45
|
+
function applyRunFormattingOverrideMark(formatting, mark) {
|
|
46
|
+
applyRunFormattingOverrideAttrs(formatting, expectRunFormattingOverrideMarkAttrs(mark));
|
|
37
47
|
}
|
|
38
48
|
const RunFormattingOverrideExtension = createMarkExtension({
|
|
39
49
|
name: "runFormattingOverride",
|
|
@@ -52,7 +62,11 @@ const RunFormattingOverrideExtension = createMarkExtension({
|
|
|
52
62
|
imprint: { default: null },
|
|
53
63
|
shadow: { default: null },
|
|
54
64
|
outline: { default: null },
|
|
55
|
-
rtl: { default: null }
|
|
65
|
+
rtl: { default: null },
|
|
66
|
+
boldCs: { default: null },
|
|
67
|
+
italicCs: { default: null },
|
|
68
|
+
fontSizeCs: { default: null },
|
|
69
|
+
cs: { default: null }
|
|
56
70
|
},
|
|
57
71
|
toDOM(mark) {
|
|
58
72
|
const attrs = expectRunFormattingOverrideMarkAttrs(mark);
|
|
@@ -72,4 +86,4 @@ const RunFormattingOverrideExtension = createMarkExtension({
|
|
|
72
86
|
}
|
|
73
87
|
});
|
|
74
88
|
//#endregion
|
|
75
|
-
export { RunFormattingOverrideExtension, applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs };
|
|
89
|
+
export { RunFormattingOverrideExtension, applyRunFormattingOverrideAttrs, applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs };
|
|
@@ -154,6 +154,7 @@ const tableSpec = {
|
|
|
154
154
|
look: { default: null },
|
|
155
155
|
borders: { default: null },
|
|
156
156
|
_resolvedIndent: { default: null },
|
|
157
|
+
_resolvedBidi: { default: null },
|
|
157
158
|
_originalFormatting: { default: null },
|
|
158
159
|
tblPrChange: { default: null },
|
|
159
160
|
_suggestedInsert: { default: null }
|
|
@@ -122,6 +122,14 @@ type RunPropertyChangeMarkAttrs = {
|
|
|
122
122
|
suggestionId?: string;
|
|
123
123
|
};
|
|
124
124
|
type RunFormattingOverrideAttrs = { [K in keyof Pick<document_d_exports.TextFormatting, "bold" | "italic" | "strike" | "doubleStrike" | "allCaps" | "smallCaps" | "hidden" | "emboss" | "imprint" | "shadow" | "outline" | "rtl">]?: false; } & {
|
|
125
|
+
/** Independent complex-script weight (`w:bCs`). */
|
|
126
|
+
boldCs?: boolean;
|
|
127
|
+
/** Force complex-script formatting for the full run (`w:cs`). */
|
|
128
|
+
cs?: boolean;
|
|
129
|
+
/** Independent complex-script size in half-points (`w:szCs`). */
|
|
130
|
+
fontSizeCs?: number;
|
|
131
|
+
/** Independent complex-script slant (`w:iCs`). */
|
|
132
|
+
italicCs?: boolean;
|
|
125
133
|
underline?: "none";
|
|
126
134
|
};
|
|
127
135
|
/**
|
|
@@ -555,6 +555,8 @@ type TableAttrs = {
|
|
|
555
555
|
borders?: document_d_exports.TableBorders;
|
|
556
556
|
/** Effective table indent after style resolution. PM-only; never serialized. */
|
|
557
557
|
_resolvedIndent?: NonNullable<document_d_exports.TableFormatting["indent"]>;
|
|
558
|
+
/** Effective table direction after style resolution. PM-only; never serialized. */
|
|
559
|
+
_resolvedBidi?: boolean;
|
|
558
560
|
/** Original table formatting from DOCX for lossless round-trip serialization */
|
|
559
561
|
_originalFormatting?: document_d_exports.TableFormatting;
|
|
560
562
|
/** Tracked table property changes (w:tblPrChange) for round-trip + accept/reject */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.1",
|
|
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",
|