@shbernal/ts-pptx 4.1.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/anim-presets-Qbgh8uut.js +55 -0
- package/dist/anim-presets-Qbgh8uut.js.map +1 -0
- package/dist/{autopage-D4kyVp11.js → autopage-DqZ37VpL.js} +11 -12
- package/dist/autopage-DqZ37VpL.js.map +1 -0
- package/dist/{binary-string-CKVAYI3M.js → binary-string-Ba8VM3b9.js} +3 -4
- package/dist/binary-string-Ba8VM3b9.js.map +1 -0
- package/dist/{body-insets-kVHmjGc6.js → body-insets-BDHymJvz.js} +7 -9
- package/dist/body-insets-BDHymJvz.js.map +1 -0
- package/dist/browser.d.ts +24 -16
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -19
- package/dist/browser.js.map +1 -1
- package/dist/{image-size-DwDbakcl.js → chart-metadata-CwiTTcJq.js} +576 -538
- package/dist/chart-metadata-CwiTTcJq.js.map +1 -0
- package/dist/{clip-DHDlnHUq.d.ts → clip-ISfCMtWA.d.ts} +6 -10
- package/dist/clip-ISfCMtWA.d.ts.map +1 -0
- package/dist/{notes-BcT571R4.js → comments-CKIZYRbZ.js} +517 -389
- package/dist/comments-CKIZYRbZ.js.map +1 -0
- package/dist/{diagnostics-DiMmBU8P.d.ts → diagnostics-MoA4MBq5.d.ts} +52 -50
- package/dist/diagnostics-MoA4MBq5.d.ts.map +1 -0
- package/dist/{embedded-fonts-CI_YGW2d.d.ts → embedded-fonts-U7HIIhPO.d.ts} +4 -6
- package/dist/embedded-fonts-U7HIIhPO.d.ts.map +1 -0
- package/dist/{entry-compose-6hF9aTmT.d.ts → entry-compose-CiakSt-f.d.ts} +53 -74
- package/dist/entry-compose-CiakSt-f.d.ts.map +1 -0
- package/dist/{errors-Da2nXCJm.js → entry-errors-JMthgJ2g.js} +41 -25
- package/dist/entry-errors-JMthgJ2g.js.map +1 -0
- package/dist/{table-cell-margins-PDshga8T.js → enums-BP9wsb9Q.js} +42 -45
- package/dist/enums-BP9wsb9Q.js.map +1 -0
- package/dist/{enums-DQRpVOLh.d.ts → enums-PcXr3o3J.d.ts} +11 -12
- package/dist/{enums-DQRpVOLh.d.ts.map → enums-PcXr3o3J.d.ts.map} +1 -1
- package/dist/families.d.ts +24 -26
- package/dist/families.d.ts.map +1 -1
- package/dist/families.js +3 -4
- package/dist/{fit-CcXbg__l.js → fit-Bpmzep6O.js} +60 -52
- package/dist/fit-Bpmzep6O.js.map +1 -0
- package/dist/{font-metrics-CBGmhLo0.d.ts → font-metrics-DTppw4t3.d.ts} +61 -37
- package/dist/font-metrics-DTppw4t3.d.ts.map +1 -0
- package/dist/{grid-9B2w5EaY.js → grid-DUIMxjfl.js} +23 -26
- package/dist/grid-DUIMxjfl.js.map +1 -0
- package/dist/{html-dom-DvJmuHt2.js → html-dom-LZCgntnJ.js} +42 -43
- package/dist/html-dom-LZCgntnJ.js.map +1 -0
- package/dist/html.d.ts +53 -9
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +12 -13
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +21 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +14 -16
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +18 -19
- package/dist/inspect.js.map +1 -1
- package/dist/{text-anchor-BgLPbwbL.js → lock-attrs-CSQnFDHP.js} +62 -12
- package/dist/lock-attrs-CSQnFDHP.js.map +1 -0
- package/dist/math.d.ts +2 -4
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +12 -13
- package/dist/math.js.map +1 -1
- package/dist/measure.d.ts +23 -12
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +3 -3
- package/dist/node.d.ts +21 -13
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +12 -12
- package/dist/node.js.map +1 -1
- package/dist/{options-internal-WqgMf720.js → options-internal-BWgmLPdx.js} +4 -5
- package/dist/options-internal-BWgmLPdx.js.map +1 -0
- package/dist/{package-KoEgVwII.d.ts → package-CANBWuSm.d.ts} +4 -12
- package/dist/package-CANBWuSm.d.ts.map +1 -0
- package/dist/{playbtn-CUqQdoDf.js → playbtn-BQZFJir9.js} +4 -5
- package/dist/playbtn-BQZFJir9.js.map +1 -0
- package/dist/{pres-BA9_lJbY.d.ts → pres-BkEkUAEM.d.ts} +383 -230
- package/dist/pres-BkEkUAEM.d.ts.map +1 -0
- package/dist/{presentation-Cyl74rq2.js → presentation-4Ggq0_Xa.js} +408 -288
- package/dist/presentation-4Ggq0_Xa.js.map +1 -0
- package/dist/{presentation-types-B3VQH4Bz.d.ts → presentation-types-BgnZR-0a.d.ts} +1104 -457
- package/dist/presentation-types-BgnZR-0a.d.ts.map +1 -0
- package/dist/read.d.ts +18 -13
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +4 -4
- package/dist/script.d.ts +116 -65
- package/dist/script.d.ts.map +1 -1
- package/dist/script.js +2697 -777
- package/dist/script.js.map +1 -1
- package/dist/{shapes-BcyFdZpp.js → shapes-CAPOjU0Q.js} +1556 -487
- package/dist/shapes-CAPOjU0Q.js.map +1 -0
- package/dist/{slide-BqPtyKmb.d.ts → slide-BmT4kMoO.d.ts} +94 -86
- package/dist/slide-BmT4kMoO.d.ts.map +1 -0
- package/dist/{slide-size-BalTjFuv.js → slide-size-SkScz1ig.js} +2 -3
- package/dist/{slide-size-BalTjFuv.js.map → slide-size-SkScz1ig.js.map} +1 -1
- package/dist/{table-dom-CVbvUfgh.js → table-dom-BYga4FYY.js} +3 -4
- package/dist/{table-dom-CVbvUfgh.js.map → table-dom-BYga4FYY.js.map} +1 -1
- package/dist/{text-BvFFMMFQ.js → text-Dz0ArGIp.js} +365 -318
- package/dist/text-Dz0ArGIp.js.map +1 -0
- package/dist/{transition-speed-kUEWDWTx.js → transition-speed-CNJ0fSpQ.js} +2 -3
- package/dist/{transition-speed-kUEWDWTx.js.map → transition-speed-CNJ0fSpQ.js.map} +1 -1
- package/dist/{units-internal-DFcUYjh3.js → units-internal-BR3a4cIi.js} +26 -29
- package/dist/units-internal-BR3a4cIi.js.map +1 -0
- package/dist/{zip-CYZ0F6BV.js → zip-7JTh61LX.js} +8 -10
- package/dist/zip-7JTh61LX.js.map +1 -0
- package/dist/{zip-CTll_dr0.d.ts → zip-uUjs9Cqx.d.ts} +4 -6
- package/dist/zip-uUjs9Cqx.d.ts.map +1 -0
- package/dist/zip.d.ts +3 -3
- package/dist/zip.js +3 -3
- package/dist/{zoom-BoNyOlPm.js → zoom-CSSeOwM8.js} +1153 -583
- package/dist/zoom-CSSeOwM8.js.map +1 -0
- package/package.json +20 -21
- package/skills/{ts-pptx-upstream → pptx-ts-upstream}/SKILL.md +27 -74
- package/dist/autopage-D4kyVp11.js.map +0 -1
- package/dist/binary-string-CKVAYI3M.js.map +0 -1
- package/dist/body-insets-kVHmjGc6.js.map +0 -1
- package/dist/clip-DHDlnHUq.d.ts.map +0 -1
- package/dist/diagnostics-DiMmBU8P.d.ts.map +0 -1
- package/dist/embedded-fonts-CI_YGW2d.d.ts.map +0 -1
- package/dist/entry-compose-6hF9aTmT.d.ts.map +0 -1
- package/dist/errors-Da2nXCJm.js.map +0 -1
- package/dist/fit-CcXbg__l.js.map +0 -1
- package/dist/font-metrics-CBGmhLo0.d.ts.map +0 -1
- package/dist/grid-9B2w5EaY.js.map +0 -1
- package/dist/html-dom-DvJmuHt2.js.map +0 -1
- package/dist/image-size-DwDbakcl.js.map +0 -1
- package/dist/notes-BcT571R4.js.map +0 -1
- package/dist/options-internal-WqgMf720.js.map +0 -1
- package/dist/package-KoEgVwII.d.ts.map +0 -1
- package/dist/playbtn-CUqQdoDf.js.map +0 -1
- package/dist/pres-BA9_lJbY.d.ts.map +0 -1
- package/dist/presentation-Cyl74rq2.js.map +0 -1
- package/dist/presentation-types-B3VQH4Bz.d.ts.map +0 -1
- package/dist/shapes-BcyFdZpp.js.map +0 -1
- package/dist/slide-BqPtyKmb.d.ts.map +0 -1
- package/dist/table-cell-margins-PDshga8T.js.map +0 -1
- package/dist/text-BvFFMMFQ.js.map +0 -1
- package/dist/text-anchor-BgLPbwbL.js.map +0 -1
- package/dist/units-internal-DFcUYjh3.js.map +0 -1
- package/dist/zip-CTll_dr0.d.ts.map +0 -1
- package/dist/zip-CYZ0F6BV.js.map +0 -1
- package/dist/zoom-BoNyOlPm.js.map +0 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { c as PLACEHOLDER_TYPE, d as SHAPE_NAME, g as TextAnchor, i as CHART_NAME, m as SlideObjectType, o as ChartType, t as AlignH } from "./enums-
|
|
2
|
-
import {
|
|
3
|
-
import { O as TableCell, S as AnimationProps, _ as MasterTextStyleProps, a as Slide, i as ObjectOptions, o as SlideLayout, x as SlideNumberProps } from "./slide-
|
|
4
|
-
import { t as EmbeddedFont } from "./embedded-fonts-
|
|
5
|
-
//#region src/types/internal.d.ts
|
|
1
|
+
import { c as PLACEHOLDER_TYPE, d as SHAPE_NAME, g as TextAnchor, i as CHART_NAME, m as SlideObjectType, o as ChartType, t as AlignH } from "./enums-PcXr3o3J.js";
|
|
2
|
+
import { An as TextShapeType, Cn as PlaceholderXmlType, Dt as OptsChartData, E as Margin, H as HyperlinkProps, M as TextVertType, Q as ChartErrorBarOptions, Vt as SlideComment, Xt as TextPropsOptions, Yt as TextProps, a as PresentationProps, i as PresLayout, it as ChartOpts, nn as MediaType, o as SectionProps, p as BackgroundOption, rt as ChartMulti, tn as MediaProps } from "./pres-BkEkUAEM.js";
|
|
3
|
+
import { O as TableCell, S as AnimationProps, _ as MasterTextStyleProps, a as Slide, i as ObjectOptions, o as SlideLayout, x as SlideNumberProps } from "./slide-BmT4kMoO.js";
|
|
4
|
+
import { t as EmbeddedFont } from "./embedded-fonts-U7HIIhPO.js";
|
|
6
5
|
/** The keys of `T` that are declared optional. */
|
|
7
6
|
type OptionalKeysOf<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never; }[keyof T];
|
|
8
7
|
/**
|
|
9
8
|
* `T`, but every *optional* property may also be spelled as a present `undefined`.
|
|
10
9
|
*
|
|
11
10
|
* Under `exactOptionalPropertyTypes` a `foo?: T` says the key is either absent or holds a `T`.
|
|
12
|
-
* That distinction is real for a bag that is **stored, spread or enumerated**
|
|
13
|
-
* ...options }` inherits from an absent key and is overridden by a present `undefined`
|
|
11
|
+
* That distinction is real for a bag that is **stored, spread or enumerated** (`{ ...defaults,
|
|
12
|
+
* ...options }` inherits from an absent key and is overridden by a present `undefined`), and
|
|
14
13
|
* those bags keep the strict declaration, with `delete` as their one spelling of absent (the
|
|
15
14
|
* write-side twin of `compact()` in `script/from-read/values.ts`).
|
|
16
15
|
*
|
|
@@ -26,7 +25,7 @@ type MaybeUndefined<T> = Omit<T, OptionalKeysOf<T>> & { [K in OptionalKeysOf<T>]
|
|
|
26
25
|
* Text options carrying the two members the emitters write onto them.
|
|
27
26
|
*
|
|
28
27
|
* `_bodyProp` is the normalized `a:bodyPr` the definer builds out of the caller's `align`,
|
|
29
|
-
* `valign`, `margin`, `columns`, `textDirection` and `textWarp
|
|
28
|
+
* `valign`, `margin`, `columns`, `textDirection` and `textWarp`: a *derived* shape, not an
|
|
30
29
|
* input, which is what made its presence on the public interface a de-facto API nobody
|
|
31
30
|
* intended. `_lineIdx` is the paragraph index the run emitter stamps while walking an array
|
|
32
31
|
* of runs.
|
|
@@ -53,6 +52,18 @@ interface TextPropsOptionsInternal extends TextPropsOptions {
|
|
|
53
52
|
prstTxWarp?: TextShapeType;
|
|
54
53
|
};
|
|
55
54
|
_lineIdx?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Set by the definer on text that would otherwise be written black: no colour of its own, none
|
|
57
|
+
* on its shape, not a placeholder, not a link. The emitter paints it in the slide's
|
|
58
|
+
* {@link Slide.color}, else black. It is a flag rather than the colour because the slide's
|
|
59
|
+
* colour is read when the slide is written, not when the text is added (#88).
|
|
60
|
+
*/
|
|
61
|
+
_slideColor?: true;
|
|
62
|
+
/**
|
|
63
|
+
* Set by the emitter on a run whose `hyperlink` it took from the shape, so the run writes no
|
|
64
|
+
* show jump of its own: the shape's lives on its `p:cNvPr`.
|
|
65
|
+
*/
|
|
66
|
+
_shapeHyperlink?: true;
|
|
56
67
|
}
|
|
57
68
|
/**
|
|
58
69
|
* A slide object's options carrying the six members the definers and emitters write onto them.
|
|
@@ -66,7 +77,7 @@ interface TextPropsOptionsInternal extends TextPropsOptions {
|
|
|
66
77
|
*/
|
|
67
78
|
interface ObjectOptionsInternal extends ObjectOptions, TextPropsOptionsInternal {
|
|
68
79
|
_placeholderIdx?: number;
|
|
69
|
-
_placeholderType?: PLACEHOLDER_TYPE;
|
|
80
|
+
_placeholderType?: PLACEHOLDER_TYPE | PlaceholderXmlType;
|
|
70
81
|
/** Connector adjust-guide values (OOXML 1000ths-of-a-percent), one per bend; emitted as `<a:gd name="adjN">` */
|
|
71
82
|
_connectorAdj?: number[];
|
|
72
83
|
/** Connector start-point binding: target shape `objectName` (raw, as the caller spelled it) + connection-site index; resolved to `<a:stCxn>` at serialize time */
|
|
@@ -110,7 +121,7 @@ interface ChartOptsInternal extends ChartOpts {
|
|
|
110
121
|
_type?: ChartType | ChartMultiInternal[];
|
|
111
122
|
}
|
|
112
123
|
/**
|
|
113
|
-
* A combo subchart's option overrides after `addChartDefinition` vetted them
|
|
124
|
+
* A combo subchart's option overrides after `addChartDefinition` vetted them: the one bag in the
|
|
114
125
|
* generator where a key may be *present* and hold `undefined`.
|
|
115
126
|
*
|
|
116
127
|
* Everywhere else "unset" has exactly one spelling, an absent key: `compact()` enforces it on the
|
|
@@ -119,7 +130,7 @@ interface ChartOptsInternal extends ChartOpts {
|
|
|
119
130
|
* chart-level options at emit time (`{ ...rel.opts, ...type.options }` in `gen/chart/chart-xml.ts`),
|
|
120
131
|
* where a present `undefined` suppresses the chart-level value and an absent key inherits it.
|
|
121
132
|
* Suppressing is the intent: the subchart supplied an override the schema rejects, and the
|
|
122
|
-
* chart-level value is one it never asked for
|
|
133
|
+
* chart-level value is one it never asked for. Inheriting it would be a different chart than
|
|
123
134
|
* either party described. For a combo chart the chart-level pass cannot vet these itself, since
|
|
124
135
|
* `_type` is an array there and every type-keyed correction matches no branch.
|
|
125
136
|
*/
|
|
@@ -148,6 +159,15 @@ interface SlideRelChart extends OptsChartData {
|
|
|
148
159
|
* via `<mc:AlternateContent>`. Set at define time from {@link isChartExType}.
|
|
149
160
|
*/
|
|
150
161
|
isChartEx?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* The pictures the chart part references (a chart or plot area's picture fill), each under the
|
|
164
|
+
* relationship id the chart part gives it. The media rel is the slide's, marked
|
|
165
|
+
* {@link SlideRelMedia.chartOwned}, so its `Target` is read at write time, after media dedupe.
|
|
166
|
+
*/
|
|
167
|
+
media?: Array<{
|
|
168
|
+
rId: number;
|
|
169
|
+
rel: SlideRelMedia;
|
|
170
|
+
}>;
|
|
151
171
|
}
|
|
152
172
|
interface SlideRel {
|
|
153
173
|
type: SlideObjectType;
|
|
@@ -155,7 +175,7 @@ interface SlideRel {
|
|
|
155
175
|
* Relationship target, stored **unescaped**. Every emitter escapes it on the way out
|
|
156
176
|
* (`gen/slide/object.ts`, `gen/slide/notes.ts`, and `read/opc/relationships.ts` for the
|
|
157
177
|
* append path). Escaping at definition time instead would double-escape on append,
|
|
158
|
-
* where the serializer escapes again
|
|
178
|
+
* where the serializer escapes again, so `&` in a hyperlink or online-video URL must
|
|
159
179
|
* arrive here verbatim.
|
|
160
180
|
*/
|
|
161
181
|
Target: string;
|
|
@@ -171,12 +191,12 @@ interface SlideRelMedia {
|
|
|
171
191
|
type: string;
|
|
172
192
|
opts?: MediaProps;
|
|
173
193
|
path?: string;
|
|
174
|
-
extn
|
|
175
|
-
data
|
|
194
|
+
extn: string;
|
|
195
|
+
data: string;
|
|
176
196
|
/**
|
|
177
197
|
* An `addMedia` poster frame the caller supplied no `cover` for, so it takes the library's
|
|
178
|
-
* default play-button artwork. `addMediaDefinition` pushes the rel with this flag and
|
|
179
|
-
* `data`; `encodeSlideMediaRels` fills the bytes in during the async media pass, behind the
|
|
198
|
+
* default play-button artwork. `addMediaDefinition` pushes the rel with this flag and an
|
|
199
|
+
* empty `data`; `encodeSlideMediaRels` fills the bytes in during the async media pass, behind the
|
|
180
200
|
* dynamic import that keeps the artwork out of every consumer's entry chunk. Every rel
|
|
181
201
|
* carrying it has its `data` resolved before any part is emitted.
|
|
182
202
|
*/
|
|
@@ -189,7 +209,7 @@ interface SlideRelMedia {
|
|
|
189
209
|
h: number;
|
|
190
210
|
};
|
|
191
211
|
/**
|
|
192
|
-
* Embedded OLE object part (`addOleObject`): the `.rels` `Type` URI to emit
|
|
212
|
+
* Embedded OLE object part (`addOleObject`): the `.rels` `Type` URI to emit: `.../package` for
|
|
193
213
|
* an embedded OPC package (xlsx/docx/pptx, themselves zips) or `.../oleObject` for a generic OLE
|
|
194
214
|
* server blob (ECMA-376 Part 1 §15.2.10). Present only on OLE payload rels, where it takes
|
|
195
215
|
* precedence over the image/audio/video branch in `slideObjectRelationsToXml` and `type` carries
|
|
@@ -198,7 +218,7 @@ interface SlideRelMedia {
|
|
|
198
218
|
*/
|
|
199
219
|
oleRelType?: string;
|
|
200
220
|
/**
|
|
201
|
-
* Embedded 3D model part (`addModel3d`): the `.rels` `Type` URI to emit
|
|
221
|
+
* Embedded 3D model part (`addModel3d`): the `.rels` `Type` URI to emit: the Microsoft
|
|
202
222
|
* `…/office/2017/06/relationships/model3d` type, which no `includes('image'|'audio'|'video')`
|
|
203
223
|
* sniff would ever reach. Present only on the `.glb` payload rel, where it takes precedence
|
|
204
224
|
* over the image/audio/video branch in `slideObjectRelationsToXml` and `type` carries the
|
|
@@ -206,8 +226,14 @@ interface SlideRelMedia {
|
|
|
206
226
|
* separate, perfectly ordinary image rel. Same escape hatch as {@link oleRelType}.
|
|
207
227
|
*/
|
|
208
228
|
model3dRelType?: string;
|
|
229
|
+
/**
|
|
230
|
+
* The picture of a chart's area fill, registered on the slide so the media pass loads, dedupes and
|
|
231
|
+
* writes its part like any other picture. The chart part references it (see
|
|
232
|
+
* {@link SlideRelChart.media}); the slide does not, so the slide's `.rels` leaves it out.
|
|
233
|
+
*/
|
|
234
|
+
chartOwned?: true;
|
|
209
235
|
rId: number;
|
|
210
|
-
/** Unescaped
|
|
236
|
+
/** Unescaped; see {@link SlideRel.Target}. Doubles as the zip entry name for embedded media. */
|
|
211
237
|
Target: string;
|
|
212
238
|
}
|
|
213
239
|
interface SlideObject {
|
|
@@ -229,6 +255,7 @@ interface SlideObject {
|
|
|
229
255
|
zoom?: ZoomInternal;
|
|
230
256
|
ole?: OleInternal;
|
|
231
257
|
model3d?: Model3dInternal;
|
|
258
|
+
_seeded?: boolean;
|
|
232
259
|
}
|
|
233
260
|
/**
|
|
234
261
|
* Resolved 3D-model payload carried on a {@link SlideObject} until `gen/slide/objects/model3d.ts`
|
|
@@ -239,7 +266,7 @@ interface SlideObject {
|
|
|
239
266
|
interface Model3dInternal {
|
|
240
267
|
/** rId of the embedded `.glb` part rel (see {@link SlideRelMedia.model3dRelType}). */
|
|
241
268
|
modelRid: number;
|
|
242
|
-
/** rId of the preview picture's image rel
|
|
269
|
+
/** rId of the preview picture's image rel, shared by `am3d:blip` and the `mc:Fallback` `p:pic`. */
|
|
243
270
|
previewRid: number;
|
|
244
271
|
/** `am3d:camera/am3d:pos` (`@x`/`@y`/`@z`). */
|
|
245
272
|
pos: {
|
|
@@ -270,9 +297,9 @@ interface OleInternal {
|
|
|
270
297
|
objectRid: number;
|
|
271
298
|
/** rId of the preview picture's image rel (`p:pic > a:blip@r:embed`). */
|
|
272
299
|
previewRid: number;
|
|
273
|
-
/** `p:oleObj@progId
|
|
300
|
+
/** `p:oleObj@progId`: the OLE server PowerPoint launches on double-click. */
|
|
274
301
|
progId: string;
|
|
275
|
-
/** `p:oleObj@name
|
|
302
|
+
/** `p:oleObj@name`: the object's kind as PowerPoint labels it (`Worksheet`, `Document`, …). */
|
|
276
303
|
name: string;
|
|
277
304
|
/** `p:oleObj@showAsIcon`; omitted when false, matching PowerPoint. */
|
|
278
305
|
showAsIcon: boolean;
|
|
@@ -349,6 +376,8 @@ interface PresSlideInternal extends SlideBaseProps, Slide {
|
|
|
349
376
|
_rId: number;
|
|
350
377
|
_slideLayout: SlideLayoutInternal | null;
|
|
351
378
|
_slideId: number;
|
|
379
|
+
/** Review comments; a slide always has the list, empty until `addComment` pushes one. */
|
|
380
|
+
_comments: SlideComment[];
|
|
352
381
|
/** Preset build animations on this slide, in play order (see {@link Slide.addAnimation}). */
|
|
353
382
|
_animations: AnimationProps[];
|
|
354
383
|
}
|
|
@@ -372,11 +401,9 @@ interface PresentationPropsInternal extends PresentationProps {
|
|
|
372
401
|
sections: SectionInternalProps[];
|
|
373
402
|
slideLayouts: SlideLayoutInternal[];
|
|
374
403
|
slides: PresSlideInternal[];
|
|
375
|
-
/** Author-side embedded fonts (see {@link
|
|
404
|
+
/** Author-side embedded fonts (see {@link PptxTs.embedFont}); empty when none. */
|
|
376
405
|
embeddedFonts: EmbeddedFont[];
|
|
377
406
|
}
|
|
378
|
-
//#endregion
|
|
379
|
-
//#region src/measure/text-fit.d.ts
|
|
380
407
|
/**
|
|
381
408
|
* PowerPoint single-spacing line pitch as a multiple of font size.
|
|
382
409
|
*
|
|
@@ -395,7 +422,7 @@ declare const MIN_FONT_SCALE_PCT = 25;
|
|
|
395
422
|
* Conservative safety factors applied by the shrink solver (not by the pure
|
|
396
423
|
* `measureHeightPt`). Raw `hmtx` advances summed without shaping still pack a line
|
|
397
424
|
* a little tighter than PowerPoint, which lays text out at a device DPI and rounds
|
|
398
|
-
* each glyph advance up
|
|
425
|
+
* each glyph advance up, so PowerPoint wraps marginally earlier and its fitted
|
|
399
426
|
* box is marginally taller. Inflating measured width and height by these factors
|
|
400
427
|
* makes the computed `fontScale` ≤ PowerPoint's across the calibration oracle
|
|
401
428
|
* (`test/read/autofit-calibration-oracle.test.ts`: 0 violations over the Aptos
|
|
@@ -420,7 +447,7 @@ interface FitRun {
|
|
|
420
447
|
* generator's option bags follow (`options-internal.ts`): these are measurement records, built in
|
|
421
448
|
* one place by `paragraphs.ts` and read in one place by the solver below, with `??` and
|
|
422
449
|
* truthiness. Nothing spreads or enumerates them, so a key holding `undefined` cannot mean
|
|
423
|
-
* anything different from an absent one
|
|
450
|
+
* anything different from an absent one, and the builder does produce every key on every run.
|
|
424
451
|
* Saying so is more honest than making the builder omit keys nothing distinguishes.
|
|
425
452
|
*/
|
|
426
453
|
interface FitParagraph {
|
|
@@ -440,7 +467,7 @@ interface FitBox {
|
|
|
440
467
|
* `false` when the frame does not wrap (`wrap:false` / `wrap="none"`): text lays
|
|
441
468
|
* out as one line per paragraph (no width-wrapping), and the shrink solver must
|
|
442
469
|
* additionally keep the widest line within `innerWidthPt`. A too-wide line
|
|
443
|
-
* overflows HORIZONTALLY
|
|
470
|
+
* overflows HORIZONTALLY. `normAutofit`'s vertical shrink never catches it, so
|
|
444
471
|
* without this check a non-wrapping line is never shrunk and spills out of the box
|
|
445
472
|
* in PowerPoint. Defaults to wrapping (`true`), so table cells and `measureText`
|
|
446
473
|
* are unaffected.
|
|
@@ -494,10 +521,10 @@ type ResizeOutcome = {
|
|
|
494
521
|
neededInnerHeightPt: number;
|
|
495
522
|
};
|
|
496
523
|
/**
|
|
497
|
-
* Inner height (points) the text needs at full size
|
|
524
|
+
* Inner height (points) the text needs at full size: the value to bake into the
|
|
498
525
|
* shape's `a:ext/@cy` for `fit: 'resize'` (`spAutoFit`). Unlike shrink, resize has
|
|
499
526
|
* **no safety net**: an under-estimate overflows (there is no text scaling
|
|
500
|
-
* fallback), so this errs **tall
|
|
527
|
+
* fallback), so this errs **tall**. Width is inflated (earlier wrap ⇒ more lines)
|
|
501
528
|
* and the laid-out height by the calibrated height factor, so the computed `cy` is
|
|
502
529
|
* ≥ PowerPoint's and ≥ the LibreOffice-rendered height across the resize oracle.
|
|
503
530
|
*/
|
|
@@ -507,14 +534,12 @@ declare function solveResize(paragraphs: FitParagraph[], box: FitBox, resolve: M
|
|
|
507
534
|
* Width and height both re-measured per scale. Conservative: because the model
|
|
508
535
|
* over-estimates, the returned scale is ≤ PowerPoint's and the text never overflows.
|
|
509
536
|
*
|
|
510
|
-
* `lnSpcReduction` is left at 0
|
|
537
|
+
* `lnSpcReduction` is left at 0: dropping `fontScale` alone is provably
|
|
511
538
|
* conservative (PowerPoint trades line-spacing reduction to keep the font *larger*,
|
|
512
539
|
* so a reduction-free fit is always ≤ PowerPoint's scale). The reduction ramp
|
|
513
540
|
* PowerPoint applies is recorded in `docs/contributing/design/text-fit.md`.
|
|
514
541
|
*/
|
|
515
542
|
declare function solveShrink(paragraphs: FitParagraph[], box: FitBox, resolve: MetricsResolver): ShrinkOutcome;
|
|
516
|
-
//#endregion
|
|
517
|
-
//#region src/measure/font-metrics.d.ts
|
|
518
543
|
/** Per-(face,bold,italic) advance-width source backed by a parsed font file. */
|
|
519
544
|
interface FontMetrics {
|
|
520
545
|
/** Font design units per em (advances are in these units). */
|
|
@@ -536,7 +561,7 @@ interface FontMetrics {
|
|
|
536
561
|
/**
|
|
537
562
|
* Shared, font-independent `FontMetrics` used when a named face has no registered
|
|
538
563
|
* metrics but the deck has opted into measured fit (some other face is registered).
|
|
539
|
-
* Approximate but conservative
|
|
564
|
+
* Approximate but conservative; see `heuristicCharRatio`. A deck with no
|
|
540
565
|
* registered metrics at all does not engage measured fit, so this never fires there.
|
|
541
566
|
*/
|
|
542
567
|
declare function getHeuristicFontMetrics(): FontMetrics;
|
|
@@ -587,7 +612,7 @@ declare class FontMetricsRegistry {
|
|
|
587
612
|
* Coverage of code point `cp` for `face`, read from the registered font's cmap:
|
|
588
613
|
* `true`/`false` when a variant of `face` is registered (see {@link get} for the
|
|
589
614
|
* exact→regular→any-variant fallback), or `undefined` when the face has **no**
|
|
590
|
-
* registered metrics
|
|
615
|
+
* registered metrics: "unknown", deliberately distinct from a `false`
|
|
591
616
|
* "registered but not covered". A coverage audit must not treat an unregistered
|
|
592
617
|
* face as fully covered, so callers get `undefined` here rather than the per-face
|
|
593
618
|
* {@link FontMetrics.hasCodepoint} boolean (which, for the heuristic fallback,
|
|
@@ -608,6 +633,5 @@ declare class FontMetricsRegistry {
|
|
|
608
633
|
* no `fontFace` at all resolves to `undefined`, which the callers treat as unmeasurable.
|
|
609
634
|
*/
|
|
610
635
|
declare function makeRegistryResolver(registry: FontMetricsRegistry, onHeuristic?: (face: string) => void): MetricsResolver;
|
|
611
|
-
//#endregion
|
|
612
636
|
export { SlideObject as A, solveShrink as C, SectionInternalProps as D, PresentationPropsInternal as E, SlideRelChart as M, SlideRelMedia as N, SlideLayoutInternal as O, solveResize as S, PresSlideInternal as T, ShrinkOutcome as _, makeRegistryResolver as a, measureHeightPt as b, FitBox as c, HEIGHT_SAFETY_FACTOR as d, LayoutResult as f, SINGLE_LINE_PITCH as g, ResizeOutcome as h, getHeuristicFontMetrics as i, SlideRel as j, SlideMasterInternal as k, FitParagraph as l, MetricsResolver as m, FontMetricsRegistry as n, parseFontMetrics as o, MIN_FONT_SCALE_PCT as p, ParseFontMetricsOptions as r, FONT_SCALE_STEP_PCT as s, FontMetrics as t, FitRun as u, ShrinkResult as v, ObjectOptionsInternal as w, measureLayout as x, WIDTH_SAFETY_FACTOR as y };
|
|
613
|
-
//# sourceMappingURL=font-metrics-
|
|
637
|
+
//# sourceMappingURL=font-metrics-DTppw4t3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-metrics-DTppw4t3.d.ts","names":[],"sources":["../src/types/internal.ts","../src/measure/text-fit.ts","../src/measure/font-metrics.ts"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { u as warn } from "./entry-errors-JMthgJ2g.js";
|
|
2
|
+
// src/gen/table/spans.ts
|
|
3
3
|
/**
|
|
4
4
|
* The largest `colspan`/`rowspan` this library will honour.
|
|
5
5
|
*
|
|
@@ -14,14 +14,14 @@ const MAX_TABLE_SPAN = 1e3;
|
|
|
14
14
|
* Validate one cell's `colspan`/`rowspan`, warning and falling back to `1` when it is not a whole
|
|
15
15
|
* number in `1..MAX_TABLE_SPAN`.
|
|
16
16
|
*
|
|
17
|
-
* `undefined` is the common case and means "no span"
|
|
17
|
+
* `undefined` is the common case and means "no span": it warns about nothing and returns `1`.
|
|
18
18
|
* Everything else is caller error: `NaN`, a negative, a fraction and a span past the ceiling all
|
|
19
19
|
* describe a table that cannot be built (a fractional span silently truncates, a negative one
|
|
20
20
|
* shifts every column after it, an enormous one is the allocation above).
|
|
21
21
|
*
|
|
22
22
|
* The parameter is typed `unknown` because this is also **the** reading of a span for the six
|
|
23
23
|
* sites that consume one after {@link withCheckedSpans} has run. Those had six different
|
|
24
|
-
* coercions
|
|
24
|
+
* coercions (`Number(x) ? … : 1`, `Math.max(1, Number(x) || 1)`, `x ?? 1`), which agreed only
|
|
25
25
|
* on the values that were already valid, and one of them let a non-numeric span reach a grid
|
|
26
26
|
* column count as `NaN`. Reading a span through one function is what stops them drifting apart
|
|
27
27
|
* again if the up-front check is ever moved.
|
|
@@ -45,7 +45,7 @@ function resolveSpan(value, kind) {
|
|
|
45
45
|
* Re-clone `rows` with every out-of-range `colspan`/`rowspan` corrected to `1`.
|
|
46
46
|
*
|
|
47
47
|
* Runs once, up front, so the column count, the `_hmerge`/`_vmerge` dummies, the auto-pager's
|
|
48
|
-
* grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number
|
|
48
|
+
* grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number. Checking at
|
|
49
49
|
* each of those sites instead would warn several times per bad cell and could still disagree.
|
|
50
50
|
*
|
|
51
51
|
* A cell whose spans are fine is passed through by identity, not copied: `_spanOrigin` links the
|
|
@@ -74,27 +74,25 @@ function withCheckedSpans(rows) {
|
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
|
-
* Whether
|
|
78
|
-
*
|
|
77
|
+
* Whether a cell carries a hyperlink, on the cell itself or on any run of its `text` when that
|
|
78
|
+
* is a run array.
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
80
|
+
* The table's black text default is direct formatting on the cell's runs, so on a linked cell it
|
|
81
|
+
* would paint the words *after* the link black rather than letting them follow the link colour.
|
|
82
|
+
* The emitter stands the default down for such a cell, and only for it: the test used to be
|
|
83
|
+
* table-wide, so one link stripped the default from every cell in the grid and a cell's output
|
|
84
|
+
* depended on its neighbours (#101). Before that it was
|
|
85
|
+
* `JSON.stringify({ arrRows }).includes('hyperlink')`, which matched the literal word anywhere in
|
|
86
|
+
* the grid's *content*.
|
|
87
|
+
* @param cell - the cell, or a hole in the grid
|
|
87
88
|
*/
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return cell.text.some((run) => !!run?.options?.hyperlink);
|
|
94
|
-
}));
|
|
89
|
+
function cellHasHyperlink(cell) {
|
|
90
|
+
if (!cell) return false;
|
|
91
|
+
if (cell.options?.hyperlink) return true;
|
|
92
|
+
if (!Array.isArray(cell.text)) return false;
|
|
93
|
+
return cell.text.some((run) => !!run?.options?.hyperlink);
|
|
95
94
|
}
|
|
96
|
-
|
|
97
|
-
//#region src/gen/table/grid.ts
|
|
95
|
+
// src/gen/table/grid.ts
|
|
98
96
|
/**
|
|
99
97
|
* How many grid columns a table has: the sum of the first row's colspans.
|
|
100
98
|
*
|
|
@@ -181,7 +179,6 @@ function* walkTableGrid(rows, numCols) {
|
|
|
181
179
|
occupancy.endRow();
|
|
182
180
|
}
|
|
183
181
|
}
|
|
184
|
-
|
|
185
|
-
export { resolveSpan as a, MAX_TABLE_SPAN as i, tableColCount as n, tableHasHyperlink as o, walkTableGrid as r, withCheckedSpans as s, createRowSpanOccupancy as t };
|
|
182
|
+
export { cellHasHyperlink as a, MAX_TABLE_SPAN as i, tableColCount as n, resolveSpan as o, walkTableGrid as r, withCheckedSpans as s, createRowSpanOccupancy as t };
|
|
186
183
|
|
|
187
|
-
//# sourceMappingURL=grid-
|
|
184
|
+
//# sourceMappingURL=grid-DUIMxjfl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid-DUIMxjfl.js","names":[],"sources":["../src/gen/table/spans.ts","../src/gen/table/grid.ts"],"sourcesContent":["/**\n * pptx-ts: table `colspan`/`rowspan` range checking.\n *\n * The spans decide two allocations, on two different paths, and both used to trust the caller:\n * the merge grid's `new Array(colspan - 1)` in `gen/slide/objects/table.ts`, and the auto-pager's\n * per-column depth array, sized from a column count that is a sum of colspans\n * (`gen/table/autopage.ts`). `new Array(4294967294).fill(undefined)` is not a slow path: V8\n * aborts on the allocation and there is no exception to catch. So a table built with\n * `autoPage: true` and one without needed the same guard, which is why it lives here rather than\n * in either of them.\n *\n * This is the write side, so the bad number comes from the calling program rather than from a\n * hostile file, which makes it far less serious than the read-side twin in the chart point caches\n * (`read/oxml/point-cache.ts`, the model this copies). It is still the project's stated line: warn\n * on out-of-range input rather than emit a degenerate result.\n */\n\nimport type { TableCellInternal } from '../../types/internal.js'\nimport { warn } from '../../diagnostics.js'\n\n/**\n * The largest `colspan`/`rowspan` this library will honour.\n *\n * Unlike the read side's point-cache ceiling there is no format number to borrow: `a:tc@gridSpan`\n * is a bare `xsd:int`. So this is a sanity bound rather than a schema one, and it is set an order\n * of magnitude past PowerPoint's own maximum table (its Insert Table dialog stops at 75 columns\n * and 75 rows), which is what makes it something no authored table can reach. What it stops is\n * the other end, where the allocation takes the host process with it.\n */\nexport const MAX_TABLE_SPAN = 1000\n\n/**\n * Validate one cell's `colspan`/`rowspan`, warning and falling back to `1` when it is not a whole\n * number in `1..MAX_TABLE_SPAN`.\n *\n * `undefined` is the common case and means \"no span\": it warns about nothing and returns `1`.\n * Everything else is caller error: `NaN`, a negative, a fraction and a span past the ceiling all\n * describe a table that cannot be built (a fractional span silently truncates, a negative one\n * shifts every column after it, an enormous one is the allocation above).\n *\n * The parameter is typed `unknown` because this is also **the** reading of a span for the six\n * sites that consume one after {@link withCheckedSpans} has run. Those had six different\n * coercions (`Number(x) ? … : 1`, `Math.max(1, Number(x) || 1)`, `x ?? 1`), which agreed only\n * on the values that were already valid, and one of them let a non-numeric span reach a grid\n * column count as `NaN`. Reading a span through one function is what stops them drifting apart\n * again if the up-front check is ever moved.\n * @param value - the raw option value, as the caller wrote it\n * @param kind - `'colspan'` or `'rowspan'`, for the diagnostic\n * @returns the span to use, at least 1\n */\nexport function resolveSpan(value: unknown, kind: 'colspan' | 'rowspan'): number {\n\tif (value === undefined || value === null || value === '') return 1\n\tif (typeof value !== 'number') {\n\t\twarn(\n\t\t\t'table/span-out-of-range',\n\t\t\t`table cell: ${kind} must be a whole number between 1 and ${MAX_TABLE_SPAN}; got ${String(value)}. Using 1.`\n\t\t)\n\t\treturn 1\n\t}\n\tif (!Number.isInteger(value) || value < 1 || value > MAX_TABLE_SPAN) {\n\t\twarn(\n\t\t\t'table/span-out-of-range',\n\t\t\t`table cell: ${kind} must be a whole number between 1 and ${MAX_TABLE_SPAN}; got ${String(value)}. Using 1.`\n\t\t)\n\t\treturn 1\n\t}\n\treturn value\n}\n\n/**\n * Re-clone `rows` with every out-of-range `colspan`/`rowspan` corrected to `1`.\n *\n * Runs once, up front, so the column count, the `_hmerge`/`_vmerge` dummies, the auto-pager's\n * grid and the emitted `gridSpan`/`rowSpan` attributes all read the same number. Checking at\n * each of those sites instead would warn several times per bad cell and could still disagree.\n *\n * A cell whose spans are fine is passed through by identity, not copied: `_spanOrigin` links the\n * merge dummies back to the origin *object*, and the all-valid path is every real table, which\n * must stay allocation-free and byte-identical.\n * @param rows - the rows to check; row arrays are never mutated\n * @returns the same rows with only the offending cells replaced\n */\nexport function withCheckedSpans(rows: TableCellInternal[][]): TableCellInternal[][] {\n\treturn rows.map((cells) =>\n\t\tcells.map((cell) => {\n\t\t\tconst opts = cell?.options\n\t\t\tif (!opts) return cell\n\t\t\tconst colspan = resolveSpan(opts.colspan, 'colspan')\n\t\t\tconst rowspan = resolveSpan(opts.rowspan, 'rowspan')\n\t\t\tconst colspanOk = opts.colspan === undefined || opts.colspan === colspan\n\t\t\tconst rowspanOk = opts.rowspan === undefined || opts.rowspan === rowspan\n\t\t\tif (colspanOk && rowspanOk) return cell\n\t\t\treturn {\n\t\t\t\t...cell,\n\t\t\t\toptions: {\n\t\t\t\t\t...opts,\n\t\t\t\t\t...(opts.colspan === undefined ? {} : { colspan }),\n\t\t\t\t\t...(opts.rowspan === undefined ? {} : { rowspan }),\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\t)\n}\n\n/**\n * Whether a cell carries a hyperlink, on the cell itself or on any run of its `text` when that\n * is a run array.\n *\n * The table's black text default is direct formatting on the cell's runs, so on a linked cell it\n * would paint the words *after* the link black rather than letting them follow the link colour.\n * The emitter stands the default down for such a cell, and only for it: the test used to be\n * table-wide, so one link stripped the default from every cell in the grid and a cell's output\n * depended on its neighbours (#101). Before that it was\n * `JSON.stringify({ arrRows }).includes('hyperlink')`, which matched the literal word anywhere in\n * the grid's *content*.\n * @param cell - the cell, or a hole in the grid\n */\nexport function cellHasHyperlink(cell: TableCellInternal | undefined): boolean {\n\tif (!cell) return false\n\tif (cell.options?.hyperlink) return true\n\tif (!Array.isArray(cell.text)) return false\n\treturn cell.text.some((run) => !!run?.options?.hyperlink)\n}\n","/**\n * pptx-ts: a table's cell grid.\n *\n * Rows arrive lopsided -- `row1: [A, B, C]`, `row2: [D]` when the first two columns are held by\n * a rowspan from above -- so a cell's position in its row array is not its column. Four places\n * needed to know where a cell actually lands (the auto-pager, twice, in one function; the\n * measured-fit pass; the table emitter) and each walked the grid itself, tracking rowspan\n * occupancy in its own array with its own off-by-one convention.\n *\n * This is that traversal, once. It lives beside {@link resolveSpan} rather than in `measure/`\n * because the grid is a fact about the authored table, not a measurement of it -- the pager and\n * the emitter want it as much as the fitter does, and `measure/table-fit.ts` was already\n * reaching into `gen/table/` for the span reader it is built on.\n */\n\nimport type { TableCellInternal } from '../../types/internal.js'\nimport { resolveSpan } from './spans.js'\n\n/**\n * How many grid columns a table has: the sum of the first row's colspans.\n *\n * The count cannot come from `rows[0].length` -- a colspan makes one cell occupy several\n * columns -- and it is read off the first row alone, which is the writer's standing rule: a\n * later row wider than the first is ragged input, and the grid it is measured, paged and\n * emitted against is the one `a:tblGrid` declares.\n */\nexport function tableColCount(rows: TableCellInternal[][]): number {\n\tconst first = rows[0]\n\treturn first ? first.reduce((n, c) => n + resolveSpan(c?.options?.colspan, 'colspan'), 0) : 0\n}\n\n/** The bookkeeping a row-major grid walk needs to route around rowspans; see {@link createRowSpanOccupancy}. */\ninterface RowSpanOccupancy {\n\t/** The first column at or after `col` that no rowspan from above is holding. */\n\tnextFree: (col: number) => number\n\t/** Record that `colSpan` columns from `col` are held for `rowSpan` rows, this one included. */\n\thold: (col: number, colSpan: number, rowSpan: number) => void\n\t/** Close the current row: every held column has one fewer row left to hold. */\n\tendRow: () => void\n}\n\n/**\n * The rowspan-occupancy rule, stated once.\n *\n * A row states only the cells it *starts*: a column held by a `rowspan` from above is filled\n * without the row mentioning it, so a cell's position in its row array is not its column. Tracking\n * that is three operations -- skip what is held, mark what this cell holds, age the holds by a row\n * -- and getting the ageing off by one silently shifts every column below.\n *\n * It has two callers asking different questions on different input. {@link walkTableGrid} places\n * authored `TableCell`s into a grid whose width `a:tblGrid` already declares; `measureGridColumns`\n * (`gen/table/html-dom.ts`) measures how wide an imported HTML table's grid *is*, reading spans off\n * HTML attributes, with no width known up front. Neither can be expressed as the other without\n * giving one of them a mode it does not want -- but the rule underneath is the same rule, and it is\n * here rather than in both.\n *\n * The array is sparse and unbounded on purpose: a caller that knows its width clamps what it\n * `hold`s, and then nothing past that width is ever held, so an unbounded `nextFree` returns the\n * same answer a bounded one would.\n */\nexport function createRowSpanOccupancy(): RowSpanOccupancy {\n\t// held[c] = rows still covered by a rowspan started at or above the current row.\n\tconst held: number[] = []\n\treturn {\n\t\tnextFree(col) {\n\t\t\tlet free = col\n\t\t\twhile ((held[free] ?? 0) > 0) free++\n\t\t\treturn free\n\t\t},\n\t\thold(col, colSpan, rowSpan) {\n\t\t\tfor (let idx = 0; idx < colSpan; idx++) held[col + idx] = rowSpan\n\t\t},\n\t\tendRow() {\n\t\t\tfor (let idx = 0; idx < held.length; idx++) {\n\t\t\t\tconst rows = held[idx] ?? 0\n\t\t\t\tif (rows > 0) held[idx] = rows - 1\n\t\t\t}\n\t\t},\n\t}\n}\n\n/** A placed (non-merged origin) cell yielded by {@link walkTableGrid}. */\nexport interface GridPlacement {\n\tcell: TableCellInternal\n\t/** Zero-based grid row of the cell's top-left origin. */\n\trow: number\n\t/** Zero-based grid column of the cell's top-left origin. */\n\tcol: number\n\t/** Rows spanned, clamped to the available rows. */\n\trowSpan: number\n\t/** Columns spanned, clamped to the grid width. */\n\tcolSpan: number\n}\n\n/**\n * Walk a table's cell grid in row-major order, resolving each authored cell to its\n * grid origin (`row`/`col`) and clamped colspan/rowspan. Tracks rowspan occupancy so\n * a cell never lands beneath one spanned from above. This is the single traversal the\n * auto-pager, the measured-fit shrink pass, {@link computeTableLayout} and the table emitter's\n * merge grid all read, so the table that is paged and measured is the table that is written.\n *\n * A cell that starts past the last grid column is not yielded: a row longer than the first is\n * ragged input, and the grid is the one `a:tblGrid` declares.\n */\nexport function* walkTableGrid(rows: TableCellInternal[][], numCols: number): Generator<GridPlacement> {\n\tconst occupancy = createRowSpanOccupancy()\n\tfor (let r = 0; r < rows.length; r++) {\n\t\tconst row = rows[r]\n\t\tif (!row) continue\n\t\tlet col = 0\n\t\tfor (const cell of row) {\n\t\t\tcol = occupancy.nextFree(col)\n\t\t\tif (col >= numCols) break\n\t\t\tconst colspan = resolveSpan(cell?.options?.colspan, 'colspan')\n\t\t\tconst rowspan = Math.min(resolveSpan(cell?.options?.rowspan, 'rowspan'), rows.length - r)\n\t\t\tconst colStart = col\n\t\t\t// Clamped to the declared width, which is also what keeps `nextFree` unbounded and still\n\t\t\t// correct: nothing past `numCols` is ever held, so it never has a reason to walk past it.\n\t\t\tconst colEnd = Math.min(colStart + colspan, numCols)\n\t\t\toccupancy.hold(colStart, colEnd - colStart, rowspan)\n\t\t\tcol = colEnd\n\t\t\tyield { cell, row: r, col: colStart, rowSpan: rowspan, colSpan: colEnd - colStart }\n\t\t}\n\t\toccupancy.endRow()\n\t}\n}\n"],"mappings":"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"}
|