slotdeck 0.1.1 → 0.2.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 +94 -8
- package/dist/deck/alternatives.d.ts +34 -0
- package/dist/deck/alternatives.js +370 -0
- package/dist/deck/alternatives.js.map +1 -0
- package/dist/deck/design.d.ts +40 -0
- package/dist/deck/design.js +112 -0
- package/dist/deck/design.js.map +1 -0
- package/dist/deck/validate.d.ts +18 -0
- package/dist/deck/validate.js +44 -6
- package/dist/deck/validate.js.map +1 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/gemini.d.ts +4 -0
- package/dist/llm/gemini.js +43 -7
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/provider.d.ts +12 -0
- package/dist/node.d.ts +7 -0
- package/dist/node.js +29 -0
- package/dist/node.js.map +1 -1
- package/dist/plan/catalog.d.ts +11 -1
- package/dist/plan/catalog.js +23 -8
- package/dist/plan/catalog.js.map +1 -1
- package/dist/plan/edit.js +14 -6
- package/dist/plan/edit.js.map +1 -1
- package/dist/plan/plan.d.ts +26 -2
- package/dist/plan/plan.js +58 -17
- package/dist/plan/plan.js.map +1 -1
- package/dist/plan/review.d.ts +43 -0
- package/dist/plan/review.js +141 -0
- package/dist/plan/review.js.map +1 -0
- package/dist/plan/write.d.ts +13 -1
- package/dist/plan/write.js +40 -7
- package/dist/plan/write.js.map +1 -1
- package/dist/preview/pagus.d.ts +30 -0
- package/dist/preview/pagus.js +45 -0
- package/dist/preview/pagus.js.map +1 -0
- package/dist/preview/patterns.d.ts +27 -0
- package/dist/preview/patterns.js +35 -0
- package/dist/preview/patterns.js.map +1 -0
- package/dist/preview/provider.d.ts +30 -0
- package/dist/preview/provider.js +11 -0
- package/dist/preview/provider.js.map +1 -0
- package/dist/render/render.d.ts +18 -1
- package/dist/render/render.js +32 -12
- package/dist/render/render.js.map +1 -1
- package/dist/render/repeat.d.ts +17 -2
- package/dist/render/repeat.js +150 -4
- package/dist/render/repeat.js.map +1 -1
- package/dist/render/text.d.ts +6 -0
- package/dist/render/text.js +24 -0
- package/dist/render/text.js.map +1 -1
- package/dist/template/budgets.d.ts +33 -0
- package/dist/template/budgets.js +38 -0
- package/dist/template/budgets.js.map +1 -0
- package/dist/template/change.d.ts +19 -1
- package/dist/template/change.js +45 -3
- package/dist/template/change.js.map +1 -1
- package/dist/template/check.d.ts +3 -0
- package/dist/template/check.js +53 -3
- package/dist/template/check.js.map +1 -1
- package/dist/template/derive.d.ts +54 -0
- package/dist/template/derive.js +402 -0
- package/dist/template/derive.js.map +1 -0
- package/dist/template/draft.d.ts +7 -0
- package/dist/template/draft.js +17 -1
- package/dist/template/draft.js.map +1 -1
- package/dist/template/instruct.js +15 -7
- package/dist/template/instruct.js.map +1 -1
- package/dist/template/manifest.d.ts +38 -0
- package/dist/template/manifest.js +43 -1
- package/dist/template/manifest.js.map +1 -1
- package/dist/template/sample.d.ts +17 -0
- package/dist/template/sample.js +31 -5
- package/dist/template/sample.js.map +1 -1
- package/dist/text/fontkit.d.ts +18 -0
- package/dist/text/fontkit.js +91 -0
- package/dist/text/fontkit.js.map +1 -0
- package/dist/text/fonts.d.ts +45 -0
- package/dist/text/fonts.js +59 -0
- package/dist/text/fonts.js.map +1 -0
- package/dist/text/layout.d.ts +12 -0
- package/dist/text/layout.js +104 -0
- package/dist/text/layout.js.map +1 -0
- package/dist/text/measure.d.ts +85 -0
- package/dist/text/measure.js +369 -0
- package/dist/text/measure.js.map +1 -0
- package/dist/text/styles.d.ts +123 -0
- package/dist/text/styles.js +417 -0
- package/dist/text/styles.js.map +1 -0
- package/dist/tools.d.ts +12 -0
- package/dist/tools.js +38 -6
- package/dist/tools.js.map +1 -1
- package/docs/README.md +16 -5
- package/docs/api-reference.md +291 -9
- package/docs/changelog.md +242 -0
- package/docs/chat-tools.md +26 -5
- package/docs/deck-format.md +6 -0
- package/docs/design-checks.md +216 -0
- package/docs/generating.md +43 -4
- package/docs/layout-freedom.md +278 -3
- package/docs/manifest-format.md +20 -3
- package/docs/preview.md +217 -0
- package/docs/providers.md +49 -4
- package/docs/rendering.md +8 -0
- package/docs/template-studio.md +121 -12
- package/docs/text-fit.md +456 -0
- package/docs/troubleshooting.md +21 -2
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -37,7 +37,8 @@ the chat tools, connecting your own model, the template studio, and every error
|
|
|
37
37
|
|
|
38
38
|
It is plain Markdown with no links to the internet, and it ships inside the npm package
|
|
39
39
|
(`node_modules/slotdeck/docs/`), so a coding assistant without network access can read it where the package is
|
|
40
|
-
installed. This page is the overview.
|
|
40
|
+
installed. This page is the overview. What changed in each version is in
|
|
41
|
+
[`docs/changelog.md`](docs/changelog.md).
|
|
41
42
|
|
|
42
43
|
## How it works
|
|
43
44
|
|
|
@@ -137,6 +138,10 @@ contains figures. In a live run without this guard the model filled such a slide
|
|
|
137
138
|
`numberPatterns: 'always'` to offer them regardless, or `'never'` to rule them out. Chart values the brief does
|
|
138
139
|
not state come back as warnings (`chart values not stated in the brief: 89`).
|
|
139
140
|
|
|
141
|
+
A wish about the kind of slides, such as "text only" or "no tables", decides which patterns may be used and
|
|
142
|
+
comes before variety. For a deck of text and nothing else, set `textOnly: true` on the brief (`text_only` in the
|
|
143
|
+
chat tool): only the template's plain text patterns are then offered.
|
|
144
|
+
|
|
140
145
|
### Editing a deck
|
|
141
146
|
|
|
142
147
|
```ts
|
|
@@ -213,7 +218,9 @@ data reaches a model, and a pptx can be rebuilt from the JSON and the pictures a
|
|
|
213
218
|
new plan or deck under a new id; earlier versions stay.
|
|
214
219
|
|
|
215
220
|
To show a plan as layout thumbnails, render the template once and name the pictures after the patterns
|
|
216
|
-
(`scripts/pattern-thumbnails.ts`).
|
|
221
|
+
(`scripts/pattern-thumbnails.ts`). A derived pattern, such as a mirror image, looks different from the slide it
|
|
222
|
+
comes from: `scripts/template-deck.ts` writes a deck with one slide per pattern, filled with the template's own
|
|
223
|
+
sample content, to take those pictures from. `examples/plan-preview.ts` turns a plan into a self-contained page.
|
|
217
224
|
|
|
218
225
|
### Other models
|
|
219
226
|
|
|
@@ -280,15 +287,91 @@ manifest allows and the code moves the shapes; the model never positions anythin
|
|
|
280
287
|
accepts (in the demo template `icon-cards` takes 2 to 4 and `stat-cards` 2 to 6). A slide says how many with
|
|
281
288
|
`items`. Surplus cards are removed, extra ones are copies of the last, and the row is spaced out again around
|
|
282
289
|
its centre. A copied card has its own slots (`card5Icon`, `card5Heading`, ...).
|
|
290
|
+
- **Rows that fill their line.** With `widen` on the `repeat`, fewer cards than drawn grow wider instead of
|
|
291
|
+
standing in the middle of the row: backgrounds and text boxes widen, icons and pictures keep their size
|
|
292
|
+
and their side, and the text budgets grow with the cards. The number of cards decides, never the length of
|
|
293
|
+
the text.
|
|
283
294
|
- **Grids.** With `columns`, the items form a grid. They take as few rows as they need and spread evenly: four
|
|
284
295
|
figures in a three-column grid make two rows of two, five make three and two, three make one row.
|
|
285
296
|
- **Larger text.** `textScale` on a deck (or `textSize: 'large' | 'x-large'` on a brief) enlarges body text:
|
|
286
297
|
slots of 12 pt and under by default, not titles. Because the boxes stay the same size, character budgets fall
|
|
287
|
-
with the square of the scale, so the model writes less.
|
|
298
|
+
with the square of the scale, so the model writes less. A template whose own body text is small can be
|
|
299
|
+
enlarged once for every deck with `textScale` on the manifest.
|
|
288
300
|
- **Derived patterns.** Several patterns can come from one slide. A text slot can be moved and resized (`box`),
|
|
289
301
|
given a font size (`fontSize`) and paragraph spacing, and any shape can be dropped. In the demo template
|
|
290
302
|
`text-only` is the photo slide with its photo dropped and its text widened, and `chart-native` is the chart
|
|
291
303
|
slide with a native chart in place of the picture.
|
|
304
|
+
- **Variants the code works out.** For three common variants nobody types a box: the mirror image of a slide
|
|
305
|
+
with a picture, the same slide without its picture, and a slide without one of its optional lines. One
|
|
306
|
+
operation (`derivePattern`) makes each, moving the shapes and measuring the budgets again; the header, logo
|
|
307
|
+
and page number stay where they are. In the demo template `text-and-photo-mirrored`, `photo-stat-mirrored`
|
|
308
|
+
and `list-with-photo-mirrored` were made this way.
|
|
309
|
+
|
|
310
|
+
### Another layout for a slide
|
|
311
|
+
|
|
312
|
+
`slideAlternatives(manifest, deck, slideNumber)` takes a slide that already has its content and lists the
|
|
313
|
+
other patterns that can hold the same content, with the slide written for each: three cards as a list of three
|
|
314
|
+
points, two cards as two columns, a photo slide as its mirror image. It is code only. No model is asked and no
|
|
315
|
+
word is changed, so a pattern that would need a subtitle, a number or an icon the slide does not have is not
|
|
316
|
+
offered. What does not fit a new slot's budget is reported, not cut.
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
import { slideAlternatives } from 'slotdeck';
|
|
320
|
+
|
|
321
|
+
const [first] = slideAlternatives(manifest, deck, 5, { layout: 'adaptive' });
|
|
322
|
+
// first.pattern, first.slide, first.changes, first.dropped, first.warnings
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Text that fits
|
|
326
|
+
|
|
327
|
+
By default a slot's limit is a character budget, which cannot see where lines break. Give the template its font
|
|
328
|
+
files and text is measured the way PowerPoint sets it: broken into lines at the slot's typeface and size and
|
|
329
|
+
compared with the room in its box.
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
import * as fontkit from 'fontkit'; // installed by you; slotdeck does not depend on it
|
|
333
|
+
import { fontkitMetrics, loadTemplate, renderDeck } from 'slotdeck';
|
|
334
|
+
|
|
335
|
+
const fonts = fontkitMetrics(fontkit, { Calibri: [calibri, calibriBold], Cambria: [cambria, cambriaBold] });
|
|
336
|
+
const template = loadTemplate(pptx, manifest, { fonts });
|
|
337
|
+
|
|
338
|
+
renderDeck(template, deck, { assets }).warnings;
|
|
339
|
+
// text takes 7 lines at 18 pt; the box holds 5 (2 lines too many). Text of about 290 characters fits.
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
The planner repairs drafts by the same measurement, `shrinkText` on the manifest lets text that does not fit be
|
|
343
|
+
set a little smaller, and `measuredBudgets` works out budgets from what the boxes hold. On the demo template
|
|
344
|
+
every line broke at the same word as in PowerPoint in all 1,153 text slots checked, in English and Hebrew. See
|
|
345
|
+
[`docs/text-fit.md`](docs/text-fit.md).
|
|
346
|
+
|
|
347
|
+
### Design checks
|
|
348
|
+
|
|
349
|
+
A deck can fit its boxes and still look wrong. With fonts loaded, `checkDesign(template, deck)` finds what
|
|
350
|
+
measurement can see: a box left almost empty, a card far shorter than its neighbours, a heading that ends with
|
|
351
|
+
one word on a line of its own. Each finding says what length of text would put it right, and
|
|
352
|
+
`review: designReview(template)` sends the findings back to the writing model while a deck is planned. On the
|
|
353
|
+
example deck it reports the two orphan words that PowerPoint's own picture shows. See
|
|
354
|
+
[`docs/design-checks.md`](docs/design-checks.md).
|
|
355
|
+
|
|
356
|
+
### Previews
|
|
357
|
+
|
|
358
|
+
slotdeck draws nothing itself, but it has a hook for a renderer that does: a `PreviewProvider` turns a pptx into
|
|
359
|
+
one picture for each slide. An adapter for the Pagus library comes with the package (you install Pagus), and
|
|
360
|
+
any other renderer or service can be plugged in.
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
import * as pagusCore from '@pagus-kit/core';
|
|
364
|
+
import * as pagusRenderer from '@pagus-kit/renderer';
|
|
365
|
+
import { pagusPreviews, patternPreviews, previewDeck } from 'slotdeck';
|
|
366
|
+
|
|
367
|
+
const preview = pagusPreviews(pagusCore, pagusRenderer);
|
|
368
|
+
const { pptx, previews } = await previewDeck(template, deck, preview, { assets }); // SVG, one for each slide
|
|
369
|
+
const thumbnails = await patternPreviews(template, preview); // one for each pattern
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
The chat tools take the same provider and keep a picture of every slide they make. A preview shows what a deck
|
|
373
|
+
looks like; it is not PowerPoint. What three renderers got right and wrong, in English and in Hebrew, is in
|
|
374
|
+
[`docs/preview.md`](docs/preview.md).
|
|
292
375
|
|
|
293
376
|
## Template studio
|
|
294
377
|
|
|
@@ -366,8 +449,9 @@ const view = studioView(template);
|
|
|
366
449
|
| `setSlot` | A slot's budget, whether it is required, optional, kept or always removed (`empty`), font size, area (`box`), name, deck field, picture kind, and the settings of a table or chart. |
|
|
367
450
|
| `addSlot` | Makes a shape a slot in a role (`title`, `text`, `list`, `number`, `caption`, `photo`, `icon`, `graphic`, `chart`, `table`, `decoration`), with limits measured from the shape. On a shape that is already a slot it changes the role. |
|
|
368
451
|
| `removeSlot` | The shape goes back to being part of the design. |
|
|
369
|
-
| `setRepeat`, `removeRepeat` | How many items a row or grid takes. Finds the row from numbered slot names when the pattern has none. |
|
|
452
|
+
| `setRepeat`, `removeRepeat` | How many items a row or grid takes, and whether fewer items grow wider to fill the row (`widen`). Finds the row from numbered slot names when the pattern has none. |
|
|
370
453
|
| `addPattern`, `copyPattern`, `setPattern`, `removePattern` | Which slides are patterns, their ids and descriptions, and variants of a pattern from the same slide. |
|
|
454
|
+
| `derivePattern` | A variant of a pattern that the code lays out by itself: `mirror`, `text-only`, or `without` an optional text. Refused with the reason when the slide does not allow it. |
|
|
371
455
|
| `setManifest` | The template's name, language, direction and alignment policy. |
|
|
372
456
|
|
|
373
457
|
What the code adds to each change:
|
|
@@ -381,7 +465,8 @@ What the code adds to each change:
|
|
|
381
465
|
is refused, and the rest of the list is still applied.
|
|
382
466
|
|
|
383
467
|
`editManifest` makes one model call, and a second when some of its operations were refused, so the model can
|
|
384
|
-
correct them. The model never sets a position: `box` and `span` exist only for changes made by hand
|
|
468
|
+
correct them. The model never sets a position: `box` and `span` exist only for changes made by hand, and a
|
|
469
|
+
variant it asks for by name is laid out by the code.
|
|
385
470
|
`describeManifest(template)` returns the text the model reads, for an app that wants to show the manifest to its
|
|
386
471
|
own chat model.
|
|
387
472
|
|
|
@@ -396,6 +481,7 @@ own chat model.
|
|
|
396
481
|
native-chart variant. It also asked for five cards in a row; that was refused, because four fit.
|
|
397
482
|
3. A few changes by hand with `changeManifest`: the text-only variant, chart colours, mirrored alignment for
|
|
398
483
|
right-to-left decks, and tighter budgets for figures and one-line captions.
|
|
484
|
+
4. Three `derivePattern` operations for the mirror images of the slides with a photo.
|
|
399
485
|
|
|
400
486
|
A draft is a starting point. What it does not contain, and a person adds while reviewing: budgets tuned by eye,
|
|
401
487
|
derived patterns, wider rows, picture areas and chart colours. On a 36-slide corporate template (not included
|
|
@@ -474,15 +560,15 @@ powershell -File scripts/render-pptx.ps1 -Path out/patterns-en.pptx -OutDir out/
|
|
|
474
560
|
as empty, so its budget is only as long as its sample text. Decks exported from Google Slides and decks built
|
|
475
561
|
from free-standing text boxes work as they are.
|
|
476
562
|
- **Budgets are estimates.** A character budget cannot see lines lost to wrapping. Budgets for slots with several
|
|
477
|
-
paragraphs should be set with room to spare, and a sample deck is the way to see them.
|
|
563
|
+
paragraphs should be set with room to spare, and a sample deck is the way to see them. A template loaded with
|
|
564
|
+
its fonts measures text slots in lines instead (see Text that fits); tables and charts keep their budgets.
|
|
478
565
|
- **Models invent details.** In the showcase deck the model made up an email address and a phone number for the
|
|
479
566
|
closing slide, which were replaced by hand. Figures are guarded (see How planning works); contact details and
|
|
480
567
|
names are not.
|
|
481
568
|
- **What has been run.** The whole path was run against the Gemini Developer API with `gemini-3.8-flash` for
|
|
482
569
|
text and `gemini-3.1-flash-image` for photos, in English and Hebrew. Vertex AI is supported by the adapter but
|
|
483
570
|
has not been run live. Output was checked by rendering in PowerPoint on Windows; other viewers were not tested.
|
|
484
|
-
- **Not built:**
|
|
485
|
-
made in PowerPoint.
|
|
571
|
+
- **Not built:** stacked or combined charts, speaker notes, and reading back changes made in PowerPoint.
|
|
486
572
|
|
|
487
573
|
## The demo template and pictures
|
|
488
574
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { TemplateManifest } from '../template/manifest.ts';
|
|
2
|
+
import type { DeckSpec, SlideSpec } from './spec.ts';
|
|
3
|
+
import type { Issue, LayoutMode } from './validate.ts';
|
|
4
|
+
export interface SlideAlternative {
|
|
5
|
+
/** Id of a pattern that has a place for everything the slide says. */
|
|
6
|
+
pattern: string;
|
|
7
|
+
/** What that pattern is for, from the manifest. */
|
|
8
|
+
description: string;
|
|
9
|
+
/** The slide written for that pattern. Put it in the deck in place of the original. */
|
|
10
|
+
slide: SlideSpec;
|
|
11
|
+
/** What was done to the content where it was not copied slot for slot, a sentence each. */
|
|
12
|
+
changes: string[];
|
|
13
|
+
/** Slots of the original slide whose photo or icon the pattern has no place for. */
|
|
14
|
+
dropped: string[];
|
|
15
|
+
/** What `validateDeck` says about the new slide, such as a text over its budget. Empty when everything fits. */
|
|
16
|
+
warnings: Issue[];
|
|
17
|
+
}
|
|
18
|
+
export interface AlternativesOptions {
|
|
19
|
+
/** `strict` (default): every slot of the new pattern must be filled. `adaptive`: its optional slots may stay empty. */
|
|
20
|
+
layout?: LayoutMode;
|
|
21
|
+
/** Consider only these patterns. */
|
|
22
|
+
patterns?: string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Lists the other patterns that can hold what one slide of a deck says, with the slide written
|
|
26
|
+
* for each. `slide` is the slide's number in the deck, from 1. No model is asked and no text is
|
|
27
|
+
* rewritten: a title stays a title, and a row of items becomes other items or a list of points.
|
|
28
|
+
*
|
|
29
|
+
* A pattern is an alternative when every text, table, chart and supplied graphic of the slide
|
|
30
|
+
* has a place in it and every slot it requires can be filled. A photo or an icon may be left
|
|
31
|
+
* out, which `dropped` reports. A text that is longer than its new slot holds is reported in
|
|
32
|
+
* `warnings`, as `validateDeck` would. Alternatives that fit without a warning come first.
|
|
33
|
+
*/
|
|
34
|
+
export declare function slideAlternatives(manifest: TemplateManifest, deck: DeckSpec, slide: number, options?: AlternativesOptions): SlideAlternative[];
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
// Other layouts for a slide that already has its content. The content is read out of the slide
|
|
2
|
+
// by what each slot is for (a title, a body, items with a heading and a text) and put into every
|
|
3
|
+
// other pattern that has a place for all of it. Code only: no model is asked and nothing is
|
|
4
|
+
// rewritten, so an alternative says exactly what the slide said.
|
|
5
|
+
import { effectiveSlots, itemRange } from '../template/manifest.js';
|
|
6
|
+
import { isImageRef, toParagraphs } from './spec.js';
|
|
7
|
+
import { validateDeck } from './validate.js';
|
|
8
|
+
const fillable = (slot) => slot.empty !== 'keep' && slot.empty !== 'drop' && !(slot.kind === 'text' && slot.deckField);
|
|
9
|
+
const sizeOf = (slot) => slot.fontSize ?? slot.size ?? 0;
|
|
10
|
+
/** A big, short text is a figure: "87%", "3.5x". */
|
|
11
|
+
const isFigure = (slot) => (slot.maxChars ?? Infinity) <= 10 && sizeOf(slot) >= 24;
|
|
12
|
+
const largest = (slots) => slots.slice().sort((a, b) => (b.maxChars ?? 0) - (a.maxChars ?? 0))[0];
|
|
13
|
+
const plural = (count, word) => `${count} ${word}${count === 1 ? '' : 's'}`;
|
|
14
|
+
const empty = (value) => value === null || value === undefined || (typeof value === 'string' && value.trim() === '');
|
|
15
|
+
/** A photo or an icon illustrates and may be left out; a supplied graphic is something the slide says. */
|
|
16
|
+
const illustrates = (kind) => kind !== 'graphic';
|
|
17
|
+
const asValue = (text) => (text.length === 1 ? text[0] : text);
|
|
18
|
+
const isList = (slot) => (slot?.maxParagraphs ?? 1) > 1;
|
|
19
|
+
function textOf(value) {
|
|
20
|
+
if (typeof value !== 'string' && !Array.isArray(value))
|
|
21
|
+
return undefined;
|
|
22
|
+
const paragraphs = toParagraphs(value).filter((paragraph) => paragraph !== '');
|
|
23
|
+
return paragraphs.length > 0 ? paragraphs : undefined;
|
|
24
|
+
}
|
|
25
|
+
function anatomy(pattern) {
|
|
26
|
+
const repeat = pattern.repeat;
|
|
27
|
+
const inRow = new Set(repeat ? repeat.shapes.flatMap((_, index) => repeat.slots.map((name) => name.replace('{n}', String(index + 1)))) : []);
|
|
28
|
+
const own = pattern.slots.filter((slot) => fillable(slot) && !inRow.has(slot.name));
|
|
29
|
+
const texts = own.filter((slot) => slot.kind === 'text');
|
|
30
|
+
const take = (slot) => {
|
|
31
|
+
if (slot)
|
|
32
|
+
texts.splice(texts.indexOf(slot), 1);
|
|
33
|
+
return slot;
|
|
34
|
+
};
|
|
35
|
+
const shape = { others: [] };
|
|
36
|
+
const title = take(texts.find((slot) => /title$/i.test(slot.name) && !/sub/i.test(slot.name)));
|
|
37
|
+
const subtitle = take(texts.find((slot) => /sub(title|heading)$/i.test(slot.name)));
|
|
38
|
+
const figure = take(texts.find(isFigure));
|
|
39
|
+
// Of what is left, the text with the most room is the body.
|
|
40
|
+
const body = take(largest(texts));
|
|
41
|
+
if (title)
|
|
42
|
+
shape.title = title;
|
|
43
|
+
if (subtitle)
|
|
44
|
+
shape.subtitle = subtitle;
|
|
45
|
+
if (figure)
|
|
46
|
+
shape.figure = figure;
|
|
47
|
+
if (body)
|
|
48
|
+
shape.body = body;
|
|
49
|
+
const pictures = own.filter((slot) => slot.kind === 'image' && slot.imageKind !== 'icon');
|
|
50
|
+
if (pictures.length === 1 && pictures[0])
|
|
51
|
+
shape.picture = pictures[0];
|
|
52
|
+
shape.others = [...texts, ...own.filter((slot) => slot.kind !== 'text' && slot !== shape.picture)];
|
|
53
|
+
if (repeat) {
|
|
54
|
+
const parts = new Map();
|
|
55
|
+
let clear = true;
|
|
56
|
+
const itemTexts = [];
|
|
57
|
+
for (const template of repeat.slots) {
|
|
58
|
+
const slot = pattern.slots.find((candidate) => candidate.name === template.replace('{n}', '1'));
|
|
59
|
+
if (!slot || !fillable(slot))
|
|
60
|
+
continue;
|
|
61
|
+
if (slot.kind === 'text')
|
|
62
|
+
itemTexts.push({ template, slot });
|
|
63
|
+
else if (slot.kind === 'image') {
|
|
64
|
+
const part = slot.imageKind === 'icon' ? 'icon' : 'picture';
|
|
65
|
+
if (parts.has(part))
|
|
66
|
+
clear = false;
|
|
67
|
+
parts.set(part, { template, slot });
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
clear = false;
|
|
71
|
+
}
|
|
72
|
+
const number = itemTexts.length > 1 ? itemTexts.find((entry) => isFigure(entry.slot)) : undefined;
|
|
73
|
+
if (number)
|
|
74
|
+
parts.set('figure', number);
|
|
75
|
+
const rest = itemTexts.filter((entry) => entry !== number).sort((a, b) => (a.slot.maxChars ?? 0) - (b.slot.maxChars ?? 0));
|
|
76
|
+
// Of two texts, the one with less room is the heading. More than two cannot be told apart.
|
|
77
|
+
if (rest.length > 2)
|
|
78
|
+
clear = false;
|
|
79
|
+
if (rest.length === 2 && rest[0])
|
|
80
|
+
parts.set('heading', rest[0]);
|
|
81
|
+
const main = rest.at(-1);
|
|
82
|
+
if (main)
|
|
83
|
+
parts.set('text', main);
|
|
84
|
+
shape.row = { parts, clear };
|
|
85
|
+
}
|
|
86
|
+
return shape;
|
|
87
|
+
}
|
|
88
|
+
function contentOf(pattern, shape, slide) {
|
|
89
|
+
const content = { others: new Map(), items: [], itemName: pattern.repeat?.item ?? 'item', itemPictures: [], bodyIsList: isList(shape.body) };
|
|
90
|
+
const read = (slot) => (slot ? textOf(slide.slots[slot.name]) : undefined);
|
|
91
|
+
const title = read(shape.title);
|
|
92
|
+
const subtitle = read(shape.subtitle);
|
|
93
|
+
const figure = read(shape.figure);
|
|
94
|
+
const body = read(shape.body);
|
|
95
|
+
if (title)
|
|
96
|
+
content.title = title;
|
|
97
|
+
if (subtitle)
|
|
98
|
+
content.subtitle = subtitle;
|
|
99
|
+
if (figure)
|
|
100
|
+
content.figure = figure;
|
|
101
|
+
if (body)
|
|
102
|
+
content.body = body;
|
|
103
|
+
const picture = shape.picture && slide.slots[shape.picture.name];
|
|
104
|
+
if (shape.picture && isImageRef(picture))
|
|
105
|
+
content.picture = { ref: picture, kind: shape.picture.imageKind, from: shape.picture.name };
|
|
106
|
+
for (const slot of shape.others) {
|
|
107
|
+
const value = slide.slots[slot.name];
|
|
108
|
+
if (!empty(value))
|
|
109
|
+
content.others.set(slot.name, { value, slot });
|
|
110
|
+
}
|
|
111
|
+
const range = itemRange(pattern);
|
|
112
|
+
if (shape.row && range) {
|
|
113
|
+
for (let n = 1; n <= (slide.items ?? range.drawn); n++) {
|
|
114
|
+
const item = {};
|
|
115
|
+
for (const [part, { template, slot }] of shape.row.parts) {
|
|
116
|
+
const name = template.replace('{n}', String(n));
|
|
117
|
+
const value = slide.slots[name];
|
|
118
|
+
if (part === 'icon' || part === 'picture') {
|
|
119
|
+
if (isImageRef(value) && slot.kind === 'image') {
|
|
120
|
+
item[part] = value;
|
|
121
|
+
content.itemPictures.push({ from: name, part, kind: slot.imageKind });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const text = textOf(value);
|
|
126
|
+
if (text)
|
|
127
|
+
item[part] = text;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
content.items.push(item);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return content;
|
|
134
|
+
}
|
|
135
|
+
class NoPlace extends Error {
|
|
136
|
+
}
|
|
137
|
+
const no = () => {
|
|
138
|
+
throw new NoPlace();
|
|
139
|
+
};
|
|
140
|
+
/** A heading and a text as one line: "Heading: text". */
|
|
141
|
+
function joined(lead, text) {
|
|
142
|
+
const head = (lead ?? []).join(' ');
|
|
143
|
+
const rest = (text ?? []).join(' ');
|
|
144
|
+
if (!head || !rest)
|
|
145
|
+
return head || rest;
|
|
146
|
+
return /[:.!?…]$/.test(head) ? `${head} ${rest}` : `${head}: ${rest}`;
|
|
147
|
+
}
|
|
148
|
+
/** The two halves of "Heading: text", or nothing when the line is not written that way. */
|
|
149
|
+
function split(line) {
|
|
150
|
+
const match = /^(.{1,80}?)(?::\s+|\s+[–—-]\s+)(\S.*)$/.exec(line);
|
|
151
|
+
return match ? [match[1], match[2]] : undefined;
|
|
152
|
+
}
|
|
153
|
+
/** Copies every value to the slot of the same name: the way between variants of one slide. */
|
|
154
|
+
function byName(source, target, slide) {
|
|
155
|
+
const range = itemRange(target);
|
|
156
|
+
const items = range ? (slide.items ?? itemRange(source)?.drawn ?? range.drawn) : undefined;
|
|
157
|
+
if (range && items !== undefined && (items < range.min || items > range.max))
|
|
158
|
+
no();
|
|
159
|
+
const places = new Map(effectiveSlots(target, items).filter(fillable).map((slot) => [slot.name, slot]));
|
|
160
|
+
const draft = { slots: {}, changes: [], dropped: [] };
|
|
161
|
+
if (items !== undefined)
|
|
162
|
+
draft.items = items;
|
|
163
|
+
for (const slot of effectiveSlots(source, slide.items).filter(fillable)) {
|
|
164
|
+
const value = slide.slots[slot.name];
|
|
165
|
+
if (empty(value))
|
|
166
|
+
continue;
|
|
167
|
+
const place = places.get(slot.name);
|
|
168
|
+
const same = place && place.kind === slot.kind && (place.kind !== 'image' || slot.kind !== 'image' || place.imageKind === slot.imageKind);
|
|
169
|
+
if (same)
|
|
170
|
+
draft.slots[slot.name] = value;
|
|
171
|
+
else if (slot.kind === 'image' && illustrates(slot.imageKind))
|
|
172
|
+
draft.dropped.push(slot.name);
|
|
173
|
+
else
|
|
174
|
+
no();
|
|
175
|
+
}
|
|
176
|
+
return draft;
|
|
177
|
+
}
|
|
178
|
+
/** Puts the content into the target by what each slot is for. */
|
|
179
|
+
function byParts(content, target, shape) {
|
|
180
|
+
const draft = { slots: {}, changes: [], dropped: [] };
|
|
181
|
+
const put = (slot, text) => {
|
|
182
|
+
if (!text)
|
|
183
|
+
return;
|
|
184
|
+
if (!slot)
|
|
185
|
+
return no();
|
|
186
|
+
draft.slots[slot.name] = asValue(text);
|
|
187
|
+
};
|
|
188
|
+
put(shape.title, content.title);
|
|
189
|
+
put(shape.subtitle, content.subtitle);
|
|
190
|
+
put(shape.figure, content.figure);
|
|
191
|
+
for (const [name, { value, slot }] of content.others) {
|
|
192
|
+
if (!shape.others.some((candidate) => candidate.name === name && candidate.kind === slot.kind))
|
|
193
|
+
no();
|
|
194
|
+
draft.slots[name] = value;
|
|
195
|
+
}
|
|
196
|
+
if (content.picture) {
|
|
197
|
+
if (shape.picture && shape.picture.imageKind === content.picture.kind)
|
|
198
|
+
draft.slots[shape.picture.name] = content.picture.ref;
|
|
199
|
+
else if (illustrates(content.picture.kind))
|
|
200
|
+
draft.dropped.push(content.picture.from);
|
|
201
|
+
else
|
|
202
|
+
no();
|
|
203
|
+
}
|
|
204
|
+
const row = shape.row;
|
|
205
|
+
const range = itemRange(target);
|
|
206
|
+
const count = content.items.length;
|
|
207
|
+
const itemWord = target.repeat?.item ?? 'item';
|
|
208
|
+
const nameOf = (part, n) => (row?.parts.get(part)?.template ?? '').replace('{n}', String(n));
|
|
209
|
+
const oneLine = (item) => [item.heading, item.text, item.figure].every((part) => (part?.length ?? 0) <= 1);
|
|
210
|
+
if (count > 0 && row && range) {
|
|
211
|
+
// Items into items: cards into columns, a row into a grid.
|
|
212
|
+
if (!row.clear || count < range.min || count > range.max)
|
|
213
|
+
no();
|
|
214
|
+
put(shape.body, content.body);
|
|
215
|
+
draft.items = count;
|
|
216
|
+
// A row of single texts written "heading: text" can fill items that want the two apart.
|
|
217
|
+
const halves = row.parts.has('heading') && row.parts.has('text') ? content.items.map((item) => (!item.heading && !item.figure && item.text?.length === 1 ? split(item.text[0]) : undefined)) : [];
|
|
218
|
+
const apart = halves.length > 0 && halves.every((half) => half !== undefined);
|
|
219
|
+
let merged = false;
|
|
220
|
+
content.items.forEach((item, index) => {
|
|
221
|
+
const n = index + 1;
|
|
222
|
+
if (item.figure && item.heading)
|
|
223
|
+
no();
|
|
224
|
+
const leadPart = item.figure ? 'figure' : item.heading ? 'heading' : undefined;
|
|
225
|
+
const lead = item.figure ?? item.heading;
|
|
226
|
+
if (apart) {
|
|
227
|
+
const [heading, text] = halves[index];
|
|
228
|
+
draft.slots[nameOf('heading', n)] = heading;
|
|
229
|
+
draft.slots[nameOf('text', n)] = text;
|
|
230
|
+
}
|
|
231
|
+
else if (leadPart && row.parts.has(leadPart)) {
|
|
232
|
+
draft.slots[nameOf(leadPart, n)] = lead.join(' ');
|
|
233
|
+
if (item.text) {
|
|
234
|
+
if (!row.parts.has('text'))
|
|
235
|
+
no();
|
|
236
|
+
draft.slots[nameOf('text', n)] = asValue(item.text);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else if (leadPart) {
|
|
240
|
+
// The target's items have one text: the heading leads it.
|
|
241
|
+
if (!row.parts.has('text') || row.parts.has('heading') || row.parts.has('figure') || !oneLine(item))
|
|
242
|
+
no();
|
|
243
|
+
draft.slots[nameOf('text', n)] = joined(lead, item.text);
|
|
244
|
+
merged = true;
|
|
245
|
+
}
|
|
246
|
+
else if (item.text) {
|
|
247
|
+
if (!row.parts.has('text'))
|
|
248
|
+
no();
|
|
249
|
+
draft.slots[nameOf('text', n)] = asValue(item.text);
|
|
250
|
+
}
|
|
251
|
+
for (const part of ['icon', 'picture']) {
|
|
252
|
+
const place = row.parts.get(part)?.slot;
|
|
253
|
+
const kind = content.itemPictures.find((picture) => picture.part === part)?.kind;
|
|
254
|
+
if (item[part] && place?.kind === 'image' && place.imageKind === kind)
|
|
255
|
+
draft.slots[nameOf(part, n)] = item[part];
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
for (const picture of content.itemPictures) {
|
|
259
|
+
const place = row.parts.get(picture.part)?.slot;
|
|
260
|
+
if (place?.kind === 'image' && place.imageKind === picture.kind)
|
|
261
|
+
continue;
|
|
262
|
+
if (!illustrates(picture.kind))
|
|
263
|
+
no();
|
|
264
|
+
draft.dropped.push(picture.from);
|
|
265
|
+
}
|
|
266
|
+
if (content.itemName !== itemWord)
|
|
267
|
+
draft.changes.push(`The ${plural(count, content.itemName)} became ${plural(count, itemWord)}.`);
|
|
268
|
+
if (merged)
|
|
269
|
+
draft.changes.push(`Each ${itemWord} is written as one text, "heading: text".`);
|
|
270
|
+
if (apart)
|
|
271
|
+
draft.changes.push(`Each ${itemWord} was split at the colon into a heading and a text.`);
|
|
272
|
+
}
|
|
273
|
+
else if (count > 0) {
|
|
274
|
+
// Items into a list: one point for each item.
|
|
275
|
+
const body = shape.body;
|
|
276
|
+
if (!body || content.body || !isList(body) || !content.items.every(oneLine))
|
|
277
|
+
return no();
|
|
278
|
+
if (content.itemPictures.some((picture) => !illustrates(picture.kind)))
|
|
279
|
+
no();
|
|
280
|
+
draft.slots[body.name] = content.items.map((item) => joined(item.figure ?? item.heading, item.text));
|
|
281
|
+
draft.dropped.push(...content.itemPictures.map((picture) => picture.from));
|
|
282
|
+
const lead = content.items.some((item) => item.figure) ? 'figure' : 'heading';
|
|
283
|
+
const written = content.items.some((item) => (item.figure ?? item.heading) && item.text) ? `, each written as "${lead}: text"` : '';
|
|
284
|
+
draft.changes.push(`The ${plural(count, content.itemName)} became a list of ${plural(count, 'point')}${written}.`);
|
|
285
|
+
}
|
|
286
|
+
else if (row && range) {
|
|
287
|
+
// A list into items: one item for each point.
|
|
288
|
+
const points = content.body;
|
|
289
|
+
if (!points || !row.clear || points.length < 2 || points.length < range.min || points.length > range.max || row.parts.has('figure') || !row.parts.has('text'))
|
|
290
|
+
return no();
|
|
291
|
+
draft.items = points.length;
|
|
292
|
+
if (row.parts.has('heading')) {
|
|
293
|
+
// The items want a heading and a text each: only a list written "heading: text" gives both.
|
|
294
|
+
const halves = points.map(split);
|
|
295
|
+
if (!halves.every((half) => half !== undefined))
|
|
296
|
+
no();
|
|
297
|
+
halves.forEach((half, index) => {
|
|
298
|
+
draft.slots[nameOf('heading', index + 1)] = half[0];
|
|
299
|
+
draft.slots[nameOf('text', index + 1)] = half[1];
|
|
300
|
+
});
|
|
301
|
+
draft.changes.push(`The ${plural(points.length, 'point')} became ${plural(points.length, itemWord)}, each split at the colon into a heading and a text.`);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
points.forEach((point, index) => (draft.slots[nameOf('text', index + 1)] = point));
|
|
305
|
+
draft.changes.push(`The ${plural(points.length, 'point')} became ${plural(points.length, itemWord)}.`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
put(shape.body, content.body);
|
|
310
|
+
// The words are the same; whether they show as points or as paragraphs is the new slot's own formatting.
|
|
311
|
+
const lines = content.body?.length ?? 0;
|
|
312
|
+
if (lines > 1 && content.bodyIsList !== isList(shape.body)) {
|
|
313
|
+
draft.changes.push(content.bodyIsList ? `The ${plural(lines, 'point')} of the list are written as ${plural(lines, 'paragraph')}.` : `The ${plural(lines, 'paragraph')} became a list of ${plural(lines, 'point')}.`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return draft;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Lists the other patterns that can hold what one slide of a deck says, with the slide written
|
|
320
|
+
* for each. `slide` is the slide's number in the deck, from 1. No model is asked and no text is
|
|
321
|
+
* rewritten: a title stays a title, and a row of items becomes other items or a list of points.
|
|
322
|
+
*
|
|
323
|
+
* A pattern is an alternative when every text, table, chart and supplied graphic of the slide
|
|
324
|
+
* has a place in it and every slot it requires can be filled. A photo or an icon may be left
|
|
325
|
+
* out, which `dropped` reports. A text that is longer than its new slot holds is reported in
|
|
326
|
+
* `warnings`, as `validateDeck` would. Alternatives that fit without a warning come first.
|
|
327
|
+
*/
|
|
328
|
+
export function slideAlternatives(manifest, deck, slide, options = {}) {
|
|
329
|
+
const original = deck.slides[slide - 1];
|
|
330
|
+
if (!original)
|
|
331
|
+
throw new RangeError(`the deck has ${deck.slides.length} slides; there is no slide ${slide}`);
|
|
332
|
+
const source = manifest.patterns.find((pattern) => pattern.id === original.pattern);
|
|
333
|
+
if (!source)
|
|
334
|
+
throw new Error(`slide ${slide} uses the pattern "${original.pattern}", which the manifest does not have`);
|
|
335
|
+
const layout = options.layout ?? 'strict';
|
|
336
|
+
const filled = { ...original, slots: original.slots ?? {} };
|
|
337
|
+
const content = contentOf(source, anatomy(source), filled);
|
|
338
|
+
const found = [];
|
|
339
|
+
for (const target of manifest.patterns) {
|
|
340
|
+
if (target === source || (options.patterns && !options.patterns.includes(target.id)))
|
|
341
|
+
continue;
|
|
342
|
+
// Slot for slot where the names agree, which is exact; by what the slots are for where they do not.
|
|
343
|
+
for (const attempt of [() => byName(source, target, filled), () => byParts(content, target, anatomy(target))]) {
|
|
344
|
+
let draft;
|
|
345
|
+
try {
|
|
346
|
+
draft = attempt();
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
if (!(error instanceof NoPlace))
|
|
350
|
+
throw error;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
const written = { pattern: target.id, slots: draft.slots };
|
|
354
|
+
if (draft.items !== undefined)
|
|
355
|
+
written.items = draft.items;
|
|
356
|
+
// The renderer's own rules decide whether the slide can be made: a required slot left empty is an error.
|
|
357
|
+
const issues = validateDeck(manifest, { ...deck, slides: [written] }, { layout });
|
|
358
|
+
if (issues.some((issue) => issue.severity === 'error'))
|
|
359
|
+
continue;
|
|
360
|
+
found.push({ pattern: target.id, description: target.description, slide: written, changes: draft.changes, dropped: draft.dropped, warnings: issues.map((issue) => ({ ...issue, slide })) });
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const rank = (alternative) => (alternative.warnings.length > 0 ? 2 : alternative.dropped.length > 0 ? 1 : 0);
|
|
365
|
+
return found
|
|
366
|
+
.map((alternative, index) => ({ alternative, index }))
|
|
367
|
+
.sort((a, b) => rank(a.alternative) - rank(b.alternative) || a.index - b.index)
|
|
368
|
+
.map((entry) => entry.alternative);
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=alternatives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alternatives.js","sourceRoot":"","sources":["../../src/deck/alternatives.ts"],"names":[],"mappings":"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"}
|