@stll/folio-core 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/headless.d.ts +2 -1
- package/dist/ai-edits/headless.js +9 -7
- package/dist/controller/layoutPipeline.js +22 -0
- package/dist/docx/encryption/agileDecryption.d.ts +6 -0
- package/dist/docx/encryption/agileDecryption.js +208 -0
- package/dist/docx/encryption/compoundFile.d.ts +20 -0
- package/dist/docx/encryption/compoundFile.js +249 -0
- package/dist/docx/encryption/containerFormat.d.ts +15 -0
- package/dist/docx/encryption/containerFormat.js +40 -0
- package/dist/docx/encryption/cryptoBytes.d.ts +11 -0
- package/dist/docx/encryption/cryptoBytes.js +55 -0
- package/dist/docx/encryption/encryptionInfo.d.ts +32 -0
- package/dist/docx/encryption/encryptionInfo.js +128 -0
- package/dist/docx/encryption/errors.d.ts +18 -0
- package/dist/docx/encryption/errors.js +13 -0
- package/dist/docx/encryption/index.d.ts +4 -0
- package/dist/docx/encryption/index.js +4 -0
- package/dist/docx/encryption/openEncryptedDocx.d.ts +28 -0
- package/dist/docx/encryption/openEncryptedDocx.js +65 -0
- package/dist/docx/index.d.ts +3 -1
- package/dist/docx/index.js +3 -1
- package/dist/docx/parser.d.ts +4 -5
- package/dist/docx/parser.js +8 -2
- package/dist/docx/unzip.d.ts +7 -5
- package/dist/docx/unzip.js +8 -2
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -1
- package/dist/layout-bridge/convert/headerFooterLayout.js +16 -6
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -0
- package/dist/layout-engine/index.js +27 -1
- package/dist/layout-engine/measure/measureBlocks.js +15 -1
- package/dist/layout-engine/measure/measureParagraph.js +37 -6
- package/dist/layout-engine/types.d.ts +3 -0
- package/dist/layout-painter/renderPage.js +2 -1
- package/dist/layout-painter/renderParagraph.js +30 -5
- package/dist/layout-painter/renderTable.js +17 -0
- package/dist/managers/DocumentLoaderManager.d.ts +3 -1
- package/dist/managers/DocumentLoaderManager.js +3 -2
- package/dist/paged-layout/headerFooterMargins.d.ts +3 -1
- package/dist/paged-layout/headerFooterMargins.js +5 -3
- package/dist/prosemirror/attrs/index.js +1 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +7 -2
- package/dist/prosemirror/conversion/toProseDoc.js +14 -7
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +4 -2
- package/dist/utils/fontResolver.js +17 -0
- package/package.json +5 -1
|
@@ -71,6 +71,11 @@ function measureTableCellBlockVisualHeight(block, blockMeasure) {
|
|
|
71
71
|
}
|
|
72
72
|
let maxImageHeight = 0;
|
|
73
73
|
for (const run of inlineImageRuns) maxImageHeight = Math.max(maxImageHeight, run.height);
|
|
74
|
+
if (inlineImageRuns.length === 1) {
|
|
75
|
+
const spacingBefore = paragraphBlock.attrs?.spacing?.before ?? 0;
|
|
76
|
+
const spacingAfter = paragraphBlock.attrs?.spacing?.after ?? 0;
|
|
77
|
+
return spacingBefore + maxImageHeight + spacingAfter;
|
|
78
|
+
}
|
|
74
79
|
const spacingBefore = paragraphBlock.attrs?.spacing?.before ?? 0;
|
|
75
80
|
const spacingAfter = paragraphBlock.attrs?.spacing?.after ?? 0;
|
|
76
81
|
return spacingBefore + maxImageHeight + spacingAfter;
|
|
@@ -143,6 +148,16 @@ function measureTableBlock(tableBlock, contentWidth, fieldValues) {
|
|
|
143
148
|
});
|
|
144
149
|
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
|
|
145
150
|
const row = rows[rowIdx];
|
|
151
|
+
const sourceRow = tableBlock.rows[rowIdx];
|
|
152
|
+
if (sourceRow?.hidden) {
|
|
153
|
+
row.height = 0;
|
|
154
|
+
row.cells = sourceRow.cells.map(() => ({
|
|
155
|
+
blocks: [],
|
|
156
|
+
width: 0,
|
|
157
|
+
height: 0
|
|
158
|
+
}));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
146
161
|
const sourceRowCells = tableBlock.rows[rowIdx]?.cells;
|
|
147
162
|
let maxCellHeightWithBorders = 0;
|
|
148
163
|
for (let cellIdx = 0; cellIdx < row.cells.length; cellIdx++) {
|
|
@@ -160,7 +175,6 @@ function measureTableBlock(tableBlock, contentWidth, fieldValues) {
|
|
|
160
175
|
cell.height += padTop + padBottom;
|
|
161
176
|
maxCellHeightWithBorders = Math.max(maxCellHeightWithBorders, cell.height + getTableCellVerticalBorderHeight(sourceCell));
|
|
162
177
|
}
|
|
163
|
-
const sourceRow = tableBlock.rows[rowIdx];
|
|
164
178
|
const explicitHeight = sourceRow?.height;
|
|
165
179
|
const heightRule = sourceRow?.heightRule;
|
|
166
180
|
if (explicitHeight && heightRule === "exact") row.height = explicitHeight;
|
|
@@ -21,6 +21,10 @@ const DEFAULT_FONT_SIZE = 11;
|
|
|
21
21
|
const DEFAULT_FONT_FAMILY = "Calibri";
|
|
22
22
|
const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
23
23
|
const WIDTH_TOLERANCE = .5;
|
|
24
|
+
const JUSTIFY_SHRINK_TOLERANCE_RATIO = .016;
|
|
25
|
+
const JUSTIFY_PROSE_SHRINK_TOLERANCE_RATIO = .025;
|
|
26
|
+
const JUSTIFY_HANGING_TAB_SHRINK_TOLERANCE_RATIO = .021;
|
|
27
|
+
const ALL_CAPS_RATIO_THRESHOLD = .8;
|
|
24
28
|
/**
|
|
25
29
|
* Find the longest prefix of `text` that fits within `maxWidth` pixels.
|
|
26
30
|
* Returns the number of characters that fit (at least 1 if `forceMin` is true).
|
|
@@ -266,6 +270,10 @@ function hasFollowingTabOnLine(runs, tabIndex) {
|
|
|
266
270
|
}
|
|
267
271
|
return false;
|
|
268
272
|
}
|
|
273
|
+
function canClampTabToRightEdge(alignment, currentLineWidth) {
|
|
274
|
+
if (alignment === "start" || alignment === "default") return currentLineWidth > WIDTH_TOLERANCE;
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
269
277
|
/**
|
|
270
278
|
* Width of the inline content preceding the first `.` in the runs that follow
|
|
271
279
|
* a tab, used to anchor `decimal` tab stops. Mirrors `getTextAfterTab` +
|
|
@@ -299,6 +307,25 @@ function measureDecimalPrefixWidthAfterTab(runs, tabIndex, fieldValues) {
|
|
|
299
307
|
function isSpaceOrTab(char) {
|
|
300
308
|
return char === " " || char === " ";
|
|
301
309
|
}
|
|
310
|
+
function uppercaseLetterRatio(text) {
|
|
311
|
+
let letters = 0;
|
|
312
|
+
let uppercase = 0;
|
|
313
|
+
for (const char of text) {
|
|
314
|
+
const lower = char.toLocaleLowerCase();
|
|
315
|
+
const upper = char.toLocaleUpperCase();
|
|
316
|
+
if (lower === upper) continue;
|
|
317
|
+
letters++;
|
|
318
|
+
if (char === upper) uppercase++;
|
|
319
|
+
}
|
|
320
|
+
return letters === 0 ? 0 : uppercase / letters;
|
|
321
|
+
}
|
|
322
|
+
function justifyShrinkToleranceRatio(block) {
|
|
323
|
+
const hasTabStops = (block.attrs?.tabs?.length ?? 0) > 0;
|
|
324
|
+
const hasTabRuns = block.runs.some(isTabRun);
|
|
325
|
+
if (hasTabStops || hasTabRuns) return (block.attrs?.indent?.firstLine ?? 0) === 0 ? JUSTIFY_HANGING_TAB_SHRINK_TOLERANCE_RATIO : JUSTIFY_SHRINK_TOLERANCE_RATIO;
|
|
326
|
+
if (uppercaseLetterRatio(block.runs.map((run) => isTextRun(run) ? run.text ?? "" : "").join("")) > ALL_CAPS_RATIO_THRESHOLD) return JUSTIFY_SHRINK_TOLERANCE_RATIO;
|
|
327
|
+
return JUSTIFY_PROSE_SHRINK_TOLERANCE_RATIO;
|
|
328
|
+
}
|
|
302
329
|
function trimTrailingSpacesAndTabs(text) {
|
|
303
330
|
let end = text.length;
|
|
304
331
|
while (end > 0) {
|
|
@@ -384,6 +411,8 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
384
411
|
const runs = block.runs;
|
|
385
412
|
const attrs = block.attrs;
|
|
386
413
|
const spacing = attrs?.spacing;
|
|
414
|
+
const isJustifiedParagraph = attrs?.alignment === "justify";
|
|
415
|
+
const justifyToleranceRatio = justifyShrinkToleranceRatio(block);
|
|
387
416
|
const floatingZones = options?.floatingZones;
|
|
388
417
|
const paragraphYOffset = options?.paragraphYOffset ?? 0;
|
|
389
418
|
const indent = attrs?.indent;
|
|
@@ -589,15 +618,16 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
589
618
|
const lineX = currentLine.width + currentLine.leftOffset;
|
|
590
619
|
const isFirstLine = lines.length === 0;
|
|
591
620
|
const contentX = indentLeft + (isFirstLine ? firstLineOffset + markerInlineWidth : 0) + lineX;
|
|
592
|
-
|
|
621
|
+
const tabResult = calculateTabWidth(contentX, {
|
|
593
622
|
...attrs?.tabs !== void 0 ? { explicitStops: attrs.tabs } : {},
|
|
594
623
|
leftIndent: pixelsToTwips(indentLeft)
|
|
595
624
|
}, {
|
|
596
625
|
followingWidth,
|
|
597
626
|
decimalPrefixWidth
|
|
598
|
-
})
|
|
627
|
+
});
|
|
628
|
+
let tabWidth = tabResult.width;
|
|
599
629
|
const lineRightEdgeX = indentLeft + (isFirstLine ? firstLineOffset + markerInlineWidth : 0) + currentLine.availableWidth + currentLine.leftOffset;
|
|
600
|
-
if (!hasFollowingTabOnLine(runs, runIndex) && (tabWidth > 0 || followingWidth > 0) && contentX + tabWidth + followingWidth > lineRightEdgeX + WIDTH_TOLERANCE) tabWidth = Math.max(1, lineRightEdgeX - contentX - followingWidth);
|
|
630
|
+
if (!hasFollowingTabOnLine(runs, runIndex) && canClampTabToRightEdge(tabResult.alignment, currentLine.width) && (tabWidth > 0 || followingWidth > 0) && contentX + tabWidth + followingWidth > lineRightEdgeX + WIDTH_TOLERANCE) tabWidth = Math.max(1, lineRightEdgeX - contentX - followingWidth);
|
|
601
631
|
if (currentLine.width + tabWidth > currentLine.availableWidth + WIDTH_TOLERANCE) {
|
|
602
632
|
startNewLine(runIndex, 0);
|
|
603
633
|
updateMaxFont(style);
|
|
@@ -691,7 +721,8 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
691
721
|
}
|
|
692
722
|
const word = text.slice(charIndex, nextBreak);
|
|
693
723
|
const wordWidth = measureTextWidth(word, style);
|
|
694
|
-
|
|
724
|
+
const widthTolerance = isJustifiedParagraph ? Math.max(WIDTH_TOLERANCE, currentLine.availableWidth * justifyToleranceRatio) : WIDTH_TOLERANCE;
|
|
725
|
+
if (wordWidth > currentLine.availableWidth + widthTolerance) {
|
|
695
726
|
let chunkStart = 0;
|
|
696
727
|
while (chunkStart < word.length) {
|
|
697
728
|
const spaceLeft = currentLine.availableWidth - currentLine.width + WIDTH_TOLERANCE;
|
|
@@ -719,8 +750,8 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
719
750
|
continue;
|
|
720
751
|
}
|
|
721
752
|
const rawGlueWidth = nextBreak === text.length && word.length > 0 && !isBreakChar(word[word.length - 1]) ? trailingGlueWidths[runIndex] ?? 0 : 0;
|
|
722
|
-
const glueWidth = rawGlueWidth > 0 && wordWidth + rawGlueWidth <= getPostWrapAvailableWidth() +
|
|
723
|
-
if (currentLine.width > 0 && currentLine.width + wordWidth + glueWidth > currentLine.availableWidth +
|
|
753
|
+
const glueWidth = rawGlueWidth > 0 && wordWidth + rawGlueWidth <= getPostWrapAvailableWidth() + widthTolerance ? rawGlueWidth : 0;
|
|
754
|
+
if (currentLine.width > 0 && currentLine.width + wordWidth + glueWidth > currentLine.availableWidth + widthTolerance) {
|
|
724
755
|
startNewLine(runIndex, charIndex);
|
|
725
756
|
updateMaxFont(lineHeightStyle);
|
|
726
757
|
}
|
|
@@ -303,6 +303,7 @@ type ParagraphAttrs = {
|
|
|
303
303
|
indent?: ParagraphIndent;
|
|
304
304
|
keepNext?: boolean;
|
|
305
305
|
keepLines?: boolean;
|
|
306
|
+
widowControl?: boolean;
|
|
306
307
|
pageBreakBefore?: boolean;
|
|
307
308
|
styleId?: string;
|
|
308
309
|
contextualSpacing?: boolean;
|
|
@@ -432,6 +433,7 @@ type TableRow = {
|
|
|
432
433
|
height?: number;
|
|
433
434
|
heightRule?: "auto" | "atLeast" | "exact";
|
|
434
435
|
isHeader?: boolean;
|
|
436
|
+
hidden?: boolean;
|
|
435
437
|
};
|
|
436
438
|
/**
|
|
437
439
|
* Floating table positioning info (pixel values).
|
|
@@ -518,6 +520,7 @@ type SectionBreakBlock = {
|
|
|
518
520
|
};
|
|
519
521
|
type PageHeaderFooterRefs = {
|
|
520
522
|
titlePg?: boolean;
|
|
523
|
+
evenAndOddHeaders?: boolean;
|
|
521
524
|
headerDefault?: string;
|
|
522
525
|
headerFirst?: string;
|
|
523
526
|
headerEven?: string;
|
|
@@ -1162,7 +1162,8 @@ function applySectionHeaderFooterOptions(page, pageOptions, options) {
|
|
|
1162
1162
|
if (!refs) return false;
|
|
1163
1163
|
const isFirstSectionPage = page.sectionPageNumber === 1;
|
|
1164
1164
|
const useFirst = refs.titlePg === true && isFirstSectionPage;
|
|
1165
|
-
const
|
|
1165
|
+
const sectionPageNumber = page.sectionPageNumber ?? page.number;
|
|
1166
|
+
const useEven = refs.evenAndOddHeaders === true && sectionPageNumber % 2 === 0;
|
|
1166
1167
|
const headerRId = (() => {
|
|
1167
1168
|
if (useFirst) return refs.headerFirst;
|
|
1168
1169
|
if (useEven && refs.headerEven) return refs.headerEven;
|
|
@@ -330,6 +330,10 @@ function renderTabRun(run, doc, width, leader) {
|
|
|
330
330
|
} else span.textContent = "\xA0";
|
|
331
331
|
return span;
|
|
332
332
|
}
|
|
333
|
+
function canClampTabToRightEdge(alignment, hasPriorRenderedContent) {
|
|
334
|
+
if (alignment === "start" || alignment === "default") return hasPriorRenderedContent;
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
333
337
|
function applyTabUnderline(element, run) {
|
|
334
338
|
if (!run.underline) return;
|
|
335
339
|
removeUnderlineTextDecoration(element);
|
|
@@ -529,7 +533,9 @@ const EMPTY_SEQ_VALUES = /* @__PURE__ */ new Map();
|
|
|
529
533
|
* Returns the cached fallback when no render context is available.
|
|
530
534
|
*/
|
|
531
535
|
function resolveFieldText(run, context) {
|
|
532
|
-
|
|
536
|
+
const fallback = run.fallback ?? "";
|
|
537
|
+
if (run.fieldType === "OTHER" && run.pmStart === void 0) return fallback;
|
|
538
|
+
if (!context) return fallback;
|
|
533
539
|
const fieldContext = {
|
|
534
540
|
pageNumber: context.pageNumber,
|
|
535
541
|
totalPages: context.totalPages,
|
|
@@ -540,7 +546,7 @@ function resolveFieldText(run, context) {
|
|
|
540
546
|
...context.sectionPages === void 0 ? {} : { sectionPages: context.sectionPages }
|
|
541
547
|
};
|
|
542
548
|
return evaluateFieldInstruction(run.instruction || run.fieldType, fieldContext, {
|
|
543
|
-
fallback
|
|
549
|
+
fallback,
|
|
544
550
|
...run.pmStart === void 0 ? {} : { instanceId: run.pmStart },
|
|
545
551
|
...run.fldLock ? { locked: true } : {}
|
|
546
552
|
});
|
|
@@ -710,6 +716,17 @@ function splitTextRunsByEastAsia(runs) {
|
|
|
710
716
|
* must trigger within this slack.
|
|
711
717
|
*/
|
|
712
718
|
const RIGHT_EDGE_EPSILON_PX = .5;
|
|
719
|
+
function countShrinkableSpaces(runs) {
|
|
720
|
+
let count = 0;
|
|
721
|
+
for (const run of runs) if (isTextRun(run)) {
|
|
722
|
+
for (const char of run.text ?? "") if (char === " ") count++;
|
|
723
|
+
} else if (isFieldRun(run)) {
|
|
724
|
+
for (const char of run.fallback ?? "") if (char === " ") count++;
|
|
725
|
+
} else if (isMathRun(run)) {
|
|
726
|
+
for (const char of run.plainText ?? "") if (char === " ") count++;
|
|
727
|
+
}
|
|
728
|
+
return count;
|
|
729
|
+
}
|
|
713
730
|
/**
|
|
714
731
|
* Build a TextMeasureStyle from a TextRun or FieldRun's relevant fields.
|
|
715
732
|
*/
|
|
@@ -890,8 +907,16 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
890
907
|
}
|
|
891
908
|
if (alignment === "justify" && options) {
|
|
892
909
|
if (!options.isLastLine || options.paragraphEndsWithLineBreak) {
|
|
893
|
-
|
|
894
|
-
|
|
910
|
+
const overfullPx = line.width - options.availableWidth;
|
|
911
|
+
const shrinkableSpaces = countShrinkableSpaces(runsForLine);
|
|
912
|
+
if (overfullPx > RIGHT_EDGE_EPSILON_PX && shrinkableSpaces > 0) {
|
|
913
|
+
lineEl.style.textAlign = "left";
|
|
914
|
+
lineEl.style.textAlignLast = "auto";
|
|
915
|
+
lineEl.style.wordSpacing = `${-overfullPx / shrinkableSpaces}px`;
|
|
916
|
+
} else {
|
|
917
|
+
lineEl.style.textAlign = "justify";
|
|
918
|
+
lineEl.style.textAlignLast = "justify";
|
|
919
|
+
}
|
|
895
920
|
lineEl.style.width = `${options.availableWidth}px`;
|
|
896
921
|
}
|
|
897
922
|
}
|
|
@@ -967,7 +992,7 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
967
992
|
break;
|
|
968
993
|
}
|
|
969
994
|
let tabWidth = tabResult.width;
|
|
970
|
-
if (lineRightEdgeX !== void 0 && currentX + tabWidth + followingWidthForCheck > lineRightEdgeX) tabWidth = Math.max(1, lineRightEdgeX - currentX - followingWidthForCheck);
|
|
995
|
+
if (lineRightEdgeX !== void 0 && canClampTabToRightEdge(tabResult.alignment, i > 0) && currentX + tabWidth + followingWidthForCheck > lineRightEdgeX) tabWidth = Math.max(1, lineRightEdgeX - currentX - followingWidthForCheck);
|
|
971
996
|
const tabEl = renderTabRun(run, doc, tabWidth, tabResult.leader);
|
|
972
997
|
lineEl.append(tabEl);
|
|
973
998
|
currentX += tabWidth;
|
|
@@ -97,6 +97,10 @@ function renderCellContent(cell, cellMeasure, context, doc) {
|
|
|
97
97
|
};
|
|
98
98
|
const fragEl = renderParagraphFragment(syntheticFragment, paragraphBlock, paragraphMeasure, cellContext, { document: doc });
|
|
99
99
|
fragEl.style.position = "relative";
|
|
100
|
+
fragEl.style.boxSizing = "border-box";
|
|
101
|
+
fragEl.style.height = `${paragraphMeasure.totalHeight}px`;
|
|
102
|
+
const spaceBefore = paragraphBlock.attrs?.spacing?.before ?? 0;
|
|
103
|
+
if (spaceBefore > 0) fragEl.style.paddingTop = `${spaceBefore}px`;
|
|
100
104
|
contentEl.append(fragEl);
|
|
101
105
|
cumulativeY += paragraphMeasure.totalHeight;
|
|
102
106
|
} else if (block?.kind === "table" && measure?.kind === "table") {
|
|
@@ -138,6 +142,10 @@ function renderNestedTable(block, measure, context, doc) {
|
|
|
138
142
|
const row = block.rows[rowIndex];
|
|
139
143
|
const rowMeasure = measure.rows[rowIndex];
|
|
140
144
|
if (!row || !rowMeasure) continue;
|
|
145
|
+
if (row.hidden) {
|
|
146
|
+
y += rowMeasure.height;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
141
149
|
const rowEl = renderTableRow(row, rowMeasure, rowIndex, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, void 0, block.bidi);
|
|
142
150
|
tableEl.append(rowEl);
|
|
143
151
|
y += rowMeasure.height;
|
|
@@ -346,6 +354,10 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
|
|
|
346
354
|
const hdrRow = block.rows[hdrIdx];
|
|
347
355
|
const hdrRowMeasure = measure.rows[hdrIdx];
|
|
348
356
|
if (!hdrRow || !hdrRowMeasure) continue;
|
|
357
|
+
if (hdrRow.hidden) {
|
|
358
|
+
y += hdrRowMeasure.height;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
349
361
|
const rowEl = renderTableRow(hdrRow, hdrRowMeasure, hdrIdx, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, hdrIdx === 0, block.bidi);
|
|
350
362
|
rowEl.dataset["repeatedHeader"] = "true";
|
|
351
363
|
tableEl.append(rowEl);
|
|
@@ -369,6 +381,10 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
|
|
|
369
381
|
const row = block.rows[rowIndex];
|
|
370
382
|
const rowMeasure = measure.rows[rowIndex];
|
|
371
383
|
if (!row || !rowMeasure) continue;
|
|
384
|
+
if (row.hidden) {
|
|
385
|
+
y += rowMeasure.height;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
372
388
|
const isFirstRowInFragment = headerRowCount > 0 && fragment.continuesFromPrev ? false : fragment.continuesFromPrev && rowIndex === fragment.fromRow;
|
|
373
389
|
const rowEl = renderTableRow(row, rowMeasure, rowIndex, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, isFirstRowInFragment, block.bidi);
|
|
374
390
|
contentParent.append(rowEl);
|
|
@@ -376,6 +392,7 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
|
|
|
376
392
|
}
|
|
377
393
|
let handleY = 0;
|
|
378
394
|
for (let rowIdx = fragment.fromRow; rowIdx < fragment.toRow; rowIdx++) {
|
|
395
|
+
if (block.rows[rowIdx]?.hidden) continue;
|
|
379
396
|
handleY += measure.rows[rowIdx]?.height ?? 0;
|
|
380
397
|
if (rowIdx < fragment.toRow - 1) {
|
|
381
398
|
const rowHandle = doc.createElement("div");
|
|
@@ -41,7 +41,9 @@ declare class DocumentLoaderManager {
|
|
|
41
41
|
* the result (and any error) when a newer load started while this one was in
|
|
42
42
|
* flight.
|
|
43
43
|
*/
|
|
44
|
-
loadBuffer(buffer: DocxInput
|
|
44
|
+
loadBuffer(buffer: DocxInput, options?: {
|
|
45
|
+
password?: string | undefined;
|
|
46
|
+
}): Promise<void>;
|
|
45
47
|
}
|
|
46
48
|
//#endregion
|
|
47
49
|
export { DocumentLoadState, DocumentLoaderCallbacks, DocumentLoaderHistory, DocumentLoaderManager };
|
|
@@ -43,14 +43,15 @@ var DocumentLoaderManager = class {
|
|
|
43
43
|
* the result (and any error) when a newer load started while this one was in
|
|
44
44
|
* flight.
|
|
45
45
|
*/
|
|
46
|
-
async loadBuffer(buffer) {
|
|
46
|
+
async loadBuffer(buffer, options = {}) {
|
|
47
47
|
const { history, onError, setDocumentLoadState } = this.callbacks;
|
|
48
48
|
const generation = ++this.loadGeneration;
|
|
49
49
|
if (!(history.state !== null)) setDocumentLoadState({ status: "loading" });
|
|
50
50
|
try {
|
|
51
51
|
const doc = await parseDocx(buffer, {
|
|
52
52
|
detectVariables: false,
|
|
53
|
-
preloadFonts: false
|
|
53
|
+
preloadFonts: false,
|
|
54
|
+
password: options.password
|
|
54
55
|
});
|
|
55
56
|
if (this.loadGeneration !== generation) return;
|
|
56
57
|
this.loadParsedDocument(doc);
|
|
@@ -43,7 +43,8 @@ declare function computeEffectiveHeaderFooterMargins({
|
|
|
43
43
|
/** Rendered header/footer content shared by every extender on a page. */
|
|
44
44
|
type HeaderFooterExtenderContent = Omit<EffectiveHeaderFooterMarginsInput, "margins" | "pageSize" | "warn">;
|
|
45
45
|
type ExtendSectionBreakMarginsInput = {
|
|
46
|
-
content: HeaderFooterExtenderContent;
|
|
46
|
+
content: HeaderFooterExtenderContent;
|
|
47
|
+
sectionContent?: HeaderFooterExtenderContent[] | undefined; /** Body page size and effective margins — the inheritance seed. */
|
|
47
48
|
bodyPageSize: {
|
|
48
49
|
w: number;
|
|
49
50
|
h: number;
|
|
@@ -65,6 +66,7 @@ type ExtendSectionBreakMarginsInput = {
|
|
|
65
66
|
*/
|
|
66
67
|
declare function extendSectionBreakMargins(sectionBreaks: SectionBreakBlock[], {
|
|
67
68
|
content,
|
|
69
|
+
sectionContent,
|
|
68
70
|
bodyPageSize,
|
|
69
71
|
bodyMargins,
|
|
70
72
|
warn
|
|
@@ -102,14 +102,16 @@ function computeEffectiveHeaderFooterMargins({ margins, headerContent, footerCon
|
|
|
102
102
|
* clamped reservation (and vice versa). Materializes `margins` on every
|
|
103
103
|
* non-inheriting break in place.
|
|
104
104
|
*/
|
|
105
|
-
function extendSectionBreakMargins(sectionBreaks, { content, bodyPageSize, bodyMargins, warn }) {
|
|
105
|
+
function extendSectionBreakMargins(sectionBreaks, { content, sectionContent, bodyPageSize, bodyMargins, warn }) {
|
|
106
106
|
let pageSize = bodyPageSize;
|
|
107
107
|
let margins = bodyMargins;
|
|
108
|
-
for (
|
|
108
|
+
for (let index = 0; index < sectionBreaks.length; index++) {
|
|
109
|
+
const sb = sectionBreaks[index];
|
|
110
|
+
if (!sb) continue;
|
|
109
111
|
if (!sb.pageSize && !sb.margins) continue;
|
|
110
112
|
pageSize = sb.pageSize ?? pageSize;
|
|
111
113
|
margins = computeHeaderFooterMarginExtender({
|
|
112
|
-
...content,
|
|
114
|
+
...sectionContent?.[index + 1] ?? content,
|
|
113
115
|
pageSize,
|
|
114
116
|
warn
|
|
115
117
|
})(sb.margins ?? margins);
|
|
@@ -236,6 +236,7 @@ const readTableRowAttrs = (node) => {
|
|
|
236
236
|
optionalNumber(attrs, "height", "tableRow.attrs.height", issues);
|
|
237
237
|
optionalOneOf(attrs, "heightRule", "tableRow.attrs.heightRule", issues, TABLE_ROW_HEIGHT_RULE_VALUES);
|
|
238
238
|
optionalBoolean(attrs, "isHeader", "tableRow.attrs.isHeader", issues);
|
|
239
|
+
optionalBoolean(attrs, "hidden", "tableRow.attrs.hidden", issues);
|
|
239
240
|
optionalRecord(attrs, "_originalFormatting", "tableRow.attrs._originalFormatting", issues);
|
|
240
241
|
return attrsResult(attrs, issues);
|
|
241
242
|
};
|
|
@@ -341,6 +341,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
341
341
|
if (attrs.styleId !== (orig.styleId ?? void 0)) if (attrs.styleId) result.styleId = attrs.styleId;
|
|
342
342
|
else delete result.styleId;
|
|
343
343
|
assignBooleanToggle(result, attrs, orig, "pageBreakBefore");
|
|
344
|
+
assignBooleanToggle(result, attrs, orig, "widowControl");
|
|
344
345
|
if (attrs.spacingExplicit !== orig.spacingExplicit) if (attrs.spacingExplicit) result.spacingExplicit = attrs.spacingExplicit;
|
|
345
346
|
else delete result.spacingExplicit;
|
|
346
347
|
const bidi = directionToBidi(attrs.direction);
|
|
@@ -350,7 +351,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
350
351
|
}
|
|
351
352
|
const outlineLevel = Reflect.get(attrs, "outlineLevel");
|
|
352
353
|
const bidi = directionToBidi(attrs.direction);
|
|
353
|
-
if (!(attrs.alignment || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || attrs.lineSpacing || attrs.indentLeft || attrs.indentRight || attrs.indentFirstLine || attrs.numPr || attrs.styleId || attrs.borders || attrs.shading || attrs.tabs || typeof outlineLevel === "number" || attrs.contextualSpacing || attrs.spacingExplicit || bidi != null || attrs.pageBreakBefore != null)) return;
|
|
354
|
+
if (!(attrs.alignment || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || attrs.lineSpacing || attrs.indentLeft || attrs.indentRight || attrs.indentFirstLine || attrs.numPr || attrs.styleId || attrs.borders || attrs.shading || attrs.tabs || typeof outlineLevel === "number" || attrs.contextualSpacing || attrs.spacingExplicit || bidi != null || attrs.pageBreakBefore != null || attrs.widowControl != null)) return;
|
|
354
355
|
const f = {};
|
|
355
356
|
if (attrs.alignment) f.alignment = attrs.alignment;
|
|
356
357
|
if (shouldSerializeSpaceBefore) f.spaceBefore = spaceBefore;
|
|
@@ -373,6 +374,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
373
374
|
if (attrs.contextualSpacing) f.contextualSpacing = attrs.contextualSpacing;
|
|
374
375
|
if (bidi != null) f.bidi = bidi;
|
|
375
376
|
if (attrs.pageBreakBefore != null) f.pageBreakBefore = attrs.pageBreakBefore;
|
|
377
|
+
if (attrs.widowControl != null) f.widowControl = attrs.widowControl;
|
|
376
378
|
return f;
|
|
377
379
|
}
|
|
378
380
|
/**
|
|
@@ -1397,9 +1399,11 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
1397
1399
|
else delete result.heightRule;
|
|
1398
1400
|
if (attrs.isHeader !== (orig.header ?? void 0)) if (attrs.isHeader) result.header = attrs.isHeader;
|
|
1399
1401
|
else delete result.header;
|
|
1402
|
+
if (attrs.hidden !== (orig.hidden ?? void 0)) if (attrs.hidden) result.hidden = attrs.hidden;
|
|
1403
|
+
else delete result.hidden;
|
|
1400
1404
|
return result;
|
|
1401
1405
|
}
|
|
1402
|
-
if (!(attrs.height || attrs.isHeader)) return;
|
|
1406
|
+
if (!(attrs.height || attrs.isHeader || attrs.hidden)) return;
|
|
1403
1407
|
const f = {};
|
|
1404
1408
|
if (attrs.height) f.height = {
|
|
1405
1409
|
value: attrs.height,
|
|
@@ -1407,6 +1411,7 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
1407
1411
|
};
|
|
1408
1412
|
if (attrs.heightRule) f.heightRule = attrs.heightRule;
|
|
1409
1413
|
if (attrs.isHeader) f.header = attrs.isHeader;
|
|
1414
|
+
if (attrs.hidden) f.hidden = attrs.hidden;
|
|
1410
1415
|
return f;
|
|
1411
1416
|
}
|
|
1412
1417
|
/**
|
|
@@ -11,6 +11,7 @@ import { createStyleEngine } from "../../style-engine/styleEngine.js";
|
|
|
11
11
|
import { buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
12
12
|
import { schema } from "../schema/index.js";
|
|
13
13
|
//#region src/prosemirror/conversion/toProseDoc.ts
|
|
14
|
+
const TOC_STYLE_ID = /^TOC\d*$/iu;
|
|
14
15
|
/**
|
|
15
16
|
* Convert a Document to a ProseMirror document
|
|
16
17
|
*
|
|
@@ -80,6 +81,7 @@ function convertBlockSdt(blockSdt, convertBlocks) {
|
|
|
80
81
|
*/
|
|
81
82
|
function convertParagraph(paragraph, styleResolver, activeCommentIds, extraRunFormatting, tableParagraphOverlay) {
|
|
82
83
|
const attrs = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
|
|
84
|
+
const isTocParagraph = TOC_STYLE_ID.test(paragraph.formatting?.styleId ?? "");
|
|
83
85
|
const inlineNodes = [];
|
|
84
86
|
let inlineOffset = 0;
|
|
85
87
|
let bookmarksArr;
|
|
@@ -99,10 +101,12 @@ function convertParagraph(paragraph, styleResolver, activeCommentIds, extraRunFo
|
|
|
99
101
|
let styleRunFormatting;
|
|
100
102
|
if (styleResolver) styleRunFormatting = styleResolver.resolveParagraphStyle(paragraph.formatting?.styleId).runFormatting;
|
|
101
103
|
const paragraphRunFormatting = paragraph.formatting?.runProperties ? resolveTextFormatting(paragraph.formatting.runProperties, styleResolver) : void 0;
|
|
102
|
-
|
|
104
|
+
let inheritableParagraphRunFormatting;
|
|
105
|
+
if (paragraphRunFormatting && !isTocParagraph) inheritableParagraphRunFormatting = stripParagraphMarkOnlyFormatting(paragraphRunFormatting);
|
|
103
106
|
const baseRunFormatting = mergeTextFormatting(styleRunFormatting, extraRunFormatting);
|
|
104
107
|
const defaultRunFormatting = mergeTextFormatting(baseRunFormatting, inheritableParagraphRunFormatting);
|
|
105
|
-
const getInheritedRunFormatting = (formatting) => {
|
|
108
|
+
const getInheritedRunFormatting = (formatting, fieldType) => {
|
|
109
|
+
if (fieldType === "TOC") return hasDirectRunFormatting(formatting) ? suppressParagraphMarkFormatting(baseRunFormatting, void 0, formatting) : baseRunFormatting;
|
|
106
110
|
if (!hasDirectRunFormatting(formatting)) return defaultRunFormatting;
|
|
107
111
|
return suppressParagraphMarkFormatting(baseRunFormatting, inheritableParagraphRunFormatting, formatting);
|
|
108
112
|
};
|
|
@@ -252,11 +256,12 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
252
256
|
set("pageBreakBefore", formatting?.pageBreakBefore ?? stylePpr?.pageBreakBefore);
|
|
253
257
|
set("keepNext", formatting?.keepNext ?? stylePpr?.keepNext);
|
|
254
258
|
set("keepLines", formatting?.keepLines ?? stylePpr?.keepLines);
|
|
259
|
+
set("widowControl", formatting?.widowControl ?? stylePpr?.widowControl);
|
|
255
260
|
set("contextualSpacing", formatting?.contextualSpacing ?? stylePpr?.contextualSpacing);
|
|
256
261
|
set("runInWithNext", formatting?.runInWithNext ?? stylePpr?.runInWithNext);
|
|
257
262
|
set("outlineLevel", formatting?.outlineLevel ?? stylePpr?.outlineLevel);
|
|
258
263
|
set("direction", directionFromBidi(formatting?.bidi ?? stylePpr?.bidi));
|
|
259
|
-
set("defaultTextFormatting", resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver));
|
|
264
|
+
set("defaultTextFormatting", resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, { includeParagraphMarkRunProperties: !TOC_STYLE_ID.test(styleId ?? "") }));
|
|
260
265
|
if (!formatting?.numPr && stylePpr?.numPr && stylePpr.numPr.numId !== 0) {
|
|
261
266
|
attrs.numPr = stylePpr.numPr;
|
|
262
267
|
attrs.numPrFromStyle = stylePpr.numPr;
|
|
@@ -278,6 +283,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
278
283
|
set("pageBreakBefore", formatting?.pageBreakBefore);
|
|
279
284
|
set("keepNext", formatting?.keepNext);
|
|
280
285
|
set("keepLines", formatting?.keepLines);
|
|
286
|
+
set("widowControl", formatting?.widowControl);
|
|
281
287
|
set("runInWithNext", formatting?.runInWithNext);
|
|
282
288
|
set("outlineLevel", formatting?.outlineLevel);
|
|
283
289
|
set("direction", directionFromBidi(formatting?.bidi));
|
|
@@ -381,7 +387,7 @@ function hasDirectRunFormatting(formatting) {
|
|
|
381
387
|
return Object.entries(formatting).some(([key, value]) => key !== "styleId" && value !== void 0);
|
|
382
388
|
}
|
|
383
389
|
function stripParagraphMarkOnlyFormatting(formatting) {
|
|
384
|
-
const { highlight: _h, shading: _s, ...rest } = formatting;
|
|
390
|
+
const { allCaps: _ac, highlight: _h, shading: _s, smallCaps: _sc, ...rest } = formatting;
|
|
385
391
|
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
386
392
|
}
|
|
387
393
|
function suppressParagraphMarkFormatting(base, paragraphMark, direct) {
|
|
@@ -411,10 +417,10 @@ function resolveTextFormatting(formatting, styleResolver) {
|
|
|
411
417
|
if (!styleResolver) return formatting;
|
|
412
418
|
return mergeTextFormatting(styleResolver.resolveRunStyle(formatting.styleId), formatting);
|
|
413
419
|
}
|
|
414
|
-
function resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver) {
|
|
420
|
+
function resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, options = {}) {
|
|
415
421
|
const style = styleId ? styleResolver.getStyle(styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
|
|
416
422
|
const paragraphStyleRpr = style?.type === "paragraph" ? style.rPr : void 0;
|
|
417
|
-
const rawParagraphMarkRpr = formatting?.runProperties;
|
|
423
|
+
const rawParagraphMarkRpr = options.includeParagraphMarkRunProperties === false ? void 0 : formatting?.runProperties;
|
|
418
424
|
const characterStyleRpr = rawParagraphMarkRpr?.styleId !== void 0 ? styleResolver.getRunStyleOwnProperties(rawParagraphMarkRpr.styleId) : void 0;
|
|
419
425
|
const paragraphRunProperties = rawParagraphMarkRpr ? stripParagraphMarkOnlyFormatting(mergeTextFormatting(characterStyleRpr, rawParagraphMarkRpr) ?? {}) : void 0;
|
|
420
426
|
return mergeTextFormatting(mergeTextFormatting(mergeTextFormatting(styleResolver.getDocDefaults()?.rPr, styleResolver.getDefaultCharacterStyle()?.rPr), paragraphStyleRpr), paragraphRunProperties);
|
|
@@ -599,6 +605,7 @@ function convertTableRow(row, styleResolver, isHeaderRow, columnWidths, totalWid
|
|
|
599
605
|
const attrs = { isHeader: !!row.formatting?.header };
|
|
600
606
|
if (row.formatting?.height?.value !== void 0) attrs.height = row.formatting.height.value;
|
|
601
607
|
if (row.formatting?.heightRule) attrs.heightRule = row.formatting.heightRule;
|
|
608
|
+
if (row.formatting?.hidden) attrs.hidden = true;
|
|
602
609
|
if (row.formatting) attrs._originalFormatting = row.formatting;
|
|
603
610
|
const numCells = row.cells.length;
|
|
604
611
|
const isFirstRow = rowIndex === 0;
|
|
@@ -769,7 +776,7 @@ function convertField(field, getInheritedRunFormatting, styleResolver) {
|
|
|
769
776
|
if (!fieldFormatting && r.formatting) fieldFormatting = r.formatting;
|
|
770
777
|
}
|
|
771
778
|
if (!fieldFormatting && field.type === "complexField" && field.fieldResult.length === 0) fieldFormatting = field.formatting;
|
|
772
|
-
const inheritedFormatting = getInheritedRunFormatting(fieldFormatting);
|
|
779
|
+
const inheritedFormatting = getInheritedRunFormatting(fieldFormatting, field.fieldType);
|
|
773
780
|
const { marks } = buildRunMarks(fieldFormatting, inheritedFormatting, styleResolver);
|
|
774
781
|
return schema.node("field", {
|
|
775
782
|
fieldType: field.fieldType,
|
|
@@ -213,6 +213,7 @@ const paragraphNodeSpec = {
|
|
|
213
213
|
renderedPageBreakBefore: { default: null },
|
|
214
214
|
keepNext: { default: null },
|
|
215
215
|
keepLines: { default: null },
|
|
216
|
+
widowControl: { default: null },
|
|
216
217
|
contextualSpacing: { default: null },
|
|
217
218
|
runInWithNext: { default: null },
|
|
218
219
|
defaultTextFormatting: { default: null },
|
|
@@ -199,6 +199,7 @@ const tableRowSpec = {
|
|
|
199
199
|
height: { default: null },
|
|
200
200
|
heightRule: { default: null },
|
|
201
201
|
isHeader: { default: false },
|
|
202
|
+
hidden: { default: false },
|
|
202
203
|
_originalFormatting: { default: null }
|
|
203
204
|
},
|
|
204
205
|
parseDOM: [{ tag: "tr" }],
|
|
@@ -206,6 +207,7 @@ const tableRowSpec = {
|
|
|
206
207
|
const attrs = expectTableRowAttrs(node);
|
|
207
208
|
const domAttrs = {};
|
|
208
209
|
if (typeof attrs.height === "number") domAttrs["style"] = `height: ${Math.round(attrs.height / 20 * 1.333)}px`;
|
|
210
|
+
if (attrs.hidden) domAttrs["style"] = `${domAttrs["style"] ? `${domAttrs["style"]}; ` : ""}display: none`;
|
|
209
211
|
return [
|
|
210
212
|
"tr",
|
|
211
213
|
domAttrs,
|
|
@@ -82,7 +82,8 @@ type ParagraphAttrs = {
|
|
|
82
82
|
pageBreakBefore?: boolean; /** Word's cached rendered-page-break marker; preserved for round-trip only. */
|
|
83
83
|
renderedPageBreakBefore?: boolean;
|
|
84
84
|
keepNext?: boolean;
|
|
85
|
-
keepLines?: boolean;
|
|
85
|
+
keepLines?: boolean;
|
|
86
|
+
widowControl?: boolean; /** Contextual spacing — suppress space between same-style paragraphs */
|
|
86
87
|
contextualSpacing?: boolean;
|
|
87
88
|
defaultTextFormatting?: document_d_exports.TextFormatting;
|
|
88
89
|
sectionBreakType?: "nextPage" | "continuous" | "oddPage" | "evenPage";
|
|
@@ -353,7 +354,8 @@ type TableAttrs = {
|
|
|
353
354
|
type TableRowAttrs = {
|
|
354
355
|
/** Row height (in twips) */height?: number; /** Height rule ('auto', 'exact', 'atLeast') */
|
|
355
356
|
heightRule?: NonNullable<document_d_exports.TableRowFormatting["heightRule"]>; /** Is header row */
|
|
356
|
-
isHeader?: boolean; /**
|
|
357
|
+
isHeader?: boolean; /** Whether the row is hidden (`w:hidden`) */
|
|
358
|
+
hidden?: boolean; /** Original row formatting from DOCX for lossless round-trip serialization */
|
|
357
359
|
_originalFormatting?: document_d_exports.TableRowFormatting;
|
|
358
360
|
};
|
|
359
361
|
/**
|
|
@@ -128,6 +128,23 @@ const FONT_MAPPINGS = {
|
|
|
128
128
|
unitsPerEm: 2048
|
|
129
129
|
})
|
|
130
130
|
},
|
|
131
|
+
"cg times": {
|
|
132
|
+
googleFont: "Tinos",
|
|
133
|
+
category: "serif",
|
|
134
|
+
fallbackStack: [
|
|
135
|
+
"Times New Roman",
|
|
136
|
+
"Tinos",
|
|
137
|
+
"Times",
|
|
138
|
+
"serif"
|
|
139
|
+
],
|
|
140
|
+
singleLineRatio: singleLineRatioOf({
|
|
141
|
+
source: "hhea",
|
|
142
|
+
hheaAscent: 1825,
|
|
143
|
+
hheaDescent: -443,
|
|
144
|
+
hheaLineGap: 87,
|
|
145
|
+
unitsPerEm: 2048
|
|
146
|
+
})
|
|
147
|
+
},
|
|
131
148
|
"courier new": {
|
|
132
149
|
googleFont: "Cousine",
|
|
133
150
|
category: "monospace",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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",
|
|
@@ -49,6 +49,10 @@
|
|
|
49
49
|
"types": "./dist/compat/eigenpal.d.ts",
|
|
50
50
|
"import": "./dist/compat/eigenpal.js"
|
|
51
51
|
},
|
|
52
|
+
"./watermark": {
|
|
53
|
+
"types": "./dist/watermark/index.d.ts",
|
|
54
|
+
"import": "./dist/watermark/index.js"
|
|
55
|
+
},
|
|
52
56
|
"./layout-engine": {
|
|
53
57
|
"types": "./dist/layout-engine/index.d.ts",
|
|
54
58
|
"import": "./dist/layout-engine/index.js"
|