@stll/folio-core 0.33.1 → 0.34.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/apply.d.ts +15 -0
- package/dist/ai-edits/apply.js +271 -48
- package/dist/ai-edits/headless.d.ts +47 -3
- package/dist/ai-edits/headless.js +53 -3
- package/dist/ai-edits/index.d.ts +1 -1
- package/dist/ai-edits/snapshot.d.ts +19 -1
- package/dist/ai-edits/snapshot.js +49 -5
- package/dist/ai-edits/table-geometry.d.ts +56 -0
- package/dist/ai-edits/table-geometry.js +217 -0
- package/dist/ai-edits/table-row-column-mutations.d.ts +34 -16
- package/dist/ai-edits/table-row-column-mutations.js +12 -4
- package/dist/ai-edits/table-template.d.ts +60 -0
- package/dist/ai-edits/table-template.js +176 -0
- package/dist/ai-edits/types.d.ts +13 -6
- package/dist/compare/__fixtures__/body-sequence.d.ts +61 -2
- package/dist/compare/__fixtures__/body-sequence.js +94 -6
- package/dist/compare/compare.d.ts +14 -7
- package/dist/compare/compare.js +136 -38
- package/dist/compare/formatting.d.ts +1 -1
- package/dist/compare/formatting.js +38 -9
- package/dist/compare/plan.d.ts +31 -1
- package/dist/compare/plan.js +233 -66
- package/dist/compare/types.d.ts +9 -7
- package/dist/compare/types.js +7 -5
- package/dist/compare/verification.d.ts +31 -12
- package/dist/compare/verification.js +106 -18
- package/dist/compat/eigenpal.d.ts +4 -4
- package/dist/compat/eigenpal.js +2 -2
- package/dist/controller/headerFooterEditorManager.js +11 -9
- package/dist/controller/layoutPipeline.js +24 -3
- package/dist/display-list/build/watermarkPrimitives.js +15 -3
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +10 -1
- package/dist/document-operations.js +33 -5
- package/dist/docx/appVersionNormalization.d.ts +49 -0
- package/dist/docx/appVersionNormalization.js +74 -0
- package/dist/docx/blockContentParser.js +3 -2
- package/dist/docx/drawingUtils.js +4 -3
- package/dist/docx/headerFooterParser.js +8 -14
- package/dist/docx/paragraphParser.js +48 -2
- package/dist/docx/rezip.d.ts +10 -4
- package/dist/docx/rezip.js +54 -18
- package/dist/docx/runParser.js +9 -8
- package/dist/docx/sdtProperties.js +4 -3
- package/dist/docx/selectiveSave.js +7 -6
- package/dist/docx/serializer/commentSerializer.d.ts +1 -1
- package/dist/docx/serializer/commentSerializer.js +43 -19
- package/dist/docx/serializer/documentSerializer.d.ts +3 -1
- package/dist/docx/serializer/documentSerializer.js +42 -78
- package/dist/docx/serializer/fontTableSerializer.js +8 -5
- package/dist/docx/serializer/headerFooterSerializer.d.ts +4 -1
- package/dist/docx/serializer/headerFooterSerializer.js +55 -31
- package/dist/docx/serializer/noteSerializer.js +34 -30
- package/dist/docx/serializer/numberingSerializer.js +8 -4
- package/dist/docx/serializer/paragraphSerializer.d.ts +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +22 -12
- package/dist/docx/serializer/partNamespaces.d.ts +78 -0
- package/dist/docx/serializer/partNamespaces.js +324 -0
- package/dist/docx/serializer/runSerializer.js +1 -1
- package/dist/docx/serializer/settingsSerializer.js +8 -2
- package/dist/docx/serializer/stylesSerializer.js +8 -5
- package/dist/docx/serializer/tableSerializer.js +83 -18
- package/dist/docx/serializer/themeSerializer.js +10 -2
- package/dist/docx/server/build.d.ts +1 -1
- package/dist/docx/settingsParser.js +3 -0
- package/dist/docx/strictValueEncodings.gen.d.ts +15 -0
- package/dist/docx/strictValueEncodings.gen.js +275 -0
- package/dist/docx/tableParser.d.ts +0 -6
- package/dist/docx/tableParser.js +52 -7
- package/dist/docx/transitionalSpelling.d.ts +23 -0
- package/dist/docx/transitionalSpelling.js +36 -0
- package/dist/docx/universalMeasure.d.ts +20 -0
- package/dist/docx/universalMeasure.js +32 -0
- package/dist/docx/verbatimCapture.d.ts +20 -0
- package/dist/docx/verbatimCapture.js +131 -0
- package/dist/docx/vmlImageParser.js +4 -3
- package/dist/docx/watermarkParser.d.ts +2 -4
- package/dist/docx/watermarkParser.js +8 -9
- package/dist/docx/xmlParser.d.ts +23 -2
- package/dist/docx/xmlParser.js +43 -11
- package/dist/headless-layout.js +14 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +2 -2
- package/dist/layout-bridge/convert/footnoteLayout.js +23 -10
- package/dist/layout-bridge/convert/headerFooterLayout.js +13 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +96 -13
- package/dist/layout-engine/index.js +11 -4
- package/dist/layout-engine/justifiedLineFit.d.ts +4 -4
- package/dist/layout-engine/justifiedLineFit.js +4 -4
- package/dist/layout-engine/measure/lineBreakProvider.js +1 -0
- package/dist/layout-engine/measure/measureBlocks.js +1 -1
- package/dist/layout-engine/measure/measureParagraph.js +29 -29
- package/dist/layout-painter/renderPage.js +6 -1
- package/dist/layout-painter/renderParagraph.js +18 -8
- package/dist/layout-painter/renderWatermark.js +11 -4
- package/dist/model.d.ts +3 -3
- package/dist/model.js +2 -2
- package/dist/prosemirror/attrs/index.js +11 -0
- package/dist/prosemirror/commands/comments.js +24 -3
- package/dist/prosemirror/containerFinalParagraph.d.ts +47 -0
- package/dist/prosemirror/containerFinalParagraph.js +92 -0
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +47 -9
- package/dist/prosemirror/conversion/toProseDoc.js +61 -14
- package/dist/prosemirror/extensions/core/DocExtension.js +7 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +5 -0
- package/dist/prosemirror/schema/marks.d.ts +3 -9
- package/dist/prosemirror/schema/nodes.d.ts +22 -0
- package/dist/server.d.ts +1 -1
- package/dist/types/block-id.d.ts +12 -1
- package/dist/types/block-id.js +17 -1
- package/dist/utils/canonicalJson.d.ts +14 -0
- package/dist/utils/canonicalJson.js +19 -0
- package/dist/utils/fontResolver.js +51 -0
- package/dist/utils/formatToStyle.d.ts +1 -1
- package/dist/utils/formatToStyle.js +41 -1
- package/dist/watermark/index.js +7 -0
- package/package.json +2 -2
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./ai-edits/types.js";
|
|
2
2
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
3
3
|
import { FolioReviewChange, FolioReviewChangeKind } from "./ai-edits/read.js";
|
|
4
|
-
import { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewChangeFilter, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView } from "./ai-edits/headless.js";
|
|
5
4
|
import { createFolioAITextRangeHandle, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
5
|
+
import { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewChangeFilter, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView } from "./ai-edits/headless.js";
|
|
6
6
|
import { getFolioDocumentOutline, readFolioDocumentSection } from "./ai-edits/scoped-reading.js";
|
|
7
7
|
import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
|
|
8
8
|
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DocumentPreset, DocumentStyleSet } from "./style-sets/types.js";
|
package/dist/types/block-id.d.ts
CHANGED
|
@@ -61,6 +61,17 @@ declare const isBlankFolioBlockId: (id: string) => boolean;
|
|
|
61
61
|
* without an upfront brand check.
|
|
62
62
|
*/
|
|
63
63
|
declare const getFolioParaIdFromBlockId: (id: string) => string | null;
|
|
64
|
+
/**
|
|
65
|
+
* The id a block recorded earlier answers to in the document as parsed now.
|
|
66
|
+
*
|
|
67
|
+
* A paragraph id above the 31-bit bound the schema sets is brought into range
|
|
68
|
+
* on parse, so an id recorded from such a paragraph before that no longer
|
|
69
|
+
* names it. The mapping is a pure function of the id alone, so the recorded id
|
|
70
|
+
* resolves to the current one with no document in hand. Sequential and blank
|
|
71
|
+
* ids carry no paragraph id, and an id the parser would not have mapped is
|
|
72
|
+
* returned as it is.
|
|
73
|
+
*/
|
|
74
|
+
declare const currentFolioBlockId: (id: string) => string;
|
|
64
75
|
/**
|
|
65
76
|
* The 1-based document position encoded in a sequential fallback id
|
|
66
77
|
* (`seq-0011` -> 11), or `null` for paraId-backed ids. The number is
|
|
@@ -76,4 +87,4 @@ declare const getSequentialFolioBlockIdIndex: (id: string) => number | null;
|
|
|
76
87
|
*/
|
|
77
88
|
declare const isFolioBlockId: (value: unknown) => value is FolioBlockId;
|
|
78
89
|
//#endregion
|
|
79
|
-
export { DeriveBlockIdInput, FolioBlockId, deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
|
|
90
|
+
export { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
|
package/dist/types/block-id.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { paraIdInRange } from "../docx/paraIdRangeNormalization.js";
|
|
2
|
+
import { isValidHexId } from "../utils/hexId.js";
|
|
1
3
|
//#region src/types/block-id.ts
|
|
2
4
|
/**
|
|
3
5
|
* Single source of truth for folio block ids.
|
|
@@ -91,6 +93,20 @@ const isBlankFolioBlockId = (id) => BLANK_BLOCK_ID_PATTERN.test(id);
|
|
|
91
93
|
*/
|
|
92
94
|
const getFolioParaIdFromBlockId = (id) => isSequentialFolioBlockId(id) || isBlankFolioBlockId(id) ? null : id;
|
|
93
95
|
/**
|
|
96
|
+
* The id a block recorded earlier answers to in the document as parsed now.
|
|
97
|
+
*
|
|
98
|
+
* A paragraph id above the 31-bit bound the schema sets is brought into range
|
|
99
|
+
* on parse, so an id recorded from such a paragraph before that no longer
|
|
100
|
+
* names it. The mapping is a pure function of the id alone, so the recorded id
|
|
101
|
+
* resolves to the current one with no document in hand. Sequential and blank
|
|
102
|
+
* ids carry no paragraph id, and an id the parser would not have mapped is
|
|
103
|
+
* returned as it is.
|
|
104
|
+
*/
|
|
105
|
+
const currentFolioBlockId = (id) => {
|
|
106
|
+
const paraId = getFolioParaIdFromBlockId(id);
|
|
107
|
+
return paraId !== null && isValidHexId(paraId) ? paraIdInRange(paraId) : id;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
94
110
|
* The 1-based document position encoded in a sequential fallback id
|
|
95
111
|
* (`seq-0011` -> 11), or `null` for paraId-backed ids. The number is
|
|
96
112
|
* the block's position in the same non-empty-block walk both the
|
|
@@ -114,4 +130,4 @@ const isFolioBlockId = (value) => {
|
|
|
114
130
|
return true;
|
|
115
131
|
};
|
|
116
132
|
//#endregion
|
|
117
|
-
export { deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
|
|
133
|
+
export { currentFolioBlockId, deriveBlankBlockId, deriveBlockId, getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex, isBlankFolioBlockId, isFolioBlockId, isSequentialFolioBlockId };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/utils/canonicalJson.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* JSON with object keys in a fixed order, for comparing two values that were
|
|
4
|
+
* built by different code paths.
|
|
5
|
+
*
|
|
6
|
+
* `JSON.stringify` writes keys in insertion order, so two objects holding the
|
|
7
|
+
* same properties compare unequal whenever one was assembled in a different
|
|
8
|
+
* sequence — which is what happens whenever a parsed record is compared with a
|
|
9
|
+
* rebuilt one. `undefined` members are omitted, so an absent property and one
|
|
10
|
+
* explicitly set to `undefined` read alike.
|
|
11
|
+
*/
|
|
12
|
+
declare const canonicalJson: (value: unknown) => string;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { canonicalJson };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/utils/canonicalJson.ts
|
|
2
|
+
/**
|
|
3
|
+
* JSON with object keys in a fixed order, for comparing two values that were
|
|
4
|
+
* built by different code paths.
|
|
5
|
+
*
|
|
6
|
+
* `JSON.stringify` writes keys in insertion order, so two objects holding the
|
|
7
|
+
* same properties compare unequal whenever one was assembled in a different
|
|
8
|
+
* sequence — which is what happens whenever a parsed record is compared with a
|
|
9
|
+
* rebuilt one. `undefined` members are omitted, so an absent property and one
|
|
10
|
+
* explicitly set to `undefined` read alike.
|
|
11
|
+
*/
|
|
12
|
+
const canonicalJson = (value) => {
|
|
13
|
+
if (value === null || value === void 0) return "null";
|
|
14
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
15
|
+
if (typeof value !== "object") return JSON.stringify(value) ?? "null";
|
|
16
|
+
return `{${Object.entries(value).filter(([, entry]) => entry !== void 0).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { canonicalJson };
|
|
@@ -191,6 +191,23 @@ const FONT_MAPPINGS = {
|
|
|
191
191
|
unitsPerEm: 2048
|
|
192
192
|
})
|
|
193
193
|
},
|
|
194
|
+
david: {
|
|
195
|
+
googleFont: "Noto Serif Hebrew",
|
|
196
|
+
category: "serif",
|
|
197
|
+
fallbackStack: [
|
|
198
|
+
"David",
|
|
199
|
+
"Noto Serif Hebrew",
|
|
200
|
+
"Times New Roman",
|
|
201
|
+
"serif"
|
|
202
|
+
],
|
|
203
|
+
singleLineRatio: singleLineRatioOf({
|
|
204
|
+
source: "hhea",
|
|
205
|
+
hheaAscent: 1505,
|
|
206
|
+
hheaDescent: -510,
|
|
207
|
+
hheaLineGap: 0,
|
|
208
|
+
unitsPerEm: 2048
|
|
209
|
+
})
|
|
210
|
+
},
|
|
194
211
|
georgia: {
|
|
195
212
|
googleFont: "Tinos",
|
|
196
213
|
category: "serif",
|
|
@@ -628,6 +645,40 @@ const FONT_MAPPINGS = {
|
|
|
628
645
|
note: "Measured at 11pt against a 15.36pt reference-layout line pitch; the face ships with the office suite, not as a readable font file."
|
|
629
646
|
})
|
|
630
647
|
},
|
|
648
|
+
frankruehl: {
|
|
649
|
+
googleFont: "Frank Ruhl Libre",
|
|
650
|
+
category: "serif",
|
|
651
|
+
fallbackStack: [
|
|
652
|
+
"FrankRuehl",
|
|
653
|
+
"Frank Ruhl Libre",
|
|
654
|
+
"Times New Roman",
|
|
655
|
+
"serif"
|
|
656
|
+
],
|
|
657
|
+
singleLineRatio: singleLineRatioOf({
|
|
658
|
+
source: "hhea",
|
|
659
|
+
hheaAscent: 1462,
|
|
660
|
+
hheaDescent: -442,
|
|
661
|
+
hheaLineGap: 0,
|
|
662
|
+
unitsPerEm: 2048
|
|
663
|
+
})
|
|
664
|
+
},
|
|
665
|
+
miriam: {
|
|
666
|
+
googleFont: "Miriam Libre",
|
|
667
|
+
category: "sans-serif",
|
|
668
|
+
fallbackStack: [
|
|
669
|
+
"Miriam",
|
|
670
|
+
"Miriam Libre",
|
|
671
|
+
"Arial",
|
|
672
|
+
"sans-serif"
|
|
673
|
+
],
|
|
674
|
+
singleLineRatio: singleLineRatioOf({
|
|
675
|
+
source: "hhea",
|
|
676
|
+
hheaAscent: 1546,
|
|
677
|
+
hheaDescent: -512,
|
|
678
|
+
hheaLineGap: 0,
|
|
679
|
+
unitsPerEm: 2048
|
|
680
|
+
})
|
|
681
|
+
},
|
|
631
682
|
"ms mincho": {
|
|
632
683
|
googleFont: "Noto Serif JP",
|
|
633
684
|
category: "serif",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { document_d_exports } from "../types/document.js";
|
|
2
1
|
import { ColorValue } from "../types/colors.js";
|
|
2
|
+
import { document_d_exports } from "../types/document.js";
|
|
3
3
|
import { Properties } from "csstype";
|
|
4
4
|
//#region src/utils/formatToStyle.d.ts
|
|
5
5
|
type CSSProperties = Properties<string | number>;
|
|
@@ -151,6 +151,33 @@ function borderToStyle(border, side = "", theme) {
|
|
|
151
151
|
});
|
|
152
152
|
return style;
|
|
153
153
|
}
|
|
154
|
+
const HALF_STEP_SHADING_PATTERNS = /* @__PURE__ */ new Set([
|
|
155
|
+
"pct12",
|
|
156
|
+
"pct37",
|
|
157
|
+
"pct62",
|
|
158
|
+
"pct87"
|
|
159
|
+
]);
|
|
160
|
+
const AUTO_PATTERN_COLOR = "000000";
|
|
161
|
+
const AUTO_PATTERN_BACKGROUND = "FFFFFF";
|
|
162
|
+
function percentageShadingRatio(pattern) {
|
|
163
|
+
if (!pattern?.startsWith("pct")) return;
|
|
164
|
+
const percentage = Number.parseInt(pattern.slice(3), 10);
|
|
165
|
+
if (!Number.isFinite(percentage)) return;
|
|
166
|
+
return (percentage + (HALF_STEP_SHADING_PATTERNS.has(pattern) ? .5 : 0)) / 100;
|
|
167
|
+
}
|
|
168
|
+
function resolvePatternHex({ color, fallback, theme }) {
|
|
169
|
+
const resolved = resolveShadingColor(color, theme);
|
|
170
|
+
return /^#(?<hex>[0-9A-F]{6})$/iu.exec(resolved)?.groups?.["hex"]?.toUpperCase() ?? fallback;
|
|
171
|
+
}
|
|
172
|
+
function blendShadingColors({ foreground, background, ratio }) {
|
|
173
|
+
const channels = [];
|
|
174
|
+
for (let offset = 0; offset < 6; offset += 2) {
|
|
175
|
+
const foregroundChannel = Number.parseInt(foreground.slice(offset, offset + 2), 16);
|
|
176
|
+
const backgroundChannel = Number.parseInt(background.slice(offset, offset + 2), 16);
|
|
177
|
+
channels.push(Math.round(foregroundChannel * ratio + backgroundChannel * (1 - ratio)).toString(16).padStart(2, "0"));
|
|
178
|
+
}
|
|
179
|
+
return `#${channels.join("").toUpperCase()}`;
|
|
180
|
+
}
|
|
154
181
|
/**
|
|
155
182
|
* Convert ShadingProperties to background color
|
|
156
183
|
*
|
|
@@ -161,13 +188,26 @@ function borderToStyle(border, side = "", theme) {
|
|
|
161
188
|
function resolveShadingFill(shading, theme) {
|
|
162
189
|
if (!shading) return "";
|
|
163
190
|
if (shading.pattern === "nil") return "";
|
|
191
|
+
const percentageRatio = percentageShadingRatio(shading.pattern);
|
|
192
|
+
if (percentageRatio !== void 0) return blendShadingColors({
|
|
193
|
+
foreground: resolvePatternHex({
|
|
194
|
+
color: shading.color,
|
|
195
|
+
fallback: AUTO_PATTERN_COLOR,
|
|
196
|
+
theme
|
|
197
|
+
}),
|
|
198
|
+
background: resolvePatternHex({
|
|
199
|
+
color: shading.fill,
|
|
200
|
+
fallback: AUTO_PATTERN_BACKGROUND,
|
|
201
|
+
theme
|
|
202
|
+
}),
|
|
203
|
+
ratio: percentageRatio
|
|
204
|
+
});
|
|
164
205
|
if (shading.fill) {
|
|
165
206
|
if (shading.fill.auto) return "";
|
|
166
207
|
if (shading.fill.rgb === "auto" || shading.fill.rgb === "FFFFFF") return "";
|
|
167
208
|
return resolveShadingColor(shading.fill, theme);
|
|
168
209
|
}
|
|
169
210
|
if (shading.pattern === "solid" && shading.color) return resolveShadingColor(shading.color, theme);
|
|
170
|
-
if (shading.pattern && shading.pattern.startsWith("pct") && shading.color) return resolveShadingColor(shading.color, theme);
|
|
171
211
|
return "";
|
|
172
212
|
}
|
|
173
213
|
/**
|
package/dist/watermark/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isEmptyParagraph } from "../docx/paragraphParser.js";
|
|
1
2
|
//#region src/watermark/index.ts
|
|
2
3
|
/**
|
|
3
4
|
* Schemes allowed for a picture watermark's external image target
|
|
@@ -42,6 +43,12 @@ function setDocumentWatermark(doc, watermark) {
|
|
|
42
43
|
const nextHeaders = /* @__PURE__ */ new Map();
|
|
43
44
|
if (headers) for (const [rId, header] of headers) {
|
|
44
45
|
const next = { ...header };
|
|
46
|
+
const retainedHostIndex = next.watermarkBlockIndex;
|
|
47
|
+
const retainedHost = next.rawWatermarkXml !== void 0 && retainedHostIndex !== void 0 ? next.content.at(retainedHostIndex) : void 0;
|
|
48
|
+
if (retainedHostIndex !== void 0 && retainedHost?.type === "paragraph" && isEmptyParagraph(retainedHost)) {
|
|
49
|
+
next.content = [...next.content];
|
|
50
|
+
next.content.splice(retainedHostIndex, 1);
|
|
51
|
+
}
|
|
45
52
|
if (watermark === void 0) {
|
|
46
53
|
delete next.watermark;
|
|
47
54
|
delete next.watermarkBlockIndex;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.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",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"perf": "bun scripts/profile-editor.ts"
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
|
-
"@stll/docx-core": "^0.19.
|
|
118
|
+
"@stll/docx-core": "^0.19.2",
|
|
119
119
|
"@stll/docx-utils": "^0.1.0",
|
|
120
120
|
"@stll/template-conditions": "^0.1.0",
|
|
121
121
|
"better-result": "3.0.1",
|