@docx-editor.dev/core 2.15.1 → 2.16.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 +9 -15
- package/dist/automation.cjs +1 -1
- package/dist/automation.d.ts +11 -9
- package/dist/automation.js +1 -1
- package/dist/binding.cjs +1 -1
- package/dist/binding.d.ts +12 -16
- package/dist/binding.js +1 -1
- package/dist/{chunk-Q4AB7E4O.cjs → chunk-4MIFIUEV.cjs} +1 -1
- package/dist/chunk-66DTF4TD.cjs +2 -0
- package/dist/chunk-67U2OZS7.cjs +2 -0
- package/dist/chunk-6EGMDUL7.js +21 -0
- package/dist/chunk-ABXCIZVW.js +2 -0
- package/dist/chunk-AEIAYDCG.js +1 -0
- package/dist/{chunk-YL4Q5LZP.cjs → chunk-BPSGGVP5.cjs} +1 -1
- package/dist/chunk-CMV2MTDE.js +5 -0
- package/dist/chunk-DYPT6YDY.js +1 -0
- package/dist/chunk-EWV5JMJY.cjs +21 -0
- package/dist/chunk-FAD7DH6Q.cjs +1 -0
- package/dist/chunk-GHNTGVKG.cjs +11 -0
- package/dist/chunk-GQVKCK33.js +2 -0
- package/dist/chunk-I4ENGOOZ.js +1 -0
- package/dist/chunk-IZHDCQUC.js +20 -0
- package/dist/chunk-KEXMDQ2Z.js +1 -0
- package/dist/chunk-KQEUFAAG.cjs +20 -0
- package/dist/chunk-QVJO5FUR.js +11 -0
- package/dist/chunk-SIUUTE5M.js +2 -0
- package/dist/chunk-TDHR2QLH.cjs +1 -0
- package/dist/{chunk-PXKZUTHX.cjs → chunk-WGHVIB6B.cjs} +2 -2
- package/dist/chunk-XKQTITOJ.cjs +5 -0
- package/dist/{chunk-KXPVOPR5.js → chunk-YKDRBDI2.js} +1 -1
- package/dist/chunk-YRTRPSSA.cjs +1 -0
- 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 +4 -4
- package/dist/contracts/editor.d.ts +9 -7
- package/dist/contracts/interaction.d.ts +73 -10
- package/dist/contracts/modules.d.ts +8 -8
- package/dist/{custom-node-writes-C9ArIlJh.d.ts → custom-node-writes-4WOL8JB_.d.ts} +2 -2
- package/dist/{editor-sRxrFJd8.d.ts → editor-PDx0fqSo.d.ts} +26 -125
- package/dist/editor-scope-DZJT4ukT.d.ts +53 -0
- package/dist/editor.cjs +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.d.ts +32 -26
- package/dist/editor.js +1 -1
- package/dist/export.cjs +2 -2
- package/dist/export.d.ts +24 -12
- package/dist/export.js +2 -2
- package/dist/{font-resolver-BYEHQGTw.d.ts → font-resolver-CdqOugwZ.d.ts} +2 -2
- package/dist/{headless-document-view-DELC4E5v.d.ts → headless-document-view-C9ONlGtf.d.ts} +2 -2
- package/dist/{hf-references-DTrHkktY.d.ts → hf-references-BZVHctVD.d.ts} +1 -1
- package/dist/{index-C3Gvq4jN.d.ts → index-BVb4a6O3.d.ts} +74 -28
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +20 -18
- package/dist/index.js +1 -1
- package/dist/{layout-shaping-DoGR5cf8.d.ts → layout-shaping-D_U5z-Qh.d.ts} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.d.ts +270 -459
- package/dist/layout.js +1 -1
- package/dist/{note-properties-DSe8igrz.d.ts → note-properties-BosjbkGC.d.ts} +1 -1
- package/dist/{omml-equation-BpRmfDAf.d.ts → omml-equation-oLlbPpVy.d.ts} +1 -1
- package/dist/output.cjs +1 -1
- package/dist/output.d.ts +6 -6
- package/dist/output.js +1 -1
- package/dist/{protocol-DZzKxH5r.d.ts → protocol-CUsqt13U.d.ts} +28 -6
- package/dist/{review-items-DYRx187i.d.ts → review-items-kC-YI70C.d.ts} +1 -1
- package/dist/{review-reads-LbGUdNzn.d.ts → review-reads-DdvADsmp.d.ts} +8 -7
- package/dist/{revision-projection-DHRJH48u.d.ts → revision-projection-CN_DiOl_.d.ts} +1 -1
- package/dist/{semantic-cell-selection-BXVWCBYm.d.ts → semantic-cell-selection-BMrXDniV.d.ts} +4 -4
- package/dist/{semantic-interaction-DZsDmPg5.d.ts → semantic-interaction-NGeYzYCN.d.ts} +1 -1
- package/dist/{semantic-paint-f7SqN4oW.d.ts → semantic-paint-CM8F-8pH.d.ts} +2 -2
- package/dist/{semantic-records-EIdwId-a.d.ts → semantic-records-BreR44Ki.d.ts} +1231 -947
- package/dist/store.cjs +1 -1
- package/dist/store.d.ts +80 -20
- package/dist/store.js +1 -1
- package/dist/{tree-op-types-egdarvH_.d.ts → tree-op-types-C5rZzoAz.d.ts} +131 -53
- package/dist/{tree-package-fragment-DjkH4ESI.d.ts → tree-package-fragment-DDQHk8sv.d.ts} +3 -3
- package/dist/{tree-session-contract-CGOOgPjW.d.ts → tree-session-contract-dKgbKH9A.d.ts} +18 -8
- package/dist/{tree-store-DKJB0IcA.d.ts → tree-store-DU192chS.d.ts} +1 -1
- package/package.json +2 -2
- package/dist/chunk-24APKZAN.cjs +0 -11
- package/dist/chunk-2YH4MSHX.cjs +0 -2
- package/dist/chunk-5Y7AADI6.js +0 -1
- package/dist/chunk-AREFLNUP.js +0 -11
- package/dist/chunk-AS7YZNQE.cjs +0 -2
- package/dist/chunk-AVGCKH6A.cjs +0 -20
- package/dist/chunk-CDYVDQRI.cjs +0 -5
- package/dist/chunk-HOEWFH5U.cjs +0 -1
- package/dist/chunk-KFELX7CN.js +0 -2
- package/dist/chunk-LGFKIF4M.cjs +0 -1
- package/dist/chunk-M52QXFKI.js +0 -1
- package/dist/chunk-MNUKSXRO.js +0 -1
- package/dist/chunk-PBOIGBDO.js +0 -2
- package/dist/chunk-PMHGONET.cjs +0 -1
- package/dist/chunk-QJYH6AYD.js +0 -1
- package/dist/chunk-QRC37MWG.cjs +0 -20
- package/dist/chunk-RJSB6RJ7.js +0 -20
- package/dist/chunk-SB54HLFJ.js +0 -20
- package/dist/chunk-XCESLTJL.js +0 -2
- package/dist/chunk-Z4527AXR.js +0 -5
|
@@ -1,264 +1,174 @@
|
|
|
1
|
-
import { b as RevisionAttribution, R as RevisionDisplayMode } from './revision-projection-
|
|
2
|
-
import {
|
|
3
|
-
import { O as OmmlEquationProjection } from './omml-equation-
|
|
1
|
+
import { b as RevisionAttribution, R as RevisionDisplayMode, a as RevisionAuthorFilter } from './revision-projection-CN_DiOl_.js';
|
|
2
|
+
import { q as OoxmlProperty, c as OoxmlElement, a as OoxmlNode, O as OoxmlPart, U as TableBorderStyle, x as ImageResourceState, W as DrawingAccessibility, X as DrawingImageEffects, S as SourceCrop, Y as DrawingTransform, Z as VectorShapeProjection, z as DrawingHorizontalReferenceFrame, A as DrawingVerticalReferenceFrame, u as ImageWrapTarget, _ as DrawingProjection, $ as OoxmlDrawingNode } from './tree-op-types-C5rZzoAz.js';
|
|
3
|
+
import { O as OmmlEquationProjection } from './omml-equation-oLlbPpVy.js';
|
|
4
4
|
|
|
5
|
+
/** Soft ceiling on abstractNum / num entries read from one part. */
|
|
6
|
+
declare const MAX_NUMBERING_DEFINITIONS = 512;
|
|
7
|
+
/** Soft ceiling on override entries per `w:num`. */
|
|
8
|
+
declare const MAX_LVL_OVERRIDES = 9;
|
|
9
|
+
/** `w:suff` — what separates a list marker from the text after it. */
|
|
10
|
+
type ListSuffix = 'tab' | 'space' | 'nothing';
|
|
11
|
+
/** `w:lvlJc` — how a list marker aligns within its own indent. */
|
|
12
|
+
type ListMarkerAlign = 'left' | 'center' | 'right';
|
|
5
13
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
9
|
-
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
10
|
-
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
11
|
-
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
12
|
-
* page number after it was wrong.
|
|
14
|
+
* One level's indent, plus which parts the level actually AUTHORED.
|
|
13
15
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
20
|
-
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
16
|
+
* The provenance matters: `w:ind` cascades per-attribute, so a level that authored only `left`
|
|
17
|
+
* must not overwrite an inherited `hanging` with a synthesized zero.
|
|
21
18
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
interface NumberingLevelIndent {
|
|
20
|
+
readonly left: number;
|
|
21
|
+
readonly right: number;
|
|
22
|
+
readonly hanging: number;
|
|
23
|
+
readonly firstLine: number;
|
|
24
|
+
/**
|
|
25
|
+
* Which of these the LEVEL actually authored.
|
|
26
|
+
*
|
|
27
|
+
* A level's `w:pPr/w:ind` sits between the paragraph style and direct formatting, so the
|
|
28
|
+
* merge has to tell "the level says left = 0" from "the level says nothing about left and
|
|
29
|
+
* the style's value stands". Absent (the default) reads as "says nothing", which is what a
|
|
30
|
+
* hand-built level in a test means.
|
|
31
|
+
*/
|
|
32
|
+
readonly stated?: {
|
|
33
|
+
readonly left: boolean;
|
|
34
|
+
readonly right: boolean;
|
|
35
|
+
/** `w:hanging`/`w:firstLine` are one mutually exclusive slot (§17.3.1.10, §17.3.1.12). */
|
|
36
|
+
readonly firstLineOffset: boolean;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** One `w:lvl`: how this depth numbers, what its marker looks like, and how it indents. */
|
|
40
|
+
interface NumberingLevel {
|
|
41
|
+
readonly ilvl: number;
|
|
42
|
+
readonly start: number;
|
|
43
|
+
readonly numFmt: string;
|
|
44
|
+
readonly lvlText: string;
|
|
45
|
+
readonly lvlJc: ListMarkerAlign;
|
|
46
|
+
readonly suff: ListSuffix;
|
|
47
|
+
readonly indent: NumberingLevelIndent;
|
|
48
|
+
/**
|
|
49
|
+
* `w:lvlRestart` one-based trigger level, or `0` when the level never restarts.
|
|
50
|
+
* Omitted in XML → restart when the previous level (or any earlier level) is used.
|
|
51
|
+
*/
|
|
52
|
+
readonly lvlRestart?: number;
|
|
53
|
+
/**
|
|
54
|
+
* `w:isLgl` (§17.9.9): render EVERY level referenced by this level's `w:lvlText` in
|
|
55
|
+
* decimal, whatever number format those levels declare for themselves.
|
|
56
|
+
*/
|
|
57
|
+
readonly isLgl: boolean;
|
|
58
|
+
/** Level `w:rPr` as flat properties (for marker face / vanish). */
|
|
59
|
+
readonly runProperties: readonly OoxmlProperty[];
|
|
60
|
+
/** True when level run props request vanish — marker must not paint. */
|
|
61
|
+
readonly vanish: boolean;
|
|
62
|
+
}
|
|
27
63
|
/**
|
|
28
|
-
*
|
|
64
|
+
* One `w:lvlOverride` on a `w:num`: a restart value, a replacement level, or both.
|
|
29
65
|
*
|
|
30
|
-
*
|
|
31
|
-
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
66
|
+
* How two lists share an abstract definition while numbering independently.
|
|
32
67
|
*/
|
|
33
|
-
interface
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
readonly after: number;
|
|
68
|
+
interface LevelOverride {
|
|
69
|
+
readonly startOverride?: number;
|
|
70
|
+
/** Full level replacement when `w:lvl` is present under the override. */
|
|
71
|
+
readonly level?: NumberingLevel;
|
|
38
72
|
}
|
|
39
73
|
/**
|
|
40
|
-
*
|
|
41
|
-
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
74
|
+
* One `w:abstractNum` — the shape of a list, without being a list.
|
|
42
75
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
46
|
-
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
47
|
-
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
76
|
+
* Never referenced by a paragraph directly. Paragraphs name a {@link NumDefinition}, which names
|
|
77
|
+
* one of these, so several lists can share a definition and still count separately.
|
|
48
78
|
*/
|
|
49
|
-
|
|
79
|
+
interface AbstractNumDefinition {
|
|
80
|
+
readonly abstractNumId: string;
|
|
81
|
+
readonly levels: ReadonlyMap<number, NumberingLevel>;
|
|
82
|
+
/**
|
|
83
|
+
* `w:numStyleLink` (§17.9.21): this definition carries no levels of its own — the numbering
|
|
84
|
+
* lives on the named style. Word follows the link; resolve it with
|
|
85
|
+
* {@link resolveNumberingStyleLinks} before reading levels, or every paragraph on this
|
|
86
|
+
* abstract renders with NO marker at all.
|
|
87
|
+
*/
|
|
88
|
+
readonly numStyleLink?: string;
|
|
89
|
+
/**
|
|
90
|
+
* `w:styleLink` (§17.9.23): the definition side of the same pair — this abstract IS the
|
|
91
|
+
* numbering of the named style. Kept so a link can be verified rather than assumed.
|
|
92
|
+
*/
|
|
93
|
+
readonly styleLink?: string;
|
|
94
|
+
}
|
|
50
95
|
/**
|
|
51
|
-
*
|
|
52
|
-
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
96
|
+
* One `w:num` — the thing a paragraph's `w:numId` actually names.
|
|
53
97
|
*
|
|
54
|
-
*
|
|
55
|
-
* paragraph margin, a bare `<p>` does not. A caller that says nothing gets the body answer.
|
|
98
|
+
* Points at an {@link AbstractNumDefinition} and may override any of its levels.
|
|
56
99
|
*/
|
|
57
|
-
interface
|
|
58
|
-
|
|
59
|
-
readonly
|
|
60
|
-
|
|
61
|
-
readonly inTableCell?: boolean;
|
|
100
|
+
interface NumDefinition {
|
|
101
|
+
readonly numId: string;
|
|
102
|
+
readonly abstractNumId: string;
|
|
103
|
+
readonly overrides: ReadonlyMap<number, LevelOverride>;
|
|
62
104
|
}
|
|
63
105
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
67
|
-
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
68
|
-
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
69
|
-
* moves every page break, so this is not a cosmetic detail.
|
|
106
|
+
* The bounded projection of `numbering.xml` that list layout resolves against.
|
|
70
107
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
108
|
+
* Projection ONLY — never a mutation or serialization authority. Hostile values are dropped or
|
|
109
|
+
* clamped, and a missing definition resolves to "no list" rather than a guess.
|
|
73
110
|
*/
|
|
74
|
-
|
|
111
|
+
interface NumberingIndex {
|
|
112
|
+
readonly abstractNums: ReadonlyMap<string, AbstractNumDefinition>;
|
|
113
|
+
readonly nums: ReadonlyMap<string, NumDefinition>;
|
|
114
|
+
}
|
|
75
115
|
/**
|
|
76
|
-
*
|
|
116
|
+
* Build a numbering index from the root of a numbering part (`w:numbering`).
|
|
77
117
|
*
|
|
78
|
-
*
|
|
79
|
-
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
118
|
+
* Empty / missing roots yield an empty index. Duplicate ids keep the first definition.
|
|
80
119
|
*/
|
|
81
|
-
interface ParagraphLineSpacing {
|
|
82
|
-
readonly rule: LineSpacingRule;
|
|
83
|
-
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
84
|
-
readonly value: number;
|
|
85
|
-
}
|
|
86
|
-
/** Single spacing: what a paragraph that says nothing gets. */
|
|
87
|
-
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
88
120
|
/**
|
|
89
|
-
*
|
|
121
|
+
* Project `numbering.xml` into the bounded index.
|
|
90
122
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
123
|
+
* Every ceiling here exists because the input is file-derived: definition counts, override
|
|
124
|
+
* counts, indent magnitudes and style-link hop depth are all capped, and nothing from the file
|
|
125
|
+
* becomes a loop bound or an allocation size.
|
|
93
126
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
readonly val: string;
|
|
97
|
-
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
98
|
-
readonly color: string | null;
|
|
99
|
-
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
100
|
-
readonly widthPt: number;
|
|
101
|
-
/** Gap from text to the rule, in points (`w:space`). */
|
|
102
|
-
readonly spacePt: number;
|
|
103
|
-
/**
|
|
104
|
-
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
105
|
-
*
|
|
106
|
-
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
107
|
-
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
108
|
-
*/
|
|
109
|
-
readonly shadow?: true;
|
|
110
|
-
}
|
|
111
|
-
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
112
|
-
declare const PARAGRAPH_BORDER_SIDES: readonly ["top", "left", "bottom", "right", "between", "bar"];
|
|
127
|
+
declare function buildNumberingIndex(root: OoxmlElement | null | undefined): NumberingIndex;
|
|
128
|
+
/** Resolve the effective level for a `numId` + `ilvl`, applying overrides. */
|
|
113
129
|
/**
|
|
114
|
-
*
|
|
130
|
+
* The effective level for one paragraph's numbering reference, after overrides and style links.
|
|
115
131
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
132
|
+
* Answers null for a reference the index cannot resolve — a paragraph naming a definition the
|
|
133
|
+
* file never declared is an unnumbered paragraph, not an error.
|
|
118
134
|
*/
|
|
119
|
-
|
|
135
|
+
declare function resolveNumberingLevel(index: NumberingIndex, numId: string, ilvl: number): {
|
|
136
|
+
readonly abstractNumId: string;
|
|
137
|
+
readonly level: NumberingLevel;
|
|
138
|
+
readonly startOverride?: number;
|
|
139
|
+
} | null;
|
|
140
|
+
/** Empty index for tests / documents without numbering. */
|
|
141
|
+
declare const EMPTY_NUMBERING_INDEX: NumberingIndex;
|
|
142
|
+
|
|
143
|
+
/** Soft ceiling matching Word's practical custom-tab UI limit. */
|
|
144
|
+
declare const MAX_TAB_STOPS = 64;
|
|
120
145
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
124
|
-
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
125
|
-
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
126
|
-
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
146
|
+
* Soft ceiling on a tab position (31_680 twips ≈ 22"), matching paragraph-spacing bounds so
|
|
147
|
+
* a hostile stop cannot shove layout into pathological widths.
|
|
127
148
|
*/
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
readonly between?: ParagraphBorderEdge;
|
|
134
|
-
readonly bar?: ParagraphBorderEdge;
|
|
135
|
-
}
|
|
149
|
+
declare const MAX_TAB_POSITION_TWIPS = 31680;
|
|
150
|
+
/** OOXML / Word default when `w:settings/w:defaultTabStop` is absent: 720 twips = 0.5". */
|
|
151
|
+
declare const DEFAULT_TAB_INTERVAL_TWIPS = 720;
|
|
152
|
+
/** The default tab interval in points — {@link DEFAULT_TAB_INTERVAL_TWIPS} converted. */
|
|
153
|
+
declare const DEFAULT_TAB_INTERVAL_PT: number;
|
|
136
154
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
140
|
-
* height, not the gap between paragraphs — and is not resolved here.
|
|
155
|
+
* How a tab stop positions the text that follows it.
|
|
141
156
|
*
|
|
142
|
-
* `
|
|
143
|
-
*
|
|
157
|
+
* Only `left` is a plain cursor jump. The other three size the tab glyph from the MEASURED
|
|
158
|
+
* following segment, so its end, centre or decimal point lands on the stop.
|
|
144
159
|
*/
|
|
145
|
-
|
|
160
|
+
type TabAlignment = 'left' | 'center' | 'right' | 'decimal';
|
|
146
161
|
/**
|
|
147
|
-
*
|
|
162
|
+
* `w:tab/@w:leader` (ECMA-376 §17.3.1.38, ST_TabTlc): the character repeated across the
|
|
163
|
+
* space a tab reserves. `none` is the default and is represented by an absent leader.
|
|
148
164
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
165
|
+
* This is the difference between a Word table of contents and a column of headings floating
|
|
166
|
+
* next to a column of page numbers, so it is carried through layout to paint rather than
|
|
167
|
+
* dropped as a geometry-irrelevant attribute.
|
|
152
168
|
*/
|
|
153
|
-
|
|
169
|
+
type TabLeader = 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
154
170
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* Word places `auto` / `atLeast` extras BELOW the line (the last line's multiple spacing
|
|
158
|
-
* still separates it from the next paragraph). Putting that delta above inverted cover-page
|
|
159
|
-
* rhythm: `w:line="460"` on "between" opened a large gap above the word and almost none
|
|
160
|
-
* before "MERIDIAN". `exact` taller than the glyphs centers the text (ECMA-376 17.3.1.33).
|
|
161
|
-
* An `exact` box smaller than the glyphs keeps the baseline inside so clipped text still
|
|
162
|
-
* sits on it.
|
|
163
|
-
*/
|
|
164
|
-
declare function applyLineSpacing(spacing: ParagraphLineSpacing, naturalHeight: number, naturalBaseline: number): {
|
|
165
|
-
height: number;
|
|
166
|
-
baseline: number;
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* `w:contextualSpacing` (17.3.1.9): drop before/after between paragraphs of the SAME
|
|
170
|
-
* style. Word's built-in `ListParagraph` sets it, so every list authored in Word gets a
|
|
171
|
-
* paragraph gap between items without this.
|
|
172
|
-
*/
|
|
173
|
-
declare function paragraphContextualSpacing(props: readonly OoxmlProperty[]): boolean;
|
|
174
|
-
/**
|
|
175
|
-
* Resolve `w:pBdr` from the paragraph-properties node.
|
|
176
|
-
*
|
|
177
|
-
* Nested — every edge is a child of `pBdr`, not an attribute — so this reads the typed tree
|
|
178
|
-
* rather than the flattened `OoxmlProperty[]` bag `propertiesOf` builds for leaf props.
|
|
179
|
-
*/
|
|
180
|
-
declare function paragraphBorders(pPr: OoxmlNode | undefined): ParagraphBorders;
|
|
181
|
-
/**
|
|
182
|
-
* `w:pBdr` after the style cascade: a later `w:pBdr` replaces an earlier one WHOLESALE.
|
|
183
|
-
*
|
|
184
|
-
* Word does not merge edges across the cascade. A style that states only `w:bottom` discards
|
|
185
|
-
* the box its `basedOn` ancestor declared, so folding edge by edge would leave a lone
|
|
186
|
-
* underline surrounded by a box no one authored. Absence inherits; `nil`/`none` clear.
|
|
187
|
-
*/
|
|
188
|
-
declare function cascadedParagraphBorders(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorders;
|
|
189
|
-
/**
|
|
190
|
-
* Visual stroke thickness layout publishes for one edge (points).
|
|
191
|
-
*
|
|
192
|
-
* Compound `ST_Border` values (`double`, …) use the shared inflated band so a thin
|
|
193
|
-
* `w:sz="3"` double still occupies a visible double-line box — matching table borders.
|
|
194
|
-
*/
|
|
195
|
-
declare function paragraphBorderStrokeWidthPt(edge: ParagraphBorderEdge): number;
|
|
196
|
-
/**
|
|
197
|
-
* Extent one border edge occupies away from the text it decorates: gap plus rule, in points.
|
|
198
|
-
*
|
|
199
|
-
* Vertically that is flow height — a top rule pushes the first line down, a bottom rule holds
|
|
200
|
-
* the page open below the last one — so pagination has to see it. Horizontally it is
|
|
201
|
-
* publish-only: Word draws left/right paragraph rules OUTSIDE the text column and never
|
|
202
|
-
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
203
|
-
*/
|
|
204
|
-
declare function paragraphBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
205
|
-
/** Vertical extent a bottom border adds below the last line (gap + rule). */
|
|
206
|
-
declare function bottomBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
207
|
-
/**
|
|
208
|
-
* Identity of a paragraph's border set, for the `w:between` group rule.
|
|
209
|
-
*
|
|
210
|
-
* Word treats consecutive paragraphs whose border settings are IDENTICAL as ONE bordered
|
|
211
|
-
* block: the top rule draws above the first, the bottom rule below the last, and each
|
|
212
|
-
* interior boundary gets `w:between` or nothing (§17.3.1.24). That is why applying a box to
|
|
213
|
-
* three selected paragraphs in Word draws one box and not three.
|
|
214
|
-
*
|
|
215
|
-
* Empty string means "no borders", which never groups with anything.
|
|
216
|
-
*/
|
|
217
|
-
declare function paragraphBordersFingerprint(borders: ParagraphBorders): string;
|
|
218
|
-
/**
|
|
219
|
-
* Gap to insert before a paragraph once the previous paragraph's `after` is already in the
|
|
220
|
-
* flow cursor — Word takes the larger of the two rather than summing them.
|
|
221
|
-
*/
|
|
222
|
-
declare function collapsedSpaceBefore(before: number, previousAfter: number): number;
|
|
223
|
-
/**
|
|
224
|
-
* Applied before-spacing for placement (Word 2013+ / compat mode 15).
|
|
225
|
-
*
|
|
226
|
-
* Adjacent before/after still collapse to the larger gap, but before is dropped entirely when
|
|
227
|
-
* the paragraph begins at the top of a page mid-section. The first paragraph of a document or
|
|
228
|
-
* section retains before. Callers publish this applied value on the fragment so shading, borders,
|
|
229
|
-
* selection, and paint share one geometry.
|
|
230
|
-
*/
|
|
231
|
-
declare function appliedSpaceBefore(before: number, previousAfter: number, atTopOfPage: boolean, firstParagraphOfSection: boolean): number;
|
|
232
|
-
|
|
233
|
-
/** Soft ceiling matching Word's practical custom-tab UI limit. */
|
|
234
|
-
declare const MAX_TAB_STOPS = 64;
|
|
235
|
-
/**
|
|
236
|
-
* Soft ceiling on a tab position (31_680 twips ≈ 22"), matching paragraph-spacing bounds so
|
|
237
|
-
* a hostile stop cannot shove layout into pathological widths.
|
|
238
|
-
*/
|
|
239
|
-
declare const MAX_TAB_POSITION_TWIPS = 31680;
|
|
240
|
-
/** OOXML / Word default when `w:settings/w:defaultTabStop` is absent: 720 twips = 0.5". */
|
|
241
|
-
declare const DEFAULT_TAB_INTERVAL_TWIPS = 720;
|
|
242
|
-
/** The default tab interval in points — {@link DEFAULT_TAB_INTERVAL_TWIPS} converted. */
|
|
243
|
-
declare const DEFAULT_TAB_INTERVAL_PT: number;
|
|
244
|
-
/**
|
|
245
|
-
* How a tab stop positions the text that follows it.
|
|
246
|
-
*
|
|
247
|
-
* Only `left` is a plain cursor jump. The other three size the tab glyph from the MEASURED
|
|
248
|
-
* following segment, so its end, centre or decimal point lands on the stop.
|
|
249
|
-
*/
|
|
250
|
-
type TabAlignment = 'left' | 'center' | 'right' | 'decimal';
|
|
251
|
-
/**
|
|
252
|
-
* `w:tab/@w:leader` (ECMA-376 §17.3.1.38, ST_TabTlc): the character repeated across the
|
|
253
|
-
* space a tab reserves. `none` is the default and is represented by an absent leader.
|
|
254
|
-
*
|
|
255
|
-
* This is the difference between a Word table of contents and a column of headings floating
|
|
256
|
-
* next to a column of page numbers, so it is carried through layout to paint rather than
|
|
257
|
-
* dropped as a geometry-irrelevant attribute.
|
|
258
|
-
*/
|
|
259
|
-
type TabLeader = 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
|
|
260
|
-
/**
|
|
261
|
-
* The character each leader repeats (§17.3.1.38, ST_TabTlc).
|
|
171
|
+
* The character each leader repeats (§17.3.1.38, ST_TabTlc).
|
|
262
172
|
*
|
|
263
173
|
* Lives with the type rather than with the painter because LAYOUT has to measure it: a
|
|
264
174
|
* leader is the same character typed over and over, and the only way to space it the way
|
|
@@ -339,6 +249,125 @@ declare function tabAdvanceWidth(alignment: TabAlignment, currentX: number, dest
|
|
|
339
249
|
*/
|
|
340
250
|
declare function tabStopsFingerprint(tabs: ResolvedTabStops): string;
|
|
341
251
|
|
|
252
|
+
/** `w:vertAlign` — script position, which also scales the run's effective size. */
|
|
253
|
+
type VerticalAlign = 'baseline' | 'superscript' | 'subscript';
|
|
254
|
+
/** A resolved underline: its variant, and its colour when it does not follow the text. */
|
|
255
|
+
interface ResolvedUnderline {
|
|
256
|
+
/** The authored `ST_Underline` variant. */
|
|
257
|
+
readonly variant: string;
|
|
258
|
+
/** RRGGBB, or null when the underline follows the text colour. */
|
|
259
|
+
readonly color: string | null;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* A run's character properties after the full cascade, in the units layout works in.
|
|
263
|
+
*
|
|
264
|
+
* Points rather than half-points, RRGGBB rather than theme references — everything already
|
|
265
|
+
* resolved, so measurement and paint never re-run the cascade per glyph.
|
|
266
|
+
*/
|
|
267
|
+
interface ResolvedRunStyle {
|
|
268
|
+
readonly fontFamily: string | null;
|
|
269
|
+
/**
|
|
270
|
+
* The `eastAsia` slot's typeface (`w:rFonts w:eastAsia`/`w:eastAsiaTheme`), or null when
|
|
271
|
+
* no level authors one.
|
|
272
|
+
*
|
|
273
|
+
* OOXML picks a run's face per SCRIPT: `fontFamily` covers the ascii/hAnsi slots, and
|
|
274
|
+
* ideographic/kana/hangul text resolves through this one instead. Kept beside — not
|
|
275
|
+
* folded into — `fontFamily`, because a mixed run needs both at once and the split into
|
|
276
|
+
* slot-homogeneous pieces happens downstream (`piecesOfParagraph`).
|
|
277
|
+
*/
|
|
278
|
+
readonly fontFamilyEastAsia: string | null;
|
|
279
|
+
/** Points. `w:sz` is half-points, so 22 becomes 11. */
|
|
280
|
+
readonly fontSizePt: number;
|
|
281
|
+
/** RRGGBB, or null for the inherited/automatic colour. */
|
|
282
|
+
readonly color: string | null;
|
|
283
|
+
readonly bold: boolean;
|
|
284
|
+
/** Opaque solid `w14:textOutline`, in points; paint only, never a font-weight change. */
|
|
285
|
+
readonly textOutline?: {
|
|
286
|
+
readonly widthPt: number;
|
|
287
|
+
readonly color: string;
|
|
288
|
+
};
|
|
289
|
+
readonly italic: boolean;
|
|
290
|
+
readonly underline: ResolvedUnderline | null;
|
|
291
|
+
readonly strike: boolean;
|
|
292
|
+
readonly doubleStrike: boolean;
|
|
293
|
+
/** An `ST_HighlightColor` name, or null. */
|
|
294
|
+
readonly highlight: string | null;
|
|
295
|
+
/**
|
|
296
|
+
* Character shading fill (`w:rPr/w:shd`), validated RRGGBB, or null.
|
|
297
|
+
*
|
|
298
|
+
* Paint applies this as the glyph-box background; a recognised highlight overrides it.
|
|
299
|
+
* Measurement ignores shading.
|
|
300
|
+
*/
|
|
301
|
+
readonly shading: string | null;
|
|
302
|
+
readonly verticalAlign: VerticalAlign;
|
|
303
|
+
/** `w:position`, in points. Positive raises the baseline. */
|
|
304
|
+
readonly baselineShiftPt: number;
|
|
305
|
+
readonly caps: boolean;
|
|
306
|
+
readonly smallCaps: boolean;
|
|
307
|
+
/** `w:spacing`, in points. Added to every advance. */
|
|
308
|
+
readonly characterSpacingPt: number;
|
|
309
|
+
/** `w:w`, as a percentage. 100 is unscaled. */
|
|
310
|
+
readonly horizontalScalePercent: number;
|
|
311
|
+
/** `w:kern`, in points: the size at or above which kerning applies. 0 disables it. */
|
|
312
|
+
readonly kerningMinPt: number;
|
|
313
|
+
/**
|
|
314
|
+
* `w:vanish` (ECMA-376 §17.3.2.45): the run is hidden text.
|
|
315
|
+
*
|
|
316
|
+
* Word does not draw it AND does not paginate it — hidden index or comment text takes no
|
|
317
|
+
* space at all. So this cannot be a paint-time opacity: a hidden run that is still measured
|
|
318
|
+
* pushes every following line, and every following page break, to the wrong place. Layout
|
|
319
|
+
* drops the content instead (see `piecesOfParagraph`).
|
|
320
|
+
*
|
|
321
|
+
* `w:specVanish` (§17.3.2.36) is a different property — an always-hidden paragraph mark on
|
|
322
|
+
* a heading — and never sets this.
|
|
323
|
+
*/
|
|
324
|
+
readonly hidden: boolean;
|
|
325
|
+
}
|
|
326
|
+
/** The style a run inherits when it authors nothing. */
|
|
327
|
+
declare const DEFAULT_RUN_STYLE: ResolvedRunStyle;
|
|
328
|
+
/**
|
|
329
|
+
* The theme part's typefaces, for resolving `w:rFonts` theme attributes.
|
|
330
|
+
*
|
|
331
|
+
* Structurally identical to the binding lane's `DocumentThemeFonts` and assignable from it.
|
|
332
|
+
* Declared here so this lane reads validated strings rather than the theme tree.
|
|
333
|
+
*/
|
|
334
|
+
interface ThemeFonts {
|
|
335
|
+
/** `a:majorFont` latin typeface — headings. */
|
|
336
|
+
readonly major: string | null;
|
|
337
|
+
/** `a:minorFont` latin typeface — body text. */
|
|
338
|
+
readonly minor: string | null;
|
|
339
|
+
/** `a:majorFont` east asian typeface (`a:ea`) — headings. Optional for back-compat. */
|
|
340
|
+
readonly majorEastAsia?: string | null;
|
|
341
|
+
/** `a:minorFont` east asian typeface (`a:ea`) — body text. Optional for back-compat. */
|
|
342
|
+
readonly minorEastAsia?: string | null;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Resolve one run's direct formatting.
|
|
346
|
+
*
|
|
347
|
+
* Unrecognised values are DROPPED rather than guessed: a `w:sz` of `"large"` leaves the
|
|
348
|
+
* default size rather than inventing one, because a wrong measurement moves every glyph
|
|
349
|
+
* after it and a missing one is visible immediately.
|
|
350
|
+
*
|
|
351
|
+
* `themeFonts` resolves `w:rFonts` theme references. Absent, a theme-only `rFonts` leaves
|
|
352
|
+
* the family inherited — which is what every run of a theme-fonted document does, so the
|
|
353
|
+
* whole document falls back to the surface default face.
|
|
354
|
+
*/
|
|
355
|
+
declare function resolveRunStyle(props: readonly OoxmlProperty[], themeFonts?: ThemeFonts): ResolvedRunStyle;
|
|
356
|
+
/** The text as it is DRAWN, after case transforms. Measurement must use this, not the source. */
|
|
357
|
+
declare function displayText(text: string, style: ResolvedRunStyle): string;
|
|
358
|
+
/** Measure run text the way layout breaks lines and paints glyphs (caps/small-caps aware). */
|
|
359
|
+
declare function measureDisplayText(text: string, style: ResolvedRunStyle, measurer: TextMeasurer): number;
|
|
360
|
+
/** Whether two resolved styles are identical, for span merging and cache keys. */
|
|
361
|
+
declare function runStylesEqual(a: ResolvedRunStyle, b: ResolvedRunStyle): boolean;
|
|
362
|
+
/**
|
|
363
|
+
* How far a run's glyphs are lifted off the line's baseline, in points. Positive is up.
|
|
364
|
+
*
|
|
365
|
+
* Super and subscript move the GLYPHS without moving the run's box, so the box keeps tiling
|
|
366
|
+
* the line and the selection band stays continuous. Anything drawing at the glyphs — the
|
|
367
|
+
* painter, and the caret — has to apply this itself, and from one place, or the two drift.
|
|
368
|
+
*/
|
|
369
|
+
declare function baselineShiftPtOf(style: ResolvedRunStyle): number;
|
|
370
|
+
|
|
342
371
|
/**
|
|
343
372
|
* UAX #9 embedding levels, one per UTF-16 code unit, plus the paragraph ranges they were resolved
|
|
344
373
|
* within.
|
|
@@ -806,146 +835,32 @@ declare const createShapedRun: (input: ShapedRun, environmentInput: ShapingEnvir
|
|
|
806
835
|
*/
|
|
807
836
|
declare const shapedRunComparatorInputs: (input: ShapedRun, environment: ShapingEnvironmentInput) => ShapedRunComparatorInputs;
|
|
808
837
|
|
|
809
|
-
/**
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
838
|
+
/**
|
|
839
|
+
* Which `w:rFonts` slot a character resolves its face through.
|
|
840
|
+
*
|
|
841
|
+
* OOXML gives a run up to four faces and picks between them by SCRIPT, so one run of mixed Latin
|
|
842
|
+
* and CJK text uses two different fonts without saying so anywhere in its properties.
|
|
843
|
+
*/
|
|
844
|
+
type FontSlot = 'ascii' | 'hAnsi' | 'eastAsia' | 'cs';
|
|
845
|
+
/**
|
|
846
|
+
* A run of text sharing one script, direction and font slot — the unit handed to the shaper.
|
|
847
|
+
*
|
|
848
|
+
* Shaping cannot span a script change: Arabic and Latin in one call would produce wrong joining
|
|
849
|
+
* behaviour, so a run is itemized into these first.
|
|
850
|
+
*/
|
|
851
|
+
interface ScriptItem {
|
|
852
|
+
readonly from: number;
|
|
853
|
+
readonly to: number;
|
|
854
|
+
readonly direction: TextDirection;
|
|
855
|
+
readonly bidiLevel: number;
|
|
856
|
+
readonly script: 'Zyyy' | 'Latn' | 'Grek' | 'Cyrl' | 'Hani' | 'Hebr' | 'Arab' | 'Deva' | 'Beng' | 'Thai' | 'Khmr';
|
|
857
|
+
readonly slot: FontSlot;
|
|
817
858
|
}
|
|
818
859
|
/**
|
|
819
|
-
* A
|
|
860
|
+
* A code point whose script this engine does not itemize.
|
|
820
861
|
*
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*/
|
|
824
|
-
interface ResolvedRunStyle {
|
|
825
|
-
readonly fontFamily: string | null;
|
|
826
|
-
/**
|
|
827
|
-
* The `eastAsia` slot's typeface (`w:rFonts w:eastAsia`/`w:eastAsiaTheme`), or null when
|
|
828
|
-
* no level authors one.
|
|
829
|
-
*
|
|
830
|
-
* OOXML picks a run's face per SCRIPT: `fontFamily` covers the ascii/hAnsi slots, and
|
|
831
|
-
* ideographic/kana/hangul text resolves through this one instead. Kept beside — not
|
|
832
|
-
* folded into — `fontFamily`, because a mixed run needs both at once and the split into
|
|
833
|
-
* slot-homogeneous pieces happens downstream (`piecesOfParagraph`).
|
|
834
|
-
*/
|
|
835
|
-
readonly fontFamilyEastAsia: string | null;
|
|
836
|
-
/** Points. `w:sz` is half-points, so 22 becomes 11. */
|
|
837
|
-
readonly fontSizePt: number;
|
|
838
|
-
/** RRGGBB, or null for the inherited/automatic colour. */
|
|
839
|
-
readonly color: string | null;
|
|
840
|
-
readonly bold: boolean;
|
|
841
|
-
readonly italic: boolean;
|
|
842
|
-
readonly underline: ResolvedUnderline | null;
|
|
843
|
-
readonly strike: boolean;
|
|
844
|
-
readonly doubleStrike: boolean;
|
|
845
|
-
/** An `ST_HighlightColor` name, or null. */
|
|
846
|
-
readonly highlight: string | null;
|
|
847
|
-
/**
|
|
848
|
-
* Character shading fill (`w:rPr/w:shd`), validated RRGGBB, or null.
|
|
849
|
-
*
|
|
850
|
-
* Paint applies this as the glyph-box background; a recognised highlight overrides it.
|
|
851
|
-
* Measurement ignores shading.
|
|
852
|
-
*/
|
|
853
|
-
readonly shading: string | null;
|
|
854
|
-
readonly verticalAlign: VerticalAlign;
|
|
855
|
-
/** `w:position`, in points. Positive raises the baseline. */
|
|
856
|
-
readonly baselineShiftPt: number;
|
|
857
|
-
readonly caps: boolean;
|
|
858
|
-
readonly smallCaps: boolean;
|
|
859
|
-
/** `w:spacing`, in points. Added to every advance. */
|
|
860
|
-
readonly characterSpacingPt: number;
|
|
861
|
-
/** `w:w`, as a percentage. 100 is unscaled. */
|
|
862
|
-
readonly horizontalScalePercent: number;
|
|
863
|
-
/** `w:kern`, in points: the size at or above which kerning applies. 0 disables it. */
|
|
864
|
-
readonly kerningMinPt: number;
|
|
865
|
-
/**
|
|
866
|
-
* `w:vanish` (ECMA-376 §17.3.2.45): the run is hidden text.
|
|
867
|
-
*
|
|
868
|
-
* Word does not draw it AND does not paginate it — hidden index or comment text takes no
|
|
869
|
-
* space at all. So this cannot be a paint-time opacity: a hidden run that is still measured
|
|
870
|
-
* pushes every following line, and every following page break, to the wrong place. Layout
|
|
871
|
-
* drops the content instead (see `piecesOfParagraph`).
|
|
872
|
-
*
|
|
873
|
-
* `w:specVanish` (§17.3.2.36) is a different property — an always-hidden paragraph mark on
|
|
874
|
-
* a heading — and never sets this.
|
|
875
|
-
*/
|
|
876
|
-
readonly hidden: boolean;
|
|
877
|
-
}
|
|
878
|
-
/** The style a run inherits when it authors nothing. */
|
|
879
|
-
declare const DEFAULT_RUN_STYLE: ResolvedRunStyle;
|
|
880
|
-
/**
|
|
881
|
-
* The theme part's typefaces, for resolving `w:rFonts` theme attributes.
|
|
882
|
-
*
|
|
883
|
-
* Structurally identical to the binding lane's `DocumentThemeFonts` and assignable from it.
|
|
884
|
-
* Declared here so this lane reads validated strings rather than the theme tree.
|
|
885
|
-
*/
|
|
886
|
-
interface ThemeFonts {
|
|
887
|
-
/** `a:majorFont` latin typeface — headings. */
|
|
888
|
-
readonly major: string | null;
|
|
889
|
-
/** `a:minorFont` latin typeface — body text. */
|
|
890
|
-
readonly minor: string | null;
|
|
891
|
-
/** `a:majorFont` east asian typeface (`a:ea`) — headings. Optional for back-compat. */
|
|
892
|
-
readonly majorEastAsia?: string | null;
|
|
893
|
-
/** `a:minorFont` east asian typeface (`a:ea`) — body text. Optional for back-compat. */
|
|
894
|
-
readonly minorEastAsia?: string | null;
|
|
895
|
-
}
|
|
896
|
-
/**
|
|
897
|
-
* Resolve one run's direct formatting.
|
|
898
|
-
*
|
|
899
|
-
* Unrecognised values are DROPPED rather than guessed: a `w:sz` of `"large"` leaves the
|
|
900
|
-
* default size rather than inventing one, because a wrong measurement moves every glyph
|
|
901
|
-
* after it and a missing one is visible immediately.
|
|
902
|
-
*
|
|
903
|
-
* `themeFonts` resolves `w:rFonts` theme references. Absent, a theme-only `rFonts` leaves
|
|
904
|
-
* the family inherited — which is what every run of a theme-fonted document does, so the
|
|
905
|
-
* whole document falls back to the surface default face.
|
|
906
|
-
*/
|
|
907
|
-
declare function resolveRunStyle(props: readonly OoxmlProperty[], themeFonts?: ThemeFonts): ResolvedRunStyle;
|
|
908
|
-
/** The text as it is DRAWN, after case transforms. Measurement must use this, not the source. */
|
|
909
|
-
declare function displayText(text: string, style: ResolvedRunStyle): string;
|
|
910
|
-
/** Measure run text the way layout breaks lines and paints glyphs (caps/small-caps aware). */
|
|
911
|
-
declare function measureDisplayText(text: string, style: ResolvedRunStyle, measurer: TextMeasurer): number;
|
|
912
|
-
/** Whether two resolved styles are identical, for span merging and cache keys. */
|
|
913
|
-
declare function runStylesEqual(a: ResolvedRunStyle, b: ResolvedRunStyle): boolean;
|
|
914
|
-
/**
|
|
915
|
-
* How far a run's glyphs are lifted off the line's baseline, in points. Positive is up.
|
|
916
|
-
*
|
|
917
|
-
* Super and subscript move the GLYPHS without moving the run's box, so the box keeps tiling
|
|
918
|
-
* the line and the selection band stays continuous. Anything drawing at the glyphs — the
|
|
919
|
-
* painter, and the caret — has to apply this itself, and from one place, or the two drift.
|
|
920
|
-
*/
|
|
921
|
-
declare function baselineShiftPtOf(style: ResolvedRunStyle): number;
|
|
922
|
-
|
|
923
|
-
/**
|
|
924
|
-
* Which `w:rFonts` slot a character resolves its face through.
|
|
925
|
-
*
|
|
926
|
-
* OOXML gives a run up to four faces and picks between them by SCRIPT, so one run of mixed Latin
|
|
927
|
-
* and CJK text uses two different fonts without saying so anywhere in its properties.
|
|
928
|
-
*/
|
|
929
|
-
type FontSlot = 'ascii' | 'hAnsi' | 'eastAsia' | 'cs';
|
|
930
|
-
/**
|
|
931
|
-
* A run of text sharing one script, direction and font slot — the unit handed to the shaper.
|
|
932
|
-
*
|
|
933
|
-
* Shaping cannot span a script change: Arabic and Latin in one call would produce wrong joining
|
|
934
|
-
* behaviour, so a run is itemized into these first.
|
|
935
|
-
*/
|
|
936
|
-
interface ScriptItem {
|
|
937
|
-
readonly from: number;
|
|
938
|
-
readonly to: number;
|
|
939
|
-
readonly direction: TextDirection;
|
|
940
|
-
readonly bidiLevel: number;
|
|
941
|
-
readonly script: 'Zyyy' | 'Latn' | 'Grek' | 'Cyrl' | 'Hani' | 'Hebr' | 'Arab' | 'Deva' | 'Beng' | 'Thai' | 'Khmr';
|
|
942
|
-
readonly slot: FontSlot;
|
|
943
|
-
}
|
|
944
|
-
/**
|
|
945
|
-
* A code point whose script this engine does not itemize.
|
|
946
|
-
*
|
|
947
|
-
* Carries the offending `codePoint` so the caller can report which character stopped it, rather
|
|
948
|
-
* than failing anonymously somewhere in the middle of a paragraph.
|
|
862
|
+
* Carries the offending `codePoint` so the caller can report which character stopped it, rather
|
|
863
|
+
* than failing anonymously somewhere in the middle of a paragraph.
|
|
949
864
|
*/
|
|
950
865
|
declare class UnsupportedScriptError extends Error {
|
|
951
866
|
readonly name = "UnsupportedScriptError";
|
|
@@ -972,19 +887,19 @@ declare function itemizeScriptFontSlots(text: string, paragraphOffset: number, e
|
|
|
972
887
|
*/
|
|
973
888
|
declare function styleForFontSlot(style: ResolvedRunStyle, slot: FontSlot | undefined): ResolvedRunStyle;
|
|
974
889
|
|
|
975
|
-
type AllowlistedPageField = 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES';
|
|
976
890
|
/**
|
|
977
|
-
*
|
|
891
|
+
* One parsed `HYPERLINK` instruction: the raw, unsanitized pieces.
|
|
978
892
|
*
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
* distinct evaluated values with a bounded cache. Counts both complex markers and
|
|
982
|
-
* `w:fldSimple` (including an allowlisted page field nested inside a non-page simple field).
|
|
893
|
+
* `target` and `anchor` are verbatim from the instruction — the projector at the trust
|
|
894
|
+
* boundary decides what, if anything, they become in a DOM sink.
|
|
983
895
|
*/
|
|
984
|
-
interface
|
|
985
|
-
|
|
986
|
-
readonly
|
|
987
|
-
|
|
896
|
+
interface HyperlinkFieldSpec {
|
|
897
|
+
/** The target as authored (first quoted or bare non-switch token), or null. */
|
|
898
|
+
readonly target: string | null;
|
|
899
|
+
/** `\l` — a bookmark name in this document, or null. */
|
|
900
|
+
readonly anchor: string | null;
|
|
901
|
+
/** `\o` — the hover tooltip, or null. */
|
|
902
|
+
readonly tooltip: string | null;
|
|
988
903
|
}
|
|
989
904
|
|
|
990
905
|
/** One recognized REF instruction: the target name and the supported switches, nothing else. */
|
|
@@ -1007,380 +922,434 @@ interface RefFieldSpec {
|
|
|
1007
922
|
*/
|
|
1008
923
|
declare function parseRefInstruction(raw: string): RefFieldSpec | null;
|
|
1009
924
|
|
|
1010
|
-
/** Soft ceiling on abstractNum / num entries read from one part. */
|
|
1011
|
-
declare const MAX_NUMBERING_DEFINITIONS = 512;
|
|
1012
|
-
/** Soft ceiling on override entries per `w:num`. */
|
|
1013
|
-
declare const MAX_LVL_OVERRIDES = 9;
|
|
1014
|
-
/** `w:suff` — what separates a list marker from the text after it. */
|
|
1015
|
-
type ListSuffix = 'tab' | 'space' | 'nothing';
|
|
1016
|
-
/** `w:lvlJc` — how a list marker aligns within its own indent. */
|
|
1017
|
-
type ListMarkerAlign = 'left' | 'center' | 'right';
|
|
1018
925
|
/**
|
|
1019
|
-
*
|
|
926
|
+
* The story's resolved REF inputs for one layout pass.
|
|
1020
927
|
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
928
|
+
* Threaded as a runtime rider on the layout options (see `layoutSemanticDocument`) rather
|
|
929
|
+
* than a `SemanticLayoutOptions` member, so the public options surface stays put. Absent
|
|
930
|
+
* means every REF field paints its cached result — the pre-existing degradation, and the one
|
|
931
|
+
* header/footer and text-box stories still take. Note stories receive the body's context
|
|
932
|
+
* through `NotesLayoutInput.refFields`.
|
|
1023
933
|
*/
|
|
1024
|
-
interface
|
|
1025
|
-
readonly left: number;
|
|
1026
|
-
readonly right: number;
|
|
1027
|
-
readonly hanging: number;
|
|
1028
|
-
readonly firstLine: number;
|
|
934
|
+
interface RefFieldContext {
|
|
1029
935
|
/**
|
|
1030
|
-
*
|
|
1031
|
-
*
|
|
1032
|
-
*
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
936
|
+
* Content token over each paragraph ID and its PAINTED REF outputs in the story, for the
|
|
937
|
+
* section prepass memo. IDs keep structural edits from moving an identical sequence of
|
|
938
|
+
* outputs between paragraphs while the aggregate falsely reports unchanged dependencies.
|
|
939
|
+
* A renumbering edit can move a REF value in a section whose own blocks and list map are
|
|
940
|
+
* identity-unchanged, and this token is the only validator that sees it. A field that
|
|
941
|
+
* failed calibration contributes its (session-constant) cached text, so the token still
|
|
942
|
+
* moves when painted output or its owning paragraph changes.
|
|
1036
943
|
*/
|
|
1037
|
-
readonly
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
/** `w:hanging`/`w:firstLine` are one mutually exclusive slot (§17.3.1.10, §17.3.1.12). */
|
|
1041
|
-
readonly firstLineOffset: boolean;
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
/** One `w:lvl`: how this depth numbers, what its marker looks like, and how it indents. */
|
|
1045
|
-
interface NumberingLevel {
|
|
1046
|
-
readonly ilvl: number;
|
|
1047
|
-
readonly start: number;
|
|
1048
|
-
readonly numFmt: string;
|
|
1049
|
-
readonly lvlText: string;
|
|
1050
|
-
readonly lvlJc: ListMarkerAlign;
|
|
1051
|
-
readonly suff: ListSuffix;
|
|
1052
|
-
readonly indent: NumberingLevelIndent;
|
|
944
|
+
readonly valuesToken: string;
|
|
945
|
+
/** The paragraph's REF outputs folded for its block cache key; `''` when it holds none. */
|
|
946
|
+
tokenForParagraph(paragraphId: string): string;
|
|
1053
947
|
/**
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
948
|
+
* The live value ONE field paints, keyed by its begin / `w:fldSimple` node id, or null to
|
|
949
|
+
* keep the cached result (failed calibration, unresolvable, or an anchor this scan never
|
|
950
|
+
* saw). Anchor-keyed so the projection's paint and this context's token fold read the SAME
|
|
951
|
+
* calibration verdict, however each walk collected the field's cached text.
|
|
1056
952
|
*/
|
|
1057
|
-
|
|
953
|
+
liveValueOf(anchorId: string, spec: RefFieldSpec): string | null;
|
|
1058
954
|
/**
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
955
|
+
* The synthesized display of ONE AUTONUM-family field, keyed by its begin / `w:fldSimple`
|
|
956
|
+
* node id, or null to paint nothing (unsupported switches, or an anchor this scan never
|
|
957
|
+
* saw — both the field's historical rendering). These fields carry no cached result at
|
|
958
|
+
* all, so there is no calibration: the sequential value is the only display they have.
|
|
959
|
+
* Optional so hand-built contexts predating it stay valid.
|
|
1061
960
|
*/
|
|
1062
|
-
|
|
1063
|
-
/**
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
961
|
+
autonumValueOf?(anchorId: string): string | null;
|
|
962
|
+
/**
|
|
963
|
+
* The deferred projection of ONE `PAGEREF` field, or null to keep the cached result
|
|
964
|
+
* (missing bookmark, unsupported switches, or an anchor this scan never saw).
|
|
965
|
+
*
|
|
966
|
+
* A `PAGEREF` value is a property of pagination, so the scan cannot compute it — it hands
|
|
967
|
+
* the projection the resolved TARGET and the calibration inputs instead, and document
|
|
968
|
+
* finalize (`finalizePageFieldProjection`) substitutes the page number the target's first
|
|
969
|
+
* fragment lands on. Optional so hand-built contexts predating it stay valid.
|
|
970
|
+
*/
|
|
971
|
+
pageRefProjectionOf?(anchorId: string, spec: RefFieldSpec): PageRefFieldProjection | null;
|
|
1067
972
|
}
|
|
1068
973
|
/**
|
|
1069
|
-
*
|
|
974
|
+
* Sticky calibration identity for one `PAGEREF` field.
|
|
1070
975
|
*
|
|
1071
|
-
*
|
|
976
|
+
* An opaque frozen object rather than a mutable verdict holder because span markers are
|
|
977
|
+
* serialized into fragment signatures — a verdict written into the marker would move a
|
|
978
|
+
* signature that no painted output moved. The verdict itself lives beside the finalize pass
|
|
979
|
+
* (`field-page-furniture.ts`), keyed weakly on this object; the registry below carries the
|
|
980
|
+
* object across passes the same way REF verdicts are carried.
|
|
1072
981
|
*/
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
982
|
+
type PageRefCalibrationCell = Readonly<Record<never, never>>;
|
|
983
|
+
/**
|
|
984
|
+
* What a `PAGEREF` span carries to document finalize: the resolved target, the normalized
|
|
985
|
+
* authored cache (the calibration oracle), and the sticky calibration identity.
|
|
986
|
+
*/
|
|
987
|
+
interface PageRefFieldProjection {
|
|
988
|
+
/** Canonical id of the paragraph the bookmark names — first declaration wins. */
|
|
989
|
+
readonly targetParagraphId: string;
|
|
990
|
+
/** The authored cached result, whitespace-collapsed — what the computed number must reproduce. */
|
|
991
|
+
readonly cached: string;
|
|
992
|
+
readonly calibration: PageRefCalibrationCell;
|
|
1077
993
|
}
|
|
1078
994
|
/**
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
995
|
+
* Note parts whose stories join the context: their REF fields resolve against the body's
|
|
996
|
+
* bookmarks and numbering (a footnote citing "Section 1.2(c)" targets a body paragraph),
|
|
997
|
+
* and their bookmark declarations become plain-REF targets. Number switches aimed AT a
|
|
998
|
+
* note paragraph still fall back to the cached result — the list map is the body's.
|
|
1083
999
|
*/
|
|
1084
|
-
interface
|
|
1085
|
-
readonly
|
|
1086
|
-
readonly
|
|
1087
|
-
/**
|
|
1088
|
-
* `w:numStyleLink` (§17.9.21): this definition carries no levels of its own — the numbering
|
|
1089
|
-
* lives on the named style. Word follows the link; resolve it with
|
|
1090
|
-
* {@link resolveNumberingStyleLinks} before reading levels, or every paragraph on this
|
|
1091
|
-
* abstract renders with NO marker at all.
|
|
1092
|
-
*/
|
|
1093
|
-
readonly numStyleLink?: string;
|
|
1094
|
-
/**
|
|
1095
|
-
* `w:styleLink` (§17.9.23): the definition side of the same pair — this abstract IS the
|
|
1096
|
-
* numbering of the named style. Kept so a link can be verified rather than assumed.
|
|
1097
|
-
*/
|
|
1098
|
-
readonly styleLink?: string;
|
|
1000
|
+
interface RefNoteParts {
|
|
1001
|
+
readonly footnotesPart: OoxmlPart | null;
|
|
1002
|
+
readonly endnotesPart: OoxmlPart | null;
|
|
1099
1003
|
}
|
|
1100
1004
|
/**
|
|
1101
|
-
*
|
|
1005
|
+
* Resolve the document's REF fields for one layout pass, or null when it has none.
|
|
1102
1006
|
*
|
|
1103
|
-
*
|
|
1007
|
+
* Bookmarks and REF fields resolve across the body story and (when `notes` is given) the
|
|
1008
|
+
* footnote/endnote stories, against ONE shared target index — a footnote REF finds the
|
|
1009
|
+
* body bookmark it cites. Header/footer and text-box stories are not given a context and
|
|
1010
|
+
* keep painting cached results.
|
|
1104
1011
|
*/
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
readonly overrides: ReadonlyMap<number, LevelOverride>;
|
|
1109
|
-
}
|
|
1012
|
+
declare function resolveStoryRefFields(blocks: readonly OoxmlElement[], listItems: ReadonlyMap<string, ResolvedListItem> | undefined, notes?: RefNoteParts): RefFieldContext | null;
|
|
1013
|
+
|
|
1014
|
+
type AllowlistedPageField = 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES';
|
|
1110
1015
|
/**
|
|
1111
|
-
*
|
|
1016
|
+
* Which allowlisted page fields a header/footer story actually contains.
|
|
1112
1017
|
*
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1018
|
+
* Drives layout reuse: no fields → one baseline; NUMPAGES only → one layout per page count;
|
|
1019
|
+
* SECTIONPAGES only → one layout per section page count; PAGE (alone or combined) → per
|
|
1020
|
+
* distinct evaluated values with a bounded cache. Counts both complex markers and
|
|
1021
|
+
* `w:fldSimple` (including an allowlisted page field nested inside a non-page simple field).
|
|
1115
1022
|
*/
|
|
1116
|
-
interface
|
|
1117
|
-
readonly
|
|
1118
|
-
readonly
|
|
1023
|
+
interface StoryPageFieldNeeds {
|
|
1024
|
+
readonly hasPage: boolean;
|
|
1025
|
+
readonly hasNumPages: boolean;
|
|
1026
|
+
readonly hasSectionPages: boolean;
|
|
1119
1027
|
}
|
|
1028
|
+
|
|
1120
1029
|
/**
|
|
1121
|
-
*
|
|
1030
|
+
* What a piece says about the FIELD result it came from, for Word's shading.
|
|
1122
1031
|
*
|
|
1123
|
-
*
|
|
1032
|
+
* Carried from layout rather than decided at paint time because only the walk knows an atom was
|
|
1033
|
+
* a field at all — by paint the result is just text. Whether the shading is actually drawn is a
|
|
1034
|
+
* view decision made downstream, so this states the fact and nothing about the appearance.
|
|
1124
1035
|
*/
|
|
1036
|
+
interface FieldAtomMarker {
|
|
1037
|
+
/**
|
|
1038
|
+
* A legacy form field: `w:fldChar/w:ffData` (FORMTEXT, FORMCHECKBOX, FORMDROPDOWN).
|
|
1039
|
+
*
|
|
1040
|
+
* Word shades these on a different rule from ordinary fields — always, unless the document
|
|
1041
|
+
* turns it off — because they mark the blanks somebody is meant to fill in.
|
|
1042
|
+
*/
|
|
1043
|
+
readonly formField: boolean;
|
|
1044
|
+
/**
|
|
1045
|
+
* A BODY PAGE / NUMPAGES / SECTIONPAGES atom whose value depends on pagination.
|
|
1046
|
+
*
|
|
1047
|
+
* The paragraph walk cannot know which page the field lands on — layout runs before the page
|
|
1048
|
+
* count — so it paints a placeholder and records the field's kind here. Document finalize
|
|
1049
|
+
* (`substituteBodyPageFields`) reads this marker and substitutes the real value per page.
|
|
1050
|
+
* Absent in headers/footers, which evaluate live through their own per-page projector.
|
|
1051
|
+
*/
|
|
1052
|
+
readonly pageField?: {
|
|
1053
|
+
readonly kind: AllowlistedPageField;
|
|
1054
|
+
/** The field's `\#` numeric picture, applied when finalize substitutes the value. */
|
|
1055
|
+
readonly picture?: string;
|
|
1056
|
+
};
|
|
1057
|
+
/**
|
|
1058
|
+
* A BODY `PAGEREF` atom whose value is the page number its bookmark target lands on.
|
|
1059
|
+
*
|
|
1060
|
+
* Deferred exactly like {@link pageField}: the paragraph walk paints the field's cached
|
|
1061
|
+
* result (or the placeholder digit when the file cached none) and records the resolved
|
|
1062
|
+
* target here; document finalize substitutes the number of the page hosting the target's
|
|
1063
|
+
* first fragment, gated per field on the calibration verdict.
|
|
1064
|
+
*/
|
|
1065
|
+
readonly pageRef?: PageRefFieldProjection;
|
|
1066
|
+
}
|
|
1067
|
+
/** A half-open model-offset range, in the paragraph's own UTF-16 offset space. */
|
|
1068
|
+
interface ModelRange {
|
|
1069
|
+
readonly start: number;
|
|
1070
|
+
readonly end: number;
|
|
1071
|
+
}
|
|
1125
1072
|
/**
|
|
1126
|
-
*
|
|
1073
|
+
* How layout turns a typed `w:hyperlink` node into the sanitized record spans carry.
|
|
1127
1074
|
*
|
|
1128
|
-
*
|
|
1129
|
-
*
|
|
1130
|
-
*
|
|
1075
|
+
* Injected rather than computed here because resolving `r:id` needs the PACKAGE's
|
|
1076
|
+
* relationships and this module only ever sees one part's tree. `null` means the caller
|
|
1077
|
+
* declined to project — the runs still measure and paint, they simply carry no link, which is
|
|
1078
|
+
* the right degradation: text is never lost for want of a target.
|
|
1131
1079
|
*/
|
|
1132
|
-
|
|
1133
|
-
/** Resolve the effective level for a `numId` + `ilvl`, applying overrides. */
|
|
1080
|
+
type HyperlinkProjector = (link: OoxmlNode) => SpanLinkRecord | null;
|
|
1134
1081
|
/**
|
|
1135
|
-
*
|
|
1082
|
+
* How layout turns a parsed HYPERLINK field instruction into the sanitized record spans carry.
|
|
1136
1083
|
*
|
|
1137
|
-
*
|
|
1138
|
-
*
|
|
1084
|
+
* Injected for the same reason as {@link HyperlinkProjector}: the spec's raw target must cross
|
|
1085
|
+
* the surface's ONE href trust boundary, and layout owns no sanitization policy. `null` means
|
|
1086
|
+
* no link — the cached result still paints as plain text, which is the right degradation.
|
|
1139
1087
|
*/
|
|
1140
|
-
|
|
1141
|
-
readonly abstractNumId: string;
|
|
1142
|
-
readonly level: NumberingLevel;
|
|
1143
|
-
readonly startOverride?: number;
|
|
1144
|
-
} | null;
|
|
1145
|
-
/** Empty index for tests / documents without numbering. */
|
|
1146
|
-
declare const EMPTY_NUMBERING_INDEX: NumberingIndex;
|
|
1088
|
+
type FieldLinkProjector = (spec: HyperlinkFieldSpec) => SpanLinkRecord | null;
|
|
1147
1089
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
readonly
|
|
1154
|
-
|
|
1155
|
-
readonly
|
|
1156
|
-
|
|
1090
|
+
/** Document-wide East Asian line-break and whitespace policy. @public */
|
|
1091
|
+
interface CjkTypographySettings {
|
|
1092
|
+
/** Apply the strict Japanese small-kana and prolonged-sound-mark restrictions. */
|
|
1093
|
+
readonly strict: boolean;
|
|
1094
|
+
/** Whitespace compression selected by `w:characterSpacingControl`. */
|
|
1095
|
+
readonly compression: 'doNotCompress' | 'compressPunctuation' | 'compressPunctuationAndJapaneseKana';
|
|
1096
|
+
/** Custom no-line-start characters, keyed by normalized language tag. */
|
|
1097
|
+
readonly before: Readonly<Record<string, string>>;
|
|
1098
|
+
/** Custom no-line-end characters, keyed by normalized language tag. */
|
|
1099
|
+
readonly after: Readonly<Record<string, string>>;
|
|
1157
1100
|
}
|
|
1158
|
-
type DrawingClipFallback = 'none' | 'unsupported-preset';
|
|
1159
|
-
interface DrawingGeometry {
|
|
1160
|
-
readonly contentBounds: LayoutBox;
|
|
1161
|
-
readonly paintBounds: LayoutBox;
|
|
1162
|
-
readonly hitBounds: LayoutBox;
|
|
1163
|
-
readonly transformedCorners: readonly DrawingPoint[];
|
|
1164
|
-
readonly clipPolygon: readonly DrawingPoint[] | null;
|
|
1165
|
-
readonly clipFallback: DrawingClipFallback;
|
|
1166
|
-
readonly effectInsets: DrawingInsets;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
/** Horizontal alignment of a paragraph (`w:jc`, ECMA-376 §17.3.1.13). */
|
|
1170
|
-
type Alignment = 'left' | 'center' | 'right' | 'both';
|
|
1171
1101
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1102
|
+
/**
|
|
1103
|
+
* Whether a paragraph must start a new page (`w:pageBreakBefore`).
|
|
1104
|
+
*
|
|
1105
|
+
* LAST WINS, like every other toggle read off the cascade (`paragraphKeeps` does the same
|
|
1106
|
+
* for `w:keepNext`). An any-wins `.some()` cannot be switched off: a Chapter or Heading style
|
|
1107
|
+
* carries `w:pageBreakBefore`, and Word writes `w:val="0"` on the one instance whose author
|
|
1108
|
+
* unchecked the box — that paragraph still broke, so the document grew a blank page and every
|
|
1109
|
+
* page number after it was wrong.
|
|
1110
|
+
*
|
|
1111
|
+
* An absent `w:val` is on (§17.17.4), and the off vocabulary is the whole of it — `off` is a
|
|
1112
|
+
* spelling too, which {@link isOn} beside this already accepts.
|
|
1113
|
+
*/
|
|
1114
|
+
declare function paragraphBreaksBefore(props: readonly OoxmlProperty[]): boolean;
|
|
1115
|
+
/**
|
|
1116
|
+
* Soft ceiling matching the spike's resolved-style limit (31_680 twips ≈ 22"). Beyond
|
|
1117
|
+
* that an attacker-authored spacing would push pagination into pathological page counts.
|
|
1118
|
+
*/
|
|
1119
|
+
declare const MAX_PARAGRAPH_SPACING_PT: number;
|
|
1120
|
+
/** Soft ceiling on border width (96 eighths = 12pt). Word's UI tops out well below this. */
|
|
1121
|
+
declare const MAX_BORDER_WIDTH_PT = 12;
|
|
1122
|
+
/** Soft ceiling on border-to-text gap (`w:space`, already in points). */
|
|
1123
|
+
declare const MAX_BORDER_SPACE_PT = 3168;
|
|
1124
|
+
/**
|
|
1125
|
+
* A paragraph's resolved space before and after, in points.
|
|
1126
|
+
*
|
|
1127
|
+
* Already collapsed against `w:contextualSpacing`, so adjacent same-style paragraphs that suppress
|
|
1128
|
+
* their gap arrive here with it removed rather than leaving that to whoever stacks them.
|
|
1129
|
+
*/
|
|
1130
|
+
interface ParagraphSpacing {
|
|
1131
|
+
/** `w:spacing/@before`, in points. */
|
|
1132
|
+
readonly before: number;
|
|
1133
|
+
/** `w:spacing/@after`, in points. */
|
|
1134
|
+
readonly after: number;
|
|
1185
1135
|
}
|
|
1186
|
-
declare function isValidStyleId(raw: string | undefined): raw is string;
|
|
1187
|
-
|
|
1188
|
-
/** Soft ceiling on `basedOn` chain length — enough for real templates, refuses hostile graphs. */
|
|
1189
|
-
declare const MAX_STYLE_BASED_ON_DEPTH = 32;
|
|
1190
|
-
/** Soft ceiling on style definitions read from one styles part. */
|
|
1191
|
-
declare const MAX_STYLE_DEFINITIONS = 4096;
|
|
1192
1136
|
/**
|
|
1193
|
-
* The
|
|
1137
|
+
* The gap Word substitutes when `w:beforeAutospacing` / `w:afterAutospacing` is on
|
|
1138
|
+
* (ECMA-376 §17.3.1.33, the `w:spacing` clause both attributes belong to).
|
|
1194
1139
|
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1140
|
+
* The attribute means "the consumer decides", and the authored `@before` / `@after` beside it
|
|
1141
|
+
* is IGNORED rather than used as the value. Word's answer is HTML's default `<p>` margin,
|
|
1142
|
+
* 14pt, which is what a document round-tripped through Word's HTML filter carries — and this
|
|
1143
|
+
* one is everywhere, because Word writes `w:before="100" w:beforeAutospacing="1"` for it. Reading
|
|
1144
|
+
* only the literal 100 twips lays every such paragraph out 9pt tight, which moves page breaks.
|
|
1197
1145
|
*/
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
/** `w:
|
|
1208
|
-
readonly
|
|
1209
|
-
/**
|
|
1210
|
-
readonly
|
|
1211
|
-
/**
|
|
1212
|
-
* `w:style[@w:default='1'][@w:type='table']` — last wins among defaults of that type.
|
|
1213
|
-
*
|
|
1214
|
-
* A `w:tbl` with no `w:tblStyle` still resolves against this one. Word's own
|
|
1215
|
-
* `TableNormal` is where the 0/108/0/108 twip cell margins live, so skipping it gives
|
|
1216
|
-
* every unstyled table padding the document says it does not have.
|
|
1217
|
-
*/
|
|
1218
|
-
readonly defaultTableStyleId: string | null;
|
|
1219
|
-
/**
|
|
1220
|
-
* The theme part's typefaces, for `w:rFonts` theme references.
|
|
1221
|
-
*
|
|
1222
|
-
* Lives on the cascade because it is document-level style material with the same
|
|
1223
|
-
* lifetime, and because every site that resolves run properties already holds this table.
|
|
1224
|
-
*/
|
|
1225
|
-
readonly themeFonts: ThemeFonts;
|
|
1226
|
-
readonly styles: ReadonlyMap<string, StyleDefinition>;
|
|
1146
|
+
declare const AUTO_PARAGRAPH_SPACING_PT = 14;
|
|
1147
|
+
/**
|
|
1148
|
+
* Where a paragraph sits, for the two contexts in which Word's auto spacing resolves to 0
|
|
1149
|
+
* instead of {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
1150
|
+
*
|
|
1151
|
+
* Both come from the HTML model the attribute emulates: a `<li>` and a `<td>` collapse the
|
|
1152
|
+
* paragraph margin, a bare `<p>` does not. A caller that says nothing gets the body answer.
|
|
1153
|
+
*/
|
|
1154
|
+
interface ParagraphAutoSpacingContext {
|
|
1155
|
+
/** The paragraph participates in numbering (`w:numPr`), i.e. it is a list item. */
|
|
1156
|
+
readonly inList?: boolean;
|
|
1157
|
+
/** The paragraph lives in a table cell. */
|
|
1158
|
+
readonly inTableCell?: boolean;
|
|
1227
1159
|
}
|
|
1228
1160
|
/**
|
|
1229
|
-
*
|
|
1161
|
+
* Resolved line spacing (`w:spacing/@line` + `@lineRule`, ECMA-376 17.3.1.33).
|
|
1230
1162
|
*
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
1233
|
-
*
|
|
1163
|
+
* `auto` is the interesting one: `@line` is 240ths of a line, so 240 is single, 360 is
|
|
1164
|
+
* one-and-a-half, 480 is double — and Word's own Normal style since 2013 is 259, i.e.
|
|
1165
|
+
* 1.08. A document laid out at a flat single spacing is ~8% tight on EVERY line, which
|
|
1166
|
+
* moves every page break, so this is not a cosmetic detail.
|
|
1167
|
+
*
|
|
1168
|
+
* `exact` fixes the line box at `@line` twips and lets tall glyphs clip, the way Word
|
|
1169
|
+
* does. `atLeast` uses it as a floor.
|
|
1234
1170
|
*/
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1171
|
+
type LineSpacingRule = 'auto' | 'exact' | 'atLeast';
|
|
1172
|
+
/**
|
|
1173
|
+
* Resolved line spacing: the rule, and the value it applies.
|
|
1174
|
+
*
|
|
1175
|
+
* `value` means different things per rule — 240ths of a line under `auto`, points under `exact`
|
|
1176
|
+
* and `atLeast` — which is why the two travel together and neither is useful alone.
|
|
1177
|
+
*/
|
|
1178
|
+
interface ParagraphLineSpacing {
|
|
1179
|
+
readonly rule: LineSpacingRule;
|
|
1180
|
+
/** `auto`: the 240ths-of-a-line multiplier numerator. Otherwise points. */
|
|
1181
|
+
readonly value: number;
|
|
1182
|
+
}
|
|
1183
|
+
/** Single spacing: what a paragraph that says nothing gets. */
|
|
1184
|
+
declare const SINGLE_LINE_SPACING: ParagraphLineSpacing;
|
|
1185
|
+
/**
|
|
1186
|
+
* One resolved `w:pBdr` edge: its style, colour, thickness and gap.
|
|
1187
|
+
*
|
|
1188
|
+
* `widthPt` and `spacePt` are already converted and CLAMPED — both come from a file, and an
|
|
1189
|
+
* unbounded border width becomes a layout dimension.
|
|
1190
|
+
*/
|
|
1191
|
+
interface ParagraphBorderEdge {
|
|
1192
|
+
/** Authored `ST_Border` value (`single`, `dashed`, …). */
|
|
1193
|
+
readonly val: string;
|
|
1194
|
+
/** RRGGBB, or null when auto/missing (paint defaults to black). */
|
|
1195
|
+
readonly color: string | null;
|
|
1196
|
+
/** Border thickness in points (`w:sz` is eighths of a point). */
|
|
1197
|
+
readonly widthPt: number;
|
|
1198
|
+
/** Gap from text to the rule, in points (`w:space`). */
|
|
1199
|
+
readonly spacePt: number;
|
|
1247
1200
|
/**
|
|
1248
|
-
*
|
|
1201
|
+
* `w:shadow` — Word offsets a drop shadow behind the rule.
|
|
1249
1202
|
*
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
* direct size paint at the mark's size (Selection Notice "or" alternative → 6.5pt).
|
|
1253
|
-
*/
|
|
1254
|
-
readonly runProperties: readonly OoxmlProperty[];
|
|
1255
|
-
/**
|
|
1256
|
-
* Content cascade plus direct `w:pPr/w:rPr` — empty-line metrics and last-line mark height.
|
|
1257
|
-
*/
|
|
1258
|
-
readonly markRunProperties: readonly OoxmlProperty[];
|
|
1259
|
-
/**
|
|
1260
|
-
* The style this paragraph resolved to, or null when it names none and there is no
|
|
1261
|
-
* document default. `w:contextualSpacing` compares neighbours by exactly this.
|
|
1203
|
+
* Present only when authored true, so an edge that says nothing keeps the shape earlier
|
|
1204
|
+
* fixtures assert. Resolved and carried; drawing it is deferred.
|
|
1262
1205
|
*/
|
|
1263
|
-
readonly
|
|
1206
|
+
readonly shadow?: true;
|
|
1264
1207
|
}
|
|
1208
|
+
/** The six `CT_PBdr` children, in schema order (ECMA-376 §17.3.1.24). */
|
|
1209
|
+
declare const PARAGRAPH_BORDER_SIDES: readonly ["top", "left", "bottom", "right", "between", "bar"];
|
|
1265
1210
|
/**
|
|
1266
|
-
*
|
|
1267
|
-
* `w:pPr`/`w:rPr` followed by every `w:tblStylePr` the cell is under (17.7.6.6), weakest
|
|
1268
|
-
* first in the caller's condition order (banding, column, row, corner).
|
|
1211
|
+
* Which of the six `CT_PBdr` edges.
|
|
1269
1212
|
*
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
1213
|
+
* Four are physical box edges; `between` and `bar` are group-relative, drawn only where
|
|
1214
|
+
* consecutive paragraphs share a border definition.
|
|
1272
1215
|
*/
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1216
|
+
type ParagraphBorderSide = (typeof PARAGRAPH_BORDER_SIDES)[number];
|
|
1217
|
+
/**
|
|
1218
|
+
* A paragraph's resolved `w:pBdr` (ECMA-376 §17.3.1.24).
|
|
1219
|
+
*
|
|
1220
|
+
* `top`/`left`/`bottom`/`right` are the four physical edges of the box. The other two are
|
|
1221
|
+
* group-relative: `between` draws at a boundary INSIDE a run of consecutive paragraphs whose
|
|
1222
|
+
* border settings are identical, and `bar` is the vertical change-bar rule beside the
|
|
1223
|
+
* paragraph, drawn whether or not the paragraph groups with its neighbours.
|
|
1224
|
+
*/
|
|
1225
|
+
interface ParagraphBorders {
|
|
1226
|
+
readonly top?: ParagraphBorderEdge;
|
|
1227
|
+
readonly left?: ParagraphBorderEdge;
|
|
1228
|
+
readonly bottom?: ParagraphBorderEdge;
|
|
1229
|
+
readonly right?: ParagraphBorderEdge;
|
|
1230
|
+
readonly between?: ParagraphBorderEdge;
|
|
1231
|
+
readonly bar?: ParagraphBorderEdge;
|
|
1279
1232
|
}
|
|
1280
1233
|
/**
|
|
1281
|
-
*
|
|
1234
|
+
* Resolve `w:spacing` before/after from flat paragraph properties.
|
|
1282
1235
|
*
|
|
1283
|
-
*
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1236
|
+
* Line spacing (`w:line` / `w:lineRule`) is a separate concern — it changes measured line
|
|
1237
|
+
* height, not the gap between paragraphs — and is not resolved here.
|
|
1238
|
+
*
|
|
1239
|
+
* `w:beforeAutospacing` / `w:afterAutospacing` REPLACE the authored measurement on their own
|
|
1240
|
+
* side rather than adding to it; see {@link AUTO_PARAGRAPH_SPACING_PT}.
|
|
1286
1241
|
*/
|
|
1287
|
-
declare function
|
|
1242
|
+
declare function paragraphSpacing(props: readonly OoxmlProperty[], context?: ParagraphAutoSpacingContext): ParagraphSpacing;
|
|
1288
1243
|
/**
|
|
1289
|
-
*
|
|
1244
|
+
* Resolve `w:line` / `w:lineRule` from flat paragraph properties.
|
|
1290
1245
|
*
|
|
1291
|
-
*
|
|
1292
|
-
*
|
|
1293
|
-
*
|
|
1294
|
-
|
|
1295
|
-
|
|
1246
|
+
* Merged per attribute for the same reason as before/after: `w:spacing` is one element
|
|
1247
|
+
* carrying independent attributes, and a style that states only `@line` must not reset the
|
|
1248
|
+
* rule an earlier entry in the cascade set.
|
|
1249
|
+
*/
|
|
1250
|
+
declare function paragraphLineSpacing(props: readonly OoxmlProperty[]): ParagraphLineSpacing;
|
|
1251
|
+
/**
|
|
1252
|
+
* Apply resolved line spacing to a line's natural (glyph-derived) box.
|
|
1253
|
+
*
|
|
1254
|
+
* Word places `auto` / `atLeast` extras BELOW the line (the last line's multiple spacing
|
|
1255
|
+
* still separates it from the next paragraph). Putting that delta above inverted cover-page
|
|
1256
|
+
* rhythm: `w:line="460"` on "between" opened a large gap above the word and almost none
|
|
1257
|
+
* before "MERIDIAN". `exact` taller than the glyphs centers the text (ECMA-376 17.3.1.33).
|
|
1258
|
+
* An `exact` box smaller than the glyphs keeps the baseline inside so clipped text still
|
|
1259
|
+
* sits on it.
|
|
1260
|
+
*/
|
|
1261
|
+
declare function applyLineSpacing(spacing: ParagraphLineSpacing, naturalHeight: number, naturalBaseline: number): {
|
|
1262
|
+
height: number;
|
|
1263
|
+
baseline: number;
|
|
1264
|
+
};
|
|
1265
|
+
/**
|
|
1266
|
+
* `w:contextualSpacing` (17.3.1.9): drop before/after between paragraphs of the SAME
|
|
1267
|
+
* style. Word's built-in `ListParagraph` sets it, so every list authored in Word gets a
|
|
1268
|
+
* paragraph gap between items without this.
|
|
1269
|
+
*/
|
|
1270
|
+
declare function paragraphContextualSpacing(props: readonly OoxmlProperty[]): boolean;
|
|
1271
|
+
/**
|
|
1272
|
+
* Resolve `w:pBdr` from the paragraph-properties node.
|
|
1273
|
+
*
|
|
1274
|
+
* Nested — every edge is a child of `pBdr`, not an attribute — so this reads the typed tree
|
|
1275
|
+
* rather than the flattened `OoxmlProperty[]` bag `propertiesOf` builds for leaf props.
|
|
1276
|
+
*/
|
|
1277
|
+
declare function paragraphBorders(pPr: OoxmlNode | undefined): ParagraphBorders;
|
|
1278
|
+
/**
|
|
1279
|
+
* `w:pBdr` after the style cascade: a later `w:pBdr` replaces an earlier one WHOLESALE.
|
|
1280
|
+
*
|
|
1281
|
+
* Word does not merge edges across the cascade. A style that states only `w:bottom` discards
|
|
1282
|
+
* the box its `basedOn` ancestor declared, so folding edge by edge would leave a lone
|
|
1283
|
+
* underline surrounded by a box no one authored. Absence inherits; `nil`/`none` clear.
|
|
1284
|
+
*/
|
|
1285
|
+
declare function cascadedParagraphBorders(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorders;
|
|
1286
|
+
/**
|
|
1287
|
+
* Visual stroke thickness layout publishes for one edge (points).
|
|
1288
|
+
*
|
|
1289
|
+
* Compound `ST_Border` values (`double`, …) use the shared inflated band so a thin
|
|
1290
|
+
* `w:sz="3"` double still occupies a visible double-line box — matching table borders.
|
|
1291
|
+
*/
|
|
1292
|
+
declare function paragraphBorderStrokeWidthPt(edge: ParagraphBorderEdge): number;
|
|
1293
|
+
/**
|
|
1294
|
+
* Extent one border edge occupies away from the text it decorates: gap plus rule, in points.
|
|
1295
|
+
*
|
|
1296
|
+
* Vertically that is flow height — a top rule pushes the first line down, a bottom rule holds
|
|
1297
|
+
* the page open below the last one — so pagination has to see it. Horizontally it is
|
|
1298
|
+
* publish-only: Word draws left/right paragraph rules OUTSIDE the text column and never
|
|
1299
|
+
* re-breaks the lines, which is why adding a box to a paragraph in Word does not reflow it.
|
|
1300
|
+
*/
|
|
1301
|
+
declare function paragraphBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
1302
|
+
/** Vertical extent a bottom border adds below the last line (gap + rule). */
|
|
1303
|
+
declare function bottomBorderExtentPt(edge: ParagraphBorderEdge | undefined): number;
|
|
1304
|
+
/**
|
|
1305
|
+
* Identity of a paragraph's border set, for the `w:between` group rule.
|
|
1306
|
+
*
|
|
1307
|
+
* Word treats consecutive paragraphs whose border settings are IDENTICAL as ONE bordered
|
|
1308
|
+
* block: the top rule draws above the first, the bottom rule below the last, and each
|
|
1309
|
+
* interior boundary gets `w:between` or nothing (§17.3.1.24). That is why applying a box to
|
|
1310
|
+
* three selected paragraphs in Word draws one box and not three.
|
|
1311
|
+
*
|
|
1312
|
+
* Empty string means "no borders", which never groups with anything.
|
|
1296
1313
|
*/
|
|
1297
|
-
declare function
|
|
1314
|
+
declare function paragraphBordersFingerprint(borders: ParagraphBorders): string;
|
|
1298
1315
|
/**
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1316
|
+
* Gap to insert before a paragraph once the previous paragraph's `after` is already in the
|
|
1317
|
+
* flow cursor — Word takes the larger of the two rather than summing them.
|
|
1301
1318
|
*/
|
|
1302
|
-
declare function
|
|
1319
|
+
declare function collapsedSpaceBefore(before: number, previousAfter: number): number;
|
|
1303
1320
|
/**
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1306
|
-
* When a cascade table is supplied, also resolves `w:rStyle` character styles (basedOn chain,
|
|
1307
|
-
* cycle/depth capped). Runs without an explicit `rStyle` pick up the default character style
|
|
1308
|
-
* (`w:default="1"`). Precedence: inherited → character style chain → direct formatting.
|
|
1321
|
+
* Applied before-spacing for placement (Word 2013+ / compat mode 15).
|
|
1309
1322
|
*
|
|
1310
|
-
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
* whether the document defaults' short circuit is still standing decides what the character
|
|
1315
|
-
* style's own toggle does next, and no single `w:b` element can spell that. The paragraph
|
|
1316
|
-
* cascade attaches that state to the array it returns, so spreading, filtering or sorting the
|
|
1317
|
-
* list drops it. (`Object.freeze` returns the same object, so that one is safe.) A list
|
|
1318
|
-
* without it is read as one ordinary level, which is the most a bare property list can say
|
|
1319
|
-
* and is what a caller assembling its own list gets.
|
|
1323
|
+
* Adjacent before/after still collapse to the larger gap, but before is dropped entirely when
|
|
1324
|
+
* the paragraph begins at the top of a page mid-section. The first paragraph of a document or
|
|
1325
|
+
* section retains before. Callers publish this applied value on the fragment so shading, borders,
|
|
1326
|
+
* selection, and paint share one geometry.
|
|
1320
1327
|
*/
|
|
1321
|
-
declare function
|
|
1322
|
-
|
|
1323
|
-
interface
|
|
1324
|
-
readonly
|
|
1325
|
-
readonly
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
readonly
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
readonly
|
|
1336
|
-
|
|
1337
|
-
readonly
|
|
1338
|
-
|
|
1339
|
-
readonly
|
|
1340
|
-
|
|
1341
|
-
readonly
|
|
1342
|
-
readonly bottomBorder: ParagraphBorderEdge | undefined;
|
|
1343
|
-
/**
|
|
1344
|
-
* Every `CT_PBdr` edge after cascade, not just the bottom one.
|
|
1345
|
-
*
|
|
1346
|
-
* `bottomBorder` stays alongside it because the fragment signature and the table flow
|
|
1347
|
-
* read that field by name; this is the whole box, so a cell paragraph gets the same
|
|
1348
|
-
* frame a body paragraph does.
|
|
1349
|
-
*/
|
|
1350
|
-
readonly borders: ParagraphBorders;
|
|
1351
|
-
/** Validated 6-hex paragraph shading fill from cascaded `w:pPr/w:shd`, absent for none. */
|
|
1352
|
-
readonly shading: string | undefined;
|
|
1353
|
-
readonly inheritedRunProperties: readonly OoxmlProperty[];
|
|
1354
|
-
/**
|
|
1355
|
-
* Paragraph-mark cascade (`inheritedRunProperties` + direct `w:pPr/w:rPr`).
|
|
1356
|
-
* Empty-line sizing and last-line mark height — never content-run face.
|
|
1357
|
-
*/
|
|
1358
|
-
readonly markRunProperties: readonly OoxmlProperty[];
|
|
1359
|
-
/** Cascaded custom tab stops + default interval for paragraph-flow breaking. */
|
|
1360
|
-
readonly tabStops: ResolvedTabStops;
|
|
1361
|
-
/**
|
|
1362
|
-
* Fingerprint folded into the paragraph layout cache key — nested `w:tabs` are absent
|
|
1363
|
-
* from flat property bags, so style-inherited stops must be named explicitly.
|
|
1364
|
-
*/
|
|
1365
|
-
readonly tabStopsCacheToken: string;
|
|
1366
|
-
/** Resolved list marker inputs when the paragraph participates in numbering. */
|
|
1367
|
-
readonly listItem?: ResolvedListItem;
|
|
1328
|
+
declare function appliedSpaceBefore(before: number, previousAfter: number, atTopOfPage: boolean, firstParagraphOfSection: boolean): number;
|
|
1329
|
+
|
|
1330
|
+
interface DrawingPoint {
|
|
1331
|
+
readonly x: number;
|
|
1332
|
+
readonly y: number;
|
|
1333
|
+
}
|
|
1334
|
+
interface DrawingInsets {
|
|
1335
|
+
readonly top: number;
|
|
1336
|
+
readonly right: number;
|
|
1337
|
+
readonly bottom: number;
|
|
1338
|
+
readonly left: number;
|
|
1339
|
+
}
|
|
1340
|
+
type DrawingClipFallback = 'none' | 'unsupported-preset';
|
|
1341
|
+
interface DrawingGeometry {
|
|
1342
|
+
readonly contentBounds: LayoutBox;
|
|
1343
|
+
readonly paintBounds: LayoutBox;
|
|
1344
|
+
readonly hitBounds: LayoutBox;
|
|
1345
|
+
readonly transformedCorners: readonly DrawingPoint[];
|
|
1346
|
+
readonly clipPolygon: readonly DrawingPoint[] | null;
|
|
1347
|
+
readonly clipFallback: DrawingClipFallback;
|
|
1348
|
+
readonly effectInsets: DrawingInsets;
|
|
1368
1349
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
*
|
|
1373
|
-
* When `listItem` is provided, its merged level indent becomes the paragraph indent (list
|
|
1374
|
-
* hanging / left from `numbering.xml`), which is what Word uses for fixture list paragraphs
|
|
1375
|
-
* that author no direct `w:ind`.
|
|
1376
|
-
*
|
|
1377
|
-
* `tableCellStyle` carries what the enclosing table's style says about this cell's
|
|
1378
|
-
* paragraphs; body paragraphs pass nothing.
|
|
1379
|
-
*
|
|
1380
|
-
* `inTableCell` is asked for separately because a cell paragraph may have no table style to
|
|
1381
|
-
* inherit at all, and `w:beforeAutospacing` still needs to know it is in a cell.
|
|
1382
|
-
*/
|
|
1383
|
-
declare function resolveParagraphLayoutInputs(paragraph: OoxmlElement, contentWidth: number, styleCascade: StyleCascadeTable | undefined, listItem?: ResolvedListItem, tableCellStyle?: TableCellStyleFormatting, inTableCell?: boolean): ParagraphLayoutInputs;
|
|
1350
|
+
|
|
1351
|
+
/** Horizontal alignment of a paragraph (`w:jc`, ECMA-376 §17.3.1.13). */
|
|
1352
|
+
type Alignment = 'left' | 'center' | 'right' | 'both';
|
|
1384
1353
|
|
|
1385
1354
|
/** Test-only mutable counters; omitted by production call sites. Not package-public. */
|
|
1386
1355
|
interface TableBorderGridResolveWork {
|
|
@@ -1531,34 +1500,159 @@ interface BorderGridGeometry {
|
|
|
1531
1500
|
/** Absolute column widths for the whole table (points). */
|
|
1532
1501
|
readonly columnWidthsPt: readonly number[];
|
|
1533
1502
|
/**
|
|
1534
|
-
* Per laid-out row: absolute top and height in the same coordinate space as cell boxes
|
|
1535
|
-
* (only relative differences matter for vertical edge segmentation).
|
|
1503
|
+
* Per laid-out row: absolute top and height in the same coordinate space as cell boxes
|
|
1504
|
+
* (only relative differences matter for vertical edge segmentation).
|
|
1505
|
+
*/
|
|
1506
|
+
readonly rowBands: readonly {
|
|
1507
|
+
readonly y: number;
|
|
1508
|
+
readonly height: number;
|
|
1509
|
+
}[];
|
|
1510
|
+
/** Per laid-out cell: width/height after vMerge expansion (cell-local stroke space). */
|
|
1511
|
+
readonly cellBoxes: readonly (readonly {
|
|
1512
|
+
readonly width: number;
|
|
1513
|
+
readonly height: number;
|
|
1514
|
+
}[])[];
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Resolve borders for every cell in a laid-out table fragment.
|
|
1518
|
+
*
|
|
1519
|
+
* Shared vertical edges: conflict(left.right, right.left) → assigned to the left cell,
|
|
1520
|
+
* segmented per row when a vMerge restart faces differing neighbors.
|
|
1521
|
+
* Shared horizontal edges: conflict(above.bottom, below.top) → assigned to the above cell,
|
|
1522
|
+
* segmented per grid column when a gridSpan cell faces differing below neighbors; vMerge
|
|
1523
|
+
* interior seams are suppressed per interval.
|
|
1524
|
+
*
|
|
1525
|
+
* When `geometry` is provided, compound edges expand into explicit stroke records with
|
|
1526
|
+
* corner-adjusted endpoints in cell-local points.
|
|
1527
|
+
*/
|
|
1528
|
+
declare function resolveTableCellBorderGrid(rows: readonly (readonly BorderGridCell[])[], table: TableBorderBox, columnCount: number, geometry?: BorderGridGeometry, work?: TableBorderGridResolveWork, ownershipBudget?: TableBorderOwnershipBudget): ResolvedCellBorders[][];
|
|
1529
|
+
/** Width contribution of a resolved edge for content inset / row sizing. */
|
|
1530
|
+
declare function borderExtentPt(edge: ResolvedTableBorderEdge | TableBorderSide | undefined): number;
|
|
1531
|
+
|
|
1532
|
+
/**
|
|
1533
|
+
* Why textbox story layout stopped short.
|
|
1534
|
+
*
|
|
1535
|
+
* Every one is a BOUND rather than a bug: nesting depth, fragment counts and the extent all
|
|
1536
|
+
* come from a file. Falling back with a reason keeps the drawing rendered (clipped) instead
|
|
1537
|
+
* of failing the layout pass.
|
|
1538
|
+
*/
|
|
1539
|
+
type TextboxStoryFallbackReason = 'textbox-nesting-limit' | 'textbox-fragment-limit'
|
|
1540
|
+
/** Flowed content is taller than the extent; trailing fragments were dropped. */
|
|
1541
|
+
| 'textbox-height-clip';
|
|
1542
|
+
/**
|
|
1543
|
+
* One text box's story laid out inside its extent, in content-box-relative coordinates.
|
|
1544
|
+
*
|
|
1545
|
+
* Fragments origin at the content box's top-left; paint places the content box at
|
|
1546
|
+
* `drawing origin + contentOffset` and clips to the extent.
|
|
1547
|
+
*/
|
|
1548
|
+
interface TextboxStoryLayout {
|
|
1549
|
+
/** Content-box-relative fragments (origin at the content box's top-left). */
|
|
1550
|
+
readonly fragments: readonly BlockFragmentRecord[];
|
|
1551
|
+
/** Height the blocks flow to (points), before vertical anchoring. */
|
|
1552
|
+
readonly flowHeight: number;
|
|
1553
|
+
/** Offset of the content box inside the drawing extent: insets plus vertical anchoring. */
|
|
1554
|
+
readonly contentOffset: Readonly<{
|
|
1555
|
+
x: number;
|
|
1556
|
+
y: number;
|
|
1557
|
+
}>;
|
|
1558
|
+
/** Content box width (extent minus horizontal insets). */
|
|
1559
|
+
readonly contentWidth: number;
|
|
1560
|
+
/** Content box height (extent minus vertical insets). */
|
|
1561
|
+
readonly contentHeight: number;
|
|
1562
|
+
/** Solid fill of the hosting shape, painted behind the story; null for no fill. */
|
|
1563
|
+
readonly fillHex: string | null;
|
|
1564
|
+
/** Solid outline of the hosting shape; null for no outline. */
|
|
1565
|
+
readonly strokeHex: string | null;
|
|
1566
|
+
/** Outline width in points; 0 when absent. */
|
|
1567
|
+
readonly strokeWidthPt: number;
|
|
1568
|
+
/** True when layout hit a named bound and returned a truncated / empty story. */
|
|
1569
|
+
readonly fallbackReason?: TextboxStoryFallbackReason;
|
|
1570
|
+
/**
|
|
1571
|
+
* Resource identities of the drawings the clip DROPPED, in flow order.
|
|
1572
|
+
*
|
|
1573
|
+
* The furniture invalidation token walks laid-out records, and a dropped fragment leaves
|
|
1574
|
+
* none — while a `withPageContext` projection of the same story can wrap differently
|
|
1575
|
+
* (PAGE digits) and keep the drawing. Without this a picture clipped out of the baseline
|
|
1576
|
+
* but painted by a projection never reaches the session context, so its decode settling
|
|
1577
|
+
* moves nothing and the unchanged-pass early exit reuses the placeholder pages forever
|
|
1578
|
+
* (#467). Absent when the clip dropped no drawings, so the common story keys byte-for-byte
|
|
1579
|
+
* as before.
|
|
1580
|
+
*/
|
|
1581
|
+
readonly clippedResourceToken?: string;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
interface InlineDrawingRecord {
|
|
1585
|
+
readonly kind: 'inlineDrawing';
|
|
1586
|
+
readonly drawingNodeId: string;
|
|
1587
|
+
readonly paragraphId: string;
|
|
1588
|
+
readonly ownerPartName: string;
|
|
1589
|
+
readonly start: number;
|
|
1590
|
+
/** Left edge of the extent box (slot + distL). */
|
|
1591
|
+
readonly x: number;
|
|
1592
|
+
readonly y: number;
|
|
1593
|
+
readonly width: number;
|
|
1594
|
+
readonly height: number;
|
|
1595
|
+
readonly distL: number;
|
|
1596
|
+
readonly distR: number;
|
|
1597
|
+
readonly distT: number;
|
|
1598
|
+
readonly distB: number;
|
|
1599
|
+
/** Caret/hit advance start (slot left, before distL). */
|
|
1600
|
+
readonly advanceStart: number;
|
|
1601
|
+
/** Caret/hit advance end (slot + totalWidth). */
|
|
1602
|
+
readonly advanceEnd: number;
|
|
1603
|
+
readonly baselineOffset: number;
|
|
1604
|
+
readonly paintBounds: LayoutBox;
|
|
1605
|
+
readonly hitBounds: LayoutBox;
|
|
1606
|
+
readonly geometry: DrawingGeometry;
|
|
1607
|
+
readonly resource: ImageResourceState;
|
|
1608
|
+
readonly accessibility: DrawingAccessibility;
|
|
1609
|
+
/** Sanitized external hyperlink projection; inert until an explicit gesture activates it. */
|
|
1610
|
+
readonly hyperlinkHref: string | null;
|
|
1611
|
+
readonly effects: DrawingImageEffects;
|
|
1612
|
+
readonly crop: SourceCrop;
|
|
1613
|
+
readonly transform: DrawingTransform;
|
|
1614
|
+
/** Fixed non-picture graphic kind for refusal labels (`chart`, `group`, …); null for pictures. */
|
|
1615
|
+
readonly placeholderGraphicKind: string | null;
|
|
1616
|
+
/** Typed solid-geometry payload for a renderable `wps:wsp` shape; null otherwise. */
|
|
1617
|
+
readonly vectorShape: VectorShapeProjection | null;
|
|
1618
|
+
/**
|
|
1619
|
+
* The revision wrappers enclosing the owning run, outermost first — the same stack spans
|
|
1620
|
+
* carry, so paint and review chrome give a tracked picture the same cues as tracked text.
|
|
1621
|
+
* Absent when the drawing is untracked.
|
|
1622
|
+
*/
|
|
1623
|
+
readonly revisions?: readonly RevisionAttribution[];
|
|
1624
|
+
}
|
|
1625
|
+
interface InlineDrawingLayoutContext {
|
|
1626
|
+
readonly ownerPartName: string;
|
|
1627
|
+
/** Precomputed run-level atom id (`w:drawing` or MC wrapper) → projection. */
|
|
1628
|
+
readonly projectionForAtom?: (atomNodeId: string) => DrawingProjection | null;
|
|
1629
|
+
readonly project: (drawing: OoxmlDrawingNode) => DrawingProjection | null;
|
|
1630
|
+
readonly resourceOf: (projection: DrawingProjection) => ImageResourceState;
|
|
1631
|
+
}
|
|
1632
|
+
/** Named fallback when a positioning frame cannot be resolved (OpenSpec 4.6). */
|
|
1633
|
+
type AnchoredDrawingLayoutFallback = 'unresolvable-frame' | 'page-defer-exhausted';
|
|
1634
|
+
interface AnchoredDrawingRecord extends Omit<InlineDrawingRecord, 'kind' | 'baselineOffset' | 'advanceStart' | 'advanceEnd' | 'distL' | 'distR' | 'distT' | 'distB'> {
|
|
1635
|
+
readonly kind: 'anchoredDrawing';
|
|
1636
|
+
readonly anchorParagraphId: string;
|
|
1637
|
+
readonly horizontalFrame: DrawingHorizontalReferenceFrame;
|
|
1638
|
+
readonly verticalFrame: DrawingVerticalReferenceFrame;
|
|
1639
|
+
readonly horizontalFrameOrigin: number;
|
|
1640
|
+
readonly verticalFrameOrigin: number;
|
|
1641
|
+
readonly behindDocument: boolean;
|
|
1642
|
+
readonly allowOverlap: boolean;
|
|
1643
|
+
readonly layoutInCell: boolean;
|
|
1644
|
+
readonly relativeHeight: number;
|
|
1645
|
+
readonly wrap: Exclude<ImageWrapTarget, 'inline'>;
|
|
1646
|
+
readonly layoutFallback?: AnchoredDrawingLayoutFallback;
|
|
1647
|
+
/** Canonical document traversal index within the owner story part. */
|
|
1648
|
+
readonly sourceOrder?: number;
|
|
1649
|
+
/**
|
|
1650
|
+
* Laid-out textbox story for a `wps:txbx` drawing; paint renders it clipped inside the
|
|
1651
|
+
* extent instead of a placeholder. Absent when the drawing carries no story or the host
|
|
1652
|
+
* did not thread story layout (the record then degrades to the placeholder path).
|
|
1536
1653
|
*/
|
|
1537
|
-
readonly
|
|
1538
|
-
readonly y: number;
|
|
1539
|
-
readonly height: number;
|
|
1540
|
-
}[];
|
|
1541
|
-
/** Per laid-out cell: width/height after vMerge expansion (cell-local stroke space). */
|
|
1542
|
-
readonly cellBoxes: readonly (readonly {
|
|
1543
|
-
readonly width: number;
|
|
1544
|
-
readonly height: number;
|
|
1545
|
-
}[])[];
|
|
1654
|
+
readonly textboxStory?: TextboxStoryLayout;
|
|
1546
1655
|
}
|
|
1547
|
-
/**
|
|
1548
|
-
* Resolve borders for every cell in a laid-out table fragment.
|
|
1549
|
-
*
|
|
1550
|
-
* Shared vertical edges: conflict(left.right, right.left) → assigned to the left cell,
|
|
1551
|
-
* segmented per row when a vMerge restart faces differing neighbors.
|
|
1552
|
-
* Shared horizontal edges: conflict(above.bottom, below.top) → assigned to the above cell,
|
|
1553
|
-
* segmented per grid column when a gridSpan cell faces differing below neighbors; vMerge
|
|
1554
|
-
* interior seams are suppressed per interval.
|
|
1555
|
-
*
|
|
1556
|
-
* When `geometry` is provided, compound edges expand into explicit stroke records with
|
|
1557
|
-
* corner-adjusted endpoints in cell-local points.
|
|
1558
|
-
*/
|
|
1559
|
-
declare function resolveTableCellBorderGrid(rows: readonly (readonly BorderGridCell[])[], table: TableBorderBox, columnCount: number, geometry?: BorderGridGeometry, work?: TableBorderGridResolveWork, ownershipBudget?: TableBorderOwnershipBudget): ResolvedCellBorders[][];
|
|
1560
|
-
/** Width contribution of a resolved edge for content inset / row sizing. */
|
|
1561
|
-
declare function borderExtentPt(edge: ResolvedTableBorderEdge | TableBorderSide | undefined): number;
|
|
1562
1656
|
|
|
1563
1657
|
/**
|
|
1564
1658
|
* A paragraph's list membership fully resolved: definition, level, marker text and geometry.
|
|
@@ -1673,297 +1767,465 @@ declare function listMarkerBox(item: ResolvedListItem, markerWidth: number, line
|
|
|
1673
1767
|
height: number;
|
|
1674
1768
|
} | null;
|
|
1675
1769
|
|
|
1770
|
+
interface StyleDefinition {
|
|
1771
|
+
readonly styleId: string;
|
|
1772
|
+
readonly type: string;
|
|
1773
|
+
readonly basedOn: string | null;
|
|
1774
|
+
/** `w:next` — the authoring style for a following paragraph. */
|
|
1775
|
+
readonly next: string | null;
|
|
1776
|
+
readonly outlineLevel: number | null;
|
|
1777
|
+
readonly paragraphProperties: readonly OoxmlProperty[];
|
|
1778
|
+
readonly runProperties: readonly OoxmlProperty[];
|
|
1779
|
+
readonly paragraphPropertiesNode: OoxmlElement | undefined;
|
|
1780
|
+
readonly tablePropertiesNode: OoxmlElement | undefined;
|
|
1781
|
+
readonly tableRowPropertiesNode: OoxmlElement | undefined;
|
|
1782
|
+
readonly conditionalTableFormats: ReadonlyMap<string, OoxmlElement>;
|
|
1783
|
+
}
|
|
1784
|
+
declare function isValidStyleId(raw: string | undefined): raw is string;
|
|
1785
|
+
|
|
1786
|
+
/** Soft ceiling on `basedOn` chain length — enough for real templates, refuses hostile graphs. */
|
|
1787
|
+
declare const MAX_STYLE_BASED_ON_DEPTH = 32;
|
|
1788
|
+
/** Soft ceiling on style definitions read from one styles part. */
|
|
1789
|
+
declare const MAX_STYLE_DEFINITIONS = 4096;
|
|
1676
1790
|
/**
|
|
1677
|
-
* The
|
|
1791
|
+
* The whole styles part, indexed and ready to resolve against.
|
|
1678
1792
|
*
|
|
1679
|
-
*
|
|
1680
|
-
*
|
|
1681
|
-
* means every REF field paints its cached result — the pre-existing degradation, and the one
|
|
1682
|
-
* header/footer and text-box stories still take. Note stories receive the body's context
|
|
1683
|
-
* through `NotesLayoutInput.refFields`.
|
|
1793
|
+
* `cacheToken` is load-bearing: it folds into layout cache producers so breaks measured under one
|
|
1794
|
+
* styles part are never reused under another.
|
|
1684
1795
|
*/
|
|
1685
|
-
interface
|
|
1796
|
+
interface StyleCascadeTable {
|
|
1797
|
+
readonly typography?: CjkTypographySettings;
|
|
1686
1798
|
/**
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1689
|
-
* identity-unchanged, and this token is the only validator that sees it. A field that
|
|
1690
|
-
* failed calibration contributes its (session-constant) cached text, so the token still
|
|
1691
|
-
* moves exactly when painted output moves.
|
|
1799
|
+
* Bounded fingerprint folded into layout cache producers so a different styles part cannot
|
|
1800
|
+
* reuse breaks measured under another cascade. Computed once per table (FNV-1a hex).
|
|
1692
1801
|
*/
|
|
1693
|
-
readonly
|
|
1694
|
-
|
|
1695
|
-
|
|
1802
|
+
readonly cacheToken: string;
|
|
1803
|
+
readonly docDefaultsRun: readonly OoxmlProperty[];
|
|
1804
|
+
readonly docDefaultsParagraph: readonly OoxmlProperty[];
|
|
1805
|
+
readonly docDefaultsParagraphNode: OoxmlElement | undefined;
|
|
1806
|
+
/** `w:style[@w:default='1'][@w:type='paragraph']` — last wins among defaults of that type. */
|
|
1807
|
+
readonly defaultParagraphStyleId: string | null;
|
|
1808
|
+
/** `w:style[@w:default='1'][@w:type='character']` — last wins among defaults of that type. */
|
|
1809
|
+
readonly defaultCharacterStyleId: string | null;
|
|
1696
1810
|
/**
|
|
1697
|
-
*
|
|
1698
|
-
*
|
|
1699
|
-
*
|
|
1700
|
-
*
|
|
1811
|
+
* `w:style[@w:default='1'][@w:type='table']` — last wins among defaults of that type.
|
|
1812
|
+
*
|
|
1813
|
+
* A `w:tbl` with no `w:tblStyle` still resolves against this one. Word's own
|
|
1814
|
+
* `TableNormal` is where the 0/108/0/108 twip cell margins live, so skipping it gives
|
|
1815
|
+
* every unstyled table padding the document says it does not have.
|
|
1701
1816
|
*/
|
|
1702
|
-
|
|
1817
|
+
readonly defaultTableStyleId: string | null;
|
|
1703
1818
|
/**
|
|
1704
|
-
* The
|
|
1705
|
-
*
|
|
1706
|
-
*
|
|
1707
|
-
*
|
|
1708
|
-
* Optional so hand-built contexts predating it stay valid.
|
|
1819
|
+
* The theme part's typefaces, for `w:rFonts` theme references.
|
|
1820
|
+
*
|
|
1821
|
+
* Lives on the cascade because it is document-level style material with the same
|
|
1822
|
+
* lifetime, and because every site that resolves run properties already holds this table.
|
|
1709
1823
|
*/
|
|
1710
|
-
|
|
1824
|
+
readonly themeFonts: ThemeFonts;
|
|
1825
|
+
readonly styles: ReadonlyMap<string, StyleDefinition>;
|
|
1826
|
+
}
|
|
1827
|
+
/**
|
|
1828
|
+
* A paragraph's properties after the cascade, plus the same list WITHOUT its own `w:pPr`.
|
|
1829
|
+
*
|
|
1830
|
+
* Both, because a writer needs to know what a paragraph INHERITS to decide whether setting a
|
|
1831
|
+
* value is a change or a no-op — and writing back an inherited value freezes it into the
|
|
1832
|
+
* paragraph as though the author had chosen it.
|
|
1833
|
+
*/
|
|
1834
|
+
interface CascadedParagraphFormatting {
|
|
1835
|
+
/** Flat paragraph properties in cascade order (defaults → bases → style → direct). */
|
|
1836
|
+
readonly paragraphProperties: readonly OoxmlProperty[];
|
|
1711
1837
|
/**
|
|
1712
|
-
* The
|
|
1713
|
-
* (missing bookmark, unsupported switches, or an anchor this scan never saw).
|
|
1838
|
+
* The same list WITHOUT the paragraph's own `w:pPr` — everything it inherits.
|
|
1714
1839
|
*
|
|
1715
|
-
*
|
|
1716
|
-
*
|
|
1717
|
-
* finalize (`finalizePageFieldProjection`) substitutes the page number the target's first
|
|
1718
|
-
* fragment lands on. Optional so hand-built contexts predating it stay valid.
|
|
1840
|
+
* Numbering needs the two tiers apart: a level's `w:pPr/w:ind` outranks the style's and is
|
|
1841
|
+
* outranked by the paragraph's own, and a flattened list cannot say which is which.
|
|
1719
1842
|
*/
|
|
1720
|
-
|
|
1843
|
+
readonly inheritedParagraphProperties: readonly OoxmlProperty[];
|
|
1844
|
+
/** Matching `w:pPr` nodes for nested border resolution. */
|
|
1845
|
+
readonly paragraphPropertyNodes: readonly OoxmlNode[];
|
|
1846
|
+
/**
|
|
1847
|
+
* Inherited run properties for CONTENT runs (before direct run `rPr`).
|
|
1848
|
+
*
|
|
1849
|
+
* Does NOT include direct `w:pPr/w:rPr` — that formats the paragraph MARK only
|
|
1850
|
+
* (ECMA-376 §17.3.1.36). Folding mark `w:sz` into content made BodyText runs with no
|
|
1851
|
+
* direct size paint at the mark's size (Selection Notice "or" alternative → 6.5pt).
|
|
1852
|
+
*/
|
|
1853
|
+
readonly runProperties: readonly OoxmlProperty[];
|
|
1854
|
+
/**
|
|
1855
|
+
* Content cascade plus direct `w:pPr/w:rPr` — empty-line metrics and last-line mark height.
|
|
1856
|
+
*/
|
|
1857
|
+
readonly markRunProperties: readonly OoxmlProperty[];
|
|
1858
|
+
/**
|
|
1859
|
+
* The style this paragraph resolved to, or null when it names none and there is no
|
|
1860
|
+
* document default. `w:contextualSpacing` compares neighbours by exactly this.
|
|
1861
|
+
*/
|
|
1862
|
+
readonly styleId: string | null;
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* What a table style contributes to the paragraphs of ONE cell: the style's whole-table
|
|
1866
|
+
* `w:pPr`/`w:rPr` followed by every `w:tblStylePr` the cell is under (17.7.6.6), weakest
|
|
1867
|
+
* first in the caller's condition order (banding, column, row, corner).
|
|
1868
|
+
*
|
|
1869
|
+
* This is how Word makes a header row bold and centred while the document states nothing
|
|
1870
|
+
* but `<w:tblStyle w:val="…"/>` on the table and plain runs in the cells.
|
|
1871
|
+
*/
|
|
1872
|
+
interface TableCellStyleFormatting {
|
|
1873
|
+
readonly paragraphProperties: readonly OoxmlProperty[];
|
|
1874
|
+
/** Matching `w:pPr` nodes, for nested `w:pBdr` / `w:tabs` resolution. */
|
|
1875
|
+
readonly paragraphPropertyNodes: readonly OoxmlElement[];
|
|
1876
|
+
/** Inherited run properties for every run in the cell, before the paragraph style. */
|
|
1877
|
+
readonly runProperties: readonly OoxmlProperty[];
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Build a cascade table from a styles part root.
|
|
1881
|
+
*
|
|
1882
|
+
* Only direct `w:style` children of the root participate (bounded count). Duplicate
|
|
1883
|
+
* `styleId` values keep the last definition, matching Word's reader for this fixture class.
|
|
1884
|
+
* Default paragraph/character style ids track `w:default="1"` with the same last-wins rule.
|
|
1885
|
+
*/
|
|
1886
|
+
declare function buildStyleCascadeTable(stylesRoot: OoxmlElement | null, themeFonts?: ThemeFonts, settingsRoot?: OoxmlElement | null): StyleCascadeTable;
|
|
1887
|
+
/**
|
|
1888
|
+
* Cascade paragraph + inherited run properties for one paragraph's direct `w:pPr`.
|
|
1889
|
+
*
|
|
1890
|
+
* Order: `docDefaults` → table style → `basedOn` ancestors → paragraph style → direct
|
|
1891
|
+
* formatting, which is the style hierarchy of 17.7.2: a table style sits above the document
|
|
1892
|
+
* defaults and below the paragraph style a cell paragraph names for itself.
|
|
1893
|
+
* When `w:pStyle` is absent, the document's default paragraph style (`w:default="1"`) is used.
|
|
1894
|
+
* Direct formatting is last so it overrides inherited values inside the existing resolvers.
|
|
1895
|
+
*/
|
|
1896
|
+
declare function cascadeParagraphFormatting(table: StyleCascadeTable, directPPr: OoxmlNode | undefined, tableCellStyle?: TableCellStyleFormatting): CascadedParagraphFormatting;
|
|
1897
|
+
/**
|
|
1898
|
+
* Bottom border after cascade: a later `w:pBdr` replaces an earlier one; absence inherits.
|
|
1899
|
+
* `nil`/`none` clear the edge via `paragraphBorders`.
|
|
1900
|
+
*/
|
|
1901
|
+
declare function cascadedBottomBorder(paragraphPropertyNodes: readonly OoxmlNode[]): ParagraphBorderEdge | undefined;
|
|
1902
|
+
/**
|
|
1903
|
+
* Merge inherited paragraph-style run props with a run's direct `rPr` (direct last).
|
|
1904
|
+
*
|
|
1905
|
+
* When a cascade table is supplied, also resolves `w:rStyle` character styles (basedOn chain,
|
|
1906
|
+
* cycle/depth capped). Runs without an explicit `rStyle` pick up the default character style
|
|
1907
|
+
* (`w:default="1"`). Precedence: inherited → character style chain → direct formatting.
|
|
1908
|
+
*
|
|
1909
|
+
* PASS `inheritedRunProperties` BY IDENTITY. It must be an array
|
|
1910
|
+
* {@link cascadeParagraphFormatting} returned — `runProperties` or `markRunProperties` — and
|
|
1911
|
+
* not a copy of one. A toggle property (ECMA-376 §17.7.3) resolves per level of the style
|
|
1912
|
+
* hierarchy, and the levels below the character style resolve to more than a true or a false:
|
|
1913
|
+
* whether the document defaults' short circuit is still standing decides what the character
|
|
1914
|
+
* style's own toggle does next, and no single `w:b` element can spell that. The paragraph
|
|
1915
|
+
* cascade attaches that state to the array it returns, so spreading, filtering or sorting the
|
|
1916
|
+
* list drops it. (`Object.freeze` returns the same object, so that one is safe.) A list
|
|
1917
|
+
* without it is read as one ordinary level, which is the most a bare property list can say
|
|
1918
|
+
* and is what a caller assembling its own list gets.
|
|
1919
|
+
*/
|
|
1920
|
+
declare function cascadeRunProperties(inheritedRunProperties: readonly OoxmlProperty[], directRunProperties: readonly OoxmlProperty[], table?: StyleCascadeTable): readonly OoxmlProperty[];
|
|
1921
|
+
/** Everything the line breaker needs about one paragraph, already cascaded and converted. */
|
|
1922
|
+
interface ParagraphLayoutInputs {
|
|
1923
|
+
readonly props: OoxmlProperty[];
|
|
1924
|
+
readonly indent: {
|
|
1925
|
+
left: number;
|
|
1926
|
+
right: number;
|
|
1927
|
+
hanging: number;
|
|
1928
|
+
firstLine: number;
|
|
1929
|
+
};
|
|
1930
|
+
readonly available: number;
|
|
1931
|
+
readonly alignment: Alignment;
|
|
1932
|
+
readonly spacing: ParagraphSpacing;
|
|
1933
|
+
/** Resolved `w:line` / `w:lineRule`; single spacing where the cascade says nothing. */
|
|
1934
|
+
readonly lineSpacing: ParagraphLineSpacing;
|
|
1935
|
+
/** `w:contextualSpacing`: drop before/after between same-style neighbours. */
|
|
1936
|
+
readonly contextualSpacing: boolean;
|
|
1937
|
+
/** Resolved paragraph style id, for the `w:contextualSpacing` neighbour comparison. */
|
|
1938
|
+
readonly styleId: string | null;
|
|
1939
|
+
/** Resolved outline level, with 9/invalid values treated as body text. */
|
|
1940
|
+
readonly outlineLevel: number | null;
|
|
1941
|
+
readonly bottomBorder: ParagraphBorderEdge | undefined;
|
|
1942
|
+
/**
|
|
1943
|
+
* Every `CT_PBdr` edge after cascade, not just the bottom one.
|
|
1944
|
+
*
|
|
1945
|
+
* `bottomBorder` stays alongside it because the fragment signature and the table flow
|
|
1946
|
+
* read that field by name; this is the whole box, so a cell paragraph gets the same
|
|
1947
|
+
* frame a body paragraph does.
|
|
1948
|
+
*/
|
|
1949
|
+
readonly borders: ParagraphBorders;
|
|
1950
|
+
/** Validated 6-hex paragraph shading fill from cascaded `w:pPr/w:shd`, absent for none. */
|
|
1951
|
+
readonly shading: string | undefined;
|
|
1952
|
+
readonly inheritedRunProperties: readonly OoxmlProperty[];
|
|
1953
|
+
/**
|
|
1954
|
+
* Paragraph-mark cascade (`inheritedRunProperties` + direct `w:pPr/w:rPr`).
|
|
1955
|
+
* Empty-line sizing and last-line mark height — never content-run face.
|
|
1956
|
+
*/
|
|
1957
|
+
readonly markRunProperties: readonly OoxmlProperty[];
|
|
1958
|
+
/** Cascaded custom tab stops + default interval for paragraph-flow breaking. */
|
|
1959
|
+
readonly tabStops: ResolvedTabStops;
|
|
1960
|
+
/**
|
|
1961
|
+
* Fingerprint folded into the paragraph layout cache key — nested `w:tabs` are absent
|
|
1962
|
+
* from flat property bags, so style-inherited stops must be named explicitly.
|
|
1963
|
+
*/
|
|
1964
|
+
readonly tabStopsCacheToken: string;
|
|
1965
|
+
/** Resolved list marker inputs when the paragraph participates in numbering. */
|
|
1966
|
+
readonly listItem?: ResolvedListItem;
|
|
1721
1967
|
}
|
|
1722
1968
|
/**
|
|
1723
|
-
*
|
|
1969
|
+
* Resolve every paragraph input semantic layout / table cells share: cascaded props when a
|
|
1970
|
+
* style table is present, otherwise direct formatting only.
|
|
1971
|
+
*
|
|
1972
|
+
* When `listItem` is provided, its merged level indent becomes the paragraph indent (list
|
|
1973
|
+
* hanging / left from `numbering.xml`), which is what Word uses for fixture list paragraphs
|
|
1974
|
+
* that author no direct `w:ind`.
|
|
1975
|
+
*
|
|
1976
|
+
* `tableCellStyle` carries what the enclosing table's style says about this cell's
|
|
1977
|
+
* paragraphs; body paragraphs pass nothing.
|
|
1978
|
+
*
|
|
1979
|
+
* `inTableCell` is asked for separately because a cell paragraph may have no table style to
|
|
1980
|
+
* inherit at all, and `w:beforeAutospacing` still needs to know it is in a cell.
|
|
1981
|
+
*/
|
|
1982
|
+
declare function resolveParagraphLayoutInputs(paragraph: OoxmlElement, contentWidth: number, styleCascade: StyleCascadeTable | undefined, listItem?: ResolvedListItem, tableCellStyle?: TableCellStyleFormatting, inTableCell?: boolean): ParagraphLayoutInputs;
|
|
1983
|
+
|
|
1984
|
+
/**
|
|
1985
|
+
* `w:tblW` / `w:tcW` / `w:wBefore` (CT_TblWidth, 17.4.63 / 17.4.71 / 17.4.86): a PREFERRED
|
|
1986
|
+
* width plus the unit it is stated in. Preferred is the operative word — it is what the
|
|
1987
|
+
* producer asked for, not what the table resolved to.
|
|
1724
1988
|
*
|
|
1725
|
-
*
|
|
1726
|
-
*
|
|
1727
|
-
* signature that no painted output moved. The verdict itself lives beside the finalize pass
|
|
1728
|
-
* (`field-page-furniture.ts`), keyed weakly on this object; the registry below carries the
|
|
1729
|
-
* object across passes the same way REF verdicts are carried.
|
|
1989
|
+
* `pct` is stated in fiftieths of a percent (5000 = 100%) by Word, and in the `"50%"`
|
|
1990
|
+
* string form of `ST_Percentage` by others; both are read. `auto` and `nil` carry no width.
|
|
1730
1991
|
*/
|
|
1731
|
-
type
|
|
1992
|
+
type PreferredWidthType = 'dxa' | 'pct' | 'auto' | 'nil';
|
|
1732
1993
|
/**
|
|
1733
|
-
*
|
|
1734
|
-
*
|
|
1994
|
+
* `w:tblW` / `w:tcW` — a requested width, whose UNIT depends on its type.
|
|
1995
|
+
*
|
|
1996
|
+
* Points for `dxa`, percent for `pct`, and zero for `auto`/`nil`. Reading `value` without `type`
|
|
1997
|
+
* is always wrong.
|
|
1735
1998
|
*/
|
|
1736
|
-
interface
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
readonly cached: string;
|
|
1741
|
-
readonly calibration: PageRefCalibrationCell;
|
|
1999
|
+
interface PreferredWidth {
|
|
2000
|
+
readonly type: PreferredWidthType;
|
|
2001
|
+
/** POINTS for `dxa`, PERCENT (0–100) for `pct`, 0 for `auto`/`nil`. */
|
|
2002
|
+
readonly value: number;
|
|
1742
2003
|
}
|
|
2004
|
+
/** The frozen "no preferred width" value — what a table or cell that declares none resolves to. */
|
|
2005
|
+
declare const AUTO_PREFERRED_WIDTH: PreferredWidth;
|
|
2006
|
+
|
|
1743
2007
|
/**
|
|
1744
|
-
*
|
|
1745
|
-
*
|
|
1746
|
-
*
|
|
1747
|
-
*
|
|
2008
|
+
* The uniform 3 pt (60 twip) inset this lane used to apply on every side.
|
|
2009
|
+
*
|
|
2010
|
+
* Word's defaults are not uniform — see {@link DEFAULT_CELL_MARGINS} — so nothing resolves
|
|
2011
|
+
* against this any more. Kept because it is published.
|
|
1748
2012
|
*/
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
2013
|
+
declare const CELL_PAD = 3;
|
|
2014
|
+
/** Resolved cell padding in points, after the table default and any per-cell override. */
|
|
2015
|
+
interface CellMarginsPt {
|
|
2016
|
+
readonly top: number;
|
|
2017
|
+
readonly right: number;
|
|
2018
|
+
readonly bottom: number;
|
|
2019
|
+
readonly left: number;
|
|
1752
2020
|
}
|
|
1753
2021
|
/**
|
|
1754
|
-
*
|
|
2022
|
+
* Word's own default cell padding, for a document whose styles part states none.
|
|
1755
2023
|
*
|
|
1756
|
-
*
|
|
1757
|
-
*
|
|
1758
|
-
*
|
|
1759
|
-
*
|
|
2024
|
+
* 0 top, 0 bottom, 108 twips left and right — the values `TableNormal` carries. A uniform
|
|
2025
|
+
* 3 pt on all four sides made every row of every table that authored no `w:tblCellMar` 6 pt
|
|
2026
|
+
* taller than Word's, and that error compounds down a table until it paginates a page early.
|
|
2027
|
+
* A document that DOES ship a default table style resolves against that instead; this is the
|
|
2028
|
+
* floor beneath it.
|
|
1760
2029
|
*/
|
|
1761
|
-
declare
|
|
2030
|
+
declare const DEFAULT_CELL_MARGINS: CellMarginsPt;
|
|
2031
|
+
|
|
2032
|
+
/** `w:vAlign` — where a cell's content sits when the row is taller than the content. */
|
|
2033
|
+
type CellVerticalAlign = 'top' | 'center' | 'bottom';
|
|
1762
2034
|
|
|
1763
2035
|
/**
|
|
1764
|
-
*
|
|
2036
|
+
* Layout-time nesting ceiling. Parse-time depth (MAX_DEPTH = 256 XML levels) alone still
|
|
2037
|
+
* admits ~80 levels of `w:tbl` recursion into the layout walk; deeper tables render as an
|
|
2038
|
+
* empty cell box rather than recursing.
|
|
2039
|
+
*/
|
|
2040
|
+
declare const MAX_TABLE_NESTING = 16;
|
|
2041
|
+
/**
|
|
2042
|
+
* Soft ceiling on an authored `w:trHeight` (~22"). Hostile `w:val` otherwise becomes a
|
|
2043
|
+
* multi-page row that every pagination preflight and cell box inherits.
|
|
2044
|
+
*/
|
|
2045
|
+
declare const MAX_TABLE_ROW_HEIGHT_PT: number;
|
|
2046
|
+
/**
|
|
2047
|
+
* `w:trPr/w:trHeight` (17.4.81) resolved for layout. Points leave the reader already —
|
|
2048
|
+
* twips convert once here, matching every other table geometry boundary.
|
|
1765
2049
|
*
|
|
1766
|
-
*
|
|
1767
|
-
*
|
|
1768
|
-
* of failing the layout pass.
|
|
2050
|
+
* Word quirk (matches Form025U and Word's UI export): a present `@w:val` with an omitted
|
|
2051
|
+
* `@w:hRule` is treated as `atLeast`, not ECMA's `auto`. Explicit `auto` still ignores val.
|
|
1769
2052
|
*/
|
|
1770
|
-
type
|
|
1771
|
-
/** Flowed content is taller than the extent; trailing fragments were dropped. */
|
|
1772
|
-
| 'textbox-height-clip';
|
|
2053
|
+
type TableRowHeightRule = 'auto' | 'atLeast' | 'exact';
|
|
1773
2054
|
/**
|
|
1774
|
-
*
|
|
2055
|
+
* `w:trHeight` — a row's height rule and its value.
|
|
1775
2056
|
*
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
2057
|
+
* `auto` carries no value at all, which is why this is a union rather than a rule plus an
|
|
2058
|
+
* optional number.
|
|
1778
2059
|
*/
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
readonly
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
2060
|
+
type TableRowHeight = {
|
|
2061
|
+
readonly rule: 'auto';
|
|
2062
|
+
} | {
|
|
2063
|
+
readonly rule: 'atLeast' | 'exact';
|
|
2064
|
+
readonly valuePt: number;
|
|
2065
|
+
};
|
|
2066
|
+
/** `w:tblPr/w:jc` (17.4.29, ST_JcTable): where the table sits within the text column. */
|
|
2067
|
+
type TableAlignment = 'left' | 'center' | 'right';
|
|
2068
|
+
/**
|
|
2069
|
+
* `w:tblpPr/@w:horzAnchor` (17.4.58) and `@w:vertAnchor` (17.4.66): the box a floated
|
|
2070
|
+
* table's offsets are measured from. Absent means `text` for both.
|
|
2071
|
+
*/
|
|
2072
|
+
type TableFloatAnchor = 'text' | 'margin' | 'page';
|
|
2073
|
+
/** `w:tblpPr/@w:tblpXSpec` (17.4.63, ST_XAlign). */
|
|
2074
|
+
type TableFloatXSpec = 'left' | 'center' | 'right' | 'inside' | 'outside';
|
|
2075
|
+
/** `w:tblpPr/@w:tblpYSpec` (17.4.65, ST_YAlign). */
|
|
2076
|
+
type TableFloatYSpec = 'inline' | 'top' | 'center' | 'bottom' | 'inside' | 'outside';
|
|
2077
|
+
/**
|
|
2078
|
+
* `w:tblPr/w:tblpPr` (17.4.57) — a table positioned against an anchor box rather than at
|
|
2079
|
+
* the point in the text where it was authored.
|
|
2080
|
+
*
|
|
2081
|
+
* A spec (`tblpXSpec`/`tblpYSpec`) supersedes the matching offset when both are present:
|
|
2082
|
+
* 17.4.57 states the alignment outright, and the offset only answers "how far from the
|
|
2083
|
+
* anchor" for the case where no alignment was stated.
|
|
2084
|
+
*/
|
|
2085
|
+
interface TableFloatPosition {
|
|
2086
|
+
readonly horzAnchor: TableFloatAnchor;
|
|
2087
|
+
readonly vertAnchor: TableFloatAnchor;
|
|
2088
|
+
readonly xSpec?: TableFloatXSpec;
|
|
2089
|
+
/** `w:tblpX` in points; signed, so a table can be pulled into the margin. */
|
|
2090
|
+
readonly xPt: number;
|
|
2091
|
+
readonly ySpec?: TableFloatYSpec;
|
|
2092
|
+
/** `w:tblpY` in points; signed. */
|
|
2093
|
+
readonly yPt: number;
|
|
2094
|
+
readonly distances?: {
|
|
2095
|
+
readonly top: number;
|
|
2096
|
+
readonly right: number;
|
|
2097
|
+
readonly bottom: number;
|
|
2098
|
+
readonly left: number;
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* One cell in the resolved table structure.
|
|
2103
|
+
*
|
|
2104
|
+
* `gridSpan` is clamped at READ time and layout never re-derives it — the value comes from a file
|
|
2105
|
+
* and would otherwise be a loop bound an attacker controls.
|
|
2106
|
+
*/
|
|
2107
|
+
interface SemanticTableCell {
|
|
2108
|
+
readonly id: string;
|
|
2109
|
+
/** Derived content-edge geometry for a verified legacy full-width parent table. */
|
|
2110
|
+
readonly legacyContentAlignment?: true;
|
|
2111
|
+
/** Clamped to [1, MAX_TABLE_COLUMNS] at read time; layout never re-derives it. */
|
|
2112
|
+
readonly gridSpan: number;
|
|
1801
2113
|
/**
|
|
1802
|
-
*
|
|
2114
|
+
* Absolute grid column this cell starts on, after `w:gridBefore` and every preceding
|
|
2115
|
+
* span. Structural conditional formats and cell geometry both key on this, never on the
|
|
2116
|
+
* cell's position in the row: one `gridSpan` cell otherwise shifts firstCol/lastCol and
|
|
2117
|
+
* the vertical bands for every cell after it.
|
|
2118
|
+
*/
|
|
2119
|
+
readonly gridColumn: number;
|
|
2120
|
+
/** Canonical `w:gridCol` node id for this cell's start column, when the grid is authored. */
|
|
2121
|
+
readonly gridColumnId?: string;
|
|
2122
|
+
/** A vMerge cell that is not the restart continues the cell above: box, no content. */
|
|
2123
|
+
readonly vMergeContinue: boolean;
|
|
2124
|
+
/** `w:vAlign` — defaults to top when omitted/unrecognised. */
|
|
2125
|
+
readonly vAlign: CellVerticalAlign;
|
|
2126
|
+
/** `w:textDirection`; unsupported values keep horizontal layout. */
|
|
2127
|
+
readonly textDirection: 'horizontal' | 'btLr';
|
|
2128
|
+
/** Resolved per-side margins (tcMar over tblCellMar over the table style over Word's default). */
|
|
2129
|
+
readonly margins: CellMarginsPt;
|
|
2130
|
+
/** Three-state authored `tcBorders` (omitted / none / edge). */
|
|
2131
|
+
readonly borders: CellBorderBox;
|
|
2132
|
+
/** Validated 6-hex shading fill, absent for none/auto. */
|
|
2133
|
+
readonly shading?: string;
|
|
2134
|
+
/**
|
|
2135
|
+
* `w:tcW` — the width this cell asked for, as authored.
|
|
1803
2136
|
*
|
|
1804
|
-
*
|
|
1805
|
-
*
|
|
1806
|
-
*
|
|
1807
|
-
*
|
|
1808
|
-
*
|
|
1809
|
-
* (#467). Absent when the clip dropped no drawings, so the common story keys byte-for-byte
|
|
1810
|
-
* as before.
|
|
2137
|
+
* Published for consumers that need the cell's own statement (a column-resize handle has
|
|
2138
|
+
* to write back to it). Column geometry is NOT derived from this field: the resolver works
|
|
2139
|
+
* from a flat claim list built in the same pass, because resolving a column means looking
|
|
2140
|
+
* at every cell that covers it across every row, not at one cell at a time. Read
|
|
2141
|
+
* `columnWidthsPt` for what the table actually laid out.
|
|
1811
2142
|
*/
|
|
1812
|
-
readonly
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
interface InlineDrawingRecord {
|
|
1816
|
-
readonly kind: 'inlineDrawing';
|
|
1817
|
-
readonly drawingNodeId: string;
|
|
1818
|
-
readonly paragraphId: string;
|
|
1819
|
-
readonly ownerPartName: string;
|
|
1820
|
-
readonly start: number;
|
|
1821
|
-
/** Left edge of the extent box (slot + distL). */
|
|
1822
|
-
readonly x: number;
|
|
1823
|
-
readonly y: number;
|
|
1824
|
-
readonly width: number;
|
|
1825
|
-
readonly height: number;
|
|
1826
|
-
readonly distL: number;
|
|
1827
|
-
readonly distR: number;
|
|
1828
|
-
readonly distT: number;
|
|
1829
|
-
readonly distB: number;
|
|
1830
|
-
/** Caret/hit advance start (slot left, before distL). */
|
|
1831
|
-
readonly advanceStart: number;
|
|
1832
|
-
/** Caret/hit advance end (slot + totalWidth). */
|
|
1833
|
-
readonly advanceEnd: number;
|
|
1834
|
-
readonly baselineOffset: number;
|
|
1835
|
-
readonly paintBounds: LayoutBox;
|
|
1836
|
-
readonly hitBounds: LayoutBox;
|
|
1837
|
-
readonly geometry: DrawingGeometry;
|
|
1838
|
-
readonly resource: ImageResourceState;
|
|
1839
|
-
readonly accessibility: DrawingAccessibility;
|
|
1840
|
-
/** Sanitized external hyperlink projection; inert until an explicit gesture activates it. */
|
|
1841
|
-
readonly hyperlinkHref: string | null;
|
|
1842
|
-
readonly effects: Readonly<{
|
|
1843
|
-
readonly grayscale: boolean;
|
|
1844
|
-
readonly brightness: number;
|
|
1845
|
-
readonly contrast: number;
|
|
1846
|
-
}>;
|
|
1847
|
-
readonly crop: SourceCrop;
|
|
1848
|
-
readonly transform: DrawingTransform;
|
|
1849
|
-
/** Fixed non-picture graphic kind for refusal labels (`chart`, `group`, …); null for pictures. */
|
|
1850
|
-
readonly placeholderGraphicKind: string | null;
|
|
1851
|
-
/** Typed solid-geometry payload for a renderable `wps:wsp` shape; null otherwise. */
|
|
1852
|
-
readonly vectorShape: VectorShapeProjection | null;
|
|
2143
|
+
readonly preferredWidth: PreferredWidth;
|
|
1853
2144
|
/**
|
|
1854
|
-
*
|
|
1855
|
-
*
|
|
1856
|
-
* Absent when the drawing is untracked.
|
|
2145
|
+
* What the table style says about this cell's paragraphs and runs (17.7.6.6) — a header
|
|
2146
|
+
* row's bold and centring live here, not in the cell's own properties.
|
|
1857
2147
|
*/
|
|
1858
|
-
readonly
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
readonly ownerPartName: string;
|
|
1862
|
-
/** Precomputed run-level atom id (`w:drawing` or MC wrapper) → projection. */
|
|
1863
|
-
readonly projectionForAtom?: (atomNodeId: string) => DrawingProjection | null;
|
|
1864
|
-
readonly project: (drawing: OoxmlDrawingNode) => DrawingProjection | null;
|
|
1865
|
-
readonly resourceOf: (projection: DrawingProjection) => ImageResourceState;
|
|
2148
|
+
readonly styleFormatting: TableCellStyleFormatting;
|
|
2149
|
+
/** Block children in reading order, with content-control wrappers flattened. */
|
|
2150
|
+
readonly blocks: readonly OoxmlElement[];
|
|
1866
2151
|
}
|
|
1867
|
-
/**
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
readonly
|
|
1872
|
-
readonly horizontalFrame: DrawingHorizontalReferenceFrame;
|
|
1873
|
-
readonly verticalFrame: DrawingVerticalReferenceFrame;
|
|
1874
|
-
readonly horizontalFrameOrigin: number;
|
|
1875
|
-
readonly verticalFrameOrigin: number;
|
|
1876
|
-
readonly behindDocument: boolean;
|
|
1877
|
-
readonly allowOverlap: boolean;
|
|
1878
|
-
readonly layoutInCell: boolean;
|
|
1879
|
-
readonly relativeHeight: number;
|
|
1880
|
-
readonly wrap: Exclude<ImageWrapTarget, 'inline'>;
|
|
1881
|
-
readonly layoutFallback?: AnchoredDrawingLayoutFallback;
|
|
1882
|
-
/** Canonical document traversal index within the owner story part. */
|
|
1883
|
-
readonly sourceOrder?: number;
|
|
2152
|
+
/** One row in the resolved structure: its cells, its height rule, and any row-level revision. */
|
|
2153
|
+
interface SemanticTableRow {
|
|
2154
|
+
readonly id: string;
|
|
2155
|
+
/** Pending Word row insertion/deletion authored in `w:trPr`. */
|
|
2156
|
+
readonly revisionKind?: 'insert' | 'delete';
|
|
1884
2157
|
/**
|
|
1885
|
-
*
|
|
1886
|
-
*
|
|
1887
|
-
*
|
|
2158
|
+
* The `w:trPr/w:ins|w:del` attribution, carried with the kind so a painted row can say
|
|
2159
|
+
* WHOSE pending decision it is — the review model addresses the decision by exactly this
|
|
2160
|
+
* `(id, author, date)` triple, and a surface with only the kind could highlight the row
|
|
2161
|
+
* but never open its card.
|
|
1888
2162
|
*/
|
|
1889
|
-
readonly
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
/**
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
/**
|
|
1900
|
-
readonly
|
|
1901
|
-
|
|
1902
|
-
readonly anchor: string | null;
|
|
1903
|
-
/** `\o` — the hover tooltip, or null. */
|
|
1904
|
-
readonly tooltip: string | null;
|
|
2163
|
+
readonly revisionId?: string;
|
|
2164
|
+
readonly revisionAuthor?: string;
|
|
2165
|
+
readonly revisionDate?: string;
|
|
2166
|
+
/** `w:trPr/w:tblHeader` — the row repeats atop each page the table continues onto. */
|
|
2167
|
+
readonly isHeader: boolean;
|
|
2168
|
+
/**
|
|
2169
|
+
* `w:trPr/w:cantSplit` — the row must stay on one page. When it cannot fit a fresh page,
|
|
2170
|
+
* layout fails closed rather than fragmenting or overflowing the content box.
|
|
2171
|
+
*/
|
|
2172
|
+
readonly cantSplit: boolean;
|
|
2173
|
+
/** `w:trPr/w:trHeight` — auto / atLeast floor / exact (clipped) row height. */
|
|
2174
|
+
readonly height: TableRowHeight;
|
|
2175
|
+
readonly cells: readonly SemanticTableCell[];
|
|
1905
2176
|
}
|
|
1906
|
-
|
|
1907
2177
|
/**
|
|
1908
|
-
*
|
|
2178
|
+
* A table resolved into a rectangular grid: column widths, rows, and the widths it asked for.
|
|
1909
2179
|
*
|
|
1910
|
-
*
|
|
1911
|
-
*
|
|
1912
|
-
* view decision made downstream, so this states the fact and nothing about the appearance.
|
|
2180
|
+
* The grid is normalized here so layout never has to reconcile `w:gridCol` against actual cell
|
|
2181
|
+
* spans — vertical merges and column spans are already accounted for.
|
|
1913
2182
|
*/
|
|
1914
|
-
interface
|
|
2183
|
+
interface SemanticTableStructure {
|
|
2184
|
+
readonly columnWidthsPt: readonly number[];
|
|
2185
|
+
readonly rows: readonly SemanticTableRow[];
|
|
2186
|
+
/** Verified pre-2013 content-aligned full-width inline table; derived, never serialized. */
|
|
2187
|
+
readonly legacyContentAlignment?: true;
|
|
2188
|
+
/** `w:tblPr/w:tblW` — the width the table asked for. */
|
|
2189
|
+
readonly tableWidth: PreferredWidth;
|
|
1915
2190
|
/**
|
|
1916
|
-
*
|
|
1917
|
-
*
|
|
1918
|
-
*
|
|
1919
|
-
* turns it off — because they mark the blanks somebody is meant to fill in.
|
|
2191
|
+
* `w:tblInd` (17.4.50) in points — "this indentation should shift the table into the text
|
|
2192
|
+
* margin by the specified amount". Applies to a left-aligned table; `w:jc` decides the
|
|
2193
|
+
* placement outright for the other two.
|
|
1920
2194
|
*/
|
|
1921
|
-
readonly
|
|
2195
|
+
readonly indentPt: number;
|
|
2196
|
+
/** `w:tblPr/w:jc` (17.4.29) — where the table sits in the text column. */
|
|
2197
|
+
readonly alignment: TableAlignment;
|
|
1922
2198
|
/**
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1925
|
-
* The paragraph walk cannot know which page the field lands on — layout runs before the page
|
|
1926
|
-
* count — so it paints a placeholder and records the field's kind here. Document finalize
|
|
1927
|
-
* (`substituteBodyPageFields`) reads this marker and substitutes the real value per page.
|
|
1928
|
-
* Absent in headers/footers, which evaluate live through their own per-page projector.
|
|
2199
|
+
* `w:tblPr/w:tblpPr` (17.4.57) — present when the table is positioned against an anchor
|
|
2200
|
+
* box. Placement then comes from {@link tableFloatOriginX} rather than `w:jc`/`w:tblInd`.
|
|
1929
2201
|
*/
|
|
1930
|
-
readonly
|
|
1931
|
-
readonly kind: AllowlistedPageField;
|
|
1932
|
-
/** The field's `\#` numeric picture, applied when finalize substitutes the value. */
|
|
1933
|
-
readonly picture?: string;
|
|
1934
|
-
};
|
|
2202
|
+
readonly float?: TableFloatPosition;
|
|
1935
2203
|
/**
|
|
1936
|
-
*
|
|
1937
|
-
*
|
|
1938
|
-
*
|
|
1939
|
-
*
|
|
1940
|
-
*
|
|
1941
|
-
* first fragment, gated per field on the calibration verdict.
|
|
2204
|
+
* `w:tblCellSpacing` (17.4.45) in points: the gap between adjacent cell edges. Applied as
|
|
2205
|
+
* a half-gap inset on each side of every cell, so cells separate visually without the grid
|
|
2206
|
+
* itself moving. Word ALSO grows the table's overall width by the spacing it adds around
|
|
2207
|
+
* the outside; that part is not modelled, so a spaced table is laid out on the same grid
|
|
2208
|
+
* its file states rather than a wider one.
|
|
1942
2209
|
*/
|
|
1943
|
-
readonly
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2210
|
+
readonly cellSpacingPt: number;
|
|
2211
|
+
/**
|
|
2212
|
+
* `w:tblPr/w:tblLayout/@w:type="fixed"` (17.4.52 — 17.4.53 is the `w:tblPrEx` exception
|
|
2213
|
+
* variant, not this element). Fixed layout takes the grid as final;
|
|
2214
|
+
* anything else is autofit, which in Word never renders wider than the text column.
|
|
2215
|
+
*/
|
|
2216
|
+
readonly layoutFixed: boolean;
|
|
2217
|
+
/** Table-level `tblBorders` (three-state, including insideH/insideV). */
|
|
2218
|
+
readonly tableBorders: TableBorderBox;
|
|
2219
|
+
/** Table-level `tblCellMar` defaults (per-side, Word's own default when a side is omitted). */
|
|
2220
|
+
readonly defaultMargins: CellMarginsPt;
|
|
1949
2221
|
}
|
|
1950
2222
|
/**
|
|
1951
|
-
*
|
|
1952
|
-
*
|
|
1953
|
-
* Injected rather than computed here because resolving `r:id` needs the PACKAGE's
|
|
1954
|
-
* relationships and this module only ever sees one part's tree. `null` means the caller
|
|
1955
|
-
* declined to project — the runs still measure and paint, they simply carry no link, which is
|
|
1956
|
-
* the right degradation: text is never lost for want of a target.
|
|
1957
|
-
*/
|
|
1958
|
-
type HyperlinkProjector = (link: OoxmlNode) => SpanLinkRecord | null;
|
|
1959
|
-
/**
|
|
1960
|
-
* How layout turns a parsed HYPERLINK field instruction into the sanitized record spans carry.
|
|
1961
|
-
*
|
|
1962
|
-
* Injected for the same reason as {@link HyperlinkProjector}: the spec's raw target must cross
|
|
1963
|
-
* the surface's ONE href trust boundary, and layout owns no sanitization policy. `null` means
|
|
1964
|
-
* no link — the cached result still paints as plain text, which is the right degradation.
|
|
2223
|
+
* Read one typed table node into a bounded structure, or null when the node is not a
|
|
2224
|
+
* typed table or sits beyond the nesting ceiling.
|
|
1965
2225
|
*/
|
|
1966
|
-
|
|
2226
|
+
declare function readTableStructure(table: OoxmlNode, contentWidthPt: number, depth: number, styleCascade?: StyleCascadeTable,
|
|
2227
|
+
/** Which revisions the view resolves away; only the proposed result performs the join. */
|
|
2228
|
+
displayMode?: RevisionDisplayMode, authorFilter?: RevisionAuthorFilter, compatibilityMode?: number): SemanticTableStructure | null;
|
|
1967
2229
|
|
|
1968
2230
|
interface EquationGeometryBase {
|
|
1969
2231
|
readonly box: LayoutBox;
|
|
@@ -2384,6 +2646,21 @@ interface ParagraphFragmentRecord {
|
|
|
2384
2646
|
readonly paragraphId: string;
|
|
2385
2647
|
/** 0 for the first fragment of the paragraph, 1 for its continuation, and so on. */
|
|
2386
2648
|
readonly fragmentIndex: number;
|
|
2649
|
+
/** A fixed text frame clips its painted ink to this fragment's box; source ranges remain intact. */
|
|
2650
|
+
readonly clipToBox?: true;
|
|
2651
|
+
/** A positioned text frame retains its source identity without consuming body flow height. */
|
|
2652
|
+
readonly outOfFlow?: true;
|
|
2653
|
+
/** Placement and wrapping of one authored text-frame group, in page-content coordinates. */
|
|
2654
|
+
readonly positionedFrame?: {
|
|
2655
|
+
readonly anchorId: string;
|
|
2656
|
+
readonly columnIndex: number;
|
|
2657
|
+
readonly groupId: string;
|
|
2658
|
+
readonly sourceOrder: number;
|
|
2659
|
+
readonly wrap: 'around' | 'none' | 'notBeside';
|
|
2660
|
+
readonly hSpace: number;
|
|
2661
|
+
readonly vSpace: number;
|
|
2662
|
+
readonly box: LayoutBox;
|
|
2663
|
+
};
|
|
2387
2664
|
readonly range: SourceRange;
|
|
2388
2665
|
readonly props: readonly OoxmlProperty[];
|
|
2389
2666
|
/** Resolved paragraph style after the style/default cascade, or null when none applies. */
|
|
@@ -2543,6 +2820,13 @@ interface ListMarkerRecord {
|
|
|
2543
2820
|
*/
|
|
2544
2821
|
interface TableFragmentRecord {
|
|
2545
2822
|
readonly kind: 'table';
|
|
2823
|
+
/** Source and positioning inputs needed to reconstruct wrapping on an incremental pass. */
|
|
2824
|
+
readonly floatingWrap?: {
|
|
2825
|
+
readonly anchorId: string;
|
|
2826
|
+
readonly columnIndex: number;
|
|
2827
|
+
readonly float: TableFloatPosition;
|
|
2828
|
+
readonly sourceOrder: number;
|
|
2829
|
+
};
|
|
2546
2830
|
readonly id: string;
|
|
2547
2831
|
/** Canonical node id of the `w:tbl`. */
|
|
2548
2832
|
readonly tableId: string;
|
|
@@ -2914,4 +3198,4 @@ interface TextMeasurer {
|
|
|
2914
3198
|
};
|
|
2915
3199
|
}
|
|
2916
3200
|
|
|
2917
|
-
export { type
|
|
3201
|
+
export { type BidiEmbeddingLevels as $, type AnchoredDrawingRecord as A, type BlockFragmentRecord as B, type ContentControlBoundaryRecord as C, type DrawingPoint as D, type HyperlinkProjector as E, type FontResourceSnapshot as F, type InlineDrawingLayoutContext as G, type HeaderFooterStoryRecord as H, type InlineDrawingRecord as I, type FieldLinkProjector as J, type StoryPageFieldNeeds as K, type LineRecord as L, type ModelRange as M, type NormalizationPolicy as N, type RefFieldContext as O, type PageGeometry as P, type HyperlinkFieldSpec as Q, type ResolvedRunStyle as R, type SemanticLayout as S, type TextMeasurer as T, type SpanLinkRecord as U, type VersionedShapingLibrary as V, type ResolvedListItem as W, AUTO_PARAGRAPH_SPACING_PT as X, AUTO_PREFERRED_WIDTH as Y, type AbstractNumDefinition as Z, type AnchoredDrawingLayoutFallback as _, type StyleSpanRecord as a, type ParagraphAutoSpacingContext as a$, type BorderGridGeometry as a0, CELL_PAD as a1, type CascadedParagraphFormatting as a2, type CellBorderBox as a3, type CellMarginsPt as a4, type CellVerticalAlign as a5, type CjkTypographySettings as a6, type ContentControlGeometryFragment as a7, type ContentControlLevel as a8, type ContentControlMappedType as a9, type FontValidationResult as aA, type GlyphOutline as aB, HARD_MAX_AGGREGATE_FONT_BYTES as aC, HARD_MAX_FONT_BYTES as aD, HARD_MAX_FONT_SOURCES as aE, type LevelOverride as aF, type LineSpacingRule as aG, type ListMarkerAlign as aH, type ListMarkerRecord as aI, type ListSuffix as aJ, MAX_BORDER_SPACE_PT as aK, MAX_BORDER_WIDTH_PT as aL, MAX_LVL_OVERRIDES as aM, MAX_NUMBERING_DEFINITIONS as aN, MAX_PARAGRAPH_SPACING_PT as aO, MAX_STYLE_BASED_ON_DEPTH as aP, MAX_STYLE_DEFINITIONS as aQ, MAX_TABLE_BORDER_STROKES as aR, MAX_TABLE_NESTING as aS, MAX_TABLE_ROW_HEIGHT_PT as aT, MAX_TAB_POSITION_TWIPS as aU, MAX_TAB_STOPS as aV, type NumDefinition as aW, type NumberingLevelIndent as aX, PARAGRAPH_BORDER_SIDES as aY, type PageRefCalibrationCell as aZ, type PageRefFieldProjection as a_, DEFAULT_CELL_MARGINS as aa, DEFAULT_PAGE_GEOMETRY as ab, DEFAULT_RUN_STYLE as ac, DEFAULT_TAB_INTERVAL_PT as ad, DEFAULT_TAB_INTERVAL_TWIPS as ae, type DeclaredFontSubstitution as af, type DrawingClipFallback as ag, type DrawingGeometry as ah, EMPTY_NUMBERING_INDEX as ai, EMPTY_TAB_STOPS as aj, type EquationFractionGeometry as ak, type EquationGeometry as al, type EquationNaryGeometry as am, type EquationRadicalGeometry as an, type EquationRowGeometry as ao, type EquationScriptGeometry as ap, type EquationSpanRecord as aq, type EquationTextGeometry as ar, type FieldAtomMarker as as, type FontFingerprintInputs as at, FontResolutionError as au, type FontResolutionErrorCode as av, type FontResourceDefinition as aw, type FontResourceInstrumentation as ax, type FontResourceSnapshotOptions as ay, type FontSlot as az, type TableRowFragmentRecord as b, boundedStructuralFontValidator as b$, type ParagraphBorderEdge as b0, type ParagraphBorderSide as b1, type ParagraphBorderStrokeRecord as b2, type ParagraphBorders as b3, type ParagraphBottomBorderRecord as b4, type ParagraphIndent as b5, type ParagraphLayoutInputs as b6, type ParagraphLineSpacing as b7, type ParagraphSpacing as b8, type PreferredWidth as b9, type ShapingEnvironment as bA, type ShapingEnvironmentFingerprintInputs as bB, type StyleDefinition as bC, TAB_LEADER_GLYPH as bD, type TabAlignment as bE, type TabDestination as bF, type TabLeader as bG, type TabStop as bH, type TableAlignment as bI, type TableBorderBox as bJ, type TableBorderSideName as bK, type TableBorderStrokeRecord as bL, type TableCellStyleFormatting as bM, type TableFragmentRecord as bN, type TableRowHeight as bO, type TableRowHeightRule as bP, type TextDirection as bQ, type TextboxStoryFallbackReason as bR, type TextboxStoryLayout as bS, UnsupportedScriptError as bT, type VerticalAlign as bU, appliedSpaceBefore as bV, applyLineSpacing as bW, baselineShiftPtOf as bX, borderExtentPt as bY, borderWeight as bZ, bottomBorderExtentPt as b_, type PreferredWidthType as ba, type RefFieldSpec as bb, type RefNoteParts as bc, type ResolvedCellBorders as bd, type ResolvedTabStops as be, type ResolvedTableBorderEdge as bf, type ResolvedTableBorderEdgeSegment as bg, type ResolvedUnderline as bh, SINGLE_LINE_SPACING as bi, type ScriptItem as bj, type SemanticArtifactRootStoryKind as bk, type SemanticArtifactStoryKind as bl, type SemanticCommentArtifactRecord as bm, type SemanticReviewArtifactOccurrence as bn, type SemanticReviewArtifactOccurrenceGeometry as bo, type SemanticReviewArtifactPosition as bp, type SemanticReviewArtifactSource as bq, type SemanticTableCell as br, type SemanticTableRow as bs, type SemanticTrackedChangeArtifactRecord as bt, type ShapeInput as bu, type ShapedCluster as bv, type ShapedFontSpan as bw, type ShapedGlyph as bx, type ShapedRunComparatorInputs as by, type ShapedVerticalMetrics as bz, type TableCellFragmentRecord as c, buildNumberingIndex as c0, buildStyleCascadeTable as c1, cascadeParagraphFormatting as c2, cascadeRunProperties as c3, cascadedBottomBorder as c4, cascadedParagraphBorders as c5, cascadedTabStops as c6, collapsedSpaceBefore as c7, createFontResourceSnapshot as c8, createShapedRun as c9, readTableStructure as cA, resolveBorderConflict as cB, resolveNumberingLevel as cC, resolveParagraphLayoutInputs as cD, resolveRunStyle as cE, resolveStoryListItems as cF, resolveStoryRefFields as cG, resolveTableCellBorderGrid as cH, runStylesEqual as cI, shapedRunComparatorInputs as cJ, shapingEnvironmentFingerprint as cK, shapingEnvironmentFingerprintInputs as cL, styleForFontSlot as cM, tabAdvanceWidth as cN, tabStopsFingerprint as cO, walkStoryParagraphs as cP, withDefaultTabInterval as cQ, withNumberingStyleLinks as cR, withResolvedListItems as cS, createShapingEnvironment as ca, defaultTabIntervalFromSettings as cb, displayText as cc, fixedPoint as cd, fontRequestKey as ce, isValidStyleId as cf, itemizeScriptFontSlots as cg, layoutEquation as ch, listMarkerBox as ci, measureDisplayText as cj, mergeListIndent as ck, nextTabDestination as cl, paragraphBorderExtentPt as cm, paragraphBorderStrokeWidthPt as cn, paragraphBorders as co, paragraphBordersFingerprint as cp, paragraphBreaksBefore as cq, paragraphContextualSpacing as cr, paragraphLineSpacing as cs, paragraphSpacing as ct, paragraphTabStops as cu, parseRefInstruction as cv, readBorderSide as cw, readCellBorders as cx, readNumPr as cy, readTableBorders as cz, type ShapingEnvironmentInput as d, type TextShaper as e, type ResolvedFont as f, type FixedPointRoundingMode as g, type FontRequest as h, type SemanticReviewArtifactRecord as i, type FontSubstitution as j, type ShapedRun as k, type NumberingLevel as l, type NumberingIndex as m, type ParagraphFragmentRecord as n, type LayoutBox as o, type DrawingInsets as p, type TableBorderSide as q, type PageRecord as r, type SemanticTableStructure as s, type NoteAreaRecord as t, type NoteStoryRecord as u, type ContentControlLock as v, type FontByteValidator as w, type FixedPoint as x, type SourceRange as y, type StyleCascadeTable as z };
|