pptx-ts 3.7.0 → 4.0.1

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.
Files changed (136) hide show
  1. package/README.md +116 -269
  2. package/dist/autopage-odPz7zZO.js +536 -0
  3. package/dist/autopage-odPz7zZO.js.map +1 -0
  4. package/dist/binary-string-CKVAYI3M.js +24 -0
  5. package/dist/binary-string-CKVAYI3M.js.map +1 -0
  6. package/dist/body-insets-Dw_BeWD_.js +54 -0
  7. package/dist/body-insets-Dw_BeWD_.js.map +1 -0
  8. package/dist/browser.d.ts +29 -9
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +41 -14
  11. package/dist/browser.js.map +1 -1
  12. package/dist/clip-Bl01BPcN.d.ts +67 -0
  13. package/dist/clip-Bl01BPcN.d.ts.map +1 -0
  14. package/dist/diagnostics-D8ot4Ei7.d.ts +244 -0
  15. package/dist/diagnostics-D8ot4Ei7.d.ts.map +1 -0
  16. package/dist/embedded-fonts-DarT9aoa.d.ts +20 -0
  17. package/dist/embedded-fonts-DarT9aoa.d.ts.map +1 -0
  18. package/dist/entry-compose-DCnvBZz2.d.ts +1046 -0
  19. package/dist/entry-compose-DCnvBZz2.d.ts.map +1 -0
  20. package/dist/{enums-CvRYniUA.d.ts → enums-BUKTUB6V.d.ts} +21 -13
  21. package/dist/{enums-CvRYniUA.d.ts.map → enums-BUKTUB6V.d.ts.map} +1 -1
  22. package/dist/{errors-Bvln0H-7.js → errors-C4oENPcu.js} +92 -2
  23. package/dist/errors-C4oENPcu.js.map +1 -0
  24. package/dist/families.d.ts +260 -0
  25. package/dist/families.d.ts.map +1 -0
  26. package/dist/families.js +57 -0
  27. package/dist/families.js.map +1 -0
  28. package/dist/{fit-BKs0zxMI.js → fit-Cb7naFj6.js} +249 -167
  29. package/dist/fit-Cb7naFj6.js.map +1 -0
  30. package/dist/font-metrics-v5fn7s7e.d.ts +613 -0
  31. package/dist/font-metrics-v5fn7s7e.d.ts.map +1 -0
  32. package/dist/grid-DikTjFey.js +187 -0
  33. package/dist/grid-DikTjFey.js.map +1 -0
  34. package/dist/{html-dom-B0I0QSbU.js → html-dom-Iuog2wdK.js} +121 -91
  35. package/dist/html-dom-Iuog2wdK.js.map +1 -0
  36. package/dist/html.d.ts +6 -6
  37. package/dist/html.d.ts.map +1 -1
  38. package/dist/html.js +7 -6
  39. package/dist/html.js.map +1 -1
  40. package/dist/image-size-CvN2iCA4.js +1611 -0
  41. package/dist/image-size-CvN2iCA4.js.map +1 -0
  42. package/dist/index.d.ts +24 -10
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +31 -11
  45. package/dist/index.js.map +1 -1
  46. package/dist/inspect.d.ts +40 -31
  47. package/dist/inspect.d.ts.map +1 -1
  48. package/dist/inspect.js +40 -48
  49. package/dist/inspect.js.map +1 -1
  50. package/dist/math.d.ts +7 -5
  51. package/dist/math.d.ts.map +1 -1
  52. package/dist/math.js +16 -7
  53. package/dist/math.js.map +1 -1
  54. package/dist/measure.d.ts +12 -225
  55. package/dist/measure.d.ts.map +1 -1
  56. package/dist/measure.js +3 -3
  57. package/dist/node.d.ts +22 -8
  58. package/dist/node.d.ts.map +1 -1
  59. package/dist/node.js +27 -7
  60. package/dist/node.js.map +1 -1
  61. package/dist/notes-Dh12JAbn.js +3264 -0
  62. package/dist/notes-Dh12JAbn.js.map +1 -0
  63. package/dist/options-internal-WqgMf720.js +43 -0
  64. package/dist/options-internal-WqgMf720.js.map +1 -0
  65. package/dist/{package-CaOLXSNi.d.ts → package-J49Ck6S2.d.ts} +27 -12
  66. package/dist/package-J49Ck6S2.d.ts.map +1 -0
  67. package/dist/playbtn-CUqQdoDf.js +22 -0
  68. package/dist/playbtn-CUqQdoDf.js.map +1 -0
  69. package/dist/{slide-ZqAdVvHV.d.ts → pres-C6qgOFAa.d.ts} +1021 -1423
  70. package/dist/pres-C6qgOFAa.d.ts.map +1 -0
  71. package/dist/{presentation-DrJtj3-C.js → presentation-DGYlAWhl.js} +3208 -2727
  72. package/dist/presentation-DGYlAWhl.js.map +1 -0
  73. package/dist/{presentation-types-CDjScsev.d.ts → presentation-types-8jLQHI4M.d.ts} +1070 -683
  74. package/dist/presentation-types-8jLQHI4M.d.ts.map +1 -0
  75. package/dist/read.d.ts +9 -9
  76. package/dist/read.d.ts.map +1 -1
  77. package/dist/read.js +4 -4
  78. package/dist/script.d.ts +80 -66
  79. package/dist/script.d.ts.map +1 -1
  80. package/dist/script.js +2399 -1139
  81. package/dist/script.js.map +1 -1
  82. package/dist/{shapes-BemroU-z.js → shapes-re0KyQk_.js} +2807 -1609
  83. package/dist/shapes-re0KyQk_.js.map +1 -0
  84. package/dist/slide-Dx2ZeVZ6.d.ts +1256 -0
  85. package/dist/slide-Dx2ZeVZ6.d.ts.map +1 -0
  86. package/dist/slide-size-BalTjFuv.js +88 -0
  87. package/dist/slide-size-BalTjFuv.js.map +1 -0
  88. package/dist/{units-internal-Dg95w_YD.js → table-cell-margins-EVg0EwxT.js} +235 -273
  89. package/dist/table-cell-margins-EVg0EwxT.js.map +1 -0
  90. package/dist/table-dom-BTDP3lEP.js +21 -0
  91. package/dist/table-dom-BTDP3lEP.js.map +1 -0
  92. package/dist/text-anchor-CrYXAfUu.js +176 -0
  93. package/dist/text-anchor-CrYXAfUu.js.map +1 -0
  94. package/dist/text-sN64Otf_.js +3980 -0
  95. package/dist/text-sN64Otf_.js.map +1 -0
  96. package/dist/transition-speed-kUEWDWTx.js +14 -0
  97. package/dist/transition-speed-kUEWDWTx.js.map +1 -0
  98. package/dist/units-internal-XJlf-hOl.js +649 -0
  99. package/dist/units-internal-XJlf-hOl.js.map +1 -0
  100. package/dist/zip-C0leZZMj.d.ts +67 -0
  101. package/dist/zip-C0leZZMj.d.ts.map +1 -0
  102. package/dist/zip-CKd8ihcf.js +177 -0
  103. package/dist/zip-CKd8ihcf.js.map +1 -0
  104. package/dist/zip.d.ts +3 -68
  105. package/dist/zip.js +3 -163
  106. package/dist/zoom-DPUHh85d.js +8865 -0
  107. package/dist/zoom-DPUHh85d.js.map +1 -0
  108. package/package.json +106 -19
  109. package/skills/ts-pptx-upstream/SKILL.md +58 -57
  110. package/dist/autopage-DkjYZUFD.js +0 -423
  111. package/dist/autopage-DkjYZUFD.js.map +0 -1
  112. package/dist/diagnostics-DfBdDHre.d.ts +0 -829
  113. package/dist/diagnostics-DfBdDHre.d.ts.map +0 -1
  114. package/dist/errors-Bvln0H-7.js.map +0 -1
  115. package/dist/errors-PflMPWBn.d.ts +0 -182
  116. package/dist/errors-PflMPWBn.d.ts.map +0 -1
  117. package/dist/fit-BKs0zxMI.js.map +0 -1
  118. package/dist/html-dom-B0I0QSbU.js.map +0 -1
  119. package/dist/namespaces-BVnNu7sg.js +0 -666
  120. package/dist/namespaces-BVnNu7sg.js.map +0 -1
  121. package/dist/notes-CJFJaG6M.js +0 -1724
  122. package/dist/notes-CJFJaG6M.js.map +0 -1
  123. package/dist/package-CaOLXSNi.d.ts.map +0 -1
  124. package/dist/pres-BcBR3CSM.d.ts +0 -202
  125. package/dist/pres-BcBR3CSM.d.ts.map +0 -1
  126. package/dist/presentation-DrJtj3-C.js.map +0 -1
  127. package/dist/presentation-types-CDjScsev.d.ts.map +0 -1
  128. package/dist/shapes-BemroU-z.js.map +0 -1
  129. package/dist/slide-ZqAdVvHV.d.ts.map +0 -1
  130. package/dist/text-B8SLEaZx.js +0 -11327
  131. package/dist/text-B8SLEaZx.js.map +0 -1
  132. package/dist/units-1kRzYShk.js +0 -231
  133. package/dist/units-1kRzYShk.js.map +0 -1
  134. package/dist/units-internal-Dg95w_YD.js.map +0 -1
  135. package/dist/zip.d.ts.map +0 -1
  136. package/dist/zip.js.map +0 -1
@@ -0,0 +1,536 @@
1
+ import { l as warn } from "./errors-C4oENPcu.js";
2
+ import { C as usableTableWidthEmu, R as DEF_SLIDE_MARGIN_IN, _ as resolveCellMarginsInches, b as resolveTableColWidthsEmu, c as inch2Emu, d as marginToEmu, m as pinnedRowHeightInches, s as getSmartParseNumber, t as autoPageLineHeightEmu, y as resolveSlideMarginsInches } from "./units-internal-XJlf-hOl.js";
3
+ import { F as EMU_PER_INCH } from "./table-cell-margins-EVg0EwxT.js";
4
+ import { a as resolveSpan, n as tableColCount, r as walkTableGrid, s as withCheckedSpans } from "./grid-DikTjFey.js";
5
+ //#region src/gen/table/autopage.ts
6
+ /**
7
+ * A cell for the pager's working grid, carrying the source cell's options only when it has some.
8
+ *
9
+ * Every one of these used to be an inline `{ …, options: cell.options }`, which put an `options`
10
+ * key holding `undefined` on a cell whose source had none. Readers cannot see the difference —
11
+ * they all go through `cell.options?.…` — but a `TableCellProps` bag *is* spread in
12
+ * `gen/define/table.ts` (`{ ...colDef, ...headerRow, ...cell.options }`), where the two states
13
+ * are not the same thing. So the model keeps one spelling of absent.
14
+ * @param text - the cell's content, a string or the run list the pager is accumulating
15
+ * @param options - the source cell's options, if it had any
16
+ */
17
+ function workingCell(text, options) {
18
+ return options === void 0 ? {
19
+ _type: "tablecell",
20
+ text
21
+ } : {
22
+ _type: "tablecell",
23
+ text,
24
+ options
25
+ };
26
+ }
27
+ /**
28
+ * Break cell text into lines based upon table column width (e.g.: Magic Happens Here(tm))
29
+ *
30
+ * `charWeight` arrives as an argument rather than being read off `cell.options` because the
31
+ * caller used to *stamp* it there: the table's weight was written onto the caller's own cell
32
+ * options bag, or `delete`d from it when the table stated none. That mutated caller input --
33
+ * which the chart path has a dedicated guard against -- and it made the option's precedence
34
+ * differ by call site: the row-height probe read the cell's own value while the main loop had
35
+ * just overwritten it with the table's. Both callers now resolve it the same way, and the more
36
+ * specific statement wins, as it does everywhere else in this codebase.
37
+ *
38
+ * `fontSizePt` arrives resolved for the same reason. This read `cell.options.fontSize` or the
39
+ * library default and never the table's `fontSize`, while the row's line height and the emitted
40
+ * `sz` both used the table's. A table of 24pt text was wrapped as if it were 12pt, so the pager
41
+ * counted about half the lines and rows ran off the bottom of each page.
42
+ * @param {TableCellInternal} cell - table cell
43
+ * @param {number} colWidth - table column width (inches)
44
+ * @param {number} fontSizePt - resolved font size: the cell's, else the table's, else the default
45
+ * @param {number} charWeight - resolved `autoPageCharWeight`: the cell's, else the table's, else 0
46
+ * @param {boolean} [verbose] - dump the four wrapping stages; carries `addTable({ verbose })`
47
+ * down, which is the only stage of the pager that flag did not reach
48
+ * @return {TableRowInternal[]} - cell's text objects grouped into lines
49
+ */
50
+ function parseTextToLines(cell, colWidth, fontSizePt, charWeight, verbose) {
51
+ const FOCO = 2.3 + charWeight;
52
+ const CPL = Math.floor(colWidth * 72) / (fontSizePt / FOCO);
53
+ if (verbose) console.log(`[0/4] colWidth=${colWidth}in fontSize=${fontSizePt} FOCO=${FOCO} CPL=${CPL}`);
54
+ const parsedLines = [];
55
+ let inputCells = [];
56
+ const inputLines1 = [];
57
+ const inputLines2 = [];
58
+ /**
59
+ * EX INPUTS: `cell.text`
60
+ * - string....: "Account Name Column"
61
+ * - object....: { text:"Account Name Column" }
62
+ * - object[]..: [{ text:"Account Name", options:{ bold:true } }, { text:" Column" }]
63
+ * - object[]..: [{ text:"Account Name", options:{ breakLine:true } }, { text:"Input" }]
64
+ */
65
+ /**
66
+ * EX OUTPUTS:
67
+ * - string....: [{ text:"Account Name Column" }]
68
+ * - object....: [{ text:"Account Name Column" }]
69
+ * - object[]..: [{ text:"Account Name", options:{ breakLine:true } }, { text:"Input" }]
70
+ * - object[]..: [{ text:"Account Name", options:{ breakLine:true } }, { text:"Input" }]
71
+ */
72
+ if (cell.text && cell.text.toString().trim().length === 0) inputCells.push({
73
+ _type: "tablecell",
74
+ text: " "
75
+ });
76
+ else if (typeof cell.text === "number" || typeof cell.text === "string") inputCells.push({
77
+ _type: "tablecell",
78
+ text: (cell.text || "").toString().trim()
79
+ });
80
+ else if (Array.isArray(cell.text)) inputCells = cell.text;
81
+ if (verbose) {
82
+ console.log("[1/4] inputCells");
83
+ inputCells.forEach((cell, idx) => console.log(`[1/4] [${idx + 1}] cell: ${JSON.stringify(cell)}`));
84
+ }
85
+ /**
86
+ * - EX: `[{ text:"Input Output" }, { text:"Extra" }]` == 1 line
87
+ * - EX: `[{ text:"Input" }, { text:"Output", options:{ breakLine:true } }]` == 1 line
88
+ * - EX: `[{ text:"Input\nOutput" }]` == 2 lines
89
+ * - EX: `[{ text:"Input", options:{ breakLine:true } }, { text:"Output" }]` == 2 lines
90
+ */
91
+ let newLine = [];
92
+ inputCells.forEach((cell) => {
93
+ if (typeof cell.text !== "string") return;
94
+ if (cell.text.includes("\n")) {
95
+ const parts = cell.text.split("\n");
96
+ parts.forEach((part, partIdx) => {
97
+ if (partIdx === parts.length - 1) newLine.push(workingCell(part, cell.options));
98
+ else {
99
+ newLine.push({
100
+ _type: "tablecell",
101
+ text: part,
102
+ options: {
103
+ ...cell.options,
104
+ breakLine: true
105
+ }
106
+ });
107
+ inputLines1.push(newLine);
108
+ newLine = [];
109
+ }
110
+ });
111
+ } else newLine.push(workingCell(cell.text.trim(), cell.options));
112
+ if (cell.options?.breakLine) {
113
+ if (verbose) console.log(`inputCells: new line > ${JSON.stringify(newLine)}`);
114
+ inputLines1.push(newLine);
115
+ newLine = [];
116
+ }
117
+ });
118
+ if (newLine.length > 0) {
119
+ inputLines1.push(newLine);
120
+ newLine = [];
121
+ }
122
+ if (verbose) {
123
+ console.log(`[2/4] inputLines1 (${inputLines1.length})`);
124
+ inputLines1.forEach((line, idx) => console.log(`[2/4] [${idx + 1}] line: ${JSON.stringify(line)}`));
125
+ }
126
+ inputLines1.forEach((line) => {
127
+ const lineTokens = [];
128
+ line.forEach((cell) => {
129
+ const lineWords = String(cell.text).split(" ");
130
+ lineWords.forEach((word, idx) => {
131
+ const cellProps = { ...cell.options };
132
+ if (cellProps?.breakLine) cellProps.breakLine = idx + 1 === lineWords.length;
133
+ lineTokens.push({
134
+ _type: "tablecell",
135
+ text: word + (idx + 1 < lineWords.length ? " " : ""),
136
+ options: cellProps
137
+ });
138
+ });
139
+ });
140
+ inputLines2.push(lineTokens);
141
+ });
142
+ if (verbose) {
143
+ console.log(`[3/4] inputLines2 (${inputLines2.length})`);
144
+ inputLines2.forEach((line) => console.log(`[3/4] line: ${JSON.stringify(line)}`));
145
+ }
146
+ inputLines2.forEach((line) => {
147
+ let lineCells = [];
148
+ let strCurrLine = "";
149
+ line.forEach((word) => {
150
+ const wordText = String(word.text || "");
151
+ if (strCurrLine.length + wordText.length > CPL) {
152
+ if (lineCells.length > 0) parsedLines.push(lineCells);
153
+ lineCells = [];
154
+ strCurrLine = "";
155
+ }
156
+ lineCells.push(word);
157
+ strCurrLine += wordText;
158
+ });
159
+ if (lineCells.length > 0) parsedLines.push(lineCells);
160
+ });
161
+ if (verbose) {
162
+ console.log(`[4/4] parsedLines (${parsedLines.length})`);
163
+ parsedLines.forEach((line, idx) => console.log(`[4/4] [Line ${idx + 1}]:\n${JSON.stringify(line)}`));
164
+ console.log("...............................................\n\n");
165
+ }
166
+ return parsedLines;
167
+ }
168
+ /**
169
+ * The font size in points one auto-paged cell is measured at: the cell's own `fontSize`,
170
+ * else the table's, else the library default. Pass `null` for the cell to ask the same
171
+ * question of the table alone.
172
+ */
173
+ function resolveCellFontSize(cellOpts, tableOpts) {
174
+ const size = cellOpts?.fontSize ?? tableOpts.fontSize;
175
+ return typeof size === "number" ? size : 12;
176
+ }
177
+ /**
178
+ * The `autoPageCharWeight` a cell wraps at: its own, else the table's, else none.
179
+ *
180
+ * The sibling of {@link resolveCellFontSize}, and named for the same reason -- the two call
181
+ * sites of {@link parseTextToLines} had resolved this one differently. The row-height probe
182
+ * read the cell's own value; the main loop stamped the table's over it first, and `delete`d the
183
+ * cell's when the table stated none, so a weight set on a cell alone was accepted and dropped.
184
+ * The precedence here is the one every other paired option in this codebase uses.
185
+ * @param cellOpts - the cell's own options, if any
186
+ * @param tableOpts - the table's options
187
+ */
188
+ function resolveCellCharWeight(cellOpts, tableOpts) {
189
+ const weight = cellOpts?.autoPageCharWeight ?? tableOpts.autoPageCharWeight;
190
+ return typeof weight === "number" ? weight : 0;
191
+ }
192
+ /**
193
+ * The largest top and bottom cell margin in one row, in EMU.
194
+ *
195
+ * A cell's own `margin` wins over the table's when it states one, and a stated `0` counts as
196
+ * stating one. Both sites that read this gated on truthiness and on `Array.isArray`, so a cell
197
+ * asking for `margin: [0, …]` fell through to the table's margin instead of taking its own, and
198
+ * a scalar `margin: 0.2` was not seen at all -- while the emitter broadcasts a scalar to four
199
+ * sides. `resolveCellMarginsInches` is the resolver the emitter itself reads.
200
+ * @param row - the row's cells
201
+ * @param tableProps - the table's options, for the fallback margin
202
+ * @returns the row's top and bottom margin allowance in EMU
203
+ */
204
+ function rowMarginsEmu(row, tableProps) {
205
+ let topEmu = 0;
206
+ let btmEmu = 0;
207
+ row.forEach((cell) => {
208
+ const stated = cell?.options?.margin ?? tableProps.margin;
209
+ if (stated === void 0 || stated === null) return;
210
+ const [top, , btm] = resolveCellMarginsInches(stated);
211
+ if (marginToEmu(top) > topEmu) topEmu = marginToEmu(top);
212
+ if (marginToEmu(btm) > btmEmu) btmEmu = marginToEmu(btm);
213
+ });
214
+ return {
215
+ topEmu,
216
+ btmEmu
217
+ };
218
+ }
219
+ /**
220
+ * Takes an array of table rows and breaks into an array of slides, which contain the calculated amount of table rows that fit on that slide
221
+ * @param {TableCellInternal[][]} tableRows - table rows
222
+ * @param {TableToSlidesPropsInternal} tableProps - table2slides properties
223
+ * @param {PresLayout} presLayout - presentation layout
224
+ * @param {SlideLayoutInternal} masterSlide - master slide
225
+ * @return {TableRowSlide[]} array of table rows
226
+ */
227
+ function getSlidesForTableRows(rows = [], tableProps = {}, presLayout, masterSlide) {
228
+ const tableRows = withCheckedSpans(rows);
229
+ let arrInchMargins = DEF_SLIDE_MARGIN_IN;
230
+ let emuSlideTabW;
231
+ let colWidthsIn = [];
232
+ let emuSlideTabH = EMU_PER_INCH * 1;
233
+ let emuTabCurrH = 0;
234
+ let numCols = 0;
235
+ let warnedNoTabH = false;
236
+ const tableRowSlides = [];
237
+ const tablePropX = getSmartParseNumber(tableProps.x, "X", presLayout);
238
+ const tablePropY = getSmartParseNumber(tableProps.y, "Y", presLayout);
239
+ const tablePropW = getSmartParseNumber(tableProps.w, "X", presLayout);
240
+ const tablePropH = getSmartParseNumber(tableProps.h, "Y", presLayout);
241
+ let tableCalcW = tablePropW;
242
+ /**
243
+ * Where this page's table starts, in EMU from the top of the slide.
244
+ *
245
+ * There used to be three rules for two cases. The first page and "every page after it"
246
+ * were handled together, then a block gated on `tableRowSlides.length > 1` overrode the
247
+ * result -- so despite its own comment it began on the THIRD page, and its first arm
248
+ * recomputed exactly what had just been computed. Page 2 therefore got a different usable
249
+ * height from pages 3 and up: with `y` above the top margin and an explicit `h`, a
250
+ * 60-row table paged 9 / 7 / 9 / 9 / 9 / 9 / 8, which is the same "pages disagree about
251
+ * how many identical rows fit" symptom the margin-reset note in `calcSlideTabH` records.
252
+ *
253
+ * It is a function rather than two expressions because the too-small-height fallback in
254
+ * `calcSlideTabH` had spelled the continuation arm its own way and drifted the same way
255
+ * twice over: `autoPageSlideStartY || margin` discarded an explicit `0` that the main rule
256
+ * honoured, and the `Math.min` clause below was missing outright. Two readings of one rule
257
+ * is what the paragraph above is about; there is now one.
258
+ */
259
+ function startYEmu() {
260
+ const statedY = tableProps.y !== void 0 && tableProps.y !== null;
261
+ if (tableRowSlides.length === 0) return statedY ? tablePropY : inch2Emu(arrInchMargins[0]);
262
+ if (typeof tableProps.autoPageSlideStartY === "number") return inch2Emu(tableProps.autoPageSlideStartY);
263
+ return inch2Emu(statedY ? Math.min(tablePropY / EMU_PER_INCH, arrInchMargins[0]) : arrInchMargins[0]);
264
+ }
265
+ function calcSlideTabH() {
266
+ const emuStartY = startYEmu();
267
+ emuSlideTabH = (tablePropH || presLayout.height) - emuStartY - inch2Emu(arrInchMargins[2]);
268
+ if (tablePropH && emuSlideTabH < tablePropH) emuSlideTabH = tablePropH;
269
+ const emuBaseLineH = autoPageLineHeightEmu(resolveCellFontSize(null, tableProps), tableProps.autoPageLineWeight || 0);
270
+ if (emuSlideTabH < emuBaseLineH) {
271
+ const fallbackH = presLayout.height - startYEmu() - inch2Emu(arrInchMargins[2]);
272
+ if (!warnedNoTabH) {
273
+ warn("table/autopage-height-too-small", "addTable/autoPage: the table height (`h`) leaves no room to paginate; ignoring it and using the slide height. Increase `h` or decrease `y`.");
274
+ warnedNoTabH = true;
275
+ }
276
+ emuSlideTabH = fallbackH > 0 ? fallbackH : presLayout.height;
277
+ }
278
+ }
279
+ if (tableProps.verbose) {
280
+ console.log("[[VERBOSE MODE]]");
281
+ console.log("|-- TABLE PROPS --------------------------------------------------------|");
282
+ console.log(`| presLayout.width ................................ = ${(presLayout.width / EMU_PER_INCH).toFixed(1)}`);
283
+ console.log(`| presLayout.height ............................... = ${(presLayout.height / EMU_PER_INCH).toFixed(1)}`);
284
+ console.log(`| tableProps.x .................................... = ${typeof tableProps.x === "number" ? (tableProps.x / EMU_PER_INCH).toFixed(1) : tableProps.x}`);
285
+ console.log(`| tableProps.y .................................... = ${typeof tableProps.y === "number" ? (tableProps.y / EMU_PER_INCH).toFixed(1) : tableProps.y}`);
286
+ console.log(`| tableProps.w .................................... = ${typeof tableProps.w === "number" ? (tableProps.w / EMU_PER_INCH).toFixed(1) : tableProps.w}`);
287
+ console.log(`| tableProps.h .................................... = ${typeof tableProps.h === "number" ? (tableProps.h / EMU_PER_INCH).toFixed(1) : tableProps.h}`);
288
+ console.log(`| tableProps.slideMargin .......................... = ${tableProps.slideMargin ? String(tableProps.slideMargin) : ""}`);
289
+ console.log(`| tableProps.margin ............................... = ${String(tableProps.margin)}`);
290
+ console.log(`| tableProps.colW ................................. = ${String(tableProps.colW)}`);
291
+ console.log(`| tableProps.autoPageSlideStartY .................. = ${tableProps.autoPageSlideStartY}`);
292
+ console.log(`| tableProps.autoPageCharWeight ................... = ${tableProps.autoPageCharWeight}`);
293
+ console.log("|-- CALCULATIONS -------------------------------------------------------|");
294
+ console.log(`| tablePropX ...................................... = ${tablePropX / EMU_PER_INCH}`);
295
+ console.log(`| tablePropY ...................................... = ${tablePropY / EMU_PER_INCH}`);
296
+ console.log(`| tablePropW ...................................... = ${tablePropW / EMU_PER_INCH}`);
297
+ console.log(`| tablePropH ...................................... = ${tablePropH / EMU_PER_INCH}`);
298
+ console.log(`| tableCalcW ...................................... = ${tableCalcW / EMU_PER_INCH}`);
299
+ }
300
+ arrInchMargins = resolveSlideMarginsInches(masterSlide?._margin, tableProps.slideMargin);
301
+ if (tableProps.verbose) console.log(`| arrInchMargins .................................. = [${arrInchMargins.join(", ")}]`);
302
+ numCols = tableColCount(tableRows);
303
+ if (tableProps.verbose) console.log(`| numCols ......................................... = ${numCols}`);
304
+ const placements = tableRows.map(() => []);
305
+ /**
306
+ * How many of each row's grid columns are held by a rowspan opened ABOVE it, accumulated as
307
+ * the placements arrive rather than searched for afterwards.
308
+ *
309
+ * The question used to be answered by scanning every placement in the table, once per row,
310
+ * which is quadratic in a table of any width. Two columns of short text and no spans at all:
311
+ * 1000 rows took 55ms, 2000 took 115ms, 4000 took 333ms and 8000 took 1036ms. The same four
312
+ * now take 24ms, 19ms, 40ms and 83ms -- so it was pure overhead, paid in full by the long
313
+ * report table that is the whole reason this code exists.
314
+ *
315
+ * Filling forward instead is bounded by the placement's own `rowSpan`, so the total work is
316
+ * the sum of all rowspans. That is safe to expand without a further check because
317
+ * `walkTableGrid` has already clamped each `rowSpan` to `rows.length - r`: a span cannot
318
+ * reach past the last row however large the caller wrote it, so the sum is bounded by the
319
+ * grid rather than by anything the caller states.
320
+ *
321
+ * The fill starts at `row + 1`. A `rowSpan` of 1 must contribute nothing -- starting at
322
+ * `row` would have every ordinary row counting itself as covered, and the
323
+ * `coveredFromAbove(iRow) === numCols` reader below would then fire on all of them.
324
+ */
325
+ const coveredCols = Array.from({ length: tableRows.length }, () => 0);
326
+ for (const placement of walkTableGrid(tableRows, numCols)) {
327
+ placements[placement.row]?.push(placement);
328
+ const last = Math.min(placement.row + placement.rowSpan, coveredCols.length);
329
+ for (let r = placement.row + 1; r < last; r++) coveredCols[r] = (coveredCols[r] ?? 0) + placement.colSpan;
330
+ }
331
+ /** How many of `iRow`'s grid columns are held by a rowspan opened above it. */
332
+ const coveredFromAbove = (iRow) => coveredCols[iRow] ?? 0;
333
+ /** Whether a rowspan opened above `iRow` is still covering it. */
334
+ const spannedFromAbove = (iRow) => coveredFromAbove(iRow) > 0;
335
+ if (!tablePropW && Array.isArray(tableProps.colW)) {
336
+ tableCalcW = tableProps.colW.reduce((p, n) => p + n, 0) * EMU_PER_INCH;
337
+ if (tableProps.verbose) console.log(`| tableCalcW ...................................... = ${tableCalcW / EMU_PER_INCH}`);
338
+ }
339
+ emuSlideTabW = tableCalcW || usableTableWidthEmu(presLayout, tablePropX, arrInchMargins);
340
+ if (tableProps.verbose) console.log(`| emuSlideTabW .................................... = ${(emuSlideTabW / EMU_PER_INCH).toFixed(1)}`);
341
+ colWidthsIn = resolveTableColWidthsEmu(tableProps.colW, emuSlideTabW, numCols).map((emu) => emu / EMU_PER_INCH);
342
+ const resolveRowH = (origRowIdx) => Array.isArray(tableProps.rowH) ? pinnedRowHeightInches(tableProps.rowH[origRowIdx]) ?? void 0 : void 0;
343
+ /**
344
+ * Wrap each of row `iRow`'s cells against the grid columns it covers, and price the row.
345
+ *
346
+ * The one row measure. The repeated header rows used to be priced by a second copy of it with its
347
+ * own column cursor, which ignored the columns a rowspan holds -- the fault `walkTableGrid`
348
+ * fixed for the main loop -- and skipped the line-height exemption for a cell that spans rows,
349
+ * so a header row inside a rowspan was measured against the wrong columns.
350
+ * @param iRow - the row's index in `tableRows`
351
+ * @param verbose - dump the wrapping stages, as `addTable({ verbose })` asks
352
+ */
353
+ function measureRow(iRow, verbose) {
354
+ const row = tableRows[iRow] ?? [];
355
+ const { topEmu, btmEmu } = rowMarginsEmu(row, tableProps);
356
+ const rowPlacements = placements[iRow] ?? [];
357
+ const cells = row.map((cell, iCell) => {
358
+ const placed = rowPlacements[iCell];
359
+ const colStart = placed ? placed.col : numCols;
360
+ const cellColspan = placed ? placed.colSpan : resolveSpan(cell.options?.colspan, "colspan");
361
+ const totalColW = colWidthsIn.slice(colStart, colStart + cellColspan).reduce((prev, curr) => prev + curr, 0);
362
+ const fontSizePt = resolveCellFontSize(cell.options, tableProps);
363
+ return {
364
+ _type: "tablecell",
365
+ _lines: parseTextToLines(cell, totalColW, fontSizePt, resolveCellCharWeight(cell.options, tableProps), verbose),
366
+ _lineHeight: placed && placed.rowSpan > 1 ? 0 : autoPageLineHeightEmu(fontSizePt, tableProps.autoPageLineWeight || 0),
367
+ text: [],
368
+ options: cell.options || {}
369
+ };
370
+ });
371
+ const lineHeightEmu = cells.reduce((max, cell) => Math.max(max, cell._lineHeight), 0);
372
+ const maxLines = cells.reduce((max, cell) => Math.max(max, cell._lines.length), 0);
373
+ const marginsEmu = topEmu + btmEmu;
374
+ return {
375
+ cells,
376
+ marginsEmu,
377
+ lineHeightEmu,
378
+ heightEmu: marginsEmu + maxLines * lineHeightEmu
379
+ };
380
+ }
381
+ const repeatHeaderRows = tableProps.autoPageRepeatHeader && tableProps._arrObjTabHeadRows ? tableProps._arrObjTabHeadRows : [];
382
+ const repeatHeaderHeightsEmu = repeatHeaderRows.map((_row, headIdx) => measureRow(headIdx).heightEmu);
383
+ /**
384
+ * The last row of the rowspan group that row `iRow` opens: the furthest row any of its spans
385
+ * reaches, extended by every span a covered row opens in turn. `walkTableGrid` has clamped each
386
+ * span to the table, so the walk ends inside it.
387
+ * @param iRow - the row that opens the group
388
+ */
389
+ function rowSpanGroupEnd(iRow) {
390
+ let end = iRow;
391
+ for (let r = iRow; r <= end; r++) for (const placement of placements[r] ?? []) end = Math.max(end, r + placement.rowSpan - 1);
392
+ return end;
393
+ }
394
+ let newTableRowSlide = {
395
+ rows: [],
396
+ rowH: [],
397
+ colW: colWidthsIn,
398
+ y: startYEmu() / EMU_PER_INCH
399
+ };
400
+ /** Rows placed on the working page other than its repeated header rows. */
401
+ let bodyRowsOnPage = 0;
402
+ let warnedTallRowSpan = false;
403
+ /**
404
+ * Close the working page and open the next: push the page when it has rows, re-derive the page
405
+ * height, charge `chargedEmu` to the new page, then repeat the header rows onto it.
406
+ * @param chargedEmu - what the new page already owes before its header rows: the margins of a
407
+ * row that is starting over here, or nothing
408
+ */
409
+ function startNewPage(chargedEmu) {
410
+ if (newTableRowSlide.rows.length > 0) tableRowSlides.push(newTableRowSlide);
411
+ newTableRowSlide = {
412
+ rows: [],
413
+ rowH: [],
414
+ colW: colWidthsIn,
415
+ y: startYEmu() / EMU_PER_INCH
416
+ };
417
+ bodyRowsOnPage = 0;
418
+ calcSlideTabH();
419
+ emuTabCurrH = chargedEmu;
420
+ if (tableProps.verbose) console.log(`| SLIDE [${tableRowSlides.length}]: emuSlideTabH ...... = ${(emuSlideTabH / EMU_PER_INCH).toFixed(1)} `);
421
+ repeatHeaderRows.forEach((headRow, headIdx) => {
422
+ newTableRowSlide.rows.push([...headRow]);
423
+ newTableRowSlide.rowH?.push(resolveRowH(headIdx));
424
+ emuTabCurrH += repeatHeaderHeightsEmu[headIdx] ?? 0;
425
+ });
426
+ }
427
+ tableRows.forEach((row, iRow) => {
428
+ const hasActiveRowSpan = spannedFromAbove(iRow);
429
+ let currTableRow = [];
430
+ row.forEach((cell) => currTableRow.push(workingCell([], cell.options)));
431
+ calcSlideTabH();
432
+ if (tableProps.verbose && iRow === 0) console.log(`| SLIDE [${tableRowSlides.length}]: emuSlideTabH ...... = ${(emuSlideTabH / EMU_PER_INCH).toFixed(1)} `);
433
+ const startsRowSpan = !hasActiveRowSpan && (placements[iRow] ?? []).some((placement) => placement.rowSpan > 1);
434
+ if (startsRowSpan) {
435
+ let groupHeightEmu = 0;
436
+ for (let r = iRow; r <= rowSpanGroupEnd(iRow); r++) groupHeightEmu += measureRow(r).heightEmu;
437
+ if (bodyRowsOnPage > 0 && emuTabCurrH + groupHeightEmu > emuSlideTabH) startNewPage(0);
438
+ if (emuTabCurrH + groupHeightEmu > emuSlideTabH && !warnedTallRowSpan) {
439
+ warn("table/autopage-rowspan-too-tall", "addTable/autoPage: a group of rows joined by a rowspan is taller than a page; it is kept on one page and runs past its bottom. Reduce the span or the text in it.");
440
+ warnedTallRowSpan = true;
441
+ }
442
+ }
443
+ const keepRowTogether = hasActiveRowSpan || startsRowSpan;
444
+ const { cells: rowCellLines, marginsEmu: rowMarginsTotalEmu, lineHeightEmu: emuLineMaxH } = measureRow(iRow, tableProps.verbose);
445
+ emuTabCurrH += rowMarginsTotalEmu;
446
+ /** E: --==[[ PAGE DATA SET ]]==--
447
+ * Add text one-line-a-time to this row's cells until: lines are exhausted OR table height limit is hit
448
+ *
449
+ * Design:
450
+ * - Building cells L-to-R/loop style wont work as one could be 100 lines and another 1 line
451
+ * - Therefore, build the whole row, one-line-at-a-time, across each table columns
452
+ * - Then, when the vertical size limit is hit is by any of the cells, make a new slide and continue adding any remaining lines
453
+ *
454
+ * Implementation:
455
+ * - `rowCellLines` is an array of cells, one for each column in the table, with each cell containing an array of lines
456
+ *
457
+ * Sample Data:
458
+ * - `rowCellLines` ..: [ TableCellInternal, TableCellInternal, TableCellInternal ]
459
+ * - `TableCellInternal` .....: { _type: 'tablecell', _lines: TableCellInternal[], _lineHeight: 10 }
460
+ * - `_lines` ........: [ {_type: 'tablecell', text: 'cell-1,line-1', options: {…}}, {_type: 'tablecell', text: 'cell-1,line-2', options: {…}} }
461
+ * - `_lines` is TableCellInternal[] (the 1-N words in the line)
462
+ * {
463
+ * _lines: [{ text:'cell-1,line-1' }, { text:'cell-1,line-2' }], // TOTAL-CELL-HEIGHT = 2
464
+ * _lines: [{ text:'cell-2,line-1' }, { text:'cell-2,line-2' }], // TOTAL-CELL-HEIGHT = 2
465
+ * _lines: [{ text:'cell-3,line-1' }, { text:'cell-3,line-2' }, { text:'cell-3,line-3' }, { text:'cell-3,line-4' }], // TOTAL-CELL-HEIGHT = 4
466
+ * }
467
+ *
468
+ * Example: 2 rows, with the firstrow overflowing onto a new slide
469
+ * SLIDE 1:
470
+ * |--------|--------|--------|--------|
471
+ * | line-1 | line-1 | line-1 | line-1 |
472
+ * | | | line-2 | |
473
+ * | | | line-3 | |
474
+ * |--------|--------|--------|--------|
475
+ *
476
+ * SLIDE 2:
477
+ * |--------|--------|--------|--------|
478
+ * | | | line-4 | |
479
+ * |--------|--------|--------|--------|
480
+ * | line-1 | line-1 | line-1 | line-1 |
481
+ * |--------|--------|--------|--------|
482
+ */
483
+ if (tableProps.verbose) console.log(`\n| SLIDE [${tableRowSlides.length}]: ROW [${iRow}]: START...`);
484
+ let currCellIdx = 0;
485
+ let isDone = false;
486
+ while (!isDone) {
487
+ const srcCell = rowCellLines[currCellIdx];
488
+ if (!srcCell) break;
489
+ let tgtCell = currTableRow[currCellIdx];
490
+ if (emuTabCurrH + emuLineMaxH > emuSlideTabH && !keepRowTogether) {
491
+ if (tableProps.verbose) {
492
+ console.log("\n|-----------------------------------------------------------------------|");
493
+ console.log(`|-- NEW SLIDE CREATED (currTabH+currLineH > maxH) => ${(emuTabCurrH / EMU_PER_INCH).toFixed(2)} + ${(srcCell._lineHeight / EMU_PER_INCH).toFixed(2)} > ${emuSlideTabH / EMU_PER_INCH}`);
494
+ console.log("|-----------------------------------------------------------------------|\n\n");
495
+ }
496
+ if (currTableRow.length > 0 && currTableRow.map((cell) => Array.isArray(cell.text) ? cell.text.length : 0).reduce((p, n) => p + n) > 0) {
497
+ newTableRowSlide.rows.push(currTableRow);
498
+ newTableRowSlide.rowH?.push(resolveRowH(iRow));
499
+ }
500
+ startNewPage(rowMarginsTotalEmu);
501
+ currTableRow = [];
502
+ row.forEach((cell) => currTableRow.push(workingCell([], cell.options)));
503
+ tgtCell = currTableRow[currCellIdx];
504
+ }
505
+ const currLine = srcCell._lines.shift();
506
+ if (tgtCell && Array.isArray(tgtCell.text)) {
507
+ if (currLine) tgtCell.text = tgtCell.text.concat(currLine);
508
+ else if (tgtCell.text.length === 0) tgtCell.text = tgtCell.text.concat({
509
+ _type: "tablecell",
510
+ text: ""
511
+ });
512
+ }
513
+ if (currCellIdx === rowCellLines.length - 1) emuTabCurrH += emuLineMaxH;
514
+ currCellIdx = currCellIdx < rowCellLines.length - 1 ? currCellIdx + 1 : 0;
515
+ if (rowCellLines.map((cell) => cell._lines.length).reduce((prev, next) => prev + next) === 0) isDone = true;
516
+ }
517
+ if (currTableRow.length > 0 || row.length === 0 && coveredFromAbove(iRow) === numCols) {
518
+ newTableRowSlide.rows.push(currTableRow);
519
+ newTableRowSlide.rowH?.push(resolveRowH(iRow));
520
+ bodyRowsOnPage++;
521
+ }
522
+ if (tableProps.verbose) console.log(`- SLIDE [${tableRowSlides.length}]: ROW [${iRow}]: ...COMPLETE ...... emuTabCurrH = ${(emuTabCurrH / EMU_PER_INCH).toFixed(2)} ( emuSlideTabH = ${(emuSlideTabH / EMU_PER_INCH).toFixed(2)} )`);
523
+ });
524
+ if (newTableRowSlide.rows.length > 0 || tableRowSlides.length === 0) tableRowSlides.push(newTableRowSlide);
525
+ if (tableProps.verbose) {
526
+ console.log("\n|================================================|");
527
+ console.log(`| FINAL: tableRowSlides.length = ${tableRowSlides.length}`);
528
+ tableRowSlides.forEach((slide) => console.log(slide));
529
+ console.log("|================================================|\n\n");
530
+ }
531
+ return tableRowSlides;
532
+ }
533
+ //#endregion
534
+ export { getSlidesForTableRows as t };
535
+
536
+ //# sourceMappingURL=autopage-odPz7zZO.js.map