@stll/folio-core 0.53.0 → 0.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +415 -166
- package/dist/ai-edits/batch-claims.d.ts +21 -6
- package/dist/ai-edits/batch-claims.js +47 -16
- package/dist/ai-edits/headless.d.ts +20 -0
- package/dist/ai-edits/headless.js +140 -11
- package/dist/ai-edits/pending-suggestions.js +1 -1
- package/dist/ai-edits/read.d.ts +5 -3
- package/dist/ai-edits/read.js +97 -47
- package/dist/ai-edits/revisionStretches.d.ts +17 -0
- package/dist/ai-edits/revisionStretches.js +80 -0
- package/dist/ai-edits/snapshot.js +3 -2
- package/dist/ai-edits/table-cell-mutations.d.ts +3 -1
- package/dist/ai-edits/table-cell-mutations.js +2 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +6 -1
- package/dist/ai-edits/table-row-column-mutations.js +27 -10
- package/dist/compare/content-alignment.d.ts +5 -1
- package/dist/compare/content-alignment.js +39 -32
- package/dist/compare/inline-provenance.js +1 -1
- package/dist/controller/layoutPipeline.js +3 -2
- package/dist/docx/archiveInflation.d.ts +127 -0
- package/dist/docx/archiveInflation.js +181 -0
- package/dist/docx/metadataPrivacy.js +24 -1
- package/dist/docx/noteReferenceMark.d.ts +15 -0
- package/dist/docx/noteReferenceMark.js +48 -0
- package/dist/docx/paragraphParser.js +5 -3
- package/dist/docx/paragraphPropertySource.d.ts +1 -1
- package/dist/docx/paragraphPropertySource.js +4 -2
- package/dist/docx/parser.js +2 -2
- package/dist/docx/rezip.js +4 -2
- package/dist/docx/selectiveXmlPatch.d.ts +3 -1
- package/dist/docx/selectiveXmlPatch.js +81 -3
- package/dist/docx/server/boundedArchive.d.ts +8 -13
- package/dist/docx/server/boundedArchive.js +70 -59
- package/dist/docx/server/extractDocxText.d.ts +8 -2
- package/dist/docx/server/extractDocxText.js +2 -2
- package/dist/docx/server/validateDocxConformance.d.ts +1 -1
- package/dist/docx/server/validateDocxConformance.js +1 -0
- package/dist/docx/unzip.d.ts +19 -2
- package/dist/docx/unzip.js +135 -24
- package/dist/docx/verticalMergeProjection.d.ts +17 -0
- package/dist/docx/verticalMergeProjection.js +120 -0
- package/dist/fonts/embeddedFonts.js +1 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +34 -34
- package/dist/i18n/messages/catalogs.gen.js +34 -34
- package/dist/i18n/messages/messages.gen.d.ts +2 -2
- package/dist/internal/wholeStoryRevisionResolution.js +95 -25
- package/dist/layout-engine/measure/measureParagraph.js +2 -2
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
- package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
- package/dist/markdown/escape.d.ts +2 -2
- package/dist/markdown/escape.js +4 -5
- package/dist/markdown/renderBlock.js +91 -25
- package/dist/markdown/renderRuns.d.ts +10 -1
- package/dist/markdown/renderRuns.js +320 -59
- package/dist/prosemirror/clearRunColor.d.ts +6 -0
- package/dist/prosemirror/clearRunColor.js +46 -0
- package/dist/prosemirror/commands/comments.js +62 -22
- package/dist/prosemirror/commands/formatPainter.js +1 -1
- package/dist/prosemirror/commands/hyperlink.js +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +28 -4
- package/dist/prosemirror/commands/resolveAllTableChanges.js +40 -41
- package/dist/prosemirror/commands/resolveParagraphProperties.js +33 -8
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +7 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.js +39 -20
- package/dist/prosemirror/commands/tableMergeFoldDecisions.d.ts +61 -0
- package/dist/prosemirror/commands/tableMergeFoldDecisions.js +79 -0
- package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
- package/dist/prosemirror/containerFinalParagraph.js +7 -6
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +12 -590
- package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -13
- package/dist/prosemirror/conversion/toProseDoc.js +28 -262
- package/dist/prosemirror/documentSchema.d.ts +8 -0
- package/dist/prosemirror/documentSchema.js +18 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +104 -63
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -1
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +10 -9
- package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -4
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +14 -8
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
- package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -6
- package/dist/prosemirror/extensions/marks/markUtils.js +17 -8
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +3 -1
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +12 -1
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
- package/dist/prosemirror/extensions/nodes/TableExtension.js +104 -210
- package/dist/prosemirror/extensions/types.d.ts +7 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
- package/dist/prosemirror/hyperlinkRemoval.js +129 -0
- package/dist/prosemirror/index.d.ts +2 -1
- package/dist/prosemirror/index.js +2 -1
- package/dist/prosemirror/listNumbering.d.ts +3 -21
- package/dist/prosemirror/listNumbering.js +24 -39
- package/dist/prosemirror/listRendering.d.ts +29 -0
- package/dist/prosemirror/listRendering.js +26 -0
- package/dist/prosemirror/markupViewNotes.d.ts +8 -0
- package/dist/prosemirror/markupViewNotes.js +49 -0
- package/dist/prosemirror/markupViewProjection.d.ts +3 -1
- package/dist/prosemirror/markupViewProjection.js +7 -2
- package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
- package/dist/prosemirror/noteReferenceReview.js +332 -0
- package/dist/prosemirror/paragraphIndentation.js +5 -2
- package/dist/prosemirror/paragraphMarkJoin.d.ts +6 -4
- package/dist/prosemirror/paragraphMarkJoin.js +21 -19
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
- package/dist/prosemirror/paragraphPropertyCarry.js +155 -0
- package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
- package/dist/prosemirror/plugins/documentStyleState.js +32 -0
- package/dist/prosemirror/plugins/documentStyles.d.ts +2 -21
- package/dist/prosemirror/plugins/documentStyles.js +66 -29
- package/dist/prosemirror/plugins/index.d.ts +2 -1
- package/dist/prosemirror/plugins/index.js +2 -1
- package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
- package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
- package/dist/prosemirror/plugins/suggestionMode.d.ts +12 -2
- package/dist/prosemirror/plugins/suggestionMode.js +387 -28
- package/dist/prosemirror/plugins/templateDirectives.d.ts +6 -0
- package/dist/prosemirror/plugins/templateDirectives.js +21 -7
- package/dist/prosemirror/plugins/templatePreviewValues.js +14 -21
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +22 -2
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
- package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
- package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
- package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
- package/dist/prosemirror/runFormattingFromMarks.js +567 -0
- package/dist/prosemirror/runFormattingReconciliation.js +10 -9
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
- package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
- package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
- package/dist/prosemirror/tableCellPaste.d.ts +74 -0
- package/dist/prosemirror/tableCellPaste.js +525 -0
- package/dist/prosemirror/tableGridMutation.d.ts +53 -14
- package/dist/prosemirror/tableGridMutation.js +166 -18
- package/dist/prosemirror/tableRunIn.d.ts +51 -0
- package/dist/prosemirror/tableRunIn.js +165 -0
- package/dist/prosemirror/textInput.js +11 -2
- package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
- package/dist/prosemirror/trackedRevisionPath.js +32 -0
- package/dist/server.d.ts +2 -2
- package/package.json +6 -6
|
@@ -5,21 +5,30 @@ import { inlineBookmarksOf } from "../prosemirror/commands/paragraphBookmarkJoin
|
|
|
5
5
|
import { resolveAllTableChanges } from "../prosemirror/commands/resolveAllTableChanges.js";
|
|
6
6
|
import { resolveAllNodePropertyChangeAttrs } from "../prosemirror/commands/resolveNodePropertyChangeAttrs.js";
|
|
7
7
|
import { resolveParagraphChangeAttrs } from "../prosemirror/commands/resolveParagraphProperties.js";
|
|
8
|
+
import { rebaseParagraphRunContent } from "../prosemirror/rebaseParagraphRuns.js";
|
|
8
9
|
import { expandRunFormattingCarrier } from "../prosemirror/runFormattingInlineCarriers.js";
|
|
9
10
|
import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "../prosemirror/runFormattingReconciliation.js";
|
|
10
11
|
import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
|
|
12
|
+
import { runParagraphsIntoTables, runsIntoFollowingTable } from "../prosemirror/tableRunIn.js";
|
|
11
13
|
import { holdsNoContent } from "../prosemirror/zeroWidthAnchors.js";
|
|
12
14
|
import { recordNodeResolution } from "./revisionResolutionEdits.js";
|
|
13
15
|
import { resolveInlineRevisions } from "./revisionResolutionInline.js";
|
|
14
16
|
import { composeRevisionResolutionMaps } from "./revisionResolutionStep.js";
|
|
15
17
|
import { REVIEW_CARRIERS } from "@stll/docx-core/model";
|
|
16
18
|
import { Fragment, Slice } from "prosemirror-model";
|
|
17
|
-
import { Mapping, ReplaceStep, StepMap } from "prosemirror-transform";
|
|
19
|
+
import { Mapping, ReplaceStep, StepMap, Transform } from "prosemirror-transform";
|
|
18
20
|
//#region src/internal/wholeStoryRevisionResolution.ts
|
|
19
21
|
const resolveProperties = ({ doc, mode, styleResolver, numbering, steps, changedRanges }) => {
|
|
20
22
|
let structural = false;
|
|
23
|
+
let runsIntoTable = false;
|
|
21
24
|
const walk = (node, position) => {
|
|
22
25
|
if (node.isText) return node;
|
|
26
|
+
if (!runsIntoTable && !node.isTextblock) {
|
|
27
|
+
for (let index = 0; index + 1 < node.childCount; index++) if (runsIntoFollowingTable(node.child(index), node.child(index + 1), mode)) {
|
|
28
|
+
runsIntoTable = true;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
23
32
|
const nextAttrs = node.type.name === "paragraph" ? resolveParagraphChangeAttrs({
|
|
24
33
|
node,
|
|
25
34
|
mode,
|
|
@@ -94,7 +103,8 @@ const resolveProperties = ({ doc, mode, styleResolver, numbering, steps, changed
|
|
|
94
103
|
};
|
|
95
104
|
return {
|
|
96
105
|
resolved: walk(doc, -1),
|
|
97
|
-
structural
|
|
106
|
+
structural,
|
|
107
|
+
runsIntoTable
|
|
98
108
|
};
|
|
99
109
|
};
|
|
100
110
|
const structuralReplacementMap = ({ replacements, tables, bookmarkJoins, origin }) => {
|
|
@@ -157,11 +167,14 @@ const structuralReplacementMap = ({ replacements, tables, bookmarkJoins, origin
|
|
|
157
167
|
const last = ranges.length - 3;
|
|
158
168
|
const previousStart = ranges.at(last);
|
|
159
169
|
const previousOldSize = ranges.at(last + 1);
|
|
160
|
-
|
|
170
|
+
const previousNewSize = ranges.at(last + 2);
|
|
171
|
+
const newSize = newEnd - newStart;
|
|
172
|
+
if (last >= 0 && previousStart !== void 0 && previousOldSize !== void 0 && previousNewSize !== void 0 && (previousNewSize === 0 || newSize === 0) && previousStart + previousOldSize === oldStart) {
|
|
161
173
|
ranges[last + 1] = previousOldSize + oldEnd - oldStart;
|
|
174
|
+
ranges[last + 2] = previousNewSize + newSize;
|
|
162
175
|
return;
|
|
163
176
|
}
|
|
164
|
-
ranges.push(oldStart, oldEnd - oldStart,
|
|
177
|
+
ranges.push(oldStart, oldEnd - oldStart, newSize);
|
|
165
178
|
});
|
|
166
179
|
};
|
|
167
180
|
for (const replacement of replacements) {
|
|
@@ -228,7 +241,24 @@ const resolveStructure = ({ node, position, context }) => {
|
|
|
228
241
|
let final = chain.node;
|
|
229
242
|
if (chain.chunks.length > 1) {
|
|
230
243
|
const children = [];
|
|
231
|
-
for (let index = chain.chunks.length - 1; index >= 0; index--)
|
|
244
|
+
for (let index = chain.chunks.length - 1; index >= 0; index--) {
|
|
245
|
+
const chunk = chain.chunks[index];
|
|
246
|
+
if (!chunk) continue;
|
|
247
|
+
let content = chunk.type === "paragraph" ? chunk.source.content : chunk.content;
|
|
248
|
+
if (chunk.type === "paragraph" && chunk.position !== chain.formattingOwnerPosition) content = rebaseParagraphRunContent({
|
|
249
|
+
paragraph: chunk.source,
|
|
250
|
+
target: chain.node,
|
|
251
|
+
position: chunk.position,
|
|
252
|
+
styleResolver: context.styleResolver,
|
|
253
|
+
onRebased: ({ before, after, position: runPosition }) => recordNodeResolution({
|
|
254
|
+
before,
|
|
255
|
+
after,
|
|
256
|
+
position: runPosition,
|
|
257
|
+
steps: context.steps
|
|
258
|
+
})
|
|
259
|
+
});
|
|
260
|
+
content.forEach((child) => children.push(child));
|
|
261
|
+
}
|
|
232
262
|
final = recreateProseNodeWithParagraphPropertySource(chain.node, { content: Fragment.fromArray(children) });
|
|
233
263
|
}
|
|
234
264
|
if (!chain.before.sameMarkup(final)) context.changedRanges.push({
|
|
@@ -313,26 +343,23 @@ const resolveStructure = ({ node, position, context }) => {
|
|
|
313
343
|
return null;
|
|
314
344
|
}
|
|
315
345
|
bookmarks = Fragment.fromArray(inline);
|
|
316
|
-
chain.chunks.push(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const empty = holdsNoContent(paragraph);
|
|
320
|
-
const owner = empty ? chain.node : paragraph;
|
|
321
|
-
const next = chain.node;
|
|
322
|
-
if (empty) {
|
|
323
|
-
const displacedToken = getProseParagraphPropertySourceToken(paragraph);
|
|
324
|
-
const selectedToken = getProseParagraphPropertySourceToken(next);
|
|
325
|
-
context.transfers.push({
|
|
326
|
-
displacedToken: typeof displacedToken === "string" ? displacedToken : null,
|
|
327
|
-
selectedToken: typeof selectedToken === "string" ? selectedToken : null
|
|
346
|
+
chain.chunks.push({
|
|
347
|
+
type: "bookmarks",
|
|
348
|
+
content: bookmarks
|
|
328
349
|
});
|
|
350
|
+
pendingBookmarks = [];
|
|
329
351
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
352
|
+
const displacedToken = getProseParagraphPropertySourceToken(paragraph);
|
|
353
|
+
const selectedToken = getProseParagraphPropertySourceToken(chain.node);
|
|
354
|
+
context.transfers.push({
|
|
355
|
+
displacedToken: typeof displacedToken === "string" ? displacedToken : null,
|
|
356
|
+
selectedToken: typeof selectedToken === "string" ? selectedToken : null
|
|
357
|
+
});
|
|
358
|
+
chain.chunks.push({
|
|
359
|
+
type: "paragraph",
|
|
360
|
+
source: paragraph,
|
|
361
|
+
position: entry.position
|
|
362
|
+
});
|
|
336
363
|
chain.position = entry.position;
|
|
337
364
|
chain.before = paragraph;
|
|
338
365
|
chain.joinBoundaries.push({
|
|
@@ -357,7 +384,12 @@ const resolveStructure = ({ node, position, context }) => {
|
|
|
357
384
|
} }) : paragraph;
|
|
358
385
|
chain = {
|
|
359
386
|
node: resolved,
|
|
360
|
-
|
|
387
|
+
formattingOwnerPosition: entry.position,
|
|
388
|
+
chunks: [{
|
|
389
|
+
type: "paragraph",
|
|
390
|
+
source: resolved,
|
|
391
|
+
position: entry.position
|
|
392
|
+
}],
|
|
361
393
|
position: entry.position,
|
|
362
394
|
before: paragraph,
|
|
363
395
|
joinBoundaries: []
|
|
@@ -456,6 +488,42 @@ const resolveStructure = ({ node, position, context }) => {
|
|
|
456
488
|
return final;
|
|
457
489
|
};
|
|
458
490
|
const resolveWholeStory = ({ doc, mode, styleResolver, numbering }) => {
|
|
491
|
+
const { runsIntoTable, ...direct } = resolveStoryRevisions({
|
|
492
|
+
doc,
|
|
493
|
+
mode,
|
|
494
|
+
styleResolver,
|
|
495
|
+
numbering
|
|
496
|
+
});
|
|
497
|
+
if (!runsIntoTable) return direct;
|
|
498
|
+
const runIn = new Transform(doc);
|
|
499
|
+
const { targets, maps, transfers } = runParagraphsIntoTables(runIn, mode, styleResolver);
|
|
500
|
+
if (!runIn.docChanged) return direct;
|
|
501
|
+
const { runsIntoTable: _rerun, ...result } = resolveStoryRevisions({
|
|
502
|
+
doc: runIn.doc,
|
|
503
|
+
mode,
|
|
504
|
+
styleResolver,
|
|
505
|
+
numbering
|
|
506
|
+
});
|
|
507
|
+
for (const { position, step } of targets) {
|
|
508
|
+
const from = runIn.mapping.slice(step).map(position);
|
|
509
|
+
const target = runIn.doc.nodeAt(from);
|
|
510
|
+
if (target) result.changedRanges.push({
|
|
511
|
+
from,
|
|
512
|
+
to: from + target.nodeSize
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
let runInMap = StepMap.empty;
|
|
516
|
+
for (const map of maps) runInMap = composeRevisionResolutionMaps(runInMap, map);
|
|
517
|
+
const positionMap = composeRevisionResolutionMaps(runInMap, result.positionMap);
|
|
518
|
+
return {
|
|
519
|
+
...result,
|
|
520
|
+
steps: [...runIn.steps, ...result.steps],
|
|
521
|
+
positionMap,
|
|
522
|
+
mapping: new Mapping([positionMap]),
|
|
523
|
+
transfers: [...transfers, ...result.transfers]
|
|
524
|
+
};
|
|
525
|
+
};
|
|
526
|
+
const resolveStoryRevisions = ({ doc, mode, styleResolver, numbering }) => {
|
|
459
527
|
const steps = [];
|
|
460
528
|
const propertyRanges = [];
|
|
461
529
|
const propertyResult = resolveProperties({
|
|
@@ -476,6 +544,7 @@ const resolveWholeStory = ({ doc, mode, styleResolver, numbering }) => {
|
|
|
476
544
|
});
|
|
477
545
|
const context = {
|
|
478
546
|
mode,
|
|
547
|
+
styleResolver,
|
|
479
548
|
steps: [],
|
|
480
549
|
changedRanges: [],
|
|
481
550
|
deleted: [],
|
|
@@ -523,7 +592,8 @@ const resolveWholeStory = ({ doc, mode, styleResolver, numbering }) => {
|
|
|
523
592
|
structural: context.structural,
|
|
524
593
|
failed: context.failed,
|
|
525
594
|
removedEndpointCount: context.removedEndpointCount,
|
|
526
|
-
removedReferences: context.removedReferences
|
|
595
|
+
removedReferences: context.removedReferences,
|
|
596
|
+
runsIntoTable: propertyResult.runsIntoTable
|
|
527
597
|
};
|
|
528
598
|
};
|
|
529
599
|
//#endregion
|
|
@@ -15,7 +15,7 @@ import { applyDocumentGrid, calculateEmptyParagraphMetrics, calculateTypographyM
|
|
|
15
15
|
import { getListMarkerInlineWidth } from "./listMarkerWidth.js";
|
|
16
16
|
import { DEFAULT_FONT_FAMILY, buildRunFontStyle, ptToPx } from "./measureHelpers.js";
|
|
17
17
|
import { getFontMetrics, measureRun, measureTextWidth } from "./measureProvider.js";
|
|
18
|
-
import { WIDTH_TOLERANCE, fieldMeasureText, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isTabRun, isTextRun, runToFontStyle } from "./paragraphMeasureShared.js";
|
|
18
|
+
import { WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isTabRun, isTextRun, runToFontStyle } from "./paragraphMeasureShared.js";
|
|
19
19
|
import { canClampTabToRightEdge, hasFollowingTabOnLine, hasPriorTabOnLine, measureDecimalPrefixWidthAfterTab, measureInlineWidthAfterTab } from "./paragraphTabs.js";
|
|
20
20
|
import { calculateTabWidth, pixelsToTwips } from "./tabCalculator.js";
|
|
21
21
|
//#region src/layout-engine/measure/measureParagraph.ts
|
|
@@ -215,7 +215,7 @@ function measureParagraph(block, maxWidth, options) {
|
|
|
215
215
|
fromChar: currentLine.fromChar,
|
|
216
216
|
toRun: currentLine.toRun,
|
|
217
217
|
toChar: currentLine.toChar,
|
|
218
|
-
width:
|
|
218
|
+
width: canonicalLineWidth(currentLine.width - currentLine.trailingWhitespaceWidth),
|
|
219
219
|
...finalTypography,
|
|
220
220
|
...currentLine.justificationPaint !== void 0 ? { justificationPaint: currentLine.justificationPaint } : {},
|
|
221
221
|
...currentLine.discretionaryHyphen ? { discretionaryHyphen: currentLine.discretionaryHyphen } : {},
|
|
@@ -5,6 +5,17 @@ import { FloatingLineSegmentZone } from "./floatingZones.js";
|
|
|
5
5
|
declare const DEFAULT_FONT_SIZE = 11;
|
|
6
6
|
declare const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
7
7
|
declare const WIDTH_TOLERANCE = 0.5;
|
|
8
|
+
/**
|
|
9
|
+
* The width a finished line reports. A line's width is a floating-point sum
|
|
10
|
+
* of per-token measurements, and the same text can reach it through different
|
|
11
|
+
* token groupings, e.g. a run split where a hidden revision sat measures
|
|
12
|
+
* "confirm" + "ation" where the resolved text measures "confirmation". Those
|
|
13
|
+
* sums agree only up to the last few bits, so the result snaps to a
|
|
14
|
+
* binary-exact 1/1024 px grid (under 0.0005 px, far below a device pixel):
|
|
15
|
+
* the same text yields the same width whichever grouping summed it, and the
|
|
16
|
+
* alignment offsets derived from it agree too.
|
|
17
|
+
*/
|
|
18
|
+
declare const canonicalLineWidth: (width: number) => number;
|
|
8
19
|
/**
|
|
9
20
|
* Typography metrics for a line
|
|
10
21
|
*/
|
|
@@ -106,4 +117,4 @@ declare function isEmptyTextRun(run: TextRun): boolean;
|
|
|
106
117
|
declare function isBlockLayoutImageRun(run: ImageRun): boolean;
|
|
107
118
|
declare function isSpaceOrTab(char: string | undefined): boolean;
|
|
108
119
|
//#endregion
|
|
109
|
-
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, LineState, LineTypography, WIDTH_TOLERANCE, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
120
|
+
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, LineState, LineTypography, WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
@@ -4,6 +4,19 @@ import { DEFAULT_FONT_FAMILY, buildRunFontStyle } from "./measureHelpers.js";
|
|
|
4
4
|
const DEFAULT_FONT_SIZE = 11;
|
|
5
5
|
const DEFAULT_LINE_HEIGHT_MULTIPLIER = 1;
|
|
6
6
|
const WIDTH_TOLERANCE = .5;
|
|
7
|
+
/** Grid a finished line's width snaps to: 1/1024 px, exact in binary floating point. */
|
|
8
|
+
const LINE_WIDTH_GRID = 1024;
|
|
9
|
+
/**
|
|
10
|
+
* The width a finished line reports. A line's width is a floating-point sum
|
|
11
|
+
* of per-token measurements, and the same text can reach it through different
|
|
12
|
+
* token groupings, e.g. a run split where a hidden revision sat measures
|
|
13
|
+
* "confirm" + "ation" where the resolved text measures "confirmation". Those
|
|
14
|
+
* sums agree only up to the last few bits, so the result snaps to a
|
|
15
|
+
* binary-exact 1/1024 px grid (under 0.0005 px, far below a device pixel):
|
|
16
|
+
* the same text yields the same width whichever grouping summed it, and the
|
|
17
|
+
* alignment offsets derived from it agree too.
|
|
18
|
+
*/
|
|
19
|
+
const canonicalLineWidth = (width) => Math.round(Math.max(0, width) * LINE_WIDTH_GRID) / LINE_WIDTH_GRID;
|
|
7
20
|
/**
|
|
8
21
|
* Extract FontStyle from a run that carries RunFormatting (text, tab, or
|
|
9
22
|
* field). All three share the same formatting shape, so they measure the
|
|
@@ -79,4 +92,4 @@ function isSpaceOrTab(char) {
|
|
|
79
92
|
return char === " " || char === " ";
|
|
80
93
|
}
|
|
81
94
|
//#endregion
|
|
82
|
-
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, WIDTH_TOLERANCE, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
95
|
+
export { DEFAULT_FONT_SIZE, DEFAULT_LINE_HEIGHT_MULTIPLIER, WIDTH_TOLERANCE, canonicalLineWidth, fieldMeasureText, isBlockLayoutImageRun, isEmptyTextRun, isFieldRun, isImageRun, isLineBreakRun, isMathRun, isSpaceOrTab, isTabRun, isTextRun, runToFontStyle };
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Escape only characters that would change markdown structure mid-text:
|
|
10
|
-
* - backslash, backtick, asterisk, brackets (always)
|
|
11
|
-
* - underscore:
|
|
10
|
+
* - backslash, backtick, asterisk, brackets, tilde (always)
|
|
11
|
+
* - underscore: unless between two letters or digits (emphasis trigger)
|
|
12
12
|
* - angle brackets: only when they look like a tag/autolink
|
|
13
13
|
*
|
|
14
14
|
* Characters like `.` `-` `+` `#` `(` `)` `!` are only meaningful at line
|
package/dist/markdown/escape.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Escape only characters that would change markdown structure mid-text:
|
|
10
|
-
* - backslash, backtick, asterisk, brackets (always)
|
|
11
|
-
* - underscore:
|
|
10
|
+
* - backslash, backtick, asterisk, brackets, tilde (always)
|
|
11
|
+
* - underscore: unless between two letters or digits (emphasis trigger)
|
|
12
12
|
* - angle brackets: only when they look like a tag/autolink
|
|
13
13
|
*
|
|
14
14
|
* Characters like `.` `-` `+` `#` `(` `)` `!` are only meaningful at line
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
* when to escape those.
|
|
17
17
|
*/
|
|
18
18
|
function escapeInline(text) {
|
|
19
|
-
let out = text.replace(/(?<ch>[\\`*[\]])/gu, "\\$<ch>");
|
|
20
|
-
out = out.replace(/(
|
|
21
|
-
out = out.replace(/_(?<post>\s|$)/gu, "\\_$<post>");
|
|
19
|
+
let out = text.replace(/(?<ch>[\\`*[\]~])/gu, "\\$<ch>");
|
|
20
|
+
out = out.replace(/(?<![\p{L}\p{N}])_|_(?![\p{L}\p{N}])/gu, "\\_");
|
|
22
21
|
out = out.replace(/<(?<tag>\/?[A-Za-z][\w-]*)(?=[\s/>])/gu, "\\<$<tag>");
|
|
23
22
|
return out;
|
|
24
23
|
}
|
|
@@ -11,37 +11,103 @@ import { panic } from "better-result";
|
|
|
11
11
|
* of the same list. Ported from eigenpal/docx-editor PR #595.
|
|
12
12
|
*/
|
|
13
13
|
/**
|
|
14
|
-
* In `trackedChanges: "clean"` mode every change is accepted
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
14
|
+
* In `trackedChanges: "clean"` mode every change is accepted, as the editor's
|
|
15
|
+
* accept-all resolves the story (`internal/wholeStoryRevisionResolution.ts`).
|
|
16
|
+
*
|
|
17
|
+
* A paragraph whose mark is pending deletion loses its break on accept and
|
|
18
|
+
* runs on into the paragraph after it, which is the paragraph left: its mark
|
|
19
|
+
* ends the joined text, and a paragraph's properties (style, list) live on its
|
|
20
|
+
* mark. A run of consecutive deletions collapses into that last paragraph.
|
|
21
|
+
*
|
|
22
|
+
* With a table right after it, its words run on into the table's first cell
|
|
23
|
+
* and lead that cell's first paragraph (`prosemirror/tableRunIn.ts`), unless
|
|
24
|
+
* it ends a section, keeps nothing once accepted, or that cell is pending.
|
|
25
|
+
* Otherwise a paragraph that cannot join keeps its place, or goes when it
|
|
26
|
+
* keeps nothing and something follows it.
|
|
25
27
|
*/
|
|
26
28
|
function mergeAcceptedParagraphBreaks(blocks) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
const reversed = [];
|
|
30
|
+
let survivor = null;
|
|
31
|
+
let tableFollows = false;
|
|
32
|
+
let followed = false;
|
|
33
|
+
const flush = () => {
|
|
34
|
+
if (survivor) reversed.push(survivor);
|
|
35
|
+
survivor = null;
|
|
36
|
+
};
|
|
37
|
+
for (let index = blocks.length - 1; index >= 0; index--) {
|
|
38
|
+
const block = blocks[index];
|
|
39
|
+
if (!block) continue;
|
|
40
|
+
if (block.type !== "paragraph") {
|
|
41
|
+
flush();
|
|
42
|
+
reversed.push(block);
|
|
43
|
+
tableFollows = block.type === "table";
|
|
44
|
+
followed ||= tableFollows;
|
|
39
45
|
continue;
|
|
40
46
|
}
|
|
41
|
-
|
|
47
|
+
const goes = block.pPrMark?.kind === "del" || block.pPrMark?.kind === "moveFrom";
|
|
48
|
+
if (goes && survivor) {
|
|
49
|
+
survivor = cloneParagraphWithoutPropertySource(survivor, { content: [...block.content, ...survivor.content] });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const table = reversed.at(-1);
|
|
53
|
+
if (goes && tableFollows && table?.type === "table") {
|
|
54
|
+
const ranIn = tableWithParagraphRunIn(table, block);
|
|
55
|
+
if (ranIn) {
|
|
56
|
+
reversed[reversed.length - 1] = ranIn;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
flush();
|
|
61
|
+
tableFollows = false;
|
|
62
|
+
if (goes && holdsNothingOnAccept(block) && followed && index + reversed.length > 0) continue;
|
|
63
|
+
survivor = block;
|
|
64
|
+
followed = true;
|
|
42
65
|
}
|
|
43
|
-
|
|
66
|
+
flush();
|
|
67
|
+
return reversed.reverse();
|
|
44
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether the cell a paragraph's words would run into is itself pending (its
|
|
71
|
+
* row or the cell, through nested tables' first cells), as
|
|
72
|
+
* `prosemirror/tableRunIn.ts` reads it.
|
|
73
|
+
*/
|
|
74
|
+
const runInCellPending = (table) => {
|
|
75
|
+
const row = table.rows[0];
|
|
76
|
+
const cell = row?.cells[0];
|
|
77
|
+
if (!row || !cell) return false;
|
|
78
|
+
if (row.structuralChange !== void 0 || cell.structuralChange !== void 0) return true;
|
|
79
|
+
const first = cell.content[0];
|
|
80
|
+
return first?.type === "table" && runInCellPending(first);
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* `table` with `paragraph`'s words leading its first cell's first paragraph,
|
|
84
|
+
* descending into nested tables, or null when the paragraph keeps its place.
|
|
85
|
+
*/
|
|
86
|
+
const tableWithParagraphRunIn = (table, paragraph) => {
|
|
87
|
+
if (paragraph.sectionProperties !== void 0 || holdsNothingOnAccept(paragraph)) return null;
|
|
88
|
+
if (runInCellPending(table)) return null;
|
|
89
|
+
const runIn = (current) => {
|
|
90
|
+
const [row, ...rows] = current.rows;
|
|
91
|
+
const [cell, ...cells] = row?.cells ?? [];
|
|
92
|
+
const [first, ...rest] = cell?.content ?? [];
|
|
93
|
+
if (!row || !cell || !first) return null;
|
|
94
|
+
let led = null;
|
|
95
|
+
if (first.type === "paragraph") led = cloneParagraphWithoutPropertySource(first, { content: [...paragraph.content, ...first.content] });
|
|
96
|
+
else if (first.type === "table") led = runIn(first);
|
|
97
|
+
if (!led) return null;
|
|
98
|
+
return {
|
|
99
|
+
...current,
|
|
100
|
+
rows: [{
|
|
101
|
+
...row,
|
|
102
|
+
cells: [{
|
|
103
|
+
...cell,
|
|
104
|
+
content: [led, ...rest]
|
|
105
|
+
}, ...cells]
|
|
106
|
+
}, ...rows]
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
return runIn(table);
|
|
110
|
+
};
|
|
45
111
|
/** Paragraph content that shows nothing: range boundaries and anchors. */
|
|
46
112
|
const ZERO_WIDTH_CONTENT = /* @__PURE__ */ new Set([
|
|
47
113
|
"bookmarkStart",
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { RenderContext } from "./types.js";
|
|
3
3
|
//#region src/markdown/renderRuns.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The character beside a run's delimiters: `""` at the paragraph's edge,
|
|
6
|
+
* `undefined` when it cannot be told (read as a letter, the strictest case).
|
|
7
|
+
*/
|
|
8
|
+
type Neighbor = string | undefined;
|
|
9
|
+
type RunNeighbors = {
|
|
10
|
+
before: Neighbor;
|
|
11
|
+
after: Neighbor;
|
|
12
|
+
};
|
|
4
13
|
/**
|
|
5
14
|
* Render the full inline content of a paragraph, tracking comment-range
|
|
6
15
|
* boundaries to apply the configured wrapper.
|
|
7
16
|
*/
|
|
8
|
-
declare function renderParagraphInline(ctx: RenderContext, pkg: document_d_exports.DocxPackage | undefined, content: readonly document_d_exports.ParagraphContent[], paraId: string | undefined): string;
|
|
17
|
+
declare function renderParagraphInline(ctx: RenderContext, pkg: document_d_exports.DocxPackage | undefined, content: readonly document_d_exports.ParagraphContent[], paraId: string | undefined, edges?: RunNeighbors): string;
|
|
9
18
|
//#endregion
|
|
10
19
|
export { renderParagraphInline };
|