@wordinweb/agent 0.1.0 → 0.2.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/README.md +59 -16
- package/dist/{chunk-E7AFDS2O.js → chunk-EMDLXVNY.js} +20243 -8902
- package/dist/chunk-EMDLXVNY.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +330 -36
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1578 -100
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-E7AFDS2O.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -121,10 +121,21 @@ interface RunProps {
|
|
|
121
121
|
raise?: number;
|
|
122
122
|
/** w:outline — hollow stroked glyphs. */
|
|
123
123
|
outline?: boolean;
|
|
124
|
+
/** w14:textOutline — glyph outline stroke (WordArt gallery styles). */
|
|
125
|
+
textOutline?: {
|
|
126
|
+
color: string;
|
|
127
|
+
width: number;
|
|
128
|
+
};
|
|
129
|
+
/** w:shadow / w14:shadow — offset glyph shadow. */
|
|
130
|
+
textShadow?: boolean;
|
|
124
131
|
/** w:emboss / w:imprint — Word triple-draws offset copies. */
|
|
125
132
|
emboss?: boolean;
|
|
126
133
|
imprint?: boolean;
|
|
127
134
|
vanish?: boolean;
|
|
135
|
+
/** w:rPr w:snapToGrid: whether this run participates in the section's
|
|
136
|
+
* docGrid. A line whose runs ALL declare 0 lays off the grid (see
|
|
137
|
+
* finishLine); ParaProps.snapToGrid covers the whole paragraph. */
|
|
138
|
+
snapToGrid?: boolean;
|
|
128
139
|
/** Character style id (w:rStyle). */
|
|
129
140
|
styleId?: string;
|
|
130
141
|
lang?: string;
|
|
@@ -306,7 +317,7 @@ interface EmbeddedObjectReference {
|
|
|
306
317
|
progId: string;
|
|
307
318
|
}
|
|
308
319
|
/** OMML equation node (subset: runs, scripts, fractions, radicals). */
|
|
309
|
-
type MathNode = {
|
|
320
|
+
type MathNode = ({
|
|
310
321
|
t: "run";
|
|
311
322
|
text: string;
|
|
312
323
|
normal?: boolean;
|
|
@@ -375,6 +386,15 @@ type MathNode = {
|
|
|
375
386
|
pos: "low" | "upp";
|
|
376
387
|
e: MathNode[];
|
|
377
388
|
lim: MathNode[];
|
|
389
|
+
}) & {
|
|
390
|
+
/**
|
|
391
|
+
* The OMML element this node was read from. Only the math EDITOR's reader
|
|
392
|
+
* (edit/math.ts) sets it; the renderer's parser leaves it undefined. Editing
|
|
393
|
+
* re-emits through it, so the properties the linear syntax does not spell
|
|
394
|
+
* out — run fonts, m:ctrlPr, a matrix's column specs, an n-ary's limit
|
|
395
|
+
* placement — survive a text edit instead of being dropped.
|
|
396
|
+
*/
|
|
397
|
+
src?: XmlElement;
|
|
378
398
|
};
|
|
379
399
|
interface MathContent {
|
|
380
400
|
kind: "math";
|
|
@@ -403,6 +423,11 @@ interface FieldContent {
|
|
|
403
423
|
* (in the fldChar begin's w:ffData). Its presence makes the rendered ballot
|
|
404
424
|
* box a click-to-toggle target; the glyph derives from its w:checked child. */
|
|
405
425
|
checkbox?: XmlElement;
|
|
426
|
+
/** The field's own XML: the `w:fldSimple`, or the `w:fldChar` begin of a
|
|
427
|
+
* complex field. The update pass (edit/update-fields.ts) writes a recomputed
|
|
428
|
+
* result back through it — layout resolves fields from this model, so
|
|
429
|
+
* without the link the computed value has nowhere to land in the file. */
|
|
430
|
+
src?: XmlElement;
|
|
406
431
|
}
|
|
407
432
|
/** What an anchored shape's coordinates are measured from. "char" (relH=
|
|
408
433
|
* "character") measures from the anchor run's pen position; "line" (relV=
|
|
@@ -478,12 +503,18 @@ interface ShapeTextbox {
|
|
|
478
503
|
r: number;
|
|
479
504
|
b: number;
|
|
480
505
|
};
|
|
481
|
-
/** Non-rect preset geometry: paint
|
|
482
|
-
* scaled to the shape box) instead of a rectangle.
|
|
506
|
+
/** Non-rect preset geometry: paint these outline paths (in a viewW x viewH
|
|
507
|
+
* space scaled to the shape box) instead of a rectangle. Each path carries
|
|
508
|
+
* its resolved fill colour (undefined = unfilled) and whether the shape's
|
|
509
|
+
* stroke applies to it. */
|
|
483
510
|
geom?: {
|
|
484
|
-
d: string;
|
|
485
511
|
viewW: number;
|
|
486
512
|
viewH: number;
|
|
513
|
+
paths: {
|
|
514
|
+
d: string;
|
|
515
|
+
fill?: string;
|
|
516
|
+
stroke: boolean;
|
|
517
|
+
}[];
|
|
487
518
|
};
|
|
488
519
|
/** bodyPr a:noAutofit: the box does NOT grow with its text — Word hides
|
|
489
520
|
* whole lines that stick out past the shape bottom (phase23 p12 ovals:
|
|
@@ -493,6 +524,13 @@ interface ShapeTextbox {
|
|
|
493
524
|
* plus the top/bottom insets (the stored cy is only Word's last cached
|
|
494
525
|
* value). Width is fixed. */
|
|
495
526
|
autofitHeight?: boolean;
|
|
527
|
+
/** bodyPr a:normAutofit — "shrink text on overflow". The mode is recorded
|
|
528
|
+
* because the fit report names it, NOT because it changes the layout:
|
|
529
|
+
* probe-shapefit measured fourteen normAutofit shapes through desktop Word
|
|
530
|
+
* and every one paints at its authored size and clips at the box bottom,
|
|
531
|
+
* exactly like a:noAutofit. `clipText` is set alongside this and is what the
|
|
532
|
+
* layout reads. */
|
|
533
|
+
shrinkText?: boolean;
|
|
496
534
|
/** Linked text-box chain id (wps:txbx/@id or wps:linkedTxbx/@id): boxes with
|
|
497
535
|
* the same id form one story. The seq-0 box (wps:txbx) holds the content;
|
|
498
536
|
* later boxes (wps:linkedTxbx, chainSeq>0) are empty sinks that continue the
|
|
@@ -569,6 +607,16 @@ interface ShapeArt {
|
|
|
569
607
|
behind?: boolean;
|
|
570
608
|
/** a:xfrm rotation, degrees clockwise. */
|
|
571
609
|
rotation?: number;
|
|
610
|
+
/** wp:wrapSquare/.../wrapTopAndBottom on the anchor. Only FRAME stories
|
|
611
|
+
* (header/footer/cell) act on it - body flow ignores art wrap, as before. */
|
|
612
|
+
wrap?: WrapMode;
|
|
613
|
+
/** wp:anchor dist* in px, used with `wrap`. */
|
|
614
|
+
dist?: {
|
|
615
|
+
t: number;
|
|
616
|
+
b: number;
|
|
617
|
+
l: number;
|
|
618
|
+
r: number;
|
|
619
|
+
};
|
|
572
620
|
lines: DrawingLine[];
|
|
573
621
|
images: DrawingImage[];
|
|
574
622
|
paths: DrawingPath[];
|
|
@@ -702,16 +750,91 @@ interface DrawingContent {
|
|
|
702
750
|
* SmartArt cached-drawing shapes). Painted above lines/paths. */
|
|
703
751
|
texts?: DrawingTextShape[];
|
|
704
752
|
}
|
|
705
|
-
|
|
753
|
+
/** The c:chartSpace plot kinds the renderer paints. Anything else (3-D, radar,
|
|
754
|
+
* surface, stock, bubble) parses with `unsupported` set instead. */
|
|
755
|
+
type ChartType = "column" | "bar" | "line" | "pie" | "doughnut" | "area" | "scatter";
|
|
706
756
|
interface ChartSeries {
|
|
707
757
|
name: string;
|
|
708
758
|
values: number[];
|
|
759
|
+
/** c:xVal of a scatter series. Every other type shares one category axis,
|
|
760
|
+
* so only scatter carries per-series x values. */
|
|
761
|
+
xValues?: number[];
|
|
762
|
+
/** Explicit series fill/line from c:spPr, overriding the palette slot. */
|
|
763
|
+
color?: string;
|
|
764
|
+
/** Explicit c:dPt fills, keyed by point index (pie slices, single bars). */
|
|
765
|
+
pointColors?: Record<number, string>;
|
|
766
|
+
/** c:smooth — draw the line series through a spline instead of segments. */
|
|
767
|
+
smooth?: boolean;
|
|
768
|
+
/** c:spPr/a:ln/@w, in px. A line or scatter series says here how heavy its
|
|
769
|
+
* stroke is; a scatter series, whose stroke is optional, says it has one. */
|
|
770
|
+
lineWidth?: number;
|
|
771
|
+
/** c:marker/c:symbol, an ST_MarkerStyle name. "none" draws no marker, and a
|
|
772
|
+
* name with no shape behind it takes the series' slot in Word's sequence. */
|
|
773
|
+
markerSymbol?: string;
|
|
774
|
+
/** c:marker/c:size, the width across the marker in px. */
|
|
775
|
+
markerSize?: number;
|
|
776
|
+
}
|
|
777
|
+
type ChartTickMark = "none" | "in" | "out" | "cross";
|
|
778
|
+
/** One axis of a 2-D chart (c:catAx/c:valAx/c:dateAx). */
|
|
779
|
+
interface ChartAxis {
|
|
780
|
+
/** c:delete val="1": Word draws no line, ticks or labels for the axis. */
|
|
781
|
+
hidden?: boolean;
|
|
782
|
+
/** A c:majorGridlines child is present. */
|
|
783
|
+
gridlines?: boolean;
|
|
784
|
+
/** c:numFmt formatCode applied to the tick labels, e.g. "0.0%". */
|
|
785
|
+
format?: string;
|
|
786
|
+
title?: string;
|
|
787
|
+
/** c:scaling overrides of the automatic scale. */
|
|
788
|
+
min?: number;
|
|
789
|
+
max?: number;
|
|
790
|
+
majorUnit?: number;
|
|
791
|
+
/** c:scaling/c:orientation val="maxMin". */
|
|
792
|
+
reversed?: boolean;
|
|
793
|
+
/** c:majorTickMark / c:minorTickMark. The schema default is "out" for major
|
|
794
|
+
* and "none" for minor; Word writes both explicitly. */
|
|
795
|
+
majorTick?: ChartTickMark;
|
|
796
|
+
minorTick?: ChartTickMark;
|
|
797
|
+
/** c:tickLblPos val="none" keeps the axis but drops its labels. */
|
|
798
|
+
labels?: boolean;
|
|
799
|
+
/** c:crossBetween on a value axis, which decides where the category axis puts
|
|
800
|
+
* its points: "between" insets them by half a category (Word's choice for
|
|
801
|
+
* bar and column), "midCat" seats the first and last on the plot's edges
|
|
802
|
+
* (Word's choice for line and area). */
|
|
803
|
+
crossBetween?: "between" | "midCat";
|
|
709
804
|
}
|
|
710
805
|
interface ChartData {
|
|
711
806
|
type: ChartType;
|
|
807
|
+
/** Local name of a plot the renderer does not paint (bar3DChart, radarChart,
|
|
808
|
+
* …). When set, `type` is a placeholder and the renderer draws a labeled box
|
|
809
|
+
* rather than pretending the data is a column chart. */
|
|
810
|
+
unsupported?: string;
|
|
712
811
|
title?: string;
|
|
713
812
|
categories: string[];
|
|
714
813
|
series: ChartSeries[];
|
|
814
|
+
/** c:grouping — how bar/column/area series stack. */
|
|
815
|
+
grouping?: "clustered" | "stacked" | "percentStacked";
|
|
816
|
+
/** Legend edge. Absent when the chart has no c:legend. */
|
|
817
|
+
legend?: "l" | "r" | "t" | "b" | "tr";
|
|
818
|
+
/** c:dLbls showVal on the plot or on every series. */
|
|
819
|
+
dataLabels?: boolean;
|
|
820
|
+
/** c:varyColors — give each point of a single series its own palette slot. */
|
|
821
|
+
varyColors?: boolean;
|
|
822
|
+
categoryAxis?: ChartAxis;
|
|
823
|
+
valueAxis?: ChartAxis;
|
|
824
|
+
/** c:holeSize percent of a doughnut (Word's default is 75). */
|
|
825
|
+
holeSize?: number;
|
|
826
|
+
/** c:gapWidth percent between bar/column categories (Word's default is 150). */
|
|
827
|
+
gapWidth?: number;
|
|
828
|
+
/** c:overlap percent between bars of one category (Word: -27 clustered,
|
|
829
|
+
* 100 stacked). */
|
|
830
|
+
overlap?: number;
|
|
831
|
+
/** c:marker val="1" on a line chart: draw a point marker at each value. */
|
|
832
|
+
markers?: boolean;
|
|
833
|
+
/** Font size in px from c:title//a:defRPr@sz. Word's default title is 14pt. */
|
|
834
|
+
titleSize?: number;
|
|
835
|
+
/** Font size in px from c:txPr//a:defRPr@sz, the chart-wide text size. Word's
|
|
836
|
+
* default for axis labels, legend entries and data labels is 9pt. */
|
|
837
|
+
textSize?: number;
|
|
715
838
|
}
|
|
716
839
|
type SmartArtLayout = "process" | "cycle" | "hierarchy" | "list";
|
|
717
840
|
interface SmartArtData {
|
|
@@ -997,7 +1120,10 @@ interface SectionProps {
|
|
|
997
1120
|
right?: Border;
|
|
998
1121
|
offsetFrom: "text" | "page";
|
|
999
1122
|
};
|
|
1000
|
-
/** w:lnNumType: margin line numbering. distance px from the text edge.
|
|
1123
|
+
/** w:lnNumType: margin line numbering. distance px from the text edge.
|
|
1124
|
+
* start is the raw w:start OFFSET (0 when the attribute is absent, its
|
|
1125
|
+
* literal value otherwise) added to the running per-line count — see
|
|
1126
|
+
* parse/section.ts for why an absent attribute isn't just "start 1". */
|
|
1001
1127
|
lineNumbering?: {
|
|
1002
1128
|
countBy: number;
|
|
1003
1129
|
start: number;
|
|
@@ -1009,6 +1135,16 @@ interface SectionProps {
|
|
|
1009
1135
|
footnoteNumStart?: number;
|
|
1010
1136
|
endnoteNumFmt?: string;
|
|
1011
1137
|
endnoteNumStart?: number;
|
|
1138
|
+
/** w:numRestart: when the mark counter resets. Absent means "continuous"
|
|
1139
|
+
* (the whole document shares one counter — this engine's only honored
|
|
1140
|
+
* value; eachSect/eachPage are round-trip preserved but not laid out). */
|
|
1141
|
+
footnoteNumRestart?: "continuous" | "eachSect" | "eachPage";
|
|
1142
|
+
endnoteNumRestart?: "continuous" | "eachSect" | "eachPage";
|
|
1143
|
+
/** w:pos: where the note text is placed. Round-trip preserved only — the
|
|
1144
|
+
* layout always places footnotes at the page bottom and endnotes at the
|
|
1145
|
+
* document end, regardless of this value. */
|
|
1146
|
+
footnotePos?: "pageBottom" | "beneathText";
|
|
1147
|
+
endnotePos?: "sectEnd" | "docEnd";
|
|
1012
1148
|
/** w:textDirection tbRl: the whole section flows as East-Asian vertical
|
|
1013
1149
|
* writing — lines run top-to-bottom, progressing right-to-left. */
|
|
1014
1150
|
textDirection?: "tbRl";
|
|
@@ -1030,6 +1166,10 @@ interface DocComment {
|
|
|
1030
1166
|
paraId?: string;
|
|
1031
1167
|
/** Parent comment id when this comment is a reply (commentsExtended). */
|
|
1032
1168
|
parentId?: string;
|
|
1169
|
+
/** Thread resolved (w15:commentEx w15:done="1" — the [MS-DOCX] CT_CommentEx
|
|
1170
|
+
* extension; ECMA-376 itself has no resolved state). Meaningful on the
|
|
1171
|
+
* thread parent; Word grays the whole thread from the parent's flag. */
|
|
1172
|
+
resolved?: boolean;
|
|
1033
1173
|
}
|
|
1034
1174
|
interface HeaderFooter {
|
|
1035
1175
|
blocks: Block[];
|
|
@@ -1151,10 +1291,10 @@ declare class Package {
|
|
|
1151
1291
|
* the table is keyed by element identity and in-place XML mutation preserves
|
|
1152
1292
|
* identity across `refresh()`.
|
|
1153
1293
|
*/
|
|
1154
|
-
type StableId$
|
|
1294
|
+
type StableId$2 = number;
|
|
1155
1295
|
interface EncodedCaret {
|
|
1156
|
-
blockId: StableId$
|
|
1157
|
-
runId: StableId$
|
|
1296
|
+
blockId: StableId$2;
|
|
1297
|
+
runId: StableId$2;
|
|
1158
1298
|
/** Offset in the run's WIRE space: cumulative through the run's inline
|
|
1159
1299
|
* content in document order, where each w:t contributes its text length
|
|
1160
1300
|
* and each inline separator (w:tab / w:br / w:cr) contributes ONE unit.
|
|
@@ -1198,14 +1338,21 @@ declare class StableIds {
|
|
|
1198
1338
|
/** Explicitly assign an id to a newly created node. Local edits allocate
|
|
1199
1339
|
* (`assign(el)`); applying a replicated edit installs the carried value
|
|
1200
1340
|
* (`assign(el, carriedId)`). Carried ids must not collide. */
|
|
1201
|
-
assign(el: XmlElement, id?: StableId$
|
|
1341
|
+
assign(el: XmlElement, id?: StableId$2): StableId$2;
|
|
1202
1342
|
/** Force `el` to carry `id`, replacing any id it already has (e.g. one
|
|
1203
1343
|
* auto-assigned by a refresh() before a carried id could be installed).
|
|
1204
1344
|
* The previous id is retired. Throws if `id` is held by a different element. */
|
|
1205
|
-
reassign(el: XmlElement, id: StableId$
|
|
1345
|
+
reassign(el: XmlElement, id: StableId$2): void;
|
|
1346
|
+
/** Drop an element's mapping entirely; its id retires (never reused —
|
|
1347
|
+
* `next` stays monotonic). Used before carried-id assignment: a refresh
|
|
1348
|
+
* inside a mutation auto-assigns sequential ids to the nodes it created,
|
|
1349
|
+
* and one of those autos can equal a LATER id of the same carried batch,
|
|
1350
|
+
* which would make reassign throw on a perfectly good intent. No-op for an
|
|
1351
|
+
* unmapped element. */
|
|
1352
|
+
unassign(el: XmlElement): void;
|
|
1206
1353
|
private install;
|
|
1207
|
-
idOf(el: XmlElement): StableId$
|
|
1208
|
-
elOf(id: StableId$
|
|
1354
|
+
idOf(el: XmlElement): StableId$2 | undefined;
|
|
1355
|
+
elOf(id: StableId$2): XmlElement | undefined;
|
|
1209
1356
|
/** Drop mappings for elements no longer reachable from the given roots
|
|
1210
1357
|
* (deleted content). Keeps the table from growing across long sessions.
|
|
1211
1358
|
* Ids of dropped elements are retired, never reused. */
|
|
@@ -1215,10 +1362,10 @@ declare class StableIds {
|
|
|
1215
1362
|
* the tree: `pairs` maps originals→clones (as produced by walking original
|
|
1216
1363
|
* and cloned roots in step). Used by the reconciliation snapshot (plan
|
|
1217
1364
|
* doc 03) so a restore re-keys the table to the restored elements. */
|
|
1218
|
-
captureForClone(originalToClone: Map<XmlElement, XmlElement>): Map<StableId$
|
|
1365
|
+
captureForClone(originalToClone: Map<XmlElement, XmlElement>): Map<StableId$2, XmlElement>;
|
|
1219
1366
|
/** Replace the table wholesale from a captured mapping (restore path). */
|
|
1220
|
-
restore(fromCapture: Map<StableId$
|
|
1221
|
-
nextId(): StableId$
|
|
1367
|
+
restore(fromCapture: Map<StableId$2, XmlElement>, nextId: StableId$2): void;
|
|
1368
|
+
nextId(): StableId$2;
|
|
1222
1369
|
/**
|
|
1223
1370
|
* Export the table as `(id, path)` pairs, where a path is the structural
|
|
1224
1371
|
* location of the id'd element within the given roots: `[rootIndex,
|
|
@@ -1229,14 +1376,14 @@ declare class StableIds {
|
|
|
1229
1376
|
* consistently.
|
|
1230
1377
|
*/
|
|
1231
1378
|
exportSidecar(roots: XmlElement[]): {
|
|
1232
|
-
next: StableId$
|
|
1233
|
-
entries: [StableId$
|
|
1379
|
+
next: StableId$2;
|
|
1380
|
+
entries: [StableId$2, number[]][];
|
|
1234
1381
|
};
|
|
1235
1382
|
/** Rebuild the table from a sidecar against freshly parsed roots (the
|
|
1236
1383
|
* snapshot the sidecar was exported from). Replaces any current mappings. */
|
|
1237
1384
|
importSidecar(roots: XmlElement[], sidecar: {
|
|
1238
|
-
next: StableId$
|
|
1239
|
-
entries: [StableId$
|
|
1385
|
+
next: StableId$2;
|
|
1386
|
+
entries: [StableId$2, number[]][];
|
|
1240
1387
|
}): void;
|
|
1241
1388
|
/** Encode a caret as wire-stable addresses. `t` is the w:t (or other text
|
|
1242
1389
|
* holder) the caret sits in; the run is its nearest tracked ancestor run,
|
|
@@ -1264,6 +1411,8 @@ interface Relationship {
|
|
|
1264
1411
|
}
|
|
1265
1412
|
type Relationships = Map<string, Relationship>;
|
|
1266
1413
|
|
|
1414
|
+
/** The two note parts a document can carry — see notePartsHolding. */
|
|
1415
|
+
type NotePart = "footnotes" | "endnotes";
|
|
1267
1416
|
/**
|
|
1268
1417
|
* A fully parsed .docx: sections of blocks, styles, numbering, theme, and
|
|
1269
1418
|
* header/footer parts, with helpers to resolve effective formatting.
|
|
@@ -1284,7 +1433,7 @@ declare class DocxDocument {
|
|
|
1284
1433
|
/** Header/footer parts keyed by relationship id from document.xml.rels. */
|
|
1285
1434
|
readonly headers: Map<string, HeaderFooter>;
|
|
1286
1435
|
readonly footers: Map<string, HeaderFooter>;
|
|
1287
|
-
/** Note content by note id
|
|
1436
|
+
/** Note content by note id. */
|
|
1288
1437
|
readonly footnotes: Map<number, Block[]>;
|
|
1289
1438
|
readonly endnotes: Map<number, Block[]>;
|
|
1290
1439
|
/** The separator paragraph controls the gap between its rule and the first
|
|
@@ -1297,11 +1446,23 @@ declare class DocxDocument {
|
|
|
1297
1446
|
readonly documentRels: Relationships;
|
|
1298
1447
|
/** settings.xml w:evenAndOddHeaders — enables the "even" header/footer variants. */
|
|
1299
1448
|
readonly evenAndOddHeaders: boolean;
|
|
1449
|
+
/** settings.xml w:autoHyphenation (§17.15.1.10). This engine's layout does
|
|
1450
|
+
* not hyphenate automatically — the setting is round-trip state that
|
|
1451
|
+
* governs Word's own rendering of the document. */
|
|
1452
|
+
readonly autoHyphenation: boolean;
|
|
1453
|
+
/** settings.xml w:hyphenationZone/@w:val in twips (§17.15.1.53); null when
|
|
1454
|
+
* the document does not declare one (Word defaults to 360 = 0.25"). */
|
|
1455
|
+
readonly hyphenationZoneTwips: number | null;
|
|
1456
|
+
/** settings.xml w:doNotHyphenateCaps (§17.15.1.41). */
|
|
1457
|
+
readonly doNotHyphenateCaps: boolean;
|
|
1300
1458
|
/** settings.xml w:mirrorMargins — facing-page (book fold) margins: even
|
|
1301
1459
|
* (verso) pages swap the left/right margins and place the gutter on the
|
|
1302
1460
|
* inside (right) edge so the binding margin stays on the inner side of
|
|
1303
1461
|
* each spread. */
|
|
1304
1462
|
readonly mirrorMargins: boolean;
|
|
1463
|
+
/** settings.xml w:compat w:suppressTopSpacing: the first line of a page
|
|
1464
|
+
* takes its character height, not its authored (exact) line spacing. */
|
|
1465
|
+
readonly suppressTopSpacing: boolean;
|
|
1305
1466
|
/** settings.xml w:defaultTabStop in px (Word default 0.5"). */
|
|
1306
1467
|
readonly defaultTabStop: number;
|
|
1307
1468
|
/** settings.xml w:compat compatibilityMode (12=Word2007, 14=Word2010,
|
|
@@ -1310,6 +1471,12 @@ declare class DocxDocument {
|
|
|
1310
1471
|
* it (nccih: a Heading1/2 after a page break sits at margin + its before).
|
|
1311
1472
|
* Absent → treated as current (15). */
|
|
1312
1473
|
readonly compatibilityMode: number;
|
|
1474
|
+
/** The compatibilityMode settings.xml actually declares, or undefined when
|
|
1475
|
+
* the setting (or settings.xml itself) is missing. `compatibilityMode`
|
|
1476
|
+
* defaults an omitted value to 15, but a table's percentage width needs the
|
|
1477
|
+
* distinction: Word fits the horizontal cell margins inside the table box at
|
|
1478
|
+
* an EXPLICIT 15 and adds them around it when the setting is absent. */
|
|
1479
|
+
readonly declaredCompatibilityMode: number | undefined;
|
|
1313
1480
|
/** settings.xml m:mathPr/m:defJc — default justification for display
|
|
1314
1481
|
* equations whose m:oMathParaPr carries no explicit m:jc (Word default:
|
|
1315
1482
|
* centerGroup — the rows of a broken equation left-align to each other and
|
|
@@ -1345,6 +1512,31 @@ declare class DocxDocument {
|
|
|
1345
1512
|
private footnotesRoot;
|
|
1346
1513
|
private footnotesDirty;
|
|
1347
1514
|
private footnotesRels;
|
|
1515
|
+
/** Retained endnotes.xml tree (endnote insertion + save round-trip). */
|
|
1516
|
+
private endnotesPart;
|
|
1517
|
+
private endnotesRoot;
|
|
1518
|
+
private endnotesDirty;
|
|
1519
|
+
private endnotesRels;
|
|
1520
|
+
/** Retained bibliography sources part (the customXml b:Sources data of
|
|
1521
|
+
* ECMA-376 §22.6), when present. Source-management editing mutates this
|
|
1522
|
+
* tree in place; a document with none gets the part on first create. */
|
|
1523
|
+
private sourcesPart;
|
|
1524
|
+
private sourcesRoot;
|
|
1525
|
+
private sourcesDirty;
|
|
1526
|
+
/** Companion parts written when THIS session created the sources part
|
|
1527
|
+
* (itemProps + its .rels); an arriving part keeps its own companions. */
|
|
1528
|
+
private sourcesAux;
|
|
1529
|
+
/** Retained glossary document part (word/glossary/document.xml, ECMA-376
|
|
1530
|
+
* §17.12: glossaryDocument/docParts/docPart — Word's Quick Parts / Building
|
|
1531
|
+
* Blocks store), when present. Building-block editing mutates this tree in
|
|
1532
|
+
* place; a document with none gets the part on first create. Unlike
|
|
1533
|
+
* headers/footers, a docPart's body is never caret-editable — it is only
|
|
1534
|
+
* ever cloned INTO the main document body (insertBuildingBlock) or captured
|
|
1535
|
+
* OUT of a selection (createBuildingBlock) — so this part carries no
|
|
1536
|
+
* editableRoots()/stable-id integration of its own. */
|
|
1537
|
+
private glossaryPart;
|
|
1538
|
+
private glossaryRoot;
|
|
1539
|
+
private glossaryDirty;
|
|
1348
1540
|
/** Serialize retained optional parts only once actually mutated, keeping
|
|
1349
1541
|
* untouched parts byte-identical through save(). */
|
|
1350
1542
|
private stylesDirty;
|
|
@@ -1467,12 +1659,80 @@ declare class DocxDocument {
|
|
|
1467
1659
|
*/
|
|
1468
1660
|
numberingTree(create?: boolean): XmlElement | null;
|
|
1469
1661
|
markNumberingChanged(): void;
|
|
1662
|
+
/** Retained styles.xml tree, or null when the package has no styles part.
|
|
1663
|
+
* Style-definition editing mutates this tree in place. */
|
|
1664
|
+
stylesTree(): XmlElement | null;
|
|
1665
|
+
/**
|
|
1666
|
+
* Re-resolve the style cascade after a definition changed in place.
|
|
1667
|
+
*
|
|
1668
|
+
* A style definition is not addressed by any paragraph's XML, so mutating one
|
|
1669
|
+
* changes how EVERY paragraph resolves without changing a single w:p. Two
|
|
1670
|
+
* things therefore have to be reset by hand: the parsed Styles map every
|
|
1671
|
+
* effective-props call reads, and layoutGlobalSig, which is what makes the
|
|
1672
|
+
* line-break cache treat cached breaks for unchanged paragraph XML as stale.
|
|
1673
|
+
*/
|
|
1674
|
+
markStylesChanged(): void;
|
|
1675
|
+
/**
|
|
1676
|
+
* Retained bibliography sources tree (b:Sources), or null when the package
|
|
1677
|
+
* has no sources part. With create=true, a missing part is created and
|
|
1678
|
+
* registered the way Word lays one out (ECMA-376 §22.6 + Part 2 custom XML
|
|
1679
|
+
* data storage): the data itself as customXml/itemN.xml, a datastore-item
|
|
1680
|
+
* properties part (itemPropsN.xml) declaring the Bibliography schema URI as
|
|
1681
|
+
* its schemaRef, a .rels from the item to its properties, a customXml
|
|
1682
|
+
* relationship from the main document part, and the content-type overrides.
|
|
1683
|
+
*
|
|
1684
|
+
* DETERMINISM. Everything written is a pure function of the package —
|
|
1685
|
+
* the item number is the first free one, and the datastore itemID GUID is a
|
|
1686
|
+
* fixed constant rather than Word's random draw — so two replicas creating
|
|
1687
|
+
* the part through the same sequenced operation write identical bytes.
|
|
1688
|
+
*/
|
|
1689
|
+
sourcesTree(create?: boolean): XmlElement | null;
|
|
1690
|
+
/**
|
|
1691
|
+
* Invalidate what a sources-part edit changes downstream. Like
|
|
1692
|
+
* markStylesChanged, the part is addressed by no paragraph's XML: a
|
|
1693
|
+
* CITATION field's painted text resolves from the part at layout, so the
|
|
1694
|
+
* layout signature has to drop for unchanged paragraph XML to repaint.
|
|
1695
|
+
*/
|
|
1696
|
+
markSourcesChanged(): void;
|
|
1697
|
+
/**
|
|
1698
|
+
* Retained glossary document tree (w:glossaryDocument), or null when the
|
|
1699
|
+
* package has no glossary part. With create=true, a missing part is
|
|
1700
|
+
* created and registered — package part, document relationship,
|
|
1701
|
+
* content-type override — the createNotesPart discipline.
|
|
1702
|
+
*
|
|
1703
|
+
* The glossary part gets none of the sources part's companion machinery
|
|
1704
|
+
* (no datastore item, no random itemID): it is an ordinary WordprocessingML
|
|
1705
|
+
* part named by relationship TYPE, so creation just mints an empty
|
|
1706
|
+
* `<w:glossaryDocument><w:docParts/></w:glossaryDocument>` and wires it up
|
|
1707
|
+
* — closer to createNotesPart than to sourcesTree. A real Word-authored
|
|
1708
|
+
* glossary part additionally carries its own styles.xml / settings.xml /
|
|
1709
|
+
* fontTable.xml; this engine writes none of them, because a docPart's
|
|
1710
|
+
* content is read once — to clone its blocks into the main document, where
|
|
1711
|
+
* they resolve styles against the MAIN document's own styles.xml — and is
|
|
1712
|
+
* never laid out or rendered as its own story the way a header/footer is.
|
|
1713
|
+
*
|
|
1714
|
+
* DETERMINISM: nothing here depends on Word's random draws (no GUID is
|
|
1715
|
+
* written at all — w:docPartPr/w:guid is optional and this engine never
|
|
1716
|
+
* reads it back), so two replicas creating the part through the same
|
|
1717
|
+
* sequenced operation write identical bytes.
|
|
1718
|
+
*/
|
|
1719
|
+
glossaryTree(create?: boolean): XmlElement | null;
|
|
1720
|
+
/** Invalidate what a glossary-part edit changes: nothing downstream, since
|
|
1721
|
+
* createBuildingBlock/deleteBuildingBlock touch only the glossary tree, not
|
|
1722
|
+
* any paragraph the layout reads. Exists for the same "explicit intent to
|
|
1723
|
+
* persist" reason markSourcesChanged does. */
|
|
1724
|
+
markGlossaryChanged(): void;
|
|
1470
1725
|
/**
|
|
1471
1726
|
* Retained footnotes tree. With create=true, a missing footnotes.xml part
|
|
1472
1727
|
* is created and registered (with Word's required separator footnotes) so
|
|
1473
1728
|
* inserted footnotes serialize and round-trip.
|
|
1474
1729
|
*/
|
|
1475
1730
|
footnotesTree(create?: boolean): XmlElement | null;
|
|
1731
|
+
/** Retained endnotes tree; the endnote mirror of footnotesTree. */
|
|
1732
|
+
endnotesTree(create?: boolean): XmlElement | null;
|
|
1733
|
+
/** Register a new notes part in document.xml.rels and [Content_Types].xml,
|
|
1734
|
+
* and return the part path. The tree itself is the caller's. */
|
|
1735
|
+
private createNotesPart;
|
|
1476
1736
|
/**
|
|
1477
1737
|
* Create an empty header/footer part (with a default-type reference in
|
|
1478
1738
|
* every sectPr) when the document has none - Word does this implicitly the
|
|
@@ -1487,7 +1747,29 @@ declare class DocxDocument {
|
|
|
1487
1747
|
* whether an ensureHeaderFooter intent has anything to do). */
|
|
1488
1748
|
hasHfPart(kind: "header" | "footer"): boolean;
|
|
1489
1749
|
ensureHfPart(kind: "header" | "footer"): XmlElement;
|
|
1750
|
+
/** A w:headerReference / w:footerReference element. */
|
|
1751
|
+
private hfReference;
|
|
1752
|
+
/** Materialize the default body-level sectPr when the document declares no
|
|
1753
|
+
* section properties at all (schema: the body's sectPr is its LAST child). */
|
|
1754
|
+
private ensureBodySectPr;
|
|
1755
|
+
/**
|
|
1756
|
+
* Give every section a header and footer reference of the given variant
|
|
1757
|
+
* type, creating one empty part per band the way Word does the first time
|
|
1758
|
+
* "different first page" (type "first") or "different odd & even pages"
|
|
1759
|
+
* (type "even") is enabled. Sections that already carry a reference of the
|
|
1760
|
+
* type keep it — and its part's content. True when anything was added.
|
|
1761
|
+
*/
|
|
1762
|
+
ensureHfVariantParts(type: "first" | "even"): boolean;
|
|
1763
|
+
/** Create and register a new empty header/footer part — package part,
|
|
1764
|
+
* document relationship, content-type override, hfParts entry — with no
|
|
1765
|
+
* section references of its own; the caller decides which sectPrs point at
|
|
1766
|
+
* it and with which w:type. */
|
|
1767
|
+
private createHfPart;
|
|
1490
1768
|
markFootnotesChanged(): void;
|
|
1769
|
+
markEndnotesChanged(): void;
|
|
1770
|
+
/** Re-derive both id -> blocks maps from the retained trees, so layout sees
|
|
1771
|
+
* an inserted or edited note. */
|
|
1772
|
+
private rederiveNotes;
|
|
1491
1773
|
/** Called by comment edit commands after mutating the comments tree. */
|
|
1492
1774
|
markCommentsChanged(): void;
|
|
1493
1775
|
/**
|
|
@@ -1503,23 +1785,78 @@ declare class DocxDocument {
|
|
|
1503
1785
|
* nearest preceding w:t.
|
|
1504
1786
|
*/
|
|
1505
1787
|
commentAnchors(): Map<string, XmlElement[]>;
|
|
1506
|
-
/** Flag
|
|
1507
|
-
* re-serializes footnotes.xml. Called by the editor after a
|
|
1508
|
-
* no-op for body/header/footer targets. */
|
|
1788
|
+
/** Flag a notes part dirty when `t` lives inside it, so save()
|
|
1789
|
+
* re-serializes footnotes.xml / endnotes.xml. Called by the editor after a
|
|
1790
|
+
* text edit; a no-op for body/header/footer targets. */
|
|
1509
1791
|
markDirtyIfFootnote(t: XmlElement): void;
|
|
1792
|
+
/**
|
|
1793
|
+
* Which note parts hold `el` right now. An operation that DETACHES `el` —
|
|
1794
|
+
* accepting or rejecting a revision, for one — has to ask BEFORE it mutates
|
|
1795
|
+
* and mark the answer afterwards: a detached element belongs to no part, so
|
|
1796
|
+
* a containment test run after the fact reports nothing and save() then
|
|
1797
|
+
* leaves the stale footnotes.xml / endnotes.xml in the package.
|
|
1798
|
+
*/
|
|
1799
|
+
notePartsHolding(el: XmlElement): NotePart[];
|
|
1800
|
+
/** Flag the given note parts dirty, so save() re-serializes exactly those. */
|
|
1801
|
+
markNotePartsChanged(parts: readonly NotePart[]): void;
|
|
1510
1802
|
/** The mutable XML roots (document body, related modeled parts, settings).
|
|
1511
1803
|
* settingsRoot is always second and always present so its history snapshot
|
|
1512
1804
|
* index stays stable even when optional related roots are created later. */
|
|
1513
1805
|
editableRoots(): XmlElement[];
|
|
1806
|
+
/** CT_Settings children that precede w:mirrorMargins in the schema sequence
|
|
1807
|
+
* (§17.15.1.78). Insertions go before the first child that is not a
|
|
1808
|
+
* predecessor, so Word never has to repair settings.xml. */
|
|
1809
|
+
private static readonly SETTINGS_BEFORE_MIRROR;
|
|
1810
|
+
/** The schema predecessors of w:evenAndOddHeaders (§17.10.1): everything up
|
|
1811
|
+
* to mirrorMargins, then the sequence through defaultTableStyle. */
|
|
1812
|
+
private static readonly SETTINGS_BEFORE_EVEN_AND_ODD;
|
|
1813
|
+
/** Set or remove one settings.xml element at its schema position. Null
|
|
1814
|
+
* removes; otherwise the element is (re)inserted before the first child
|
|
1815
|
+
* that is not a schema predecessor. */
|
|
1816
|
+
private setSettingsElement;
|
|
1817
|
+
/** Set or remove one on/off settings.xml toggle at its schema position. */
|
|
1818
|
+
private setSettingsToggle;
|
|
1819
|
+
/** The schema predecessors of w:autoHyphenation: everything through
|
|
1820
|
+
* w:defaultTabStop (§17.15.1.78). Its cluster mates append in order. */
|
|
1821
|
+
private static readonly SETTINGS_BEFORE_AUTO_HYPHENATION;
|
|
1822
|
+
/**
|
|
1823
|
+
* Patch the hyphenation settings (w:autoHyphenation §17.15.1.10,
|
|
1824
|
+
* w:hyphenationZone §17.15.1.53, w:doNotHyphenateCaps §17.15.1.41). Each
|
|
1825
|
+
* present key is written; `zoneTwips: null` removes the zone element. True
|
|
1826
|
+
* when anything changed — the honest no-op a replicated document-scoped
|
|
1827
|
+
* operation needs. This engine's layout does not hyphenate automatically;
|
|
1828
|
+
* the settings govern Word's own rendering of the file.
|
|
1829
|
+
*/
|
|
1830
|
+
setHyphenation(patch: {
|
|
1831
|
+
auto?: boolean;
|
|
1832
|
+
zoneTwips?: number | null;
|
|
1833
|
+
noCaps?: boolean;
|
|
1834
|
+
}): boolean;
|
|
1514
1835
|
/** Toggle the document-global facing-page margin mode in settings.xml. */
|
|
1515
1836
|
setMirrorMargins(enabled: boolean): void;
|
|
1837
|
+
/** Toggle w:evenAndOddHeaders (§17.10.1) — the document-global switch that
|
|
1838
|
+
* makes even pages use the "even" header/footer variants. */
|
|
1839
|
+
setEvenAndOddHeaders(enabled: boolean): void;
|
|
1840
|
+
/** Register settings.xml in document.xml.rels and [Content_Types].xml when
|
|
1841
|
+
* the package was born without it (a minimal document). */
|
|
1842
|
+
private registerSettingsPart;
|
|
1516
1843
|
/**
|
|
1517
1844
|
* Find the parent element of `target` in any modeled XML tree (document
|
|
1518
1845
|
* body, headers, footers). Linear scan — documents are small and this only
|
|
1519
1846
|
* runs on structural edits (Enter, paragraph merge).
|
|
1520
1847
|
*/
|
|
1521
|
-
/**
|
|
1848
|
+
/** The header part roots, in package order. A watermark is authored into
|
|
1849
|
+
* every one of them: Word paints it on every page, and a document with a
|
|
1850
|
+
* first-page or even-page header has more than one header part. */
|
|
1851
|
+
headerRoots(): XmlElement[];
|
|
1852
|
+
/** The footer part roots, in package order — headerRoots' counterpart, for
|
|
1853
|
+
* operations that walk both bands (the page-number gallery's removal
|
|
1854
|
+
* sweep). */
|
|
1855
|
+
footerRoots(): XmlElement[];
|
|
1856
|
+
/** XML roots that can carry tracked changes: body, headers/footers, notes. */
|
|
1522
1857
|
revisionRoots(): XmlElement[];
|
|
1858
|
+
/** Body, header/footer and note roots — every tree the caret can reach. */
|
|
1859
|
+
private contentRoots;
|
|
1523
1860
|
/**
|
|
1524
1861
|
* Memoized child→parent links. Nothing invalidates this map — the tree is
|
|
1525
1862
|
* spliced constantly — so every answer is RE-DERIVED before it is returned:
|
|
@@ -1566,6 +1903,27 @@ declare class DocxDocument {
|
|
|
1566
1903
|
saveAsync(): Promise<Uint8Array>;
|
|
1567
1904
|
private buildPackage;
|
|
1568
1905
|
private buildPackageFiles;
|
|
1906
|
+
/**
|
|
1907
|
+
* Leave out the chart parts the document no longer references.
|
|
1908
|
+
*
|
|
1909
|
+
* Deleting a chart splices its w:drawing out of the story, but the chart
|
|
1910
|
+
* part, its rels part, its embedded workbook, the document relationship, and
|
|
1911
|
+
* the two [Content_Types].xml overrides all stay. An agent that inserts a
|
|
1912
|
+
* chart, deletes it, and inserts a replacement therefore saves TWO chart
|
|
1913
|
+
* parts for the one chart the document shows.
|
|
1914
|
+
*
|
|
1915
|
+
* The release happens here, at save time, rather than when the drawing goes,
|
|
1916
|
+
* because undo restores the drawing XML — r:id and all — from a snapshot
|
|
1917
|
+
* that models package parts but no relationship state. Dropping the
|
|
1918
|
+
* relationship early would make undo produce a chart pointing at nothing.
|
|
1919
|
+
* The live tree keeps everything; only the written bytes lose the orphans,
|
|
1920
|
+
* and the saveJournal puts back the two trees this touches.
|
|
1921
|
+
*
|
|
1922
|
+
* Relationship ids are scoped to the part that owns the rels file, so the
|
|
1923
|
+
* document body is the only place that can reference these ids, and reading
|
|
1924
|
+
* it is a complete check. Headers, footers, and notes carry their own rels.
|
|
1925
|
+
*/
|
|
1926
|
+
private dropOrphanChartParts;
|
|
1569
1927
|
/** Fresh unique docPr id for inserted drawings. Seeded once past the
|
|
1570
1928
|
* highest id already present in any editable root (floor 1000, matching
|
|
1571
1929
|
* the historical seed for documents with no drawings) so a document that
|
|
@@ -1585,6 +1943,22 @@ declare class DocxDocument {
|
|
|
1585
1943
|
addHyperlinkRel(url: string): string;
|
|
1586
1944
|
/** Retarget an existing external relationship (hyperlink href edit). */
|
|
1587
1945
|
setRelTarget(relId: string, url: string): boolean;
|
|
1946
|
+
/** The relationships of the part that holds `source`: a header or footer
|
|
1947
|
+
* part when the element is inside one, else the document part. */
|
|
1948
|
+
private imageRelsOwner;
|
|
1949
|
+
/** Add an image relationship pointing at `part`, in the relationships of
|
|
1950
|
+
* whichever part holds `source`. */
|
|
1951
|
+
private addImageRel;
|
|
1952
|
+
/**
|
|
1953
|
+
* Point a SECOND part at an image part this document already has.
|
|
1954
|
+
*
|
|
1955
|
+
* Word's picture watermark is ONE media part that every header part
|
|
1956
|
+
* references. Registering the image again per header would put a full copy
|
|
1957
|
+
* of the bytes in the package for each one — three headers, three copies of
|
|
1958
|
+
* the same logo — and give the media-install path three pending parts to
|
|
1959
|
+
* fill from one upload.
|
|
1960
|
+
*/
|
|
1961
|
+
linkImageResource(part: string, source: XmlElement): string;
|
|
1588
1962
|
private addImageResourceAt;
|
|
1589
1963
|
addImageResource(bytes: Uint8Array, ext: string): string;
|
|
1590
1964
|
/** Add a GLB model part and its Office 2019 model3d relationship. */
|
|
@@ -1659,6 +2033,15 @@ declare class DocxDocument {
|
|
|
1659
2033
|
iv?: string;
|
|
1660
2034
|
genesisId?: string;
|
|
1661
2035
|
}, source?: XmlElement): string;
|
|
2036
|
+
/** As registerPendingImage, and also names the part it made — what a second
|
|
2037
|
+
* part needs to reach the same image through linkImageResource. */
|
|
2038
|
+
registerPendingImagePart(sha: string, ext: string, meta?: {
|
|
2039
|
+
iv?: string;
|
|
2040
|
+
genesisId?: string;
|
|
2041
|
+
}, source?: XmlElement): {
|
|
2042
|
+
relId: string;
|
|
2043
|
+
part: string;
|
|
2044
|
+
};
|
|
1662
2045
|
/** Install fetched bytes into a pending part (doc 05). The caller has
|
|
1663
2046
|
* ALREADY verified the sha against the intent's declaration (the
|
|
1664
2047
|
* reservation is the hash commitment — doc 16 §1.1); this installs and
|
|
@@ -1680,6 +2063,776 @@ declare class DocxDocument {
|
|
|
1680
2063
|
private readXmlOptional;
|
|
1681
2064
|
}
|
|
1682
2065
|
|
|
2066
|
+
/** Outline/shadow for an ordinary run — Word's Home-tab "Text Effects and
|
|
2067
|
+
* Typography" gallery, distinct from inserting a WordArt object. */
|
|
2068
|
+
interface RunTextEffectPatch {
|
|
2069
|
+
outline?: {
|
|
2070
|
+
color: string;
|
|
2071
|
+
widthPt: number;
|
|
2072
|
+
} | null;
|
|
2073
|
+
shadow?: boolean;
|
|
2074
|
+
}
|
|
2075
|
+
/** bodyPr's autofit choice: grow the shape, shrink the text, or neither. */
|
|
2076
|
+
type DrawingTextFitMode = "none" | "resizeShape" | "shrinkText";
|
|
2077
|
+
|
|
2078
|
+
interface RunFormatPatch {
|
|
2079
|
+
bold?: boolean;
|
|
2080
|
+
italic?: boolean;
|
|
2081
|
+
underline?: boolean;
|
|
2082
|
+
strike?: boolean;
|
|
2083
|
+
/** "#RRGGBB"; null removes the direct color. */
|
|
2084
|
+
color?: string | null;
|
|
2085
|
+
/** Word highlight name ("yellow", "cyan", …); null removes. */
|
|
2086
|
+
highlight?: string | null;
|
|
2087
|
+
/** Font size in points. */
|
|
2088
|
+
fontSizePt?: number;
|
|
2089
|
+
fontFamily?: string;
|
|
2090
|
+
/** Superscript/subscript; null returns the run to the baseline. */
|
|
2091
|
+
verticalAlign?: "superscript" | "subscript" | null;
|
|
2092
|
+
/**
|
|
2093
|
+
* Character style (w:rStyle); null removes the reference.
|
|
2094
|
+
*
|
|
2095
|
+
* This rides the run patch rather than taking an operation of its own
|
|
2096
|
+
* because applying a character style to PART of a run splits the run — which
|
|
2097
|
+
* breaks the registry's position-stable precondition, and which formatRange
|
|
2098
|
+
* already handles with its carried before/middle/after piece ids.
|
|
2099
|
+
*/
|
|
2100
|
+
characterStyleId?: string | null;
|
|
2101
|
+
/**
|
|
2102
|
+
* w14 outline/shadow run effects (Word's Home-tab "Text Effects and
|
|
2103
|
+
* Typography" gallery) — the same vocabulary a WordArt object's text
|
|
2104
|
+
* carries, applied directly to ordinary runs. null removes every w14
|
|
2105
|
+
* effect, reverting to plain text. Rides the run patch rather than an
|
|
2106
|
+
* operation of its own for the same reason characterStyleId does: applying
|
|
2107
|
+
* it to PART of a run splits the run, which formatRange already handles.
|
|
2108
|
+
*/
|
|
2109
|
+
textEffect?: RunTextEffectPatch | null;
|
|
2110
|
+
/** Remove all direct character formatting (and character style). */
|
|
2111
|
+
clear?: boolean;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/**
|
|
2115
|
+
* CITATION resolution: the document's bibliography sources and the simple
|
|
2116
|
+
* parenthetical and bibliography-entry formats Word paints for the built-in
|
|
2117
|
+
* styles.
|
|
2118
|
+
*
|
|
2119
|
+
* WHERE THE SOURCES LIVE. Word stores the bibliography source list as a
|
|
2120
|
+
* Custom XML Data part (customXml/item1.xml in Word's own files), targeted
|
|
2121
|
+
* from the main document part by a customXml relationship. The markup is the
|
|
2122
|
+
* Bibliography namespace of ECMA-376 §22.6: a b:Sources root whose
|
|
2123
|
+
* StyleName attribute names the selected citation style ("APA", "MLA", …)
|
|
2124
|
+
* and whose b:Source children each carry a b:Tag the CITATION instruction
|
|
2125
|
+
* references. The part is retained by DocxDocument (sourcesTree) so the
|
|
2126
|
+
* source-management operations in edit/sources.ts can mutate it; a part
|
|
2127
|
+
* those operations never touch keeps its original bytes through save().
|
|
2128
|
+
*
|
|
2129
|
+
* WHAT IS FORMATTED. The author-date parenthetical of the simple built-in
|
|
2130
|
+
* styles: "(Author, Year)" for the APA-shaped family and "(Author)" /
|
|
2131
|
+
* "(Author page)" for MLA — plus the matching bibliography ENTRY per source
|
|
2132
|
+
* (bibliographyEntryText below). Full style-sheet fidelity (Word ships an
|
|
2133
|
+
* XSL per style) is out of scope; a CITATION whose display this module
|
|
2134
|
+
* cannot build keeps its cached result, which is Word's own rendering.
|
|
2135
|
+
*
|
|
2136
|
+
* It lives here, above both consumers, for the style-ref.ts reason: layout
|
|
2137
|
+
* paints what the reader sees and the update pass writes what the saved file
|
|
2138
|
+
* carries, and the two must not disagree about the same field.
|
|
2139
|
+
*/
|
|
2140
|
+
/** A person author, in b:NameList order. */
|
|
2141
|
+
interface BibliographyPerson {
|
|
2142
|
+
last: string;
|
|
2143
|
+
first?: string;
|
|
2144
|
+
}
|
|
2145
|
+
/** The citation styles the style selector offers: the two whose parenthetical
|
|
2146
|
+
* and bibliography-entry rules this module models. One list, so the operation
|
|
2147
|
+
* validator, the agent schema, and the toolbar cannot disagree. */
|
|
2148
|
+
declare const CITATION_STYLES: readonly ["APA", "MLA"];
|
|
2149
|
+
type CitationStyle = (typeof CITATION_STYLES)[number];
|
|
2150
|
+
|
|
2151
|
+
/** An a:srcRect crop as fractions of the source bitmap trimmed off each edge.
|
|
2152
|
+
* The four together must leave a visible strip on both axes. */
|
|
2153
|
+
interface ImageCrop {
|
|
2154
|
+
l: number;
|
|
2155
|
+
t: number;
|
|
2156
|
+
r: number;
|
|
2157
|
+
b: number;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
/**
|
|
2161
|
+
* Numbering DEFINITION editing: the levels of an abstract numbering
|
|
2162
|
+
* definition, and the per-instance overrides that restart or continue a
|
|
2163
|
+
* sequence. Applying numbering to a paragraph lives in lists.ts.
|
|
2164
|
+
*
|
|
2165
|
+
* Two things are edited here, and the difference matters:
|
|
2166
|
+
*
|
|
2167
|
+
* - A LEVEL of an abstract definition (w:abstractNum/w:lvl). Every list
|
|
2168
|
+
* instance sharing that abstract definition changes with it.
|
|
2169
|
+
* - An OVERRIDE on one instance (w:num/w:lvlOverride). Only the paragraphs
|
|
2170
|
+
* carrying that numId change, which is how one list restarts at 1 while
|
|
2171
|
+
* another sharing the same look keeps counting.
|
|
2172
|
+
*/
|
|
2173
|
+
/** The numbering formats Word offers for a level. */
|
|
2174
|
+
declare const NUMBER_FORMATS: readonly ["decimal", "decimalZero", "upperRoman", "lowerRoman", "upperLetter", "lowerLetter", "ordinal", "bullet", "none"];
|
|
2175
|
+
type NumberFormat = (typeof NUMBER_FORMATS)[number];
|
|
2176
|
+
/** What one level of a multilevel definition can be changed to. Undefined
|
|
2177
|
+
* leaves a property alone. */
|
|
2178
|
+
interface LevelPatch {
|
|
2179
|
+
format?: NumberFormat;
|
|
2180
|
+
/** The label template: "%1." or "%1.%2." for a multilevel definition, or the
|
|
2181
|
+
* bullet glyph when format is "bullet". */
|
|
2182
|
+
text?: string;
|
|
2183
|
+
/** The counter this level starts at. */
|
|
2184
|
+
start?: number;
|
|
2185
|
+
alignment?: "left" | "center" | "right";
|
|
2186
|
+
/** Text indent, in points. */
|
|
2187
|
+
indentLeftPt?: number;
|
|
2188
|
+
/** Hanging indent of the label, in points. */
|
|
2189
|
+
hangingPt?: number;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
/** The w:val values w:tblBorders / w:tcBorders edges accept. "none" writes
|
|
2193
|
+
* w:val="nil", Word's spelling for an explicitly suppressed rule. */
|
|
2194
|
+
type TableBorderStyle = "single" | "thick" | "double" | "dotted" | "dashed" | "dotDash" | "dotDotDash" | "thinThickSmallGap" | "triple" | "wave" | "none";
|
|
2195
|
+
/** One border edge. Table scope carries the four sides plus the two inside
|
|
2196
|
+
* rules; cell scope carries the four sides plus the two diagonals. Neither
|
|
2197
|
+
* carries the other's — the parser reads only these, so writing the rest
|
|
2198
|
+
* would emit XML that renders nothing. */
|
|
2199
|
+
type TableBorderEdge = "top" | "bottom" | "left" | "right" | "insideH" | "insideV" | "tl2br" | "tr2bl";
|
|
2200
|
+
interface TableBorderSpec {
|
|
2201
|
+
style: TableBorderStyle;
|
|
2202
|
+
/** Stroke width in eighths of a point (w:sz). Word's UI offers 2..48. */
|
|
2203
|
+
sz?: number;
|
|
2204
|
+
/** "#RRGGBB", "RRGGBB", or "auto". */
|
|
2205
|
+
color?: string;
|
|
2206
|
+
/** Gap between rule and content, in points (w:space). */
|
|
2207
|
+
space?: number;
|
|
2208
|
+
}
|
|
2209
|
+
/** Word's six "Table Style Options" checkboxes. Banding is expressed
|
|
2210
|
+
* positively here and inverted into w:noHBand / w:noVBand on write — the
|
|
2211
|
+
* negative spelling is a wire detail, and every caller that had to remember
|
|
2212
|
+
* the inversion got it wrong at least once. */
|
|
2213
|
+
interface TableLookToggles {
|
|
2214
|
+
firstRow: boolean;
|
|
2215
|
+
lastRow: boolean;
|
|
2216
|
+
firstColumn: boolean;
|
|
2217
|
+
lastColumn: boolean;
|
|
2218
|
+
bandedRows: boolean;
|
|
2219
|
+
bandedCols: boolean;
|
|
2220
|
+
}
|
|
2221
|
+
/** Cell padding in points. An omitted side is left as it was; pass null to
|
|
2222
|
+
* setTableCellMargins to drop the whole override. */
|
|
2223
|
+
interface CellMarginsPt {
|
|
2224
|
+
top?: number;
|
|
2225
|
+
left?: number;
|
|
2226
|
+
bottom?: number;
|
|
2227
|
+
right?: number;
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
/**
|
|
2231
|
+
* Style DEFINITION editing: the entries in styles.xml, as opposed to applying
|
|
2232
|
+
* an existing style to content (setParagraphStyle in blocks.ts, w:rStyle via
|
|
2233
|
+
* the run format patch).
|
|
2234
|
+
*
|
|
2235
|
+
* Everything here mutates the retained styles.xml tree and then calls
|
|
2236
|
+
* doc.markStylesChanged(), which re-parses the tree and drops the layout
|
|
2237
|
+
* signature. That is the whole of the cascade re-resolution: a definition is
|
|
2238
|
+
* not addressed by any paragraph's XML, so no w:p changes and the model
|
|
2239
|
+
* re-derives effective props from the new Styles map on the next layout.
|
|
2240
|
+
*/
|
|
2241
|
+
/** The paragraph properties a style definition can carry, in points.
|
|
2242
|
+
* Null clears the property; undefined leaves it alone. */
|
|
2243
|
+
interface StyleParaPatch {
|
|
2244
|
+
alignment?: "left" | "center" | "right" | "both" | null;
|
|
2245
|
+
spacingBeforePt?: number | null;
|
|
2246
|
+
spacingAfterPt?: number | null;
|
|
2247
|
+
/** Line spacing as a multiple of single (1.5 → w:line="360" auto). */
|
|
2248
|
+
lineMultiple?: number | null;
|
|
2249
|
+
indentLeftPt?: number | null;
|
|
2250
|
+
indentFirstLinePt?: number | null;
|
|
2251
|
+
keepNext?: boolean | null;
|
|
2252
|
+
/** w:outlineLvl 0-8 — what makes a paragraph style a TOC heading level. */
|
|
2253
|
+
outlineLevel?: number | null;
|
|
2254
|
+
}
|
|
2255
|
+
/** The run properties a style definition can carry. Same names as direct
|
|
2256
|
+
* character formatting; `clear` has no meaning for a definition. */
|
|
2257
|
+
type StyleRunPatch = Omit<RunFormatPatch, "clear">;
|
|
2258
|
+
/** The four style kinds a w:style can declare. One list, so a validator and
|
|
2259
|
+
* a schema cannot disagree about which types exist. */
|
|
2260
|
+
declare const STYLE_TYPES: readonly ["paragraph", "character", "table", "numbering"];
|
|
2261
|
+
type StyleType = (typeof STYLE_TYPES)[number];
|
|
2262
|
+
interface StyleSpec {
|
|
2263
|
+
styleId: string;
|
|
2264
|
+
type: StyleType;
|
|
2265
|
+
/** The display name (w:name) — what a gallery shows. */
|
|
2266
|
+
name: string;
|
|
2267
|
+
/** Parent in the cascade. Defaults per type to what Word writes: Normal for
|
|
2268
|
+
* a paragraph style, DefaultParagraphFont for a character style,
|
|
2269
|
+
* TableNormal for a table style, and nothing for a numbering style. */
|
|
2270
|
+
basedOn?: string | null;
|
|
2271
|
+
/** Style applied to the NEXT paragraph after this one (paragraph only). */
|
|
2272
|
+
next?: string | null;
|
|
2273
|
+
/** w:qFormat — show the style in the quick-style gallery. */
|
|
2274
|
+
quickStyle?: boolean;
|
|
2275
|
+
/** w:uiPriority — gallery sort order. */
|
|
2276
|
+
uiPriority?: number;
|
|
2277
|
+
paragraph?: StyleParaPatch;
|
|
2278
|
+
run?: StyleRunPatch;
|
|
2279
|
+
/**
|
|
2280
|
+
* PARAGRAPH styles only: also write the linked character companion Word
|
|
2281
|
+
* pairs with one, so the same look can be applied to a span of text as well
|
|
2282
|
+
* as to a whole paragraph. The companion takes the id `<styleId>Char` and
|
|
2283
|
+
* the name `<name> Char`, copies the paragraph style's run properties, and
|
|
2284
|
+
* the two point at each other through w:link.
|
|
2285
|
+
*
|
|
2286
|
+
* Refused when `<styleId>Char` is already taken, rather than picking
|
|
2287
|
+
* another id: the companion's id has to be derivable from the paragraph
|
|
2288
|
+
* style's, or two replicas applying the same operation would disagree
|
|
2289
|
+
* about what to call it.
|
|
2290
|
+
*/
|
|
2291
|
+
linked?: boolean;
|
|
2292
|
+
/** TABLE styles only: the grid the style draws. Conditional formats
|
|
2293
|
+
* (w:tblStylePr — banded rows, header row) are not expressible yet. */
|
|
2294
|
+
table?: {
|
|
2295
|
+
borders?: Partial<Record<TableBorderEdge, TableBorderSpec>>;
|
|
2296
|
+
};
|
|
2297
|
+
/** NUMBERING styles only, and required for them: the w:numId of the
|
|
2298
|
+
* numbering definition the style names. A numbering style is a NAME for a
|
|
2299
|
+
* list definition, so it carries nothing else of its own. */
|
|
2300
|
+
numbering?: {
|
|
2301
|
+
numId: number;
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
interface StylePatch {
|
|
2305
|
+
name?: string;
|
|
2306
|
+
basedOn?: string | null;
|
|
2307
|
+
next?: string | null;
|
|
2308
|
+
quickStyle?: boolean;
|
|
2309
|
+
uiPriority?: number;
|
|
2310
|
+
paragraph?: StyleParaPatch;
|
|
2311
|
+
run?: StyleRunPatch;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
interface Model3DRotation {
|
|
2315
|
+
x: number;
|
|
2316
|
+
y: number;
|
|
2317
|
+
z: number;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
/**
|
|
2321
|
+
* Bibliography SOURCE editing: the b:Source entries of the customXml sources
|
|
2322
|
+
* part (ECMA-376 §22.6), as opposed to citing one (insertCitationField in
|
|
2323
|
+
* fields.ts) or rendering one (src/citations.ts).
|
|
2324
|
+
*
|
|
2325
|
+
* Everything here mutates the retained sources tree and then calls
|
|
2326
|
+
* doc.markSourcesChanged() — the styles.ts discipline. The part is created on
|
|
2327
|
+
* the first source (doc.sourcesTree(true)); only the sources part is written,
|
|
2328
|
+
* so a package whose sources this engine never touches keeps its original
|
|
2329
|
+
* bytes through save().
|
|
2330
|
+
*/
|
|
2331
|
+
/** The source kinds the manager offers, mapped to the b:SourceType values
|
|
2332
|
+
* Word's own Source Manager writes. The four cover the common cases; an
|
|
2333
|
+
* arriving source of any other type still renders and can be cited. */
|
|
2334
|
+
declare const CITATION_SOURCE_TYPES: readonly ["book", "article", "website", "report"];
|
|
2335
|
+
type CitationSourceType = (typeof CITATION_SOURCE_TYPES)[number];
|
|
2336
|
+
interface CitationSourceSpec {
|
|
2337
|
+
/** Word's Source-Manager tag shape (isValidCitationTag): what a CITATION
|
|
2338
|
+
* instruction references. */
|
|
2339
|
+
tag: string;
|
|
2340
|
+
type: CitationSourceType;
|
|
2341
|
+
/** Person authors. Mutually exclusive with `corporate`. */
|
|
2342
|
+
authors?: BibliographyPerson[];
|
|
2343
|
+
/** Corporate author (b:Corporate). */
|
|
2344
|
+
corporate?: string;
|
|
2345
|
+
title?: string;
|
|
2346
|
+
year?: string;
|
|
2347
|
+
/** Books and reports. */
|
|
2348
|
+
publisher?: string;
|
|
2349
|
+
/** Journal articles (b:JournalName). */
|
|
2350
|
+
journal?: string;
|
|
2351
|
+
/** Internet sites. */
|
|
2352
|
+
url?: string;
|
|
2353
|
+
}
|
|
2354
|
+
/** Everything but the tag, each field optional; an empty string clears the
|
|
2355
|
+
* field. `authors`/`corporate` replace the whole author element. */
|
|
2356
|
+
type CitationSourcePatch = Partial<Omit<CitationSourceSpec, "tag">>;
|
|
2357
|
+
|
|
2358
|
+
declare const PARAGRAPH_BORDER_EDGES: readonly ["top", "left", "bottom", "right", "between", "bar"];
|
|
2359
|
+
type ParagraphBorderEdge = (typeof PARAGRAPH_BORDER_EDGES)[number];
|
|
2360
|
+
interface ParagraphBordersPatch {
|
|
2361
|
+
/** Edges to change: a spec writes the rule, null removes the direct edge.
|
|
2362
|
+
* Absent edges are left alone. The spec vocabulary is the table border
|
|
2363
|
+
* picker's (style / sz in eighths / color / space in points). */
|
|
2364
|
+
borders?: Partial<Record<ParagraphBorderEdge, TableBorderSpec | null>>;
|
|
2365
|
+
/** Paragraph shading fill "RRGGBB"; null removes the direct w:shd.
|
|
2366
|
+
* Undefined leaves shading alone. */
|
|
2367
|
+
shading?: string | null;
|
|
2368
|
+
}
|
|
2369
|
+
declare const TAB_STOP_ALIGNMENTS: readonly ["left", "center", "right", "decimal", "bar"];
|
|
2370
|
+
declare const TAB_STOP_LEADERS: readonly ["none", "dot", "hyphen", "underscore", "middleDot"];
|
|
2371
|
+
interface TabStopSpec {
|
|
2372
|
+
/** Position in points from the left text edge. */
|
|
2373
|
+
posPt: number;
|
|
2374
|
+
align: (typeof TAB_STOP_ALIGNMENTS)[number];
|
|
2375
|
+
leader: (typeof TAB_STOP_LEADERS)[number];
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
/** The w:pgNumType number formats the layout engine paints (its PAGE_FMT
|
|
2379
|
+
* table); the editable subset of ST_NumberFormat (ECMA-376 §17.18.59). */
|
|
2380
|
+
declare const PAGE_NUMBER_FORMATS: readonly ["decimal", "lowerRoman", "upperRoman", "lowerLetter", "upperLetter"];
|
|
2381
|
+
type PageNumberFormat = (typeof PAGE_NUMBER_FORMATS)[number];
|
|
2382
|
+
/** Note-mark numbering formats the layout engine paints (formatNoteMark's
|
|
2383
|
+
* table): the page-number format subset plus "chicago", Word's symbol style
|
|
2384
|
+
* (*, †, ‡, §) — footnotes' traditional default in some templates. */
|
|
2385
|
+
declare const NOTE_NUMBER_FORMATS: readonly ["decimal", "lowerRoman", "upperRoman", "lowerLetter", "upperLetter", "chicago"];
|
|
2386
|
+
type NoteNumberFormat = (typeof NOTE_NUMBER_FORMATS)[number];
|
|
2387
|
+
/** ST_RestartNumber (ECMA-376 §17.18.81): when the mark counter resets.
|
|
2388
|
+
* Only "eachSect" is honored by layout (assignNoteNumbers); "continuous" is
|
|
2389
|
+
* the OOXML default; "eachPage" round-trips but is not laid out — see
|
|
2390
|
+
* assignNoteNumbers' comment for why. */
|
|
2391
|
+
declare const NOTE_RESTART_VALUES: readonly ["continuous", "eachSect", "eachPage"];
|
|
2392
|
+
type NoteRestart = (typeof NOTE_RESTART_VALUES)[number];
|
|
2393
|
+
|
|
2394
|
+
declare const PAGE_NUMBER_POSITIONS: readonly ["top", "bottom"];
|
|
2395
|
+
type PageNumberGalleryPosition = (typeof PAGE_NUMBER_POSITIONS)[number];
|
|
2396
|
+
declare const PAGE_NUMBER_ALIGNMENTS: readonly ["left", "center", "right"];
|
|
2397
|
+
type PageNumberGalleryAlign = (typeof PAGE_NUMBER_ALIGNMENTS)[number];
|
|
2398
|
+
declare const HEADER_FOOTER_PRESETS: readonly ["blank", "centeredTitle", "titleAndDate", "threeColumn"];
|
|
2399
|
+
type HeaderFooterPreset = (typeof HEADER_FOOTER_PRESETS)[number];
|
|
2400
|
+
|
|
2401
|
+
/**
|
|
2402
|
+
* A native Word table of contents: a TOC field whose cached result is the
|
|
2403
|
+
* entry list.
|
|
2404
|
+
*
|
|
2405
|
+
* WHY A FIELD AND NOT PLAIN PARAGRAPHS. Word recognises a TOC only by its
|
|
2406
|
+
* field structure, and everything a user expects from one — "Update Table",
|
|
2407
|
+
* the grey field shading, Ctrl-click navigation — follows from it. A pile of
|
|
2408
|
+
* paragraphs that merely looks like a TOC is a document Word cannot maintain.
|
|
2409
|
+
*
|
|
2410
|
+
* THE STRUCTURE, as Word writes it (verified against the parity corpus's
|
|
2411
|
+
* Word-authored TOCs, e.g. wild2-med-nccih-protocol.docx):
|
|
2412
|
+
*
|
|
2413
|
+
* <w:p> first entry paragraph, pStyle TOC1
|
|
2414
|
+
* fldChar begin
|
|
2415
|
+
* instrText ` TOC \o "1-3" \h \z \u `
|
|
2416
|
+
* fldChar separate
|
|
2417
|
+
* <w:hyperlink w:anchor="_Toc…" w:history="1"> … </w:hyperlink>
|
|
2418
|
+
* </w:p>
|
|
2419
|
+
* <w:p> … </w:p> one paragraph per further entry
|
|
2420
|
+
* <w:p> fldChar end </w:p> closes the field
|
|
2421
|
+
*
|
|
2422
|
+
* The field's begin/separate live in the FIRST entry paragraph rather than in
|
|
2423
|
+
* a paragraph of their own, and everything between separate and end is the
|
|
2424
|
+
* cached result. Each entry is a hyperlink to the heading's `_Toc` bookmark,
|
|
2425
|
+
* holding the title, a tab to a right-aligned dot-leader stop, and a PAGEREF
|
|
2426
|
+
* field for the page number.
|
|
2427
|
+
*
|
|
2428
|
+
* HOW IT STAYS CURRENT. The entries' PAGEREF fields are ordinary complex
|
|
2429
|
+
* fields, so the update pass (edit/update-fields.ts) repages the whole table
|
|
2430
|
+
* with no TOC-specific code: it harvests each PAGEREF's page from a layout
|
|
2431
|
+
* like any other. Only a change to the HEADING SET needs rebuildToc, which
|
|
2432
|
+
* replaces the entry paragraphs outright.
|
|
2433
|
+
*/
|
|
2434
|
+
/** Levels a `\o` switch includes, e.g. [1, 3] for `\o "1-3"`. */
|
|
2435
|
+
type TocLevels = [number, number];
|
|
2436
|
+
/** The tab leaders a TOC entry can draw. One list, so a validator and a
|
|
2437
|
+
* schema cannot disagree about which exist. */
|
|
2438
|
+
declare const TOC_LEADERS: readonly ["dot", "hyphen", "underscore", "none"];
|
|
2439
|
+
type TocLeader = (typeof TOC_LEADERS)[number];
|
|
2440
|
+
|
|
2441
|
+
/**
|
|
2442
|
+
* The operation registry: ONE declaration per edit operation, read by every
|
|
2443
|
+
* surface that used to carry its own hand-written copy.
|
|
2444
|
+
*
|
|
2445
|
+
* Adding an operation used to cost four to six coordinated edits — a core
|
|
2446
|
+
* mutation, an editor dispatch, a wire intent variant in TWO packages, a
|
|
2447
|
+
* transform/validate case, an agent capability row, an agent id-budget case.
|
|
2448
|
+
* Each of those is guarded by a compile-time exhaustiveness gate, so nothing
|
|
2449
|
+
* could silently go missing; the cost was the coordination, not the risk. A
|
|
2450
|
+
* registered operation is declared once here, and the gates then consume the
|
|
2451
|
+
* registry instead of a second hand-maintained list. The gates are NOT
|
|
2452
|
+
* relaxed: an operation that is not registered still has to satisfy every one
|
|
2453
|
+
* of them by hand.
|
|
2454
|
+
*
|
|
2455
|
+
* WHAT MAY BE REGISTERED. The declaration shape below is deliberately narrow.
|
|
2456
|
+
* A registered operation must be:
|
|
2457
|
+
*
|
|
2458
|
+
* 1. ADDRESSED BY STABLE ID — a run, a paragraph, or a table cell paragraph.
|
|
2459
|
+
* The address is the whole of its collaborative "honest no-op" predicate:
|
|
2460
|
+
* when the id does not resolve in the room, the operation applies as a
|
|
2461
|
+
* clean rejection everywhere rather than mutating anything locally.
|
|
2462
|
+
* 2. POSITION-STABLE — it moves no run's text, so a concurrent intent's
|
|
2463
|
+
* offsets need no remapping and its transform is identity. The
|
|
2464
|
+
* text-shaped intents (insertText, deleteText, splitParagraph,
|
|
2465
|
+
* formatRange) each carry bespoke transform logic and stay hand-written.
|
|
2466
|
+
* 3. WITHOUT A WIRE INVERSE — collaborative undo skips it, which is the
|
|
2467
|
+
* status quo for every intent except the four in @wordinweb/collab's
|
|
2468
|
+
* invert.ts. The local path still takes a history checkpoint.
|
|
2469
|
+
*
|
|
2470
|
+
* Those three preconditions ARE the operation's undo and transform
|
|
2471
|
+
* classification. They are stated once, here, instead of repeated per
|
|
2472
|
+
* operation, because every operation the registry admits shares them; an
|
|
2473
|
+
* operation that breaks one of them does not belong in the registry yet.
|
|
2474
|
+
*/
|
|
2475
|
+
/** A stable id from the core side table (the wire's addressing unit). */
|
|
2476
|
+
type StableId$1 = number;
|
|
2477
|
+
/**
|
|
2478
|
+
* How a registered operation names its target on the wire.
|
|
2479
|
+
*
|
|
2480
|
+
* "document" scopes an operation to the whole document, which means it has no
|
|
2481
|
+
* stable id and therefore none of the honest-no-op protection an id gives: a
|
|
2482
|
+
* document address ALWAYS resolves. Such an operation has to supply its own
|
|
2483
|
+
* rejection predicate from the payload — see updateFields below, whose result
|
|
2484
|
+
* count must match the document's field count — and it must carry every value
|
|
2485
|
+
* a replica cannot re-derive identically.
|
|
2486
|
+
*
|
|
2487
|
+
* "object" names a DRAWING: the stable id of the run that CARRIES it, plus an
|
|
2488
|
+
* `objectIndex` into that run's content picking out which drawing it is (a run
|
|
2489
|
+
* can hold several). This is the addressing every hand-written drawing intent
|
|
2490
|
+
* already uses — setImageWrap, resizeDrawing — so a migrated one keeps its
|
|
2491
|
+
* wire shape. The index is NOT in the table below: it is a position inside the
|
|
2492
|
+
* run rather than an id of its own, which is also why it stays out of the
|
|
2493
|
+
* agent-facing field list, where a raw index is forbidden. BOTH halves reject:
|
|
2494
|
+
* an id nobody has and an index that no longer names a drawing are each the
|
|
2495
|
+
* same clean no-op, so the honest-no-op predicate is exactly the one every
|
|
2496
|
+
* addressed operation has. The index's WELL-FORMEDNESS is checked centrally
|
|
2497
|
+
* (see validateRegisteredOperation) rather than by each operation, for the
|
|
2498
|
+
* same reason the three preconditions above are stated once.
|
|
2499
|
+
*/
|
|
2500
|
+
type OperationAddress = "run" | "block" | "cell" | "object" | "document";
|
|
2501
|
+
/**
|
|
2502
|
+
* Agent capability category. Mirrors @wordinweb/agent's
|
|
2503
|
+
* AgentEditCapability["category"]; the agent's typed capability map is what
|
|
2504
|
+
* checks the two stay equal.
|
|
2505
|
+
*/
|
|
2506
|
+
type OperationCategory = "text" | "paragraph" | "review" | "table" | "insert" | "drawing" | "math" | "document";
|
|
2507
|
+
/** An agent-facing payload field beyond the address reference. Order is the
|
|
2508
|
+
* order the agent's JSON schema lists them in. */
|
|
2509
|
+
interface OperationField {
|
|
2510
|
+
name: string;
|
|
2511
|
+
/** Absent means required. */
|
|
2512
|
+
optional?: true;
|
|
2513
|
+
}
|
|
2514
|
+
/** What an address resolved to in the document. */
|
|
2515
|
+
interface OperationTarget {
|
|
2516
|
+
/** The addressed element: the w:r, the w:p, or the w:tbl owning the cell. */
|
|
2517
|
+
el: XmlElement;
|
|
2518
|
+
/** The first w:t under a run, or the first text descendant of a paragraph.
|
|
2519
|
+
* Null when the target carries no text (and for cell addressing). */
|
|
2520
|
+
t: XmlElement | null;
|
|
2521
|
+
/** The parsed run for a run address, null for the other two. Needed by
|
|
2522
|
+
* operations whose state is reachable only through the model — the checkbox
|
|
2523
|
+
* marker parsing hangs on a run's content — rather than from the XML. */
|
|
2524
|
+
run: Run | null;
|
|
2525
|
+
/**
|
|
2526
|
+
* For cell addressing: the addressed w:p itself. `el` deliberately widens a
|
|
2527
|
+
* cell address to the owning w:tbl, which is what a table-scoped operation
|
|
2528
|
+
* wants; a CELL-scoped one (per-edge borders, a margin override) needs the
|
|
2529
|
+
* one cell the caret is in, and the paragraph is how it gets there. Null
|
|
2530
|
+
* for run and block addressing, whose addressed element IS `el`.
|
|
2531
|
+
*/
|
|
2532
|
+
cellParagraph: XmlElement | null;
|
|
2533
|
+
/** For object addressing: the w:drawing (or VML shape) the address named.
|
|
2534
|
+
* Null for every other address. */
|
|
2535
|
+
drawing: XmlElement | null;
|
|
2536
|
+
}
|
|
2537
|
+
interface OperationContext<Payload> {
|
|
2538
|
+
doc: DocxDocument;
|
|
2539
|
+
target: OperationTarget;
|
|
2540
|
+
payload: Payload;
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* The caller-supplied part of a wire payload: everything except the address
|
|
2544
|
+
* field the dispatcher fills in and the carried ids it allocates.
|
|
2545
|
+
*/
|
|
2546
|
+
type OperationArgs<Payload> = Omit<Payload, "runId" | "blockId" | "cellParagraphId" | "nodeIds">;
|
|
2547
|
+
interface OperationDefinition<Kind extends string, Payload> {
|
|
2548
|
+
kind: Kind;
|
|
2549
|
+
address: OperationAddress;
|
|
2550
|
+
/** Agent capability row: how the operation is grouped and described. */
|
|
2551
|
+
category: OperationCategory;
|
|
2552
|
+
description: string;
|
|
2553
|
+
/** Agent-facing fields beyond the address reference, in schema order. */
|
|
2554
|
+
fields: readonly OperationField[];
|
|
2555
|
+
/**
|
|
2556
|
+
* How many fresh stable ids the mutation needs for the id-tracked nodes it
|
|
2557
|
+
* creates. Omit when it creates none. Every producer (the editor, the React
|
|
2558
|
+
* host, the agent compiler) reads this instead of repeating the arithmetic.
|
|
2559
|
+
*/
|
|
2560
|
+
nodeIds?: (args: OperationArgs<Payload>) => number;
|
|
2561
|
+
/** The mutation removes id-tracked nodes, so the caller must retire their
|
|
2562
|
+
* stable ids afterwards. Deletion and pruning are paired everywhere else in
|
|
2563
|
+
* the apply path (mergeParagraph, removeDrawing); declaring it here keeps
|
|
2564
|
+
* the pairing in the operation's single declaration. */
|
|
2565
|
+
prunesIds?: true;
|
|
2566
|
+
/**
|
|
2567
|
+
* Reject a malformed payload before it is sequenced. Runs on both sides of
|
|
2568
|
+
* the wire, so it must be a pure function of the payload.
|
|
2569
|
+
*/
|
|
2570
|
+
validate?: (payload: Payload) => string | null;
|
|
2571
|
+
/**
|
|
2572
|
+
* The XML mutation, headless and from a resolved target. False means a
|
|
2573
|
+
* clean no-op: the operation applied nothing and every replica agrees.
|
|
2574
|
+
*/
|
|
2575
|
+
apply: (ctx: OperationContext<Payload>) => boolean;
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* The optional suggest payload a TRACKABLE operation carries, and the
|
|
2579
|
+
* validation they share.
|
|
2580
|
+
*
|
|
2581
|
+
* With it the operation records what it replaced — w:pPrChange for a list
|
|
2582
|
+
* marker, w:tblPrChange / w:trPrChange / w:tcPrChange for table formatting —
|
|
2583
|
+
* instead of mutating outright, so a reviewer can accept or reject it. The
|
|
2584
|
+
* author and date travel in the payload so every replica writes byte-identical
|
|
2585
|
+
* XML; the w:id is scan-derived from identical tree state and needs no
|
|
2586
|
+
* carrying. Omitting it is a direct, untracked edit.
|
|
2587
|
+
*/
|
|
2588
|
+
interface SuggestablePayload {
|
|
2589
|
+
suggest?: {
|
|
2590
|
+
author: string;
|
|
2591
|
+
date: string;
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
/** A payload with no fields of its own. Not `Record<string, never>`: that
|
|
2595
|
+
* carries an index signature, which would forbid the clientId/clientSeq/base
|
|
2596
|
+
* bookkeeping @wordinweb/collab intersects onto every wire body. */
|
|
2597
|
+
type NoPayload = Record<never, never>;
|
|
2598
|
+
declare const OPERATIONS: readonly [OperationDefinition<"setListType", {
|
|
2599
|
+
blockId: StableId$1;
|
|
2600
|
+
listKind: "bullet" | "number" | null;
|
|
2601
|
+
/** Additional target paragraphs beyond the addressed one, sharing its
|
|
2602
|
+
* minted numbering definition. Absent = the old single-paragraph form. */
|
|
2603
|
+
moreBlockIds?: StableId$1[];
|
|
2604
|
+
} & SuggestablePayload>, OperationDefinition<"insertTable", {
|
|
2605
|
+
runId: StableId$1;
|
|
2606
|
+
rows: number;
|
|
2607
|
+
cols: number;
|
|
2608
|
+
cells?: string[][];
|
|
2609
|
+
headerRow?: boolean;
|
|
2610
|
+
nodeIds: StableId$1[];
|
|
2611
|
+
}>, OperationDefinition<"resizeTableRow", {
|
|
2612
|
+
cellParagraphId: StableId$1;
|
|
2613
|
+
rowIdx: number;
|
|
2614
|
+
heightPx: number;
|
|
2615
|
+
}>, OperationDefinition<"toggleCheckbox", {
|
|
2616
|
+
runId: StableId$1;
|
|
2617
|
+
}>, OperationDefinition<"updateFields", {
|
|
2618
|
+
results: string[];
|
|
2619
|
+
}>, OperationDefinition<"insertToc", {
|
|
2620
|
+
runId: StableId$1;
|
|
2621
|
+
levels?: TocLevels;
|
|
2622
|
+
leader?: TocLeader;
|
|
2623
|
+
/** With a label the field is a TABLE OF FIGURES (`TOC \c "Label"`): the
|
|
2624
|
+
* entries come from the label's caption paragraphs instead of headings. */
|
|
2625
|
+
captionLabel?: string;
|
|
2626
|
+
entryCount: number;
|
|
2627
|
+
nodeIds: StableId$1[];
|
|
2628
|
+
}>, OperationDefinition<"insertCaption", {
|
|
2629
|
+
blockId: StableId$1;
|
|
2630
|
+
label: string;
|
|
2631
|
+
text?: string;
|
|
2632
|
+
position?: "below" | "above";
|
|
2633
|
+
nodeIds: StableId$1[];
|
|
2634
|
+
}>, OperationDefinition<"ensureRefBookmark", {
|
|
2635
|
+
blockId: StableId$1;
|
|
2636
|
+
name: string;
|
|
2637
|
+
}>, OperationDefinition<"insertIndexEntry", {
|
|
2638
|
+
runId: StableId$1;
|
|
2639
|
+
entry: string;
|
|
2640
|
+
nodeIds: StableId$1[];
|
|
2641
|
+
}>, OperationDefinition<"insertIndex", {
|
|
2642
|
+
runId: StableId$1;
|
|
2643
|
+
entryCount: number;
|
|
2644
|
+
nodeIds: StableId$1[];
|
|
2645
|
+
}>, OperationDefinition<"refreshIndex", {
|
|
2646
|
+
entryCount: number;
|
|
2647
|
+
nodeIds: StableId$1[];
|
|
2648
|
+
}>, OperationDefinition<"createStyle", {
|
|
2649
|
+
style: StyleSpec;
|
|
2650
|
+
}>, OperationDefinition<"modifyStyle", {
|
|
2651
|
+
styleId: string;
|
|
2652
|
+
patch: StylePatch;
|
|
2653
|
+
}>, OperationDefinition<"deleteStyle", {
|
|
2654
|
+
styleId: string;
|
|
2655
|
+
}>, OperationDefinition<"setNumberingLevel", {
|
|
2656
|
+
blockId: StableId$1;
|
|
2657
|
+
ilvl: number | null;
|
|
2658
|
+
patch: LevelPatch;
|
|
2659
|
+
}>, OperationDefinition<"setNumberingRestart", {
|
|
2660
|
+
blockId: StableId$1;
|
|
2661
|
+
start: number | null;
|
|
2662
|
+
}>, OperationDefinition<"setParagraphBorders", {
|
|
2663
|
+
blockId: StableId$1;
|
|
2664
|
+
patch: ParagraphBordersPatch;
|
|
2665
|
+
} & SuggestablePayload>, OperationDefinition<"setTabStops", {
|
|
2666
|
+
blockId: StableId$1;
|
|
2667
|
+
stops: TabStopSpec[];
|
|
2668
|
+
} & SuggestablePayload>, OperationDefinition<"setTableBorders", {
|
|
2669
|
+
cellParagraphId: StableId$1;
|
|
2670
|
+
scope: "cell" | "table";
|
|
2671
|
+
edges: TableBorderEdge[];
|
|
2672
|
+
border: TableBorderSpec | null;
|
|
2673
|
+
} & SuggestablePayload>, OperationDefinition<"setTableStyle", {
|
|
2674
|
+
cellParagraphId: StableId$1;
|
|
2675
|
+
styleId: string | null;
|
|
2676
|
+
} & SuggestablePayload>, OperationDefinition<"setTableLook", {
|
|
2677
|
+
cellParagraphId: StableId$1;
|
|
2678
|
+
look: Partial<TableLookToggles>;
|
|
2679
|
+
} & SuggestablePayload>, OperationDefinition<"setTableWidth", {
|
|
2680
|
+
cellParagraphId: StableId$1;
|
|
2681
|
+
unit: "pt" | "pct" | "auto";
|
|
2682
|
+
value?: number;
|
|
2683
|
+
} & SuggestablePayload>, OperationDefinition<"setTableColumnWidth", {
|
|
2684
|
+
cellParagraphId: StableId$1;
|
|
2685
|
+
colIdx: number;
|
|
2686
|
+
widthPt: number;
|
|
2687
|
+
} & SuggestablePayload>, OperationDefinition<"setTableLayout", {
|
|
2688
|
+
cellParagraphId: StableId$1;
|
|
2689
|
+
layout: "fixed" | "autofit";
|
|
2690
|
+
renderedWidths?: number[];
|
|
2691
|
+
} & SuggestablePayload>, OperationDefinition<"setTableCellMargins", {
|
|
2692
|
+
cellParagraphId: StableId$1;
|
|
2693
|
+
scope: "cell" | "table";
|
|
2694
|
+
margins: CellMarginsPt | null;
|
|
2695
|
+
} & SuggestablePayload>, OperationDefinition<"setTableHeaderRows", {
|
|
2696
|
+
cellParagraphId: StableId$1;
|
|
2697
|
+
count: number;
|
|
2698
|
+
} & SuggestablePayload>, OperationDefinition<"insertTableFormula", {
|
|
2699
|
+
cellParagraphId: StableId$1;
|
|
2700
|
+
formula: string;
|
|
2701
|
+
numFmt?: string;
|
|
2702
|
+
nodeIds: StableId$1[];
|
|
2703
|
+
}>, OperationDefinition<"sortTableRows", {
|
|
2704
|
+
cellParagraphId: StableId$1;
|
|
2705
|
+
colIdx: number;
|
|
2706
|
+
order: "asc" | "desc";
|
|
2707
|
+
/** "kind" would collide with the intent discriminant, hence "compare". */
|
|
2708
|
+
compare: "text" | "number";
|
|
2709
|
+
hasHeader?: boolean;
|
|
2710
|
+
}>, OperationDefinition<"convertTextToTable", {
|
|
2711
|
+
blockId: StableId$1;
|
|
2712
|
+
moreBlockIds?: StableId$1[];
|
|
2713
|
+
separator: "tab" | "comma";
|
|
2714
|
+
cellCount: number;
|
|
2715
|
+
nodeIds: StableId$1[];
|
|
2716
|
+
}>, OperationDefinition<"convertTableToText", {
|
|
2717
|
+
cellParagraphId: StableId$1;
|
|
2718
|
+
separator: "tab" | "comma";
|
|
2719
|
+
rowCount: number;
|
|
2720
|
+
nodeIds: StableId$1[];
|
|
2721
|
+
}>, OperationDefinition<"insertEndnote", {
|
|
2722
|
+
runId: StableId$1;
|
|
2723
|
+
text: string;
|
|
2724
|
+
nodeIds: StableId$1[];
|
|
2725
|
+
}>, OperationDefinition<"setCrop", {
|
|
2726
|
+
runId: StableId$1;
|
|
2727
|
+
objectIndex?: number;
|
|
2728
|
+
crop: ImageCrop;
|
|
2729
|
+
}>, OperationDefinition<"setModel3DRotation", {
|
|
2730
|
+
runId: StableId$1;
|
|
2731
|
+
objectIndex?: number;
|
|
2732
|
+
rotation: Model3DRotation;
|
|
2733
|
+
}>, OperationDefinition<"setDrawingTextFit", {
|
|
2734
|
+
runId: StableId$1;
|
|
2735
|
+
objectIndex?: number;
|
|
2736
|
+
mode: DrawingTextFitMode;
|
|
2737
|
+
fontScalePct?: number;
|
|
2738
|
+
}>, OperationDefinition<"insertMergeField", {
|
|
2739
|
+
runId: StableId$1;
|
|
2740
|
+
name: string;
|
|
2741
|
+
nodeIds: StableId$1[];
|
|
2742
|
+
}>, OperationDefinition<"insertCitation", {
|
|
2743
|
+
runId: StableId$1;
|
|
2744
|
+
tag: string;
|
|
2745
|
+
nodeIds: StableId$1[];
|
|
2746
|
+
}>, OperationDefinition<"insertBibliography", {
|
|
2747
|
+
runId: StableId$1;
|
|
2748
|
+
entryCount: number;
|
|
2749
|
+
nodeIds: StableId$1[];
|
|
2750
|
+
}>, OperationDefinition<"refreshBibliography", {
|
|
2751
|
+
entryCount: number;
|
|
2752
|
+
nodeIds: StableId$1[];
|
|
2753
|
+
}>, OperationDefinition<"createCitationSource", {
|
|
2754
|
+
source: CitationSourceSpec;
|
|
2755
|
+
}>, OperationDefinition<"editCitationSource", {
|
|
2756
|
+
tag: string;
|
|
2757
|
+
patch: CitationSourcePatch;
|
|
2758
|
+
}>, OperationDefinition<"deleteCitationSource", {
|
|
2759
|
+
tag: string;
|
|
2760
|
+
}>, OperationDefinition<"setCitationStyle", {
|
|
2761
|
+
style: CitationStyle;
|
|
2762
|
+
}>, OperationDefinition<"createBuildingBlock", {
|
|
2763
|
+
name: string;
|
|
2764
|
+
category?: string;
|
|
2765
|
+
blocksXml: string;
|
|
2766
|
+
}>, OperationDefinition<"insertBuildingBlock", {
|
|
2767
|
+
name: string;
|
|
2768
|
+
/** The carried-id budget, computed by the caller from the SAME already-
|
|
2769
|
+
* synced glossary state the apply side reads (buildingBlockNodeCount) —
|
|
2770
|
+
* the insertBibliography entryCount pattern. */
|
|
2771
|
+
blockCount: number;
|
|
2772
|
+
}>, OperationDefinition<"deleteBuildingBlock", {
|
|
2773
|
+
name: string;
|
|
2774
|
+
}>, OperationDefinition<"insertWatermark", {
|
|
2775
|
+
text: string;
|
|
2776
|
+
headerCount: number;
|
|
2777
|
+
diagonal?: boolean;
|
|
2778
|
+
color?: string;
|
|
2779
|
+
opacity?: number;
|
|
2780
|
+
nodeIds: StableId$1[];
|
|
2781
|
+
}>, OperationDefinition<"insertPictureWatermark", {
|
|
2782
|
+
blobSha: string;
|
|
2783
|
+
bytesLen: number;
|
|
2784
|
+
ext: string;
|
|
2785
|
+
iv?: string;
|
|
2786
|
+
naturalWidthPx: number;
|
|
2787
|
+
naturalHeightPx: number;
|
|
2788
|
+
headerCount: number;
|
|
2789
|
+
washout?: boolean;
|
|
2790
|
+
nodeIds: StableId$1[];
|
|
2791
|
+
}>, OperationDefinition<"removeWatermark", NoPayload>, OperationDefinition<"setTitlePage", {
|
|
2792
|
+
enabled: boolean;
|
|
2793
|
+
nodeIds: StableId$1[];
|
|
2794
|
+
}>, OperationDefinition<"setEvenOddHeaders", {
|
|
2795
|
+
enabled: boolean;
|
|
2796
|
+
nodeIds: StableId$1[];
|
|
2797
|
+
}>, OperationDefinition<"setPageNumberFormat", {
|
|
2798
|
+
fmt?: PageNumberFormat | null;
|
|
2799
|
+
start?: number | null;
|
|
2800
|
+
}>, OperationDefinition<"setHyphenation", {
|
|
2801
|
+
auto?: boolean;
|
|
2802
|
+
zonePt?: number | null;
|
|
2803
|
+
noCaps?: boolean;
|
|
2804
|
+
}>, OperationDefinition<"insertPageNumberPosition", {
|
|
2805
|
+
position: PageNumberGalleryPosition;
|
|
2806
|
+
align: PageNumberGalleryAlign;
|
|
2807
|
+
nodeIds: StableId$1[];
|
|
2808
|
+
}>, OperationDefinition<"removePageNumbers", Record<never, never>>, OperationDefinition<"insertHeaderFooterPreset", {
|
|
2809
|
+
hfKind: "header" | "footer";
|
|
2810
|
+
preset: HeaderFooterPreset;
|
|
2811
|
+
nodeIds: StableId$1[];
|
|
2812
|
+
}>, OperationDefinition<"setFootnoteOptions", {
|
|
2813
|
+
fmt?: NoteNumberFormat | null;
|
|
2814
|
+
start?: number | null;
|
|
2815
|
+
restart?: NoteRestart | null;
|
|
2816
|
+
pos?: "pageBottom" | "beneathText" | null;
|
|
2817
|
+
}>, OperationDefinition<"setEndnoteOptions", {
|
|
2818
|
+
fmt?: NoteNumberFormat | null;
|
|
2819
|
+
start?: number | null;
|
|
2820
|
+
restart?: NoteRestart | null;
|
|
2821
|
+
pos?: "sectEnd" | "docEnd" | null;
|
|
2822
|
+
}>];
|
|
2823
|
+
type AnyOperationDefinition = (typeof OPERATIONS)[number];
|
|
2824
|
+
/** Distributes: one body type per registered operation. */
|
|
2825
|
+
type BodyOf<D> = D extends OperationDefinition<infer Kind, infer Payload> ? {
|
|
2826
|
+
kind: Kind;
|
|
2827
|
+
} & Payload : never;
|
|
2828
|
+
type RegisteredOperationKind = AnyOperationDefinition["kind"];
|
|
2829
|
+
/**
|
|
2830
|
+
* The wire body of every registered operation. @wordinweb/collab intersects
|
|
2831
|
+
* this with its IntentBase bookkeeping to form the Intent variants, so the
|
|
2832
|
+
* payload is declared once and the wire shape follows.
|
|
2833
|
+
*/
|
|
2834
|
+
type RegisteredOperationBody = BodyOf<AnyOperationDefinition>;
|
|
2835
|
+
|
|
1683
2836
|
/**
|
|
1684
2837
|
* Wire intents for replicated editing.
|
|
1685
2838
|
*
|
|
@@ -1694,6 +2847,7 @@ declare class DocxDocument {
|
|
|
1694
2847
|
* against everything sequenced in `(base, seq)` before applying and
|
|
1695
2848
|
* broadcasting the canonical form (doc 03).
|
|
1696
2849
|
*/
|
|
2850
|
+
|
|
1697
2851
|
type StableId = number;
|
|
1698
2852
|
/** A caret/endpoint position within a run. */
|
|
1699
2853
|
interface Position {
|
|
@@ -1734,10 +2888,13 @@ interface SuggestRevisionIntent extends IntentBase {
|
|
|
1734
2888
|
blockId: StableId;
|
|
1735
2889
|
glyph: "ins" | "del";
|
|
1736
2890
|
}[];
|
|
1737
|
-
suggest:
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
2891
|
+
suggest: SuggestMeta;
|
|
2892
|
+
}
|
|
2893
|
+
/** Author + date of a tracked change, generated once by the originating
|
|
2894
|
+
* client so every replica writes the same w:author/w:date (rule a above). */
|
|
2895
|
+
interface SuggestMeta {
|
|
2896
|
+
author: string;
|
|
2897
|
+
date: string;
|
|
1741
2898
|
}
|
|
1742
2899
|
/** Insert `text` at a position. With `suggest`, the insertion is recorded as
|
|
1743
2900
|
* a tracked change (w:ins) carrying the author + date (revision tracking /
|
|
@@ -1752,6 +2909,37 @@ interface InsertTextIntent extends IntentBase {
|
|
|
1752
2909
|
date: string;
|
|
1753
2910
|
};
|
|
1754
2911
|
}
|
|
2912
|
+
/**
|
|
2913
|
+
* Insert an inline separator — a soft line break (w:br, Shift+Enter) or a
|
|
2914
|
+
* tab character (w:tab, Tab in a body paragraph) — at a position. The
|
|
2915
|
+
* mutation splits the addressed run's w:t IN PLACE (no new run, every stable
|
|
2916
|
+
* id preserved), and a separator counts ONE unit in the run's wire-offset
|
|
2917
|
+
* basis (core runWireLength), so the transform is exactly an insertText of
|
|
2918
|
+
* length one. With `suggest` the separator is recorded as a w:ins sibling
|
|
2919
|
+
* (insertSuggestedSeparator) like a typed suggestion.
|
|
2920
|
+
*/
|
|
2921
|
+
interface InsertSeparatorIntent extends IntentBase {
|
|
2922
|
+
kind: "insertSeparator";
|
|
2923
|
+
at: Position;
|
|
2924
|
+
separator: "br" | "tab";
|
|
2925
|
+
suggest?: SuggestMeta;
|
|
2926
|
+
}
|
|
2927
|
+
/**
|
|
2928
|
+
* Delete the inline separator (w:br / w:tab / w:cr) occupying wire unit
|
|
2929
|
+
* [at.offset, at.offset+1) of the addressed run — insertSeparator's inverse
|
|
2930
|
+
* (a separator-aware Backspace/Delete). The plain mutation removes the
|
|
2931
|
+
* separator element and joins the two w:t halves its insert split, so the
|
|
2932
|
+
* transform is exactly a deleteText of length one in the separator-counting
|
|
2933
|
+
* wire basis. With `suggest` the separator is recorded as a tracked deletion
|
|
2934
|
+
* instead (deleteSuggestedSeparator: a w:del around the separator's own run
|
|
2935
|
+
* slice, the host run splitting like a text strike). A unit that no longer
|
|
2936
|
+
* holds a separator (concurrent edit) is a clean no-op on every replica.
|
|
2937
|
+
*/
|
|
2938
|
+
interface DeleteSeparatorIntent extends IntentBase {
|
|
2939
|
+
kind: "deleteSeparator";
|
|
2940
|
+
at: Position;
|
|
2941
|
+
suggest?: SuggestMeta;
|
|
2942
|
+
}
|
|
1755
2943
|
/** Delete `[start, end)` characters within a single run. */
|
|
1756
2944
|
interface DeleteTextIntent extends IntentBase {
|
|
1757
2945
|
kind: "deleteText";
|
|
@@ -1793,6 +2981,9 @@ interface FormatRunIntent extends IntentBase {
|
|
|
1793
2981
|
/** RunFormatPatch (bold/italic/underline/strike/color/…). Structural shape
|
|
1794
2982
|
* mirrors @wordinweb/core's RunFormatPatch; carried verbatim. */
|
|
1795
2983
|
patch: Record<string, unknown>;
|
|
2984
|
+
/** Tracked-change (suggesting) metadata: the run records the properties it
|
|
2985
|
+
* had in a w:rPrChange instead of losing them. Omit for a direct format. */
|
|
2986
|
+
suggest?: SuggestMeta;
|
|
1796
2987
|
}
|
|
1797
2988
|
/**
|
|
1798
2989
|
* Paragraph-level formatting: alignment and/or paragraph style. Block-level —
|
|
@@ -1805,17 +2996,26 @@ interface FormatParagraphIntent extends IntentBase {
|
|
|
1805
2996
|
align?: "left" | "center" | "right" | "justify";
|
|
1806
2997
|
/** Paragraph style id; null clears to Normal. Omit to leave unchanged. */
|
|
1807
2998
|
styleId?: string | null;
|
|
2999
|
+
/** Tracked-change (suggesting) metadata: the paragraph records the
|
|
3000
|
+
* properties it had in a w:pPrChange. Omit for a direct format. */
|
|
3001
|
+
suggest?: SuggestMeta;
|
|
1808
3002
|
}
|
|
1809
3003
|
/**
|
|
1810
3004
|
* Turn a paragraph into a bullet/numbered list item, or clear its list
|
|
1811
3005
|
* formatting (kind null). Block-level: mutates w:pPr/numbering, preserves the
|
|
1812
3006
|
* block id, moves no text — transform identity.
|
|
3007
|
+
*
|
|
3008
|
+
* A multi-paragraph selection rides in ONE intent (optional `moreBlockIds`
|
|
3009
|
+
* beyond the addressed paragraph): the single apply mints ONE numbering
|
|
3010
|
+
* definition shared by every target, which is both Word's semantics (one
|
|
3011
|
+
* continuous list) and the only convergent shape — per-paragraph intents
|
|
3012
|
+
* each minted a fresh definition at apply, diverging from the originator's
|
|
3013
|
+
* single shared-definition local mutation.
|
|
3014
|
+
*
|
|
3015
|
+
* REGISTERED: shape and wiring come from the core operation registry (see
|
|
3016
|
+
* RegisteredIntent below). The alias keeps the published type name.
|
|
1813
3017
|
*/
|
|
1814
|
-
|
|
1815
|
-
kind: "setListType";
|
|
1816
|
-
blockId: StableId;
|
|
1817
|
-
listKind: "bullet" | "number" | null;
|
|
1818
|
-
}
|
|
3018
|
+
type SetListTypeIntent = RegisteredIntentOf<"setListType">;
|
|
1819
3019
|
/**
|
|
1820
3020
|
* Format a character sub-range of a single run (plan doc 03 F3). The run is
|
|
1821
3021
|
* split into up to three pieces — before [0,start), middle [start,end)
|
|
@@ -1836,19 +3036,23 @@ interface FormatRangeIntent extends IntentBase {
|
|
|
1836
3036
|
beforeId?: StableId;
|
|
1837
3037
|
middleId: StableId;
|
|
1838
3038
|
afterId?: StableId;
|
|
3039
|
+
/** Tracked-change (suggesting) metadata: the middle piece records the
|
|
3040
|
+
* properties it had in a w:rPrChange. Omit for a direct format. */
|
|
3041
|
+
suggest?: SuggestMeta;
|
|
1839
3042
|
}
|
|
1840
3043
|
/**
|
|
1841
|
-
* A table operation
|
|
1842
|
-
*
|
|
1843
|
-
*
|
|
1844
|
-
*
|
|
1845
|
-
*
|
|
3044
|
+
* A table operation addressed by the stable id of a paragraph inside the
|
|
3045
|
+
* target cell. Every op is position-stable (no surviving run's offsets move),
|
|
3046
|
+
* so the transform is identity; concurrent edits into removed cells fail
|
|
3047
|
+
* cleanly at apply (retired ids). Ops that create tracked nodes (the inserts,
|
|
3048
|
+
* mergeDown's fresh continuation paragraph, splitCell's new cells) take their
|
|
3049
|
+
* ids from `nodeIds`; ops that remove content prune the retired ids at apply.
|
|
1846
3050
|
*/
|
|
1847
3051
|
interface TableOpIntent extends IntentBase {
|
|
1848
3052
|
/** Stable id of a paragraph inside the target cell. */
|
|
1849
3053
|
cellParagraphId: StableId;
|
|
1850
3054
|
kind: "tableOp";
|
|
1851
|
-
op: "deleteRow" | "deleteCol" | "deleteTable" | "rowAbove" | "rowBelow" | "colLeft" | "colRight" | {
|
|
3055
|
+
op: "deleteRow" | "deleteCol" | "deleteTable" | "rowAbove" | "rowBelow" | "colLeft" | "colRight" | "mergeRight" | "mergeDown" | "splitCell" | {
|
|
1852
3056
|
kind: "cellShading";
|
|
1853
3057
|
fill: string | null;
|
|
1854
3058
|
} | {
|
|
@@ -1860,10 +3064,18 @@ interface TableOpIntent extends IntentBase {
|
|
|
1860
3064
|
xPx: number;
|
|
1861
3065
|
yPx: number;
|
|
1862
3066
|
};
|
|
1863
|
-
/** For
|
|
1864
|
-
* new
|
|
1865
|
-
* alike. */
|
|
3067
|
+
/** For ops that create tracked nodes (rowAbove/rowBelow/colLeft/colRight,
|
|
3068
|
+
* mergeDown, splitCell): carried ids for the new nodes (p / r) in document
|
|
3069
|
+
* order, so replicas address them alike. */
|
|
1866
3070
|
nodeIds?: StableId[];
|
|
3071
|
+
/**
|
|
3072
|
+
* Tracked-change (suggesting) metadata; see FormatParagraphIntent. Only the
|
|
3073
|
+
* three FORMATTING ops honour it — cellShading and cellVAlign record a
|
|
3074
|
+
* w:tcPrChange, textWrapping a w:tblPrChange. The structural ops have no
|
|
3075
|
+
* tracked form and ignore it, so the surfaces that enforce suggesting mode
|
|
3076
|
+
* refuse those outright rather than send one.
|
|
3077
|
+
*/
|
|
3078
|
+
suggest?: SuggestMeta;
|
|
1867
3079
|
}
|
|
1868
3080
|
/**
|
|
1869
3081
|
* Merge a paragraph into its predecessor (Backspace at paragraph start). The
|
|
@@ -1875,6 +3087,14 @@ interface MergeParagraphIntent extends IntentBase {
|
|
|
1875
3087
|
kind: "mergeParagraph";
|
|
1876
3088
|
/** The paragraph to merge into the one before it. */
|
|
1877
3089
|
blockId: StableId;
|
|
3090
|
+
/**
|
|
3091
|
+
* Tracked-change (suggesting) metadata. Word tracks a merge as a DELETED
|
|
3092
|
+
* PARAGRAPH MARK: the pilcrow that separates the two paragraphs — the
|
|
3093
|
+
* PREVIOUS paragraph's mark — gets a w:del in its pPr/rPr, and both
|
|
3094
|
+
* paragraphs stay in place until the reviewer accepts. Omit for a direct
|
|
3095
|
+
* merge.
|
|
3096
|
+
*/
|
|
3097
|
+
suggest?: SuggestMeta;
|
|
1878
3098
|
}
|
|
1879
3099
|
/**
|
|
1880
3100
|
* Add a review comment anchored to an entire run. Comment markers
|
|
@@ -1970,11 +3190,14 @@ interface InsertMathIntent extends IntentBase {
|
|
|
1970
3190
|
mathText: string;
|
|
1971
3191
|
nodeIds: StableId[];
|
|
1972
3192
|
}
|
|
1973
|
-
/** Insert a shape/textbox drawing at the end of a run (sibling — identity).
|
|
3193
|
+
/** Insert a shape/textbox drawing at the end of a run (sibling — identity).
|
|
3194
|
+
* `preset` is a legacy named preset (line/verticalLine/rectangle/
|
|
3195
|
+
* roundedRectangle/ellipse/diamond/textBox) or any ST_ShapeType name core's
|
|
3196
|
+
* preset-geometry table knows; validated with isValidShapePreset. */
|
|
1974
3197
|
interface InsertShapeIntent extends IntentBase {
|
|
1975
3198
|
kind: "insertShape";
|
|
1976
3199
|
runId: StableId;
|
|
1977
|
-
preset:
|
|
3200
|
+
preset: string;
|
|
1978
3201
|
text?: string;
|
|
1979
3202
|
nodeIds: StableId[];
|
|
1980
3203
|
}
|
|
@@ -2000,6 +3223,8 @@ interface AdjustIndentIntent extends IntentBase {
|
|
|
2000
3223
|
kind: "adjustIndent";
|
|
2001
3224
|
blockId: StableId;
|
|
2002
3225
|
direction: 1 | -1;
|
|
3226
|
+
/** Tracked-change (suggesting) metadata; see FormatParagraphIntent. */
|
|
3227
|
+
suggest?: SuggestMeta;
|
|
2003
3228
|
}
|
|
2004
3229
|
/** Set paragraph line/before/after spacing. Block-level, identity. */
|
|
2005
3230
|
interface SetSpacingIntent extends IntentBase {
|
|
@@ -2007,6 +3232,8 @@ interface SetSpacingIntent extends IntentBase {
|
|
|
2007
3232
|
blockId: StableId;
|
|
2008
3233
|
/** ParagraphSpacingPatch (before/after/line/lineRule) — carried verbatim. */
|
|
2009
3234
|
patch: Record<string, unknown>;
|
|
3235
|
+
/** Tracked-change (suggesting) metadata; see FormatParagraphIntent. */
|
|
3236
|
+
suggest?: SuggestMeta;
|
|
2010
3237
|
}
|
|
2011
3238
|
/** Insert a page-number field at the end of a run (sibling insertion,
|
|
2012
3239
|
* identity). Page fields are deterministic (no clock). */
|
|
@@ -2050,7 +3277,22 @@ interface InsertBookmarkIntent extends IntentBase {
|
|
|
2050
3277
|
runId: StableId;
|
|
2051
3278
|
name: string;
|
|
2052
3279
|
}
|
|
2053
|
-
|
|
3280
|
+
/**
|
|
3281
|
+
* Intents whose wire shape comes from the core operation registry. One
|
|
3282
|
+
* declaration in @wordinweb/core's edit/registry.ts produces the payload, the
|
|
3283
|
+
* apply, the validation, the carried-id budget, and the agent capability row;
|
|
3284
|
+
* here it just picks up the wire bookkeeping every intent carries.
|
|
3285
|
+
*
|
|
3286
|
+
* The registry admits only id-addressed, position-stable operations with no
|
|
3287
|
+
* wire inverse, so every registered intent's transform is identity and
|
|
3288
|
+
* collaborative undo skips it — see the registry's module comment.
|
|
3289
|
+
*/
|
|
3290
|
+
type RegisteredIntent = RegisteredOperationBody & IntentBase;
|
|
3291
|
+
/** One registered intent, by kind. */
|
|
3292
|
+
type RegisteredIntentOf<Kind extends RegisteredOperationKind> = Extract<RegisteredIntent, {
|
|
3293
|
+
kind: Kind;
|
|
3294
|
+
}>;
|
|
3295
|
+
type Intent = InsertTextIntent | InsertSeparatorIntent | DeleteSeparatorIntent | DeleteTextIntent | SplitParagraphIntent | FormatRunIntent | FormatParagraphIntent | SetListTypeIntent | FormatRangeIntent | TableOpIntent | MergeParagraphIntent | CommentRunIntent | PasteBlocksIntent | InsertImageIntent | SuggestRevisionIntent | InsertBreakIntent | InsertMathIntent | InsertShapeIntent | ReplyCommentIntent | AdjustIndentIntent | SetSpacingIntent | InsertPageFieldIntent | SetLinkIntent | InsertFootnoteIntent | SetDropCapIntent | SetDividerIntent | InsertBookmarkIntent | InsertBlankPageIntent | InsertSectionBreakIntent | InsertCrossRefIntent | InsertCoverPageIntent | SetPageLayoutIntent | SetListLevelIntent | InsertWordArtIntent | InsertChartIntent | InsertSmartArtIntent | SetLineNumberingIntent | InsertDateTimeFieldIntent | InsertFieldIntent | SetDrawingRotationIntent | SetDrawingFillIntent | SetChartDataIntent | SetSmartArtNodeTextIntent | SetDrawingWordArtTextIntent | SetDrawingWordArtStyleIntent | SetDrawingLineStyleIntent | SetImageAltTextIntent | RemoveLinkIntent | SetImageWrapIntent | SetDrawingOrderIntent | SetSmartArtDataIntent | SetSmartArtFillIntent | SetSmartArtTextFormatIntent | SetFloatingPagePositionIntent | ResizeDrawingIntent | ResizeTableColumnIntent | MoveTableIntent | RemoveDrawingIntent | SetMathLinearIntent | DeleteMathIntent | MoveMathIntent | EnsureHeaderFooterIntent | DeleteCommentIntent | ResolveCommentIntent | EditCommentIntent | InsertBookmarkRangeIntent | AcceptRevisionIntent | RejectRevisionIntent | AcceptAllRevisionsIntent | RejectAllRevisionsIntent | RegisteredIntent;
|
|
2054
3296
|
/** Insert a blank page at the end of a run. */
|
|
2055
3297
|
interface InsertBlankPageIntent extends IntentBase {
|
|
2056
3298
|
kind: "insertBlankPage";
|
|
@@ -2098,22 +3340,33 @@ interface InsertWordArtIntent extends IntentBase {
|
|
|
2098
3340
|
kind: "insertWordArt";
|
|
2099
3341
|
runId: StableId;
|
|
2100
3342
|
text: string;
|
|
2101
|
-
preset: "plain" | "archUp" | "archDown" | "wave" | "chevron";
|
|
3343
|
+
preset: "plain" | "archUp" | "archDown" | "wave" | "chevron" | "circle" | "button" | "chevronDown";
|
|
3344
|
+
/** Gallery style: glyph fill plus optional outline and shadow. */
|
|
3345
|
+
style?: {
|
|
3346
|
+
fill: string;
|
|
3347
|
+
outline?: {
|
|
3348
|
+
color: string;
|
|
3349
|
+
widthPt: number;
|
|
3350
|
+
};
|
|
3351
|
+
shadow?: boolean;
|
|
3352
|
+
};
|
|
2102
3353
|
nodeIds: StableId[];
|
|
2103
3354
|
}
|
|
2104
|
-
/** Insert a data chart
|
|
2105
|
-
*
|
|
3355
|
+
/** Insert a data chart at the end of a run. The chart data is carried
|
|
3356
|
+
* verbatim; the workbook part is generated deterministically. */
|
|
2106
3357
|
interface InsertChartIntent extends IntentBase {
|
|
2107
3358
|
kind: "insertChart";
|
|
2108
3359
|
runId: StableId;
|
|
2109
3360
|
chart: {
|
|
2110
|
-
type: "column" | "bar" | "line" | "pie";
|
|
3361
|
+
type: "column" | "bar" | "line" | "pie" | "doughnut" | "area" | "scatter";
|
|
2111
3362
|
title?: string;
|
|
2112
3363
|
categories: string[];
|
|
2113
3364
|
series: {
|
|
2114
3365
|
name: string;
|
|
2115
3366
|
values: number[];
|
|
2116
3367
|
}[];
|
|
3368
|
+
/** How bar/column/area series group; absent = clustered. */
|
|
3369
|
+
grouping?: "clustered" | "stacked" | "percentStacked";
|
|
2117
3370
|
};
|
|
2118
3371
|
nodeIds: StableId[];
|
|
2119
3372
|
}
|
|
@@ -2179,15 +3432,7 @@ interface SetDrawingFillIntent extends IntentBase, DrawingTarget {
|
|
|
2179
3432
|
interface SetChartDataIntent extends IntentBase, DrawingTarget {
|
|
2180
3433
|
kind: "setChartData";
|
|
2181
3434
|
runId: StableId;
|
|
2182
|
-
chart:
|
|
2183
|
-
type: "column" | "bar" | "line" | "pie";
|
|
2184
|
-
title?: string;
|
|
2185
|
-
categories: string[];
|
|
2186
|
-
series: {
|
|
2187
|
-
name: string;
|
|
2188
|
-
values: number[];
|
|
2189
|
-
}[];
|
|
2190
|
-
};
|
|
3435
|
+
chart: InsertChartIntent["chart"];
|
|
2191
3436
|
}
|
|
2192
3437
|
/** Set the text of one node of the SmartArt diagram carried by a run. */
|
|
2193
3438
|
interface SetSmartArtNodeTextIntent extends IntentBase, DrawingTarget {
|
|
@@ -2303,13 +3548,6 @@ interface ResizeTableColumnIntent extends IntentBase {
|
|
|
2303
3548
|
deltaPx: number;
|
|
2304
3549
|
renderedWidths?: number[];
|
|
2305
3550
|
}
|
|
2306
|
-
/** Drag-resize a table row's height (trHeight atLeast). */
|
|
2307
|
-
interface ResizeTableRowIntent extends IntentBase {
|
|
2308
|
-
kind: "resizeTableRow";
|
|
2309
|
-
cellParagraphId: StableId;
|
|
2310
|
-
rowIdx: number;
|
|
2311
|
-
heightPx: number;
|
|
2312
|
-
}
|
|
2313
3551
|
/** Position a table at page coordinates (converts inline to float). */
|
|
2314
3552
|
interface MoveTableIntent extends IntentBase {
|
|
2315
3553
|
kind: "moveTable";
|
|
@@ -2324,25 +3562,32 @@ interface RemoveDrawingIntent extends IntentBase, DrawingTarget {
|
|
|
2324
3562
|
kind: "removeDrawing";
|
|
2325
3563
|
runId: StableId;
|
|
2326
3564
|
}
|
|
2327
|
-
/**
|
|
3565
|
+
/**
|
|
3566
|
+
* Which equation inside a block a math intent means: its position among the
|
|
3567
|
+
* block's m:oMath elements in document order. Absent means the first one, so
|
|
3568
|
+
* an intent recorded before a block could hold more than one addressable
|
|
3569
|
+
* equation still names what it always named.
|
|
3570
|
+
*/
|
|
3571
|
+
interface MathTarget {
|
|
3572
|
+
blockId: StableId;
|
|
3573
|
+
mathIndex?: number;
|
|
3574
|
+
}
|
|
3575
|
+
/** Replace the equation of a math object in a paragraph (linear syntax).
|
|
2328
3576
|
* Math (m:oMath) lives at paragraph level, so this is block-addressed. */
|
|
2329
|
-
interface SetMathLinearIntent extends IntentBase {
|
|
3577
|
+
interface SetMathLinearIntent extends IntentBase, MathTarget {
|
|
2330
3578
|
kind: "setMathLinear";
|
|
2331
|
-
blockId: StableId;
|
|
2332
3579
|
mathText: string;
|
|
2333
3580
|
}
|
|
2334
|
-
/** Delete
|
|
2335
|
-
interface DeleteMathIntent extends IntentBase {
|
|
3581
|
+
/** Delete a math object in a paragraph. */
|
|
3582
|
+
interface DeleteMathIntent extends IntentBase, MathTarget {
|
|
2336
3583
|
kind: "deleteMath";
|
|
2337
|
-
blockId: StableId;
|
|
2338
3584
|
}
|
|
2339
3585
|
/** Drag-move the equation out of `blockId` to the text position `at`. The
|
|
2340
|
-
* equation is addressed like the other math intents (block +
|
|
3586
|
+
* equation is addressed like the other math intents (block + mathIndex); the
|
|
2341
3587
|
* destination is an ordinary wire caret. Dropping mid-text splits the
|
|
2342
3588
|
* destination run, so the split-off tail run takes a carried id. */
|
|
2343
|
-
interface MoveMathIntent extends IntentBase {
|
|
3589
|
+
interface MoveMathIntent extends IntentBase, MathTarget {
|
|
2344
3590
|
kind: "moveMath";
|
|
2345
|
-
blockId: StableId;
|
|
2346
3591
|
at: Position;
|
|
2347
3592
|
nodeIds: StableId[];
|
|
2348
3593
|
}
|
|
@@ -2358,11 +3603,36 @@ interface EnsureHeaderFooterIntent extends IntentBase {
|
|
|
2358
3603
|
hfKind: "header" | "footer";
|
|
2359
3604
|
nodeIds: StableId[];
|
|
2360
3605
|
}
|
|
2361
|
-
/** Delete a comment (and its reply thread) by id.
|
|
3606
|
+
/** Delete a comment (and its reply thread) by id. Addressed with a reply's
|
|
3607
|
+
* id it deletes just that reply — the thread/reply distinction is the id. */
|
|
2362
3608
|
interface DeleteCommentIntent extends IntentBase {
|
|
2363
3609
|
kind: "deleteComment";
|
|
2364
3610
|
commentId: string;
|
|
2365
3611
|
}
|
|
3612
|
+
/**
|
|
3613
|
+
* Resolve (true) or reopen (false) a comment thread. Addressed like
|
|
3614
|
+
* deleteComment, by the comment's deterministic string id (a reply id
|
|
3615
|
+
* resolves its thread's parent). The mutation writes w15:done on the thread
|
|
3616
|
+
* parent's commentsExtended entry; when the parent's body paragraph carries
|
|
3617
|
+
* no w14:paraId yet, the carried `paraId` candidate is consumed to mint one
|
|
3618
|
+
* (provenance rule a — generated once by the originator, identical XML on
|
|
3619
|
+
* every replica). No document run's text moves — identity transform.
|
|
3620
|
+
*/
|
|
3621
|
+
interface ResolveCommentIntent extends IntentBase {
|
|
3622
|
+
kind: "resolveComment";
|
|
3623
|
+
commentId: string;
|
|
3624
|
+
resolved: boolean;
|
|
3625
|
+
/** paraId candidate, consumed only when the thread parent lacks one. */
|
|
3626
|
+
paraId: string;
|
|
3627
|
+
}
|
|
3628
|
+
/** Replace a comment's body text (Word's edit-my-comment). Author, date, id,
|
|
3629
|
+
* anchors and threading stay; deterministic given the carried text — identity
|
|
3630
|
+
* transform, clean no-op for an unknown id or unchanged text. */
|
|
3631
|
+
interface EditCommentIntent extends IntentBase {
|
|
3632
|
+
kind: "editComment";
|
|
3633
|
+
commentId: string;
|
|
3634
|
+
text: string;
|
|
3635
|
+
}
|
|
2366
3636
|
/** Wrap a sub-range of a run's text in a named bookmark. */
|
|
2367
3637
|
interface InsertBookmarkRangeIntent extends IntentBase {
|
|
2368
3638
|
kind: "insertBookmarkRange";
|
|
@@ -2371,11 +3641,6 @@ interface InsertBookmarkRangeIntent extends IntentBase {
|
|
|
2371
3641
|
start: number;
|
|
2372
3642
|
end: number;
|
|
2373
3643
|
}
|
|
2374
|
-
/** Toggle the checkbox content control carried by a run. */
|
|
2375
|
-
interface ToggleCheckboxIntent extends IntentBase {
|
|
2376
|
-
kind: "toggleCheckbox";
|
|
2377
|
-
runId: StableId;
|
|
2378
|
-
}
|
|
2379
3644
|
/** Accept one tracked change, addressed by its position in document order
|
|
2380
3645
|
* (collectRevisions order — deterministic across replicas). */
|
|
2381
3646
|
interface AcceptRevisionIntent extends IntentBase {
|
|
@@ -2387,21 +3652,17 @@ interface RejectRevisionIntent extends IntentBase {
|
|
|
2387
3652
|
kind: "rejectRevision";
|
|
2388
3653
|
index: number;
|
|
2389
3654
|
}
|
|
2390
|
-
/** Accept every tracked change in the document
|
|
3655
|
+
/** Accept every tracked change in the document, or only one author's when
|
|
3656
|
+
* `author` is given — a surface that owns some of the revisions must not
|
|
3657
|
+
* resolve the rest. Absent means all, which is what older clients send. */
|
|
2391
3658
|
interface AcceptAllRevisionsIntent extends IntentBase {
|
|
2392
3659
|
kind: "acceptAllRevisions";
|
|
3660
|
+
author?: string;
|
|
2393
3661
|
}
|
|
2394
|
-
/** Reject every tracked change
|
|
3662
|
+
/** Reject every tracked change, or only one author's. See AcceptAll. */
|
|
2395
3663
|
interface RejectAllRevisionsIntent extends IntentBase {
|
|
2396
3664
|
kind: "rejectAllRevisions";
|
|
2397
|
-
|
|
2398
|
-
/** Insert a rows×cols table after the paragraph containing the anchor run. */
|
|
2399
|
-
interface InsertTableIntent extends IntentBase {
|
|
2400
|
-
kind: "insertTable";
|
|
2401
|
-
runId: StableId;
|
|
2402
|
-
rows: number;
|
|
2403
|
-
cols: number;
|
|
2404
|
-
nodeIds: StableId[];
|
|
3665
|
+
author?: string;
|
|
2405
3666
|
}
|
|
2406
3667
|
/** An intent minus its wire bookkeeping — distributive over the union so each
|
|
2407
3668
|
* variant keeps its own fields (a plain Omit<Intent,…> would collapse to the
|
|
@@ -2477,11 +3738,8 @@ interface AgentEditCapability {
|
|
|
2477
3738
|
required: string[];
|
|
2478
3739
|
optional?: string[];
|
|
2479
3740
|
}
|
|
2480
|
-
/**
|
|
2481
|
-
*
|
|
2482
|
-
* Record<Intent["kind"], ...> makes a new intent fail the agent build until
|
|
2483
|
-
* its tool contract is declared here.
|
|
2484
|
-
*/
|
|
3741
|
+
/** The complete agent-facing coverage map: hand-written rows plus the rows
|
|
3742
|
+
* the core operation registry declares. */
|
|
2485
3743
|
declare const AGENT_EDIT_CAPABILITIES: Record<Intent["kind"], AgentEditCapability>;
|
|
2486
3744
|
type JsonSchema$1 = Record<string, unknown>;
|
|
2487
3745
|
declare function agentOperationSchema(kind: Intent["kind"]): JsonSchema$1;
|
|
@@ -2490,6 +3748,15 @@ declare function agentCapabilities(category?: AgentEditCapability["category"], r
|
|
|
2490
3748
|
kind: Intent["kind"];
|
|
2491
3749
|
inputSchema: Record<string, unknown>;
|
|
2492
3750
|
}>;
|
|
3751
|
+
/**
|
|
3752
|
+
* Collapse every repeated subschema that describes *what to write* into one
|
|
3753
|
+
* `$defs` entry and a `$ref` at each site. Shapes that describe *where to
|
|
3754
|
+
* write* (see `ADDRESSING_PROPERTIES`) and shapes that would cost more as a
|
|
3755
|
+
* reference than as themselves are left alone. The resolved schema is
|
|
3756
|
+
* identical to the input, so no caller and no model behaviour depends on which
|
|
3757
|
+
* form it gets.
|
|
3758
|
+
*/
|
|
3759
|
+
declare function hoistRepeatedSubschemas(schema: JsonSchema$1): JsonSchema$1;
|
|
2493
3760
|
|
|
2494
3761
|
type AgentReference = string;
|
|
2495
3762
|
interface AgentCursor {
|
|
@@ -2738,6 +4005,44 @@ interface AgentSpatialResult {
|
|
|
2738
4005
|
objects: AgentSpatialObject[];
|
|
2739
4006
|
overlaps: AgentOverlap[];
|
|
2740
4007
|
}
|
|
4008
|
+
/** One text-bearing drawing's frame measured against its own laid-out text. */
|
|
4009
|
+
interface AgentDrawingFit {
|
|
4010
|
+
objectRef: AgentReference;
|
|
4011
|
+
page: number;
|
|
4012
|
+
/** The frame the shape draws, px. */
|
|
4013
|
+
boxPx: {
|
|
4014
|
+
w: number;
|
|
4015
|
+
h: number;
|
|
4016
|
+
};
|
|
4017
|
+
/** The extent the text actually laid into, px. */
|
|
4018
|
+
textPx: {
|
|
4019
|
+
w: number;
|
|
4020
|
+
h: number;
|
|
4021
|
+
};
|
|
4022
|
+
/** The text is taller than the box's insets leave room for. */
|
|
4023
|
+
overflow: boolean;
|
|
4024
|
+
/** Lines the box hides because they fall past its bottom. */
|
|
4025
|
+
clippedLines: number;
|
|
4026
|
+
/** The shape's bodyPr autofit mode. Only "resizeShape" makes an overflow
|
|
4027
|
+
* resolve itself: Word paints "shrinkText" at full size and clips it. */
|
|
4028
|
+
autofit: "none" | "resizeShape" | "shrinkText";
|
|
4029
|
+
}
|
|
4030
|
+
interface AgentFitResult {
|
|
4031
|
+
revision: string;
|
|
4032
|
+
layout: {
|
|
4033
|
+
quality: "exact" | "approximate";
|
|
4034
|
+
profile: string;
|
|
4035
|
+
};
|
|
4036
|
+
totalPages: number;
|
|
4037
|
+
/** How full each requested page is: where its lowest body content ends, and
|
|
4038
|
+
* where the body box ends. */
|
|
4039
|
+
pages: Array<{
|
|
4040
|
+
page: number;
|
|
4041
|
+
contentBottomPx: number;
|
|
4042
|
+
pageBottomPx: number;
|
|
4043
|
+
}>;
|
|
4044
|
+
drawings: AgentDrawingFit[];
|
|
4045
|
+
}
|
|
2741
4046
|
type AgentInspectRequest = {
|
|
2742
4047
|
kind: "overview";
|
|
2743
4048
|
} | {
|
|
@@ -2767,8 +4072,86 @@ type AgentInspectRequest = {
|
|
|
2767
4072
|
count: number;
|
|
2768
4073
|
};
|
|
2769
4074
|
includeOverlaps?: boolean;
|
|
4075
|
+
} | {
|
|
4076
|
+
kind: "fit";
|
|
4077
|
+
pages?: {
|
|
4078
|
+
start: number;
|
|
4079
|
+
count: number;
|
|
4080
|
+
};
|
|
2770
4081
|
};
|
|
2771
|
-
type AgentInspectResult = AgentOverview | AgentContextResult | AgentReadResult | AgentSearchResult | AgentObjectResult | AgentSpatialResult;
|
|
4082
|
+
type AgentInspectResult = AgentOverview | AgentContextResult | AgentReadResult | AgentSearchResult | AgentObjectResult | AgentSpatialResult | AgentFitResult;
|
|
4083
|
+
type AgentProjectionMode = "text" | "md" | "outline";
|
|
4084
|
+
/** One run of projected characters that came from one place in the document.
|
|
4085
|
+
* `start`/`end` are columns in the projection line; `wireStart`/`wireEnd` are
|
|
4086
|
+
* offsets in the run's wire space. An editable segment is backed by a `w:t`,
|
|
4087
|
+
* so the two spaces line up one-to-one across it and a patch can address any
|
|
4088
|
+
* column inside it. Everything else is an atom the patch path treats as
|
|
4089
|
+
* opaque. */
|
|
4090
|
+
interface AgentAnchorSegment {
|
|
4091
|
+
start: number;
|
|
4092
|
+
end: number;
|
|
4093
|
+
runRef: AgentReference;
|
|
4094
|
+
wireStart: number;
|
|
4095
|
+
wireEnd: number;
|
|
4096
|
+
editable: boolean;
|
|
4097
|
+
}
|
|
4098
|
+
interface AgentAnchorLine {
|
|
4099
|
+
line: number;
|
|
4100
|
+
role: "paragraph" | "table" | "structure";
|
|
4101
|
+
blockRef?: AgentReference;
|
|
4102
|
+
/** Leading characters of the line that are markdown structure rather than
|
|
4103
|
+
* document text (`## `, `- `, `1. `). Always 0 in `text` mode. */
|
|
4104
|
+
marker: number;
|
|
4105
|
+
editable: boolean;
|
|
4106
|
+
segments: AgentAnchorSegment[];
|
|
4107
|
+
}
|
|
4108
|
+
interface AgentProjectRequest {
|
|
4109
|
+
story?: string;
|
|
4110
|
+
mode?: AgentProjectionMode;
|
|
4111
|
+
cursor?: AgentCursor;
|
|
4112
|
+
maxBlocks?: number;
|
|
4113
|
+
maxCharacters?: number;
|
|
4114
|
+
}
|
|
4115
|
+
interface AgentProjectResult {
|
|
4116
|
+
revision: string;
|
|
4117
|
+
story: string;
|
|
4118
|
+
mode: AgentProjectionMode;
|
|
4119
|
+
text: string;
|
|
4120
|
+
lines: number;
|
|
4121
|
+
window: {
|
|
4122
|
+
cursor: string | null;
|
|
4123
|
+
startBlock: number;
|
|
4124
|
+
endBlock: number;
|
|
4125
|
+
maxBlocks: number;
|
|
4126
|
+
maxCharacters: number;
|
|
4127
|
+
};
|
|
4128
|
+
anchors: AgentAnchorLine[];
|
|
4129
|
+
next?: AgentCursor;
|
|
4130
|
+
truncated: boolean;
|
|
4131
|
+
}
|
|
4132
|
+
interface AgentPatchHunk {
|
|
4133
|
+
startLine: number;
|
|
4134
|
+
endLine: number;
|
|
4135
|
+
newText: string;
|
|
4136
|
+
}
|
|
4137
|
+
interface AgentPatchRequest {
|
|
4138
|
+
revision: string;
|
|
4139
|
+
story?: string;
|
|
4140
|
+
mode?: AgentProjectionMode;
|
|
4141
|
+
cursor?: AgentCursor;
|
|
4142
|
+
maxBlocks?: number;
|
|
4143
|
+
maxCharacters?: number;
|
|
4144
|
+
edits?: AgentPatchHunk[];
|
|
4145
|
+
diff?: string;
|
|
4146
|
+
suggest?: boolean;
|
|
4147
|
+
}
|
|
4148
|
+
interface AgentPatchResult {
|
|
4149
|
+
revision: string;
|
|
4150
|
+
status: "applied" | "submitted";
|
|
4151
|
+
operations: string[];
|
|
4152
|
+
connection?: "local" | "live" | "offline" | "reconnecting";
|
|
4153
|
+
projection: AgentProjectResult;
|
|
4154
|
+
}
|
|
2772
4155
|
type AgentOperation = Record<string, unknown> & {
|
|
2773
4156
|
kind: string;
|
|
2774
4157
|
};
|
|
@@ -2838,13 +4221,14 @@ type AgentComposeBlock = {
|
|
|
2838
4221
|
} | {
|
|
2839
4222
|
type: "chart";
|
|
2840
4223
|
chart: {
|
|
2841
|
-
type: "column" | "bar" | "line" | "pie";
|
|
4224
|
+
type: "column" | "bar" | "line" | "pie" | "doughnut" | "area" | "scatter";
|
|
2842
4225
|
title?: string;
|
|
2843
4226
|
categories: string[];
|
|
2844
4227
|
series: Array<{
|
|
2845
4228
|
name: string;
|
|
2846
4229
|
values: number[];
|
|
2847
4230
|
}>;
|
|
4231
|
+
grouping?: "clustered" | "stacked" | "percentStacked";
|
|
2848
4232
|
};
|
|
2849
4233
|
widthPx?: number;
|
|
2850
4234
|
heightPx?: number;
|
|
@@ -2872,7 +4256,7 @@ type AgentComposeBlock = {
|
|
|
2872
4256
|
};
|
|
2873
4257
|
} | {
|
|
2874
4258
|
type: "shape";
|
|
2875
|
-
preset:
|
|
4259
|
+
preset: string;
|
|
2876
4260
|
text?: string;
|
|
2877
4261
|
textStyle?: AgentComposeTextStyle;
|
|
2878
4262
|
widthPx?: number;
|
|
@@ -2983,6 +4367,7 @@ declare class AgentDocument {
|
|
|
2983
4367
|
private composeAvailable;
|
|
2984
4368
|
private readonly listeners;
|
|
2985
4369
|
private readonly inspectedTargets;
|
|
4370
|
+
private readonly projections;
|
|
2986
4371
|
private constructor();
|
|
2987
4372
|
static load(bytes: ArrayBuffer | Uint8Array, options?: {
|
|
2988
4373
|
provenance?: AgentProvenance;
|
|
@@ -2998,13 +4383,50 @@ declare class AgentDocument {
|
|
|
2998
4383
|
subscribe(listener: (document: DocxDocument, revision: string) => void): () => void;
|
|
2999
4384
|
addAsset(bytes: Uint8Array, mediaType: string): string;
|
|
3000
4385
|
private inspector;
|
|
4386
|
+
/**
|
|
4387
|
+
* Read the document the way its READER reads it, whatever is on screen.
|
|
4388
|
+
*
|
|
4389
|
+
* The model these reads walk is derived per revision view, and markup view
|
|
4390
|
+
* keeps deleted runs in it so a reviewer can see the strike-through. Right
|
|
4391
|
+
* for a screen, wrong for an agent: the AI panel turns suggesting on for its
|
|
4392
|
+
* turn, which forces markup, so a SECOND suggestion projected the pending
|
|
4393
|
+
* insertion and the pending deletion interleaved — "The quick brown fox
|
|
4394
|
+
* leajumps over the lazy dog" for a document that reads "leaps". The model
|
|
4395
|
+
* then either rewrote a string no human had ever seen, or, because deleted
|
|
4396
|
+
* runs are not editable text, got "cannot be rewritten across a non-text
|
|
4397
|
+
* atom" and could not stack a second change at all.
|
|
4398
|
+
*
|
|
4399
|
+
* So every model-derived read runs in final view: insertions are text,
|
|
4400
|
+
* deletions are gone — the document as it will read once the suggestions are
|
|
4401
|
+
* accepted. Only the READS move. The operations they produce address runs by
|
|
4402
|
+
* stable id, at offsets within a run's own text; both are properties of the
|
|
4403
|
+
* XML and mean the same thing in either view, so applying them needs no
|
|
4404
|
+
* switch and the view on screen never flickers.
|
|
4405
|
+
*/
|
|
4406
|
+
private inFinalView;
|
|
3001
4407
|
asset(ref: string): AgentAsset;
|
|
3002
4408
|
inspect(request: AgentInspectRequest): AgentInspectResult;
|
|
4409
|
+
private inspectFinal;
|
|
3003
4410
|
private recordInspection;
|
|
4411
|
+
/** Fingerprints are recorded during a final-view read, so they have to be
|
|
4412
|
+
* re-taken in one: compared across views, every block holding a tracked
|
|
4413
|
+
* change reads as concurrently edited and the patch dies as "stale". */
|
|
4414
|
+
private fingerprintsMatch;
|
|
3004
4415
|
private revisionMatchesEdit;
|
|
4416
|
+
/** Render the document as deterministic text plus the anchor map that owns
|
|
4417
|
+
* the rendered-to-wire translation. Read-only: nothing here mutates. */
|
|
4418
|
+
project(request?: AgentProjectRequest): AgentProjectResult;
|
|
4419
|
+
private projectFinal;
|
|
4420
|
+
patch(request: AgentPatchRequest): Promise<AgentPatchResult>;
|
|
4421
|
+
private patchWindow;
|
|
3005
4422
|
capabilities(category?: AgentEditCapability["category"], kind?: Intent["kind"]): ReturnType<typeof agentCapabilities>;
|
|
3006
4423
|
compose(request: AgentComposeRequest): Promise<AgentComposeResult>;
|
|
4424
|
+
private composeDocument;
|
|
3007
4425
|
edit(request: AgentEditRequest): Promise<AgentEditResult>;
|
|
4426
|
+
/** The transaction itself. patch() and compose() call this rather than
|
|
4427
|
+
* edit(), so each states the rollback in its own caller's terms instead of
|
|
4428
|
+
* telling a patch author to resend "operations" it never sent. */
|
|
4429
|
+
private editTransaction;
|
|
3008
4430
|
private editLocal;
|
|
3009
4431
|
private editCollaborative;
|
|
3010
4432
|
save(): Uint8Array;
|
|
@@ -3050,8 +4472,23 @@ declare class LocalDocumentSession implements AgentCollaborativeTarget {
|
|
|
3050
4472
|
allocIds: (count: number) => number[];
|
|
3051
4473
|
subscribe(listener: () => void): () => void;
|
|
3052
4474
|
takeRenderScope: () => Scope | null;
|
|
4475
|
+
/**
|
|
4476
|
+
* Called immediately before an intent mutates the document.
|
|
4477
|
+
*
|
|
4478
|
+
* A host that also renders this document — the desktop app, whose editor owns
|
|
4479
|
+
* an undo stack — sets this to take a checkpoint, so an edit made by an agent
|
|
4480
|
+
* is reachable with Cmd+Z like any other. Without it the agent's changes are
|
|
4481
|
+
* applied behind the editor's back: undo cannot reverse them, and structural
|
|
4482
|
+
* ones have no tracked form to reject either, leaving no way back.
|
|
4483
|
+
*/
|
|
4484
|
+
onBeforeApply: (() => void) | null;
|
|
3053
4485
|
submit: (operation: IntentBody) => void;
|
|
3054
4486
|
submitOp: (operation: IntentBody) => void;
|
|
4487
|
+
/** Record a local history undo/redo that mutated the shared doc outside the
|
|
4488
|
+
* intent path (the editor already re-rendered itself). Matches the
|
|
4489
|
+
* pre-applied contract: bump the revision so agent-side caches keyed on it
|
|
4490
|
+
* (projections, inspection fingerprints) never serve the pre-undo tree. */
|
|
4491
|
+
noteHistory: () => void;
|
|
3055
4492
|
/** Record an operation that DocxView already applied to this same object. */
|
|
3056
4493
|
submitPreApplied: (operation: IntentBody) => void;
|
|
3057
4494
|
uploadMedia(bytes: Uint8Array): Promise<{
|
|
@@ -3059,6 +4496,15 @@ declare class LocalDocumentSession implements AgentCollaborativeTarget {
|
|
|
3059
4496
|
bytesLen: number;
|
|
3060
4497
|
}>;
|
|
3061
4498
|
private fullIntent;
|
|
4499
|
+
/**
|
|
4500
|
+
* Fill the part an operation just reserved with the bytes this session is
|
|
4501
|
+
* already holding.
|
|
4502
|
+
*
|
|
4503
|
+
* Keyed on the blobSha the operation carries, not on its kind: the sha IS
|
|
4504
|
+
* the media reservation, and every operation that reserves media carries
|
|
4505
|
+
* one (insertImage, insertPictureWatermark). Naming one kind here left
|
|
4506
|
+
* every later one's picture pending forever.
|
|
4507
|
+
*/
|
|
3062
4508
|
private installUploadedImage;
|
|
3063
4509
|
}
|
|
3064
4510
|
interface LocalDocumentViewBinding {
|
|
@@ -3072,6 +4518,7 @@ interface LocalDocumentViewBinding {
|
|
|
3072
4518
|
blobSha: string;
|
|
3073
4519
|
bytesLen: number;
|
|
3074
4520
|
}>;
|
|
4521
|
+
noteHistory(): void;
|
|
3075
4522
|
takeRenderScope(): {
|
|
3076
4523
|
kind: "doc";
|
|
3077
4524
|
} | {
|
|
@@ -3085,8 +4532,39 @@ interface LocalDocumentViewBinding {
|
|
|
3085
4532
|
}
|
|
3086
4533
|
declare function localDocumentViewBinding(session: LocalDocumentSession): LocalDocumentViewBinding;
|
|
3087
4534
|
|
|
4535
|
+
/** Whether `suggest: true` on this kind records a revision. A kind outside the
|
|
4536
|
+
* set applies outright, so the flag is dropped rather than promised. */
|
|
4537
|
+
declare function isSuggestable(kind: unknown): boolean;
|
|
4538
|
+
/** Whether a tableOp's `op` has a tracked form, so it may run while
|
|
4539
|
+
* suggesting. The structural ops are plain strings and never qualify. */
|
|
4540
|
+
declare function isSuggestableTableOp(op: unknown): boolean;
|
|
4541
|
+
|
|
3088
4542
|
type JsonSchema = Record<string, unknown>;
|
|
3089
4543
|
declare const AGENT_COMPOSE_SCHEMA: JsonSchema;
|
|
3090
4544
|
declare function validateAgentComposeRequest(input: unknown): string | null;
|
|
3091
4545
|
|
|
3092
|
-
|
|
4546
|
+
/**
|
|
4547
|
+
* DocMD: a deterministic text projection of a story, produced in the same pass
|
|
4548
|
+
* as the anchor map that owns the rendered-to-wire offset translation.
|
|
4549
|
+
*
|
|
4550
|
+
* Inspection offsets are rendered text and edit offsets are wire units, and
|
|
4551
|
+
* reconciling the two used to be the caller's problem. Here the two spaces are
|
|
4552
|
+
* derived together: every projected character belongs to exactly one anchor
|
|
4553
|
+
* segment, and a segment is editable only when it came verbatim from one `w:t`
|
|
4554
|
+
* — the one case where a projection column is also a wire offset. Agents read
|
|
4555
|
+
* the text; the segments do the arithmetic.
|
|
4556
|
+
*/
|
|
4557
|
+
/** Single-character stand-ins for inline content with no editable text. One
|
|
4558
|
+
* character each, so a projection column always names one whole atom and the
|
|
4559
|
+
* anchor map can mark it opaque without span arithmetic. */
|
|
4560
|
+
declare const DOCMD_ATOMS: {
|
|
4561
|
+
readonly tab: "␉";
|
|
4562
|
+
readonly lineBreak: "␊";
|
|
4563
|
+
readonly pageBreak: "␌";
|
|
4564
|
+
readonly field: "␎";
|
|
4565
|
+
readonly math: "␏";
|
|
4566
|
+
readonly noteReference: "␅";
|
|
4567
|
+
readonly object: "";
|
|
4568
|
+
};
|
|
4569
|
+
|
|
4570
|
+
export { AGENT_COMPOSE_SCHEMA, AGENT_EDIT_CAPABILITIES, type AgentAnchorLine, type AgentAnchorSegment, type AgentAsset, type AgentBlock, type AgentBorder, type AgentCollaborativeTarget, type AgentComponentSummary, type AgentComposeBlock, type AgentComposeCell, type AgentComposeRequest, type AgentComposeResult, type AgentComposeRun, type AgentComposeTextStyle, type AgentContextParagraph, type AgentContextResult, type AgentContextRun, type AgentContextStory, type AgentContextTable, type AgentCursor, AgentDocument, type AgentDrawingFit, type AgentEditCapability, type AgentEditRequest, type AgentEditResult, type AgentFitResult, type AgentInspectRequest, type AgentInspectResult, type AgentObjectResult, type AgentOperation, type AgentOverlap, type AgentOverview, type AgentPageBorders, type AgentParagraph, type AgentPatchHunk, type AgentPatchRequest, type AgentPatchResult, type AgentProjectRequest, type AgentProjectResult, type AgentProjectionMode, type AgentProvenance, type AgentReadResult, type AgentReference, type AgentRun, type AgentSearchResult, type AgentSectionLayout, type AgentSpatialObject, type AgentSpatialResult, type AgentTable, type AgentTool, DOCMD_ATOMS, LocalDocumentSession, type LocalDocumentViewBinding, type OutlineEntry, type SpatialBounds, agentCapabilities, agentOperationSchema, collaborativeAgentTarget, hoistRepeatedSubschemas, isSuggestable, isSuggestableTableOp, localDocumentViewBinding, validateAgentComposeRequest, validateAgentOperationShape };
|