@openpresentation/opf 0.6.0 → 0.8.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.
@@ -1,3 +1,46 @@
1
+ /** Canonical table grid. No renderer, fonts, DOM or network dependencies. */
2
+ interface TableBorder {
3
+ color: string;
4
+ width: number;
5
+ dash?: 'solid' | 'dash' | 'dot';
6
+ }
7
+ interface TableCellStyle {
8
+ fill?: string;
9
+ color?: string;
10
+ align?: 'left' | 'center' | 'right';
11
+ verticalAlign?: 'top' | 'middle' | 'bottom';
12
+ padding?: Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
13
+ borders?: Partial<Record<'top' | 'right' | 'bottom' | 'left', TableBorder>>;
14
+ }
15
+ interface TableGridCell {
16
+ input: unknown;
17
+ value: unknown;
18
+ style: TableCellStyle;
19
+ row: number;
20
+ column: number;
21
+ rowSpan: number;
22
+ colSpan: number;
23
+ header: boolean;
24
+ path: string;
25
+ valuePath: string;
26
+ }
27
+ interface TableGridIssue {
28
+ path: string;
29
+ message: string;
30
+ }
31
+ interface TableGrid {
32
+ rows: TableGridCell[][];
33
+ columnCount: number;
34
+ rowCount: number;
35
+ hasHeaders: boolean;
36
+ /** Anchor at each covered position; covered positions are not additional cells. */
37
+ owners: (TableGridCell | undefined)[][];
38
+ issues: TableGridIssue[];
39
+ }
40
+ declare function tableGrid(value: unknown, path?: string): TableGrid;
41
+ /** Row boundaries that preserve every vertical merge, used by pagination. */
42
+ declare function tableRowBoundaries(value: unknown): number[];
43
+
1
44
  /** Portable layout geometry. No fonts, DOM, renderer, or network dependencies. */
2
45
  interface Composition {
3
46
  mode?: "auto" | "grid" | "row" | "column";
@@ -54,6 +97,8 @@ interface ComposedItem {
54
97
  box: LayoutBox;
55
98
  text?: TextFit | RichTextFit | ListFit;
56
99
  textStyle?: TextStyle;
100
+ /** Complete accepted quote internals; consumers must reuse these fits and styles. */
101
+ quoteLayout?: QuoteLayout;
57
102
  /** Effective container settings, including inherited readability constraints. */
58
103
  composition: Composition;
59
104
  }
@@ -78,6 +123,37 @@ interface ComposedFlow {
78
123
  itemCount: number;
79
124
  slotCount: number;
80
125
  }
126
+ /** Additive penalties in grid-score-v2; lower is preferred. These are not quality percentages. */
127
+ interface CompositionPenalties {
128
+ cellProportions: number;
129
+ fontReduction: number;
130
+ textOverflow: number;
131
+ tableOverflow: number;
132
+ smallCells: number;
133
+ emptySlots: number;
134
+ }
135
+ interface CompositionCandidate {
136
+ columns: number;
137
+ rows: number;
138
+ score: number;
139
+ penalties: CompositionPenalties;
140
+ }
141
+ interface CompositionDecision {
142
+ path: string;
143
+ mode: NonNullable<Composition['mode']> | 'regions';
144
+ reason: 'lowest-score' | 'configured-mode' | 'promoted-regions';
145
+ selectedColumns?: number;
146
+ /** Only candidates actually evaluated by automatic selection, in tie-break order. */
147
+ candidates: CompositionCandidate[];
148
+ }
149
+ interface CompositionExplanation {
150
+ algorithm: 'grid-score-v2';
151
+ /** Provided widths do not establish shaping, glyph coverage or native fidelity. */
152
+ textMeasurement: 'estimated' | 'provided';
153
+ decisions: CompositionDecision[];
154
+ /** Payloads whose complete internal fit is not covered by this scoring model. */
155
+ unmeasuredPayloads: string[];
156
+ }
81
157
  interface SlideComposition {
82
158
  width: number;
83
159
  height: number;
@@ -87,6 +163,7 @@ interface SlideComposition {
87
163
  flows: ComposedFlow[];
88
164
  diagnostics: LayoutDiagnostic[];
89
165
  composition: Composition;
166
+ explanation?: CompositionExplanation;
90
167
  }
91
168
  interface ComposeSlideOptions {
92
169
  fonts?: Partial<FontFamilies>;
@@ -95,16 +172,72 @@ interface ComposeSlideOptions {
95
172
  height?: number;
96
173
  slideIndex?: number;
97
174
  layout?: Record<string, unknown>;
175
+ /** Return candidate scores and coverage without changing the selected geometry. */
176
+ explain?: boolean;
98
177
  }
99
178
  declare class OPFCompositionError extends Error {
100
179
  readonly diagnostics: LayoutDiagnostic[];
101
180
  readonly code = "layout-overflow";
102
- constructor(diagnostics: LayoutDiagnostic[]);
181
+ readonly explanation?: CompositionExplanation;
182
+ constructor(diagnostics: LayoutDiagnostic[], explanation?: CompositionExplanation);
103
183
  }
104
184
  /** Deterministic estimate, not a font shaping engine. Preserves explicit line breaks. */
105
185
  declare function measureText(text: string, fontSize: number): number;
106
186
  declare function wrapText(text: string, width: number, fontSize: number, measure?: MeasureTextWidth): string[];
107
187
  declare function fitText(text: string, box: LayoutBox, requestedSize?: number, minFontSize?: number, measure?: MeasureTextWidth): TextFit;
188
+ interface QuoteContent {
189
+ text: string;
190
+ attribution?: string;
191
+ source?: string;
192
+ }
193
+ /** Source and displayed-text ranges are half-open UTF-16 offsets. Added punctuation has no source range. */
194
+ interface QuoteTextSource {
195
+ path: string;
196
+ start: number;
197
+ end: number;
198
+ outputStart: number;
199
+ outputEnd: number;
200
+ }
201
+ interface QuoteTextPart {
202
+ role: 'body' | 'footer';
203
+ path: string;
204
+ text: string;
205
+ sources: QuoteTextSource[];
206
+ /** Available space, before fitting. Invalid dimensions remain visible in failed results. */
207
+ box: LayoutBox;
208
+ requestedFontSize: number;
209
+ minFontSize: number;
210
+ requestedStyle: TextStyle;
211
+ style: TextStyle;
212
+ /** Absent when the available box is invalid; never fit against an invented one-pixel box. */
213
+ fit?: TextFit;
214
+ }
215
+ interface QuoteLayoutDiagnostic extends LayoutDiagnostic {
216
+ reason: 'invalid-part-box' | 'part-outside-cell' | 'text-fit' | 'part-overlap';
217
+ parts: QuoteTextPart['role'][];
218
+ }
219
+ interface QuoteLayout {
220
+ algorithm: 'quote-flow-v1';
221
+ textMeasurement: 'estimated' | 'provided';
222
+ parts: QuoteTextPart[];
223
+ diagnostics: QuoteLayoutDiagnostic[];
224
+ overflow: boolean;
225
+ }
226
+ interface QuoteLayoutOptions {
227
+ /** Canvas short edge divided by 720. Insets retain the current 18 reference-pixel contract. */
228
+ scale?: number;
229
+ fonts?: Partial<FontFamilies>;
230
+ /** Readability floor in reference pixels, before canvas scaling. */
231
+ minFontSize?: number;
232
+ overflow?: Composition['overflow'];
233
+ path?: string;
234
+ textMeasurement?: TextMeasurement;
235
+ }
236
+ /**
237
+ * Allocate and measure quote body/footer space for composition, rendering and export. Callers must
238
+ * check overflow before accepting the parts. Line boxes are not shaped glyph or native raster bounds.
239
+ */
240
+ declare function layoutQuote(value: string | QuoteContent, box: LayoutBox, options?: QuoteLayoutOptions): QuoteLayout;
108
241
  interface RichTextRun {
109
242
  text: string;
110
243
  bold?: boolean;
@@ -190,6 +323,13 @@ interface TableLayoutOptions {
190
323
  }
191
324
  interface TableCellLayout {
192
325
  value: unknown;
326
+ input: unknown;
327
+ sourcePath: string;
328
+ style: TableCellStyle;
329
+ row: number;
330
+ column: number;
331
+ rowSpan: number;
332
+ colSpan: number;
193
333
  path: string;
194
334
  header: boolean;
195
335
  rich: boolean;
@@ -222,4 +362,4 @@ declare function resolveCanvasDimensions(input: unknown): {
222
362
  height: number;
223
363
  };
224
364
 
225
- export { type ComposeSlideOptions, type ComposedFlow, type ComposedGroup, type ComposedItem, type Composition, type CompositionTrack, type FontFamilies, type LayoutBox, type LayoutDiagnostic, type ListEntryLayout, type ListFit, type ListText, type ListValue, MAX_COMPOSITION_DEPTH, type MeasureTextWidth, OPFCompositionError, type RichTextFit, type RichTextFragment, type RichTextLine, type RichTextOptions, type RichTextRun, type SlideComposition, type TableCellLayout, type TableLayout, type TableLayoutOptions, type TableRowLayout, type TextFit, type TextMeasurement, type TextStyle, composeSlide, fitList, fitRichText, fitText, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText };
365
+ export { type ComposeSlideOptions, type ComposedFlow, type ComposedGroup, type ComposedItem, type Composition, type CompositionCandidate, type CompositionDecision, type CompositionExplanation, type CompositionPenalties, type CompositionTrack, type FontFamilies, type LayoutBox, type LayoutDiagnostic, type ListEntryLayout, type ListFit, type ListText, type ListValue, MAX_COMPOSITION_DEPTH, type MeasureTextWidth, OPFCompositionError, type QuoteContent, type QuoteLayout, type QuoteLayoutDiagnostic, type QuoteLayoutOptions, type QuoteTextPart, type QuoteTextSource, type RichTextFit, type RichTextFragment, type RichTextLine, type RichTextOptions, type RichTextRun, type SlideComposition, type TableBorder, type TableCellLayout, type TableCellStyle, type TableGrid, type TableGridCell, type TableGridIssue, type TableLayout, type TableLayoutOptions, type TableRowLayout, type TextFit, type TextMeasurement, type TextStyle, composeSlide, fitList, fitRichText, fitText, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText };
@@ -1 +1 @@
1
- export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText } from './chunk-C7GKRLI6.js';
1
+ export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText } from './chunk-NEQAPMS2.js';