@docx-editor.dev/core 2.21.1 → 2.22.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/README.md +11 -5
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +10 -10
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +8 -8
- package/dist/binding.js +1 -1
- package/dist/{chunk-BF2TOG2V.js → chunk-5RKCJ5DF.js} +1 -1
- package/dist/chunk-65GJRSZ5.cjs +18 -0
- package/dist/chunk-6TBRG6SA.cjs +20 -0
- package/dist/chunk-A72MJGY7.cjs +4 -0
- package/dist/chunk-AZ7QSAXH.js +4 -0
- package/dist/chunk-BL57VQ7E.js +1 -0
- package/dist/chunk-CB6RQ3GD.cjs +11 -0
- package/dist/chunk-GG4IAKFI.js +5 -0
- package/dist/chunk-HJYLFMLX.js +2 -0
- package/dist/chunk-HL6NO7IH.cjs +2 -0
- package/dist/chunk-HZQFGB2X.cjs +5 -0
- package/dist/{chunk-FPDIJ4RF.js → chunk-IWAUA732.js} +1 -1
- package/dist/chunk-OZXBAEWW.js +2 -0
- package/dist/{chunk-4TYA4RLP.cjs → chunk-P5PWSRNW.cjs} +1 -1
- package/dist/{chunk-DZYKU2HG.js → chunk-PD5XKBJA.js} +1 -1
- package/dist/{chunk-7N77EN2Z.cjs → chunk-REMFTPDL.cjs} +1 -1
- package/dist/{chunk-T5B4NMKF.cjs → chunk-RLKX7BIP.cjs} +1 -1
- package/dist/chunk-UGLO2GA5.cjs +1 -0
- package/dist/chunk-UOQONZVQ.js +11 -0
- package/dist/chunk-VD2MWTR6.js +20 -0
- package/dist/chunk-VIXH2OVP.js +1 -0
- package/dist/chunk-W2JIZ5JH.js +18 -0
- package/dist/chunk-W5H62AWM.cjs +1 -0
- package/dist/{chunk-E5OUYRNM.cjs → chunk-X2LJDR53.cjs} +5 -5
- package/dist/chunk-YQXY6TQ3.js +5 -0
- package/dist/{chunk-RA2TDTEQ.cjs → chunk-YYFBYVW4.cjs} +1 -1
- package/dist/collaboration/replication.cjs +1 -1
- package/dist/collaboration/replication.d.ts +4 -4
- package/dist/collaboration/replication.js +1 -1
- package/dist/collaboration.d.ts +3 -3
- package/dist/contracts/document.d.ts +2 -2
- package/dist/contracts/editor.d.ts +8 -8
- package/dist/contracts/modules.d.ts +6 -6
- package/dist/contracts/types.d.ts +1 -1
- package/dist/{custom-node-writes-CncR6KfC.d.ts → custom-node-writes-Ck6eOiJ3.d.ts} +2 -2
- package/dist/{document-protection-DM6mA8Rf.d.ts → document-protection-CMPEonQc.d.ts} +1 -1
- package/dist/{editor-BRh7GuZF.d.ts → editor-BKDVqXyk.d.ts} +70 -49
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.d.ts +188 -26
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +31 -14
- package/dist/export.js +2 -2
- package/dist/{font-resolver-DwuQYj3P.d.ts → font-resolver-PBc8Vuxs.d.ts} +1 -1
- package/dist/{headless-document-view-C3fc_jV0.d.ts → headless-document-view-9wjJT20Y.d.ts} +2 -2
- package/dist/{image-resources-DxF-SN_8.d.ts → image-resources-B0v-XaTM.d.ts} +2 -2
- package/dist/{index-3pNnG4z4.d.ts → index-DQA53aR1.d.ts} +134 -16
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +17 -17
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-_GGjhhVc.d.ts → layout-shaping-Dyr0ZSOI.d.ts} +5 -2
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +376 -33
- package/dist/layout.js +1 -1
- package/dist/{note-properties-CjT31AuP.d.ts → note-properties-D_lmG9xx.d.ts} +1 -1
- package/dist/{omml-equation-Bk3OP1fv.d.ts → omml-equation-CfTm3jOK.d.ts} +1 -1
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +7 -7
- package/dist/output.js +1 -1
- package/dist/{protocol-CrbTIW2Z.d.ts → protocol-CkVDxyQ3.d.ts} +2 -2
- package/dist/{review-paragraph-order-D3KZohIL.d.ts → review-paragraph-order-BjUs-tDd.d.ts} +1 -1
- package/dist/{revision-projection-kVd7p6Wd.d.ts → revision-projection-DDVBYTIG.d.ts} +1 -1
- package/dist/{semantic-cell-selection-CkSsZHDL.d.ts → semantic-cell-selection-DW6qsmoC.d.ts} +4 -4
- package/dist/{semantic-interaction-Z2Xa68U5.d.ts → semantic-interaction-BNiYSBcB.d.ts} +1 -1
- package/dist/{semantic-paint-BHKprI9P.d.ts → semantic-paint-DE236npp.d.ts} +2 -2
- package/dist/{semantic-records-StH-AnHK.d.ts → semantic-records-C5OeXnaL.d.ts} +545 -569
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +13 -13
- package/dist/store.js +1 -1
- package/dist/{tree-package-fragment-CpEV1gl3.d.ts → tree-package-fragment-DBb97w3F.d.ts} +2 -2
- package/dist/{tree-session-contract-CTT9nM7Z.d.ts → tree-session-contract-BYat3RKx.d.ts} +5 -5
- package/dist/{types-barrel-PwcfEkaX.d.ts → types-barrel-ChGvWjkO.d.ts} +3 -1
- package/package.json +2 -2
- package/dist/chunk-25OQBAKA.js +0 -2
- package/dist/chunk-3B3DQMSL.js +0 -11
- package/dist/chunk-3P3DNJYM.js +0 -5
- package/dist/chunk-3PA64KPK.js +0 -5
- package/dist/chunk-AGWWNVIJ.cjs +0 -1
- package/dist/chunk-DFTVN25X.cjs +0 -5
- package/dist/chunk-DGONGMAV.js +0 -2
- package/dist/chunk-F4H3LC6M.cjs +0 -2
- package/dist/chunk-IUTTOBQW.cjs +0 -20
- package/dist/chunk-IYCXQAFT.cjs +0 -4
- package/dist/chunk-JL3SI5SZ.js +0 -18
- package/dist/chunk-OFWUHH52.js +0 -20
- package/dist/chunk-OKY6JRJL.js +0 -4
- package/dist/chunk-P24FHMQW.cjs +0 -1
- package/dist/chunk-QBKAOSVF.cjs +0 -18
- package/dist/chunk-U5GUJKTS.js +0 -1
- package/dist/chunk-XRYSPKKC.js +0 -1
- package/dist/chunk-ZZRCVDQU.cjs +0 -11
|
@@ -1,7 +1,85 @@
|
|
|
1
|
-
import { c as RevisionAttribution, a as RevisionDisplayMode
|
|
2
|
-
import { a0 as OoxmlProperty, a1 as OoxmlElement, i as OoxmlNode, O as OoxmlPart, aG as TableBorderStyle, aH as DrawingAccessibility, aI as DrawingImageEffects,
|
|
3
|
-
import {
|
|
4
|
-
import { O as OmmlEquationProjection } from './omml-equation-
|
|
1
|
+
import { c as RevisionAttribution, a as RevisionDisplayMode } from './revision-projection-DDVBYTIG.js';
|
|
2
|
+
import { a0 as OoxmlProperty, a1 as OoxmlElement, i as OoxmlNode, O as OoxmlPart, aG as TableBorderStyle, aH as DrawingAccessibility, aI as DrawingImageEffects, a8 as SourceCrop, aJ as DrawingTransform, aK as VectorShapeProjection, aj as DrawingHorizontalReferenceFrame, ak as DrawingVerticalReferenceFrame, aa as ImageWrapTarget, a4 as DrawingProjection, aL as OoxmlDrawingNode } from './types-barrel-ChGvWjkO.js';
|
|
3
|
+
import { b as ImageResourceState } from './image-resources-B0v-XaTM.js';
|
|
4
|
+
import { O as OmmlEquationProjection } from './omml-equation-CfTm3jOK.js';
|
|
5
|
+
|
|
6
|
+
/** A strikeout stroke at the drawn size, in points. `offsetPt` is the stroke TOP. @public */
|
|
7
|
+
interface StrikeoutStrokePt {
|
|
8
|
+
/** Distance from the baseline UP to the top of the stroke. */
|
|
9
|
+
readonly offsetPt: number;
|
|
10
|
+
/** Stroke height. Always positive. */
|
|
11
|
+
readonly thicknessPt: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `w:tblpPr/@w:horzAnchor` (17.4.58) and `@w:vertAnchor` (17.4.66): the box a floated
|
|
16
|
+
* table's offsets are measured from. Absent means `text` for both.
|
|
17
|
+
*/
|
|
18
|
+
type TableFloatAnchor = 'text' | 'margin' | 'page';
|
|
19
|
+
/** `w:tblpPr/@w:tblpXSpec` (17.4.63, ST_XAlign). */
|
|
20
|
+
type TableFloatXSpec = 'left' | 'center' | 'right' | 'inside' | 'outside';
|
|
21
|
+
/** `w:tblpPr/@w:tblpYSpec` (17.4.65, ST_YAlign). */
|
|
22
|
+
type TableFloatYSpec = 'inline' | 'top' | 'center' | 'bottom' | 'inside' | 'outside';
|
|
23
|
+
/**
|
|
24
|
+
* `w:tblPr/w:tblpPr` (17.4.57) — a table positioned against an anchor box rather than at
|
|
25
|
+
* the point in the text where it was authored.
|
|
26
|
+
*
|
|
27
|
+
* A spec (`tblpXSpec`/`tblpYSpec`) supersedes the matching offset when both are present:
|
|
28
|
+
* 17.4.57 states the alignment outright, and the offset only answers "how far from the
|
|
29
|
+
* anchor" for the case where no alignment was stated.
|
|
30
|
+
*/
|
|
31
|
+
interface TableFloatPosition {
|
|
32
|
+
readonly horzAnchor: TableFloatAnchor;
|
|
33
|
+
readonly vertAnchor: TableFloatAnchor;
|
|
34
|
+
readonly xSpec?: TableFloatXSpec;
|
|
35
|
+
/** `w:tblpX` in points; signed, so a table can be pulled into the margin. */
|
|
36
|
+
readonly xPt: number;
|
|
37
|
+
readonly ySpec?: TableFloatYSpec;
|
|
38
|
+
/** `w:tblpY` in points; signed. */
|
|
39
|
+
readonly yPt: number;
|
|
40
|
+
readonly distances?: {
|
|
41
|
+
readonly top: number;
|
|
42
|
+
readonly right: number;
|
|
43
|
+
readonly bottom: number;
|
|
44
|
+
readonly left: number;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* One `w:numPicBullet`: the image a level draws instead of its `w:lvlText`.
|
|
50
|
+
*
|
|
51
|
+
* `relationshipId` is unresolved on purpose — it names a relationship of the numbering part,
|
|
52
|
+
* and resolving it is the image-resource lookup's job, under its own validation and caps.
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
interface NumberingPictureBullet {
|
|
56
|
+
/** `w:numPicBulletId` — what a level's `w:lvlPicBulletId` names. */
|
|
57
|
+
readonly picBulletId: string;
|
|
58
|
+
/** `v:imagedata/@r:id`, relative to the NUMBERING part's relationships. */
|
|
59
|
+
readonly relationshipId: string;
|
|
60
|
+
/** Authored `v:shape` width in points. */
|
|
61
|
+
readonly width: number;
|
|
62
|
+
/** Authored `v:shape` height in points. */
|
|
63
|
+
readonly height: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A level's picture bullet with the size it is actually DRAWN at.
|
|
67
|
+
*
|
|
68
|
+
* Separate from {@link NumberingPictureBullet} because the authored `v:shape` extent is not
|
|
69
|
+
* the painted extent: Word scales it by the marker run's font size. Layout, hit testing and
|
|
70
|
+
* both paint sinks read `width` / `height`; `authored` is kept so the scale stays inspectable.
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
interface ResolvedPictureBullet {
|
|
74
|
+
/** `v:imagedata/@r:id`, relative to the NUMBERING part's relationships. */
|
|
75
|
+
readonly relationshipId: string;
|
|
76
|
+
/** Painted width in points, after the marker font scale. */
|
|
77
|
+
readonly width: number;
|
|
78
|
+
/** Painted height in points, after the marker font scale. */
|
|
79
|
+
readonly height: number;
|
|
80
|
+
/** The `v:shape` extent exactly as the file authored it. */
|
|
81
|
+
readonly authored: NumberingPictureBullet;
|
|
82
|
+
}
|
|
5
83
|
|
|
6
84
|
/** Soft ceiling on abstractNum / num entries read from one part. */
|
|
7
85
|
declare const MAX_NUMBERING_DEFINITIONS = 512;
|
|
@@ -63,6 +141,11 @@ interface NumberingLevel {
|
|
|
63
141
|
* decimal, whatever number format those levels declare for themselves.
|
|
64
142
|
*/
|
|
65
143
|
readonly isLgl: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* `w:lvlPicBulletId` (§17.9.12): this level's marker is the `w:numPicBullet` of that id,
|
|
146
|
+
* drawn INSTEAD of `w:lvlText`. Absent on every ordinary level.
|
|
147
|
+
*/
|
|
148
|
+
readonly picBulletId?: string;
|
|
66
149
|
/** Level `w:rPr` as flat properties (for marker face / vanish). */
|
|
67
150
|
readonly runProperties: readonly OoxmlProperty[];
|
|
68
151
|
/** True when level run props request vanish — marker must not paint. */
|
|
@@ -119,6 +202,13 @@ interface NumDefinition {
|
|
|
119
202
|
interface NumberingIndex {
|
|
120
203
|
readonly abstractNums: ReadonlyMap<string, AbstractNumDefinition>;
|
|
121
204
|
readonly nums: ReadonlyMap<string, NumDefinition>;
|
|
205
|
+
/**
|
|
206
|
+
* `w:numPicBullet` declarations keyed by `w:numPicBulletId` (§17.9.20).
|
|
207
|
+
*
|
|
208
|
+
* Optional so a hand-built index stays valid; absent reads as "this part declares none",
|
|
209
|
+
* which is what a level's `w:lvlPicBulletId` then falls back from.
|
|
210
|
+
*/
|
|
211
|
+
readonly pictureBullets?: ReadonlyMap<string, NumberingPictureBullet>;
|
|
122
212
|
}
|
|
123
213
|
/**
|
|
124
214
|
* Build a numbering index from the root of a numbering part (`w:numbering`).
|
|
@@ -148,114 +238,257 @@ declare function resolveNumberingLevel(index: NumberingIndex, numId: string, ilv
|
|
|
148
238
|
/** Empty index for tests / documents without numbering. */
|
|
149
239
|
declare const EMPTY_NUMBERING_INDEX: NumberingIndex;
|
|
150
240
|
|
|
151
|
-
/** Soft ceiling matching Word's practical custom-tab UI limit. */
|
|
152
|
-
declare const MAX_TAB_STOPS = 64;
|
|
153
241
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
242
|
+
* Whether a paragraph must start a new page (`w:pageBreakBefore`).
|
|
243
|
+
*
|
|
244
|
+
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
245
|
+
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
246
|
+
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
247
|
+
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
248
|
+
* page number after it was wrong.
|
|
249
|
+
*
|
|
250
|
+
* An absent `w:val` is on (§17.17.4), and the off vocabulary is the whole of it — `off` is a
|
|
251
|
+
* spelling too, which {@link isOn} beside this already accepts.
|
|
156
252
|
*/
|
|
157
|
-
declare
|
|
158
|
-
/** OOXML / Word default when `w:settings/w:defaultTabStop` is absent: 720 twips = 0.5". */
|
|
159
|
-
declare const DEFAULT_TAB_INTERVAL_TWIPS = 720;
|
|
160
|
-
/** The default tab interval in points — {@link DEFAULT_TAB_INTERVAL_TWIPS} converted. */
|
|
161
|
-
declare const DEFAULT_TAB_INTERVAL_PT: number;
|
|
253
|
+
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
162
254
|
/**
|
|
163
|
-
*
|
|
255
|
+
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
256
|
+
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
257
|
+
*/
|
|
258
|
+
declare const MAX_PARAGRAPH_SPACING_PT: number;
|
|
259
|
+
/** Soft ceiling on border width (96 eighths = 12pt). Word's UI tops out well below this. */
|
|
260
|
+
declare const MAX_BORDER_WIDTH_PT = 12;
|
|
261
|
+
/** Soft ceiling on border-to-text gap (`w:space`, already in points). */
|
|
262
|
+
declare const MAX_BORDER_SPACE_PT = 3168;
|
|
263
|
+
/**
|
|
264
|
+
* A paragraph's resolved space before and after, in points.
|
|
164
265
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
266
|
+
* Already collapsed against `w:contextualSpacing`, so adjacent same-style paragraphs that suppress
|
|
267
|
+
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
167
268
|
*/
|
|
168
|
-
|
|
269
|
+
interface ParagraphSpacing {
|
|
270
|
+
/** `w:spacing/@before`, in points. */
|
|
271
|
+
readonly before: number;
|
|
272
|
+
/** `w:spacing/@after`, in points. */
|
|
273
|
+
readonly after: number;
|
|
274
|
+
}
|
|
169
275
|
/**
|
|
170
|
-
* `w:
|
|
171
|
-
*
|
|
276
|
+
* The gap Word substitutes when `w:beforeAutospacing` / `w:afterAutospacing` is on
|
|
277
|
+
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
172
278
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
279
|
+
* The attribute means "the consumer decides", and the authored `@before` / `@after` beside it
|
|
280
|
+
* is IGNORED rather than used as the value. Word's answer is HTML's default `<p>` margin,
|
|
281
|
+
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
282
|
+
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
283
|
+
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
176
284
|
*/
|
|
177
|
-
|
|
285
|
+
declare const AUTO_PARAGRAPH_SPACING_PT = 14;
|
|
178
286
|
/**
|
|
179
|
-
*
|
|
287
|
+
* Where a paragraph sits, for the contexts in which Word's auto spacing resolves to 0
|
|
288
|
+
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
180
289
|
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
290
|
+
* This resolves the interior list-item value. Body layout restores each outer list margin
|
|
291
|
+
* in `resolveListAutoSpacing`, where neighboring blocks are available. A caller that says
|
|
292
|
+
* nothing gets the body answer.
|
|
293
|
+
*
|
|
294
|
+
* A TABLE CELL is not such a context. Measured on a captured control at 10pt, where the
|
|
295
|
+
* line pitch is 11.52pt: the reference puts 26.16pt between two paragraphs in the body with
|
|
296
|
+
* auto spacing on, and the SAME 26.16pt between two paragraphs inside a cell. With an empty
|
|
297
|
+
* paragraph between them it is 52.32, exactly twice. Reading it as 0 in a cell lays every
|
|
298
|
+
* such paragraph 13.92pt tight, which is enough to pull a signature block back onto the
|
|
299
|
+
* previous page. See `.cache/pdf/claude-autospacing/`.
|
|
184
300
|
*/
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
readonly
|
|
301
|
+
interface ParagraphAutoSpacingContext {
|
|
302
|
+
/** The paragraph participates in numbering (`w:numPr`), i.e. it is a list item. */
|
|
303
|
+
readonly inList?: boolean;
|
|
304
|
+
/**
|
|
305
|
+
* The paragraph lives in a table cell. Kept because callers describe position with it and
|
|
306
|
+
* list resolution reads it; it does NOT zero auto spacing.
|
|
307
|
+
*/
|
|
308
|
+
readonly inTableCell?: boolean;
|
|
309
|
+
/** Section grid pitch in points; no grid uses Word's fixed 12pt line unit. */
|
|
310
|
+
readonly lineUnitPt?: number;
|
|
193
311
|
}
|
|
194
312
|
/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
313
|
+
* Resolved line spacing (`w:spacing/@line` + `@lineRule`, ECMA-376 17.3.1.33).
|
|
314
|
+
*
|
|
315
|
+
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
316
|
+
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
317
|
+
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
318
|
+
* moves every page break, so this is not a cosmetic detail.
|
|
319
|
+
*
|
|
320
|
+
* `exact` fixes the line box at `@line` twips and lets tall glyphs clip, the way Word
|
|
321
|
+
* does. `atLeast` uses it as a floor.
|
|
197
322
|
*/
|
|
198
|
-
|
|
199
|
-
/** Custom stops sorted by ascending position. */
|
|
200
|
-
readonly stops: readonly TabStop[];
|
|
201
|
-
/** Default-tab interval in points (always positive and bounded). */
|
|
202
|
-
readonly defaultIntervalPt: number;
|
|
203
|
-
}
|
|
204
|
-
/** The frozen "no custom stops" value, so a paragraph without tabs mints no object. */
|
|
205
|
-
declare const EMPTY_TAB_STOPS: ResolvedTabStops;
|
|
323
|
+
type LineSpacingRule = 'auto' | 'exact' | 'atLeast';
|
|
206
324
|
/**
|
|
207
|
-
*
|
|
325
|
+
* Resolved line spacing: the rule, and the value it applies.
|
|
208
326
|
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
327
|
+
* `value` means different things per rule — 240ths of a line under `auto`, points under `exact`
|
|
328
|
+
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
211
329
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
330
|
+
interface ParagraphLineSpacing {
|
|
331
|
+
readonly rule: LineSpacingRule;
|
|
332
|
+
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
333
|
+
readonly value: number;
|
|
334
|
+
/** Legacy noExtraLineSpacing: retain the natural baseline within an exact-height box. */
|
|
335
|
+
readonly preserveExactBaseline?: true;
|
|
336
|
+
}
|
|
337
|
+
/** Single spacing: what a paragraph that says nothing gets. */
|
|
338
|
+
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
215
339
|
/**
|
|
216
|
-
*
|
|
340
|
+
* One resolved `w:pBdr` edge: its style, colour, thickness and gap.
|
|
217
341
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* the input unchanged when nothing moves, so a cache-key fingerprint stays stable.
|
|
342
|
+
* `widthPt` and `spacePt` are already converted and CLAMPED — both come from a file, and an
|
|
343
|
+
* unbounded border width becomes a layout dimension.
|
|
221
344
|
*/
|
|
222
|
-
|
|
345
|
+
interface ParagraphBorderEdge {
|
|
346
|
+
/** Authored `ST_Border` value (`single`, `dashed`, …). */
|
|
347
|
+
readonly val: string;
|
|
348
|
+
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
349
|
+
readonly color: string | null;
|
|
350
|
+
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
351
|
+
readonly widthPt: number;
|
|
352
|
+
/** Gap from text to the rule, in points (`w:space`). */
|
|
353
|
+
readonly spacePt: number;
|
|
354
|
+
/**
|
|
355
|
+
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
356
|
+
*
|
|
357
|
+
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
358
|
+
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
359
|
+
*/
|
|
360
|
+
readonly shadow?: true;
|
|
361
|
+
}
|
|
362
|
+
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
363
|
+
declare const PARAGRAPH_BORDER_SIDES: readonly ["top", "left", "bottom", "right", "between", "bar"];
|
|
223
364
|
/**
|
|
224
|
-
*
|
|
365
|
+
* Which of the six `CT_PBdr` edges.
|
|
225
366
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
|
|
229
|
-
|
|
367
|
+
* Four are physical box edges; `between` and `bar` are group-relative, drawn only where
|
|
368
|
+
* consecutive paragraphs share a border definition.
|
|
369
|
+
*/
|
|
370
|
+
type ParagraphBorderSide = (typeof PARAGRAPH_BORDER_SIDES)[number];
|
|
371
|
+
/**
|
|
372
|
+
* A paragraph's resolved `w:pBdr` (ECMA-376 §17.3.1.24).
|
|
230
373
|
*
|
|
231
|
-
* `
|
|
232
|
-
*
|
|
374
|
+
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
375
|
+
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
376
|
+
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
377
|
+
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
233
378
|
*/
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
readonly
|
|
238
|
-
readonly
|
|
239
|
-
|
|
240
|
-
readonly
|
|
379
|
+
interface ParagraphBorders {
|
|
380
|
+
readonly top?: ParagraphBorderEdge;
|
|
381
|
+
readonly left?: ParagraphBorderEdge;
|
|
382
|
+
readonly bottom?: ParagraphBorderEdge;
|
|
383
|
+
readonly right?: ParagraphBorderEdge;
|
|
384
|
+
readonly between?: ParagraphBorderEdge;
|
|
385
|
+
readonly bar?: ParagraphBorderEdge;
|
|
241
386
|
}
|
|
242
387
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
388
|
+
* Resolve `w:spacing` before/after from flat paragraph properties.
|
|
389
|
+
*
|
|
390
|
+
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
391
|
+
* height, not the gap between paragraphs — and is not resolved here.
|
|
392
|
+
*
|
|
393
|
+
* `w:beforeAutospacing` / `w:afterAutospacing` REPLACE the authored measurement on their own
|
|
394
|
+
* side rather than adding to it; see {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
245
395
|
*/
|
|
246
|
-
declare function
|
|
396
|
+
declare function paragraphSpacing(props: readonly OoxmlProperty[], context?: ParagraphAutoSpacingContext): ParagraphSpacing;
|
|
247
397
|
/**
|
|
248
|
-
*
|
|
398
|
+
* Resolve `w:line` / `w:lineRule` from flat paragraph properties.
|
|
249
399
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
400
|
+
* Merged per attribute for the same reason as before/after: `w:spacing` is one element
|
|
401
|
+
* carrying independent attributes, and a style that states only `@line` must not reset the
|
|
402
|
+
* rule an earlier entry in the cascade set.
|
|
252
403
|
*/
|
|
253
|
-
declare function
|
|
404
|
+
declare function paragraphLineSpacing(props: readonly OoxmlProperty[]): ParagraphLineSpacing;
|
|
254
405
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
406
|
+
* Apply resolved line spacing to a line's natural (glyph-derived) box.
|
|
407
|
+
*
|
|
408
|
+
* `auto` places its extra BELOW the line — the last line's multiple spacing still separates
|
|
409
|
+
* it from the next paragraph. Putting that delta above inverted cover-page rhythm:
|
|
410
|
+
* `w:line="460"` on "between" opened a large gap above the word and almost none before
|
|
411
|
+
* "MERIDIAN".
|
|
412
|
+
*
|
|
413
|
+
* `atLeast` does the OPPOSITE: the box grows upward and the glyphs sit on its floor. A
|
|
414
|
+
* captured control settles it — Times New Roman 12 pt at `w:line="360" w:lineRule="atLeast"`
|
|
415
|
+
* puts the reference's baseline at 15.36 pt, which is `18 - descent` snapped to the device
|
|
416
|
+
* grid, where treating it like `auto` leaves the baseline at 11.28 and the text 4.08 pt too
|
|
417
|
+
* high. `w:line="240" atLeast` is below the natural line, falls through to the natural
|
|
418
|
+
* height, and is unaffected. See `.cache/pdf/claude-linerule/`.
|
|
419
|
+
*
|
|
420
|
+
* Exact-height boxes place their baseline at 80% of the height; the legacy
|
|
421
|
+
* noExtraLineSpacing switch instead preserves the face baseline within the box.
|
|
257
422
|
*/
|
|
258
|
-
declare function
|
|
423
|
+
declare function applyLineSpacing(spacing: ParagraphLineSpacing, naturalHeight: number, naturalBaseline: number): {
|
|
424
|
+
height: number;
|
|
425
|
+
baseline: number;
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* `w:contextualSpacing` (17.3.1.9): drop before/after between paragraphs of the SAME
|
|
429
|
+
* style. Word's built-in `ListParagraph` sets it, so every list authored in Word gets a
|
|
430
|
+
* paragraph gap between items without this.
|
|
431
|
+
*/
|
|
432
|
+
declare function paragraphContextualSpacing(props: readonly OoxmlProperty[]): boolean;
|
|
433
|
+
/**
|
|
434
|
+
* Resolve `w:pBdr` from the paragraph-properties node.
|
|
435
|
+
*
|
|
436
|
+
* Nested — every edge is a child of `pBdr`, not an attribute — so this reads the typed tree
|
|
437
|
+
* rather than the flattened `OoxmlProperty[]` bag `propertiesOf` builds for leaf props.
|
|
438
|
+
*/
|
|
439
|
+
declare function paragraphBorders(pPr: OoxmlNode | undefined): ParagraphBorders;
|
|
440
|
+
/**
|
|
441
|
+
* `w:pBdr` after the style cascade: a later `w:pBdr` replaces an earlier one WHOLESALE.
|
|
442
|
+
*
|
|
443
|
+
* Word does not merge edges across the cascade. A style that states only `w:bottom` discards
|
|
444
|
+
* the box its `basedOn` ancestor declared, so folding edge by edge would leave a lone
|
|
445
|
+
* underline surrounded by a box no one authored. Absence inherits; `nil`/`none` clear.
|
|
446
|
+
*/
|
|
447
|
+
declare function cascadedParagraphBorders(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorders;
|
|
448
|
+
/**
|
|
449
|
+
* Visual stroke thickness layout publishes for one edge (points).
|
|
450
|
+
*
|
|
451
|
+
* Compound `ST_Border` values (`double`, …) use the shared inflated band so a thin
|
|
452
|
+
* `w:sz="3"` double still occupies a visible double-line box — matching table borders.
|
|
453
|
+
*/
|
|
454
|
+
declare function paragraphBorderStrokeWidthPt(edge: ParagraphBorderEdge): number;
|
|
455
|
+
/**
|
|
456
|
+
* Extent one border edge occupies away from the text it decorates: gap plus rule, in points.
|
|
457
|
+
*
|
|
458
|
+
* Vertically that is flow height — a top rule pushes the first line down, a bottom rule holds
|
|
459
|
+
* the page open below the last one — so pagination has to see it. Horizontally it is
|
|
460
|
+
* publish-only: Word draws left/right paragraph rules OUTSIDE the text column and never
|
|
461
|
+
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
462
|
+
*/
|
|
463
|
+
declare function paragraphBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
464
|
+
/** Vertical extent a bottom border adds below the last line (gap + rule). */
|
|
465
|
+
declare function bottomBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
466
|
+
/**
|
|
467
|
+
* Identity of a paragraph's border set, for the `w:between` group rule.
|
|
468
|
+
*
|
|
469
|
+
* Word treats consecutive paragraphs whose border settings are IDENTICAL as ONE bordered
|
|
470
|
+
* block: the top rule draws above the first, the bottom rule below the last, and each
|
|
471
|
+
* interior boundary gets `w:between` or nothing (§17.3.1.24). That is why applying a box to
|
|
472
|
+
* three selected paragraphs in Word draws one box and not three.
|
|
473
|
+
*
|
|
474
|
+
* Empty string means "no borders", which never groups with anything.
|
|
475
|
+
*/
|
|
476
|
+
declare function paragraphBordersFingerprint(borders: ParagraphBorders): string;
|
|
477
|
+
/**
|
|
478
|
+
* Gap to insert before a paragraph once the previous paragraph's `after` is already in the
|
|
479
|
+
* flow cursor — Word takes the larger of the two rather than summing them.
|
|
480
|
+
*/
|
|
481
|
+
declare function collapsedSpaceBefore(before: number, previousAfter: number): number;
|
|
482
|
+
/**
|
|
483
|
+
* Applied before-spacing for placement (Word 2013+ / compat mode 15).
|
|
484
|
+
*
|
|
485
|
+
* Adjacent before/after still collapse to the larger gap, but before is dropped entirely when
|
|
486
|
+
* the paragraph naturally moves to the top of a page mid-section. An explicit page-break-before
|
|
487
|
+
* paragraph, or the first paragraph of a document/section, retains before. Callers publish this
|
|
488
|
+
* applied value on the fragment so shading, borders,
|
|
489
|
+
* selection, and paint share one geometry.
|
|
490
|
+
*/
|
|
491
|
+
declare function appliedSpaceBefore(before: number, previousAfter: number, atTopOfPage: boolean, preserveAtPageStart: boolean): number;
|
|
259
492
|
|
|
260
493
|
/** `w:vertAlign` — script position, which also scales the run's effective size. */
|
|
261
494
|
type VerticalAlign = 'baseline' | 'superscript' | 'subscript';
|
|
@@ -304,6 +537,8 @@ interface ResolvedRunStyle {
|
|
|
304
537
|
readonly widthPt: number;
|
|
305
538
|
readonly color: string;
|
|
306
539
|
};
|
|
540
|
+
/** Character border; adjacent runs with matching edges share one outline. */
|
|
541
|
+
readonly border?: ParagraphBorderEdge;
|
|
307
542
|
readonly italic: boolean;
|
|
308
543
|
readonly underline: ResolvedUnderline | null;
|
|
309
544
|
readonly strike: boolean;
|
|
@@ -326,8 +561,17 @@ interface ResolvedRunStyle {
|
|
|
326
561
|
readonly characterSpacingPt: number;
|
|
327
562
|
/** `w:w`, as a percentage. 100 is unscaled. */
|
|
328
563
|
readonly horizontalScalePercent: number;
|
|
329
|
-
/** `w:kern`, in points: the size at or above which kerning applies.
|
|
564
|
+
/** `w:kern`, in points: the size at or above which kerning applies. */
|
|
330
565
|
readonly kerningMinPt: number;
|
|
566
|
+
/** Explicit kerning selection; a zero threshold disables it. Absent uses a positive threshold. */
|
|
567
|
+
readonly kerningEnabled?: boolean;
|
|
568
|
+
/** Resolved optional OpenType substitutions; required script ligatures are independent. */
|
|
569
|
+
readonly ligatures?: {
|
|
570
|
+
readonly standard: boolean;
|
|
571
|
+
readonly contextual: boolean;
|
|
572
|
+
readonly historical: boolean;
|
|
573
|
+
readonly discretionary: boolean;
|
|
574
|
+
};
|
|
331
575
|
/**
|
|
332
576
|
* `w:vanish` (ECMA-376 §17.3.2.45): the run is hidden text.
|
|
333
577
|
*
|
|
@@ -391,6 +635,16 @@ declare function runStylesEqual(a: ResolvedRunStyle, b: ResolvedRunStyle): boole
|
|
|
391
635
|
* painter, and the caret — has to apply this itself, and from one place, or the two drift.
|
|
392
636
|
*/
|
|
393
637
|
declare function baselineShiftPtOf(style: ResolvedRunStyle): number;
|
|
638
|
+
/**
|
|
639
|
+
* Shared glyph-size factor for baseline, superscript, and subscript text.
|
|
640
|
+
*
|
|
641
|
+
* The 65% script scale follows the common Word font metrics (Arial, Calibri, Times New
|
|
642
|
+
* Roman) and improves the saved Word reference at 10pt and 11pt. It is a uniform policy;
|
|
643
|
+
* per-face script metrics and Word's output-device rounding are not modeled here.
|
|
644
|
+
* Layout, surface paint, and exporters must apply the same factor to avoid caret drift.
|
|
645
|
+
* @public
|
|
646
|
+
*/
|
|
647
|
+
declare function glyphSizeFactorOf(style: ResolvedRunStyle): number;
|
|
394
648
|
|
|
395
649
|
/**
|
|
396
650
|
* UAX #9 embedding levels, one per UTF-16 code unit, plus the paragraph ranges they were resolved
|
|
@@ -677,6 +931,8 @@ interface ShapeInput {
|
|
|
677
931
|
*/
|
|
678
932
|
interface ShapedGlyph {
|
|
679
933
|
readonly id: number;
|
|
934
|
+
/** Optional synthetic glyph-size factor; positions and advances already include it. */
|
|
935
|
+
readonly drawScale?: number;
|
|
680
936
|
/** UTF-16 text offset identifying the cluster that produced this glyph. */
|
|
681
937
|
readonly cluster: number;
|
|
682
938
|
/** Pen origin before this glyph's shaping offsets, in fixed-point run coordinates. */
|
|
@@ -749,6 +1005,19 @@ interface ShapedRun {
|
|
|
749
1005
|
readonly clusters: readonly ShapedCluster[];
|
|
750
1006
|
readonly fontSpans: readonly ShapedFontSpan[];
|
|
751
1007
|
readonly metrics: ShapedVerticalMetrics;
|
|
1008
|
+
/**
|
|
1009
|
+
* The same horizontal advances as `glyphs[i].advanceX`, in the same fixed-point units, but
|
|
1010
|
+
* BEFORE the per-glyph rounding to the fixed-point grid. Parallel to `glyphs`.
|
|
1011
|
+
*
|
|
1012
|
+
* Measurement and line breaking read `advanceX` and must keep doing so: pagination is decided
|
|
1013
|
+
* on those numbers, and two runs shaped identically have to compare equal. A painter that
|
|
1014
|
+
* gives every glyph its own absolute position sums the advances instead, and a sum of ROUNDED
|
|
1015
|
+
* advances drifts by up to half a fixed-point unit per glyph — an error that only grows along
|
|
1016
|
+
* a line. Summing these and rounding once, at the position actually written, does not.
|
|
1017
|
+
*
|
|
1018
|
+
* Absent on runs an assembly path cannot state exactly; a reader falls back to `originX`.
|
|
1019
|
+
*/
|
|
1020
|
+
readonly exactAdvancesX?: readonly number[];
|
|
752
1021
|
}
|
|
753
1022
|
/**
|
|
754
1023
|
* A {@link ShapedRun} reduced to the fields two shaping results must agree on to be considered
|
|
@@ -1143,236 +1412,116 @@ interface CjkTypographySettings {
|
|
|
1143
1412
|
readonly after: Readonly<Record<string, string>>;
|
|
1144
1413
|
}
|
|
1145
1414
|
|
|
1415
|
+
/** Soft ceiling matching Word's practical custom-tab UI limit. */
|
|
1416
|
+
declare const MAX_TAB_STOPS = 64;
|
|
1146
1417
|
/**
|
|
1147
|
-
*
|
|
1148
|
-
*
|
|
1149
|
-
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
1150
|
-
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
1151
|
-
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
1152
|
-
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
1153
|
-
* page number after it was wrong.
|
|
1154
|
-
*
|
|
1155
|
-
* An absent `w:val` is on (§17.17.4), and the off vocabulary is the whole of it — `off` is a
|
|
1156
|
-
* spelling too, which {@link isOn} beside this already accepts.
|
|
1157
|
-
*/
|
|
1158
|
-
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
1159
|
-
/**
|
|
1160
|
-
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
1161
|
-
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
1162
|
-
*/
|
|
1163
|
-
declare const MAX_PARAGRAPH_SPACING_PT: number;
|
|
1164
|
-
/** Soft ceiling on border width (96 eighths = 12pt). Word's UI tops out well below this. */
|
|
1165
|
-
declare const MAX_BORDER_WIDTH_PT = 12;
|
|
1166
|
-
/** Soft ceiling on border-to-text gap (`w:space`, already in points). */
|
|
1167
|
-
declare const MAX_BORDER_SPACE_PT = 3168;
|
|
1168
|
-
/**
|
|
1169
|
-
* A paragraph's resolved space before and after, in points.
|
|
1170
|
-
*
|
|
1171
|
-
* Already collapsed against `w:contextualSpacing`, so adjacent same-style paragraphs that suppress
|
|
1172
|
-
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
1173
|
-
*/
|
|
1174
|
-
interface ParagraphSpacing {
|
|
1175
|
-
/** `w:spacing/@before`, in points. */
|
|
1176
|
-
readonly before: number;
|
|
1177
|
-
/** `w:spacing/@after`, in points. */
|
|
1178
|
-
readonly after: number;
|
|
1179
|
-
}
|
|
1180
|
-
/**
|
|
1181
|
-
* The gap Word substitutes when `w:beforeAutospacing` / `w:afterAutospacing` is on
|
|
1182
|
-
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
1183
|
-
*
|
|
1184
|
-
* The attribute means "the consumer decides", and the authored `@before` / `@after` beside it
|
|
1185
|
-
* is IGNORED rather than used as the value. Word's answer is HTML's default `<p>` margin,
|
|
1186
|
-
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
1187
|
-
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
1188
|
-
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
1189
|
-
*/
|
|
1190
|
-
declare const AUTO_PARAGRAPH_SPACING_PT = 14;
|
|
1191
|
-
/**
|
|
1192
|
-
* Where a paragraph sits, for the contexts in which Word's auto spacing resolves to 0
|
|
1193
|
-
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
1194
|
-
*
|
|
1195
|
-
* This resolves the interior list-item or table-cell value. Body layout restores each
|
|
1196
|
-
* outer list margin in `resolveListAutoSpacing`, where neighboring blocks are available.
|
|
1197
|
-
* A caller that says nothing gets the body answer.
|
|
1198
|
-
*/
|
|
1199
|
-
interface ParagraphAutoSpacingContext {
|
|
1200
|
-
/** The paragraph participates in numbering (`w:numPr`), i.e. it is a list item. */
|
|
1201
|
-
readonly inList?: boolean;
|
|
1202
|
-
/** The paragraph lives in a table cell. */
|
|
1203
|
-
readonly inTableCell?: boolean;
|
|
1204
|
-
/** Section grid pitch in points; no grid uses Word's fixed 12pt line unit. */
|
|
1205
|
-
readonly lineUnitPt?: number;
|
|
1206
|
-
}
|
|
1207
|
-
/**
|
|
1208
|
-
* Resolved line spacing (`w:spacing/@line` + `@lineRule`, ECMA-376 17.3.1.33).
|
|
1209
|
-
*
|
|
1210
|
-
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
1211
|
-
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
1212
|
-
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
1213
|
-
* moves every page break, so this is not a cosmetic detail.
|
|
1214
|
-
*
|
|
1215
|
-
* `exact` fixes the line box at `@line` twips and lets tall glyphs clip, the way Word
|
|
1216
|
-
* does. `atLeast` uses it as a floor.
|
|
1217
|
-
*/
|
|
1218
|
-
type LineSpacingRule = 'auto' | 'exact' | 'atLeast';
|
|
1219
|
-
/**
|
|
1220
|
-
* Resolved line spacing: the rule, and the value it applies.
|
|
1221
|
-
*
|
|
1222
|
-
* `value` means different things per rule — 240ths of a line under `auto`, points under `exact`
|
|
1223
|
-
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
1224
|
-
*/
|
|
1225
|
-
interface ParagraphLineSpacing {
|
|
1226
|
-
readonly rule: LineSpacingRule;
|
|
1227
|
-
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
1228
|
-
readonly value: number;
|
|
1229
|
-
}
|
|
1230
|
-
/** Single spacing: what a paragraph that says nothing gets. */
|
|
1231
|
-
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
1232
|
-
/**
|
|
1233
|
-
* One resolved `w:pBdr` edge: its style, colour, thickness and gap.
|
|
1234
|
-
*
|
|
1235
|
-
* `widthPt` and `spacePt` are already converted and CLAMPED — both come from a file, and an
|
|
1236
|
-
* unbounded border width becomes a layout dimension.
|
|
1237
|
-
*/
|
|
1238
|
-
interface ParagraphBorderEdge {
|
|
1239
|
-
/** Authored `ST_Border` value (`single`, `dashed`, …). */
|
|
1240
|
-
readonly val: string;
|
|
1241
|
-
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
1242
|
-
readonly color: string | null;
|
|
1243
|
-
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
1244
|
-
readonly widthPt: number;
|
|
1245
|
-
/** Gap from text to the rule, in points (`w:space`). */
|
|
1246
|
-
readonly spacePt: number;
|
|
1247
|
-
/**
|
|
1248
|
-
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
1249
|
-
*
|
|
1250
|
-
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
1251
|
-
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
1252
|
-
*/
|
|
1253
|
-
readonly shadow?: true;
|
|
1254
|
-
}
|
|
1255
|
-
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
1256
|
-
declare const PARAGRAPH_BORDER_SIDES: readonly ["top", "left", "bottom", "right", "between", "bar"];
|
|
1257
|
-
/**
|
|
1258
|
-
* Which of the six `CT_PBdr` edges.
|
|
1259
|
-
*
|
|
1260
|
-
* Four are physical box edges; `between` and `bar` are group-relative, drawn only where
|
|
1261
|
-
* consecutive paragraphs share a border definition.
|
|
1262
|
-
*/
|
|
1263
|
-
type ParagraphBorderSide = (typeof PARAGRAPH_BORDER_SIDES)[number];
|
|
1264
|
-
/**
|
|
1265
|
-
* A paragraph's resolved `w:pBdr` (ECMA-376 §17.3.1.24).
|
|
1266
|
-
*
|
|
1267
|
-
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
1268
|
-
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
1269
|
-
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
1270
|
-
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
1271
|
-
*/
|
|
1272
|
-
interface ParagraphBorders {
|
|
1273
|
-
readonly top?: ParagraphBorderEdge;
|
|
1274
|
-
readonly left?: ParagraphBorderEdge;
|
|
1275
|
-
readonly bottom?: ParagraphBorderEdge;
|
|
1276
|
-
readonly right?: ParagraphBorderEdge;
|
|
1277
|
-
readonly between?: ParagraphBorderEdge;
|
|
1278
|
-
readonly bar?: ParagraphBorderEdge;
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Resolve `w:spacing` before/after from flat paragraph properties.
|
|
1282
|
-
*
|
|
1283
|
-
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
1284
|
-
* height, not the gap between paragraphs — and is not resolved here.
|
|
1285
|
-
*
|
|
1286
|
-
* `w:beforeAutospacing` / `w:afterAutospacing` REPLACE the authored measurement on their own
|
|
1287
|
-
* side rather than adding to it; see {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
1288
|
-
*/
|
|
1289
|
-
declare function paragraphSpacing(props: readonly OoxmlProperty[], context?: ParagraphAutoSpacingContext): ParagraphSpacing;
|
|
1290
|
-
/**
|
|
1291
|
-
* Resolve `w:line` / `w:lineRule` from flat paragraph properties.
|
|
1292
|
-
*
|
|
1293
|
-
* Merged per attribute for the same reason as before/after: `w:spacing` is one element
|
|
1294
|
-
* carrying independent attributes, and a style that states only `@line` must not reset the
|
|
1295
|
-
* rule an earlier entry in the cascade set.
|
|
1418
|
+
* Soft ceiling on a tab position (31_680 twips ≈ 22"), matching paragraph-spacing bounds so
|
|
1419
|
+
* a hostile stop cannot shove layout into pathological widths.
|
|
1296
1420
|
*/
|
|
1297
|
-
declare
|
|
1421
|
+
declare const MAX_TAB_POSITION_TWIPS = 31680;
|
|
1422
|
+
/** OOXML / Word default when `w:settings/w:defaultTabStop` is absent: 720 twips = 0.5". */
|
|
1423
|
+
declare const DEFAULT_TAB_INTERVAL_TWIPS = 720;
|
|
1424
|
+
/** The default tab interval in points — {@link DEFAULT_TAB_INTERVAL_TWIPS} converted. */
|
|
1425
|
+
declare const DEFAULT_TAB_INTERVAL_PT: number;
|
|
1298
1426
|
/**
|
|
1299
|
-
*
|
|
1427
|
+
* How a tab stop positions the text that follows it.
|
|
1300
1428
|
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
* rhythm: `w:line="460"` on "between" opened a large gap above the word and almost none
|
|
1304
|
-
* before "MERIDIAN". `exact` taller than the glyphs centers the text (ECMA-376 17.3.1.33).
|
|
1305
|
-
* An `exact` box smaller than the glyphs keeps the baseline inside so clipped text still
|
|
1306
|
-
* sits on it.
|
|
1429
|
+
* Only `left` is a plain cursor jump. The other three size the tab glyph from the MEASURED
|
|
1430
|
+
* following segment, so its end, centre or decimal point lands on the stop.
|
|
1307
1431
|
*/
|
|
1308
|
-
|
|
1309
|
-
height: number;
|
|
1310
|
-
baseline: number;
|
|
1311
|
-
};
|
|
1432
|
+
type TabAlignment = 'left' | 'center' | 'right' | 'decimal';
|
|
1312
1433
|
/**
|
|
1313
|
-
* `w:
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1434
|
+
* `w:tab/@w:leader` (ECMA-376 §17.3.1.38, ST_TabTlc): the character repeated across the
|
|
1435
|
+
* space a tab reserves. `none` is the default and is represented by an absent leader.
|
|
1436
|
+
*
|
|
1437
|
+
* This is the difference between a Word table of contents and a column of headings floating
|
|
1438
|
+
* next to a column of page numbers, so it is carried through layout to paint rather than
|
|
1439
|
+
* dropped as a geometry-irrelevant attribute.
|
|
1316
1440
|
*/
|
|
1317
|
-
|
|
1441
|
+
type TabLeader = 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
1318
1442
|
/**
|
|
1319
|
-
*
|
|
1443
|
+
* The character each leader repeats (§17.3.1.38, ST_TabTlc).
|
|
1320
1444
|
*
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1445
|
+
* Lives with the type rather than with the painter because LAYOUT has to measure it: a
|
|
1446
|
+
* leader is the same character typed over and over, and the only way to space it the way
|
|
1447
|
+
* typing it would is to ask the measurer how wide it actually is.
|
|
1323
1448
|
*/
|
|
1324
|
-
declare
|
|
1449
|
+
declare const TAB_LEADER_GLYPH: ReadonlyMap<TabLeader, string>;
|
|
1450
|
+
/** One authored `w:tab`: where it sits, how it aligns, and what fills the gap. */
|
|
1451
|
+
interface TabStop {
|
|
1452
|
+
/** Position from the paragraph content origin, in points. */
|
|
1453
|
+
readonly positionPt: number;
|
|
1454
|
+
readonly alignment: TabAlignment;
|
|
1455
|
+
/** Legacy `num` stop: positions a numbering suffix, not a tab in ordinary text. */
|
|
1456
|
+
readonly numberingOnly?: true;
|
|
1457
|
+
/** Absent for `none` — the schema default and the overwhelming majority of stops. */
|
|
1458
|
+
readonly leader?: TabLeader;
|
|
1459
|
+
}
|
|
1325
1460
|
/**
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
* Word does not merge edges across the cascade. A style that states only `w:bottom` discards
|
|
1329
|
-
* the box its `basedOn` ancestor declared, so folding edge by edge would leave a lone
|
|
1330
|
-
* underline surrounded by a box no one authored. Absence inherits; `nil`/`none` clear.
|
|
1461
|
+
* A paragraph's tab stops after the style cascade, with the default interval that applies past
|
|
1462
|
+
* the last explicit one.
|
|
1331
1463
|
*/
|
|
1332
|
-
|
|
1464
|
+
interface ResolvedTabStops {
|
|
1465
|
+
/** Custom stops sorted by ascending position. */
|
|
1466
|
+
readonly stops: readonly TabStop[];
|
|
1467
|
+
/** Default-tab interval in points (always positive and bounded). */
|
|
1468
|
+
readonly defaultIntervalPt: number;
|
|
1469
|
+
}
|
|
1470
|
+
/** The frozen "no custom stops" value, so a paragraph without tabs mints no object. */
|
|
1471
|
+
declare const EMPTY_TAB_STOPS: ResolvedTabStops;
|
|
1333
1472
|
/**
|
|
1334
|
-
*
|
|
1473
|
+
* Resolve tab stops from cascaded `w:pPr` nodes (docDefaults → style chain → direct).
|
|
1335
1474
|
*
|
|
1336
|
-
*
|
|
1337
|
-
*
|
|
1475
|
+
* Each `w:tabs` merges with `clear` support; absence inherits. The leader travels with the
|
|
1476
|
+
* stop that declared it — a `clear` at the same position discards both together.
|
|
1338
1477
|
*/
|
|
1339
|
-
declare function
|
|
1478
|
+
declare function cascadedTabStops(paragraphPropertyNodes: readonly OoxmlNode[]): ResolvedTabStops;
|
|
1479
|
+
/** Direct `w:pPr` only — used when no style cascade table is present. */
|
|
1480
|
+
declare function paragraphTabStops(pPr: OoxmlNode | undefined): ResolvedTabStops;
|
|
1340
1481
|
/**
|
|
1341
|
-
*
|
|
1482
|
+
* Republish stops under a document-wide default-tab interval (`w:defaultTabStop`).
|
|
1342
1483
|
*
|
|
1343
|
-
*
|
|
1344
|
-
* the
|
|
1345
|
-
*
|
|
1346
|
-
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
1484
|
+
* The cascade resolves stops from the paragraph's own property chain, which cannot see
|
|
1485
|
+
* `settings.xml`; the interval is a document constant that arrives from the session. Returns
|
|
1486
|
+
* the input unchanged when nothing moves, so a cache-key fingerprint stays stable.
|
|
1347
1487
|
*/
|
|
1348
|
-
declare function
|
|
1349
|
-
/** Vertical extent a bottom border adds below the last line (gap + rule). */
|
|
1350
|
-
declare function bottomBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
1488
|
+
declare function withDefaultTabInterval(tabs: ResolvedTabStops, defaultIntervalPt: number | undefined): ResolvedTabStops;
|
|
1351
1489
|
/**
|
|
1352
|
-
*
|
|
1490
|
+
* Read `w:settings/w:defaultTabStop` (ECMA-376 §17.15.1.25), in points.
|
|
1353
1491
|
*
|
|
1354
|
-
* Word
|
|
1355
|
-
*
|
|
1356
|
-
*
|
|
1357
|
-
*
|
|
1492
|
+
* Word's own interval, not a constant: a metric-locale template writes `w:val="1134"` (2cm)
|
|
1493
|
+
* and every default-interval tab in the document lands on that grid instead of the 0.5"
|
|
1494
|
+
* one. The value is FILE-DERIVED, so a non-integer, non-positive or out-of-range `val` falls
|
|
1495
|
+
* back to the schema default rather than being trusted into layout arithmetic.
|
|
1358
1496
|
*
|
|
1359
|
-
*
|
|
1497
|
+
* `ST_TwipsMeasure` also admits a universal measure (`"2cm"`); Word writes plain twips, and
|
|
1498
|
+
* the spelled form falls back to the default rather than being parsed here.
|
|
1360
1499
|
*/
|
|
1361
|
-
declare function
|
|
1500
|
+
declare function defaultTabIntervalFromSettings(settings: OoxmlNode | null | undefined): number;
|
|
1501
|
+
/** Where one tab character lands: the resolved x, and the stop that decided it. */
|
|
1502
|
+
interface TabDestination {
|
|
1503
|
+
readonly positionPt: number;
|
|
1504
|
+
readonly alignment: TabAlignment;
|
|
1505
|
+
/** Leader of the stop that was reached; absent for `none` and for default-interval tabs. */
|
|
1506
|
+
readonly leader?: TabLeader;
|
|
1507
|
+
}
|
|
1362
1508
|
/**
|
|
1363
|
-
*
|
|
1364
|
-
*
|
|
1509
|
+
* Next tab destination strictly past `currentX`, preferring custom stops then the default
|
|
1510
|
+
* interval. Destination is clamped to `rightEdge` so stops cannot escape the content box.
|
|
1365
1511
|
*/
|
|
1366
|
-
declare function
|
|
1512
|
+
declare function nextTabDestination(tabs: ResolvedTabStops, currentX: number, rightEdge: number, forNumbering?: boolean): TabDestination;
|
|
1367
1513
|
/**
|
|
1368
|
-
*
|
|
1514
|
+
* Width of a tab glyph so the following segment lands on the destination.
|
|
1369
1515
|
*
|
|
1370
|
-
*
|
|
1371
|
-
* the
|
|
1372
|
-
|
|
1373
|
-
|
|
1516
|
+
* `segmentWidth` / `decimalOffset` are already measured in points. Decimal offset is the
|
|
1517
|
+
* advance from the segment start to the decimal point (0 when none — treated like right).
|
|
1518
|
+
*/
|
|
1519
|
+
declare function tabAdvanceWidth(alignment: TabAlignment, currentX: number, destinationX: number, segmentWidth: number, decimalOffset: number): number;
|
|
1520
|
+
/**
|
|
1521
|
+
* Stable fingerprint for layout cache keys — nested `w:tabs` are not in flat `OoxmlProperty`
|
|
1522
|
+
* bags, so style-inherited stops must be named explicitly or breaks would collide.
|
|
1374
1523
|
*/
|
|
1375
|
-
declare function
|
|
1524
|
+
declare function tabStopsFingerprint(tabs: ResolvedTabStops): string;
|
|
1376
1525
|
|
|
1377
1526
|
interface DrawingPoint {
|
|
1378
1527
|
readonly x: number;
|
|
@@ -1390,6 +1539,8 @@ interface DrawingGeometry {
|
|
|
1390
1539
|
readonly paintBounds: LayoutBox;
|
|
1391
1540
|
readonly hitBounds: LayoutBox;
|
|
1392
1541
|
readonly transformedCorners: readonly DrawingPoint[];
|
|
1542
|
+
/** Unclipped image corners for affine encoding; clipping must not stretch the image. */
|
|
1543
|
+
readonly imageTransformCorners?: readonly DrawingPoint[];
|
|
1393
1544
|
readonly clipPolygon: readonly DrawingPoint[] | null;
|
|
1394
1545
|
readonly clipFallback: DrawingClipFallback;
|
|
1395
1546
|
readonly effectInsets: DrawingInsets;
|
|
@@ -1411,9 +1562,9 @@ type TableBorderSideName = 'top' | 'right' | 'bottom' | 'left';
|
|
|
1411
1562
|
/**
|
|
1412
1563
|
* One border edge in one of three states.
|
|
1413
1564
|
*
|
|
1414
|
-
*
|
|
1415
|
-
*
|
|
1416
|
-
*
|
|
1565
|
+
* Omitted edges inherit. Explicit no-border edges suppress inherited rules; a directly
|
|
1566
|
+
* authored opposing edge can still win. This matches the saved Word sample's mixed and
|
|
1567
|
+
* borderless tables, including cells authored with `w:val="none"`.
|
|
1417
1568
|
*/
|
|
1418
1569
|
type TableBorderSide = {
|
|
1419
1570
|
readonly state: 'omitted';
|
|
@@ -1508,21 +1659,15 @@ declare function readBorderSide(node: OoxmlElement | undefined): TableBorderSide
|
|
|
1508
1659
|
declare function readTableBorders(tblPr: OoxmlElement | undefined): TableBorderBox;
|
|
1509
1660
|
/** Read one cell's `w:tcBorders`, under the same bounds {@link readTableBorders} applies. */
|
|
1510
1661
|
declare function readCellBorders(tcPr: OoxmlElement | undefined): CellBorderBox;
|
|
1511
|
-
/**
|
|
1512
|
-
*
|
|
1513
|
-
*
|
|
1514
|
-
* Word-matching, not conformance — §17.4.39 (`w:tblBorders`) and §17.4.66 (`w:tcBorders`)
|
|
1515
|
-
* describe the elements and specify no conflict algorithm. Word picks the heavier RULE, so
|
|
1516
|
-
* a 6pt dashed rule beats a hairline single. Folding the style rank into the weight (an
|
|
1517
|
-
* `sz × border-number` product) made a 0.5pt double outrank a 1pt single and made every
|
|
1518
|
-
* dashed or dotted rule weigh 1 regardless of `w:sz`, which erased its width entirely.
|
|
1662
|
+
/** Word's weighted border selection (MS-OI29500 §2.1.169, tcBorders).
|
|
1663
|
+
* https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oi29500/7c791c5d-44c3-4fe8-abdd-8f136761bb93
|
|
1519
1664
|
*/
|
|
1520
1665
|
declare function borderWeight(side: TableBorderSide): number;
|
|
1521
1666
|
/**
|
|
1522
1667
|
* Pick the winner between two candidates on a shared grid line (zero cell spacing).
|
|
1523
1668
|
*
|
|
1524
|
-
* `none` loses to any edge; two `none`/omitted
|
|
1525
|
-
* equal
|
|
1669
|
+
* `none` loses to any edge; two `none`/omitted do not paint. Weighted widths decide;
|
|
1670
|
+
* equal weights rank by style, then prefer the darker color, then `preferFirst`
|
|
1526
1671
|
* (reading-order / first candidate).
|
|
1527
1672
|
*/
|
|
1528
1673
|
declare function resolveBorderConflict(first: TableBorderSide, second: TableBorderSide, preferFirst?: boolean): TableBorderSide;
|
|
@@ -1541,6 +1686,8 @@ interface BorderGridCell {
|
|
|
1541
1686
|
* own and leaving a hairline gap between them.
|
|
1542
1687
|
*/
|
|
1543
1688
|
interface BorderGridGeometry {
|
|
1689
|
+
/** Center simple horizontal strokes on collapsed row boundaries. */
|
|
1690
|
+
readonly collapsedHorizontal?: boolean;
|
|
1544
1691
|
/** Absolute column widths for the whole table (points). */
|
|
1545
1692
|
readonly columnWidthsPt: readonly number[];
|
|
1546
1693
|
/**
|
|
@@ -1555,6 +1702,12 @@ interface BorderGridGeometry {
|
|
|
1555
1702
|
readonly cellBoxes: readonly (readonly {
|
|
1556
1703
|
readonly width: number;
|
|
1557
1704
|
readonly height: number;
|
|
1705
|
+
/** False when a split occurrence still reserves a shared bottom stroke. */
|
|
1706
|
+
readonly outerBottomInsetReserved?: boolean;
|
|
1707
|
+
/** Simple vertical strokes share the cell grid line with legacy padding. */
|
|
1708
|
+
readonly centeredSideRules?: boolean;
|
|
1709
|
+
/** Simple vertical strokes paint centered on the grid line. */
|
|
1710
|
+
readonly centeredSidePaint?: boolean;
|
|
1558
1711
|
}[])[];
|
|
1559
1712
|
}
|
|
1560
1713
|
/**
|
|
@@ -1570,7 +1723,7 @@ interface BorderGridGeometry {
|
|
|
1570
1723
|
* corner-adjusted endpoints in cell-local points.
|
|
1571
1724
|
*/
|
|
1572
1725
|
declare function resolveTableCellBorderGrid(rows: readonly (readonly BorderGridCell[])[], table: TableBorderBox, columnCount: number, geometry?: BorderGridGeometry, work?: TableBorderGridResolveWork, ownershipBudget?: TableBorderOwnershipBudget): ResolvedCellBorders[][];
|
|
1573
|
-
/**
|
|
1726
|
+
/** Painted extent inward from the cell edge; existing padding may already clear it. */
|
|
1574
1727
|
declare function borderExtentPt(edge: ResolvedTableBorderEdge | TableBorderSide | undefined): number;
|
|
1575
1728
|
|
|
1576
1729
|
/**
|
|
@@ -1672,6 +1825,19 @@ interface InlineDrawingLayoutContext {
|
|
|
1672
1825
|
readonly projectionForAtom?: (atomNodeId: string) => DrawingProjection | null;
|
|
1673
1826
|
readonly project: (drawing: OoxmlDrawingNode) => DrawingProjection | null;
|
|
1674
1827
|
readonly resourceOf: (projection: DrawingProjection) => ImageResourceState;
|
|
1828
|
+
/**
|
|
1829
|
+
* Resolve a numbering picture bullet's image by relationship id.
|
|
1830
|
+
*
|
|
1831
|
+
* The owner is the NUMBERING part, not this context's story part: `w:numPicBullet` lives in
|
|
1832
|
+
* `numbering.xml` and its `r:id` names a relationship of that part. The resolver answers the
|
|
1833
|
+
* owner it used so a sink can key the resource without assuming the part name. Absent on a
|
|
1834
|
+
* context whose host resolves no image resources, which degrades a picture bullet to its
|
|
1835
|
+
* level's `w:lvlText`.
|
|
1836
|
+
*/
|
|
1837
|
+
readonly pictureBulletResource?: (relationshipId: string) => {
|
|
1838
|
+
readonly ownerPartName: string;
|
|
1839
|
+
readonly resource: ImageResourceState;
|
|
1840
|
+
} | null;
|
|
1675
1841
|
}
|
|
1676
1842
|
/** Named fallback when a positioning frame cannot be resolved (OpenSpec 4.6). */
|
|
1677
1843
|
type AnchoredDrawingLayoutFallback = 'unresolvable-frame' | 'page-defer-exhausted';
|
|
@@ -1684,6 +1850,11 @@ interface AnchoredDrawingRecord extends Omit<InlineDrawingRecord, 'kind' | 'base
|
|
|
1684
1850
|
readonly verticalFrameOrigin: number;
|
|
1685
1851
|
readonly behindDocument: boolean;
|
|
1686
1852
|
readonly allowOverlap: boolean;
|
|
1853
|
+
/**
|
|
1854
|
+
* Whether the object is laid out in the box it flows in. For an anchor in a table cell this
|
|
1855
|
+
* is the layout's reading: `true` from compatibility mode 15, which ignores
|
|
1856
|
+
* `layoutInCell="0"`. Everywhere else it is the authored `wp:anchor/@layoutInCell`.
|
|
1857
|
+
*/
|
|
1687
1858
|
readonly layoutInCell: boolean;
|
|
1688
1859
|
readonly relativeHeight: number;
|
|
1689
1860
|
readonly wrap: Exclude<ImageWrapTarget, 'inline'>;
|
|
@@ -1718,6 +1889,17 @@ interface ResolvedListItem {
|
|
|
1718
1889
|
/** Effective indent after merging level + paragraph indents, in points. */
|
|
1719
1890
|
readonly indent: NumberingLevelIndent;
|
|
1720
1891
|
readonly markerStyle: ResolvedRunStyle;
|
|
1892
|
+
/**
|
|
1893
|
+
* The image marker a `w:lvlPicBulletId` level resolved to, absent on every other item.
|
|
1894
|
+
*
|
|
1895
|
+
* Present means the marker is an IMAGE: it occupies `width` x `height` points in the
|
|
1896
|
+
* hanging slot and `markerText` is only what a sink that cannot draw the image falls back
|
|
1897
|
+
* to. The extent is the AUTHORED `v:shape` size scaled by the marker font size — see
|
|
1898
|
+
* {@link resolvePictureBullet}, which also decides when the answer is no picture at all.
|
|
1899
|
+
* Absent means the level declared none, named one the part does not declare, declared one
|
|
1900
|
+
* this projection could not read, or resolved to a size nothing can paint.
|
|
1901
|
+
*/
|
|
1902
|
+
readonly picBullet?: ResolvedPictureBullet;
|
|
1721
1903
|
/** Fingerprint for layout cache keys (indent, marker text, marker face). */
|
|
1722
1904
|
readonly cacheToken: string;
|
|
1723
1905
|
}
|
|
@@ -1786,30 +1968,11 @@ declare function withResolvedListItems<T extends {
|
|
|
1786
1968
|
readonly listItems?: ReadonlyMap<string, ResolvedListItem>;
|
|
1787
1969
|
readonly styleCascade?: StyleCascadeTable;
|
|
1788
1970
|
readonly isFontAvailable?: (family: string) => boolean;
|
|
1971
|
+
readonly measurer?: TextMeasurer;
|
|
1789
1972
|
}>(options: T, blocks: readonly OoxmlElement[]): T & {
|
|
1790
1973
|
readonly numberingIndex: NumberingIndex;
|
|
1791
1974
|
readonly listItems?: ReadonlyMap<string, ResolvedListItem>;
|
|
1792
1975
|
};
|
|
1793
|
-
/**
|
|
1794
|
-
* Horizontal marker box inside the first-line indent slot.
|
|
1795
|
-
*
|
|
1796
|
-
* Coordinates are relative to the same origin as paragraph content (`indent.left` is the
|
|
1797
|
-
* text start). Returns null when there is nothing to paint.
|
|
1798
|
-
*
|
|
1799
|
-
* `w:hanging` and a positive `w:firstLine` are one mutually exclusive slot
|
|
1800
|
-
* (§17.3.1.10, §17.3.1.12), so the marker has two placements, not an interaction:
|
|
1801
|
-
* a hanging level puts the marker BEFORE the text start (`left - hanging`); a
|
|
1802
|
-
* positive-firstLine level puts it AFTER (`left + firstLine`) — the standard legal
|
|
1803
|
-
* shape `w:ind w:left="0" w:firstLine="720"` numbers at 0.5" while continuation
|
|
1804
|
-
* lines return to the margin. Reading only the hanging model painted every such
|
|
1805
|
-
* marker at the left margin.
|
|
1806
|
-
*/
|
|
1807
|
-
declare function listMarkerBox(item: ResolvedListItem, markerWidth: number, lineY: number, lineHeight: number): {
|
|
1808
|
-
x: number;
|
|
1809
|
-
y: number;
|
|
1810
|
-
width: number;
|
|
1811
|
-
height: number;
|
|
1812
|
-
} | null;
|
|
1813
1976
|
|
|
1814
1977
|
interface StyleDefinition {
|
|
1815
1978
|
readonly styleId: string;
|
|
@@ -1823,6 +1986,7 @@ interface StyleDefinition {
|
|
|
1823
1986
|
readonly paragraphPropertiesNode: OoxmlElement | undefined;
|
|
1824
1987
|
readonly tablePropertiesNode: OoxmlElement | undefined;
|
|
1825
1988
|
readonly tableRowPropertiesNode: OoxmlElement | undefined;
|
|
1989
|
+
readonly tableCellPropertiesNode?: OoxmlElement;
|
|
1826
1990
|
readonly conditionalTableFormats: ReadonlyMap<string, OoxmlElement>;
|
|
1827
1991
|
}
|
|
1828
1992
|
declare function isValidStyleId(raw: string | undefined): raw is string;
|
|
@@ -1838,6 +2002,12 @@ declare const MAX_STYLE_DEFINITIONS = 4096;
|
|
|
1838
2002
|
* styles part are never reused under another.
|
|
1839
2003
|
*/
|
|
1840
2004
|
interface StyleCascadeTable {
|
|
2005
|
+
/** Legacy or explicitly disabled optional OpenType substitutions. */
|
|
2006
|
+
readonly disableOptionalLigatures?: true;
|
|
2007
|
+
/** Legacy noExtraLineSpacing behavior, included in the producer fingerprint. */
|
|
2008
|
+
readonly preserveExactLineBaseline?: true;
|
|
2009
|
+
/** Explicit compatibility opt-in to the unmodified ISO table style hierarchy. */
|
|
2010
|
+
readonly strictTableStyleHierarchy?: boolean;
|
|
1841
2011
|
readonly typography?: CjkTypographySettings;
|
|
1842
2012
|
/**
|
|
1843
2013
|
* Bounded fingerprint folded into layout cache producers so a different styles part cannot
|
|
@@ -2025,253 +2195,6 @@ interface ParagraphLayoutInputs {
|
|
|
2025
2195
|
*/
|
|
2026
2196
|
declare function resolveParagraphLayoutInputs(paragraph: OoxmlElement, contentWidth: number, styleCascade: StyleCascadeTable | undefined, listItem?: ResolvedListItem, tableCellStyle?: TableCellStyleFormatting, inTableCell?: boolean, lineUnitPt?: number): ParagraphLayoutInputs;
|
|
2027
2197
|
|
|
2028
|
-
/**
|
|
2029
|
-
* `w:tblW` / `w:tcW` / `w:wBefore` (CT_TblWidth, 17.4.63 / 17.4.71 / 17.4.86): a PREFERRED
|
|
2030
|
-
* width plus the unit it is stated in. Preferred is the operative word — it is what the
|
|
2031
|
-
* producer asked for, not what the table resolved to.
|
|
2032
|
-
*
|
|
2033
|
-
* `pct` is stated in fiftieths of a percent (5000 = 100%) by Word, and in the `"50%"`
|
|
2034
|
-
* string form of `ST_Percentage` by others; both are read. `auto` and `nil` carry no width.
|
|
2035
|
-
*/
|
|
2036
|
-
type PreferredWidthType = 'dxa' | 'pct' | 'auto' | 'nil';
|
|
2037
|
-
/**
|
|
2038
|
-
* `w:tblW` / `w:tcW` — a requested width, whose UNIT depends on its type.
|
|
2039
|
-
*
|
|
2040
|
-
* Points for `dxa`, percent for `pct`, and zero for `auto`/`nil`. Reading `value` without `type`
|
|
2041
|
-
* is always wrong.
|
|
2042
|
-
*/
|
|
2043
|
-
interface PreferredWidth {
|
|
2044
|
-
readonly type: PreferredWidthType;
|
|
2045
|
-
/** POINTS for `dxa`, PERCENT (0–100) for `pct`, 0 for `auto`/`nil`. */
|
|
2046
|
-
readonly value: number;
|
|
2047
|
-
}
|
|
2048
|
-
/** The frozen "no preferred width" value — what a table or cell that declares none resolves to. */
|
|
2049
|
-
declare const AUTO_PREFERRED_WIDTH: PreferredWidth;
|
|
2050
|
-
|
|
2051
|
-
/**
|
|
2052
|
-
* The uniform 3 pt (60 twip) inset this lane used to apply on every side.
|
|
2053
|
-
*
|
|
2054
|
-
* Word's defaults are not uniform — see {@link DEFAULT_CELL_MARGINS} — so nothing resolves
|
|
2055
|
-
* against this any more. Kept because it is published.
|
|
2056
|
-
*/
|
|
2057
|
-
declare const CELL_PAD = 3;
|
|
2058
|
-
/** Resolved cell padding in points, after the table default and any per-cell override. */
|
|
2059
|
-
interface CellMarginsPt {
|
|
2060
|
-
readonly top: number;
|
|
2061
|
-
readonly right: number;
|
|
2062
|
-
readonly bottom: number;
|
|
2063
|
-
readonly left: number;
|
|
2064
|
-
}
|
|
2065
|
-
/**
|
|
2066
|
-
* Word's own default cell padding, for a document whose styles part states none.
|
|
2067
|
-
*
|
|
2068
|
-
* 0 top, 0 bottom, 108 twips left and right — the values `TableNormal` carries. A uniform
|
|
2069
|
-
* 3 pt on all four sides made every row of every table that authored no `w:tblCellMar` 6 pt
|
|
2070
|
-
* taller than Word's, and that error compounds down a table until it paginates a page early.
|
|
2071
|
-
* A document that DOES ship a default table style resolves against that instead; this is the
|
|
2072
|
-
* floor beneath it.
|
|
2073
|
-
*/
|
|
2074
|
-
declare const DEFAULT_CELL_MARGINS: CellMarginsPt;
|
|
2075
|
-
|
|
2076
|
-
/** `w:vAlign` — where a cell's content sits when the row is taller than the content. */
|
|
2077
|
-
type CellVerticalAlign = 'top' | 'center' | 'bottom';
|
|
2078
|
-
|
|
2079
|
-
/**
|
|
2080
|
-
* Layout-time nesting ceiling. Parse-time depth (MAX_DEPTH = 256 XML levels) alone still
|
|
2081
|
-
* admits ~80 levels of `w:tbl` recursion into the layout walk; deeper tables render as an
|
|
2082
|
-
* empty cell box rather than recursing.
|
|
2083
|
-
*/
|
|
2084
|
-
declare const MAX_TABLE_NESTING = 16;
|
|
2085
|
-
/**
|
|
2086
|
-
* Soft ceiling on an authored `w:trHeight` (~22"). Hostile `w:val` otherwise becomes a
|
|
2087
|
-
* multi-page row that every pagination preflight and cell box inherits.
|
|
2088
|
-
*/
|
|
2089
|
-
declare const MAX_TABLE_ROW_HEIGHT_PT: number;
|
|
2090
|
-
/**
|
|
2091
|
-
* `w:trPr/w:trHeight` (17.4.81) resolved for layout. Points leave the reader already —
|
|
2092
|
-
* twips convert once here, matching every other table geometry boundary.
|
|
2093
|
-
*
|
|
2094
|
-
* Word quirk (matches Form025U and Word's UI export): a present `@w:val` with an omitted
|
|
2095
|
-
* `@w:hRule` is treated as `atLeast`, not ECMA's `auto`. Explicit `auto` still ignores val.
|
|
2096
|
-
*/
|
|
2097
|
-
type TableRowHeightRule = 'auto' | 'atLeast' | 'exact';
|
|
2098
|
-
/**
|
|
2099
|
-
* `w:trHeight` — a row's height rule and its value.
|
|
2100
|
-
*
|
|
2101
|
-
* `auto` carries no value at all, which is why this is a union rather than a rule plus an
|
|
2102
|
-
* optional number.
|
|
2103
|
-
*/
|
|
2104
|
-
type TableRowHeight = {
|
|
2105
|
-
readonly rule: 'auto';
|
|
2106
|
-
} | {
|
|
2107
|
-
readonly rule: 'atLeast' | 'exact';
|
|
2108
|
-
readonly valuePt: number;
|
|
2109
|
-
};
|
|
2110
|
-
/** `w:tblPr/w:jc` (17.4.29, ST_JcTable): where the table sits within the text column. */
|
|
2111
|
-
type TableAlignment = 'left' | 'center' | 'right';
|
|
2112
|
-
/**
|
|
2113
|
-
* `w:tblpPr/@w:horzAnchor` (17.4.58) and `@w:vertAnchor` (17.4.66): the box a floated
|
|
2114
|
-
* table's offsets are measured from. Absent means `text` for both.
|
|
2115
|
-
*/
|
|
2116
|
-
type TableFloatAnchor = 'text' | 'margin' | 'page';
|
|
2117
|
-
/** `w:tblpPr/@w:tblpXSpec` (17.4.63, ST_XAlign). */
|
|
2118
|
-
type TableFloatXSpec = 'left' | 'center' | 'right' | 'inside' | 'outside';
|
|
2119
|
-
/** `w:tblpPr/@w:tblpYSpec` (17.4.65, ST_YAlign). */
|
|
2120
|
-
type TableFloatYSpec = 'inline' | 'top' | 'center' | 'bottom' | 'inside' | 'outside';
|
|
2121
|
-
/**
|
|
2122
|
-
* `w:tblPr/w:tblpPr` (17.4.57) — a table positioned against an anchor box rather than at
|
|
2123
|
-
* the point in the text where it was authored.
|
|
2124
|
-
*
|
|
2125
|
-
* A spec (`tblpXSpec`/`tblpYSpec`) supersedes the matching offset when both are present:
|
|
2126
|
-
* 17.4.57 states the alignment outright, and the offset only answers "how far from the
|
|
2127
|
-
* anchor" for the case where no alignment was stated.
|
|
2128
|
-
*/
|
|
2129
|
-
interface TableFloatPosition {
|
|
2130
|
-
readonly horzAnchor: TableFloatAnchor;
|
|
2131
|
-
readonly vertAnchor: TableFloatAnchor;
|
|
2132
|
-
readonly xSpec?: TableFloatXSpec;
|
|
2133
|
-
/** `w:tblpX` in points; signed, so a table can be pulled into the margin. */
|
|
2134
|
-
readonly xPt: number;
|
|
2135
|
-
readonly ySpec?: TableFloatYSpec;
|
|
2136
|
-
/** `w:tblpY` in points; signed. */
|
|
2137
|
-
readonly yPt: number;
|
|
2138
|
-
readonly distances?: {
|
|
2139
|
-
readonly top: number;
|
|
2140
|
-
readonly right: number;
|
|
2141
|
-
readonly bottom: number;
|
|
2142
|
-
readonly left: number;
|
|
2143
|
-
};
|
|
2144
|
-
}
|
|
2145
|
-
/**
|
|
2146
|
-
* One cell in the resolved table structure.
|
|
2147
|
-
*
|
|
2148
|
-
* `gridSpan` is clamped at READ time and layout never re-derives it — the value comes from a file
|
|
2149
|
-
* and would otherwise be a loop bound an attacker controls.
|
|
2150
|
-
*/
|
|
2151
|
-
interface SemanticTableCell {
|
|
2152
|
-
readonly id: string;
|
|
2153
|
-
/** Derived content-edge geometry for a verified legacy full-width parent table. */
|
|
2154
|
-
readonly legacyContentAlignment?: true;
|
|
2155
|
-
/** Clamped to [1, MAX_TABLE_COLUMNS] at read time; layout never re-derives it. */
|
|
2156
|
-
readonly gridSpan: number;
|
|
2157
|
-
/** Physical grid column after width/style resolution and the bidiVisual projection. */
|
|
2158
|
-
readonly gridColumn: number;
|
|
2159
|
-
/** Stored grid index when bidiVisual maps this cell into a physical RTL grid. */
|
|
2160
|
-
readonly logicalGridColumn?: number;
|
|
2161
|
-
/** Canonical `w:gridCol` node id for this cell's start column, when the grid is authored. */
|
|
2162
|
-
readonly gridColumnId?: string;
|
|
2163
|
-
/** A vMerge cell that is not the restart continues the cell above: box, no content. */
|
|
2164
|
-
readonly vMergeContinue: boolean;
|
|
2165
|
-
/** `w:vAlign` — defaults to top when omitted/unrecognised. */
|
|
2166
|
-
readonly vAlign: CellVerticalAlign;
|
|
2167
|
-
/** `w:textDirection`; unsupported values keep horizontal layout. */
|
|
2168
|
-
readonly textDirection: 'horizontal' | 'btLr';
|
|
2169
|
-
/** Resolved per-side margins (tcMar over tblCellMar over the table style over Word's default). */
|
|
2170
|
-
readonly margins: CellMarginsPt;
|
|
2171
|
-
/** Three-state authored `tcBorders` (omitted / none / edge). */
|
|
2172
|
-
readonly borders: CellBorderBox;
|
|
2173
|
-
/** Validated 6-hex shading fill, absent for none/auto. */
|
|
2174
|
-
readonly shading?: string;
|
|
2175
|
-
/**
|
|
2176
|
-
* `w:tcW` — the width this cell asked for, as authored.
|
|
2177
|
-
*
|
|
2178
|
-
* Published for consumers that need the cell's own statement (a column-resize handle has
|
|
2179
|
-
* to write back to it). Column geometry is NOT derived from this field: the resolver works
|
|
2180
|
-
* from a flat claim list built in the same pass, because resolving a column means looking
|
|
2181
|
-
* at every cell that covers it across every row, not at one cell at a time. Read
|
|
2182
|
-
* `columnWidthsPt` for what the table actually laid out.
|
|
2183
|
-
*/
|
|
2184
|
-
readonly preferredWidth: PreferredWidth;
|
|
2185
|
-
/**
|
|
2186
|
-
* What the table style says about this cell's paragraphs and runs (17.7.6.6) — a header
|
|
2187
|
-
* row's bold and centring live here, not in the cell's own properties.
|
|
2188
|
-
*/
|
|
2189
|
-
readonly styleFormatting: TableCellStyleFormatting;
|
|
2190
|
-
/** Block children in reading order, with content-control wrappers flattened. */
|
|
2191
|
-
readonly blocks: readonly OoxmlElement[];
|
|
2192
|
-
}
|
|
2193
|
-
/** One row in the resolved structure: its cells, its height rule, and any row-level revision. */
|
|
2194
|
-
interface SemanticTableRow {
|
|
2195
|
-
readonly id: string;
|
|
2196
|
-
/** Pending Word row insertion/deletion authored in `w:trPr`. */
|
|
2197
|
-
readonly revisionKind?: 'insert' | 'delete';
|
|
2198
|
-
/**
|
|
2199
|
-
* The `w:trPr/w:ins|w:del` attribution, carried with the kind so a painted row can say
|
|
2200
|
-
* WHOSE pending decision it is — the review model addresses the decision by exactly this
|
|
2201
|
-
* `(id, author, date)` triple, and a surface with only the kind could highlight the row
|
|
2202
|
-
* but never open its card.
|
|
2203
|
-
*/
|
|
2204
|
-
readonly revisionId?: string;
|
|
2205
|
-
readonly revisionAuthor?: string;
|
|
2206
|
-
readonly revisionDate?: string;
|
|
2207
|
-
/** The row insertion a resolved view kept the row through; see the fragment record. */
|
|
2208
|
-
readonly changeSites?: readonly RevisionAttribution[];
|
|
2209
|
-
/** `w:trPr/w:tblHeader` — the row repeats atop each page the table continues onto. */
|
|
2210
|
-
readonly isHeader: boolean;
|
|
2211
|
-
/**
|
|
2212
|
-
* `w:trPr/w:cantSplit` — the row must stay on one page. When it cannot fit a fresh page,
|
|
2213
|
-
* layout fails closed rather than fragmenting or overflowing the content box.
|
|
2214
|
-
*/
|
|
2215
|
-
readonly cantSplit: boolean;
|
|
2216
|
-
/** `w:trPr/w:trHeight` — auto / atLeast floor / exact (clipped) row height. */
|
|
2217
|
-
readonly height: TableRowHeight;
|
|
2218
|
-
readonly cells: readonly SemanticTableCell[];
|
|
2219
|
-
}
|
|
2220
|
-
/**
|
|
2221
|
-
* A table resolved into a rectangular grid: column widths, rows, and the widths it asked for.
|
|
2222
|
-
*
|
|
2223
|
-
* The grid is normalized here so layout never has to reconcile `w:gridCol` against actual cell
|
|
2224
|
-
* spans — vertical merges and column spans are already accounted for.
|
|
2225
|
-
*/
|
|
2226
|
-
interface SemanticTableStructure {
|
|
2227
|
-
/** Whether stored columns and horizontal table properties display right to left. */
|
|
2228
|
-
readonly bidiVisual?: true;
|
|
2229
|
-
readonly columnWidthsPt: readonly number[];
|
|
2230
|
-
readonly rows: readonly SemanticTableRow[];
|
|
2231
|
-
/** Verified pre-2013 content-aligned full-width inline table; derived, never serialized. */
|
|
2232
|
-
readonly legacyContentAlignment?: true;
|
|
2233
|
-
/** `w:tblPr/w:tblW` — the width the table asked for. */
|
|
2234
|
-
readonly tableWidth: PreferredWidth;
|
|
2235
|
-
/**
|
|
2236
|
-
* `w:tblInd` (17.4.50) in points — "this indentation should shift the table into the text
|
|
2237
|
-
* margin by the specified amount". Applies to a left-aligned table; `w:jc` decides the
|
|
2238
|
-
* placement outright for the other two.
|
|
2239
|
-
*/
|
|
2240
|
-
readonly indentPt: number;
|
|
2241
|
-
/** `w:tblPr/w:jc` (17.4.29) — where the table sits in the text column. */
|
|
2242
|
-
readonly alignment: TableAlignment;
|
|
2243
|
-
/**
|
|
2244
|
-
* `w:tblPr/w:tblpPr` (17.4.57) — present when the table is positioned against an anchor
|
|
2245
|
-
* box. Placement then comes from {@link tableFloatOriginX} rather than `w:jc`/`w:tblInd`.
|
|
2246
|
-
*/
|
|
2247
|
-
readonly float?: TableFloatPosition;
|
|
2248
|
-
/**
|
|
2249
|
-
* `w:tblCellSpacing` (17.4.45) in points: the gap between adjacent cell edges. Applied as
|
|
2250
|
-
* a half-gap inset on each side of every cell, so cells separate visually without the grid
|
|
2251
|
-
* itself moving. Word ALSO grows the table's overall width by the spacing it adds around
|
|
2252
|
-
* the outside; that part is not modelled, so a spaced table is laid out on the same grid
|
|
2253
|
-
* its file states rather than a wider one.
|
|
2254
|
-
*/
|
|
2255
|
-
readonly cellSpacingPt: number;
|
|
2256
|
-
/**
|
|
2257
|
-
* `w:tblPr/w:tblLayout/@w:type="fixed"` (17.4.52 — 17.4.53 is the `w:tblPrEx` exception
|
|
2258
|
-
* variant, not this element). Fixed layout takes the grid as final;
|
|
2259
|
-
* anything else is autofit, which in Word never renders wider than the text column.
|
|
2260
|
-
*/
|
|
2261
|
-
readonly layoutFixed: boolean;
|
|
2262
|
-
/** Table-level `tblBorders` (three-state, including insideH/insideV). */
|
|
2263
|
-
readonly tableBorders: TableBorderBox;
|
|
2264
|
-
/** Table-level `tblCellMar` defaults (per-side, Word's own default when a side is omitted). */
|
|
2265
|
-
readonly defaultMargins: CellMarginsPt;
|
|
2266
|
-
}
|
|
2267
|
-
/**
|
|
2268
|
-
* Read one typed table node into a bounded structure, or null when the node is not a
|
|
2269
|
-
* typed table or sits beyond the nesting ceiling.
|
|
2270
|
-
*/
|
|
2271
|
-
declare function readTableStructure(table: OoxmlNode, contentWidthPt: number, depth: number, styleCascade?: StyleCascadeTable,
|
|
2272
|
-
/** Which revisions the view resolves away; only the proposed result performs the join. */
|
|
2273
|
-
displayMode?: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter, compatibilityMode?: number): SemanticTableStructure | null;
|
|
2274
|
-
|
|
2275
2198
|
interface EquationGeometryBase {
|
|
2276
2199
|
readonly box: LayoutBox;
|
|
2277
2200
|
/** Baseline measured from this node's top edge. */
|
|
@@ -2570,6 +2493,8 @@ interface StyleSpanRecord {
|
|
|
2570
2493
|
* ink displacement. Exporters must apply this offset to the ink origin.
|
|
2571
2494
|
*/
|
|
2572
2495
|
readonly glyphOffsetPt?: number;
|
|
2496
|
+
/** Measured face baseline for character-border geometry; span boxes remain selection bands. */
|
|
2497
|
+
readonly borderBaselinePt?: number;
|
|
2573
2498
|
readonly range: SourceRange;
|
|
2574
2499
|
readonly text: string;
|
|
2575
2500
|
/** The run's authored properties, retained as evidence. */
|
|
@@ -2674,6 +2599,8 @@ interface StyleSpanRecord {
|
|
|
2674
2599
|
* and selection mapping refuses them the way it refuses markers.
|
|
2675
2600
|
*/
|
|
2676
2601
|
readonly projected?: boolean;
|
|
2602
|
+
/** Authored inline separator rule; its advance belongs to one note atom. */
|
|
2603
|
+
readonly noteSeparator?: 'separator' | 'continuationSeparator';
|
|
2677
2604
|
/** Paint-ready geometry for one atomic Office Math equation. */
|
|
2678
2605
|
readonly equation?: EquationSpanRecord;
|
|
2679
2606
|
/**
|
|
@@ -2813,10 +2740,15 @@ interface ParagraphFragmentRecord {
|
|
|
2813
2740
|
readonly emptyParagraphStyle?: ResolvedRunStyle;
|
|
2814
2741
|
/** A fixed text frame clips its painted ink to this fragment's box; source ranges remain intact. */
|
|
2815
2742
|
readonly clipToBox?: true;
|
|
2816
|
-
/**
|
|
2743
|
+
/**
|
|
2744
|
+
* The fragment retains its source identity without consuming body flow height: a positioned
|
|
2745
|
+
* text frame (with {@link ParagraphFragmentRecord.positionedFrame}), or an empty section-mark
|
|
2746
|
+
* paragraph before a continuous section, which paints nothing.
|
|
2747
|
+
*/
|
|
2817
2748
|
readonly outOfFlow?: true;
|
|
2818
2749
|
/** Placement and wrapping of one authored text-frame group, in page-content coordinates. */
|
|
2819
2750
|
readonly positionedFrame?: {
|
|
2751
|
+
readonly dropCapLines?: number;
|
|
2820
2752
|
readonly anchorId: string;
|
|
2821
2753
|
readonly columnIndex: number;
|
|
2822
2754
|
readonly groupId: string;
|
|
@@ -2982,6 +2914,40 @@ interface ListMarkerRecord {
|
|
|
2982
2914
|
readonly numFmt: string;
|
|
2983
2915
|
/** Resolved counter at this marker's own level; absent for bullets. */
|
|
2984
2916
|
readonly ordinal?: number;
|
|
2917
|
+
/**
|
|
2918
|
+
* The IMAGE this marker draws instead of {@link ListMarkerRecord.text}, when the resolved
|
|
2919
|
+
* level carries `w:lvlPicBulletId` (§17.9.12) and the referenced `w:numPicBullet` resolved.
|
|
2920
|
+
*
|
|
2921
|
+
* Absent on every ordinary marker, and absent when the picture bullet is missing, external,
|
|
2922
|
+
* malformed or oversized — in which case `text` stands and the marker paints as the level's
|
|
2923
|
+
* `w:lvlText` did before. A sink that cannot draw the resource paints `text` too, which is
|
|
2924
|
+
* why both are published rather than one replacing the other.
|
|
2925
|
+
*/
|
|
2926
|
+
readonly picture?: ListMarkerPictureRecord;
|
|
2927
|
+
}
|
|
2928
|
+
/**
|
|
2929
|
+
* The picture a `w:lvlPicBulletId` marker paints, with its geometry already decided.
|
|
2930
|
+
*
|
|
2931
|
+
* Geometry is in the same coordinate space as {@link ListMarkerRecord.box}: paint positions
|
|
2932
|
+
* from `box` and MUST NOT rescale it, neither from the resource's intrinsic pixels nor from
|
|
2933
|
+
* the authored `v:shape` extent, which the marker font size has already scaled. The image
|
|
2934
|
+
* sits with its BOTTOM on the first line's baseline, which is what makes the line tall
|
|
2935
|
+
* enough for it.
|
|
2936
|
+
*
|
|
2937
|
+
* `resource` is the same validated-image projection an inline drawing carries, resolved
|
|
2938
|
+
* through the numbering part's OWN relationships. A `ready` resource is the only one that
|
|
2939
|
+
* can be drawn; every other state is a clean fall back to the marker text.
|
|
2940
|
+
* @public
|
|
2941
|
+
*/
|
|
2942
|
+
interface ListMarkerPictureRecord {
|
|
2943
|
+
/** The part whose relationships `relationshipId` belongs to — the numbering part. */
|
|
2944
|
+
readonly ownerPartName: string;
|
|
2945
|
+
/** `v:imagedata/@r:id` of the `w:numPicBullet` shape. */
|
|
2946
|
+
readonly relationshipId: string;
|
|
2947
|
+
/** Where the image paints, authored extent, in the marker's coordinate space. */
|
|
2948
|
+
readonly box: LayoutBox;
|
|
2949
|
+
/** Validated image state, or why there is none. */
|
|
2950
|
+
readonly resource: ImageResourceState;
|
|
2985
2951
|
}
|
|
2986
2952
|
/**
|
|
2987
2953
|
* The part of one table that sits on one page.
|
|
@@ -3187,6 +3153,8 @@ interface NoteAreaRecord {
|
|
|
3187
3153
|
readonly synthetic: boolean;
|
|
3188
3154
|
/** Layout-owned single/double rule when marker-only or synthetic; absent for authored stories. */
|
|
3189
3155
|
readonly ruleStyle?: 'single' | 'double';
|
|
3156
|
+
/** Resolved marker-run color; null/absent uses automatic black. */
|
|
3157
|
+
readonly ruleColor?: string | null;
|
|
3190
3158
|
};
|
|
3191
3159
|
readonly notes: readonly NoteStoryRecord[];
|
|
3192
3160
|
readonly fallbackReason?: string;
|
|
@@ -3387,11 +3355,19 @@ interface TextMeasurer {
|
|
|
3387
3355
|
left: number;
|
|
3388
3356
|
right: number;
|
|
3389
3357
|
} | undefined;
|
|
3390
|
-
/**
|
|
3391
|
-
|
|
3358
|
+
/** Whether line metrics use an admitted face instead of approximate fallback metrics. */
|
|
3359
|
+
hasResolvedFont?(style: ResolvedRunStyle): boolean;
|
|
3360
|
+
/**
|
|
3361
|
+
* Optional `OS/2` strikeout stroke for the resolved face, at the drawn size. Word paints
|
|
3362
|
+
* `w:separator` as a strikeout, so the note rule reads its thickness and offset here rather
|
|
3363
|
+
* than assuming one face's numbers. Undefined keeps the caller's own default.
|
|
3364
|
+
*/
|
|
3365
|
+
strikeoutMetrics?(style: ResolvedRunStyle): StrikeoutStrokePt | undefined;
|
|
3366
|
+
/** Line metrics for the actual text faces; omitted text measures the primary face. */
|
|
3367
|
+
lineMetrics(style: ResolvedRunStyle, text?: string): {
|
|
3392
3368
|
height: number;
|
|
3393
3369
|
baseline: number;
|
|
3394
3370
|
};
|
|
3395
3371
|
}
|
|
3396
3372
|
|
|
3397
|
-
export { type
|
|
3373
|
+
export { type SpanLinkRecord as $, type AnchoredDrawingRecord as A, type BlockFragmentRecord as B, type ContentControlBoundaryRecord as C, type DrawingPoint as D, type NoteAreaRecord as E, type FontResourceSnapshot as F, type NoteStoryRecord as G, type HeaderFooterStoryRecord as H, type InlineDrawingRecord as I, type ContentControlLock as J, type FontByteValidator as K, type LineRecord as L, type ModelRange as M, type NormalizationPolicy as N, type FixedPoint as O, type PageGeometry as P, type SourceRange as Q, type ResolvedRunStyle as R, type SemanticLayout as S, type TextMeasurer as T, type HyperlinkProjector as U, type VersionedShapingLibrary as V, type InlineDrawingLayoutContext as W, type FieldLinkProjector as X, type StoryPageFieldNeeds as Y, type RefFieldContext as Z, type HyperlinkFieldSpec as _, type StyleSpanRecord as a, type PageBorderDisplay as a$, type PageBorderFrameRecord as a0, type ParagraphBorderStrokeRecord as a1, type StrikeoutStrokePt as a2, AUTO_PARAGRAPH_SPACING_PT as a3, type AbstractNumDefinition as a4, type AnchoredDrawingLayoutFallback as a5, type BidiEmbeddingLevels as a6, type BorderGridGeometry as a7, type CascadedParagraphFormatting as a8, type CjkTypographySettings as a9, type FontResourceSnapshotOptions as aA, type FontSlot as aB, type FontValidationResult as aC, type GlyphOutline as aD, HARD_MAX_AGGREGATE_FONT_BYTES as aE, HARD_MAX_FONT_BYTES as aF, HARD_MAX_FONT_SOURCES as aG, type LevelOverride as aH, type LineSpacingRule as aI, type ListMarkerAlign as aJ, type ListMarkerRecord as aK, type ListSuffix as aL, MAX_BORDER_SPACE_PT as aM, MAX_BORDER_WIDTH_PT as aN, MAX_LVL_OVERRIDES as aO, MAX_NUMBERING_DEFINITIONS as aP, MAX_PARAGRAPH_SPACING_PT as aQ, MAX_STYLE_BASED_ON_DEPTH as aR, MAX_STYLE_DEFINITIONS as aS, MAX_TABLE_BORDER_STROKES as aT, MAX_TAB_POSITION_TWIPS as aU, MAX_TAB_STOPS as aV, type NumDefinition as aW, type NumberingLevelIndent as aX, type NumberingPictureBullet as aY, PAGE_BORDER_SIDES as aZ, PARAGRAPH_BORDER_SIDES as a_, type ContentControlGeometryFragment as aa, type ContentControlLevel as ab, type ContentControlMappedType as ac, DEFAULT_PAGE_GEOMETRY as ad, DEFAULT_RUN_STYLE as ae, DEFAULT_TAB_INTERVAL_PT as af, DEFAULT_TAB_INTERVAL_TWIPS as ag, type DeclaredFontSubstitution as ah, type DrawingClipFallback as ai, type DrawingGeometry as aj, EMPTY_NUMBERING_INDEX as ak, EMPTY_TAB_STOPS as al, type EquationFractionGeometry as am, type EquationGeometry as an, type EquationNaryGeometry as ao, type EquationRadicalGeometry as ap, type EquationRowGeometry as aq, type EquationScriptGeometry as ar, type EquationSpanRecord as as, type EquationTextGeometry as at, type FieldAtomMarker as au, type FontFingerprintInputs as av, FontResolutionError as aw, type FontResolutionErrorCode as ax, type FontResourceDefinition as ay, type FontResourceInstrumentation as az, type SectionPageBorders as b, buildStyleCascadeTable as b$, type PageBorderOffsetFrom as b0, type PageBorderSide as b1, type PageBorderStrokeRecord as b2, type PageBorderZOrder as b3, type PageRefCalibrationCell as b4, type PageRefFieldProjection as b5, type ParagraphAutoSpacingContext as b6, type ParagraphBorderEdge as b7, type ParagraphBorderSide as b8, type ParagraphBorders as b9, type ShapedGlyph as bA, type ShapedRunComparatorInputs as bB, type ShapedVerticalMetrics as bC, type ShapingEnvironment as bD, type ShapingEnvironmentFingerprintInputs as bE, type StyleDefinition as bF, TAB_LEADER_GLYPH as bG, type TabAlignment as bH, type TabDestination as bI, type TabLeader as bJ, type TabStop as bK, type TableBorderSideName as bL, type TableBorderStrokeRecord as bM, type TableFragmentRecord as bN, type TextDirection as bO, type TextboxStoryFallbackReason as bP, type TextboxStoryLayout as bQ, UnsupportedScriptError as bR, type VerticalAlign as bS, appliedSpaceBefore as bT, applyLineSpacing as bU, baselineShiftPtOf as bV, borderExtentPt as bW, borderWeight as bX, bottomBorderExtentPt as bY, boundedStructuralFontValidator as bZ, buildNumberingIndex as b_, type ParagraphBottomBorderRecord as ba, type ParagraphIndent as bb, type ParagraphLayoutInputs as bc, type ParagraphLineSpacing as bd, type ParagraphSpacing as be, type RefFieldSpec as bf, type RefNoteParts as bg, type ResolvedCellBorders as bh, type ResolvedPictureBullet as bi, type ResolvedTabStops as bj, type ResolvedTableBorderEdge as bk, type ResolvedTableBorderEdgeSegment as bl, type ResolvedUnderline as bm, SINGLE_LINE_SPACING as bn, type ScriptItem as bo, type SemanticArtifactRootStoryKind as bp, type SemanticArtifactStoryKind as bq, type SemanticCommentArtifactRecord as br, type SemanticReviewArtifactOccurrence as bs, type SemanticReviewArtifactOccurrenceGeometry as bt, type SemanticReviewArtifactPosition as bu, type SemanticReviewArtifactSource as bv, type SemanticTrackedChangeArtifactRecord as bw, type ShapeInput as bx, type ShapedCluster as by, type ShapedFontSpan as bz, type TableRowFragmentRecord as c, cascadeParagraphFormatting as c0, cascadeRunProperties as c1, cascadedBottomBorder as c2, cascadedParagraphBorders as c3, cascadedTabStops as c4, collapsedSpaceBefore as c5, createFontResourceSnapshot as c6, createShapedRun as c7, createShapingEnvironment as c8, defaultTabIntervalFromSettings as c9, resolveBorderConflict as cA, resolveNumberingLevel as cB, resolveParagraphLayoutInputs as cC, resolveRunStyle as cD, resolveStoryListItems as cE, resolveStoryRefFields as cF, resolveTableCellBorderGrid as cG, runStylesEqual as cH, shapedRunComparatorInputs as cI, shapingEnvironmentFingerprint as cJ, shapingEnvironmentFingerprintInputs as cK, styleForFontSlot as cL, tabAdvanceWidth as cM, tabStopsFingerprint as cN, walkStoryParagraphs as cO, withDefaultTabInterval as cP, withNumberingStyleLinks as cQ, withResolvedListItems as cR, displayText as ca, fixedPoint as cb, fontRequestKey as cc, glyphSizeFactorOf as cd, isValidStyleId as ce, itemizeScriptFontSlots as cf, layoutEquation as cg, measureDisplayText as ch, mergeListIndent as ci, nextTabDestination as cj, pageBordersFingerprint as ck, paragraphBorderExtentPt as cl, paragraphBorderStrokeWidthPt as cm, paragraphBorders as cn, paragraphBordersFingerprint as co, paragraphBreaksBefore as cp, paragraphContextualSpacing as cq, paragraphLineSpacing as cr, paragraphSpacing as cs, paragraphTabStops as ct, parsePageBorders as cu, parseRefInstruction as cv, readBorderSide as cw, readCellBorders as cx, readNumPr as cy, readTableBorders as cz, type TableCellFragmentRecord as d, type ShapingEnvironmentInput as e, type TextShaper as f, type ResolvedFont as g, type FixedPointRoundingMode as h, type FontRequest as i, type SemanticReviewArtifactRecord as j, type ListMarkerPictureRecord as k, type FontSubstitution as l, type ShapedRun as m, type NumberingLevel as n, type NumberingIndex as o, type ParagraphFragmentRecord as p, type LayoutBox as q, type DrawingInsets as r, type TableBorderSide as s, type PageRecord as t, type ResolvedListItem as u, type CellBorderBox as v, type TableCellStyleFormatting as w, type TableFloatPosition as x, type TableBorderBox as y, type StyleCascadeTable as z };
|