@openpresentation/opf 0.11.3 → 0.12.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 +16 -0
- package/dist/audit.d.ts +156 -0
- package/dist/audit.js +7 -0
- package/dist/{catalogs-CUClB3nl.d.ts → catalogs-u6TEeMcz.d.ts} +1 -1
- package/dist/catalogs.d.ts +2 -2
- package/dist/catalogs.js +2 -1
- package/dist/{chunk-UDPSGTZI.js → chunk-32DIB5BN.js} +12 -9
- package/dist/chunk-4FWCY4ZV.js +198 -0
- package/dist/chunk-6TSDIPSH.js +3624 -0
- package/dist/chunk-FYLJVF7X.js +18448 -0
- package/dist/{chunk-HJL64ETN.js → chunk-GJKJL4YY.js} +14 -0
- package/dist/chunk-JENJZR3F.js +1690 -0
- package/dist/{chunk-57NWIYX3.js → chunk-JVTN3HPP.js} +18 -4
- package/dist/{chunk-JTXCMVVP.js → chunk-RVN5C2FX.js} +754 -39
- package/dist/chunk-S5W34SIJ.js +1 -0
- package/dist/chunk-S667QI3M.js +261 -0
- package/dist/chunk-UQKJWHSS.js +1332 -0
- package/dist/{chunk-RXNFDGPC.js → chunk-WXSPETQ6.js} +311 -40
- package/dist/composition-DWbCiMwF.d.ts +1523 -0
- package/dist/composition.d.ts +1 -1
- package/dist/composition.js +2 -1
- package/dist/convert.d.ts +261 -0
- package/dist/convert.js +1107 -0
- package/dist/diff.d.ts +145 -0
- package/dist/diff.js +604 -0
- package/dist/docs.js +69 -15
- package/dist/examples.d.ts +1 -1
- package/dist/font-policy.d.ts +15 -0
- package/dist/font-policy.js +1 -1
- package/dist/format.d.ts +20 -0
- package/dist/format.js +83 -0
- package/dist/index.d.ts +173 -24
- package/dist/index.js +926 -262
- package/dist/lint.d.ts +4 -4
- package/dist/lint.js +6 -5
- package/dist/markdown.d.ts +74 -0
- package/dist/markdown.js +1941 -0
- package/dist/pagination.d.ts +1 -1
- package/dist/pagination.js +6 -5
- package/dist/patch.d.ts +99 -0
- package/dist/patch.js +6 -0
- package/dist/{presentation-Cn6vTOCP.d.ts → presentation-DRx4hpNZ.d.ts} +479 -32
- package/dist/repo-readme.js +1 -1
- package/dist/{schemas-X_NniU4A.d.ts → schemas-BSjlG8-R.d.ts} +28 -0
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/dist/spec/reference/font-policy.json +311 -40
- package/dist/spec/reference/font-policy.schema.json +40 -0
- package/dist/spec/reference/symbol-font-encodings.json +18354 -0
- package/dist/spec/reference/symbol-font-encodings.schema.json +156 -0
- package/dist/spec/schemas/opf.schema.json +608 -35
- package/dist/spec-files.d.ts +1 -1
- package/dist/spec-files.js +1 -1
- package/dist/symbol-font-encodings.d.ts +128 -0
- package/dist/symbol-font-encodings.js +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/validator-bu396ffT.d.ts +172 -0
- package/dist/validator.d.ts +4 -36
- package/dist/validator.js +5 -4
- package/package.json +31 -2
- package/dist/chunk-BVLWFMDX.js +0 -1812
- package/dist/chunk-JCXHSTSM.js +0 -1366
- package/dist/composition-DzLwY-Mi.d.ts +0 -887
- /package/dist/{chunk-AEUSVEUY.js → chunk-3ZGSWEHK.js} +0 -0
|
@@ -0,0 +1,1523 @@
|
|
|
1
|
+
/** Canonical table grid. No renderer, fonts, DOM or network dependencies. */
|
|
2
|
+
interface TableBorder {
|
|
3
|
+
color: string;
|
|
4
|
+
width: number;
|
|
5
|
+
dash?: 'solid' | 'dash' | 'dot';
|
|
6
|
+
}
|
|
7
|
+
interface TableCellStyle {
|
|
8
|
+
fill?: string;
|
|
9
|
+
color?: string;
|
|
10
|
+
align?: 'left' | 'center' | 'right';
|
|
11
|
+
verticalAlign?: 'top' | 'middle' | 'bottom';
|
|
12
|
+
padding?: Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
|
|
13
|
+
borders?: Partial<Record<'top' | 'right' | 'bottom' | 'left', TableBorder>>;
|
|
14
|
+
}
|
|
15
|
+
interface TableGridCell {
|
|
16
|
+
input: unknown;
|
|
17
|
+
value: unknown;
|
|
18
|
+
style: TableCellStyle;
|
|
19
|
+
row: number;
|
|
20
|
+
column: number;
|
|
21
|
+
rowSpan: number;
|
|
22
|
+
colSpan: number;
|
|
23
|
+
header: boolean;
|
|
24
|
+
path: string;
|
|
25
|
+
valuePath: string;
|
|
26
|
+
}
|
|
27
|
+
interface TableGridIssue {
|
|
28
|
+
path: string;
|
|
29
|
+
message: string;
|
|
30
|
+
}
|
|
31
|
+
interface TableGrid {
|
|
32
|
+
rows: TableGridCell[][];
|
|
33
|
+
columnCount: number;
|
|
34
|
+
rowCount: number;
|
|
35
|
+
hasHeaders: boolean;
|
|
36
|
+
/** Anchor at each covered position; covered positions are not additional cells. */
|
|
37
|
+
owners: (TableGridCell | undefined)[][];
|
|
38
|
+
issues: TableGridIssue[];
|
|
39
|
+
}
|
|
40
|
+
declare function tableGrid(value: unknown, path?: string): TableGrid;
|
|
41
|
+
/** Row boundaries that preserve every vertical merge, used by pagination. */
|
|
42
|
+
declare function tableRowBoundaries(value: unknown): number[];
|
|
43
|
+
|
|
44
|
+
/** A positioned thing whose reading position is wanted. */
|
|
45
|
+
interface ReadingBox {
|
|
46
|
+
box: {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Visual reading order: rows from top to bottom, and within a row from the start to the end of the line.
|
|
55
|
+
*
|
|
56
|
+
* Items whose vertical centre falls inside an existing row's vertical extent join that row (so a full-height
|
|
57
|
+
* item shares one row with everything beside it and the row reads left to right). Rows are ordered by their
|
|
58
|
+
* top edge. Ties keep the input order, so the result is deterministic.
|
|
59
|
+
*
|
|
60
|
+
* The boxes are read as given: pass them in logical (unmirrored) coordinates and the order is the reading
|
|
61
|
+
* order of both a left-to-right and a right-to-left deck, because mirroring a deck moves where an item is
|
|
62
|
+
* drawn and where a line starts together. For boxes that are already mirrored, pass `direction: 'rtl'` to
|
|
63
|
+
* order each row from right to left. composeSlide uses this for promoted regions and `opf audit` uses it to
|
|
64
|
+
* check the composed order, so the two cannot drift apart.
|
|
65
|
+
*/
|
|
66
|
+
declare function visualReadingOrder<T extends ReadingBox>(items: readonly T[], direction?: 'ltr' | 'rtl'): T[];
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Text direction primitives shared by composition, the renderer and the PPTX exporter (RR-05).
|
|
70
|
+
* Pure: no fonts, DOM or catalogs. Deck direction comes from the presentation language's script
|
|
71
|
+
* (script-fonts.ts); a paragraph's own direction comes from its first strong character.
|
|
72
|
+
*/
|
|
73
|
+
/** Paragraph base direction. */
|
|
74
|
+
type TextDirection = "ltr" | "rtl";
|
|
75
|
+
/**
|
|
76
|
+
* The base direction of one paragraph in a deck, shared by the renderer and
|
|
77
|
+
* the PPTX exporter so preview and export agree. In a right-to-left deck a
|
|
78
|
+
* paragraph is right-to-left when its first strong character is
|
|
79
|
+
* right-to-left, or when it has no strong character (digits, punctuation or
|
|
80
|
+
* empty text); a paragraph whose first strong character is left-to-right
|
|
81
|
+
* (for example an English quote or code) stays left-to-right. In a
|
|
82
|
+
* left-to-right deck every paragraph is left-to-right.
|
|
83
|
+
*
|
|
84
|
+
* Strong characters follow UAX #9 rule P2: text inside directional isolates
|
|
85
|
+
* (LRI, RLI or FSI up to the matching PDI) is skipped. Letters count as
|
|
86
|
+
* strong; RTL letters are those of right-to-left scripts. The result does not
|
|
87
|
+
* depend on locale data, only on the JavaScript engine's Unicode tables.
|
|
88
|
+
*/
|
|
89
|
+
declare function paragraphDirection(text: string, deckDirection: TextDirection | string | undefined): TextDirection;
|
|
90
|
+
/** Horizontal alignment as drawn: the physical left, centre or right of the text box. */
|
|
91
|
+
type PhysicalAlignment = "left" | "center" | "right";
|
|
92
|
+
/**
|
|
93
|
+
* Authored alignment is logical for right-to-left text (RR-05): `left` means the start edge and
|
|
94
|
+
* `right` the end edge, so in a right-to-left paragraph `left` is drawn at the right edge and
|
|
95
|
+
* `right` at the left edge. `center` is unchanged, and so is every left-to-right paragraph.
|
|
96
|
+
*/
|
|
97
|
+
declare function physicalAlignment(alignment: PhysicalAlignment | undefined, direction: TextDirection | undefined): PhysicalAlignment;
|
|
98
|
+
/**
|
|
99
|
+
* The base direction at a UTF-16 offset of `text`, where paragraphs are the segments between hard
|
|
100
|
+
* line breaks (CR, LF or CRLF). Every wrapped line of a paragraph shares its direction, so a
|
|
101
|
+
* line made only of Latin words or digits never changes the paragraph it belongs to.
|
|
102
|
+
*/
|
|
103
|
+
declare function paragraphDirectionAt(text: string, deckDirection: TextDirection | string | undefined): (offset: number) => TextDirection;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Numbered lists: the `numbering` field of `items` and `bullets` payloads.
|
|
107
|
+
*
|
|
108
|
+
* Pure helpers shared by composition (marker text and hanging indent), the validator, pagination and the
|
|
109
|
+
* exporters, so the preview and the native PowerPoint export number every entry identically. Nothing here
|
|
110
|
+
* measures text or reads a document beyond the items it is given.
|
|
111
|
+
*/
|
|
112
|
+
/** The five number styles OPF supports; each maps to a native PowerPoint auto-number scheme. */
|
|
113
|
+
declare const NUMBERING_STYLES: readonly ["arabic", "roman-upper", "roman-lower", "alpha-upper", "alpha-lower"];
|
|
114
|
+
type NumberingStyleName = typeof NUMBERING_STYLES[number];
|
|
115
|
+
/** `period` draws `1.`, `paren` draws `1)` and `paren-both` draws `(1)`. */
|
|
116
|
+
declare const NUMBERING_SUFFIXES: readonly ["period", "paren", "paren-both"];
|
|
117
|
+
type NumberingSuffix = typeof NUMBERING_SUFFIXES[number];
|
|
118
|
+
/** Object form of one level's numbering. Every field is optional. */
|
|
119
|
+
interface Numbering {
|
|
120
|
+
/** Default `arabic`. */
|
|
121
|
+
style?: NumberingStyleName;
|
|
122
|
+
/** First number of the level, an integer from 1 to 32767 (the native `startAt` range). Default 1. */
|
|
123
|
+
start?: number;
|
|
124
|
+
/** Default `period`. */
|
|
125
|
+
suffix?: NumberingSuffix;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The `numbering` field: one style name, one {@link Numbering} object (both apply to every level) or an array with
|
|
129
|
+
* one entry per list level (index = level; the last entry repeats for deeper levels).
|
|
130
|
+
*/
|
|
131
|
+
type NumberingInput = NumberingStyleName | Numbering | readonly (NumberingStyleName | Numbering)[];
|
|
132
|
+
/** One level's numbering with every default applied. */
|
|
133
|
+
interface ResolvedNumbering {
|
|
134
|
+
style: NumberingStyleName;
|
|
135
|
+
start: number;
|
|
136
|
+
suffix: NumberingSuffix;
|
|
137
|
+
}
|
|
138
|
+
/** Largest value a native auto-number can start at (`a:buAutoNum@startAt`, ST_TextStartAt). */
|
|
139
|
+
declare const MAX_NUMBERING_VALUE = 32767;
|
|
140
|
+
/** Largest value drawn as a Roman numeral; larger values are drawn in arabic. */
|
|
141
|
+
declare const MAX_ROMAN_VALUE = 3999;
|
|
142
|
+
/** Deepest list level a native paragraph can carry (`a:pPr@lvl` is 0 to 8). */
|
|
143
|
+
declare const MAX_NUMBERING_LEVELS = 9;
|
|
144
|
+
/**
|
|
145
|
+
* Resolve a `numbering` value to one entry per authored level (a single entry when it applies to every level).
|
|
146
|
+
* Use {@link numberingAtLevel} to read the entry for a level. Throws on a value the schema rejects.
|
|
147
|
+
*/
|
|
148
|
+
declare function resolveNumbering(input: NumberingInput): ResolvedNumbering[];
|
|
149
|
+
/** The numbering of one list level: the entry at that index, else the last entry. */
|
|
150
|
+
declare function numberingAtLevel(levels: readonly ResolvedNumbering[], level: number): ResolvedNumbering;
|
|
151
|
+
/** Whether `style` can draw `value` as that style (Roman numerals stop at 3999). */
|
|
152
|
+
declare function numberingStyleDraws(style: NumberingStyleName, value: number): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Format a list number as the preview draws it and PowerPoint's matching `a:buAutoNum` scheme draws it:
|
|
155
|
+
* `formatListNumber(4, 'roman-lower')` is `iv.`, `(3, 'alpha-upper', 'paren')` is `C)` and `(27, 'alpha-lower')` is `aa.`.
|
|
156
|
+
* Roman values above 3999 fall back to arabic (see {@link listNumbers} for the reported adaptation).
|
|
157
|
+
*/
|
|
158
|
+
declare function formatListNumber(value: number, style?: NumberingStyleName, suffix?: NumberingSuffix): string;
|
|
159
|
+
/** The number of one list entry. */
|
|
160
|
+
interface ListNumber {
|
|
161
|
+
/** Position of the entry in the list. */
|
|
162
|
+
index: number;
|
|
163
|
+
level: number;
|
|
164
|
+
/** The counted number (1 or more). */
|
|
165
|
+
value: number;
|
|
166
|
+
/** The style actually drawn: `arabic` when the authored style cannot draw `value`. */
|
|
167
|
+
style: NumberingStyleName;
|
|
168
|
+
suffix: NumberingSuffix;
|
|
169
|
+
/** The drawn marker, for example `iv.`. */
|
|
170
|
+
text: string;
|
|
171
|
+
/** Why the drawn style differs from the authored one: Roman numerals stop at 3999. */
|
|
172
|
+
adapted?: 'roman-range';
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* The numbers of a list, counted as PowerPoint counts them: consecutive entries of one level count up from that
|
|
176
|
+
* level's `start`; an entry of a shallower level restarts every deeper level; deeper entries between two entries of
|
|
177
|
+
* one level do not interrupt it. An object item's own `start` (an integer from 1 to 32767) restarts the count at that
|
|
178
|
+
* entry. Items are read for their `level` and `start` only.
|
|
179
|
+
*/
|
|
180
|
+
declare function listNumbers(items: readonly unknown[], numbering: NumberingInput): ListNumber[];
|
|
181
|
+
/**
|
|
182
|
+
* The slice `items[from, to)` of a numbered list as the items of a continuation, with `start` set on every entry whose
|
|
183
|
+
* number would otherwise change, so a paginated list keeps the numbers of the whole list.
|
|
184
|
+
*/
|
|
185
|
+
declare function sliceNumberedItems<T>(items: readonly T[], numbering: NumberingInput, from: number, to?: number): T[];
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Deterministic header/footer field formatting. Nothing here consults a clock,
|
|
189
|
+
* the host locale or the host time zone: dates are calendar dates supplied by the
|
|
190
|
+
* document or the host, and month/weekday names are fixed English names.
|
|
191
|
+
*/
|
|
192
|
+
/** A live field inside displayed furniture text, as half-open UTF-16 offsets into the part's `text`. */
|
|
193
|
+
interface FurnitureField {
|
|
194
|
+
type: 'slideNumber' | 'date';
|
|
195
|
+
start: number;
|
|
196
|
+
end: number;
|
|
197
|
+
/** Resolved date pattern for a current (`date: true`) date. */
|
|
198
|
+
format?: string;
|
|
199
|
+
}
|
|
200
|
+
/** PowerPoint's first Insert > Date and Time choice for en-US (`datetime1`). */
|
|
201
|
+
declare const DEFAULT_FURNITURE_DATE_FORMAT = "M/d/yyyy";
|
|
202
|
+
declare const DEFAULT_SLIDE_NUMBER_FORMAT = "{current}";
|
|
203
|
+
/** Format an ISO calendar date with an LDML-style pattern. Returns an error message when either input is unsupported. */
|
|
204
|
+
declare function formatFurnitureDate(iso: string, pattern: string): {
|
|
205
|
+
text: string;
|
|
206
|
+
} | {
|
|
207
|
+
error: string;
|
|
208
|
+
};
|
|
209
|
+
/** Resolve a slide-number template. `{current}` becomes a live field; `{total}` is fixed text. */
|
|
210
|
+
declare function formatSlideNumber(format: string, current: number, total: number | undefined): {
|
|
211
|
+
text: string;
|
|
212
|
+
fields: FurnitureField[];
|
|
213
|
+
} | {
|
|
214
|
+
error: string;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/** Normalize a literal hex color to uppercase #RRGGBB. */
|
|
218
|
+
declare function normalizeHexColor(value: unknown): string | undefined;
|
|
219
|
+
type ResolveColorRefRoles = Partial<Record<'primary' | 'secondary' | 'accent' | 'background' | 'surface' | 'text' | 'textSecondary', string>>;
|
|
220
|
+
interface ResolveColorRefOptions {
|
|
221
|
+
/** Effective color scheme after design resolution (OOXML slots plus optional role hex overrides). */
|
|
222
|
+
colorScheme: Record<string, unknown>;
|
|
223
|
+
/** Optional resolved chrome colors (e.g. renderer `design.colors` with `textSecondary` mapped to `mutedText`). */
|
|
224
|
+
roles?: ResolveColorRefRoles;
|
|
225
|
+
/** Top-level presentation `variables` map. */
|
|
226
|
+
variables?: Record<string, unknown>;
|
|
227
|
+
/** Theme text color returned when a reference cannot be resolved. */
|
|
228
|
+
fallback: string;
|
|
229
|
+
}
|
|
230
|
+
/** Resolve a ColorRef or TextRun.color string to a literal hex color. */
|
|
231
|
+
declare function resolveColorRef(reference: string, options: ResolveColorRefOptions): string;
|
|
232
|
+
declare function colorContrast(foreground: string, background: string): number | undefined;
|
|
233
|
+
/** Keep an inherited text color at >=4.5:1; otherwise select black or white.
|
|
234
|
+
* Callers must preserve explicit text-color overrides before using this fallback.
|
|
235
|
+
* An unresolved/translucent fill preserves the preferred color, without a contrast claim.
|
|
236
|
+
*/
|
|
237
|
+
declare function textColorForFill(fill: string, preferred: string): string;
|
|
238
|
+
/** Keep an inherited chart mark at >=3:1 against its opaque panel. Otherwise
|
|
239
|
+
* mix toward black or white in bounded 1/255 steps, choosing the first passing
|
|
240
|
+
* step (higher contrast breaks a tie). This retains a recognizable palette;
|
|
241
|
+
* it does not establish distinction between adjacent series or colorblind safety.
|
|
242
|
+
* Explicit mark overrides belong to the caller; unresolved alpha is preserved.
|
|
243
|
+
*/
|
|
244
|
+
declare function chartColorForFill(fill: string, preferred: string): string;
|
|
245
|
+
/** Smallest CIE L* step kept between neighbouring series (a printed or greyscale chart tells them apart by lightness alone). */
|
|
246
|
+
declare const CHART_SERIES_MIN_LIGHTNESS_STEP = 11;
|
|
247
|
+
/** Smallest CIE76 colour difference kept between any two series that were at least that far apart before the surface adjustment. */
|
|
248
|
+
declare const CHART_SERIES_MIN_DIFFERENCE = 12;
|
|
249
|
+
/** Series colours for a chart drawn on `fill`: the palette in order, each colour adjusted for contrast
|
|
250
|
+
* (`chartColorForFill`) without letting the adjustment merge series.
|
|
251
|
+
*
|
|
252
|
+
* Lifting or darkening a colour for a dark or mid-tone surface moves every failing colour towards the same
|
|
253
|
+
* few lightness values, so two blues that differ on white can end up identical on a dark card. Colours that
|
|
254
|
+
* already have >= 3:1 contrast against `fill` are kept exactly. A colour the contrast adjustment would move is
|
|
255
|
+
* placed again on the lightness axis, keeping its hue and as much of its chroma as sRGB allows, subject to
|
|
256
|
+
* >= 3:1 contrast against `fill` and these separations from the other series (each capped at the separation
|
|
257
|
+
* that pair had in `palette`, so a pair the palette itself made close is not asked to be far apart):
|
|
258
|
+
*
|
|
259
|
+
* - a colour difference (CIE76) of at least {@link CHART_SERIES_MIN_DIFFERENCE} from every other series;
|
|
260
|
+
* - a lightness step of at least {@link CHART_SERIES_MIN_LIGHTNESS_STEP} (CIE L*) from the neighbouring
|
|
261
|
+
* series, which is what keeps neighbours apart on a greyscale print;
|
|
262
|
+
* - the same lightness step from the remaining series, as a weaker aim.
|
|
263
|
+
*
|
|
264
|
+
* Series are placed in order against the kept colours and the colours placed before them. The placement
|
|
265
|
+
* with the lowest cost wins: its distance (in L*) from the contrast-adjusted colour plus a penalty for
|
|
266
|
+
* every point it falls short of those separations, so a colour that is already clear of the others is
|
|
267
|
+
* simply the adjusted colour, a near miss is not worth a large change, and a collision is resolved at the
|
|
268
|
+
* nearest lightness that clears it. The result is deterministic and in series order. An unresolved or
|
|
269
|
+
* translucent fill or colour is passed through, like `chartColorForFill`.
|
|
270
|
+
*
|
|
271
|
+
* It depends only on the surface and the palette, so every chart on a surface gets the same series colours,
|
|
272
|
+
* and preview and export (which both call this function) draw the same ones.
|
|
273
|
+
*/
|
|
274
|
+
declare function chartPaletteForFill(fill: string, palette: readonly string[]): string[];
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Footnotes, citations and captions (RR-34).
|
|
278
|
+
*
|
|
279
|
+
* - A TextRun may `cite` one or more ids of the deck's top-level `references`, or carry an inline
|
|
280
|
+
* `footnote`. Markers are numbered per deck in reading order of first use (slides, then regions,
|
|
281
|
+
* blocks and runs); the same reference id keeps its number, every footnote takes a new one. A run's
|
|
282
|
+
* marker is a superscript fragment drawn directly after the run (`1`, or `1,2` for several ids);
|
|
283
|
+
* `richTextLayouter` emits it from `RichTextOptions.citationMarker`, so it wraps with its word and
|
|
284
|
+
* never shifts run indexes or source offsets.
|
|
285
|
+
* - A slide that carries markers gets a footnote area directly above the footer band: `layoutFootnotes`
|
|
286
|
+
* lists `<n> <text>` for the slide's markers in number order, and `composeSlide` shrinks the content
|
|
287
|
+
* area by exactly its height. Slides without markers are unchanged.
|
|
288
|
+
* - `caption` on an image, chart, table or video payload reserves a caption band inside the block's
|
|
289
|
+
* region (`layoutCaption`): the media keeps the rest. Captions use the body family at the caption size
|
|
290
|
+
* (0.6 of the body size, clamped to the readable floor) in the muted text colour.
|
|
291
|
+
*
|
|
292
|
+
* Geometry is shared: renderers and exporters only draw what these functions return.
|
|
293
|
+
*/
|
|
294
|
+
type CaptionPosition = 'below' | 'above';
|
|
295
|
+
type CaptionAlignment = 'left' | 'center' | 'right';
|
|
296
|
+
type RichText = string | readonly (string | RichTextRun)[];
|
|
297
|
+
interface CaptionObject {
|
|
298
|
+
text: RichText;
|
|
299
|
+
position?: CaptionPosition;
|
|
300
|
+
align?: CaptionAlignment;
|
|
301
|
+
}
|
|
302
|
+
type Caption = RichText | CaptionObject;
|
|
303
|
+
interface Reference {
|
|
304
|
+
id: string;
|
|
305
|
+
text: RichText;
|
|
306
|
+
url?: string;
|
|
307
|
+
}
|
|
308
|
+
interface CaptionSettings {
|
|
309
|
+
text: RichText;
|
|
310
|
+
position: CaptionPosition;
|
|
311
|
+
align: CaptionAlignment;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* A marker is exported as a superscript run at the marked run's own size with DrawingML `baseline="30000"`, the way a user ticks
|
|
315
|
+
* Superscript. PowerPoint then draws the glyph at 2/3 of that nominal size and raises it by baseline x nominal size. Measured in
|
|
316
|
+
* PowerPoint 365 on Windows on 2026-10-01 with probe-superscript.pptx (Roboto and Aptos, 10 to 44 pt, digit ink height of a
|
|
317
|
+
* superscript run against a plain run of the same size): ratio 0.655 to 0.69, mean 0.667, independent of face and size; raise
|
|
318
|
+
* 0.30 of the nominal size at every size (baseline 30000). An explicit smaller sz on top is reduced again (0.7 x sz drew at about
|
|
319
|
+
* 0.47 of the run), which is why the exporter does not write one. The preview composes the same glyph size and raise.
|
|
320
|
+
*
|
|
321
|
+
* The drawn marker glyph is this fraction of the nominal size (the marked run's size), snapped to the 0.01 pt grid.
|
|
322
|
+
*/
|
|
323
|
+
declare const CITATION_MARKER_SCALE: number;
|
|
324
|
+
/** The raise as a fraction of the NOMINAL size (the marked run's size): DrawingML `baseline="30000"`. */
|
|
325
|
+
declare const CITATION_MARKER_RAISE = 0.3;
|
|
326
|
+
/** Caption text size as a fraction of the body size, before the readable floor. */
|
|
327
|
+
declare const CAPTION_FONT_RATIO = 0.6;
|
|
328
|
+
/** A caption band takes at most this fraction of its block region. */
|
|
329
|
+
declare const CAPTION_MAX_RATIO = 0.35;
|
|
330
|
+
/** A footnote area takes at most this fraction of the span between heading top and footer band. */
|
|
331
|
+
declare const FOOTNOTE_MAX_RATIO = 0.35;
|
|
332
|
+
/** Payload fields whose blocks may carry a caption. */
|
|
333
|
+
declare const CAPTIONABLE_FIELDS: readonly string[];
|
|
334
|
+
/** Flatten a string or TextRun[] to its plain text. */
|
|
335
|
+
declare function annotationText(value: unknown): string;
|
|
336
|
+
/** Normalize a Caption value to its text, position and alignment. */
|
|
337
|
+
declare function captionSettings(value: unknown): CaptionSettings | undefined;
|
|
338
|
+
/** A run that cites or carries a footnote, with its dotted OPF path (`slides.0.blocks.1.text.2`). */
|
|
339
|
+
interface AnnotatedRun {
|
|
340
|
+
path: string;
|
|
341
|
+
run: RichTextRun;
|
|
342
|
+
cite: string[];
|
|
343
|
+
footnote?: RichText;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Visit every rich-text run of a slide that can carry a citation (text, bullets and list item runs),
|
|
347
|
+
* in reading order: promoted regions (sorted keys), then blocks (recursively), then the root payload.
|
|
348
|
+
* `basePath` is the slide's dotted path (`slides.3`).
|
|
349
|
+
*/
|
|
350
|
+
declare function walkCitationRuns(slide: unknown, basePath: string, visit: (entry: AnnotatedRun) => void): void;
|
|
351
|
+
/** One numbered note: a cited reference (by id) or an inline footnote. */
|
|
352
|
+
interface CitationNote {
|
|
353
|
+
number: number;
|
|
354
|
+
kind: 'reference' | 'footnote';
|
|
355
|
+
/** Reference id for `kind: 'reference'`. */
|
|
356
|
+
id?: string;
|
|
357
|
+
/** Note text: the reference text (its id when the references list does not resolve it) or the footnote. */
|
|
358
|
+
text: RichText;
|
|
359
|
+
/** `references.N` for a reference, the marked run's path for a footnote. */
|
|
360
|
+
sourcePath: string;
|
|
361
|
+
url?: string;
|
|
362
|
+
/** False when a cited id has no references entry. */
|
|
363
|
+
resolved: boolean;
|
|
364
|
+
}
|
|
365
|
+
/** A marked run on a slide and the numbers its marker shows. */
|
|
366
|
+
interface CitationMarker {
|
|
367
|
+
path: string;
|
|
368
|
+
numbers: number[];
|
|
369
|
+
text: string;
|
|
370
|
+
}
|
|
371
|
+
interface SlideCitations {
|
|
372
|
+
/** Marker text by run path, in reading order. */
|
|
373
|
+
markers: Map<string, string>;
|
|
374
|
+
/** Every marked run on the slide, in reading order. */
|
|
375
|
+
marked: CitationMarker[];
|
|
376
|
+
/** The notes the slide's markers use, in number order (each number once). */
|
|
377
|
+
notes: CitationNote[];
|
|
378
|
+
}
|
|
379
|
+
interface DeckCitations {
|
|
380
|
+
/** Every note of the deck in number order. */
|
|
381
|
+
notes: CitationNote[];
|
|
382
|
+
/** Cited references in number order (inline footnotes excluded). */
|
|
383
|
+
references: CitationNote[];
|
|
384
|
+
/** Per slide index. Slides without markers are absent. */
|
|
385
|
+
slides: Map<number, SlideCitations>;
|
|
386
|
+
/** Reference ids no run cites, in references order. */
|
|
387
|
+
unused: string[];
|
|
388
|
+
}
|
|
389
|
+
/** Marker text for a set of numbers: `1`, or `1,2` for several ids. */
|
|
390
|
+
declare const citationMarkerText: (numbers: readonly number[]) => string;
|
|
391
|
+
/**
|
|
392
|
+
* Number every marker of a deck in reading order. Slides are read from `presentation.slides`; a
|
|
393
|
+
* hidden slide still takes part so numbers do not change when it is shown.
|
|
394
|
+
*/
|
|
395
|
+
declare function collectCitations(presentation: unknown): DeckCitations;
|
|
396
|
+
/**
|
|
397
|
+
* Citations of one slide with the deck's numbering: the markers of `presentation.slides[0..slideIndex-1]`
|
|
398
|
+
* are counted first, then the runs of `slide` itself (which may be a paginated page or a copy of the
|
|
399
|
+
* document's slide). Without a presentation the slide's own markers start at 1 and reference texts
|
|
400
|
+
* cannot be resolved (`resolved: false`).
|
|
401
|
+
*/
|
|
402
|
+
declare function slideCitations(slide: unknown, slideIndex: number, presentation?: unknown): SlideCitations | undefined;
|
|
403
|
+
/** Fits a string or TextRun[] into a box at a requested size (composeSlide supplies its placed fitter). */
|
|
404
|
+
type AnnotationFitter = (value: RichText, box: LayoutBox, requestedSize: number, minFontSize: number, path: string, alignment: CaptionAlignment) => TextFit | RichTextFit;
|
|
405
|
+
interface AnnotationLayoutOptions {
|
|
406
|
+
scale: number;
|
|
407
|
+
minFontSize: number;
|
|
408
|
+
fit: AnnotationFitter;
|
|
409
|
+
textStyle: (path: string) => TextStyle;
|
|
410
|
+
}
|
|
411
|
+
/** A composed caption band inside a block region. */
|
|
412
|
+
interface ComposedCaption {
|
|
413
|
+
/** Dotted path of the caption field (`slides.0.blocks.1.caption`). */
|
|
414
|
+
path: string;
|
|
415
|
+
value: Caption;
|
|
416
|
+
text: RichText;
|
|
417
|
+
position: CaptionPosition;
|
|
418
|
+
alignment: CaptionAlignment;
|
|
419
|
+
/** The caption band. */
|
|
420
|
+
box: LayoutBox;
|
|
421
|
+
/** The media box after the band is reserved; `ComposedItem.box` equals it. */
|
|
422
|
+
mediaBox: LayoutBox;
|
|
423
|
+
fit: TextFit | RichTextFit;
|
|
424
|
+
textStyle: TextStyle;
|
|
425
|
+
fontSize: number;
|
|
426
|
+
overflow: boolean;
|
|
427
|
+
diagnostics: LayoutDiagnostic[];
|
|
428
|
+
}
|
|
429
|
+
/** Reserve a caption band in `box` (the payload box) and return the band and the media box. */
|
|
430
|
+
declare function layoutCaption(value: unknown, box: LayoutBox, path: string, options: AnnotationLayoutOptions): ComposedCaption | undefined;
|
|
431
|
+
/** One listed note in a slide's footnote area. */
|
|
432
|
+
interface ComposedFootnoteEntry {
|
|
433
|
+
number: number;
|
|
434
|
+
kind: 'reference' | 'footnote';
|
|
435
|
+
id?: string;
|
|
436
|
+
/** `references.N` or the marked run's path. */
|
|
437
|
+
sourcePath: string;
|
|
438
|
+
/** The listed value: `<n> <text>` as a string, or runs starting with the number. */
|
|
439
|
+
value: RichText;
|
|
440
|
+
text: RichText;
|
|
441
|
+
box: LayoutBox;
|
|
442
|
+
fit: TextFit | RichTextFit;
|
|
443
|
+
textStyle: TextStyle;
|
|
444
|
+
url?: string;
|
|
445
|
+
overflow: boolean;
|
|
446
|
+
}
|
|
447
|
+
/** The footnote area of a slide: a rule, then the slide's notes in number order. */
|
|
448
|
+
interface ComposedFootnotes {
|
|
449
|
+
algorithm: 'footnote-area-v1';
|
|
450
|
+
/** Dotted slide path (`slides.3`). */
|
|
451
|
+
path: string;
|
|
452
|
+
box: LayoutBox;
|
|
453
|
+
/** Thin rule along the top of the area. */
|
|
454
|
+
rule: {
|
|
455
|
+
x: number;
|
|
456
|
+
y: number;
|
|
457
|
+
width: number;
|
|
458
|
+
thickness: number;
|
|
459
|
+
};
|
|
460
|
+
entries: ComposedFootnoteEntry[];
|
|
461
|
+
/** Marked runs of the slide with their marker text. */
|
|
462
|
+
markers: CitationMarker[];
|
|
463
|
+
fontSize: number;
|
|
464
|
+
overflow: boolean;
|
|
465
|
+
diagnostics: LayoutDiagnostic[];
|
|
466
|
+
}
|
|
467
|
+
interface FootnoteLayoutOptions extends AnnotationLayoutOptions {
|
|
468
|
+
/** Left edge and width of the content area. */
|
|
469
|
+
x: number;
|
|
470
|
+
width: number;
|
|
471
|
+
/** The area's bottom edge (the top of the footer band gap). */
|
|
472
|
+
bottom: number;
|
|
473
|
+
/** Largest height the area may take. */
|
|
474
|
+
maxHeight: number;
|
|
475
|
+
/** Slide path for the area (`slides.3`). */
|
|
476
|
+
path: string;
|
|
477
|
+
}
|
|
478
|
+
/** List a slide's notes in a footnote area whose bottom sits at `options.bottom`. */
|
|
479
|
+
declare function layoutFootnotes(citations: SlideCitations, options: FootnoteLayoutOptions): ComposedFootnotes;
|
|
480
|
+
interface ReferencesSlideOptions {
|
|
481
|
+
title?: string;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* An ordinary list slide of the deck's cited references in marker order (`n. text`, linked to the
|
|
485
|
+
* reference url when there is one). Inline footnotes are not listed. A deck that cites nothing gets
|
|
486
|
+
* a slide with the title only.
|
|
487
|
+
*/
|
|
488
|
+
declare function referencesSlide(presentation: unknown, options?: ReferencesSlideOptions): Record<string, unknown>;
|
|
489
|
+
|
|
490
|
+
/** The chart constructs the engines draw. Every catalog chart type id resolves to one (see `chartOptionTarget`). */
|
|
491
|
+
type ChartOptionKind = 'bar' | 'line' | 'area' | 'pie' | 'doughnut' | 'scatter' | 'radar' | 'treemap' | 'histogram' | 'pareto' | 'box' | 'waterfall' | 'funnel' | 'map';
|
|
492
|
+
interface ChartOptionTarget {
|
|
493
|
+
kind: ChartOptionKind;
|
|
494
|
+
/** Stacked and 100% stacked columns, bars, lines and areas: their data labels have no outside-end position. */
|
|
495
|
+
stacked?: boolean;
|
|
496
|
+
}
|
|
497
|
+
type ChartLegendPosition = 'none' | 'top' | 'bottom' | 'left' | 'right';
|
|
498
|
+
type ChartLabelContent = 'category' | 'value' | 'percent';
|
|
499
|
+
type ChartLabelPosition = 'center' | 'inside-end' | 'inside-base' | 'outside-end' | 'above' | 'below' | 'left' | 'right';
|
|
500
|
+
interface ChartOptionDiagnostic {
|
|
501
|
+
code: 'chart-option-adapted';
|
|
502
|
+
/** The option that was adapted: `axisTitles.category`, `axisTitles.value`, `legend`, `dataLabels`, `dataLabels.content`, `dataLabels.position` or `dataLabels.separator`. */
|
|
503
|
+
option: string;
|
|
504
|
+
reason: 'unsupported-type' | 'unsupported-content' | 'unsupported-position';
|
|
505
|
+
message: string;
|
|
506
|
+
}
|
|
507
|
+
interface ResolvedChartDataLabels {
|
|
508
|
+
/** Canonical order: category, value, percent. Never empty. */
|
|
509
|
+
content: ChartLabelContent[];
|
|
510
|
+
/** The concrete position, or null for a construct whose labels have no position choice (area, doughnut, radar, treemap). */
|
|
511
|
+
position: ChartLabelPosition | null;
|
|
512
|
+
separator: string;
|
|
513
|
+
}
|
|
514
|
+
interface ResolvedChartOptions {
|
|
515
|
+
/** True when the chart carries at least one option (after adaptation); false means every engine keeps today's output. */
|
|
516
|
+
active: boolean;
|
|
517
|
+
axisTitles: {
|
|
518
|
+
category?: string;
|
|
519
|
+
value?: string;
|
|
520
|
+
};
|
|
521
|
+
/** Undefined = no legend option: each engine keeps its default (a right legend on multi-series, pie and doughnut charts). */
|
|
522
|
+
legend?: ChartLegendPosition;
|
|
523
|
+
dataLabels?: ResolvedChartDataLabels;
|
|
524
|
+
/** True when `dataLabels: false` switches off the labels a construct draws by default (funnel values, treemap category names). */
|
|
525
|
+
dataLabelsOff?: boolean;
|
|
526
|
+
diagnostics: ChartOptionDiagnostic[];
|
|
527
|
+
}
|
|
528
|
+
interface ChartOptionSupport {
|
|
529
|
+
axisTitles: {
|
|
530
|
+
category: boolean;
|
|
531
|
+
value: boolean;
|
|
532
|
+
};
|
|
533
|
+
legend: boolean;
|
|
534
|
+
dataLabels: {
|
|
535
|
+
supported: boolean;
|
|
536
|
+
content: readonly ChartLabelContent[];
|
|
537
|
+
/** Empty when labels have no position choice. */
|
|
538
|
+
positions: readonly ChartLabelPosition[];
|
|
539
|
+
/** The position `auto` resolves to; null with no positions. */
|
|
540
|
+
defaultPosition: ChartLabelPosition | null;
|
|
541
|
+
/** True for the constructs that label their marks by default (funnel, treemap): `dataLabels: false` removes those labels. */
|
|
542
|
+
defaultOn: boolean;
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
/** What a chart construct can show. The table the docs, the validator, the preview and the exporter all follow. */
|
|
546
|
+
declare function chartOptionSupport(target: ChartOptionTarget): ChartOptionSupport;
|
|
547
|
+
/** The option target for a catalog chart type id (deprecated ids resolve to their replacement); undefined for an id outside the catalog. */
|
|
548
|
+
declare function chartOptionTarget(typeId: unknown): ChartOptionTarget | undefined;
|
|
549
|
+
declare const DEFAULT_CHART_LABEL_SEPARATOR = ", ";
|
|
550
|
+
/**
|
|
551
|
+
* Normalise a chart's `axisTitles`, `legend` and `dataLabels` against what its type can show. `target` is undefined for a chart type
|
|
552
|
+
* outside the catalog: nothing is adapted then (the engines fall back to their legacy output for such charts anyway).
|
|
553
|
+
*/
|
|
554
|
+
declare function resolveChartOptions(chart: unknown, target?: ChartOptionTarget): ResolvedChartOptions;
|
|
555
|
+
/** A General-format number as a label: at most twelve significant digits, no exponent unless the value needs one. */
|
|
556
|
+
declare function formatChartLabelNumber(value: number): string;
|
|
557
|
+
/** A share as PowerPoint's `0%` label. */
|
|
558
|
+
declare function formatChartLabelPercent(share: number): string;
|
|
559
|
+
/** The label text: the selected parts in the fixed order category, value, percent, joined by the separator. */
|
|
560
|
+
declare function chartLabelText(parts: {
|
|
561
|
+
category?: string;
|
|
562
|
+
value?: string;
|
|
563
|
+
percent?: string;
|
|
564
|
+
}, content: readonly ChartLabelContent[], separator?: string): string;
|
|
565
|
+
|
|
566
|
+
/** Portable layout geometry. No fonts, DOM, renderer, or network dependencies. */
|
|
567
|
+
interface Composition {
|
|
568
|
+
mode?: "auto" | "grid" | "row" | "column";
|
|
569
|
+
columns?: number;
|
|
570
|
+
gap?: number;
|
|
571
|
+
padding?: number;
|
|
572
|
+
weights?: number[];
|
|
573
|
+
minFontSize?: number;
|
|
574
|
+
overflow?: "warn" | "error";
|
|
575
|
+
}
|
|
576
|
+
declare const MAX_COMPOSITION_DEPTH = 32;
|
|
577
|
+
interface LayoutBox {
|
|
578
|
+
x: number;
|
|
579
|
+
y: number;
|
|
580
|
+
width: number;
|
|
581
|
+
height: number;
|
|
582
|
+
}
|
|
583
|
+
interface LayoutDiagnostic {
|
|
584
|
+
code: "text-overflow" | "small-cell" | "unresolved-content" | "unsupported-image-treatment" | "numbering-adapted";
|
|
585
|
+
path: string;
|
|
586
|
+
message: string;
|
|
587
|
+
}
|
|
588
|
+
/** Physical legacy-family selection supplied by a font provider, independently of its numeric weight. */
|
|
589
|
+
interface FontFaceSelection {
|
|
590
|
+
family: string;
|
|
591
|
+
bold: boolean;
|
|
592
|
+
italic: boolean;
|
|
593
|
+
}
|
|
594
|
+
interface TextStyle {
|
|
595
|
+
fontFamily: string;
|
|
596
|
+
fontWeight: number;
|
|
597
|
+
italic?: boolean;
|
|
598
|
+
path?: string;
|
|
599
|
+
fontFace?: FontFaceSelection;
|
|
600
|
+
}
|
|
601
|
+
/** Role families. `accent` is present only when the scheme defines an accent role; the slide tag and quote body use it. */
|
|
602
|
+
interface FontFamilies {
|
|
603
|
+
heading: string;
|
|
604
|
+
body: string;
|
|
605
|
+
code: string;
|
|
606
|
+
accent?: string;
|
|
607
|
+
}
|
|
608
|
+
/** Shared last-resort font-scheme id when neither the slide, the deck nor the resolved theme names one.
|
|
609
|
+
* One default for every engine, so preview matches export (font-fidelity-everywhere owner decision). */
|
|
610
|
+
declare const DEFAULT_FONT_SCHEME = "aptos";
|
|
611
|
+
/** Reported when a font-scheme id matches no inline or bundled record. Every engine then uses the
|
|
612
|
+
* DEFAULT_FONT_SCHEME record as the base, with any sibling overrides on top. */
|
|
613
|
+
interface FontSchemeDiagnostic {
|
|
614
|
+
code: "unresolved-font-scheme";
|
|
615
|
+
/** Where the unresolved id is written: `slides.N.design.fontScheme`, `design.fontScheme`, or the
|
|
616
|
+
* `design.theme` reference whose record names it. */
|
|
617
|
+
path: string;
|
|
618
|
+
message: string;
|
|
619
|
+
/** The unresolved font-scheme id. */
|
|
620
|
+
id: string;
|
|
621
|
+
/** The font scheme used instead (DEFAULT_FONT_SCHEME). */
|
|
622
|
+
fallback: string;
|
|
623
|
+
}
|
|
624
|
+
interface ResolvedFontScheme {
|
|
625
|
+
scheme: Record<string, unknown>;
|
|
626
|
+
diagnostic?: FontSchemeDiagnostic;
|
|
627
|
+
}
|
|
628
|
+
/** Resolve a font-scheme reference the same way in every engine. A string id, or the `id` of an object
|
|
629
|
+
* reference, resolves through `lookup` (inline records, then bundled or host catalogs). An unresolved id
|
|
630
|
+
* returns a diagnostic, and the DEFAULT_FONT_SCHEME record becomes the base, so preview and export use
|
|
631
|
+
* the same families. An object without `id` is an inline scheme on the same base. Sibling fields on an
|
|
632
|
+
* object reference override the base per key. */
|
|
633
|
+
declare function resolveFontSchemeReference(reference: unknown, lookup: (id: string) => unknown, path?: string): ResolvedFontScheme;
|
|
634
|
+
/** Resolve role families from an already-merged font scheme (catalog record plus design overrides).
|
|
635
|
+
* A scheme that names no heading or body family gets the DEFAULT_FONT_SCHEME families (Aptos Display, Aptos).
|
|
636
|
+
* `code` comes from the scheme's `code` role, which catalog records such as consolas and courier-new
|
|
637
|
+
* carry; otherwise it is Roboto Mono. Heading and body families are never reused for code.
|
|
638
|
+
* `accent` is returned only when the scheme defines an `accent` role (a family string or Font object);
|
|
639
|
+
* the slide tag and the quote body use it in place of the body and heading families. */
|
|
640
|
+
declare function resolveFontFamilies(input: unknown): FontFamilies;
|
|
641
|
+
interface TextMeasurement {
|
|
642
|
+
measure: (text: string, fontSize: number, style: TextStyle) => number;
|
|
643
|
+
resolveStyle?: (style: TextStyle) => TextStyle;
|
|
644
|
+
/** Shaped vector ink relative to the left baseline origin (positive y down).
|
|
645
|
+
* Null means no outline. These are not hinted/antialiased raster bounds. */
|
|
646
|
+
outlineBounds?: (text: string, fontSize: number, style: TextStyle) => LayoutBox | null;
|
|
647
|
+
}
|
|
648
|
+
type MeasureTextWidth = (text: string, fontSize: number) => number;
|
|
649
|
+
declare function resolveTextStyle(style: TextStyle, measurement?: TextMeasurement): TextStyle;
|
|
650
|
+
declare function textWidthMeasurer(style: TextStyle, measurement?: TextMeasurement): MeasureTextWidth;
|
|
651
|
+
/** Validate an optional host outline measurement without inventing raster coverage. */
|
|
652
|
+
declare function measureTextOutline(text: string, fontSize: number, style: TextStyle, measurement?: TextMeasurement): LayoutBox | null | undefined;
|
|
653
|
+
interface TextLineInk {
|
|
654
|
+
width: number;
|
|
655
|
+
y: number;
|
|
656
|
+
baseline: number;
|
|
657
|
+
height: number;
|
|
658
|
+
outline: LayoutBox | null;
|
|
659
|
+
}
|
|
660
|
+
interface TextPlacementLine {
|
|
661
|
+
x: number;
|
|
662
|
+
y: number;
|
|
663
|
+
baseline: number;
|
|
664
|
+
height: number;
|
|
665
|
+
width: number;
|
|
666
|
+
outline: LayoutBox | null;
|
|
667
|
+
/** Physical alignment this line was placed with. Present only in a right-to-left deck, where `left` and `right` are logical start and end. */
|
|
668
|
+
alignment?: PhysicalAlignment;
|
|
669
|
+
}
|
|
670
|
+
interface TextPlacement {
|
|
671
|
+
alignment: 'left' | 'center' | 'right';
|
|
672
|
+
/** Reference-pixel clearance around vector outlines; not a universal raster guarantee. */
|
|
673
|
+
rasterPadding: number;
|
|
674
|
+
lines: TextPlacementLine[];
|
|
675
|
+
height: number;
|
|
676
|
+
overflow: boolean;
|
|
677
|
+
}
|
|
678
|
+
interface TextFit {
|
|
679
|
+
lines: string[];
|
|
680
|
+
fontSize: number;
|
|
681
|
+
lineHeight: number;
|
|
682
|
+
overflow: boolean;
|
|
683
|
+
placement?: TextPlacement;
|
|
684
|
+
/**
|
|
685
|
+
* Base direction of the paragraph each line belongs to, in line order. Present only when the fit was
|
|
686
|
+
* made for a right-to-left deck; every wrapped line shares its paragraph's direction (RR-05).
|
|
687
|
+
*/
|
|
688
|
+
directions?: TextDirection[];
|
|
689
|
+
}
|
|
690
|
+
/** Place complete measured lines, preserving alignment where it leaves room for ink.
|
|
691
|
+
* Move following baselines together when outlines need more vertical separation. */
|
|
692
|
+
declare function placeTextLines(lines: readonly TextLineInk[], box: LayoutBox, alignment?: TextPlacement['alignment'], rasterPadding?: number, directions?: readonly TextDirection[]): TextPlacement;
|
|
693
|
+
interface ComposedItem {
|
|
694
|
+
path: string;
|
|
695
|
+
field: string;
|
|
696
|
+
type: string;
|
|
697
|
+
value: unknown;
|
|
698
|
+
payload: Record<string, unknown>;
|
|
699
|
+
box: LayoutBox;
|
|
700
|
+
/** Optional visible card allocation; box and all accepted internals occupy its padded interior. */
|
|
701
|
+
frameBox?: LayoutBox;
|
|
702
|
+
text?: TextFit | RichTextFit | ListFit | CodeTextFit;
|
|
703
|
+
textStyle?: TextStyle;
|
|
704
|
+
/** Complete accepted quote internals; consumers must reuse these fits and styles. */
|
|
705
|
+
quoteLayout?: QuoteLayout;
|
|
706
|
+
/** Complete accepted code internals, including source lines and literal tab positions. */
|
|
707
|
+
codeLayout?: CodeLayout;
|
|
708
|
+
/** Complete shared metric geometry, including its unit, label and metadata. */
|
|
709
|
+
metricLayout?: MetricLayout;
|
|
710
|
+
/** Complete timeline fields, markers and connector accepted by composition. */
|
|
711
|
+
timelineLayout?: TimelineLayout;
|
|
712
|
+
/**
|
|
713
|
+
* Picture bullet for `items`/`bullets` payloads when the effective `design.listBullet` is `image`
|
|
714
|
+
* and the deck's icon logo resolves. Every entry marker in `text.listEntries` carries the same value.
|
|
715
|
+
*/
|
|
716
|
+
bulletImage?: ListBulletImage;
|
|
717
|
+
/**
|
|
718
|
+
* Caption band of an image, chart, table or video payload that carries `caption` (RR-34). `box` is
|
|
719
|
+
* the media box after the band is reserved; `caption.box` is the band inside the same region.
|
|
720
|
+
*/
|
|
721
|
+
caption?: ComposedCaption;
|
|
722
|
+
/** Effective container settings, including inherited readability constraints. */
|
|
723
|
+
composition: Composition;
|
|
724
|
+
/**
|
|
725
|
+
* Resolved horizontal text alignment for this item: titleAlignment for the
|
|
726
|
+
* title, contentAlignment for every other item (slide design, then host
|
|
727
|
+
* option, then left). Engines anchor native and preview text to this value.
|
|
728
|
+
*/
|
|
729
|
+
alignment: 'left' | 'center' | 'right';
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Slide-level image resolved from design.slideImage. It is active when the slide sets its own
|
|
733
|
+
* design.slideImage, or when the deck sets one and either the slide's layout record declares
|
|
734
|
+
* slideImage: true or the slide's root image is the same source.
|
|
735
|
+
* Content composes in the part of the slide the image does not occupy; 'background' leaves the whole slide.
|
|
736
|
+
*/
|
|
737
|
+
interface ComposedSlideImage {
|
|
738
|
+
/** The design value that configured the image: 'design.slideImage' or 'slides.N.design.slideImage'. */
|
|
739
|
+
path: string;
|
|
740
|
+
/** Path of the drawn asset value: the design value, or the slide's root image payload it replaced. */
|
|
741
|
+
sourcePath: string;
|
|
742
|
+
/** Asset value (string or Asset object) that engines resolve like any other image. */
|
|
743
|
+
value: unknown;
|
|
744
|
+
position: 'background' | 'top' | 'bottom' | 'left' | 'right';
|
|
745
|
+
/** crop covers the frame (centered); fit shows the whole image centered inside it. */
|
|
746
|
+
fill: 'crop' | 'fit';
|
|
747
|
+
/** Band allocated to the image. */
|
|
748
|
+
region: LayoutBox;
|
|
749
|
+
/** Image frame inside the region. */
|
|
750
|
+
box: LayoutBox;
|
|
751
|
+
/** True when the slide's root image payload became this slide image instead of a content item. */
|
|
752
|
+
replacesContent: boolean;
|
|
753
|
+
/** Treatment alt text; engines fall back to the asset's own alt text. */
|
|
754
|
+
alt?: string;
|
|
755
|
+
/** Mask on the frame: a DrawingML preset with its guide values, and the same outline as an SVG path. */
|
|
756
|
+
shape: SlideImageShape;
|
|
757
|
+
/** Line centered on the shape outline; width in reference pixels (already scaled to the canvas). */
|
|
758
|
+
border?: {
|
|
759
|
+
color: unknown;
|
|
760
|
+
width: number;
|
|
761
|
+
};
|
|
762
|
+
/** Image opacity below 1; the border and overlay are not affected. */
|
|
763
|
+
opacity?: number;
|
|
764
|
+
/** Luminance-based recolor (Rec. 601 weights on sRGB values). */
|
|
765
|
+
recolor?: {
|
|
766
|
+
type: 'grayscale';
|
|
767
|
+
} | {
|
|
768
|
+
type: 'duotone';
|
|
769
|
+
dark: unknown;
|
|
770
|
+
light: unknown;
|
|
771
|
+
};
|
|
772
|
+
/** Scrim over the frame (same shape) or over an edge band of a rectangle frame. */
|
|
773
|
+
overlay?: {
|
|
774
|
+
color: unknown;
|
|
775
|
+
opacity: number;
|
|
776
|
+
box: LayoutBox;
|
|
777
|
+
shape: SlideImageShape;
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
/** A frame mask. path follows the ECMA-376 preset formula for preset/adjust exactly, in reference pixels. */
|
|
781
|
+
interface SlideImageShape {
|
|
782
|
+
kind: 'rectangle' | 'rounded' | 'circle' | 'hexagon';
|
|
783
|
+
preset: 'rect' | 'roundRect' | 'ellipse' | 'hexagon';
|
|
784
|
+
/** DrawingML avLst guide values (for example adj and vf), in 1/100000 units. */
|
|
785
|
+
adjust: Record<string, number>;
|
|
786
|
+
path: string;
|
|
787
|
+
}
|
|
788
|
+
/** Which logo variant family a consumer asks for: the full lockup, a square mark, or a stacked lockup. */
|
|
789
|
+
type LogoSlot = 'lockup' | 'icon' | 'stacked';
|
|
790
|
+
/** A logo asset chosen by resolveLogo, with its source value, OPF path, LogoSet variant key and the slot it serves. */
|
|
791
|
+
interface ResolvedLogo {
|
|
792
|
+
source: unknown;
|
|
793
|
+
path: string;
|
|
794
|
+
variant: string;
|
|
795
|
+
slot: LogoSlot;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* The deck logo drawn on a cover or section slide, at the top-left of the free area and above the
|
|
799
|
+
* centered heading group. Consumers fit the image inside `box` preserving its aspect ratio,
|
|
800
|
+
* anchored left and vertically centered; content slides never carry one.
|
|
801
|
+
*/
|
|
802
|
+
interface ComposedLogo {
|
|
803
|
+
box: LayoutBox;
|
|
804
|
+
slot: 'lockup';
|
|
805
|
+
path: string;
|
|
806
|
+
source: unknown;
|
|
807
|
+
variant: string;
|
|
808
|
+
anchor: 'left' | 'right';
|
|
809
|
+
}
|
|
810
|
+
/** Picture bullet source for list markers: the deck's icon logo and the OPF path it was read from. */
|
|
811
|
+
interface ListBulletImage {
|
|
812
|
+
source: unknown;
|
|
813
|
+
path: string;
|
|
814
|
+
}
|
|
815
|
+
interface ComposedGroup {
|
|
816
|
+
path: string;
|
|
817
|
+
box: LayoutBox;
|
|
818
|
+
contentBox: LayoutBox;
|
|
819
|
+
composition: Composition;
|
|
820
|
+
}
|
|
821
|
+
interface CompositionTrack {
|
|
822
|
+
offset: number;
|
|
823
|
+
size: number;
|
|
824
|
+
}
|
|
825
|
+
/** Resolved flow geometry, including empty reserved slots. Promoted regions are not flows. */
|
|
826
|
+
interface ComposedFlow {
|
|
827
|
+
path: string;
|
|
828
|
+
box: LayoutBox;
|
|
829
|
+
composition: Composition;
|
|
830
|
+
columns: CompositionTrack[];
|
|
831
|
+
rows: CompositionTrack[];
|
|
832
|
+
gap: number;
|
|
833
|
+
itemCount: number;
|
|
834
|
+
slotCount: number;
|
|
835
|
+
}
|
|
836
|
+
/** Additive penalties in grid-score-v9; lower is preferred. These are not quality percentages. */
|
|
837
|
+
interface CompositionPenalties {
|
|
838
|
+
cellProportions: number;
|
|
839
|
+
fontReduction: number;
|
|
840
|
+
textOverflow: number;
|
|
841
|
+
tableOverflow: number;
|
|
842
|
+
smallCells: number;
|
|
843
|
+
emptySlots: number;
|
|
844
|
+
}
|
|
845
|
+
interface CompositionCandidate {
|
|
846
|
+
columns: number;
|
|
847
|
+
rows: number;
|
|
848
|
+
score: number;
|
|
849
|
+
penalties: CompositionPenalties;
|
|
850
|
+
}
|
|
851
|
+
interface CompositionDecision {
|
|
852
|
+
path: string;
|
|
853
|
+
mode: NonNullable<Composition['mode']> | 'regions';
|
|
854
|
+
/** `chart-primary`: the root split a primary chart from a synthetic container of the other nodes (design.chartPrimary). */
|
|
855
|
+
reason: 'lowest-score' | 'configured-mode' | 'promoted-regions' | 'chart-primary';
|
|
856
|
+
selectedColumns?: number;
|
|
857
|
+
/** Only candidates actually evaluated by automatic selection, in tie-break order. */
|
|
858
|
+
candidates: CompositionCandidate[];
|
|
859
|
+
}
|
|
860
|
+
interface CompositionExplanation {
|
|
861
|
+
algorithm: 'grid-score-v9';
|
|
862
|
+
/** Provided widths do not establish shaping, glyph coverage or native fidelity. */
|
|
863
|
+
textMeasurement: 'estimated' | 'provided';
|
|
864
|
+
/** Optional vector coverage for headings and scalar/rich text, not every payload. */
|
|
865
|
+
textOutlines: 'provided' | 'unavailable';
|
|
866
|
+
/** Effective body-text reference pixels; furniture reports its own placement padding. Not a universal raster tolerance. */
|
|
867
|
+
textRasterPadding: number;
|
|
868
|
+
decisions: CompositionDecision[];
|
|
869
|
+
/** Payloads whose complete internal fit is not covered by this scoring model. */
|
|
870
|
+
unmeasuredPayloads: string[];
|
|
871
|
+
}
|
|
872
|
+
interface SlideComposition {
|
|
873
|
+
width: number;
|
|
874
|
+
height: number;
|
|
875
|
+
contentBox: LayoutBox;
|
|
876
|
+
items: ComposedItem[];
|
|
877
|
+
groups: ComposedGroup[];
|
|
878
|
+
flows: ComposedFlow[];
|
|
879
|
+
diagnostics: LayoutDiagnostic[];
|
|
880
|
+
composition: Composition;
|
|
881
|
+
/** Repeated furniture is measured separately from body pagination leaves. */
|
|
882
|
+
furniture?: FurnitureLayout;
|
|
883
|
+
/** Active slide-level image; absent when design.slideImage does not apply to this slide. */
|
|
884
|
+
slideImage?: ComposedSlideImage;
|
|
885
|
+
/** Deck logo on a cover or section slide; absent on content slides and when no logo resolves. */
|
|
886
|
+
logo?: ComposedLogo;
|
|
887
|
+
/**
|
|
888
|
+
* Footnote area of a slide whose runs cite references or carry footnotes (RR-34): directly above the
|
|
889
|
+
* footer band, the content area is shrunk by exactly its height. Absent on slides without markers.
|
|
890
|
+
*/
|
|
891
|
+
footnotes?: ComposedFootnotes;
|
|
892
|
+
/** `rtl` when the slide was composed for a right-to-left deck (mirrored arrangement); absent for left-to-right decks. */
|
|
893
|
+
direction?: 'rtl';
|
|
894
|
+
explanation?: CompositionExplanation;
|
|
895
|
+
}
|
|
896
|
+
interface ComposeSlideOptions {
|
|
897
|
+
/** Context for inherited furniture, generated organization names, social profiles, logos, layout hints, references and marker numbering. */
|
|
898
|
+
presentation?: {
|
|
899
|
+
language?: unknown;
|
|
900
|
+
design?: {
|
|
901
|
+
header?: unknown;
|
|
902
|
+
footer?: unknown;
|
|
903
|
+
slideImage?: unknown;
|
|
904
|
+
imageFill?: unknown;
|
|
905
|
+
logo?: unknown;
|
|
906
|
+
contentDirection?: unknown;
|
|
907
|
+
chartPrimary?: unknown;
|
|
908
|
+
listBullet?: unknown;
|
|
909
|
+
};
|
|
910
|
+
organization?: unknown;
|
|
911
|
+
slides?: unknown;
|
|
912
|
+
catalogs?: unknown;
|
|
913
|
+
references?: unknown;
|
|
914
|
+
};
|
|
915
|
+
/**
|
|
916
|
+
* Whether the slide background is dark, by the host's own luminance test. Selects the light logo
|
|
917
|
+
* variants (cover logo, furniture `logo: true`, picture bullets). Core never inspects colors.
|
|
918
|
+
*/
|
|
919
|
+
darkBackground?: boolean;
|
|
920
|
+
/**
|
|
921
|
+
* Host-resolved social-platform records for generated `socials` furniture.
|
|
922
|
+
* Inline `presentation.catalogs.socialPlatforms.records` take precedence. Hosts
|
|
923
|
+
* normally pass the bundled catalog; without a matching record a handle renders
|
|
924
|
+
* as its raw value, as the Socials contract specifies.
|
|
925
|
+
*/
|
|
926
|
+
socialPlatforms?: readonly SocialPlatformRecord[];
|
|
927
|
+
/** One-based displayed number; source paths still use slideIndex. */
|
|
928
|
+
slideNumber?: number;
|
|
929
|
+
/** Displayed slide count for `{total}` in slideNumberFormat. Defaults to `presentation.slides.length`. */
|
|
930
|
+
slideCount?: number;
|
|
931
|
+
/**
|
|
932
|
+
* Host-supplied current calendar date (ISO YYYY-MM-DD) for `date: true` furniture. Core never
|
|
933
|
+
* consults a clock; without this option a current date is reported as unresolved content.
|
|
934
|
+
*/
|
|
935
|
+
date?: string;
|
|
936
|
+
fonts?: Partial<FontFamilies>;
|
|
937
|
+
/**
|
|
938
|
+
* Deck base direction (RR-05). Defaults to the direction of the presentation language's script. In a right-to-left deck
|
|
939
|
+
* composition mirrors the arrangement (the first column or `left` region is drawn at the right, slide images, logos and
|
|
940
|
+
* header/footer zones swap sides, tables run right to left), lists put their markers at the right, and every text fit
|
|
941
|
+
* reports each paragraph's direction. Alignment stays logical: `left` is the start edge.
|
|
942
|
+
*/
|
|
943
|
+
direction?: TextDirection;
|
|
944
|
+
/** Host-resolved alignment for shared content; slide design can override it. */
|
|
945
|
+
contentAlignment?: 'left' | 'center' | 'right';
|
|
946
|
+
titleAlignment?: 'left' | 'center' | 'right';
|
|
947
|
+
/** Unscaled reference pixels around provided vector outlines; defaults to 1 for body text and 2 for furniture. Explicit values apply to both. */
|
|
948
|
+
textRasterPadding?: number;
|
|
949
|
+
/** Host-resolved body cards. A slide's explicit design.contentBox overrides this value. */
|
|
950
|
+
contentBox?: boolean;
|
|
951
|
+
textMeasurement?: TextMeasurement;
|
|
952
|
+
width?: number;
|
|
953
|
+
height?: number;
|
|
954
|
+
slideIndex?: number;
|
|
955
|
+
layout?: Record<string, unknown>;
|
|
956
|
+
/** Return candidate scores and coverage without changing the selected geometry. */
|
|
957
|
+
explain?: boolean;
|
|
958
|
+
}
|
|
959
|
+
declare class OPFCompositionError extends Error {
|
|
960
|
+
readonly diagnostics: LayoutDiagnostic[];
|
|
961
|
+
readonly code = "layout-overflow";
|
|
962
|
+
readonly explanation?: CompositionExplanation;
|
|
963
|
+
constructor(diagnostics: LayoutDiagnostic[], explanation?: CompositionExplanation);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Outline of a DrawingML preset in a box, following the ECMA-376 presetShapeDefinitions formulas:
|
|
967
|
+
* roundRect (adj; ss = min(w,h), radius = ss*adj/100000), ellipse, and hexagon (adj, vf).
|
|
968
|
+
*/
|
|
969
|
+
declare function slideImageShape(kind: SlideImageShape['kind'], box: LayoutBox, cornerRadius?: number): SlideImageShape;
|
|
970
|
+
interface ResolveLogoOptions {
|
|
971
|
+
/** Variant family to prefer; defaults to the full lockup. */
|
|
972
|
+
slot?: LogoSlot;
|
|
973
|
+
/** True on a dark background (host luminance test): light variants are preferred, dark ones come last. */
|
|
974
|
+
onDark?: boolean;
|
|
975
|
+
/** Index used in the `slides.N.design.logo` path of a slide-level logo; defaults to 0. */
|
|
976
|
+
slideIndex?: number;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Resolve the logo a slide should draw, the same way in every engine. Source precedence:
|
|
980
|
+
* `slides[i].design.logo`, then `design.logo`, then the primary organization's `logo` (`role: 'primary'`,
|
|
981
|
+
* else the first organization; `organization` may be an object or an array). Absence inherits; a source
|
|
982
|
+
* that yields no usable asset falls through to the next. A string or Asset object is the `default`
|
|
983
|
+
* variant. A LogoSet picks by slot and tone: `icon` tries iconLight/iconDark (tone), then icon, then the
|
|
984
|
+
* lockup chain; `stacked` tries stackedLight/stackedDark (tone), then stacked, then the lockup chain; the
|
|
985
|
+
* lockup chain prefers same-tone variants, then neutral ones, then the opposite tone. `path` is the OPF
|
|
986
|
+
* path of the chosen value (`design.logo`, `design.logo.light`, `organization.2.logo`,
|
|
987
|
+
* `slides.3.design.logo.icon`) and `variant` the LogoSet key or `default`. Returns null without a logo.
|
|
988
|
+
*/
|
|
989
|
+
declare function resolveLogo(presentation: unknown, slide: unknown, options?: ResolveLogoOptions): ResolvedLogo | null;
|
|
990
|
+
interface FurniturePartBase {
|
|
991
|
+
kind: 'header' | 'footer';
|
|
992
|
+
zone: 'left' | 'center' | 'right';
|
|
993
|
+
field: 'text' | 'image' | 'logo' | 'organization' | 'socials' | 'section' | 'slideNumber' | 'date';
|
|
994
|
+
/** Literal field or controlling flag, with the actual inherited/local path. */
|
|
995
|
+
path: string;
|
|
996
|
+
/** String/asset source, when different from a generated field's flag. */
|
|
997
|
+
sourcePath?: string;
|
|
998
|
+
generated: boolean;
|
|
999
|
+
box: LayoutBox;
|
|
1000
|
+
alignment: 'left' | 'center' | 'right';
|
|
1001
|
+
}
|
|
1002
|
+
interface FurnitureTextPart extends FurniturePartBase {
|
|
1003
|
+
type: 'text';
|
|
1004
|
+
text: string;
|
|
1005
|
+
style: TextStyle;
|
|
1006
|
+
requestedFontSize: number;
|
|
1007
|
+
minFontSize: number;
|
|
1008
|
+
fit: SourceTextFit;
|
|
1009
|
+
/**
|
|
1010
|
+
* Live values inside `text`: every `{current}` slide number, and a whole current
|
|
1011
|
+
* (`date: true`) date. Hosts such as PPTX may emit them as native fields; all other
|
|
1012
|
+
* text, including `{total}` and formatted fixed dates, is fixed.
|
|
1013
|
+
*/
|
|
1014
|
+
fields?: FurnitureField[];
|
|
1015
|
+
/**
|
|
1016
|
+
* Generated `socials` only: one entry per explicit source line of `text`, in
|
|
1017
|
+
* order. A part may carry both `fields` and `links`; hosts apply each link to
|
|
1018
|
+
* its whole source line and each field range within it.
|
|
1019
|
+
*/
|
|
1020
|
+
links?: FurnitureSocialLink[];
|
|
1021
|
+
}
|
|
1022
|
+
/** Optional generated metadata for one furniture text part (live fields and/or social links). */
|
|
1023
|
+
interface FurnitureTextExtras {
|
|
1024
|
+
fields?: FurnitureField[];
|
|
1025
|
+
links?: FurnitureSocialLink[];
|
|
1026
|
+
}
|
|
1027
|
+
/** Social-platform catalog fields used to format a profile. */
|
|
1028
|
+
interface SocialPlatformRecord {
|
|
1029
|
+
id: string;
|
|
1030
|
+
name?: string;
|
|
1031
|
+
baseUrl?: string;
|
|
1032
|
+
profileUrlPattern?: string;
|
|
1033
|
+
companyUrlPattern?: string;
|
|
1034
|
+
handlePrefix?: string;
|
|
1035
|
+
}
|
|
1036
|
+
interface SocialProfile {
|
|
1037
|
+
/** Single-line display text: the profile URL without an `https://` scheme, or the raw value. */
|
|
1038
|
+
text: string;
|
|
1039
|
+
/** Full http(s) URL when the value is one or its platform record formats one. */
|
|
1040
|
+
href?: string;
|
|
1041
|
+
/** Whether a socialPlatforms record formatted a handle. */
|
|
1042
|
+
resolved: boolean;
|
|
1043
|
+
}
|
|
1044
|
+
interface FurnitureSocialLink extends SocialProfile {
|
|
1045
|
+
/** Socials key (platform id). */
|
|
1046
|
+
platform: string;
|
|
1047
|
+
/** Authored value path, such as `organization.socials.x`. */
|
|
1048
|
+
sourcePath: string;
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Format one Socials value through its platform record, deterministically and
|
|
1052
|
+
* without network access. `owner` selects companyUrlPattern for organizations.
|
|
1053
|
+
* URLs pass through; unknown platforms and unformattable values stay raw.
|
|
1054
|
+
*/
|
|
1055
|
+
declare function resolveSocialProfile(platform: string, value: string, records?: readonly SocialPlatformRecord[], owner?: 'organization' | 'speaker'): SocialProfile;
|
|
1056
|
+
interface FurnitureImagePart extends FurniturePartBase {
|
|
1057
|
+
type: 'image';
|
|
1058
|
+
image: unknown;
|
|
1059
|
+
}
|
|
1060
|
+
type FurniturePart = FurnitureTextPart | FurnitureImagePart;
|
|
1061
|
+
interface FurnitureLayout {
|
|
1062
|
+
algorithm: 'furniture-flow-v2';
|
|
1063
|
+
/** Includes explicitly empty definitions, which override inherited furniture. */
|
|
1064
|
+
configured: boolean;
|
|
1065
|
+
textMeasurement: 'estimated' | 'provided';
|
|
1066
|
+
textOutlines: 'provided' | 'unavailable';
|
|
1067
|
+
parts: FurniturePart[];
|
|
1068
|
+
/** Outer occupied edges; composeSlide adds its normal content gap. */
|
|
1069
|
+
headerBottom: number;
|
|
1070
|
+
footerTop: number;
|
|
1071
|
+
diagnostics: LayoutDiagnostic[];
|
|
1072
|
+
overflow: boolean;
|
|
1073
|
+
}
|
|
1074
|
+
/** Resolve and measure repeated fields without mutating metadata or consulting a clock. */
|
|
1075
|
+
declare function layoutFurniture(input: unknown, options?: ComposeSlideOptions): FurnitureLayout;
|
|
1076
|
+
/** Deterministic estimate, not a font shaping engine. Preserves explicit line breaks. */
|
|
1077
|
+
declare function measureText(text: string, fontSize: number): number;
|
|
1078
|
+
declare function wrapText(text: string, width: number, fontSize: number, measure?: MeasureTextWidth): string[];
|
|
1079
|
+
declare function fitText(text: string, box: LayoutBox, requestedSize?: number, minFontSize?: number, measure?: MeasureTextWidth, direction?: TextDirection): SourceTextFit;
|
|
1080
|
+
/**
|
|
1081
|
+
* PowerPoint stores a run size (`sz`) in hundredths of a point, and composition pixels are CSS pixels (96 per
|
|
1082
|
+
* inch, so a point is 4/3 px). Every composed font size is therefore a whole multiple of 0.01 pt, which is
|
|
1083
|
+
* 1/75 px: the preview then measures, breaks and draws exactly the size the export writes (RR-16).
|
|
1084
|
+
* The tolerance absorbs binary rounding noise (a size already on the grid must not drop a step).
|
|
1085
|
+
*/
|
|
1086
|
+
declare const FONT_SIZE_GRID_PER_PX = 75;
|
|
1087
|
+
/** Largest grid size not above `px`. Rounding down keeps a size that fit before snapping fitting. */
|
|
1088
|
+
declare function snapFontSizeDown(px: number): number;
|
|
1089
|
+
/** Smallest grid size not below `px`. Used for readability floors, so a floor is never undercut. */
|
|
1090
|
+
declare function snapFontSizeUp(px: number): number;
|
|
1091
|
+
interface QuoteContent {
|
|
1092
|
+
text: string;
|
|
1093
|
+
attribution?: string;
|
|
1094
|
+
source?: string;
|
|
1095
|
+
}
|
|
1096
|
+
/** Source and displayed-text ranges are half-open UTF-16 offsets. Added punctuation has no source range. */
|
|
1097
|
+
interface QuoteTextSource {
|
|
1098
|
+
path: string;
|
|
1099
|
+
start: number;
|
|
1100
|
+
end: number;
|
|
1101
|
+
outputStart: number;
|
|
1102
|
+
outputEnd: number;
|
|
1103
|
+
}
|
|
1104
|
+
interface QuoteTextPart {
|
|
1105
|
+
role: 'body' | 'footer';
|
|
1106
|
+
path: string;
|
|
1107
|
+
text: string;
|
|
1108
|
+
sources: QuoteTextSource[];
|
|
1109
|
+
/** Available space, before fitting. Invalid dimensions remain visible in failed results. */
|
|
1110
|
+
box: LayoutBox;
|
|
1111
|
+
requestedFontSize: number;
|
|
1112
|
+
minFontSize: number;
|
|
1113
|
+
requestedStyle: TextStyle;
|
|
1114
|
+
style: TextStyle;
|
|
1115
|
+
/** Absent when the available box is invalid; never fit against an invented one-pixel box. */
|
|
1116
|
+
fit?: TextFit;
|
|
1117
|
+
}
|
|
1118
|
+
interface QuoteLayoutDiagnostic extends LayoutDiagnostic {
|
|
1119
|
+
reason: 'invalid-part-box' | 'part-outside-cell' | 'text-fit' | 'part-overlap';
|
|
1120
|
+
parts: QuoteTextPart['role'][];
|
|
1121
|
+
}
|
|
1122
|
+
interface QuoteLayout {
|
|
1123
|
+
algorithm: 'quote-flow-v1';
|
|
1124
|
+
textMeasurement: 'estimated' | 'provided';
|
|
1125
|
+
parts: QuoteTextPart[];
|
|
1126
|
+
diagnostics: QuoteLayoutDiagnostic[];
|
|
1127
|
+
overflow: boolean;
|
|
1128
|
+
}
|
|
1129
|
+
interface QuoteLayoutOptions {
|
|
1130
|
+
/** Canvas short edge divided by 720. Insets retain the current 18 reference-pixel contract. */
|
|
1131
|
+
scale?: number;
|
|
1132
|
+
fonts?: Partial<FontFamilies>;
|
|
1133
|
+
/** Readability floor in reference pixels, before canvas scaling. */
|
|
1134
|
+
minFontSize?: number;
|
|
1135
|
+
overflow?: Composition['overflow'];
|
|
1136
|
+
path?: string;
|
|
1137
|
+
textMeasurement?: TextMeasurement;
|
|
1138
|
+
/** Deck direction; in a right-to-left deck every part fit reports its paragraphs' directions (RR-05). */
|
|
1139
|
+
direction?: TextDirection;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Allocate and measure quote body/footer space for composition, rendering and export. Callers must
|
|
1143
|
+
* check overflow before accepting the parts. Line boxes are not shaped glyph or native raster bounds.
|
|
1144
|
+
*/
|
|
1145
|
+
declare function layoutQuote(value: string | QuoteContent, box: LayoutBox, options?: QuoteLayoutOptions): QuoteLayout;
|
|
1146
|
+
interface MetricContent {
|
|
1147
|
+
value: string | number;
|
|
1148
|
+
label?: string;
|
|
1149
|
+
description?: string;
|
|
1150
|
+
unit?: string;
|
|
1151
|
+
delta?: string | number;
|
|
1152
|
+
trend?: 'up' | 'down' | 'flat';
|
|
1153
|
+
}
|
|
1154
|
+
/** Ranges address String(sourceValue), not the numeric token spelling in serialized JSON. */
|
|
1155
|
+
interface MetricTextSource {
|
|
1156
|
+
path: string;
|
|
1157
|
+
value: string | number;
|
|
1158
|
+
start: number;
|
|
1159
|
+
end: number;
|
|
1160
|
+
}
|
|
1161
|
+
interface MetricTextPart {
|
|
1162
|
+
role: keyof MetricContent;
|
|
1163
|
+
path: string;
|
|
1164
|
+
text: string;
|
|
1165
|
+
sources: MetricTextSource[];
|
|
1166
|
+
/** Empty optional fields retain their source mapping but occupy no visible space. */
|
|
1167
|
+
visible: boolean;
|
|
1168
|
+
/** Accepted absolute origin/baseline for each fit.sourceLines entry, including blank lines. */
|
|
1169
|
+
linePositions: {
|
|
1170
|
+
x: number;
|
|
1171
|
+
baseline: number;
|
|
1172
|
+
}[];
|
|
1173
|
+
box: LayoutBox;
|
|
1174
|
+
requestedFontSize: number;
|
|
1175
|
+
minFontSize: number;
|
|
1176
|
+
requestedStyle: TextStyle;
|
|
1177
|
+
style: TextStyle;
|
|
1178
|
+
/** Source-preserving line/segment representation shared with code, with proportional fonts. */
|
|
1179
|
+
fit?: CodeTextFit;
|
|
1180
|
+
}
|
|
1181
|
+
interface MetricLayoutDiagnostic extends LayoutDiagnostic {
|
|
1182
|
+
reason: 'invalid-part-box' | 'part-outside-cell' | 'text-fit' | 'part-overlap';
|
|
1183
|
+
parts: MetricTextPart['role'][];
|
|
1184
|
+
}
|
|
1185
|
+
interface MetricLayout {
|
|
1186
|
+
algorithm: 'metric-flow-v1';
|
|
1187
|
+
alignment: 'left' | 'center' | 'right';
|
|
1188
|
+
textMeasurement: 'estimated' | 'provided';
|
|
1189
|
+
arrangement: 'inline-unit' | 'stacked';
|
|
1190
|
+
/** At most 48 arrangements; value fitting is bounded by 77 reference-size trials per arrangement. */
|
|
1191
|
+
attempts: number;
|
|
1192
|
+
parts: MetricTextPart[];
|
|
1193
|
+
diagnostics: MetricLayoutDiagnostic[];
|
|
1194
|
+
overflow: boolean;
|
|
1195
|
+
}
|
|
1196
|
+
interface MetricLayoutOptions extends QuoteLayoutOptions {
|
|
1197
|
+
align?: 'left' | 'center' | 'right';
|
|
1198
|
+
/** Unscaled clearance around available vector outlines; defaults to one reference pixel. */
|
|
1199
|
+
textRasterPadding?: number;
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Measure every metric field before accepting geometry. Short single-line values and units can
|
|
1203
|
+
* share a baseline; longer values or units stack. No locale formatting, trend icons or rewritten
|
|
1204
|
+
* source text are invented here: the trend stays its word, and metricTrendMark derives the arrow
|
|
1205
|
+
* beside it from these accepted parts. Consumers must reuse these accepted parts and source ranges.
|
|
1206
|
+
*/
|
|
1207
|
+
declare function layoutMetric(value: string | number | MetricContent, box: LayoutBox, options?: MetricLayoutOptions): MetricLayout;
|
|
1208
|
+
interface TimelineEvent {
|
|
1209
|
+
when?: string;
|
|
1210
|
+
what: string;
|
|
1211
|
+
description?: string;
|
|
1212
|
+
}
|
|
1213
|
+
interface TimelineContent {
|
|
1214
|
+
name?: string;
|
|
1215
|
+
description?: string;
|
|
1216
|
+
events: TimelineEvent[];
|
|
1217
|
+
}
|
|
1218
|
+
interface TimelineTextPart {
|
|
1219
|
+
role: 'name' | 'description' | 'when' | 'what' | 'event-description';
|
|
1220
|
+
eventIndex?: number;
|
|
1221
|
+
path: string;
|
|
1222
|
+
text: string;
|
|
1223
|
+
sources: {
|
|
1224
|
+
path: string;
|
|
1225
|
+
start: number;
|
|
1226
|
+
end: number;
|
|
1227
|
+
}[];
|
|
1228
|
+
box: LayoutBox;
|
|
1229
|
+
/** Logical alignment: `left` is the start edge, which a right-to-left line draws at the right (see `fit.directions`). */
|
|
1230
|
+
alignment: 'left' | 'center';
|
|
1231
|
+
requestedFontSize: number;
|
|
1232
|
+
minFontSize: number;
|
|
1233
|
+
requestedStyle: TextStyle;
|
|
1234
|
+
style: TextStyle;
|
|
1235
|
+
fit?: SourceTextFit;
|
|
1236
|
+
}
|
|
1237
|
+
interface TimelineLayoutDiagnostic extends LayoutDiagnostic {
|
|
1238
|
+
reason: 'text-fit' | 'part-outside-cell' | 'event-space';
|
|
1239
|
+
}
|
|
1240
|
+
interface TimelineLayout {
|
|
1241
|
+
algorithm: 'timeline-flow-v1';
|
|
1242
|
+
arrangement: 'alternating' | 'vertical';
|
|
1243
|
+
attempts: number;
|
|
1244
|
+
textMeasurement: 'provided' | 'estimated';
|
|
1245
|
+
textOutlines: 'provided' | 'unavailable';
|
|
1246
|
+
parts: TimelineTextPart[];
|
|
1247
|
+
markers: {
|
|
1248
|
+
path: string;
|
|
1249
|
+
eventIndex: number;
|
|
1250
|
+
x: number;
|
|
1251
|
+
y: number;
|
|
1252
|
+
radius: number;
|
|
1253
|
+
}[];
|
|
1254
|
+
connector: {
|
|
1255
|
+
x1: number;
|
|
1256
|
+
y1: number;
|
|
1257
|
+
x2: number;
|
|
1258
|
+
y2: number;
|
|
1259
|
+
};
|
|
1260
|
+
diagnostics: TimelineLayoutDiagnostic[];
|
|
1261
|
+
overflow: boolean;
|
|
1262
|
+
}
|
|
1263
|
+
interface TimelineLayoutOptions extends QuoteLayoutOptions {
|
|
1264
|
+
textRasterPadding?: number;
|
|
1265
|
+
}
|
|
1266
|
+
/** Preserve event order and field boundaries while trying at most 50 readable arrangements. */
|
|
1267
|
+
declare function layoutTimeline(value: readonly TimelineEvent[] | TimelineContent, box: LayoutBox, options?: TimelineLayoutOptions): TimelineLayout;
|
|
1268
|
+
interface CodeContent {
|
|
1269
|
+
source: string;
|
|
1270
|
+
language?: string;
|
|
1271
|
+
filename?: string;
|
|
1272
|
+
}
|
|
1273
|
+
interface TextLineSegment {
|
|
1274
|
+
kind: 'text' | 'tab';
|
|
1275
|
+
start: number;
|
|
1276
|
+
end: number;
|
|
1277
|
+
/** Measured position relative to this displayed line's origin, in reference pixels. */
|
|
1278
|
+
x: number;
|
|
1279
|
+
width: number;
|
|
1280
|
+
}
|
|
1281
|
+
/** Exact half-open UTF-16 offsets into the part text, including consumed hard line breaks. */
|
|
1282
|
+
interface TextLineSource {
|
|
1283
|
+
start: number;
|
|
1284
|
+
end: number;
|
|
1285
|
+
nextStart: number;
|
|
1286
|
+
boundary: 'soft' | 'hard' | 'end';
|
|
1287
|
+
width: number;
|
|
1288
|
+
/** Explicit tab placement is required in SVG; CSS tab-size alone does not implement it. */
|
|
1289
|
+
segments: TextLineSegment[];
|
|
1290
|
+
}
|
|
1291
|
+
interface SourceTextFit extends TextFit {
|
|
1292
|
+
sourceLines: TextLineSource[];
|
|
1293
|
+
/** Tabs advance to the next multiple of four measured spaces from each displayed line's origin. */
|
|
1294
|
+
tabSize: 4;
|
|
1295
|
+
tabWidth: number;
|
|
1296
|
+
}
|
|
1297
|
+
/** Compatibility names for the shared source-preserving line contract. */
|
|
1298
|
+
type CodeLineSegment = TextLineSegment;
|
|
1299
|
+
type CodeLineSource = TextLineSource;
|
|
1300
|
+
interface CodeTextFit extends SourceTextFit {
|
|
1301
|
+
}
|
|
1302
|
+
interface CodeTextPart {
|
|
1303
|
+
role: 'filename' | 'language' | 'body';
|
|
1304
|
+
path: string;
|
|
1305
|
+
/** Original text, without case conversion, whitespace normalization or discarded newlines. */
|
|
1306
|
+
text: string;
|
|
1307
|
+
sources: {
|
|
1308
|
+
path: string;
|
|
1309
|
+
start: number;
|
|
1310
|
+
end: number;
|
|
1311
|
+
}[];
|
|
1312
|
+
generated: boolean;
|
|
1313
|
+
box: LayoutBox;
|
|
1314
|
+
requestedFontSize: number;
|
|
1315
|
+
minFontSize: number;
|
|
1316
|
+
requestedStyle: TextStyle;
|
|
1317
|
+
style: TextStyle;
|
|
1318
|
+
fit?: CodeTextFit;
|
|
1319
|
+
}
|
|
1320
|
+
interface CodeLayoutDiagnostic extends LayoutDiagnostic {
|
|
1321
|
+
reason: 'invalid-part-box' | 'part-outside-cell' | 'text-fit' | 'part-overlap';
|
|
1322
|
+
parts: CodeTextPart['role'][];
|
|
1323
|
+
}
|
|
1324
|
+
interface CodeLayout {
|
|
1325
|
+
algorithm: 'code-flow-v1';
|
|
1326
|
+
textMeasurement: 'estimated' | 'provided';
|
|
1327
|
+
parts: CodeTextPart[];
|
|
1328
|
+
diagnostics: CodeLayoutDiagnostic[];
|
|
1329
|
+
overflow: boolean;
|
|
1330
|
+
}
|
|
1331
|
+
interface CodeLayoutOptions extends QuoteLayoutOptions {
|
|
1332
|
+
}
|
|
1333
|
+
/** Shared filename/language/body allocation. Consumers must reuse the accepted fits and styles. */
|
|
1334
|
+
declare function layoutCode(value: string | CodeContent, box: LayoutBox, options?: CodeLayoutOptions): CodeLayout;
|
|
1335
|
+
interface RichTextRun {
|
|
1336
|
+
text: string;
|
|
1337
|
+
bold?: boolean;
|
|
1338
|
+
italic?: boolean;
|
|
1339
|
+
underline?: boolean;
|
|
1340
|
+
strikethrough?: boolean;
|
|
1341
|
+
color?: string;
|
|
1342
|
+
fontSize?: number;
|
|
1343
|
+
fontFamily?: string;
|
|
1344
|
+
link?: string;
|
|
1345
|
+
superscript?: boolean;
|
|
1346
|
+
subscript?: boolean;
|
|
1347
|
+
/** RR-34: reference ids this run cites (a marker follows the run; the deck's `references` list resolves them). */
|
|
1348
|
+
cite?: string | string[];
|
|
1349
|
+
/** RR-34: an inline footnote for this run (a marker follows the run; the note is listed in the slide's footnote area). */
|
|
1350
|
+
footnote?: string | (string | RichTextRun)[];
|
|
1351
|
+
}
|
|
1352
|
+
interface RichTextFragment {
|
|
1353
|
+
/**
|
|
1354
|
+
* Tabs are source-preserving layout controls with a fixed advance, not glyph text. A marker is the
|
|
1355
|
+
* superscript citation/footnote number drawn after a run that cites or carries a footnote (RR-34): it
|
|
1356
|
+
* has no source range (`start === end === run.text.length`), so run indexes and offsets never shift.
|
|
1357
|
+
*/
|
|
1358
|
+
kind?: 'tab' | 'marker';
|
|
1359
|
+
text: string;
|
|
1360
|
+
runIndex: number;
|
|
1361
|
+
start: number;
|
|
1362
|
+
end: number;
|
|
1363
|
+
x: number;
|
|
1364
|
+
width: number;
|
|
1365
|
+
fontSize: number;
|
|
1366
|
+
baselineShift: number;
|
|
1367
|
+
/** A marker only: the size the exporter writes (the marked run's size); `fontSize` is the glyph PowerPoint draws for it (2/3). */
|
|
1368
|
+
nominalSize?: number;
|
|
1369
|
+
style: TextStyle;
|
|
1370
|
+
run: RichTextRun;
|
|
1371
|
+
}
|
|
1372
|
+
interface RichTextLine {
|
|
1373
|
+
fragments: RichTextFragment[];
|
|
1374
|
+
width: number;
|
|
1375
|
+
y: number;
|
|
1376
|
+
baseline: number;
|
|
1377
|
+
height: number;
|
|
1378
|
+
}
|
|
1379
|
+
interface RichTextFit extends TextFit {
|
|
1380
|
+
richLines: RichTextLine[];
|
|
1381
|
+
height: number;
|
|
1382
|
+
}
|
|
1383
|
+
interface RichTextOptions {
|
|
1384
|
+
style: TextStyle;
|
|
1385
|
+
textMeasurement?: TextMeasurement;
|
|
1386
|
+
/** Use one measured line advance for every line, as native table cells do. */
|
|
1387
|
+
uniformLineHeight?: boolean;
|
|
1388
|
+
/** Deck direction. In a right-to-left deck every line reports its paragraph's direction in `directions`. */
|
|
1389
|
+
direction?: TextDirection;
|
|
1390
|
+
/**
|
|
1391
|
+
* Marker text (`1`, `1,2`) for a run by its dotted path (`${style.path}.${runIndex}`), or undefined.
|
|
1392
|
+
* composeSlide supplies the deck numbering from `slideCitations`; a marker fragment is emitted after the run.
|
|
1393
|
+
*/
|
|
1394
|
+
citationMarker?: (runPath: string) => string | undefined;
|
|
1395
|
+
}
|
|
1396
|
+
/** Fit mixed styles without flattening font metrics. Run fontSize is in points. */
|
|
1397
|
+
declare function fitRichText(input: readonly (string | RichTextRun)[], box: LayoutBox, requestedSize?: number, minFontSize?: number, options?: RichTextOptions): RichTextFit;
|
|
1398
|
+
type ListText = string | readonly (string | RichTextRun)[];
|
|
1399
|
+
type ListValue = ListText | {
|
|
1400
|
+
text: ListText;
|
|
1401
|
+
description?: ListText;
|
|
1402
|
+
level?: number;
|
|
1403
|
+
start?: number;
|
|
1404
|
+
};
|
|
1405
|
+
interface ListEntryLayout {
|
|
1406
|
+
index: number;
|
|
1407
|
+
level: number;
|
|
1408
|
+
textPath?: string;
|
|
1409
|
+
descriptionPath?: string;
|
|
1410
|
+
value: ListText;
|
|
1411
|
+
descriptionValue?: ListText;
|
|
1412
|
+
text: RichTextFit;
|
|
1413
|
+
description?: RichTextFit;
|
|
1414
|
+
textBox: LayoutBox;
|
|
1415
|
+
descriptionBox?: LayoutBox;
|
|
1416
|
+
/**
|
|
1417
|
+
* `x` is the marker's left edge, or its right edge when `anchor` is `end` (a right-to-left entry, whose marker sits at the right and
|
|
1418
|
+
* whose text box is the column to its left).
|
|
1419
|
+
* The entry marker: the bullet glyph, or for a numbered list (`numbering`) the formatted number such as `iv.`.
|
|
1420
|
+
* A numbered marker also carries `number` and its measured `width`; its `style` is the list style with the weight and
|
|
1421
|
+
* slant of the entry's first run, as PowerPoint draws an auto-number in the first run's character formatting.
|
|
1422
|
+
*/
|
|
1423
|
+
marker: {
|
|
1424
|
+
text: string;
|
|
1425
|
+
x: number;
|
|
1426
|
+
y: number;
|
|
1427
|
+
fontSize: number;
|
|
1428
|
+
style: TextStyle;
|
|
1429
|
+
indent: number;
|
|
1430
|
+
number?: ListNumber;
|
|
1431
|
+
width?: number;
|
|
1432
|
+
anchor?: 'end';
|
|
1433
|
+
};
|
|
1434
|
+
/** Paragraph direction of this entry. Present only when the list was fitted for a right-to-left deck. */
|
|
1435
|
+
direction?: TextDirection;
|
|
1436
|
+
/** Picture bullet replacing the marker glyph; drawn in `bulletBox`. Marker geometry is unchanged. */
|
|
1437
|
+
bulletImage?: ListBulletImage;
|
|
1438
|
+
/**
|
|
1439
|
+
* Where the picture bullet draws: a square of side `marker.fontSize * PICTURE_BULLET_SCALE` whose
|
|
1440
|
+
* bottom sits on the marker baseline (`marker.y`) and whose left edge is `marker.x` (right edge when `marker.anchor` is `end`).
|
|
1441
|
+
* Present with `bulletImage`.
|
|
1442
|
+
*/
|
|
1443
|
+
bulletBox?: LayoutBox;
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Side of a picture bullet as a fraction of the list font size. Desktop PowerPoint sizes an `a:buBlip` at
|
|
1447
|
+
* `a:buSzPct 100000` (what opf-pptx writes) as a square about 0.65 times the run's font size, bottom on the
|
|
1448
|
+
* text baseline and left at the bullet position, in every typeface: measured widths of 10, 15, 16, 20 and 31
|
|
1449
|
+
* pixels at font sizes of 16, 24, 25, 32 and 48 pixels (0.625 to 0.646; heights run about a pixel more from
|
|
1450
|
+
* anti-aliasing, so the true side is about 0.65). The export needs no size: PowerPoint sizes the bullet itself.
|
|
1451
|
+
*/
|
|
1452
|
+
declare const PICTURE_BULLET_SCALE = 0.65;
|
|
1453
|
+
interface ListFit extends TextFit {
|
|
1454
|
+
listEntries: ListEntryLayout[];
|
|
1455
|
+
height: number;
|
|
1456
|
+
}
|
|
1457
|
+
interface ListFitOptions extends RichTextOptions {
|
|
1458
|
+
/**
|
|
1459
|
+
* Number the entries instead of bulleting them (the payload's `numbering` field). The hanging indent becomes the larger of
|
|
1460
|
+
* 1.1 em and the widest marker plus 0.3 em, so wide markers never touch their text; unnumbered lists are unchanged.
|
|
1461
|
+
*/
|
|
1462
|
+
numbering?: NumberingInput;
|
|
1463
|
+
/** Picture bullet for every entry (effective `design.listBullet: "image"` with a resolved icon logo). */
|
|
1464
|
+
bulletImage?: ListBulletImage;
|
|
1465
|
+
}
|
|
1466
|
+
/** Shared hanging indents, mixed-run fitting and description spacing for list payloads. */
|
|
1467
|
+
declare function fitList(input: readonly ListValue[], box: LayoutBox, requestedSize?: number, minFontSize?: number, options?: ListFitOptions): ListFit;
|
|
1468
|
+
interface TableLayoutOptions {
|
|
1469
|
+
scale?: number;
|
|
1470
|
+
minFontSize?: number;
|
|
1471
|
+
fontFamily?: string;
|
|
1472
|
+
textMeasurement?: TextMeasurement;
|
|
1473
|
+
path?: string;
|
|
1474
|
+
/**
|
|
1475
|
+
* Deck direction. A right-to-left deck lays the columns out right to left: the first column is the rightmost
|
|
1476
|
+
* and each cell's text reports its paragraph direction (RR-05).
|
|
1477
|
+
*/
|
|
1478
|
+
direction?: TextDirection;
|
|
1479
|
+
}
|
|
1480
|
+
interface TableCellLayout {
|
|
1481
|
+
value: unknown;
|
|
1482
|
+
input: unknown;
|
|
1483
|
+
sourcePath: string;
|
|
1484
|
+
style: TableCellStyle;
|
|
1485
|
+
row: number;
|
|
1486
|
+
column: number;
|
|
1487
|
+
rowSpan: number;
|
|
1488
|
+
colSpan: number;
|
|
1489
|
+
path: string;
|
|
1490
|
+
header: boolean;
|
|
1491
|
+
rich: boolean;
|
|
1492
|
+
box: LayoutBox;
|
|
1493
|
+
textBox: LayoutBox;
|
|
1494
|
+
textStyle: TextStyle;
|
|
1495
|
+
fit: TextFit | RichTextFit;
|
|
1496
|
+
/** Paragraph direction of the cell text; present only in a right-to-left deck. */
|
|
1497
|
+
direction?: TextDirection;
|
|
1498
|
+
}
|
|
1499
|
+
interface TableRowLayout {
|
|
1500
|
+
box: LayoutBox;
|
|
1501
|
+
cells: TableCellLayout[];
|
|
1502
|
+
}
|
|
1503
|
+
interface TableLayout {
|
|
1504
|
+
rows: TableRowLayout[];
|
|
1505
|
+
columnCount: number;
|
|
1506
|
+
height: number;
|
|
1507
|
+
overflow: boolean;
|
|
1508
|
+
}
|
|
1509
|
+
/** Shared cell geometry and font fitting for SVG, native PPTX and pagination.
|
|
1510
|
+
* Short rows retain their 54px preferred height. Multiline rows use the space
|
|
1511
|
+
* their text needs; constrained tables consume row padding before readable text.
|
|
1512
|
+
* All dimensions are canvas pixels; minFontSize is an unscaled canvas size.
|
|
1513
|
+
*/
|
|
1514
|
+
declare function layoutTable(value: unknown, box: LayoutBox, options?: TableLayoutOptions): TableLayout;
|
|
1515
|
+
/** Compose a validated Slide. Layout resolution remains the caller's responsibility. */
|
|
1516
|
+
declare function composeSlide(input: unknown, options?: ComposeSlideOptions): SlideComposition;
|
|
1517
|
+
/** Canonical physical slide size, converted to reference pixels at 96 pixels/inch. */
|
|
1518
|
+
declare function resolveCanvasDimensions(input: unknown): {
|
|
1519
|
+
width: number;
|
|
1520
|
+
height: number;
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1523
|
+
export { DEFAULT_FURNITURE_DATE_FORMAT as $, type AnnotatedRun as A, type CodeLayoutOptions as B, type ComposeSlideOptions as C, type CodeLineSegment as D, type CodeLineSource as E, type FontSchemeDiagnostic as F, type CodeTextFit as G, type CodeTextPart as H, type ComposedCaption as I, type ComposedFlow as J, type ComposedFootnoteEntry as K, type LayoutDiagnostic as L, type MetricLayout as M, type ComposedFootnotes as N, type ComposedGroup as O, type ComposedItem as P, type ComposedLogo as Q, type ComposedSlideImage as R, type Composition as S, type TextMeasurement as T, type CompositionCandidate as U, type CompositionDecision as V, type CompositionExplanation as W, type CompositionPenalties as X, type CompositionTrack as Y, DEFAULT_CHART_LABEL_SEPARATOR as Z, DEFAULT_FONT_SCHEME as _, type AnnotationFitter as a, type RichTextRun as a$, DEFAULT_SLIDE_NUMBER_FORMAT as a0, type DeckCitations as a1, FONT_SIZE_GRID_PER_PX as a2, FOOTNOTE_MAX_RATIO as a3, type FontFamilies as a4, type FootnoteLayoutOptions as a5, type FurnitureField as a6, type FurnitureImagePart as a7, type FurnitureLayout as a8, type FurniturePart as a9, type NumberingInput as aA, type NumberingStyleName as aB, type NumberingSuffix as aC, OPFCompositionError as aD, PICTURE_BULLET_SCALE as aE, type PhysicalAlignment as aF, type QuoteContent as aG, type QuoteLayout as aH, type QuoteLayoutDiagnostic as aI, type QuoteLayoutOptions as aJ, type QuoteTextPart as aK, type QuoteTextSource as aL, type Reference as aM, type ReferencesSlideOptions as aN, type ResolveColorRefOptions as aO, type ResolveColorRefRoles as aP, type ResolveLogoOptions as aQ, type ResolvedChartDataLabels as aR, type ResolvedChartOptions as aS, type ResolvedFontScheme as aT, type ResolvedLogo as aU, type ResolvedNumbering as aV, type RichText as aW, type RichTextFit as aX, type RichTextFragment as aY, type RichTextLine as aZ, type RichTextOptions as a_, type FurniturePartBase as aa, type FurnitureSocialLink as ab, type FurnitureTextExtras as ac, type FurnitureTextPart as ad, type LayoutBox as ae, type ListBulletImage as af, type ListEntryLayout as ag, type ListFit as ah, type ListFitOptions as ai, type ListNumber as aj, type ListText as ak, type ListValue as al, type LogoSlot as am, MAX_COMPOSITION_DEPTH as an, MAX_NUMBERING_LEVELS as ao, MAX_NUMBERING_VALUE as ap, MAX_ROMAN_VALUE as aq, type MeasureTextWidth as ar, type MetricContent as as, type MetricLayoutDiagnostic as at, type MetricLayoutOptions as au, type MetricTextPart as av, type MetricTextSource as aw, NUMBERING_STYLES as ax, NUMBERING_SUFFIXES as ay, type Numbering as az, type AnnotationLayoutOptions as b, sliceNumberedItems as b$, type SlideCitations as b0, type SlideComposition as b1, type SlideImageShape as b2, type SocialPlatformRecord as b3, type SocialProfile as b4, type TextDirection as b5, type TextFit as b6, type TextLineInk as b7, type TextPlacement as b8, type TextPlacementLine as b9, layoutCaption as bA, layoutCode as bB, layoutFootnotes as bC, layoutFurniture as bD, layoutMetric as bE, layoutQuote as bF, layoutTimeline as bG, listNumbers as bH, measureText as bI, measureTextOutline as bJ, normalizeHexColor as bK, numberingAtLevel as bL, numberingStyleDraws as bM, paragraphDirection as bN, paragraphDirectionAt as bO, physicalAlignment as bP, placeTextLines as bQ, referencesSlide as bR, resolveCanvasDimensions as bS, resolveChartOptions as bT, resolveColorRef as bU, resolveFontFamilies as bV, resolveFontSchemeReference as bW, resolveLogo as bX, resolveNumbering as bY, resolveSocialProfile as bZ, resolveTextStyle as b_, type TextStyle as ba, type TimelineContent as bb, type TimelineEvent as bc, type TimelineLayout as bd, type TimelineLayoutDiagnostic as be, type TimelineLayoutOptions as bf, type TimelineTextPart as bg, annotationText as bh, captionSettings as bi, chartColorForFill as bj, chartLabelText as bk, chartOptionSupport as bl, chartOptionTarget as bm, chartPaletteForFill as bn, citationMarkerText as bo, collectCitations as bp, colorContrast as bq, composeSlide as br, fitList as bs, fitRichText as bt, fitText as bu, formatChartLabelNumber as bv, formatChartLabelPercent as bw, formatFurnitureDate as bx, formatListNumber as by, formatSlideNumber as bz, CAPTIONABLE_FIELDS as c, slideCitations as c0, snapFontSizeDown as c1, snapFontSizeUp as c2, textColorForFill as c3, textWidthMeasurer as c4, walkCitationRuns as c5, wrapText as c6, type FontFaceSelection as c7, type ReadingBox as c8, type SourceTextFit as c9, type TableBorder as ca, type TableCellLayout as cb, type TableCellStyle as cc, type TableGrid as cd, type TableGridCell as ce, type TableGridIssue as cf, type TableLayout as cg, type TableLayoutOptions as ch, type TableRowLayout as ci, type TextLineSegment as cj, type TextLineSource as ck, layoutTable as cl, slideImageShape as cm, tableGrid as cn, tableRowBoundaries as co, visualReadingOrder as cp, CAPTION_FONT_RATIO as d, CAPTION_MAX_RATIO as e, CHART_SERIES_MIN_DIFFERENCE as f, CHART_SERIES_MIN_LIGHTNESS_STEP as g, CITATION_MARKER_RAISE as h, CITATION_MARKER_SCALE as i, type Caption as j, type CaptionAlignment as k, type CaptionObject as l, type CaptionPosition as m, type CaptionSettings as n, type ChartLabelContent as o, type ChartLabelPosition as p, type ChartLegendPosition as q, type ChartOptionDiagnostic as r, type ChartOptionKind as s, type ChartOptionSupport as t, type ChartOptionTarget as u, type CitationMarker as v, type CitationNote as w, type CodeContent as x, type CodeLayout as y, type CodeLayoutDiagnostic as z };
|