@docx-editor.dev/core 2.28.0 → 2.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +65 -13
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +54 -38
- package/dist/binding.js +1 -1
- package/dist/{index-Bsg7oIKP.d.ts → chrome-print-BM3Js-6X.d.ts} +281 -222
- package/dist/{chunk-Z6WBFXJU.js → chunk-2PV5L5NJ.js} +3 -3
- package/dist/chunk-4HENIAFG.js +1 -0
- package/dist/chunk-5OTS2EJ7.js +7 -0
- package/dist/chunk-5P4223J4.cjs +27 -0
- package/dist/{chunk-O2AL2HSJ.cjs → chunk-5RRAZMBU.cjs} +1 -1
- package/dist/chunk-5SPITS5F.js +18 -0
- package/dist/{chunk-VDNNLG6X.js → chunk-7ATNKARV.js} +1 -1
- package/dist/{chunk-SRPILEWV.cjs → chunk-BGCUTKWE.cjs} +5 -5
- package/dist/chunk-EBCXSH2W.js +3 -0
- package/dist/{chunk-K5U2PLDP.cjs → chunk-ERECKTIR.cjs} +1 -1
- package/dist/{chunk-QMLCVPCD.cjs → chunk-FLBEJC6X.cjs} +1 -1
- package/dist/{chunk-6AWEKBLB.cjs → chunk-HYASLE2G.cjs} +1 -1
- package/dist/chunk-JC47NRJC.cjs +3 -0
- package/dist/{chunk-ZUHOMK52.cjs → chunk-KJRTNY2Q.cjs} +1 -1
- package/dist/chunk-NKPUH3QJ.js +1 -0
- package/dist/chunk-PF5NJWS3.js +2 -0
- package/dist/chunk-PWTRJSES.cjs +18 -0
- package/dist/chunk-QFKGI242.cjs +30 -0
- package/dist/{chunk-5CSUYANV.js → chunk-RJCQGJR7.js} +1 -1
- package/dist/chunk-RPPV4S6T.cjs +4 -0
- package/dist/{chunk-TSLBZ26X.js → chunk-T32MGBJS.js} +1 -1
- package/dist/chunk-UM26GH5B.js +30 -0
- package/dist/chunk-V3N4SOAK.cjs +1 -0
- package/dist/chunk-VRCZBFLH.js +27 -0
- package/dist/{chunk-2GO5T2JU.cjs → chunk-WF7JZ755.cjs} +1 -1
- package/dist/chunk-WK5X2MMA.cjs +7 -0
- package/dist/{chunk-E7BQA6UP.js → chunk-WPDD2Y32.js} +1 -1
- package/dist/chunk-YBMWBXST.cjs +2 -0
- package/dist/{chunk-ETTO6GK3.js → chunk-YZGUBCHP.js} +1 -1
- package/dist/chunk-ZOS2PM4A.js +4 -0
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +5 -5
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +4 -4
- package/dist/contracts/document.d.ts +3 -3
- package/dist/contracts/editor.d.ts +9 -10
- package/dist/contracts/interaction.d.ts +2 -2
- package/dist/contracts/modules.cjs +1 -1
- package/dist/contracts/modules.d.ts +33 -9
- package/dist/contracts/modules.js +1 -1
- package/dist/contracts/types.d.ts +2 -2
- package/dist/{custom-node-writes-cvL5rhcD.d.ts → custom-node-writes-0v0Kgw1T.d.ts} +2 -2
- package/dist/diagnostic-context-CcAO4q1s.d.ts +30 -0
- package/dist/diagnostic-hints-2Bke6H_w.d.ts +120 -0
- package/dist/{document-protection-BAGVGqaP.d.ts → document-protection-8eyMWIJ0.d.ts} +2 -2
- package/dist/{editor-Ci7IZGmG.d.ts → editor-DaEJd2so.d.ts} +460 -9
- package/dist/{editor-scope-OHPwVQ5l.d.ts → editor-scope-7o9xweiJ.d.ts} +1 -1
- package/dist/editor.cjs +1 -1
- package/dist/editor.d.ts +55 -33
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +17 -15
- package/dist/export.js +2 -2
- package/dist/{font-resolver-BVQB14qT.d.ts → font-resolver-CL9BVKZo.d.ts} +3 -3
- package/dist/font-shaping-policy-BvpkrfxM.d.ts +7 -0
- package/dist/{headless-document-view-qH331moE.d.ts → headless-document-view-DZQN8Bnx.d.ts} +2 -2
- package/dist/{image-resources-BN-hUgCn.d.ts → image-resources-Bipz8toD.d.ts} +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +67 -21
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-BEyuiQOk.d.ts → layout-shaping-cEnVrhWg.d.ts} +3 -2
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +42 -42
- package/dist/layout.js +1 -1
- package/dist/{note-properties-4Y9o6Gyk.d.ts → note-properties-9FH8zAeG.d.ts} +3 -3
- package/dist/{omml-equation-CuzBL5DD.d.ts → omml-equation-DP2WpUbK.d.ts} +13 -1
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +8 -9
- package/dist/output.js +1 -1
- package/dist/{protocol-Bqk4Izjc.d.ts → protocol-CZ1uUlPO.d.ts} +2 -2
- package/dist/{review-paragraph-order-DT-n6ouC.d.ts → review-paragraph-order-CqVelc5A.d.ts} +1 -1
- package/dist/{semantic-cell-selection-D9D1KSXq.d.ts → semantic-cell-selection-Dr9yxFZt.d.ts} +4 -211
- package/dist/{semantic-interaction-CIC-PooQ.d.ts → semantic-interaction-Dc3pf3hr.d.ts} +1 -1
- package/dist/{semantic-paint-BME37OMv.d.ts → semantic-paint-Bz3FBAoH.d.ts} +17 -5
- package/dist/{semantic-record-queries-CBlZqZNa.d.ts → semantic-record-queries-Bx0pl6kL.d.ts} +1 -1
- package/dist/{semantic-records-4B3WwFAi.d.ts → semantic-records-CjcF26ZL.d.ts} +892 -416
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +1463 -1574
- package/dist/store.js +1 -1
- package/dist/{tree-package-fragment-BeeKxDw8.d.ts → tree-package-store-DKhdEVym.d.ts} +238 -84
- package/dist/{tree-session-contract-CVbmlMlq.d.ts → tree-session-contract-CwnTEVLF.d.ts} +8 -6
- package/dist/{types-barrel-D3xCgQX6.d.ts → types-barrel-CA0xB8kH.d.ts} +548 -527
- package/package.json +3 -3
- package/dist/chunk-2RC2EPND.js +0 -3
- package/dist/chunk-4GBTELJV.cjs +0 -28
- package/dist/chunk-4R3TEXMN.js +0 -18
- package/dist/chunk-6APGXLBB.cjs +0 -3
- package/dist/chunk-6EYYL7FL.js +0 -1
- package/dist/chunk-EO4C5QJW.cjs +0 -2
- package/dist/chunk-FIJZIQXA.cjs +0 -18
- package/dist/chunk-FRXAOVTB.js +0 -28
- package/dist/chunk-J6BVWIDB.js +0 -2
- package/dist/chunk-JGNVNT2A.cjs +0 -2
- package/dist/chunk-KKIJG3C6.js +0 -2
- package/dist/chunk-LWDSDCMO.js +0 -27
- package/dist/chunk-NBCVVZOM.cjs +0 -1
- package/dist/chunk-O5INAWZQ.js +0 -1
- package/dist/chunk-RCHS4ZEH.cjs +0 -27
- package/dist/chunk-VHAVHCQY.js +0 -7
- package/dist/chunk-VX43VBAX.cjs +0 -7
- package/dist/review-pane-D9jm8DcY.d.ts +0 -128
- package/dist/revision-projection-DZ4kKVev.d.ts +0 -242
|
@@ -1,7 +1,244 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { N as OoxmlNode, am as OoxmlProperty, O as OoxmlPart, ah as OoxmlElement, aQ as TableBorderStyle, aR as DrawingAccessibility, aS as DrawingImageEffects, aJ as SourceCrop, aP as DrawingTransform, aT as VectorShapeProjection, X as DrawingHorizontalReferenceFrame, $ as DrawingVerticalReferenceFrame, a1 as ImageWrapTarget, al as DrawingProjection, aU as OoxmlDrawingNode } from './types-barrel-CA0xB8kH.js';
|
|
2
|
+
import { I as ImageResourceState } from './image-resources-Bipz8toD.js';
|
|
3
|
+
import { O as OmmlEquationProjection } from './omml-equation-DP2WpUbK.js';
|
|
4
|
+
|
|
5
|
+
/** Named revision colors. Identifiers are stable and never contain CSS. @public */
|
|
6
|
+
declare const REVISION_MARKUP_COLORS: readonly ['black', 'blue', 'turquoise', 'green', 'pink', 'red', 'yellow', 'white', 'darkBlue', 'teal', 'darkGreen', 'violet', 'darkRed', 'darkYellow', 'gray50', 'gray25', 'lightBlue', 'lightYellow', 'lightOrange', 'lightPurple', 'lightGreen', 'gray'];
|
|
7
|
+
/** @public */
|
|
8
|
+
type RevisionMarkupNamedColor = (typeof REVISION_MARKUP_COLORS)[number];
|
|
9
|
+
/** @public */
|
|
10
|
+
type RevisionMarkupColor = RevisionMarkupNamedColor | 'byAuthor' | 'auto';
|
|
11
|
+
/** @public */
|
|
12
|
+
type RevisionMarkupMark = 'none' | 'colorOnly' | 'bold' | 'italic' | 'underline' | 'doubleUnderline' | 'strikethrough' | 'doubleStrikethrough';
|
|
13
|
+
/** @public */
|
|
14
|
+
type RevisionDeletionMark = RevisionMarkupMark | 'hidden' | 'caret' | 'pound';
|
|
15
|
+
/** @public */
|
|
16
|
+
type RevisionChangedLinesMark = 'none' | 'leftBorder' | 'rightBorder' | 'outsideBorder';
|
|
17
|
+
/** @public */
|
|
18
|
+
interface RevisionMarkupStyle<Mark extends string = RevisionMarkupMark> {
|
|
19
|
+
readonly mark: Mark;
|
|
20
|
+
readonly color: RevisionMarkupColor;
|
|
21
|
+
}
|
|
22
|
+
/** Viewer-only text styling. Document highlighting remains unchanged. @public */
|
|
23
|
+
interface RevisionMarkupTextStyle<Mark extends string = RevisionMarkupMark> extends RevisionMarkupStyle<Mark> {
|
|
24
|
+
/** Background color behind revision text. Defaults to `none`. */
|
|
25
|
+
readonly background: RevisionMarkupNamedColor | 'byAuthor' | 'none';
|
|
26
|
+
}
|
|
27
|
+
/** Fully resolved, immutable viewer preferences. @public */
|
|
28
|
+
interface ResolvedRevisionMarkup {
|
|
29
|
+
readonly insertions: RevisionMarkupTextStyle;
|
|
30
|
+
readonly deletions: RevisionMarkupTextStyle<RevisionDeletionMark>;
|
|
31
|
+
readonly movedFrom: RevisionMarkupTextStyle<RevisionDeletionMark>;
|
|
32
|
+
readonly movedTo: RevisionMarkupTextStyle;
|
|
33
|
+
readonly formatting: RevisionMarkupTextStyle;
|
|
34
|
+
readonly changedLines: RevisionMarkupStyle<RevisionChangedLinesMark>;
|
|
35
|
+
readonly cells: {
|
|
36
|
+
readonly inserted: RevisionMarkupNamedColor | 'byAuthor' | 'none';
|
|
37
|
+
readonly deleted: RevisionMarkupNamedColor | 'byAuthor' | 'none';
|
|
38
|
+
readonly merged: RevisionMarkupNamedColor | 'byAuthor' | 'none';
|
|
39
|
+
readonly split: RevisionMarkupNamedColor | 'byAuthor' | 'none';
|
|
40
|
+
};
|
|
41
|
+
readonly trackMoves: boolean;
|
|
42
|
+
readonly trackFormatting: boolean;
|
|
43
|
+
}
|
|
44
|
+
/** Partial viewer preferences. Omitted values keep the previous value. @public */
|
|
45
|
+
type RevisionMarkupOptions = {
|
|
46
|
+
readonly [K in keyof ResolvedRevisionMarkup]?: ResolvedRevisionMarkup[K] extends boolean ? boolean : Partial<ResolvedRevisionMarkup[K]>;
|
|
47
|
+
};
|
|
48
|
+
/** Initial viewer preferences. @public */
|
|
49
|
+
declare const DEFAULT_REVISION_MARKUP: ResolvedRevisionMarkup;
|
|
50
|
+
/** Validate and merge preferences without modifying the input. @public */
|
|
51
|
+
declare function resolveRevisionMarkup(input?: RevisionMarkupOptions, previous?: ResolvedRevisionMarkup): ResolvedRevisionMarkup;
|
|
52
|
+
/** A local settings draft owned by the editor. @public */
|
|
53
|
+
interface RevisionMarkupDialogSession {
|
|
54
|
+
/** Aborts on close, replacement, load, detach, destroy, or renderer disposal. */
|
|
55
|
+
readonly signal: AbortSignal;
|
|
56
|
+
/** Read the immutable draft. */
|
|
57
|
+
get(): ResolvedRevisionMarkup;
|
|
58
|
+
/** Merge validated options into the draft without committing preferences. */
|
|
59
|
+
set(options: RevisionMarkupOptions): void;
|
|
60
|
+
/** Restore default preferences in the draft only. */
|
|
61
|
+
reset(): void;
|
|
62
|
+
/** Observe draft changes, including effective external preference changes. */
|
|
63
|
+
subscribe(listener: () => void): () => void;
|
|
64
|
+
canApply(): boolean;
|
|
65
|
+
/** Commit the draft and close. Returns false after cancellation. */
|
|
66
|
+
apply(): boolean;
|
|
67
|
+
/** Close without committing the draft. */
|
|
68
|
+
cancel(): void;
|
|
69
|
+
}
|
|
70
|
+
/** Host rendering for the Track changes options dialog. @public */
|
|
71
|
+
interface RevisionMarkupChromeHandlers {
|
|
72
|
+
readonly onRequest?: (session: RevisionMarkupDialogSession) => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* What a revision wrapper asserts about the content inside it.
|
|
77
|
+
*
|
|
78
|
+
* `moveFrom` / `moveTo` are deliberately distinct from `delete` / `insert`: a move is one
|
|
79
|
+
* decision with two halves, and presenting it as an unrelated deletion and insertion invites
|
|
80
|
+
* resolving one without the other, which duplicates or loses the content.
|
|
81
|
+
*/
|
|
82
|
+
type RevisionKind = 'insert' | 'delete' | 'moveFrom' | 'moveTo' | 'format';
|
|
83
|
+
/**
|
|
84
|
+
* One revision wrapper's provenance, as authored.
|
|
85
|
+
*
|
|
86
|
+
* `id` is the verbatim `@w:id` string rather than a number: `ST_DecimalNumber` restricts
|
|
87
|
+
* `xsd:integer` with no bounds, so a file may carry a value outside the safe integer range, and
|
|
88
|
+
* parsing it to a number would silently merge two distinct revisions.
|
|
89
|
+
*
|
|
90
|
+
* `date` is absent when the file omits it. `@w:date` is optional on `CT_TrackChange`, and
|
|
91
|
+
* inventing one is a silent content change.
|
|
92
|
+
*/
|
|
93
|
+
interface RevisionAttribution {
|
|
94
|
+
readonly kind: RevisionKind;
|
|
95
|
+
readonly id: string;
|
|
96
|
+
readonly author: string;
|
|
97
|
+
readonly date?: string;
|
|
98
|
+
/** The wrapper's node id, so a surface can address this exact site. */
|
|
99
|
+
readonly nodeId: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Which revisions layout resolves before producing pages.
|
|
103
|
+
*
|
|
104
|
+
* - `all-markup` shows both halves of every change.
|
|
105
|
+
* - `proposed` shows what the document becomes if every change is accepted.
|
|
106
|
+
* - `original` shows what it was before any of them.
|
|
107
|
+
*
|
|
108
|
+
* The last two are specified as equal to accept-all and reject-all OUTPUT, which is what makes
|
|
109
|
+
* them testable, without either applying an op.
|
|
110
|
+
*/
|
|
111
|
+
type RevisionDisplayMode = 'all-markup' | 'proposed' | 'original';
|
|
112
|
+
/**
|
|
113
|
+
* The views the review chrome offers, in Word's terms: the three layout projections plus
|
|
114
|
+
* Simple Markup, which reads as the proposed result with a red change bar beside every line
|
|
115
|
+
* a change touched — the document as accepting everything would leave it, and where.
|
|
116
|
+
*/
|
|
117
|
+
type ReviewDisplayMode = RevisionDisplayMode | 'simple-markup';
|
|
118
|
+
/**
|
|
119
|
+
* How a document renders tracked changes when nothing says otherwise.
|
|
120
|
+
*
|
|
121
|
+
* `all-markup` matches Word's own default: a reader who opens a document with pending changes
|
|
122
|
+
* sees them, rather than a clean-looking document hiding edits nobody has accepted.
|
|
123
|
+
*/
|
|
124
|
+
declare const DEFAULT_REVISION_DISPLAY_MODE: RevisionDisplayMode;
|
|
125
|
+
/**
|
|
126
|
+
* A view-time tracked-change filter. Revisions rejected by `includes` use the filter's accepted
|
|
127
|
+
* or rejected projection, while included revisions keep the display mode's normal projection.
|
|
128
|
+
*
|
|
129
|
+
* `cacheKey` is a canonical, content-based identity for layout caches. The set itself is kept
|
|
130
|
+
* because author names are attacker-controlled strings and must never be parsed back from a
|
|
131
|
+
* delimiter-based key.
|
|
132
|
+
*/
|
|
133
|
+
interface RevisionFilter {
|
|
134
|
+
readonly revisionMarkup?: ResolvedRevisionMarkup;
|
|
135
|
+
readonly hiddenAuthors: ReadonlySet<string>;
|
|
136
|
+
readonly includes?: (revision: RevisionAttribution) => boolean;
|
|
137
|
+
readonly includesNode?: (nodeId: string, author: string) => boolean;
|
|
138
|
+
/** Accepted/original projection for a revision excluded by `includesNode`. */
|
|
139
|
+
readonly excludedNodeMode?: (nodeId: string, author: string) => 'proposed' | 'original';
|
|
140
|
+
/**
|
|
141
|
+
* In a resolved view, content the view keeps paints as ORDINARY text: no author ink, no
|
|
142
|
+
* decoration, no change bar of its own. This is Word's No Markup, Original and Simple
|
|
143
|
+
* Markup, which the review chrome asks for. Without it the accepted projection keeps the
|
|
144
|
+
* attribution on kept insertions, which is what the engine paints when no review module
|
|
145
|
+
* is registered — colour by author, deletions resolved — and what its roster reads.
|
|
146
|
+
*/
|
|
147
|
+
readonly resolvedMarkup?: 'plain';
|
|
148
|
+
readonly cacheKey: string;
|
|
149
|
+
}
|
|
150
|
+
/** @deprecated Use {@link RevisionFilter}. */
|
|
151
|
+
interface RevisionAuthorFilter extends RevisionFilter {
|
|
152
|
+
}
|
|
153
|
+
/** Build a canonical reviewer filter. An empty input returns `undefined` for the fast path. */
|
|
154
|
+
declare function revisionAuthorFilter(hiddenAuthors: Iterable<string>): RevisionAuthorFilter | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* Whether content under this stack of revisions is laid out in the given mode.
|
|
157
|
+
*
|
|
158
|
+
* Containment governs, so a single enclosing wrapper the mode resolves away suppresses
|
|
159
|
+
* everything inside it regardless of what the inner wrappers say. An insertion inside a
|
|
160
|
+
* deletion does not survive the proposed result: the deletion it sits in was accepted.
|
|
161
|
+
*/
|
|
162
|
+
declare function revisionsVisible(revisions: readonly RevisionAttribution[], mode: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Every revision on a paragraph's own MARK, from `w:pPr/w:rPr/w:ins|w:del|w:moveFrom|w:moveTo`.
|
|
165
|
+
*
|
|
166
|
+
* All four members of `EG_ParaRPrTrackChanges`. A moved paragraph carries `w:moveFrom` on the
|
|
167
|
+
* mark of the copy it left and `w:moveTo` on the mark of the copy it arrived at, so a move
|
|
168
|
+
* that spans whole paragraphs is recorded here and nowhere else.
|
|
169
|
+
*
|
|
170
|
+
* `EG_ParaRPrTrackChanges` records that the pilcrow itself was inserted or deleted, which is how
|
|
171
|
+
* Word writes a paragraph split or merge. It is not content — there is no text to decorate — so
|
|
172
|
+
* a surface shows it as a mark of its own beside the paragraph, the way Word draws a struck-
|
|
173
|
+
* through ¶.
|
|
174
|
+
*
|
|
175
|
+
* A LIST, because the group is `ins? del? moveFrom? moveTo?` and the first two can both be
|
|
176
|
+
* there: that pair is what Word writes when a second author proposes removing a mark the first
|
|
177
|
+
* proposed adding, and it is what this engine's own writer emits (`tree-op-tracked.ts`).
|
|
178
|
+
* Answering with the first one hid the second author's decision from the PAGE. The review pane
|
|
179
|
+
* walks the tree itself and always listed both, which is the worse shape of the two: a card
|
|
180
|
+
* offering a decision the reader could see no sign of.
|
|
181
|
+
*
|
|
182
|
+
* Ordered as the file orders them, which is the order the group declares.
|
|
183
|
+
*
|
|
184
|
+
* Property-position `w:ins`/`w:del` stay `generic` in the tree deliberately, so this reads them
|
|
185
|
+
* by name rather than by kind.
|
|
186
|
+
*/
|
|
187
|
+
declare function paragraphMarkRevisionsOf(paragraph: OoxmlNode): readonly RevisionAttribution[];
|
|
188
|
+
/**
|
|
189
|
+
* The tracked FORMAT change on a paragraph's own mark, from `w:pPr/w:rPr/w:rPrChange`.
|
|
190
|
+
*
|
|
191
|
+
* `CT_ParaRPr` ends with it (§17.13.5.32), and Word writes it when a user changes the mark's
|
|
192
|
+
* own run properties with tracking on. It reaches the fragment rather than a span because it
|
|
193
|
+
* decorates no characters, and it is not in `props`: a fragment's `props` carry the mark's
|
|
194
|
+
* `w:rPr` by NAME only, with none of its children.
|
|
195
|
+
*
|
|
196
|
+
* Note that `w:rPrChange/w:rPr` is `CT_ParaRPrOriginal`, which may carry its own revision
|
|
197
|
+
* marks. Those describe the mark as it WAS and must not be read as live ones, which is why
|
|
198
|
+
* this reads the change element's own attributes and never descends into it.
|
|
199
|
+
*/
|
|
200
|
+
declare function paragraphMarkFormatRevisionOf(paragraph: OoxmlNode): RevisionAttribution | null;
|
|
201
|
+
/**
|
|
202
|
+
* The single decision a one-field reader sees.
|
|
203
|
+
*
|
|
204
|
+
* A DELETION wins when a mark carries both, for the reason paint draws it that way: a break
|
|
205
|
+
* proposed and then unproposed ends up removed, so that is the decision a reader who can only
|
|
206
|
+
* see one must see. One function decides it, so the deprecated field, the deprecated function
|
|
207
|
+
* and the painted glyph cannot answer differently.
|
|
208
|
+
*/
|
|
209
|
+
declare function shownMarkRevision(revisions: readonly RevisionAttribution[]): RevisionAttribution | undefined;
|
|
210
|
+
/**
|
|
211
|
+
* Does this decision, taken, remove the paragraph mark?
|
|
212
|
+
*
|
|
213
|
+
* A deletion does, and so does a `moveFrom`: the copy the paragraph moved OUT of goes away
|
|
214
|
+
* when the move is accepted. `insert` and `moveTo` are the other half of each pair, and they
|
|
215
|
+
* keep the break. Paint, the change bar and the resolved views all ask this one question, so
|
|
216
|
+
* a `moveFrom` cannot end up struck through in the margin and blue on the glyph.
|
|
217
|
+
*/
|
|
218
|
+
declare function markRevisionRemovesMark(revision: RevisionAttribution): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* The one decision on a paragraph's mark that a single-field reader sees.
|
|
221
|
+
*
|
|
222
|
+
* @deprecated Reads one of the revisions a mark can carry. Use {@link paragraphMarkRevisionsOf},
|
|
223
|
+
* which answers with all of them.
|
|
224
|
+
*/
|
|
225
|
+
declare function paragraphMarkRevisionOf(paragraph: OoxmlNode): RevisionAttribution | null;
|
|
226
|
+
/**
|
|
227
|
+
* The tracked FORMAT change on a property list, from `w:rPrChange` or `w:pPrChange`.
|
|
228
|
+
*
|
|
229
|
+
* A property change alters no characters, so it has no span of its own to strike or underline.
|
|
230
|
+
* Word marks the affected text and says what changed; the minimum a reader needs is to see that
|
|
231
|
+
* this text's formatting is itself a pending decision.
|
|
232
|
+
*
|
|
233
|
+
* Read from the flattened property list because that is what layout already carries — the
|
|
234
|
+
* change wrapper is a `w:rPr`/`w:pPr` child like any other.
|
|
235
|
+
*/
|
|
236
|
+
declare function formatRevisionOf(properties: readonly {
|
|
237
|
+
readonly localName: string;
|
|
238
|
+
readonly attributes?: Readonly<Record<string, string>>;
|
|
239
|
+
}[]): RevisionAttribution | null;
|
|
240
|
+
/** True when this stack of revisions marks its content as deleted from the live document. */
|
|
241
|
+
declare function revisionsAreDeletion(revisions: readonly RevisionAttribution[]): boolean;
|
|
5
242
|
|
|
6
243
|
/** A strikeout stroke at the drawn size, in points. `offsetPt` is the stroke TOP. @public */
|
|
7
244
|
interface StrikeoutStrokePt {
|
|
@@ -11,6 +248,518 @@ interface StrikeoutStrokePt {
|
|
|
11
248
|
readonly thicknessPt: number;
|
|
12
249
|
}
|
|
13
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Whether a paragraph must start a new page (`w:pageBreakBefore`).
|
|
253
|
+
*
|
|
254
|
+
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
255
|
+
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
256
|
+
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
257
|
+
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
258
|
+
* page number after it was wrong.
|
|
259
|
+
*
|
|
260
|
+
* An absent `w:val` is on (§17.17.4), and the off vocabulary is the whole of it — `off` is a
|
|
261
|
+
* spelling too, which {@link isOn} beside this already accepts.
|
|
262
|
+
*/
|
|
263
|
+
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
266
|
+
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
267
|
+
*/
|
|
268
|
+
declare const MAX_PARAGRAPH_SPACING_PT: number;
|
|
269
|
+
/** Soft ceiling on border width (96 eighths = 12pt). Word's UI tops out well below this. */
|
|
270
|
+
declare const MAX_BORDER_WIDTH_PT = 12;
|
|
271
|
+
/** Soft ceiling on border-to-text gap (`w:space`, already in points). */
|
|
272
|
+
declare const MAX_BORDER_SPACE_PT = 3168;
|
|
273
|
+
/**
|
|
274
|
+
* A paragraph's resolved space before and after, in points.
|
|
275
|
+
*
|
|
276
|
+
* Already collapsed against `w:contextualSpacing`, so adjacent same-style paragraphs that suppress
|
|
277
|
+
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
278
|
+
*/
|
|
279
|
+
interface ParagraphSpacing {
|
|
280
|
+
/** `w:spacing/@before`, in points. */
|
|
281
|
+
readonly before: number;
|
|
282
|
+
/** `w:spacing/@after`, in points. */
|
|
283
|
+
readonly after: number;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The gap Word substitutes when `w:beforeAutospacing` / `w:afterAutospacing` is on
|
|
287
|
+
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
288
|
+
*
|
|
289
|
+
* The attribute means "the consumer decides", and the authored `@before` / `@after` beside it
|
|
290
|
+
* is IGNORED rather than used as the value. Word's answer is HTML's default `<p>` margin,
|
|
291
|
+
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
292
|
+
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
293
|
+
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
294
|
+
*/
|
|
295
|
+
declare const AUTO_PARAGRAPH_SPACING_PT = 14;
|
|
296
|
+
/**
|
|
297
|
+
* Where a paragraph sits, for the contexts in which Word's auto spacing resolves to 0
|
|
298
|
+
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
299
|
+
*
|
|
300
|
+
* This resolves the interior list-item value. Body layout restores each outer list margin
|
|
301
|
+
* in `resolveListAutoSpacing`, where neighboring blocks are available. A caller that says
|
|
302
|
+
* nothing gets the body answer.
|
|
303
|
+
*
|
|
304
|
+
* A TABLE CELL is not such a context. Measured on a captured control at 10pt, where the
|
|
305
|
+
* line pitch is 11.52pt: the reference puts 26.16pt between two paragraphs in the body with
|
|
306
|
+
* auto spacing on, and the SAME 26.16pt between two paragraphs inside a cell. With an empty
|
|
307
|
+
* paragraph between them it is 52.32, exactly twice. Reading it as 0 in a cell lays every
|
|
308
|
+
* such paragraph 13.92pt tight, which is enough to pull a signature block back onto the
|
|
309
|
+
* previous page. See `.cache/pdf/claude-autospacing/`.
|
|
310
|
+
*/
|
|
311
|
+
interface ParagraphAutoSpacingContext {
|
|
312
|
+
/** The paragraph participates in numbering (`w:numPr`), i.e. it is a list item. */
|
|
313
|
+
readonly inList?: boolean;
|
|
314
|
+
/**
|
|
315
|
+
* The paragraph lives in a table cell. Kept because callers describe position with it and
|
|
316
|
+
* list resolution reads it; it does NOT zero auto spacing.
|
|
317
|
+
*/
|
|
318
|
+
readonly inTableCell?: boolean;
|
|
319
|
+
/** Section grid pitch in points; no grid uses Word's fixed 12pt line unit. */
|
|
320
|
+
readonly lineUnitPt?: number;
|
|
321
|
+
/**
|
|
322
|
+
* `w:doNotUseHTMLParagraphAutoSpacing` is on: automatic spacing outside a list resolves to
|
|
323
|
+
* the fixed 5pt before and 10pt after instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
324
|
+
*/
|
|
325
|
+
readonly fixedAutoSpacing?: boolean;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Resolved line spacing (`w:spacing/@line` + `@lineRule`, ECMA-376 17.3.1.33).
|
|
329
|
+
*
|
|
330
|
+
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
331
|
+
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
332
|
+
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
333
|
+
* moves every page break, so this is not a cosmetic detail.
|
|
334
|
+
*
|
|
335
|
+
* `exact` fixes the line box at `@line` twips and lets tall glyphs clip, the way Word
|
|
336
|
+
* does. `atLeast` uses it as a floor.
|
|
337
|
+
*/
|
|
338
|
+
type LineSpacingRule = 'auto' | 'exact' | 'atLeast';
|
|
339
|
+
/**
|
|
340
|
+
* Resolved line spacing: the rule, and the value it applies.
|
|
341
|
+
*
|
|
342
|
+
* `value` means different things per rule — 240ths of a line under `auto`, points under `exact`
|
|
343
|
+
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
344
|
+
*/
|
|
345
|
+
interface ParagraphLineSpacing {
|
|
346
|
+
readonly rule: LineSpacingRule;
|
|
347
|
+
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
348
|
+
readonly value: number;
|
|
349
|
+
/** Legacy noExtraLineSpacing: retain the natural baseline within an exact-height box. */
|
|
350
|
+
readonly preserveExactBaseline?: true;
|
|
351
|
+
/**
|
|
352
|
+
* Active section line-grid pitch in points (`w:docGrid/@w:linePitch`). Present only when
|
|
353
|
+
* the paragraph snaps to the grid; only with `auto`. See `line-grid.ts`.
|
|
354
|
+
*/
|
|
355
|
+
readonly gridPitch?: number;
|
|
356
|
+
}
|
|
357
|
+
/** Single spacing: what a paragraph that says nothing gets. */
|
|
358
|
+
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
359
|
+
/**
|
|
360
|
+
* One resolved `w:pBdr` edge: its style, colour, thickness and gap.
|
|
361
|
+
*
|
|
362
|
+
* `widthPt` and `spacePt` are already converted and CLAMPED — both come from a file, and an
|
|
363
|
+
* unbounded border width becomes a layout dimension.
|
|
364
|
+
*/
|
|
365
|
+
interface ParagraphBorderEdge {
|
|
366
|
+
/** Authored `ST_Border` value (`single`, `dashed`, …). */
|
|
367
|
+
readonly val: string;
|
|
368
|
+
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
369
|
+
readonly color: string | null;
|
|
370
|
+
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
371
|
+
readonly widthPt: number;
|
|
372
|
+
/** Gap from text to the rule, in points (`w:space`). */
|
|
373
|
+
readonly spacePt: number;
|
|
374
|
+
/**
|
|
375
|
+
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
376
|
+
*
|
|
377
|
+
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
378
|
+
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
379
|
+
*/
|
|
380
|
+
readonly shadow?: true;
|
|
381
|
+
}
|
|
382
|
+
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
383
|
+
declare const PARAGRAPH_BORDER_SIDES: readonly ['top', 'left', 'bottom', 'right', 'between', 'bar'];
|
|
384
|
+
/**
|
|
385
|
+
* Which of the six `CT_PBdr` edges.
|
|
386
|
+
*
|
|
387
|
+
* Four are physical box edges; `between` and `bar` are group-relative, drawn only where
|
|
388
|
+
* consecutive paragraphs share a border definition.
|
|
389
|
+
*/
|
|
390
|
+
type ParagraphBorderSide = (typeof PARAGRAPH_BORDER_SIDES)[number];
|
|
391
|
+
/**
|
|
392
|
+
* A paragraph's resolved `w:pBdr` (ECMA-376 §17.3.1.24).
|
|
393
|
+
*
|
|
394
|
+
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
395
|
+
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
396
|
+
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
397
|
+
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
398
|
+
*/
|
|
399
|
+
interface ParagraphBorders {
|
|
400
|
+
readonly top?: ParagraphBorderEdge;
|
|
401
|
+
readonly left?: ParagraphBorderEdge;
|
|
402
|
+
readonly bottom?: ParagraphBorderEdge;
|
|
403
|
+
readonly right?: ParagraphBorderEdge;
|
|
404
|
+
readonly between?: ParagraphBorderEdge;
|
|
405
|
+
readonly bar?: ParagraphBorderEdge;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Resolve `w:spacing` before/after from flat paragraph properties.
|
|
409
|
+
*
|
|
410
|
+
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
411
|
+
* height, not the gap between paragraphs — and is not resolved here.
|
|
412
|
+
*
|
|
413
|
+
* `w:beforeAutospacing` / `w:afterAutospacing` REPLACE the authored measurement on their own
|
|
414
|
+
* side rather than adding to it; see {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
415
|
+
*/
|
|
416
|
+
declare function paragraphSpacing(props: readonly OoxmlProperty[], context?: ParagraphAutoSpacingContext): ParagraphSpacing;
|
|
417
|
+
/**
|
|
418
|
+
* Resolve `w:line` / `w:lineRule` from flat paragraph properties.
|
|
419
|
+
*
|
|
420
|
+
* Merged per attribute for the same reason as before/after: `w:spacing` is one element
|
|
421
|
+
* carrying independent attributes, and a style that states only `@line` must not reset the
|
|
422
|
+
* rule an earlier entry in the cascade set.
|
|
423
|
+
*/
|
|
424
|
+
declare function paragraphLineSpacing(props: readonly OoxmlProperty[]): ParagraphLineSpacing;
|
|
425
|
+
/**
|
|
426
|
+
* Apply resolved line spacing to a line's natural (glyph-derived) box.
|
|
427
|
+
*
|
|
428
|
+
* `auto` places its extra BELOW the line — the last line's multiple spacing still separates
|
|
429
|
+
* it from the next paragraph. Putting that delta above inverted cover-page rhythm:
|
|
430
|
+
* `w:line="460"` on "between" opened a large gap above the word and almost none before
|
|
431
|
+
* "MERIDIAN".
|
|
432
|
+
*
|
|
433
|
+
* `atLeast` does the OPPOSITE: the box grows upward and the glyphs sit on its floor. A
|
|
434
|
+
* captured control settles it — Times New Roman 12 pt at `w:line="360" w:lineRule="atLeast"`
|
|
435
|
+
* puts the reference's baseline at 15.36 pt, which is `18 - descent` snapped to the device
|
|
436
|
+
* grid, where treating it like `auto` leaves the baseline at 11.28 and the text 4.08 pt too
|
|
437
|
+
* high. `w:line="240" atLeast` is below the natural line, falls through to the natural
|
|
438
|
+
* height, and is unaffected. See `.cache/pdf/claude-linerule/`.
|
|
439
|
+
*
|
|
440
|
+
* Exact-height boxes place their baseline at 80% of the height; the legacy
|
|
441
|
+
* noExtraLineSpacing switch instead preserves the face baseline within the box.
|
|
442
|
+
*
|
|
443
|
+
* An `auto` or `atLeast` line of a snapping paragraph under an active line grid takes whole
|
|
444
|
+
* pitches instead ({@link gridLineBox}); `trailing` then names the box below the glyphs.
|
|
445
|
+
*/
|
|
446
|
+
declare function applyLineSpacing(spacing: ParagraphLineSpacing, naturalHeight: number, naturalBaseline: number): {
|
|
447
|
+
height: number;
|
|
448
|
+
baseline: number;
|
|
449
|
+
trailing?: number;
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* `w:contextualSpacing` (17.3.1.9): drop before/after between paragraphs of the SAME
|
|
453
|
+
* style. Word's built-in `ListParagraph` sets it, so every list authored in Word gets a
|
|
454
|
+
* paragraph gap between items without this.
|
|
455
|
+
*/
|
|
456
|
+
declare function paragraphContextualSpacing(props: readonly OoxmlProperty[]): boolean;
|
|
457
|
+
/**
|
|
458
|
+
* Resolve `w:pBdr` from the paragraph-properties node.
|
|
459
|
+
*
|
|
460
|
+
* Nested — every edge is a child of `pBdr`, not an attribute — so this reads the typed tree
|
|
461
|
+
* rather than the flattened `OoxmlProperty[]` bag `propertiesOf` builds for leaf props.
|
|
462
|
+
*/
|
|
463
|
+
declare function paragraphBorders(pPr: OoxmlNode | undefined): ParagraphBorders;
|
|
464
|
+
/**
|
|
465
|
+
* `w:pBdr` after the style cascade: a later `w:pBdr` replaces an earlier one WHOLESALE.
|
|
466
|
+
*
|
|
467
|
+
* Word does not merge edges across the cascade. A style that states only `w:bottom` discards
|
|
468
|
+
* the box its `basedOn` ancestor declared, so folding edge by edge would leave a lone
|
|
469
|
+
* underline surrounded by a box no one authored. Absence inherits; `nil`/`none` clear.
|
|
470
|
+
*/
|
|
471
|
+
declare function cascadedParagraphBorders(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorders;
|
|
472
|
+
/**
|
|
473
|
+
* Visual stroke thickness layout publishes for one edge (points).
|
|
474
|
+
*
|
|
475
|
+
* Compound `ST_Border` values (`double`, …) use the shared inflated band so a thin
|
|
476
|
+
* `w:sz="3"` double still occupies a visible double-line box — matching table borders.
|
|
477
|
+
*/
|
|
478
|
+
declare function paragraphBorderStrokeWidthPt(edge: ParagraphBorderEdge): number;
|
|
479
|
+
/**
|
|
480
|
+
* Extent one border edge occupies away from the text it decorates: gap plus rule, in points.
|
|
481
|
+
*
|
|
482
|
+
* Vertically that is flow height — a top rule pushes the first line down, a bottom rule holds
|
|
483
|
+
* the page open below the last one — so pagination has to see it. Horizontally it is
|
|
484
|
+
* publish-only: Word draws left/right paragraph rules OUTSIDE the text column and never
|
|
485
|
+
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
486
|
+
*/
|
|
487
|
+
declare function paragraphBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
488
|
+
/** Vertical extent a bottom border adds below the last line (gap + rule). */
|
|
489
|
+
declare function bottomBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
490
|
+
/**
|
|
491
|
+
* Identity of a paragraph's border set, for the `w:between` group rule.
|
|
492
|
+
*
|
|
493
|
+
* Word treats consecutive paragraphs whose border settings are IDENTICAL as ONE bordered
|
|
494
|
+
* block: the top rule draws above the first, the bottom rule below the last, and each
|
|
495
|
+
* interior boundary gets `w:between` or nothing (§17.3.1.24). That is why applying a box to
|
|
496
|
+
* three selected paragraphs in Word draws one box and not three.
|
|
497
|
+
*
|
|
498
|
+
* Empty string means "no borders", which never groups with anything.
|
|
499
|
+
*/
|
|
500
|
+
declare function paragraphBordersFingerprint(borders: ParagraphBorders): string;
|
|
501
|
+
/**
|
|
502
|
+
* Gap to insert before a paragraph once the previous paragraph's `after` is already in the
|
|
503
|
+
* flow cursor — Word takes the larger of the two rather than summing them.
|
|
504
|
+
*/
|
|
505
|
+
declare function collapsedSpaceBefore(before: number, previousAfter: number): number;
|
|
506
|
+
/**
|
|
507
|
+
* Applied before-spacing for placement (Word 2013+ / compat mode 15).
|
|
508
|
+
*
|
|
509
|
+
* Adjacent before/after still collapse to the larger gap, but before is dropped entirely when
|
|
510
|
+
* the paragraph naturally moves to the top of a page mid-section. An explicit page-break-before
|
|
511
|
+
* paragraph, or the first paragraph of a document/section, retains before. Callers publish this
|
|
512
|
+
* applied value on the fragment so shading, borders,
|
|
513
|
+
* selection, and paint share one geometry.
|
|
514
|
+
*/
|
|
515
|
+
declare function appliedSpaceBefore(before: number, previousAfter: number, atTopOfPage: boolean, preserveAtPageStart: boolean): number;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* The four physical sides of `CT_PageBorders`.
|
|
519
|
+
*
|
|
520
|
+
* Four, not the six of `w:pBdr`: `w:between` and `w:bar` are paragraph-group rules and the
|
|
521
|
+
* page has no analogue for either.
|
|
522
|
+
*/
|
|
523
|
+
declare const PAGE_BORDER_SIDES: readonly ['top', 'left', 'bottom', 'right'];
|
|
524
|
+
/** Which of the four page-frame edges. */
|
|
525
|
+
type PageBorderSide = (typeof PAGE_BORDER_SIDES)[number];
|
|
526
|
+
/**
|
|
527
|
+
* `w:offsetFrom` (`ST_PgBorderOffset`) — what `w:space` on each edge is measured from.
|
|
528
|
+
*
|
|
529
|
+
* The schema default is `text`, NOT `page`. Word's own UI opens on "Edge of page", which is
|
|
530
|
+
* why the wrong default is easy to assume and expensive to hold: at `text` the rule sits
|
|
531
|
+
* `w:space` points outside the TEXT, so its distance from the sheet edge is the margin minus
|
|
532
|
+
* the space — a number that moves whenever the margins do.
|
|
533
|
+
*/
|
|
534
|
+
type PageBorderOffsetFrom = 'page' | 'text';
|
|
535
|
+
/** `w:display` (`ST_PgBorderDisplay`) — which pages of the section carry the frame. */
|
|
536
|
+
type PageBorderDisplay = 'allPages' | 'firstPage' | 'notFirstPage';
|
|
537
|
+
/** `w:zOrder` (`ST_PgBorderZOrder`) — whether the frame paints over the text or under it. */
|
|
538
|
+
type PageBorderZOrder = 'front' | 'back';
|
|
539
|
+
/**
|
|
540
|
+
* One section's resolved `w:pgBorders`.
|
|
541
|
+
*
|
|
542
|
+
* Resolved, not raw: every attribute the file omitted is filled in with the SCHEMA default,
|
|
543
|
+
* so a consumer never has to know which of the three were authored. An edge is present only
|
|
544
|
+
* when it paints — `nil` / `none` and art borders are already gone (see {@link parsePageBorders}).
|
|
545
|
+
*/
|
|
546
|
+
interface SectionPageBorders {
|
|
547
|
+
/** `w:offsetFrom`; absent attribute reads as `text` (§17.6.10). */
|
|
548
|
+
readonly offsetFrom: PageBorderOffsetFrom;
|
|
549
|
+
/** `w:display`; absent attribute reads as `allPages`. */
|
|
550
|
+
readonly display: PageBorderDisplay;
|
|
551
|
+
/** `w:zOrder`; absent attribute reads as `front`. */
|
|
552
|
+
readonly zOrder: PageBorderZOrder;
|
|
553
|
+
readonly top?: ParagraphBorderEdge;
|
|
554
|
+
readonly left?: ParagraphBorderEdge;
|
|
555
|
+
readonly bottom?: ParagraphBorderEdge;
|
|
556
|
+
readonly right?: ParagraphBorderEdge;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Parse `w:pgBorders` off one `w:sectPr`.
|
|
560
|
+
*
|
|
561
|
+
* Undefined when the element is absent AND when it paints nothing — every edge off, or every
|
|
562
|
+
* edge an art border. Unlike `w:pgNumType`, an empty-but-present element is not distinguished:
|
|
563
|
+
* these properties are a LAYOUT input, serialization re-emits the canonical tree, and a frame
|
|
564
|
+
* with no edges has exactly one meaning downstream.
|
|
565
|
+
*/
|
|
566
|
+
declare function parsePageBorders(sectPr: OoxmlNode): SectionPageBorders | undefined;
|
|
567
|
+
/**
|
|
568
|
+
* Identity of one section's page frame, for incremental-layout context keys.
|
|
569
|
+
*
|
|
570
|
+
* A `w:pgBorders` edit changes nothing the flow measures — the frame is drawn beside the text,
|
|
571
|
+
* never through it — so no per-paragraph key moves and every reuse path would hand back the
|
|
572
|
+
* previous sheets with the previous frame. This token goes in the pass context so it does not.
|
|
573
|
+
*/
|
|
574
|
+
declare function pageBordersFingerprint(borders: SectionPageBorders | undefined): string;
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Hard ceiling on sections enumerated from a document (matches write-path
|
|
578
|
+
* `MAX_SECTIONS` in note/hf lifecycle). Hostile packages with unbounded `w:sectPr`
|
|
579
|
+
* marks fail closed here rather than amplifying layout props arrays.
|
|
580
|
+
*/
|
|
581
|
+
declare const MAX_DOCUMENT_SECTIONS = 4096;
|
|
582
|
+
/** A section's margins in twips, including the header and footer reserve bands. */
|
|
583
|
+
interface SectionMargins {
|
|
584
|
+
readonly topTwips: number;
|
|
585
|
+
readonly rightTwips: number;
|
|
586
|
+
readonly bottomTwips: number;
|
|
587
|
+
readonly leftTwips: number;
|
|
588
|
+
readonly headerTwips: number;
|
|
589
|
+
readonly footerTwips: number;
|
|
590
|
+
readonly gutterTwips: number;
|
|
591
|
+
}
|
|
592
|
+
/** One explicit `w:col`: its width and the gap after it. */
|
|
593
|
+
interface SectionColumnDefinition {
|
|
594
|
+
readonly widthTwips: number;
|
|
595
|
+
/** Space after this column; zero on the final column. */
|
|
596
|
+
readonly gapTwips: number;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* A section's column layout.
|
|
600
|
+
*
|
|
601
|
+
* Equal-width and explicit-width columns are one type because a file may declare `w:num` with no
|
|
602
|
+
* `w:col` children at all, and layout must handle both without branching at every use site.
|
|
603
|
+
*/
|
|
604
|
+
interface SectionColumns {
|
|
605
|
+
readonly count: number;
|
|
606
|
+
/** Shared gap for equal-width columns and fallback gap for incomplete explicit definitions. */
|
|
607
|
+
readonly gapTwips: number;
|
|
608
|
+
readonly equalWidth?: boolean;
|
|
609
|
+
readonly separator?: boolean;
|
|
610
|
+
/** Authored `w:col` geometry when `equalWidth` is false. */
|
|
611
|
+
readonly definitions?: readonly SectionColumnDefinition[];
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* How this section is placed relative to the previous one (ECMA-376 17.6.22,
|
|
615
|
+
* `ST_SectionMark`).
|
|
616
|
+
*
|
|
617
|
+
* All five schema values are read. `nextColumn` paginates like `nextPage` for now: in a
|
|
618
|
+
* single-column section that IS Word's behaviour, and multi-column flow is not modelled,
|
|
619
|
+
* so collapsing it at the parse boundary would only hide the authored value from a
|
|
620
|
+
* consumer that asks.
|
|
621
|
+
*/
|
|
622
|
+
type SectionBreakType = 'nextPage' | 'continuous' | 'evenPage' | 'oddPage' | 'nextColumn';
|
|
623
|
+
/**
|
|
624
|
+
* Authored `w:pgNumType` (ECMA-376 CT_PageNumber).
|
|
625
|
+
*
|
|
626
|
+
* Distinguishes three states via {@link SectionProperties.pageNumbering}:
|
|
627
|
+
* - element absent → `undefined` (Word defaults; no empty element to re-emit)
|
|
628
|
+
* - empty `<w:pgNumType/>` → `{}` (present, no authored attrs; must round-trip empty)
|
|
629
|
+
* - attributes set → only those keys appear (never invent schema defaults like `fmt=decimal`)
|
|
630
|
+
*
|
|
631
|
+
* `chapStyle` / `chapSep` are preserved for consumers; PAGE projection does not yet compose
|
|
632
|
+
* chapter numbers (heading outline resolution is out of this slice).
|
|
633
|
+
*/
|
|
634
|
+
interface SectionPageNumbering {
|
|
635
|
+
/** Authored `@w:start` when present and in range; otherwise omitted. */
|
|
636
|
+
readonly start?: number;
|
|
637
|
+
/** Authored `@w:fmt` (ST_NumberFormat) when present; otherwise omitted. */
|
|
638
|
+
readonly fmt?: string;
|
|
639
|
+
/** Authored `@w:chapStyle` outline level when present and in range. */
|
|
640
|
+
readonly chapStyle?: number;
|
|
641
|
+
/** Authored `@w:chapSep` when present (hyphen / period / colon / emDash / enDash). */
|
|
642
|
+
readonly chapSep?: string;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* One section's resolved `w:sectPr`, as layout needs it.
|
|
646
|
+
*
|
|
647
|
+
* Resolved, not raw: defaults the file omitted are filled in here (an absent `w:type` is
|
|
648
|
+
* `nextPage`), so layout never has to know which attributes were authored and which were
|
|
649
|
+
* inherited.
|
|
650
|
+
*/
|
|
651
|
+
interface SectionProperties {
|
|
652
|
+
/** Active document grid line pitch: line-unit paragraph margins and line snapping. */
|
|
653
|
+
readonly gridLinePitchTwips?: number;
|
|
654
|
+
readonly pageSize: {
|
|
655
|
+
readonly widthTwips: number;
|
|
656
|
+
readonly heightTwips: number;
|
|
657
|
+
};
|
|
658
|
+
readonly margins: SectionMargins;
|
|
659
|
+
readonly columns: SectionColumns;
|
|
660
|
+
readonly landscape: boolean;
|
|
661
|
+
readonly titlePage: boolean;
|
|
662
|
+
/** Absent `w:type` defaults to `nextPage`. */
|
|
663
|
+
readonly breakType: SectionBreakType;
|
|
664
|
+
/**
|
|
665
|
+
* Authored page-number type. Absent when `w:pgNumType` is missing; empty object when the
|
|
666
|
+
* element is present with no attributes (comprehensive-fixture shape).
|
|
667
|
+
*/
|
|
668
|
+
readonly pageNumbering?: SectionPageNumbering;
|
|
669
|
+
/**
|
|
670
|
+
* Resolved `w:pgBorders` (§17.6.10). Absent when the section declares none, or when every
|
|
671
|
+
* edge it declares is off or an art border — see {@link parsePageBorders}.
|
|
672
|
+
*/
|
|
673
|
+
readonly pageBorders?: SectionPageBorders;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* One section of the body story: contiguous top-level blocks plus the properties that end it.
|
|
677
|
+
*
|
|
678
|
+
* `blockStart` / `blockEndExclusive` index into `storyBlocks(part)`.
|
|
679
|
+
*/
|
|
680
|
+
interface DocumentSection {
|
|
681
|
+
readonly index: number;
|
|
682
|
+
readonly properties: SectionProperties;
|
|
683
|
+
readonly blockStart: number;
|
|
684
|
+
readonly blockEndExclusive: number;
|
|
685
|
+
}
|
|
686
|
+
/** US Letter, portrait, one-inch margins: Word's own default when a section says nothing. */
|
|
687
|
+
declare const DEFAULT_SECTION_PROPERTIES: SectionProperties;
|
|
688
|
+
/**
|
|
689
|
+
* Parse authored `w:pgNumType` without inventing schema defaults.
|
|
690
|
+
*
|
|
691
|
+
* Returns `undefined` when the element is absent. An empty element yields `{}` so callers
|
|
692
|
+
* can tell "present but unauthored" from "missing" and serialization can re-emit empty.
|
|
693
|
+
* Hostile / out-of-range attribute values are dropped rather than clamped into meaning.
|
|
694
|
+
*/
|
|
695
|
+
declare function parsePageNumbering(sectPr: OoxmlNode): SectionPageNumbering | undefined;
|
|
696
|
+
/** Parse one `w:sectPr` into geometry/break properties (null reads as Word's defaults). */
|
|
697
|
+
declare function parseSectionProperties(sectPr: OoxmlNode | null | undefined): SectionProperties;
|
|
698
|
+
/** `w:sectPr` nested under a paragraph's `w:pPr`, if present. */
|
|
699
|
+
declare function paragraphSectionNode(paragraph: OoxmlElement): OoxmlElement | undefined;
|
|
700
|
+
/**
|
|
701
|
+
* The section properties a part declares, or Word's defaults where it says nothing.
|
|
702
|
+
*
|
|
703
|
+
* Returns the FINAL section (body-level `w:sectPr`, else the last paragraph-level one).
|
|
704
|
+
* Multi-section geometry belongs to `enumerateDocumentSections`; chrome that needs "the
|
|
705
|
+
* document's page" still reads the last section, which is what Word's body-level sectPr is.
|
|
706
|
+
*/
|
|
707
|
+
declare function readSectionProperties(part: OoxmlPart): SectionProperties;
|
|
708
|
+
/**
|
|
709
|
+
* Split the body story into sections.
|
|
710
|
+
*
|
|
711
|
+
* A paragraph carrying `w:pPr/w:sectPr` ends the current section (that paragraph is IN the
|
|
712
|
+
* section being ended). The body-level `w:sectPr` ends the final section. A document with
|
|
713
|
+
* neither yields one section of Word defaults covering every block.
|
|
714
|
+
*
|
|
715
|
+
* Enumeration is capped at {@link MAX_DOCUMENT_SECTIONS}. Further paragraph-level section
|
|
716
|
+
* breaks are ignored and remaining blocks fold into the last accepted section (fail closed).
|
|
717
|
+
*
|
|
718
|
+
* `displayMode` MUST match the one the caller passes to `storyBlocks`. `blockStart` /
|
|
719
|
+
* `blockEndExclusive` are indices into that list, and the list changes shape with the mode:
|
|
720
|
+
* the proposed view drops a paragraph whose mark and content a revision both removed. Slicing
|
|
721
|
+
* a filtered list with indices counted over an unfiltered one puts body text under another
|
|
722
|
+
* section's page geometry — the wrong paper size, the wrong margins, the wrong header.
|
|
723
|
+
*/
|
|
724
|
+
declare function enumerateDocumentSections(part: OoxmlPart, displayMode?: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter): DocumentSection[];
|
|
725
|
+
/**
|
|
726
|
+
* Canonical section index behind each section in a revision-projected body.
|
|
727
|
+
*
|
|
728
|
+
* A removed paragraph mark can collapse an entire section. The projected section keeps the
|
|
729
|
+
* surviving paragraph's geometry, while package APIs such as header/footer resolution remain
|
|
730
|
+
* indexed over the canonical tree. This bridge prevents those two index spaces from being
|
|
731
|
+
* paired positionally.
|
|
732
|
+
*/
|
|
733
|
+
declare function projectedSectionSourceIndexes(part: OoxmlPart, displayMode?: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter): readonly number[];
|
|
734
|
+
/**
|
|
735
|
+
* Every section in a document, with a flag saying whether the list was cut short.
|
|
736
|
+
*
|
|
737
|
+
* `truncated` is reported rather than silent: section count comes from a file, so a crafted
|
|
738
|
+
* document declaring thousands of paragraph-level `w:sectPr` marks is bounded, and a reader
|
|
739
|
+
* should be able to tell that happened.
|
|
740
|
+
*/
|
|
741
|
+
interface DocumentSectionsEnumeration {
|
|
742
|
+
readonly sections: DocumentSection[];
|
|
743
|
+
/** True when paragraph-level sectPr marks beyond {@link MAX_DOCUMENT_SECTIONS} were dropped. */
|
|
744
|
+
readonly truncated: boolean;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Like {@link enumerateDocumentSections}, but reports whether the section bound clipped
|
|
748
|
+
* hostile input. Prefer the plain enumerator for normal layout; use this when a caller
|
|
749
|
+
* needs a named fail-closed diagnostic.
|
|
750
|
+
*/
|
|
751
|
+
declare function enumerateDocumentSectionsBounded(part: OoxmlPart, displayMode?: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter): DocumentSectionsEnumeration;
|
|
752
|
+
/**
|
|
753
|
+
* Section properties as the geometry layout paginates against.
|
|
754
|
+
*
|
|
755
|
+
* The gutter is added to the LEFT margin: it is binding allowance, extra space on the inner
|
|
756
|
+
* edge, and folding it into the content width instead would silently narrow every line.
|
|
757
|
+
*
|
|
758
|
+
* Top and bottom keep the authored sign of `w:pgMar`: a negative value is an exact inset that
|
|
759
|
+
* header and footer height never moves. Read them through `page-body-margins.ts`.
|
|
760
|
+
*/
|
|
761
|
+
declare function geometryOfSection(section: SectionProperties): PageGeometry;
|
|
762
|
+
|
|
14
763
|
/**
|
|
15
764
|
* `w:tblpPr/@w:horzAnchor` (17.4.58) and `@w:vertAnchor` (17.4.66): the box a floated
|
|
16
765
|
* table's offsets are measured from. Absent means `text` for both.
|
|
@@ -678,314 +1427,48 @@ interface ShapingEnvironmentFingerprintInputs {
|
|
|
678
1427
|
readonly normalization: NormalizationPolicy;
|
|
679
1428
|
readonly script: string;
|
|
680
1429
|
readonly language: string;
|
|
681
|
-
readonly direction: TextDirection;
|
|
682
|
-
readonly features: readonly (readonly [string, number])[];
|
|
683
|
-
readonly fallbackOrder: readonly FontFingerprintInputs[];
|
|
684
|
-
readonly fixedPointScale: number;
|
|
685
|
-
readonly roundingMode: FixedPointRoundingMode;
|
|
686
|
-
}
|
|
687
|
-
/**
|
|
688
|
-
* Validate and freeze a shaping environment.
|
|
689
|
-
*
|
|
690
|
-
* Checks every field that could silently corrupt a measurement: OpenType tags must be four ASCII
|
|
691
|
-
* bytes, script and language must be non-blank and control-character free, fonts must already be
|
|
692
|
-
* validated. Throws rather than coercing — a bad tag that shapes anyway produces a document that
|
|
693
|
-
* measures wrong everywhere and looks fine.
|
|
694
|
-
*
|
|
695
|
-
* @throws TypeError on a malformed tag, name, or axis value.
|
|
696
|
-
*/
|
|
697
|
-
declare const createShapingEnvironment: (input: ShapingEnvironmentInput) => ShapingEnvironment;
|
|
698
|
-
/**
|
|
699
|
-
* Reduce an environment to its comparable form, with records sorted so key order cannot affect
|
|
700
|
-
* the result.
|
|
701
|
-
*/
|
|
702
|
-
declare const shapingEnvironmentFingerprintInputs: (input: ShapingEnvironmentInput) => ShapingEnvironmentFingerprintInputs;
|
|
703
|
-
/** Canonical serialization of every shaping variable, including byte hash and provenance. */
|
|
704
|
-
declare const shapingEnvironmentFingerprint: (environment: ShapingEnvironmentInput) => string;
|
|
705
|
-
/**
|
|
706
|
-
* Validate and freeze a shaped run against the environment that produced it.
|
|
707
|
-
*
|
|
708
|
-
* Checks the internal consistency a shaper must satisfy: direction matches the environment,
|
|
709
|
-
* cluster ranges tile the text without gaps or overlap, glyph ranges stay in bounds, font spans
|
|
710
|
-
* cover every glyph, and caret edges are monotonic. A shaper that violates any of these produces
|
|
711
|
-
* a caret that lands in the wrong place, which is far harder to diagnose downstream than here.
|
|
712
|
-
*
|
|
713
|
-
* @throws TypeError when the run and environment disagree, or the run is internally inconsistent.
|
|
714
|
-
*/
|
|
715
|
-
declare const createShapedRun: (input: ShapedRun, environmentInput: ShapingEnvironmentInput) => ShapedRun;
|
|
716
|
-
/**
|
|
717
|
-
* Reduce a shaped run to its comparable form, validating it on the way through.
|
|
718
|
-
*
|
|
719
|
-
* What the D9 determinism oracles compare: two shaping runs of the same text in the same
|
|
720
|
-
* environment must produce byte-identical structures here.
|
|
721
|
-
*/
|
|
722
|
-
declare const shapedRunComparatorInputs: (input: ShapedRun, environment: ShapingEnvironmentInput) => ShapedRunComparatorInputs;
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* Whether a paragraph must start a new page (`w:pageBreakBefore`).
|
|
726
|
-
*
|
|
727
|
-
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
728
|
-
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
729
|
-
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
730
|
-
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
731
|
-
* page number after it was wrong.
|
|
732
|
-
*
|
|
733
|
-
* An absent `w:val` is on (§17.17.4), and the off vocabulary is the whole of it — `off` is a
|
|
734
|
-
* spelling too, which {@link isOn} beside this already accepts.
|
|
735
|
-
*/
|
|
736
|
-
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
737
|
-
/**
|
|
738
|
-
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
739
|
-
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
740
|
-
*/
|
|
741
|
-
declare const MAX_PARAGRAPH_SPACING_PT: number;
|
|
742
|
-
/** Soft ceiling on border width (96 eighths = 12pt). Word's UI tops out well below this. */
|
|
743
|
-
declare const MAX_BORDER_WIDTH_PT = 12;
|
|
744
|
-
/** Soft ceiling on border-to-text gap (`w:space`, already in points). */
|
|
745
|
-
declare const MAX_BORDER_SPACE_PT = 3168;
|
|
746
|
-
/**
|
|
747
|
-
* A paragraph's resolved space before and after, in points.
|
|
748
|
-
*
|
|
749
|
-
* Already collapsed against `w:contextualSpacing`, so adjacent same-style paragraphs that suppress
|
|
750
|
-
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
751
|
-
*/
|
|
752
|
-
interface ParagraphSpacing {
|
|
753
|
-
/** `w:spacing/@before`, in points. */
|
|
754
|
-
readonly before: number;
|
|
755
|
-
/** `w:spacing/@after`, in points. */
|
|
756
|
-
readonly after: number;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* The gap Word substitutes when `w:beforeAutospacing` / `w:afterAutospacing` is on
|
|
760
|
-
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
761
|
-
*
|
|
762
|
-
* The attribute means "the consumer decides", and the authored `@before` / `@after` beside it
|
|
763
|
-
* is IGNORED rather than used as the value. Word's answer is HTML's default `<p>` margin,
|
|
764
|
-
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
765
|
-
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
766
|
-
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
767
|
-
*/
|
|
768
|
-
declare const AUTO_PARAGRAPH_SPACING_PT = 14;
|
|
769
|
-
/**
|
|
770
|
-
* Where a paragraph sits, for the contexts in which Word's auto spacing resolves to 0
|
|
771
|
-
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
772
|
-
*
|
|
773
|
-
* This resolves the interior list-item value. Body layout restores each outer list margin
|
|
774
|
-
* in `resolveListAutoSpacing`, where neighboring blocks are available. A caller that says
|
|
775
|
-
* nothing gets the body answer.
|
|
776
|
-
*
|
|
777
|
-
* A TABLE CELL is not such a context. Measured on a captured control at 10pt, where the
|
|
778
|
-
* line pitch is 11.52pt: the reference puts 26.16pt between two paragraphs in the body with
|
|
779
|
-
* auto spacing on, and the SAME 26.16pt between two paragraphs inside a cell. With an empty
|
|
780
|
-
* paragraph between them it is 52.32, exactly twice. Reading it as 0 in a cell lays every
|
|
781
|
-
* such paragraph 13.92pt tight, which is enough to pull a signature block back onto the
|
|
782
|
-
* previous page. See `.cache/pdf/claude-autospacing/`.
|
|
783
|
-
*/
|
|
784
|
-
interface ParagraphAutoSpacingContext {
|
|
785
|
-
/** The paragraph participates in numbering (`w:numPr`), i.e. it is a list item. */
|
|
786
|
-
readonly inList?: boolean;
|
|
787
|
-
/**
|
|
788
|
-
* The paragraph lives in a table cell. Kept because callers describe position with it and
|
|
789
|
-
* list resolution reads it; it does NOT zero auto spacing.
|
|
790
|
-
*/
|
|
791
|
-
readonly inTableCell?: boolean;
|
|
792
|
-
/** Section grid pitch in points; no grid uses Word's fixed 12pt line unit. */
|
|
793
|
-
readonly lineUnitPt?: number;
|
|
794
|
-
/**
|
|
795
|
-
* `w:doNotUseHTMLParagraphAutoSpacing` is on: automatic spacing outside a list resolves to
|
|
796
|
-
* the fixed 5pt before and 10pt after instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
797
|
-
*/
|
|
798
|
-
readonly fixedAutoSpacing?: boolean;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Resolved line spacing (`w:spacing/@line` + `@lineRule`, ECMA-376 17.3.1.33).
|
|
802
|
-
*
|
|
803
|
-
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
804
|
-
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
805
|
-
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
806
|
-
* moves every page break, so this is not a cosmetic detail.
|
|
807
|
-
*
|
|
808
|
-
* `exact` fixes the line box at `@line` twips and lets tall glyphs clip, the way Word
|
|
809
|
-
* does. `atLeast` uses it as a floor.
|
|
810
|
-
*/
|
|
811
|
-
type LineSpacingRule = 'auto' | 'exact' | 'atLeast';
|
|
812
|
-
/**
|
|
813
|
-
* Resolved line spacing: the rule, and the value it applies.
|
|
814
|
-
*
|
|
815
|
-
* `value` means different things per rule — 240ths of a line under `auto`, points under `exact`
|
|
816
|
-
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
817
|
-
*/
|
|
818
|
-
interface ParagraphLineSpacing {
|
|
819
|
-
readonly rule: LineSpacingRule;
|
|
820
|
-
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
821
|
-
readonly value: number;
|
|
822
|
-
/** Legacy noExtraLineSpacing: retain the natural baseline within an exact-height box. */
|
|
823
|
-
readonly preserveExactBaseline?: true;
|
|
824
|
-
/**
|
|
825
|
-
* Active section line-grid pitch in points (`w:docGrid/@w:linePitch`). Present only when
|
|
826
|
-
* the paragraph snaps to the grid; only with `auto`. See `line-grid.ts`.
|
|
827
|
-
*/
|
|
828
|
-
readonly gridPitch?: number;
|
|
829
|
-
}
|
|
830
|
-
/** Single spacing: what a paragraph that says nothing gets. */
|
|
831
|
-
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
832
|
-
/**
|
|
833
|
-
* One resolved `w:pBdr` edge: its style, colour, thickness and gap.
|
|
834
|
-
*
|
|
835
|
-
* `widthPt` and `spacePt` are already converted and CLAMPED — both come from a file, and an
|
|
836
|
-
* unbounded border width becomes a layout dimension.
|
|
837
|
-
*/
|
|
838
|
-
interface ParagraphBorderEdge {
|
|
839
|
-
/** Authored `ST_Border` value (`single`, `dashed`, …). */
|
|
840
|
-
readonly val: string;
|
|
841
|
-
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
842
|
-
readonly color: string | null;
|
|
843
|
-
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
844
|
-
readonly widthPt: number;
|
|
845
|
-
/** Gap from text to the rule, in points (`w:space`). */
|
|
846
|
-
readonly spacePt: number;
|
|
847
|
-
/**
|
|
848
|
-
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
849
|
-
*
|
|
850
|
-
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
851
|
-
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
852
|
-
*/
|
|
853
|
-
readonly shadow?: true;
|
|
854
|
-
}
|
|
855
|
-
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
856
|
-
declare const PARAGRAPH_BORDER_SIDES: readonly ['top', 'left', 'bottom', 'right', 'between', 'bar'];
|
|
857
|
-
/**
|
|
858
|
-
* Which of the six `CT_PBdr` edges.
|
|
859
|
-
*
|
|
860
|
-
* Four are physical box edges; `between` and `bar` are group-relative, drawn only where
|
|
861
|
-
* consecutive paragraphs share a border definition.
|
|
862
|
-
*/
|
|
863
|
-
type ParagraphBorderSide = (typeof PARAGRAPH_BORDER_SIDES)[number];
|
|
864
|
-
/**
|
|
865
|
-
* A paragraph's resolved `w:pBdr` (ECMA-376 §17.3.1.24).
|
|
866
|
-
*
|
|
867
|
-
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
868
|
-
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
869
|
-
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
870
|
-
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
871
|
-
*/
|
|
872
|
-
interface ParagraphBorders {
|
|
873
|
-
readonly top?: ParagraphBorderEdge;
|
|
874
|
-
readonly left?: ParagraphBorderEdge;
|
|
875
|
-
readonly bottom?: ParagraphBorderEdge;
|
|
876
|
-
readonly right?: ParagraphBorderEdge;
|
|
877
|
-
readonly between?: ParagraphBorderEdge;
|
|
878
|
-
readonly bar?: ParagraphBorderEdge;
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Resolve `w:spacing` before/after from flat paragraph properties.
|
|
882
|
-
*
|
|
883
|
-
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
884
|
-
* height, not the gap between paragraphs — and is not resolved here.
|
|
885
|
-
*
|
|
886
|
-
* `w:beforeAutospacing` / `w:afterAutospacing` REPLACE the authored measurement on their own
|
|
887
|
-
* side rather than adding to it; see {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
888
|
-
*/
|
|
889
|
-
declare function paragraphSpacing(props: readonly OoxmlProperty[], context?: ParagraphAutoSpacingContext): ParagraphSpacing;
|
|
890
|
-
/**
|
|
891
|
-
* Resolve `w:line` / `w:lineRule` from flat paragraph properties.
|
|
892
|
-
*
|
|
893
|
-
* Merged per attribute for the same reason as before/after: `w:spacing` is one element
|
|
894
|
-
* carrying independent attributes, and a style that states only `@line` must not reset the
|
|
895
|
-
* rule an earlier entry in the cascade set.
|
|
896
|
-
*/
|
|
897
|
-
declare function paragraphLineSpacing(props: readonly OoxmlProperty[]): ParagraphLineSpacing;
|
|
898
|
-
/**
|
|
899
|
-
* Apply resolved line spacing to a line's natural (glyph-derived) box.
|
|
900
|
-
*
|
|
901
|
-
* `auto` places its extra BELOW the line — the last line's multiple spacing still separates
|
|
902
|
-
* it from the next paragraph. Putting that delta above inverted cover-page rhythm:
|
|
903
|
-
* `w:line="460"` on "between" opened a large gap above the word and almost none before
|
|
904
|
-
* "MERIDIAN".
|
|
905
|
-
*
|
|
906
|
-
* `atLeast` does the OPPOSITE: the box grows upward and the glyphs sit on its floor. A
|
|
907
|
-
* captured control settles it — Times New Roman 12 pt at `w:line="360" w:lineRule="atLeast"`
|
|
908
|
-
* puts the reference's baseline at 15.36 pt, which is `18 - descent` snapped to the device
|
|
909
|
-
* grid, where treating it like `auto` leaves the baseline at 11.28 and the text 4.08 pt too
|
|
910
|
-
* high. `w:line="240" atLeast` is below the natural line, falls through to the natural
|
|
911
|
-
* height, and is unaffected. See `.cache/pdf/claude-linerule/`.
|
|
912
|
-
*
|
|
913
|
-
* Exact-height boxes place their baseline at 80% of the height; the legacy
|
|
914
|
-
* noExtraLineSpacing switch instead preserves the face baseline within the box.
|
|
915
|
-
*
|
|
916
|
-
* An `auto` or `atLeast` line of a snapping paragraph under an active line grid takes whole
|
|
917
|
-
* pitches instead ({@link gridLineBox}); `trailing` then names the box below the glyphs.
|
|
918
|
-
*/
|
|
919
|
-
declare function applyLineSpacing(spacing: ParagraphLineSpacing, naturalHeight: number, naturalBaseline: number): {
|
|
920
|
-
height: number;
|
|
921
|
-
baseline: number;
|
|
922
|
-
trailing?: number;
|
|
923
|
-
};
|
|
924
|
-
/**
|
|
925
|
-
* `w:contextualSpacing` (17.3.1.9): drop before/after between paragraphs of the SAME
|
|
926
|
-
* style. Word's built-in `ListParagraph` sets it, so every list authored in Word gets a
|
|
927
|
-
* paragraph gap between items without this.
|
|
928
|
-
*/
|
|
929
|
-
declare function paragraphContextualSpacing(props: readonly OoxmlProperty[]): boolean;
|
|
930
|
-
/**
|
|
931
|
-
* Resolve `w:pBdr` from the paragraph-properties node.
|
|
932
|
-
*
|
|
933
|
-
* Nested — every edge is a child of `pBdr`, not an attribute — so this reads the typed tree
|
|
934
|
-
* rather than the flattened `OoxmlProperty[]` bag `propertiesOf` builds for leaf props.
|
|
935
|
-
*/
|
|
936
|
-
declare function paragraphBorders(pPr: OoxmlNode | undefined): ParagraphBorders;
|
|
1430
|
+
readonly direction: TextDirection;
|
|
1431
|
+
readonly features: readonly (readonly [string, number])[];
|
|
1432
|
+
readonly fallbackOrder: readonly FontFingerprintInputs[];
|
|
1433
|
+
readonly fixedPointScale: number;
|
|
1434
|
+
readonly roundingMode: FixedPointRoundingMode;
|
|
1435
|
+
}
|
|
937
1436
|
/**
|
|
938
|
-
*
|
|
1437
|
+
* Validate and freeze a shaping environment.
|
|
939
1438
|
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
|
|
944
|
-
declare function cascadedParagraphBorders(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorders;
|
|
945
|
-
/**
|
|
946
|
-
* Visual stroke thickness layout publishes for one edge (points).
|
|
1439
|
+
* Checks every field that could silently corrupt a measurement: OpenType tags must be four ASCII
|
|
1440
|
+
* bytes, script and language must be non-blank and control-character free, fonts must already be
|
|
1441
|
+
* validated. Throws rather than coercing — a bad tag that shapes anyway produces a document that
|
|
1442
|
+
* measures wrong everywhere and looks fine.
|
|
947
1443
|
*
|
|
948
|
-
*
|
|
949
|
-
* `w:sz="3"` double still occupies a visible double-line box — matching table borders.
|
|
1444
|
+
* @throws TypeError on a malformed tag, name, or axis value.
|
|
950
1445
|
*/
|
|
951
|
-
declare
|
|
1446
|
+
declare const createShapingEnvironment: (input: ShapingEnvironmentInput) => ShapingEnvironment;
|
|
952
1447
|
/**
|
|
953
|
-
*
|
|
954
|
-
*
|
|
955
|
-
* Vertically that is flow height — a top rule pushes the first line down, a bottom rule holds
|
|
956
|
-
* the page open below the last one — so pagination has to see it. Horizontally it is
|
|
957
|
-
* publish-only: Word draws left/right paragraph rules OUTSIDE the text column and never
|
|
958
|
-
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
1448
|
+
* Reduce an environment to its comparable form, with records sorted so key order cannot affect
|
|
1449
|
+
* the result.
|
|
959
1450
|
*/
|
|
960
|
-
declare
|
|
961
|
-
/**
|
|
962
|
-
declare
|
|
1451
|
+
declare const shapingEnvironmentFingerprintInputs: (input: ShapingEnvironmentInput) => ShapingEnvironmentFingerprintInputs;
|
|
1452
|
+
/** Canonical serialization of every shaping variable, including byte hash and provenance. */
|
|
1453
|
+
declare const shapingEnvironmentFingerprint: (environment: ShapingEnvironmentInput) => string;
|
|
963
1454
|
/**
|
|
964
|
-
*
|
|
1455
|
+
* Validate and freeze a shaped run against the environment that produced it.
|
|
965
1456
|
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
*
|
|
1457
|
+
* Checks the internal consistency a shaper must satisfy: direction matches the environment,
|
|
1458
|
+
* cluster ranges tile the text without gaps or overlap, glyph ranges stay in bounds, font spans
|
|
1459
|
+
* cover every glyph, and caret edges are monotonic. A shaper that violates any of these produces
|
|
1460
|
+
* a caret that lands in the wrong place, which is far harder to diagnose downstream than here.
|
|
970
1461
|
*
|
|
971
|
-
*
|
|
972
|
-
*/
|
|
973
|
-
declare function paragraphBordersFingerprint(borders: ParagraphBorders): string;
|
|
974
|
-
/**
|
|
975
|
-
* Gap to insert before a paragraph once the previous paragraph's `after` is already in the
|
|
976
|
-
* flow cursor — Word takes the larger of the two rather than summing them.
|
|
1462
|
+
* @throws TypeError when the run and environment disagree, or the run is internally inconsistent.
|
|
977
1463
|
*/
|
|
978
|
-
declare
|
|
1464
|
+
declare const createShapedRun: (input: ShapedRun, environmentInput: ShapingEnvironmentInput) => ShapedRun;
|
|
979
1465
|
/**
|
|
980
|
-
*
|
|
1466
|
+
* Reduce a shaped run to its comparable form, validating it on the way through.
|
|
981
1467
|
*
|
|
982
|
-
*
|
|
983
|
-
*
|
|
984
|
-
* paragraph, or the first paragraph of a document/section, retains before. Callers publish this
|
|
985
|
-
* applied value on the fragment so shading, borders,
|
|
986
|
-
* selection, and paint share one geometry.
|
|
1468
|
+
* What the D9 determinism oracles compare: two shaping runs of the same text in the same
|
|
1469
|
+
* environment must produce byte-identical structures here.
|
|
987
1470
|
*/
|
|
988
|
-
declare
|
|
1471
|
+
declare const shapedRunComparatorInputs: (input: ShapedRun, environment: ShapingEnvironmentInput) => ShapedRunComparatorInputs;
|
|
989
1472
|
|
|
990
1473
|
/** `w:vertAlign` — script position, which also scales the run's effective size. */
|
|
991
1474
|
type VerticalAlign = 'baseline' | 'superscript' | 'subscript';
|
|
@@ -1132,6 +1615,8 @@ interface ThemeFonts {
|
|
|
1132
1615
|
readonly minorSupplemental?: Readonly<Record<string, string>>;
|
|
1133
1616
|
/** Lower-cased font table names that declare a Chinese character set. */
|
|
1134
1617
|
readonly chineseFontTableFaces?: readonly string[];
|
|
1618
|
+
/** Lower-cased font table names that declare an East Asian character set. */
|
|
1619
|
+
readonly eastAsianFontTableFaces?: readonly string[];
|
|
1135
1620
|
}
|
|
1136
1621
|
/**
|
|
1137
1622
|
* Resolve one run's direct formatting.
|
|
@@ -1628,6 +2113,10 @@ declare function tabStopsFingerprint(tabs: ResolvedTabStops): string;
|
|
|
1628
2113
|
interface CjkTypographySettings {
|
|
1629
2114
|
/** Apply the strict Japanese small-kana and prolonged-sound-mark restrictions. */
|
|
1630
2115
|
readonly strict: boolean;
|
|
2116
|
+
/** Disable adjacent full-width punctuation compression when false. */
|
|
2117
|
+
readonly punctuationKerning?: boolean;
|
|
2118
|
+
/** The document defaults explicitly select an East Asian face as the East Asian font. */
|
|
2119
|
+
readonly sourceEastAsianFont?: boolean;
|
|
1631
2120
|
/** Whitespace compression selected by `w:characterSpacingControl`. */
|
|
1632
2121
|
readonly compression: 'doNotCompress' | 'compressPunctuation' | 'compressPunctuationAndJapaneseKana';
|
|
1633
2122
|
/** Custom no-line-start characters, keyed by normalized language tag. */
|
|
@@ -2362,6 +2851,8 @@ interface EquationTextGeometry extends EquationGeometryBase {
|
|
|
2362
2851
|
readonly kind: 'text' | 'fallback';
|
|
2363
2852
|
readonly text: string;
|
|
2364
2853
|
readonly fontSizePt: number;
|
|
2854
|
+
/** The same resolved face used by measurement and the trusted paint sink. */
|
|
2855
|
+
readonly runStyle?: ResolvedRunStyle;
|
|
2365
2856
|
}
|
|
2366
2857
|
interface EquationRowGeometry extends EquationGeometryBase {
|
|
2367
2858
|
readonly kind: 'row';
|
|
@@ -2380,6 +2871,11 @@ interface EquationRadicalGeometry extends EquationGeometryBase {
|
|
|
2380
2871
|
readonly degree?: EquationGeometry;
|
|
2381
2872
|
readonly bar: LayoutBox;
|
|
2382
2873
|
}
|
|
2874
|
+
interface EquationBarGeometry extends EquationGeometryBase {
|
|
2875
|
+
readonly kind: 'bar';
|
|
2876
|
+
readonly body: EquationGeometry;
|
|
2877
|
+
readonly bar: LayoutBox;
|
|
2878
|
+
}
|
|
2383
2879
|
interface EquationScriptGeometry extends EquationGeometryBase {
|
|
2384
2880
|
readonly kind: 'script';
|
|
2385
2881
|
readonly base: EquationGeometry;
|
|
@@ -2393,7 +2889,7 @@ interface EquationNaryGeometry extends EquationGeometryBase {
|
|
|
2393
2889
|
readonly lowerLimit?: EquationGeometry;
|
|
2394
2890
|
readonly upperLimit?: EquationGeometry;
|
|
2395
2891
|
}
|
|
2396
|
-
type EquationGeometry = EquationTextGeometry | EquationRowGeometry | EquationFractionGeometry | EquationRadicalGeometry | EquationScriptGeometry | EquationNaryGeometry;
|
|
2892
|
+
type EquationGeometry = EquationTextGeometry | EquationRowGeometry | EquationFractionGeometry | EquationRadicalGeometry | EquationBarGeometry | EquationScriptGeometry | EquationNaryGeometry;
|
|
2397
2893
|
/** Equation metadata carried by one atomic semantic span. */
|
|
2398
2894
|
interface EquationSpanRecord {
|
|
2399
2895
|
readonly sourceNodeId: string;
|
|
@@ -2404,65 +2900,6 @@ interface EquationSpanRecord {
|
|
|
2404
2900
|
/** Compose one bounded OMML projection into paint-ready point geometry. */
|
|
2405
2901
|
declare function layoutEquation(projection: OmmlEquationProjection, measurer: TextMeasurer, style: ResolvedRunStyle): EquationSpanRecord;
|
|
2406
2902
|
|
|
2407
|
-
/**
|
|
2408
|
-
* The four physical sides of `CT_PageBorders`.
|
|
2409
|
-
*
|
|
2410
|
-
* Four, not the six of `w:pBdr`: `w:between` and `w:bar` are paragraph-group rules and the
|
|
2411
|
-
* page has no analogue for either.
|
|
2412
|
-
*/
|
|
2413
|
-
declare const PAGE_BORDER_SIDES: readonly ['top', 'left', 'bottom', 'right'];
|
|
2414
|
-
/** Which of the four page-frame edges. */
|
|
2415
|
-
type PageBorderSide = (typeof PAGE_BORDER_SIDES)[number];
|
|
2416
|
-
/**
|
|
2417
|
-
* `w:offsetFrom` (`ST_PgBorderOffset`) — what `w:space` on each edge is measured from.
|
|
2418
|
-
*
|
|
2419
|
-
* The schema default is `text`, NOT `page`. Word's own UI opens on "Edge of page", which is
|
|
2420
|
-
* why the wrong default is easy to assume and expensive to hold: at `text` the rule sits
|
|
2421
|
-
* `w:space` points outside the TEXT, so its distance from the sheet edge is the margin minus
|
|
2422
|
-
* the space — a number that moves whenever the margins do.
|
|
2423
|
-
*/
|
|
2424
|
-
type PageBorderOffsetFrom = 'page' | 'text';
|
|
2425
|
-
/** `w:display` (`ST_PgBorderDisplay`) — which pages of the section carry the frame. */
|
|
2426
|
-
type PageBorderDisplay = 'allPages' | 'firstPage' | 'notFirstPage';
|
|
2427
|
-
/** `w:zOrder` (`ST_PgBorderZOrder`) — whether the frame paints over the text or under it. */
|
|
2428
|
-
type PageBorderZOrder = 'front' | 'back';
|
|
2429
|
-
/**
|
|
2430
|
-
* One section's resolved `w:pgBorders`.
|
|
2431
|
-
*
|
|
2432
|
-
* Resolved, not raw: every attribute the file omitted is filled in with the SCHEMA default,
|
|
2433
|
-
* so a consumer never has to know which of the three were authored. An edge is present only
|
|
2434
|
-
* when it paints — `nil` / `none` and art borders are already gone (see {@link parsePageBorders}).
|
|
2435
|
-
*/
|
|
2436
|
-
interface SectionPageBorders {
|
|
2437
|
-
/** `w:offsetFrom`; absent attribute reads as `text` (§17.6.10). */
|
|
2438
|
-
readonly offsetFrom: PageBorderOffsetFrom;
|
|
2439
|
-
/** `w:display`; absent attribute reads as `allPages`. */
|
|
2440
|
-
readonly display: PageBorderDisplay;
|
|
2441
|
-
/** `w:zOrder`; absent attribute reads as `front`. */
|
|
2442
|
-
readonly zOrder: PageBorderZOrder;
|
|
2443
|
-
readonly top?: ParagraphBorderEdge;
|
|
2444
|
-
readonly left?: ParagraphBorderEdge;
|
|
2445
|
-
readonly bottom?: ParagraphBorderEdge;
|
|
2446
|
-
readonly right?: ParagraphBorderEdge;
|
|
2447
|
-
}
|
|
2448
|
-
/**
|
|
2449
|
-
* Parse `w:pgBorders` off one `w:sectPr`.
|
|
2450
|
-
*
|
|
2451
|
-
* Undefined when the element is absent AND when it paints nothing — every edge off, or every
|
|
2452
|
-
* edge an art border. Unlike `w:pgNumType`, an empty-but-present element is not distinguished:
|
|
2453
|
-
* these properties are a LAYOUT input, serialization re-emits the canonical tree, and a frame
|
|
2454
|
-
* with no edges has exactly one meaning downstream.
|
|
2455
|
-
*/
|
|
2456
|
-
declare function parsePageBorders(sectPr: OoxmlNode): SectionPageBorders | undefined;
|
|
2457
|
-
/**
|
|
2458
|
-
* Identity of one section's page frame, for incremental-layout context keys.
|
|
2459
|
-
*
|
|
2460
|
-
* A `w:pgBorders` edit changes nothing the flow measures — the frame is drawn beside the text,
|
|
2461
|
-
* never through it — so no per-paragraph key moves and every reuse path would hand back the
|
|
2462
|
-
* previous sheets with the previous frame. This token goes in the pass context so it does not.
|
|
2463
|
-
*/
|
|
2464
|
-
declare function pageBordersFingerprint(borders: SectionPageBorders | undefined): string;
|
|
2465
|
-
|
|
2466
2903
|
/** Published root story containing an artifact occurrence. @public */
|
|
2467
2904
|
type SemanticArtifactRootStoryKind = 'body' | 'header' | 'footer' | 'footnote' | 'endnote' | 'note-separator';
|
|
2468
2905
|
/** Exact story in which a review artifact's source anchor was laid out. @public */
|
|
@@ -2550,6 +2987,91 @@ interface SemanticCommentArtifactRecord {
|
|
|
2550
2987
|
/** Exporter-neutral review artifact normalized by core. @public */
|
|
2551
2988
|
type SemanticReviewArtifactRecord = SemanticTrackedChangeArtifactRecord | SemanticCommentArtifactRecord;
|
|
2552
2989
|
|
|
2990
|
+
/**
|
|
2991
|
+
* Raw `w:lock/@w:val` on one control, or `unlocked` when absent / unrecognised.
|
|
2992
|
+
*
|
|
2993
|
+
* Effective permissions across a nesting chain are the union of every ancestor's lock on two
|
|
2994
|
+
* axes (content edit / removal); see {@link ContentControlBoundaryRecord.effectiveLock}.
|
|
2995
|
+
*/
|
|
2996
|
+
type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
|
|
2997
|
+
/**
|
|
2998
|
+
* Mapped control type for layout / chrome — same members as the shipped public
|
|
2999
|
+
* `ContentControlType`. Untyped and preserved-only kinds report as `richText`.
|
|
3000
|
+
*/
|
|
3001
|
+
type ContentControlMappedType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'buildingBlockGallery' | 'repeatingSection';
|
|
3002
|
+
/** Where the control sits in the tree relative to its content. */
|
|
3003
|
+
type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell';
|
|
3004
|
+
/**
|
|
3005
|
+
* One piece of a control's content geometry.
|
|
3006
|
+
*
|
|
3007
|
+
* A block control that crosses a page break publishes one fragment per page rather than a
|
|
3008
|
+
* single rectangle covering the inter-page gap. An inline control publishes one fragment per
|
|
3009
|
+
* LINE it touches, covering the text's vertical extent (line-spacing leading excluded), so a
|
|
3010
|
+
* wrapped control never claims the words beside it. Coordinates match fragment boxes
|
|
3011
|
+
* (page-content space).
|
|
3012
|
+
*/
|
|
3013
|
+
interface ContentControlGeometryFragment {
|
|
3014
|
+
readonly pageIndex: number;
|
|
3015
|
+
readonly box: LayoutBox;
|
|
3016
|
+
}
|
|
3017
|
+
/**
|
|
3018
|
+
* Layout-published boundary for one content control (`w:sdt` / typed `contentControl`).
|
|
3019
|
+
*
|
|
3020
|
+
* Chrome, lock feedback, and hit resolution read this record — never painted DOM. The wrapper
|
|
3021
|
+
* itself is not a layout box; `fragments` cover the content that already flowed in place.
|
|
3022
|
+
*/
|
|
3023
|
+
interface ContentControlBoundaryRecord {
|
|
3024
|
+
/** Canonical node id of the control wrapper — not `w:id`. */
|
|
3025
|
+
readonly id: string;
|
|
3026
|
+
readonly alias?: string;
|
|
3027
|
+
readonly tag?: string;
|
|
3028
|
+
readonly controlType: ContentControlMappedType;
|
|
3029
|
+
/** This control's own `w:lock`, before ancestor union. */
|
|
3030
|
+
readonly lock: ContentControlLock;
|
|
3031
|
+
/**
|
|
3032
|
+
* Nested lock union with every ancestor control, collapsed back to a single `ST_Lock`
|
|
3033
|
+
* vocabulary value (both axes locked → `sdtContentLocked`).
|
|
3034
|
+
*/
|
|
3035
|
+
readonly effectiveLock: ContentControlLock;
|
|
3036
|
+
/** `w:showingPlcHdr` is present on the control's properties. */
|
|
3037
|
+
readonly placeholder: boolean;
|
|
3038
|
+
/** `w:dataBinding` is present — content edits are refused as bound. */
|
|
3039
|
+
readonly bound: boolean;
|
|
3040
|
+
/** 0 for a top-level control; increments through nested wrappers under the shared nesting bound. */
|
|
3041
|
+
readonly nestingDepth: number;
|
|
3042
|
+
readonly level: ContentControlLevel;
|
|
3043
|
+
readonly fragments: readonly ContentControlGeometryFragment[];
|
|
3044
|
+
/** An inline control's model offsets in its paragraph; positions map through this, not geometry. */
|
|
3045
|
+
readonly range?: ContentControlModelRange;
|
|
3046
|
+
}
|
|
3047
|
+
/** `[start, end)` UTF-16 offsets of an inline control's content in one paragraph. */
|
|
3048
|
+
interface ContentControlModelRange {
|
|
3049
|
+
/** The paragraph that holds the control. */
|
|
3050
|
+
readonly paragraphId: string;
|
|
3051
|
+
/** Offset of the control's first character. */
|
|
3052
|
+
readonly start: number;
|
|
3053
|
+
/** Offset just past the control's last character. */
|
|
3054
|
+
readonly end: number;
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
/** Page geometry, in points. */
|
|
3058
|
+
interface PageGeometry {
|
|
3059
|
+
readonly width: number;
|
|
3060
|
+
readonly height: number;
|
|
3061
|
+
readonly margin: {
|
|
3062
|
+
readonly top: number;
|
|
3063
|
+
readonly right: number;
|
|
3064
|
+
readonly bottom: number;
|
|
3065
|
+
readonly left: number;
|
|
3066
|
+
};
|
|
3067
|
+
/** `w:pgMar/@header` — sheet edge to header top, in points. Defaults to 36 (720 twips). */
|
|
3068
|
+
readonly headerDistance?: number;
|
|
3069
|
+
/** `w:pgMar/@footer` — sheet edge to footer bottom, in points. Defaults to 36. */
|
|
3070
|
+
readonly footerDistance?: number;
|
|
3071
|
+
}
|
|
3072
|
+
/** US Letter with one-inch margins, in points. */
|
|
3073
|
+
declare const DEFAULT_PAGE_GEOMETRY: PageGeometry;
|
|
3074
|
+
|
|
2553
3075
|
/** A half-open UTF-16 range inside one paragraph, addressed by its canonical node id. */
|
|
2554
3076
|
interface SourceRange {
|
|
2555
3077
|
readonly paragraphId: string;
|
|
@@ -2789,6 +3311,8 @@ interface StyleSpanRecord {
|
|
|
2789
3311
|
interface LineRecord {
|
|
2790
3312
|
/** An authored manual line break ends this line; optional display furniture can show ↵. */
|
|
2791
3313
|
readonly manualBreakAfter?: true;
|
|
3314
|
+
/** An authored page or column break ends this line; optional furniture can label it. */
|
|
3315
|
+
readonly breakAfter?: 'page' | 'column';
|
|
2792
3316
|
readonly id: string;
|
|
2793
3317
|
readonly range: SourceRange;
|
|
2794
3318
|
readonly spans: readonly StyleSpanRecord[];
|
|
@@ -3339,61 +3863,6 @@ interface NoteAreaRecord {
|
|
|
3339
3863
|
* - `endnote-overflow`: sheets inserted to finish sectEnd/docEnd collections.
|
|
3340
3864
|
*/
|
|
3341
3865
|
type PageNoteStream = 'footnote-drain' | 'endnote-overflow';
|
|
3342
|
-
/**
|
|
3343
|
-
* Raw `w:lock/@w:val` on one control, or `unlocked` when absent / unrecognised.
|
|
3344
|
-
*
|
|
3345
|
-
* Effective permissions across a nesting chain are the union of every ancestor's lock on two
|
|
3346
|
-
* axes (content edit / removal); see {@link ContentControlBoundaryRecord.effectiveLock}.
|
|
3347
|
-
*/
|
|
3348
|
-
type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
|
|
3349
|
-
/**
|
|
3350
|
-
* Mapped control type for layout / chrome — same members as the shipped public
|
|
3351
|
-
* `ContentControlType`. Untyped and preserved-only kinds report as `richText`.
|
|
3352
|
-
*/
|
|
3353
|
-
type ContentControlMappedType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'buildingBlockGallery' | 'repeatingSection';
|
|
3354
|
-
/** Where the control sits in the tree relative to its content. */
|
|
3355
|
-
type ContentControlLevel = 'block' | 'inline' | 'row' | 'cell';
|
|
3356
|
-
/**
|
|
3357
|
-
* One piece of a control's content geometry.
|
|
3358
|
-
*
|
|
3359
|
-
* A block control that crosses a page break publishes one fragment per page rather than a
|
|
3360
|
-
* single rectangle covering the inter-page gap. An inline control publishes one fragment per
|
|
3361
|
-
* LINE it touches, covering the text's vertical extent (line-spacing leading excluded), so a
|
|
3362
|
-
* wrapped control never claims the words beside it. Coordinates match fragment boxes
|
|
3363
|
-
* (page-content space).
|
|
3364
|
-
*/
|
|
3365
|
-
interface ContentControlGeometryFragment {
|
|
3366
|
-
readonly pageIndex: number;
|
|
3367
|
-
readonly box: LayoutBox;
|
|
3368
|
-
}
|
|
3369
|
-
/**
|
|
3370
|
-
* Layout-published boundary for one content control (`w:sdt` / typed `contentControl`).
|
|
3371
|
-
*
|
|
3372
|
-
* Chrome, lock feedback, and hit resolution read this record — never painted DOM. The wrapper
|
|
3373
|
-
* itself is not a layout box; `fragments` cover the content that already flowed in place.
|
|
3374
|
-
*/
|
|
3375
|
-
interface ContentControlBoundaryRecord {
|
|
3376
|
-
/** Canonical node id of the control wrapper — not `w:id`. */
|
|
3377
|
-
readonly id: string;
|
|
3378
|
-
readonly alias?: string;
|
|
3379
|
-
readonly tag?: string;
|
|
3380
|
-
readonly controlType: ContentControlMappedType;
|
|
3381
|
-
/** This control's own `w:lock`, before ancestor union. */
|
|
3382
|
-
readonly lock: ContentControlLock;
|
|
3383
|
-
/**
|
|
3384
|
-
* Nested lock union with every ancestor control, collapsed back to a single `ST_Lock`
|
|
3385
|
-
* vocabulary value (both axes locked → `sdtContentLocked`).
|
|
3386
|
-
*/
|
|
3387
|
-
readonly effectiveLock: ContentControlLock;
|
|
3388
|
-
/** `w:showingPlcHdr` is present on the control's properties. */
|
|
3389
|
-
readonly placeholder: boolean;
|
|
3390
|
-
/** `w:dataBinding` is present — content edits are refused as bound. */
|
|
3391
|
-
readonly bound: boolean;
|
|
3392
|
-
/** 0 for a top-level control; increments through nested wrappers under the shared nesting bound. */
|
|
3393
|
-
readonly nestingDepth: number;
|
|
3394
|
-
readonly level: ContentControlLevel;
|
|
3395
|
-
readonly fragments: readonly ContentControlGeometryFragment[];
|
|
3396
|
-
}
|
|
3397
3866
|
/**
|
|
3398
3867
|
* One laid-out page: the sheet, the content area, and everything that landed on it.
|
|
3399
3868
|
*
|
|
@@ -3487,6 +3956,13 @@ interface SemanticLayout {
|
|
|
3487
3956
|
* reuse paths that would otherwise return previous pages by identity with stale boundaries.
|
|
3488
3957
|
*/
|
|
3489
3958
|
readonly controlContextToken?: string;
|
|
3959
|
+
/** Body section breaks in document order, each named by the section that FOLLOWS it. */
|
|
3960
|
+
readonly sectionBreaks?: readonly SectionBreakMarkRecord[];
|
|
3961
|
+
}
|
|
3962
|
+
/** The paragraph whose `w:sectPr` ends a section, and how the next section starts. */
|
|
3963
|
+
interface SectionBreakMarkRecord {
|
|
3964
|
+
readonly paragraphId: string;
|
|
3965
|
+
readonly kind: SectionBreakType;
|
|
3490
3966
|
}
|
|
3491
3967
|
|
|
3492
3968
|
/**
|
|
@@ -3528,5 +4004,5 @@ interface TextMeasurer {
|
|
|
3528
4004
|
};
|
|
3529
4005
|
}
|
|
3530
4006
|
|
|
3531
|
-
export {
|
|
3532
|
-
export type {
|
|
4007
|
+
export { DEFAULT_REVISION_MARKUP as D, resolveRevisionMarkup as Q, DEFAULT_PAGE_GEOMETRY as aA, DEFAULT_REVISION_DISPLAY_MODE as aB, DEFAULT_RUN_STYLE as aC, DEFAULT_SECTION_PROPERTIES as aD, DEFAULT_TAB_INTERVAL_PT as aE, DEFAULT_TAB_INTERVAL_TWIPS as aF, EMPTY_NUMBERING_INDEX as aM, EMPTY_TAB_STOPS as aN, FontResolutionError as aZ, AUTO_PARAGRAPH_SPACING_PT as ap, HARD_MAX_AGGREGATE_FONT_BYTES as b6, HARD_MAX_FONT_BYTES as b7, HARD_MAX_FONT_SOURCES as b8, SINGLE_LINE_SPACING as bU, MAX_BORDER_SPACE_PT as be, MAX_BORDER_WIDTH_PT as bf, MAX_DOCUMENT_SECTIONS as bg, MAX_LVL_OVERRIDES as bh, MAX_NUMBERING_DEFINITIONS as bi, MAX_PARAGRAPH_SPACING_PT as bj, MAX_SHAPING_CONTEXT as bk, MAX_STYLE_DEFINITIONS as bl, MAX_TABLE_BORDER_STROKES as bm, MAX_TAB_POSITION_TWIPS as bn, MAX_TAB_STOPS as bo, PAGE_BORDER_SIDES as bs, PARAGRAPH_BORDER_SIDES as bt, nextTabDestination as c$, boundedStructuralFontValidator as cA, buildNumberingIndex as cB, buildStyleCascadeTable as cC, cascadeParagraphFormatting as cD, cascadeRunProperties as cE, cascadedBottomBorder as cF, cascadedParagraphBorders as cG, cascadedTabStops as cH, collapsedSpaceBefore as cI, createFontResourceSnapshot as cJ, createShapedRun as cK, createShapingEnvironment as cL, defaultTabIntervalFromSettings as cM, displayText as cN, enumerateDocumentSections as cO, enumerateDocumentSectionsBounded as cP, fixedPoint as cQ, fontRequestKey as cR, formatRevisionOf as cS, geometryOfSection as cT, glyphSizeFactorOf as cU, isValidStyleId as cV, itemizeScriptFontSlots as cW, layoutEquation as cX, markRevisionRemovesMark as cY, measureDisplayText as cZ, mergeListIndent as c_, TAB_LEADER_GLYPH as ch, UnsupportedScriptError as cs, appliedSpaceBefore as cu, applyLineSpacing as cv, baselineShiftPtOf as cw, borderExtentPt as cx, borderWeight as cy, bottomBorderExtentPt as cz, pageBordersFingerprint as d0, paragraphBorderExtentPt as d1, paragraphBorderStrokeWidthPt as d2, paragraphBorders as d3, paragraphBordersFingerprint as d4, paragraphBreaksBefore as d5, paragraphContextualSpacing as d6, paragraphLineSpacing as d7, paragraphMarkFormatRevisionOf as d8, paragraphMarkRevisionOf as d9, shapedRunComparatorInputs as dA, shapingEnvironmentFingerprint as dB, shapingEnvironmentFingerprintInputs as dC, shownMarkRevision as dD, styleForFontSlot as dE, tabAdvanceWidth as dF, tabStopsFingerprint as dG, withDefaultTabInterval as dH, withNumberingStyleLinks as dI, withResolvedListItems as dJ, paragraphMarkRevisionsOf as da, paragraphSectionNode as db, paragraphSpacing as dc, paragraphTabStops as dd, parsePageBorders as de, parsePageNumbering as df, parseRefInstruction as dg, parseSectionProperties as dh, projectedSectionSourceIndexes as di, readBorderSide as dj, readCellBorders as dk, readNumPr as dl, readSectionProperties as dm, readTableBorders as dn, resolveBorderConflict as dp, resolveNumberingLevel as dq, resolveParagraphLayoutInputs as dr, resolveRunStyle as ds, resolveStoryListItems as dt, resolveStoryRefFields as du, resolveTableCellBorderGrid as dv, revisionAuthorFilter as dw, revisionsAreDeletion as dx, revisionsVisible as dy, runStylesEqual as dz, REVISION_MARKUP_COLORS as w };
|
|
4008
|
+
export type { TableBorderSide as $, AnchoredDrawingRecord as A, BlockFragmentRecord as B, ContentControlBoundaryRecord as C, RevisionMarkupColor as E, FontResourceSnapshot as F, RevisionMarkupMark as G, HeaderFooterStoryRecord as H, InlineDrawingRecord as I, RevisionMarkupNamedColor as J, RevisionMarkupStyle as K, LineRecord as L, RevisionMarkupTextStyle as M, NoteAreaRecord as N, SectionProperties as O, ParagraphFragmentRecord as P, RevisionMarkupDialogSession as R, SemanticLayout as S, TextMeasurer as T, NumberingLevel as U, VersionedShapingLibrary as V, NumberingIndex as W, DrawingPoint as X, DrawingInsets as Y, ModelRange as Z, RevisionAttribution as _, ReviewDisplayMode as a, FontResourceDefinition as a$, TableFloatXSpec as a0, TableFloatYSpec as a1, ResolvedListItem as a2, RefFieldContext as a3, InlineDrawingLayoutContext as a4, CellBorderBox as a5, TableBorderBox as a6, TableCellStyleFormatting as a7, TableFloatPosition as a8, StyleCascadeTable as a9, DeclaredFontSubstitution as aG, DocumentSection as aH, DocumentSectionsEnumeration as aI, DrawingClipFallback as aJ, DrawingGeometry as aK, DrawingGroupPictureRecord as aL, EquationBarGeometry as aO, EquationFractionGeometry as aP, EquationGeometry as aQ, EquationNaryGeometry as aR, EquationRadicalGeometry as aS, EquationRowGeometry as aT, EquationScriptGeometry as aU, EquationSpanRecord as aV, EquationTextGeometry as aW, FieldAtomMarker as aX, FontFingerprintInputs as aY, FontResolutionErrorCode as a_, RevisionAuthorFilter as aa, FixedPoint as ab, FontByteValidator as ac, SourceRange as ad, HyperlinkProjector as ae, FieldLinkProjector as af, StoryPageFieldNeeds as ag, HyperlinkFieldSpec as ah, SpanLinkRecord as ai, PageGeometry as aj, SectionColumns as ak, SectionPageBorders as al, PageBorderFrameRecord as am, ParagraphBorderStrokeRecord as an, StrikeoutStrokePt as ao, AbstractNumDefinition as aq, AnchoredDrawingLayoutFallback as ar, BidiEmbeddingLevels as as, BorderGridGeometry as at, CascadedParagraphFormatting as au, CjkTypographySettings as av, ContentControlGeometryFragment as aw, ContentControlLevel as ax, ContentControlMappedType as ay, ContentControlModelRange as az, RevisionDisplayMode as b, SemanticArtifactRootStoryKind as b$, FontResourceInstrumentation as b0, FontResourceSnapshotOptions as b1, FontSlot as b2, FontValidationResult as b3, GlyphOutline as b4, GroupTextboxStoryRecord as b5, LevelOverride as b9, PageRefFieldProjection as bA, ParagraphAutoSpacingContext as bB, ParagraphBorderEdge as bC, ParagraphBorderSide as bD, ParagraphBorders as bE, ParagraphBottomBorderRecord as bF, ParagraphIndent as bG, ParagraphLayoutInputs as bH, ParagraphLineSpacing as bI, ParagraphSpacing as bJ, RefFieldSpec as bK, RefNoteParts as bL, ResolvedCellBorders as bM, ResolvedPictureBullet as bN, ResolvedTabStops as bO, ResolvedTableBorderEdge as bP, ResolvedTableBorderEdgeSegment as bQ, ResolvedUnderline as bR, RevisionFilter as bS, RevisionKind as bT, ScriptItem as bV, SectionBreakMarkRecord as bW, SectionBreakType as bX, SectionColumnDefinition as bY, SectionMargins as bZ, SectionPageNumbering as b_, LineSpacingRule as ba, ListMarkerAlign as bb, ListMarkerRecord as bc, ListSuffix as bd, NumDefinition as bp, NumberingLevelIndent as bq, NumberingPictureBullet as br, PageBorderDisplay as bu, PageBorderOffsetFrom as bv, PageBorderSide as bw, PageBorderStrokeRecord as bx, PageBorderZOrder as by, PageRefCalibrationCell as bz, PageRecord as c, SemanticArtifactStoryKind as c0, SemanticCommentArtifactRecord as c1, SemanticReviewArtifactOccurrence as c2, SemanticReviewArtifactOccurrenceGeometry as c3, SemanticReviewArtifactPosition as c4, SemanticReviewArtifactSource as c5, SemanticTrackedChangeArtifactRecord as c6, ShapeInput as c7, ShapedCluster as c8, ShapedFontSpan as c9, ShapedGlyph as ca, ShapedRunComparatorInputs as cb, ShapedVerticalMetrics as cc, ShapingContext as cd, ShapingEnvironment as ce, ShapingEnvironmentFingerprintInputs as cf, StyleDefinition as cg, TabAlignment as ci, TabDestination as cj, TabLeader as ck, TabStop as cl, TableBorderSideName as cm, TableBorderStrokeRecord as cn, TableFragmentRecord as co, TextDirection as cp, TextboxStoryFallbackReason as cq, TextboxStoryLayout as cr, VerticalAlign as ct, LayoutBox as d, NoteStoryRecord as e, ContentControlLock as f, StyleSpanRecord as g, TableRowFragmentRecord as h, TableCellFragmentRecord as i, ShapingEnvironmentInput as j, TextShaper as k, ResolvedRunStyle as l, ResolvedFont as m, NormalizationPolicy as n, FixedPointRoundingMode as o, FontRequest as p, ResolvedRevisionMarkup as q, SemanticReviewArtifactRecord as r, ListMarkerPictureRecord as s, RevisionMarkupOptions as t, FontSubstitution as u, ShapedRun as v, RevisionChangedLinesMark as x, RevisionDeletionMark as y, RevisionMarkupChromeHandlers as z };
|