@stll/folio-core 0.33.1 → 0.33.2
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 +134 -25
- 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 +25 -3
- 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 +7 -0
- 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/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 +88 -17
- package/dist/compat/eigenpal.d.ts +4 -4
- package/dist/compat/eigenpal.js +2 -2
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +10 -1
- package/dist/document-operations.js +3 -2
- 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/paragraphParser.js +3 -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 +34 -29
- package/dist/docx/serializer/noteSerializer.js +34 -30
- package/dist/docx/serializer/numberingSerializer.js +8 -4
- package/dist/docx/serializer/paragraphSerializer.js +3 -3
- 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/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.js +4 -3
- package/dist/docx/xmlParser.d.ts +23 -2
- package/dist/docx/xmlParser.js +43 -11
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/model.d.ts +3 -3
- package/dist/model.js +2 -2
- package/dist/prosemirror/commands/comments.js +2 -1
- 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 +15 -4
- package/dist/prosemirror/conversion/toProseDoc.js +12 -3
- package/dist/prosemirror/extensions/nodes/TableExtension.js +5 -0
- package/dist/prosemirror/schema/marks.d.ts +1 -1
- 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/formatToStyle.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
|
|
1
2
|
//#region src/compare/verification.ts
|
|
3
|
+
/**
|
|
4
|
+
* What the round-trip self-check found, and how to say it safely.
|
|
5
|
+
*
|
|
6
|
+
* The check compares two block projections: what accepting the generated
|
|
7
|
+
* revisions leaves against the target, and what rejecting them leaves against
|
|
8
|
+
* the base. A projection carries each block's container, style, list level and
|
|
9
|
+
* text, so WHICH field diverged names which part of the pipeline lost the
|
|
10
|
+
* difference — and that is worth reporting as a typed cause rather than as one
|
|
11
|
+
* opaque "did not reproduce".
|
|
12
|
+
*
|
|
13
|
+
* Every `detail` string here is structural: counts, offsets, container kinds.
|
|
14
|
+
* Never a phrase of either document, because a caller may log it, put it in a
|
|
15
|
+
* report, or quote it in a review.
|
|
16
|
+
*/
|
|
2
17
|
/** The two directions of the round trip, each an invariant of its own. */
|
|
3
18
|
const COMPARE_VERIFICATION_INVARIANTS = Object.freeze(["accept-reproduces-target", "reject-reproduces-base"]);
|
|
4
19
|
/**
|
|
@@ -10,6 +25,7 @@ const COMPARE_VERIFICATION_CAUSES = Object.freeze([
|
|
|
10
25
|
"invisible-structure",
|
|
11
26
|
"block-count",
|
|
12
27
|
"container",
|
|
28
|
+
"table-geometry",
|
|
13
29
|
"style",
|
|
14
30
|
"list-level",
|
|
15
31
|
"inline-formatting",
|
|
@@ -116,6 +132,21 @@ const firstDivergence = (actual, expected) => {
|
|
|
116
132
|
};
|
|
117
133
|
};
|
|
118
134
|
/**
|
|
135
|
+
* The failure two table-geometry projections describe, or `null` when they
|
|
136
|
+
* agree. One line per table, so the detail names which table diverged and
|
|
137
|
+
* whether the count itself did — never a property value, which could carry a
|
|
138
|
+
* style name either document chose.
|
|
139
|
+
*/
|
|
140
|
+
const classifyGeometryMismatch = ({ invariant, story, actual, expected }) => {
|
|
141
|
+
if (sameProjection(actual, expected)) return null;
|
|
142
|
+
return {
|
|
143
|
+
invariant,
|
|
144
|
+
cause: "table-geometry",
|
|
145
|
+
story,
|
|
146
|
+
detail: actual.length === expected.length ? `table ${String(actual.findIndex((entry, index) => entry !== expected[index]))} of ${String(actual.length)} carries different properties` : `${String(actual.length)} tables against ${String(expected.length)}`
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
119
150
|
* The failure two projections describe, or `null` when they agree.
|
|
120
151
|
*
|
|
121
152
|
* Total over the causes by construction: the last branch is unconditional, so
|
|
@@ -142,48 +173,88 @@ const classifyProjectionMismatch = ({ invariant, story, actual, expected }) => {
|
|
|
142
173
|
if (actual.length !== expected.length) return failure("block-count", `${counts}, first differing ${at}`);
|
|
143
174
|
return failure("text", `a ${containerKind(left.container)} block's text does not match ${at}, length ${String(left.text.length)} against ${String(right.text.length)} (${counts})`);
|
|
144
175
|
};
|
|
145
|
-
|
|
146
|
-
const JOINS_FORWARD_ON_ACCEPT = Object.freeze(["del", "moveFrom"]);
|
|
147
|
-
const joinsForwardOnAccept = (value) => JOINS_FORWARD_ON_ACCEPT.some((kind) => kind === value);
|
|
176
|
+
const isAParagraphMarkChangeKind = (value) => PARAGRAPH_MARK_CHANGE_KINDS.some((kind) => kind === value);
|
|
148
177
|
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
149
178
|
const isParagraph = (value) => isRecord(value) && value["type"] === "paragraph";
|
|
150
179
|
/**
|
|
151
|
-
*
|
|
180
|
+
* A row the package marks deleted, whose cells' marks go with it.
|
|
152
181
|
*
|
|
153
|
-
* A deleted
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
|
|
182
|
+
* A deleted table row is written as `w:trPr/w:del` PLUS a deletion on every
|
|
183
|
+
* mark the row's cells end with: accepting takes the whole row away, so those
|
|
184
|
+
* marks never have to join anything and are the shape the format asks for.
|
|
185
|
+
*/
|
|
186
|
+
const isADeletedTableRow = (value) => {
|
|
187
|
+
const change = value["structuralChange"];
|
|
188
|
+
return isRecord(change) && change["type"] === "tableRowDeletion";
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Every container in a package whose final paragraph mark carries a revision.
|
|
192
|
+
*
|
|
193
|
+
* A deleted paragraph mark says "join this paragraph with the one after it",
|
|
194
|
+
* and an inserted one says that break was ADDED, so rejecting it closes the
|
|
195
|
+
* paragraph back over the next one. The last paragraph of a body, a table
|
|
196
|
+
* cell, a header or footer, a note or a text box has no paragraph after it, so
|
|
197
|
+
* neither direction states an edit that can be carried out: a consumer refuses
|
|
198
|
+
* the package, or opens it and leaves a revision standing that neither
|
|
199
|
+
* accepting nor rejecting everything can clear. The exception is a cell of a
|
|
200
|
+
* row the package is DELETING: there the mark leaves with its row.
|
|
157
201
|
*
|
|
158
202
|
* The walk is over the package model rather than over a list of the containers
|
|
159
203
|
* known today: a container is any sequence that ends in a paragraph, so a part
|
|
160
204
|
* the model grows later is covered the day it arrives instead of the day
|
|
161
205
|
* someone remembers this function.
|
|
206
|
+
*
|
|
207
|
+
* `since` scopes it to the revisions a comparison MINTED: a base may arrive
|
|
208
|
+
* carrying one of these on a paragraph in a part no story mounts, which folio
|
|
209
|
+
* preserves the way it preserves everything else it parses. What this proves
|
|
210
|
+
* is that the comparison writes none of its own.
|
|
162
211
|
*/
|
|
163
|
-
const
|
|
212
|
+
const revisedFinalParagraphMarks = (packageModel, { since = 0 } = {}) => {
|
|
164
213
|
const found = [];
|
|
165
|
-
const
|
|
214
|
+
const trail = ["package"];
|
|
215
|
+
const pathOf = () => {
|
|
216
|
+
let path = "";
|
|
217
|
+
for (const segment of trail) path += typeof segment === "number" ? `[${String(segment)}]` : `.${segment}`;
|
|
218
|
+
return path.slice(1);
|
|
219
|
+
};
|
|
220
|
+
const visit = (value, insideADeletedRow) => {
|
|
166
221
|
if (Array.isArray(value)) {
|
|
167
222
|
const last = value.at(-1);
|
|
168
223
|
const mark = isParagraph(last) ? last["pPrMark"] : void 0;
|
|
169
224
|
const kind = isRecord(mark) ? mark["kind"] : void 0;
|
|
170
|
-
|
|
171
|
-
|
|
225
|
+
const info = isRecord(mark) ? mark["info"] : void 0;
|
|
226
|
+
const revisionId = isRecord(info) ? info["id"] : void 0;
|
|
227
|
+
const isOurs = typeof revisionId === "number" ? revisionId >= since : true;
|
|
228
|
+
if (isAParagraphMarkChangeKind(kind) && isOurs && !insideADeletedRow) found.push({
|
|
229
|
+
container: pathOf(),
|
|
172
230
|
paragraphIndex: value.length - 1,
|
|
173
231
|
kind
|
|
174
232
|
});
|
|
175
|
-
for (const [index, item] of value.entries())
|
|
233
|
+
for (const [index, item] of value.entries()) {
|
|
234
|
+
trail.push(index);
|
|
235
|
+
visit(item, insideADeletedRow);
|
|
236
|
+
trail.pop();
|
|
237
|
+
}
|
|
176
238
|
return;
|
|
177
239
|
}
|
|
178
240
|
if (value instanceof Map) {
|
|
179
|
-
for (const [key, item] of value)
|
|
241
|
+
for (const [key, item] of value) {
|
|
242
|
+
trail.push(String(key));
|
|
243
|
+
visit(item, insideADeletedRow);
|
|
244
|
+
trail.pop();
|
|
245
|
+
}
|
|
180
246
|
return;
|
|
181
247
|
}
|
|
182
248
|
if (!isRecord(value) || value instanceof Date || ArrayBuffer.isView(value)) return;
|
|
183
|
-
|
|
249
|
+
const inADeletedRow = insideADeletedRow || isADeletedTableRow(value);
|
|
250
|
+
for (const [key, item] of Object.entries(value)) {
|
|
251
|
+
trail.push(key);
|
|
252
|
+
visit(item, inADeletedRow);
|
|
253
|
+
trail.pop();
|
|
254
|
+
}
|
|
184
255
|
};
|
|
185
|
-
visit(packageModel,
|
|
256
|
+
visit(packageModel, false);
|
|
186
257
|
return found;
|
|
187
258
|
};
|
|
188
259
|
//#endregion
|
|
189
|
-
export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS,
|
|
260
|
+
export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, classifyGeometryMismatch, classifyProjectionMismatch, projectSupportedInlineFormatting, revisedFinalParagraphMarks, sameProjection };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
1
2
|
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
|
|
2
3
|
import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "../ai-edits/word-diff.js";
|
|
3
4
|
import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "../ai-edits/apply.js";
|
|
4
|
-
import { document_d_exports } from "../types/document.js";
|
|
5
5
|
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, 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, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
6
6
|
import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
|
|
7
|
-
import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
7
|
+
import { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
8
8
|
import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput, AISuggestion, AISuggestionApplyMode, AISuggestionPreset, AISuggestionSeverity, AISuggestionStatus, DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
|
|
9
9
|
import { ApplyResult, applySuggestions } from "../ai-suggestions/apply.js";
|
|
10
10
|
import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
|
|
11
11
|
import { PositionalText, buildPositionalText } from "../ai-suggestions/text-positions.js";
|
|
12
|
-
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant,
|
|
12
|
+
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision } from "../compare/verification.js";
|
|
13
13
|
import { COMPARE_UNSUPPORTED_REASONS, CompareChange, CompareChangeLocation, CompareDocxApplyError, CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, CompareFormatRange, CompareResult, CompareUnsupportedPart, CompareUnsupportedReason, InvalidCompareDocxOptionsError } from "../compare/types.js";
|
|
14
14
|
import { MAX_COMPARE_OPERATIONS, compareDocx } from "../compare/compare.js";
|
|
15
15
|
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DocumentPreset, DocumentStyleSet } from "../style-sets/types.js";
|
|
@@ -37,4 +37,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
37
37
|
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
38
38
|
type Document = document_d_exports.Document;
|
|
39
39
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
40
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type
|
|
40
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/compat/eigenpal.js
CHANGED
|
@@ -27,8 +27,8 @@ import { clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu
|
|
|
27
27
|
import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
|
|
28
28
|
import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
|
|
29
29
|
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "../style-sets/types.js";
|
|
30
|
-
import { deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
30
|
+
import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
31
31
|
import { createEmptyDocument } from "../utils/createDocument.js";
|
|
32
32
|
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
33
33
|
import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
|
|
34
|
-
export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
34
|
+
export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -15,7 +15,7 @@ import { hasComplexScript, isComplexScriptCodePoint } from "../utils/scriptSegme
|
|
|
15
15
|
* advances rightward from its origin whatever the paragraph does.
|
|
16
16
|
*/
|
|
17
17
|
declare const glyphCellOffsetsPx: (run: DisplayGlyphRun) => readonly number[];
|
|
18
|
-
declare const DISPLAY_PRIMITIVE_KINDS: ("
|
|
18
|
+
declare const DISPLAY_PRIMITIVE_KINDS: ("glyphRun" | "rect" | "line" | "image" | "clipGroup" | "rotateGroup" | "opacityGroup")[];
|
|
19
19
|
/**
|
|
20
20
|
* Dash geometry of each stroke pattern, as multiples of the stroke thickness.
|
|
21
21
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FolioTableTemplates } from "./ai-edits/table-template.js";
|
|
1
2
|
import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditNormalization, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAITextRangeHandle } from "./ai-edits/types.js";
|
|
2
3
|
import { FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions } from "./ai-edits/apply.js";
|
|
3
4
|
//#region src/document-operations.d.ts
|
|
@@ -266,7 +267,15 @@ type ApplyFolioDocumentOperationsOptions = {
|
|
|
266
267
|
revisionStamp?: FolioRevisionStamp;
|
|
267
268
|
/** Token size a replacement's redline is cut at. Word-level by default. */
|
|
268
269
|
wordDiff?: FolioWordDiffOptions;
|
|
270
|
+
/**
|
|
271
|
+
* Tables and rows an `insertTable` / `insertTableRow` in the batch places
|
|
272
|
+
* verbatim, by operation id. Outside the serialized batch because a table
|
|
273
|
+
* node is not JSON: the contract still describes a table by its cell texts,
|
|
274
|
+
* and an in-process caller that already holds the table — a comparison
|
|
275
|
+
* copying the target document's — hands the whole thing over instead.
|
|
276
|
+
*/
|
|
277
|
+
tableTemplates?: FolioTableTemplates;
|
|
269
278
|
};
|
|
270
|
-
declare const applyFolioDocumentOperations: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff }: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
|
|
279
|
+
declare const applyFolioDocumentOperations: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates }: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
|
|
271
280
|
//#endregion
|
|
272
281
|
export { ApplyFolioDocumentOperationsOptions, 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, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
@@ -879,7 +879,7 @@ const getFolioDocumentOperationReceiptsForStory = ({ operations, applied, story
|
|
|
879
879
|
});
|
|
880
880
|
return receipts;
|
|
881
881
|
};
|
|
882
|
-
const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", author, createCommentId, createUndoHandle, revisionStamp, wordDiff }) => {
|
|
882
|
+
const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates }) => {
|
|
883
883
|
const parsedBatch = parseFolioDocumentOperationBatch(batch);
|
|
884
884
|
const apply = ({ targetView, targetCreateCommentId = createCommentId, preview = false }) => {
|
|
885
885
|
return (preview ? previewFolioAIEditOperations : applyFolioAIEditOperations)({
|
|
@@ -890,7 +890,8 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
890
890
|
...author !== void 0 && { author },
|
|
891
891
|
...targetCreateCommentId !== void 0 && { createCommentId: targetCreateCommentId },
|
|
892
892
|
...revisionStamp !== void 0 && { revisionStamp },
|
|
893
|
-
...wordDiff !== void 0 && { wordDiff }
|
|
893
|
+
...wordDiff !== void 0 && { wordDiff },
|
|
894
|
+
...tableTemplates !== void 0 && { tableTemplates }
|
|
894
895
|
});
|
|
895
896
|
};
|
|
896
897
|
const preview = () => apply({
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/docx/appVersionNormalization.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Keep the application version a package states about itself in the form the
|
|
4
|
+
* schema gives it.
|
|
5
|
+
*
|
|
6
|
+
* `AppVersion` in the extended-properties part is `XX.YYYY`: a one- or
|
|
7
|
+
* two-digit integer, a dot, and four digits. Producers exist that write a
|
|
8
|
+
* three-part version there instead, and folio copies `docProps/app.xml`
|
|
9
|
+
* through verbatim when it saves a document it did not create — so a package
|
|
10
|
+
* can carry a value with two dots in, and a save that copies it out hands a
|
|
11
|
+
* consumer a package it refuses to open at all.
|
|
12
|
+
*
|
|
13
|
+
* {@link appVersionInSchemaForm} is the one mapping, and it is a pure function
|
|
14
|
+
* of the value alone: it keeps the leading integer where the value opens with
|
|
15
|
+
* one the form allows, and writes the build digits the form requires. Nothing
|
|
16
|
+
* else in the part is touched, and a package that carries no extended
|
|
17
|
+
* properties keeps carrying none — synthesizing metadata a document never
|
|
18
|
+
* stated is a different decision.
|
|
19
|
+
*/
|
|
20
|
+
declare const AppVersionSchemaError_base: import("better-result").TaggedErrorClass<"AppVersionSchemaError">;
|
|
21
|
+
/**
|
|
22
|
+
* A value reached the package that the schema form does not accept.
|
|
23
|
+
*
|
|
24
|
+
* The normalization hands every value it writes to one choke point, which
|
|
25
|
+
* throws this rather than letting the package go out carrying a version a
|
|
26
|
+
* consumer refuses.
|
|
27
|
+
*/
|
|
28
|
+
declare class AppVersionSchemaError extends AppVersionSchemaError_base<{
|
|
29
|
+
message: string;
|
|
30
|
+
appVersion: string;
|
|
31
|
+
}> {}
|
|
32
|
+
/**
|
|
33
|
+
* `value` when it already fits, and a value derived from it when it does not.
|
|
34
|
+
*
|
|
35
|
+
* The derivation reads the value and nothing else — not the package, not the
|
|
36
|
+
* clock, not folio's own version — so two saves of one document state the same
|
|
37
|
+
* application version.
|
|
38
|
+
*/
|
|
39
|
+
declare const appVersionInSchemaForm: (value: string) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Rewrite the application version an extended-properties part states.
|
|
42
|
+
*
|
|
43
|
+
* Returns the part unchanged when the value already fits and when the part
|
|
44
|
+
* states no version at all, so a save of a document that never carried a
|
|
45
|
+
* malformed one is byte-identical.
|
|
46
|
+
*/
|
|
47
|
+
declare const normalizeAppVersionInExtendedProperties: (xml: string) => string;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { AppVersionSchemaError, appVersionInSchemaForm, normalizeAppVersionInExtendedProperties };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { TaggedError } from "better-result";
|
|
2
|
+
//#region src/docx/appVersionNormalization.ts
|
|
3
|
+
/**
|
|
4
|
+
* Keep the application version a package states about itself in the form the
|
|
5
|
+
* schema gives it.
|
|
6
|
+
*
|
|
7
|
+
* `AppVersion` in the extended-properties part is `XX.YYYY`: a one- or
|
|
8
|
+
* two-digit integer, a dot, and four digits. Producers exist that write a
|
|
9
|
+
* three-part version there instead, and folio copies `docProps/app.xml`
|
|
10
|
+
* through verbatim when it saves a document it did not create — so a package
|
|
11
|
+
* can carry a value with two dots in, and a save that copies it out hands a
|
|
12
|
+
* consumer a package it refuses to open at all.
|
|
13
|
+
*
|
|
14
|
+
* {@link appVersionInSchemaForm} is the one mapping, and it is a pure function
|
|
15
|
+
* of the value alone: it keeps the leading integer where the value opens with
|
|
16
|
+
* one the form allows, and writes the build digits the form requires. Nothing
|
|
17
|
+
* else in the part is touched, and a package that carries no extended
|
|
18
|
+
* properties keeps carrying none — synthesizing metadata a document never
|
|
19
|
+
* stated is a different decision.
|
|
20
|
+
*/
|
|
21
|
+
/** `XX.YYYY`: the only form the extended-properties `AppVersion` may take. */
|
|
22
|
+
const SCHEMA_FORM = /^\d{1,2}\.\d{4}$/u;
|
|
23
|
+
/** The leading integer, when the value opens with one the form allows. */
|
|
24
|
+
const LEADING_MAJOR = /^\d{1,2}(?!\d)/u;
|
|
25
|
+
/** Major version for a value that does not open with one. */
|
|
26
|
+
const DEFAULT_MAJOR = "1";
|
|
27
|
+
/**
|
|
28
|
+
* The build digits a rewritten value gets. A value the form rejects states no
|
|
29
|
+
* build this pass could carry over, so every rewrite lands on the same one.
|
|
30
|
+
*/
|
|
31
|
+
const CANONICAL_BUILD = "0000";
|
|
32
|
+
/**
|
|
33
|
+
* A value reached the package that the schema form does not accept.
|
|
34
|
+
*
|
|
35
|
+
* The normalization hands every value it writes to one choke point, which
|
|
36
|
+
* throws this rather than letting the package go out carrying a version a
|
|
37
|
+
* consumer refuses.
|
|
38
|
+
*/
|
|
39
|
+
var AppVersionSchemaError = class extends TaggedError("AppVersionSchemaError") {};
|
|
40
|
+
/**
|
|
41
|
+
* `value` when it already fits, and a value derived from it when it does not.
|
|
42
|
+
*
|
|
43
|
+
* The derivation reads the value and nothing else — not the package, not the
|
|
44
|
+
* clock, not folio's own version — so two saves of one document state the same
|
|
45
|
+
* application version.
|
|
46
|
+
*/
|
|
47
|
+
const appVersionInSchemaForm = (value) => {
|
|
48
|
+
if (SCHEMA_FORM.test(value)) return value;
|
|
49
|
+
const normalized = `${LEADING_MAJOR.exec(value.trim())?.[0] ?? DEFAULT_MAJOR}.${CANONICAL_BUILD}`;
|
|
50
|
+
if (!SCHEMA_FORM.test(normalized)) throw new AppVersionSchemaError({
|
|
51
|
+
message: `Derived application version ${normalized} is not of the form XX.YYYY`,
|
|
52
|
+
appVersion: value
|
|
53
|
+
});
|
|
54
|
+
return normalized;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The element and its content, with the prefix and attributes it was written
|
|
58
|
+
* with preserved: the replacement rewrites the value between the tags and
|
|
59
|
+
* leaves the rest of the part byte-identical.
|
|
60
|
+
*/
|
|
61
|
+
const APP_VERSION_ELEMENT = /(<(?:[^\s<>/:]+:)?AppVersion(?:\s[^<>]*)?>)([^<]*)(<\/(?:[^\s<>/:]+:)?AppVersion>)/u;
|
|
62
|
+
/**
|
|
63
|
+
* Rewrite the application version an extended-properties part states.
|
|
64
|
+
*
|
|
65
|
+
* Returns the part unchanged when the value already fits and when the part
|
|
66
|
+
* states no version at all, so a save of a document that never carried a
|
|
67
|
+
* malformed one is byte-identical.
|
|
68
|
+
*/
|
|
69
|
+
const normalizeAppVersionInExtendedProperties = (xml) => xml.replace(APP_VERSION_ELEMENT, (whole, open, value, close) => {
|
|
70
|
+
const replacement = appVersionInSchemaForm(value);
|
|
71
|
+
return replacement === value ? whole : `${open}${replacement}${close}`;
|
|
72
|
+
});
|
|
73
|
+
//#endregion
|
|
74
|
+
export { AppVersionSchemaError, appVersionInSchemaForm, normalizeAppVersionInExtendedProperties };
|
|
@@ -6,7 +6,8 @@ import { parseParagraph } from "./paragraphParser.js";
|
|
|
6
6
|
import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
|
|
7
7
|
import { parseSdtProperties } from "./sdtProperties.js";
|
|
8
8
|
import { parseTable } from "./tableParser.js";
|
|
9
|
-
import {
|
|
9
|
+
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
10
|
+
import { findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
|
|
10
11
|
//#region src/docx/blockContentParser.ts
|
|
11
12
|
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList, siblingNumIdsByAbstractNumId }) => {
|
|
12
13
|
const listRendering = paragraph.listRendering;
|
|
@@ -192,7 +193,7 @@ const captureSdtSiblingMarkers = (sdt) => {
|
|
|
192
193
|
sawContent = true;
|
|
193
194
|
continue;
|
|
194
195
|
}
|
|
195
|
-
const xml =
|
|
196
|
+
const xml = captureVerbatimXml(ch);
|
|
196
197
|
if (sawContent) afterParts.push(xml);
|
|
197
198
|
else beforeParts.push(xml);
|
|
198
199
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ImageHorizontalAlignmentSchema, ImageHorizontalRelativeToSchema, ImageVerticalAlignmentSchema, ImageVerticalRelativeToSchema, ImageWrapTextSchema, ShapeOutlineStyleSchema, narrowEnum } from "./parserEnums.js";
|
|
2
|
-
import {
|
|
2
|
+
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
3
|
+
import { findByFullName, findChildByLocalName, findChildrenByLocalName, getAttribute, getChildElements, getTextContent, parseNumericAttribute } from "./xmlParser.js";
|
|
3
4
|
//#region src/docx/drawingUtils.ts
|
|
4
5
|
/**
|
|
5
6
|
* Map OOXML scheme names to standard theme color slots.
|
|
@@ -162,7 +163,7 @@ function parseGradientFill(gradientFill) {
|
|
|
162
163
|
}
|
|
163
164
|
return {
|
|
164
165
|
type: "gradient",
|
|
165
|
-
rawXml:
|
|
166
|
+
rawXml: captureVerbatimXml(gradientFill),
|
|
166
167
|
gradient: {
|
|
167
168
|
type,
|
|
168
169
|
...angle !== void 0 ? { angle } : {},
|
|
@@ -177,7 +178,7 @@ function parseOutline(spPr) {
|
|
|
177
178
|
const ln = spPr ? findChildByLocalName(spPr, "ln") : null;
|
|
178
179
|
if (!ln) return;
|
|
179
180
|
if (findChildByLocalName(ln, "noFill")) return;
|
|
180
|
-
const outline = { rawXml:
|
|
181
|
+
const outline = { rawXml: captureVerbatimXml(ln) };
|
|
181
182
|
const w = getAttribute(ln, null, "w");
|
|
182
183
|
if (w) {
|
|
183
184
|
const parsed = Number.parseInt(w, 10);
|
|
@@ -10,7 +10,8 @@ import { consolidateParagraphContent } from "./runConsolidator.js";
|
|
|
10
10
|
import { parseRun, parseRunProperties } from "./runParser.js";
|
|
11
11
|
import { parseSdtProperties } from "./sdtProperties.js";
|
|
12
12
|
import { parseSectionProperties } from "./sectionParser.js";
|
|
13
|
-
import {
|
|
13
|
+
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
14
|
+
import { WORDPROCESSINGML_NAMESPACE_URIS, findChild, findChildByNamespaceUri, findChildren, getAttribute, getChildElements, getLocalName, matchesName, mergeXmlnsDeclarations, parseBooleanElement, parseNumberingLevelAttribute, parseNumericAttribute } from "./xmlParser.js";
|
|
14
15
|
import { panic } from "better-result";
|
|
15
16
|
import { PARAGRAPH_MARK_CHANGE_KINDS, normalizeRevisionId } from "@stll/docx-core/model";
|
|
16
17
|
//#region src/docx/paragraphParser.ts
|
|
@@ -995,7 +996,7 @@ function parseParagraphContents(paraElement, styles, theme, _numbering, rels, me
|
|
|
995
996
|
case "oMath":
|
|
996
997
|
case "oMathPara": {
|
|
997
998
|
const isBlock = localName === "oMathPara";
|
|
998
|
-
const ommlXml =
|
|
999
|
+
const ommlXml = captureVerbatimXml(child);
|
|
999
1000
|
const plainText = extractMathText(child);
|
|
1000
1001
|
const mathEq = {
|
|
1001
1002
|
type: "mathEquation",
|
package/dist/docx/rezip.d.ts
CHANGED
|
@@ -106,11 +106,11 @@ declare function updateMultipleFiles(originalBuffer: ArrayBuffer, updates: Map<s
|
|
|
106
106
|
* Apply file updates to an already-loaded JSZip instance and generate the output.
|
|
107
107
|
* Use this when the zip is already loaded to avoid a redundant decompression pass.
|
|
108
108
|
*
|
|
109
|
-
* This is the selective save's exit, so it owes the package the same
|
|
109
|
+
* This is the selective save's exit, so it owes the package the same passes
|
|
110
110
|
* {@link generateDocxZip} runs: a save that rewrites only the changed
|
|
111
111
|
* paragraphs still has to see the parts it left alone, both to know which
|
|
112
|
-
* revision ids are free and because an out-of-range paragraph id
|
|
113
|
-
* part it never touched.
|
|
112
|
+
* revision ids are free and because an out-of-range paragraph id, or a
|
|
113
|
+
* malformed application version, can sit in a part it never touched.
|
|
114
114
|
*/
|
|
115
115
|
declare function applyUpdatesToZip(zip: JSZip, updates: Map<string, string | ArrayBuffer>, options?: RepackOptions): Promise<ArrayBuffer>;
|
|
116
116
|
/**
|
|
@@ -159,7 +159,13 @@ declare function hasUnmaterializedHeaderFooter(doc: document_d_exports.Document)
|
|
|
159
159
|
* have been set without yet resolving in that header's rels).
|
|
160
160
|
*/
|
|
161
161
|
declare function hasModelDrivenPictureWatermark(doc: document_d_exports.Document): boolean;
|
|
162
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Re-serialize every header/footer the model still owns, keyed by part path.
|
|
164
|
+
*
|
|
165
|
+
* `sourceZip` supplies each part as it stands before the save so the rebuilt
|
|
166
|
+
* root can keep any prefix binding only the source document declared.
|
|
167
|
+
*/
|
|
168
|
+
declare function collectHeaderFooterUpdates(doc: document_d_exports.Document, sourceZip: JSZip): Promise<Map<string, string>>;
|
|
163
169
|
/** `word/Footnotes.xml` -> `word/_rels/Footnotes.xml.rels` (casing preserved). */
|
|
164
170
|
declare function notePartRelsPath(partPath: string): string;
|
|
165
171
|
/** Update existing core-property values without synthesizing absent metadata. */
|