@stll/folio-core 0.37.1 → 0.37.3
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 +24 -1
- package/dist/ai-edits/headless.js +108 -71
- package/dist/ai-edits/read.d.ts +9 -1
- package/dist/ai-edits/read.js +34 -16
- package/dist/ai-edits/snapshot.d.ts +7 -5
- package/dist/ai-edits/snapshot.js +39 -12
- package/dist/ai-edits/table-cell-mutations.js +10 -5
- package/dist/ai-edits/table-template.js +19 -5
- package/dist/compare/compare.d.ts +2 -3
- package/dist/compare/compare.js +41 -64
- package/dist/compare/content-alignment.js +0 -1
- package/dist/compare/scenario.d.ts +11 -2
- package/dist/compare/scenario.js +6 -2
- package/dist/controller/hiddenEditorManager.js +11 -0
- package/dist/controller/layoutPipeline.js +1 -1
- package/dist/display-list/build/textBoxPrimitives.js +34 -1
- package/dist/display-list/dom/renderDisplayListToDom.js +5 -2
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/display-list/types.d.ts +8 -4
- package/dist/docx/paragraphPropertySource.d.ts +82 -2
- package/dist/docx/paragraphPropertySource.js +569 -3
- package/dist/docx/parser.js +9 -0
- package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
- package/dist/docx/server/materializeYjsDocx.js +21 -2
- package/dist/headless-layout.js +1 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +7 -1
- package/dist/layout-bridge/convert/headerFooterLayout.js +20 -3
- package/dist/layout-bridge/convert/toFlowBlocks.js +43 -12
- package/dist/layout-engine/index.js +20 -10
- package/dist/layout-engine/measure/measureBlocks.d.ts +7 -3
- package/dist/layout-engine/measure/measureBlocks.js +10 -7
- package/dist/layout-engine/measure/measureParagraph.d.ts +2 -0
- package/dist/layout-engine/measure/measureParagraph.js +1 -1
- package/dist/layout-engine/paginator.d.ts +1 -1
- package/dist/layout-engine/paginator.js +41 -4
- package/dist/layout-engine/textBoxFlow.d.ts +2 -0
- package/dist/layout-engine/textBoxFlow.js +9 -5
- package/dist/layout-engine/types.d.ts +6 -0
- package/dist/layout-painter/documentColors.d.ts +10 -1
- package/dist/layout-painter/documentColors.js +16 -1
- package/dist/layout-painter/renderParagraph.js +9 -24
- package/dist/layout-painter/renderTable.js +3 -3
- package/dist/layout-painter/renderTextBox.js +2 -1
- package/dist/pdf/pageSpace.d.ts +12 -1
- package/dist/pdf/pageSpace.js +24 -1
- package/dist/pdf/paint.js +2 -2
- package/dist/prosemirror/attrs/index.js +19 -8
- package/dist/prosemirror/commands/comments.js +12 -3
- package/dist/prosemirror/commands/tableCellMergeResolution.js +18 -11
- package/dist/prosemirror/conversion/fromProseDoc.js +94 -21
- package/dist/prosemirror/conversion/toProseDoc.js +100 -8
- package/dist/prosemirror/extensions/core/DocExtension.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +5 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +132 -41
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
- package/dist/prosemirror/schema/nodes.d.ts +3 -1
- package/dist/prosemirror/yjsParagraphSourceContract.d.ts +9 -0
- package/dist/prosemirror/yjsParagraphSourceContract.js +26 -0
- package/dist/utils/rotationBoundingBox.d.ts +5 -1
- package/dist/utils/rotationBoundingBox.js +9 -1
- package/package.json +2 -2
|
@@ -122,6 +122,22 @@ type FolioApplyDocumentOperationsToStoryOptions = FolioApplyDocumentOperationsOp
|
|
|
122
122
|
*/
|
|
123
123
|
tableTemplates?: FolioTableTemplates;
|
|
124
124
|
};
|
|
125
|
+
type FolioDocxComparisonProjectionMode = "with-revision-census" | "without-revision-census";
|
|
126
|
+
type FolioDocxComparisonStoryProjection = {
|
|
127
|
+
handle: FolioDocumentStoryHandle;
|
|
128
|
+
snapshot: FolioAIEditSnapshot | null;
|
|
129
|
+
};
|
|
130
|
+
type FolioDocxComparisonProjection = {
|
|
131
|
+
stories: readonly FolioDocxComparisonStoryProjection[];
|
|
132
|
+
revisions: {
|
|
133
|
+
highestId: number;
|
|
134
|
+
present: boolean;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
type FolioDocxComparisonAccess = {
|
|
138
|
+
projectStories: (mode: FolioDocxComparisonProjectionMode) => FolioDocxComparisonProjection;
|
|
139
|
+
snapshotReviewedStory: (options?: FolioReadReviewedStoryOptions) => FolioAIEditSnapshot | null;
|
|
140
|
+
};
|
|
125
141
|
declare const isFolioReviewedView: (value: unknown) => value is FolioReviewedView;
|
|
126
142
|
declare const isFolioResolvedReviewedView: (value: unknown) => value is FolioResolvedReviewedView;
|
|
127
143
|
/** Filter for {@link FolioDocxReviewer.getChanges}. */
|
|
@@ -222,6 +238,8 @@ declare class FolioDocxReviewer {
|
|
|
222
238
|
getDocumentProperties(): Readonly<NonNullable<document_d_exports.Document["package"]["properties"]>> | null;
|
|
223
239
|
/** Snapshot one editable story into stable, operation-ready blocks. */
|
|
224
240
|
snapshotStory(story: FolioEditableDocumentStoryHandle): FolioAIEditSnapshot | null;
|
|
241
|
+
private snapshotReviewedStoryInternal;
|
|
242
|
+
private projectComparisonStoriesInternal;
|
|
225
243
|
/**
|
|
226
244
|
* One story's tables, in the document order {@link snapshotStory} numbers
|
|
227
245
|
* them with, read through a reviewed view.
|
|
@@ -249,6 +267,7 @@ declare class FolioDocxReviewer {
|
|
|
249
267
|
readReviewedStory(options?: FolioReadReviewedStoryOptions): FolioReviewedStory | null;
|
|
250
268
|
/** Resolve one editable story to its original or final state. */
|
|
251
269
|
resolveReviewedStory({ story, view }: FolioResolveReviewedStoryOptions): boolean;
|
|
270
|
+
private resolveReviewedStorySnapshotInternal;
|
|
252
271
|
/**
|
|
253
272
|
* Apply operations against the current state. Reuses the live-editor applier
|
|
254
273
|
* verbatim via a headless `{ state, dispatch }` seam; the resulting state
|
|
@@ -292,6 +311,7 @@ declare class FolioDocxReviewer {
|
|
|
292
311
|
* parts and separator notes are omitted.
|
|
293
312
|
*/
|
|
294
313
|
getNotesAsText(): string;
|
|
314
|
+
private listStoryHandlesInternal;
|
|
295
315
|
/** Discover every readable document story through a typed, serializable handle. */
|
|
296
316
|
listStories(): FolioDocumentStory[];
|
|
297
317
|
/** Read one discovered story; returns null when its handle is no longer present. */
|
|
@@ -386,6 +406,7 @@ declare class FolioDocxReviewer {
|
|
|
386
406
|
private getNoteStory;
|
|
387
407
|
private getHeaderFooterStoryText;
|
|
388
408
|
private getNoteStoryText;
|
|
409
|
+
private getStoryText;
|
|
389
410
|
private mergeEditedSecondaryStories;
|
|
390
411
|
/** Apply any {@link resolveComment} overrides recorded for these comments. */
|
|
391
412
|
private withResolvedOverrides;
|
|
@@ -401,6 +422,8 @@ declare class FolioDocxReviewer {
|
|
|
401
422
|
private runCommand;
|
|
402
423
|
private runStoryCommand;
|
|
403
424
|
}
|
|
425
|
+
/** @internal Comparison-only access to atomic and fresh reviewer projections. */
|
|
426
|
+
declare const getFolioDocxComparisonAccess: (reviewer: FolioDocxReviewer) => FolioDocxComparisonAccess;
|
|
404
427
|
/** Options for {@link applyFolioAIEditsToBuffer}. */
|
|
405
428
|
type ApplyFolioAIEditsToBufferOptions = {
|
|
406
429
|
/** Default author for tracked changes and comments. (default: `"AI"`) */
|
|
@@ -428,4 +451,4 @@ type ApplyFolioAIEditsToBufferResult = FolioAIEditApplyResult & {
|
|
|
428
451
|
*/
|
|
429
452
|
declare const applyFolioAIEditsToBuffer: (buffer: ArrayBuffer, operations: FolioAIEditOperation[], options?: ApplyFolioAIEditsToBufferOptions) => Promise<ApplyFolioAIEditsToBufferResult>;
|
|
430
453
|
//#endregion
|
|
431
|
-
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioGetContentAsTextOptions, FolioMatchStoryTableGeometryOptions, FolioNumberingLevel, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, type FolioRevisionStamp, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView };
|
|
454
|
+
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioGetContentAsTextOptions, FolioMatchStoryTableGeometryOptions, FolioNumberingLevel, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, type FolioRevisionStamp, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, getFolioDocxComparisonAccess, isFolioResolvedReviewedView, isFolioReviewedView };
|
|
@@ -18,10 +18,10 @@ import { createDocumentStylesPlugin, getDocumentStyleResolver } from "../prosemi
|
|
|
18
18
|
import { schema, singletonManager } from "../prosemirror/schema/index.js";
|
|
19
19
|
import { deterministicHexId } from "../utils/hexId.js";
|
|
20
20
|
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
21
|
-
import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
22
|
-
import { createFolioAIEditSnapshotWithStyleResolver, folioStoryTables, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
21
|
+
import { getCommentAnchorsFromDoc, getTrackedChangeStatsFromDoc, getTrackedChangesFromDoc, getTrackedChangesFromSnapshot } from "./read.js";
|
|
22
|
+
import { createFolioAIEditSnapshotWithStyleResolver, folioStoryTables, isFolioAIContentBlock, normalizeFolioAIBlockText, sourceDocumentOf } from "./snapshot.js";
|
|
23
23
|
import { matchTableGeometry } from "./table-geometry.js";
|
|
24
|
-
import { TaggedError } from "better-result";
|
|
24
|
+
import { TaggedError, panic } from "better-result";
|
|
25
25
|
import { Fragment } from "prosemirror-model";
|
|
26
26
|
import { EditorState } from "prosemirror-state";
|
|
27
27
|
//#region src/ai-edits/headless.ts
|
|
@@ -160,6 +160,7 @@ const resolvedStoryBlockProjection = (block) => {
|
|
|
160
160
|
delete persisted.idStability;
|
|
161
161
|
return persisted;
|
|
162
162
|
};
|
|
163
|
+
const comparisonAccessByReviewer = /* @__PURE__ */ new WeakMap();
|
|
163
164
|
const MAIN_STORY = Object.freeze({ type: "main" });
|
|
164
165
|
const headerFooterStoryKey = ({ type, relationshipId }) => `${type}:${relationshipId}`;
|
|
165
166
|
const noteStoryKey = ({ type, noteId }) => `${type}:${noteId}`;
|
|
@@ -177,12 +178,11 @@ const createHeadlessPlugins = (styles, numbering) => [
|
|
|
177
178
|
createDocumentNumberingPlugin(numbering)
|
|
178
179
|
];
|
|
179
180
|
const createStateSnapshot = (state) => createFolioAIEditSnapshotWithStyleResolver(state.doc, getDocumentStyleResolver(state));
|
|
180
|
-
const
|
|
181
|
-
const snapshot = createStateSnapshot(state);
|
|
181
|
+
const formatStorySnapshotForLLM = (snapshot, annotated) => {
|
|
182
182
|
const blocks = snapshot.blocks.filter(isFolioAIContentBlock);
|
|
183
183
|
if (!annotated) return blocks.map(formatBlockForLLM).join("\n");
|
|
184
184
|
const nodeByStart = /* @__PURE__ */ new Map();
|
|
185
|
-
|
|
185
|
+
sourceDocumentOf(snapshot).descendants((node, pos) => {
|
|
186
186
|
if (!node.isTextblock) return true;
|
|
187
187
|
nodeByStart.set(pos, node);
|
|
188
188
|
return false;
|
|
@@ -264,6 +264,10 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
264
264
|
this.state = args.state;
|
|
265
265
|
this.author = args.author;
|
|
266
266
|
this.usedCommentIds = new Set((args.baseDocument.package.document.comments ?? []).map(({ id }) => id));
|
|
267
|
+
comparisonAccessByReviewer.set(this, Object.freeze({
|
|
268
|
+
projectStories: (mode) => this.projectComparisonStoriesInternal(mode),
|
|
269
|
+
snapshotReviewedStory: (options) => this.snapshotReviewedStoryInternal(options)
|
|
270
|
+
}));
|
|
267
271
|
}
|
|
268
272
|
/** Parse a `.docx` buffer into a reviewer. */
|
|
269
273
|
static async fromBuffer(buffer, options = {}) {
|
|
@@ -339,6 +343,43 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
339
343
|
const state = this.getEditableStoryState(story);
|
|
340
344
|
return state ? createStateSnapshot(state) : null;
|
|
341
345
|
}
|
|
346
|
+
snapshotReviewedStoryInternal(options = {}) {
|
|
347
|
+
const story = options.story ?? MAIN_STORY;
|
|
348
|
+
const view = options.view ?? "final";
|
|
349
|
+
if (!isFolioReviewedView(view)) throw new UnsupportedFolioReviewedViewError({
|
|
350
|
+
message: "Unsupported reviewed document view.",
|
|
351
|
+
receivedView: view
|
|
352
|
+
});
|
|
353
|
+
const sourceState = this.getEditableStoryState(story);
|
|
354
|
+
return sourceState ? createStateSnapshot(resolveReviewedState(sourceState, view)) : null;
|
|
355
|
+
}
|
|
356
|
+
projectComparisonStoriesInternal(mode) {
|
|
357
|
+
const handles = this.listStoryHandlesInternal();
|
|
358
|
+
let highestId = 0;
|
|
359
|
+
let present = false;
|
|
360
|
+
if (mode === "with-revision-census") for (const handle of handles) {
|
|
361
|
+
const state = this.getEditableStoryState(handle);
|
|
362
|
+
if (!state) continue;
|
|
363
|
+
const stats = getTrackedChangeStatsFromDoc(state.doc);
|
|
364
|
+
highestId = Math.max(highestId, stats.highestId);
|
|
365
|
+
present ||= stats.present;
|
|
366
|
+
}
|
|
367
|
+
const stories = [];
|
|
368
|
+
for (const handle of handles) stories.push({
|
|
369
|
+
handle,
|
|
370
|
+
snapshot: this.resolveReviewedStorySnapshotInternal({
|
|
371
|
+
story: handle,
|
|
372
|
+
view: "final"
|
|
373
|
+
})
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
stories,
|
|
377
|
+
revisions: {
|
|
378
|
+
highestId,
|
|
379
|
+
present
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
342
383
|
/**
|
|
343
384
|
* One story's tables, in the document order {@link snapshotStory} numbers
|
|
344
385
|
* them with, read through a reviewed view.
|
|
@@ -390,37 +431,42 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
390
431
|
readReviewedStory(options = {}) {
|
|
391
432
|
const story = options.story ?? MAIN_STORY;
|
|
392
433
|
const view = options.view ?? "final";
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
434
|
+
const snapshot = this.snapshotReviewedStoryInternal({
|
|
435
|
+
story,
|
|
436
|
+
view
|
|
396
437
|
});
|
|
397
|
-
|
|
398
|
-
if (!sourceState) return null;
|
|
399
|
-
const state = resolveReviewedState(sourceState, view);
|
|
438
|
+
if (!snapshot) return null;
|
|
400
439
|
return {
|
|
401
440
|
story,
|
|
402
441
|
view,
|
|
403
|
-
snapshot
|
|
404
|
-
text:
|
|
405
|
-
changes:
|
|
442
|
+
snapshot,
|
|
443
|
+
text: formatStorySnapshotForLLM(snapshot, view === "current-markup"),
|
|
444
|
+
changes: getTrackedChangesFromSnapshot(snapshot)
|
|
406
445
|
};
|
|
407
446
|
}
|
|
408
447
|
/** Resolve one editable story to its original or final state. */
|
|
409
448
|
resolveReviewedStory({ story = MAIN_STORY, view }) {
|
|
449
|
+
return this.resolveReviewedStorySnapshotInternal({
|
|
450
|
+
story,
|
|
451
|
+
view
|
|
452
|
+
}) !== null;
|
|
453
|
+
}
|
|
454
|
+
resolveReviewedStorySnapshotInternal({ story = MAIN_STORY, view }) {
|
|
410
455
|
if (!isFolioResolvedReviewedView(view)) throw new UnsupportedFolioReviewedViewError({
|
|
411
456
|
message: "Only original and final views can replace editable story state.",
|
|
412
457
|
receivedView: view
|
|
413
458
|
});
|
|
414
459
|
const sourceState = this.getEditableStoryState(story);
|
|
415
|
-
if (!sourceState) return
|
|
460
|
+
if (!sourceState) return null;
|
|
416
461
|
const resolvedState = resolveReviewedState(sourceState, view);
|
|
417
462
|
this.setEditableStoryState(story, resolvedState);
|
|
463
|
+
const snapshot = createStateSnapshot(resolvedState);
|
|
418
464
|
this.resolvedStoryExpectations.set(editableStoryKey(story), {
|
|
419
465
|
story,
|
|
420
|
-
text:
|
|
421
|
-
blocks:
|
|
466
|
+
text: formatStorySnapshotForLLM(snapshot, false),
|
|
467
|
+
blocks: snapshot.blocks.map(resolvedStoryBlockProjection)
|
|
422
468
|
});
|
|
423
|
-
return
|
|
469
|
+
return snapshot;
|
|
424
470
|
}
|
|
425
471
|
/**
|
|
426
472
|
* Apply operations against the current state. Reuses the live-editor applier
|
|
@@ -564,7 +610,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
564
610
|
* (clean) output flattens tracked changes and is unchanged.
|
|
565
611
|
*/
|
|
566
612
|
getContentAsText(options = {}) {
|
|
567
|
-
return
|
|
613
|
+
return formatStorySnapshotForLLM(this.snapshot(), options.annotated === true);
|
|
568
614
|
}
|
|
569
615
|
/**
|
|
570
616
|
* Header / footer and footnote / endnote text as labeled, LLM-ready lines,
|
|
@@ -608,54 +654,33 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
608
654
|
}
|
|
609
655
|
return lines.join("\n");
|
|
610
656
|
}
|
|
657
|
+
listStoryHandlesInternal() {
|
|
658
|
+
const pkg = this.baseDocument.package;
|
|
659
|
+
const handles = [{ type: "main" }];
|
|
660
|
+
for (const relationshipId of pkg.headers?.keys() ?? []) handles.push({
|
|
661
|
+
type: "header",
|
|
662
|
+
relationshipId
|
|
663
|
+
});
|
|
664
|
+
for (const relationshipId of pkg.footers?.keys() ?? []) handles.push({
|
|
665
|
+
type: "footer",
|
|
666
|
+
relationshipId
|
|
667
|
+
});
|
|
668
|
+
for (const footnote of pkg.footnotes ?? []) if (!isSeparatorFootnote(footnote)) handles.push({
|
|
669
|
+
type: "footnote",
|
|
670
|
+
noteId: footnote.id
|
|
671
|
+
});
|
|
672
|
+
for (const endnote of pkg.endnotes ?? []) if (!isSeparatorEndnote(endnote)) handles.push({
|
|
673
|
+
type: "endnote",
|
|
674
|
+
noteId: endnote.id
|
|
675
|
+
});
|
|
676
|
+
return handles;
|
|
677
|
+
}
|
|
611
678
|
/** Discover every readable document story through a typed, serializable handle. */
|
|
612
679
|
listStories() {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}];
|
|
618
|
-
for (const [relationshipId, header] of pkg.headers ?? []) {
|
|
619
|
-
const handle = {
|
|
620
|
-
type: "header",
|
|
621
|
-
relationshipId
|
|
622
|
-
};
|
|
623
|
-
stories.push({
|
|
624
|
-
handle,
|
|
625
|
-
text: this.getHeaderFooterStoryText(handle, header)
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
for (const [relationshipId, footer] of pkg.footers ?? []) {
|
|
629
|
-
const handle = {
|
|
630
|
-
type: "footer",
|
|
631
|
-
relationshipId
|
|
632
|
-
};
|
|
633
|
-
stories.push({
|
|
634
|
-
handle,
|
|
635
|
-
text: this.getHeaderFooterStoryText(handle, footer)
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
for (const footnote of pkg.footnotes ?? []) if (!isSeparatorFootnote(footnote)) {
|
|
639
|
-
const handle = {
|
|
640
|
-
type: "footnote",
|
|
641
|
-
noteId: footnote.id
|
|
642
|
-
};
|
|
643
|
-
stories.push({
|
|
644
|
-
handle,
|
|
645
|
-
text: this.getNoteStoryText(handle, footnote)
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
for (const endnote of pkg.endnotes ?? []) if (!isSeparatorEndnote(endnote)) {
|
|
649
|
-
const handle = {
|
|
650
|
-
type: "endnote",
|
|
651
|
-
noteId: endnote.id
|
|
652
|
-
};
|
|
653
|
-
stories.push({
|
|
654
|
-
handle,
|
|
655
|
-
text: this.getNoteStoryText(handle, endnote)
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
return stories;
|
|
680
|
+
return this.listStoryHandlesInternal().map((handle) => ({
|
|
681
|
+
handle,
|
|
682
|
+
text: this.getStoryText(handle)
|
|
683
|
+
}));
|
|
659
684
|
}
|
|
660
685
|
/** Read one discovered story; returns null when its handle is no longer present. */
|
|
661
686
|
readStory(handle) {
|
|
@@ -887,11 +912,10 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
887
912
|
story,
|
|
888
913
|
view: "current-markup"
|
|
889
914
|
});
|
|
890
|
-
const
|
|
891
|
-
const
|
|
892
|
-
const serializedBlocks = serializedState ? createStateSnapshot(serializedState).blocks.map(resolvedStoryBlockProjection) : null;
|
|
915
|
+
const serializedText = serialized ? formatStorySnapshotForLLM(serialized.snapshot, false) : null;
|
|
916
|
+
const serializedBlocks = serialized ? serialized.snapshot.blocks.map(resolvedStoryBlockProjection) : null;
|
|
893
917
|
const mismatches = [];
|
|
894
|
-
if (!serialized
|
|
918
|
+
if (!serialized) mismatches.push(FOLIO_RESOLVED_STORY_SERIALIZATION_MISMATCHES.storyMissing);
|
|
895
919
|
else {
|
|
896
920
|
if (serialized.changes.length > 0) mismatches.push(FOLIO_RESOLVED_STORY_SERIALIZATION_MISMATCHES.revisionMarkupRemains);
|
|
897
921
|
if (serializedText !== text) mismatches.push(FOLIO_RESOLVED_STORY_SERIALIZATION_MISMATCHES.textProjection);
|
|
@@ -986,6 +1010,17 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
986
1010
|
const sourceText = source.type === "footnote" ? getFootnoteText(source) : getEndnoteText(source);
|
|
987
1011
|
return normalizeFolioAIBlockText(state?.doc.textContent ?? sourceText);
|
|
988
1012
|
}
|
|
1013
|
+
getStoryText(story) {
|
|
1014
|
+
if (story.type === "main") return this.getContentAsText();
|
|
1015
|
+
if (story.type === "header" || story.type === "footer") {
|
|
1016
|
+
const source = this.getHeaderFooterStory(story);
|
|
1017
|
+
if (!source) return panic("A listed document story no longer exists", { story });
|
|
1018
|
+
return this.getHeaderFooterStoryText(story, source);
|
|
1019
|
+
}
|
|
1020
|
+
const source = this.getNoteStory(story);
|
|
1021
|
+
if (!source) return panic("A listed document story no longer exists", { story });
|
|
1022
|
+
return this.getNoteStoryText(story, source);
|
|
1023
|
+
}
|
|
989
1024
|
mergeEditedSecondaryStories(document, secondaryStoryStates = this.secondaryStoryStates.values()) {
|
|
990
1025
|
let headers;
|
|
991
1026
|
let footers;
|
|
@@ -1087,6 +1122,8 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
1087
1122
|
return handled;
|
|
1088
1123
|
}
|
|
1089
1124
|
};
|
|
1125
|
+
/** @internal Comparison-only access to atomic and fresh reviewer projections. */
|
|
1126
|
+
const getFolioDocxComparisonAccess = (reviewer) => comparisonAccessByReviewer.get(reviewer) ?? panic("Comparison access was requested for an uninitialized DOCX reviewer");
|
|
1090
1127
|
/**
|
|
1091
1128
|
* One-shot headless review: parse `buffer`, apply `operations`, and return the
|
|
1092
1129
|
* reviewed `.docx` buffer alongside the applied / skipped breakdown. Convenience
|
|
@@ -1106,4 +1143,4 @@ const applyFolioAIEditsToBuffer = async (buffer, operations, options = {}) => {
|
|
|
1106
1143
|
};
|
|
1107
1144
|
};
|
|
1108
1145
|
//#endregion
|
|
1109
|
-
export { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, FolioDocxReviewer, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView };
|
|
1146
|
+
export { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, FolioDocxReviewer, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, getFolioDocxComparisonAccess, isFolioResolvedReviewedView, isFolioReviewedView };
|
package/dist/ai-edits/read.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FolioAIEditSnapshot } from "./types.js";
|
|
1
2
|
import { FolioNodeRevisionKind } from "../prosemirror/revisionCarriers.js";
|
|
2
3
|
import { Node } from "prosemirror-model";
|
|
3
4
|
//#region src/ai-edits/read.d.ts
|
|
@@ -56,6 +57,8 @@ type FolioCommentAnchor = {
|
|
|
56
57
|
/** The document text the comment is anchored to. */
|
|
57
58
|
quote: string;
|
|
58
59
|
};
|
|
60
|
+
/** Read revisions from the exact immutable document that produced a snapshot. */
|
|
61
|
+
declare const getTrackedChangesFromSnapshot: (snapshot: FolioAIEditSnapshot) => FolioReviewChange[];
|
|
59
62
|
/**
|
|
60
63
|
* The tracked changes present in the body, read from inline marks and
|
|
61
64
|
* structural node attributes. Runs of one inline revision within a block fold
|
|
@@ -66,6 +69,11 @@ type FolioCommentAnchor = {
|
|
|
66
69
|
* fold into the row's entry rather than reporting a second time.
|
|
67
70
|
*/
|
|
68
71
|
declare const getTrackedChangesFromDoc: (doc: Node) => FolioReviewChange[];
|
|
72
|
+
/** @internal Read revision statistics without paying for an unrelated block projection. */
|
|
73
|
+
declare const getTrackedChangeStatsFromDoc: (doc: Node) => {
|
|
74
|
+
highestId: number;
|
|
75
|
+
present: boolean;
|
|
76
|
+
};
|
|
69
77
|
/**
|
|
70
78
|
* The comment anchors present in the body, read from the `comment` mark the
|
|
71
79
|
* editor renders. Each entry carries the anchored text and containing block id;
|
|
@@ -73,4 +81,4 @@ declare const getTrackedChangesFromDoc: (doc: Node) => FolioReviewChange[];
|
|
|
73
81
|
*/
|
|
74
82
|
declare const getCommentAnchorsFromDoc: (doc: Node) => FolioCommentAnchor[];
|
|
75
83
|
//#endregion
|
|
76
|
-
export { FOLIO_REVIEW_CHANGE_KINDS, FolioCommentAnchor, FolioReviewChange, FolioReviewChangeKind, getCommentAnchorsFromDoc, getTrackedChangesFromDoc };
|
|
84
|
+
export { FOLIO_REVIEW_CHANGE_KINDS, FolioCommentAnchor, FolioReviewChange, FolioReviewChangeKind, getCommentAnchorsFromDoc, getTrackedChangeStatsFromDoc, getTrackedChangesFromDoc, getTrackedChangesFromSnapshot };
|
package/dist/ai-edits/read.js
CHANGED
|
@@ -2,7 +2,7 @@ import { expectRunPropertyChangeMarkAttrs } from "../prosemirror/attrs/index.js"
|
|
|
2
2
|
import { getFolioNodeRevisionCarriers } from "../prosemirror/revisionCarriers.js";
|
|
3
3
|
import { expandRunFormattingCarrier, runFormattingCarrierReviewText, runFormattingInlineAtomDisposition } from "../prosemirror/runFormattingInlineCarriers.js";
|
|
4
4
|
import { getTableCellMergeChange } from "../prosemirror/tableCellMergeRevision.js";
|
|
5
|
-
import { createFolioAIEditSnapshot } from "./snapshot.js";
|
|
5
|
+
import { createFolioAIEditSnapshot, sourceDocumentOf } from "./snapshot.js";
|
|
6
6
|
//#region src/ai-edits/read.ts
|
|
7
7
|
/**
|
|
8
8
|
* Runtime census of every tracked-change discriminator the reviewer exposes.
|
|
@@ -31,11 +31,16 @@ const FOLIO_REVIEW_CHANGE_KINDS = Object.freeze({
|
|
|
31
31
|
});
|
|
32
32
|
/** Map each snapshot block's start position to its stable id. */
|
|
33
33
|
const blockStartIdsFromDoc = (doc) => {
|
|
34
|
+
return blockStartIdsFromSnapshot(createFolioAIEditSnapshot(doc));
|
|
35
|
+
};
|
|
36
|
+
/** Map an existing snapshot's block starts without projecting its document again. */
|
|
37
|
+
const blockStartIdsFromSnapshot = (snapshot) => {
|
|
34
38
|
const starts = /* @__PURE__ */ new Map();
|
|
35
|
-
for (const anchor of Object.values(
|
|
39
|
+
for (const anchor of Object.values(snapshot.anchors)) starts.set(anchor.from, anchor.id);
|
|
36
40
|
return starts;
|
|
37
41
|
};
|
|
38
42
|
const firstBlockIdWithin = ({ node, nodePos, blockStarts }) => {
|
|
43
|
+
if (!blockStarts) return null;
|
|
39
44
|
let blockId = null;
|
|
40
45
|
node.descendants((child, relativePos) => {
|
|
41
46
|
if (blockId !== null || !child.isTextblock) return blockId === null;
|
|
@@ -51,19 +56,10 @@ const firstBlockIdWithin = ({ node, nodePos, blockStarts }) => {
|
|
|
51
56
|
* matches neither and keeps its own entry.
|
|
52
57
|
*/
|
|
53
58
|
const belongsToRowRevision = (scope, revision) => revision.id === scope.change.id || revision.author === scope.change.author && revision.date === scope.change.date;
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
* structural node attributes. Runs of one inline revision within a block fold
|
|
57
|
-
* into a single entry.
|
|
58
|
-
*
|
|
59
|
-
* A tracked row insertion or deletion marks the row AND every run in its
|
|
60
|
-
* cells, the way Word writes it. Both halves are one change, so the run marks
|
|
61
|
-
* fold into the row's entry rather than reporting a second time.
|
|
62
|
-
*/
|
|
63
|
-
const getTrackedChangesFromDoc = (doc) => {
|
|
59
|
+
/** Shared revision interpreter; a null block map omits unrelated block-id projection. */
|
|
60
|
+
const getTrackedChangesFromProjectedDoc = (doc, blockStarts) => {
|
|
64
61
|
const insertionType = doc.type.schema.marks["insertion"];
|
|
65
62
|
const deletionType = doc.type.schema.marks["deletion"];
|
|
66
|
-
const blockStarts = blockStartIdsFromDoc(doc);
|
|
67
63
|
const grouped = /* @__PURE__ */ new Map();
|
|
68
64
|
const structuralChangeCellPositions = /* @__PURE__ */ new Map();
|
|
69
65
|
const rowRevisionScopes = [];
|
|
@@ -73,7 +69,7 @@ const getTrackedChangesFromDoc = (doc) => {
|
|
|
73
69
|
while (pos >= (rowRevisionScopes.at(-1)?.end ?? Number.POSITIVE_INFINITY)) rowRevisionScopes.pop();
|
|
74
70
|
const nodeRevisionCarriers = getFolioNodeRevisionCarriers(node, pos);
|
|
75
71
|
if (nodeRevisionCarriers.length > 0) {
|
|
76
|
-
const blockId = node.isTextblock ? blockStarts
|
|
72
|
+
const blockId = node.isTextblock ? blockStarts?.get(pos) ?? null : firstBlockIdWithin({
|
|
77
73
|
node,
|
|
78
74
|
nodePos: pos,
|
|
79
75
|
blockStarts
|
|
@@ -171,7 +167,7 @@ const getTrackedChangesFromDoc = (doc) => {
|
|
|
171
167
|
}
|
|
172
168
|
}
|
|
173
169
|
if (node.isTextblock) {
|
|
174
|
-
currentBlockId = blockStarts
|
|
170
|
+
currentBlockId = blockStarts?.get(pos) ?? null;
|
|
175
171
|
return true;
|
|
176
172
|
}
|
|
177
173
|
if (!node.isInline) return;
|
|
@@ -244,6 +240,28 @@ const getTrackedChangesFromDoc = (doc) => {
|
|
|
244
240
|
});
|
|
245
241
|
return [...grouped.values()];
|
|
246
242
|
};
|
|
243
|
+
/** Read revisions from the exact immutable document that produced a snapshot. */
|
|
244
|
+
const getTrackedChangesFromSnapshot = (snapshot) => getTrackedChangesFromProjectedDoc(sourceDocumentOf(snapshot), blockStartIdsFromSnapshot(snapshot));
|
|
245
|
+
/**
|
|
246
|
+
* The tracked changes present in the body, read from inline marks and
|
|
247
|
+
* structural node attributes. Runs of one inline revision within a block fold
|
|
248
|
+
* into a single entry.
|
|
249
|
+
*
|
|
250
|
+
* A tracked row insertion or deletion marks the row AND every run in its
|
|
251
|
+
* cells, the way Word writes it. Both halves are one change, so the run marks
|
|
252
|
+
* fold into the row's entry rather than reporting a second time.
|
|
253
|
+
*/
|
|
254
|
+
const getTrackedChangesFromDoc = (doc) => getTrackedChangesFromProjectedDoc(doc, blockStartIdsFromDoc(doc));
|
|
255
|
+
/** @internal Read revision statistics without paying for an unrelated block projection. */
|
|
256
|
+
const getTrackedChangeStatsFromDoc = (doc) => {
|
|
257
|
+
let highestId = 0;
|
|
258
|
+
const changes = getTrackedChangesFromProjectedDoc(doc, null);
|
|
259
|
+
for (const change of changes) highestId = Math.max(highestId, change.id);
|
|
260
|
+
return {
|
|
261
|
+
highestId,
|
|
262
|
+
present: changes.length > 0
|
|
263
|
+
};
|
|
264
|
+
};
|
|
247
265
|
/**
|
|
248
266
|
* The comment anchors present in the body, read from the `comment` mark the
|
|
249
267
|
* editor renders. Each entry carries the anchored text and containing block id;
|
|
@@ -281,4 +299,4 @@ const getCommentAnchorsFromDoc = (doc) => {
|
|
|
281
299
|
return [...anchors.values()];
|
|
282
300
|
};
|
|
283
301
|
//#endregion
|
|
284
|
-
export { FOLIO_REVIEW_CHANGE_KINDS, getCommentAnchorsFromDoc, getTrackedChangesFromDoc };
|
|
302
|
+
export { FOLIO_REVIEW_CHANGE_KINDS, getCommentAnchorsFromDoc, getTrackedChangeStatsFromDoc, getTrackedChangesFromDoc, getTrackedChangesFromSnapshot };
|
|
@@ -5,6 +5,10 @@ import { Node } from "prosemirror-model";
|
|
|
5
5
|
//#region src/ai-edits/snapshot.d.ts
|
|
6
6
|
/** @internal Numbering references collected during the snapshot's document walk. */
|
|
7
7
|
declare const numberingReferenceKeysOf: (snapshot: FolioAIEditSnapshot) => readonly string[];
|
|
8
|
+
/** @internal Tables collected during the snapshot's document walk. */
|
|
9
|
+
declare const storyTablesOf: (snapshot: FolioAIEditSnapshot) => readonly FolioStoryTable[];
|
|
10
|
+
/** @internal The immutable ProseMirror document that produced this snapshot. */
|
|
11
|
+
declare const sourceDocumentOf: (snapshot: FolioAIEditSnapshot) => Node;
|
|
8
12
|
declare const normalizeFolioAIBlockText: (text: string) => string;
|
|
9
13
|
/**
|
|
10
14
|
* Whether a block carries text a reader would see.
|
|
@@ -70,14 +74,12 @@ type FolioStoryTable = {
|
|
|
70
74
|
* Every table of one story in document order, nested tables included and
|
|
71
75
|
* hidden rows' subtrees excluded.
|
|
72
76
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* it checks its own work against all read this list, so no second walk can
|
|
76
|
-
* number the same document differently.
|
|
77
|
+
* Uses the same traversal classification as the snapshot's integrated census,
|
|
78
|
+
* so both surfaces skip and number the same nodes in the same order.
|
|
77
79
|
*/
|
|
78
80
|
declare const folioStoryTables: (doc: Node) => FolioStoryTable[];
|
|
79
81
|
declare const createFolioAIEditSnapshot: (doc: Node) => FolioAIEditSnapshot;
|
|
80
82
|
/** @internal Use for an EditorState that owns the document's style resolver. */
|
|
81
83
|
declare const createFolioAIEditSnapshotWithStyleResolver: (doc: Node, styleResolver: RunStyleResolver | null) => FolioAIEditSnapshot;
|
|
82
84
|
//#endregion
|
|
83
|
-
export { FolioStoryTable, createFolioAIEditSnapshot, createFolioAIEditSnapshotWithStyleResolver, createFolioAITextRangeHandle, folioStoryTables, hashFolioAIBlockStructuralBoundaries, hashFolioAIBlockText, isFolioAIContentBlock, isHiddenTableRow, normalizeFolioAIBlockText, numberingReferenceKeysOf, projectFolioAIBlockStructuralBoundaries, trailingBodyBlockId };
|
|
85
|
+
export { FolioStoryTable, createFolioAIEditSnapshot, createFolioAIEditSnapshotWithStyleResolver, createFolioAITextRangeHandle, folioStoryTables, hashFolioAIBlockStructuralBoundaries, hashFolioAIBlockText, isFolioAIContentBlock, isHiddenTableRow, normalizeFolioAIBlockText, numberingReferenceKeysOf, projectFolioAIBlockStructuralBoundaries, sourceDocumentOf, storyTablesOf, trailingBodyBlockId };
|
|
@@ -9,9 +9,14 @@ import { buildCleanBlockText } from "./clean-text.js";
|
|
|
9
9
|
import { panic } from "better-result";
|
|
10
10
|
import { TableMap } from "prosemirror-tables";
|
|
11
11
|
//#region src/ai-edits/snapshot.ts
|
|
12
|
-
const
|
|
12
|
+
const metadataBySnapshot = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
const metadataOf = (snapshot) => metadataBySnapshot.get(snapshot) ?? panic("Metadata was requested for a snapshot that did not record it");
|
|
13
14
|
/** @internal Numbering references collected during the snapshot's document walk. */
|
|
14
|
-
const numberingReferenceKeysOf = (snapshot) =>
|
|
15
|
+
const numberingReferenceKeysOf = (snapshot) => metadataOf(snapshot).numberingReferenceKeys;
|
|
16
|
+
/** @internal Tables collected during the snapshot's document walk. */
|
|
17
|
+
const storyTablesOf = (snapshot) => metadataOf(snapshot).storyTables;
|
|
18
|
+
/** @internal The immutable ProseMirror document that produced this snapshot. */
|
|
19
|
+
const sourceDocumentOf = (snapshot) => metadataOf(snapshot).sourceDocument;
|
|
15
20
|
const normalizeFolioAIBlockText = (text) => text.replace(/\s+/gu, " ").trim();
|
|
16
21
|
/**
|
|
17
22
|
* Whether a block carries text a reader would see.
|
|
@@ -96,21 +101,28 @@ const TABLE_ROLE_ROW = "row";
|
|
|
96
101
|
* whole subtree, so a table nested inside a hidden row is hidden with it.
|
|
97
102
|
*/
|
|
98
103
|
const isHiddenTableRow = (node) => node.type.name === TABLE_ROW_NODE_NAME && node.attrs["hidden"] === true;
|
|
104
|
+
const STORY_TABLE_CONTAINER = "container";
|
|
105
|
+
const STORY_TABLE_HIDDEN_SUBTREE = "hidden-subtree";
|
|
106
|
+
const STORY_TABLE = "table";
|
|
107
|
+
/** Shared visibility and table-role rule for both story projection walks. */
|
|
108
|
+
const classifyNonTextblockStoryTableNode = (node) => {
|
|
109
|
+
if (isHiddenTableRow(node)) return STORY_TABLE_HIDDEN_SUBTREE;
|
|
110
|
+
return node.type.spec["tableRole"] === TABLE_ROLE_TABLE ? STORY_TABLE : STORY_TABLE_CONTAINER;
|
|
111
|
+
};
|
|
99
112
|
/**
|
|
100
113
|
* Every table of one story in document order, nested tables included and
|
|
101
114
|
* hidden rows' subtrees excluded.
|
|
102
115
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* it checks its own work against all read this list, so no second walk can
|
|
106
|
-
* number the same document differently.
|
|
116
|
+
* Uses the same traversal classification as the snapshot's integrated census,
|
|
117
|
+
* so both surfaces skip and number the same nodes in the same order.
|
|
107
118
|
*/
|
|
108
119
|
const folioStoryTables = (doc) => {
|
|
109
120
|
const tables = [];
|
|
110
121
|
doc.descendants((node, pos) => {
|
|
111
122
|
if (node.isTextblock) return false;
|
|
112
|
-
|
|
113
|
-
if (
|
|
123
|
+
const disposition = classifyNonTextblockStoryTableNode(node);
|
|
124
|
+
if (disposition === STORY_TABLE_HIDDEN_SUBTREE) return false;
|
|
125
|
+
if (disposition === STORY_TABLE) tables.push({
|
|
114
126
|
index: tables.length,
|
|
115
127
|
start: pos,
|
|
116
128
|
node
|
|
@@ -154,14 +166,25 @@ const createFolioAIEditSnapshotInternal = (doc, styleResolver) => {
|
|
|
154
166
|
const hashCounts = /* @__PURE__ */ new Map();
|
|
155
167
|
const usedBlockIds = /* @__PURE__ */ new Set();
|
|
156
168
|
const numberingReferenceKeys = /* @__PURE__ */ new Set();
|
|
157
|
-
const
|
|
169
|
+
const tables = [];
|
|
170
|
+
const tableIndexByStart = /* @__PURE__ */ new Map();
|
|
158
171
|
const path = [];
|
|
159
172
|
let blockIndex = 0;
|
|
160
173
|
let blankIndex = 0;
|
|
161
174
|
doc.descendants((node, pos, _parent, index) => {
|
|
162
175
|
while (pos >= (path.at(-1)?.end ?? Number.POSITIVE_INFINITY)) path.pop();
|
|
163
176
|
if (!node.isTextblock) {
|
|
164
|
-
|
|
177
|
+
const disposition = classifyNonTextblockStoryTableNode(node);
|
|
178
|
+
if (disposition === STORY_TABLE_HIDDEN_SUBTREE) return false;
|
|
179
|
+
if (disposition === STORY_TABLE) {
|
|
180
|
+
const tableIndex = tables.length;
|
|
181
|
+
tables.push({
|
|
182
|
+
index: tableIndex,
|
|
183
|
+
start: pos,
|
|
184
|
+
node
|
|
185
|
+
});
|
|
186
|
+
tableIndexByStart.set(pos, tableIndex);
|
|
187
|
+
}
|
|
165
188
|
if (!node.isLeaf) path.push({
|
|
166
189
|
node,
|
|
167
190
|
start: pos,
|
|
@@ -254,7 +277,11 @@ const createFolioAIEditSnapshotInternal = (doc, styleResolver) => {
|
|
|
254
277
|
blocks,
|
|
255
278
|
anchors
|
|
256
279
|
};
|
|
257
|
-
|
|
280
|
+
metadataBySnapshot.set(snapshot, {
|
|
281
|
+
numberingReferenceKeys: [...numberingReferenceKeys],
|
|
282
|
+
sourceDocument: doc,
|
|
283
|
+
storyTables: tables
|
|
284
|
+
});
|
|
258
285
|
return snapshot;
|
|
259
286
|
};
|
|
260
287
|
const createFolioAIEditSnapshot = (doc) => createFolioAIEditSnapshotInternal(doc, null);
|
|
@@ -479,4 +506,4 @@ const isEmptyPreviewRunStyle = ({ bold, italic, underline, strike, fontFamily, f
|
|
|
479
506
|
const sameDirectFormatting = (left, right) => left === void 0 && isEmptyPreviewRunStyle(right) || left !== void 0 && left.bold === right.bold && left.italic === right.italic && left.underline === right.underline && left.strike === right.strike && left.fontFamily === right.fontFamily && left.fontSizePt === right.fontSizePt && left.color === right.color;
|
|
480
507
|
const isUnstyledPreviewRun = ({ bold, italic, underline, strike, fontFamily, fontSizePt, color }) => bold === void 0 && italic === void 0 && underline === void 0 && strike === void 0 && fontFamily === void 0 && fontSizePt === void 0 && color === void 0;
|
|
481
508
|
//#endregion
|
|
482
|
-
export { createFolioAIEditSnapshot, createFolioAIEditSnapshotWithStyleResolver, createFolioAITextRangeHandle, folioStoryTables, hashFolioAIBlockStructuralBoundaries, hashFolioAIBlockText, isFolioAIContentBlock, isHiddenTableRow, normalizeFolioAIBlockText, numberingReferenceKeysOf, projectFolioAIBlockStructuralBoundaries, trailingBodyBlockId };
|
|
509
|
+
export { createFolioAIEditSnapshot, createFolioAIEditSnapshotWithStyleResolver, createFolioAITextRangeHandle, folioStoryTables, hashFolioAIBlockStructuralBoundaries, hashFolioAIBlockText, isFolioAIContentBlock, isHiddenTableRow, normalizeFolioAIBlockText, numberingReferenceKeysOf, projectFolioAIBlockStructuralBoundaries, sourceDocumentOf, storyTablesOf, trailingBodyBlockId };
|