html-native-pptx 0.1.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.
@@ -0,0 +1,337 @@
1
+ import { Browser } from 'puppeteer';
2
+
3
+ /**
4
+ * Intermediate Representation (IR) AST for html-native-pptx.
5
+ * Decouples the DOM crawler (Harvester) from the PresentationML generator (Compiler).
6
+ */
7
+ declare const UNITS: {
8
+ readonly DPI: 96;
9
+ readonly PT_PER_INCH: 72;
10
+ readonly EMU_PER_INCH: 914400;
11
+ readonly SLIDE_16_9_WIDTH_INCHES: 13.333333;
12
+ readonly SLIDE_16_9_HEIGHT_INCHES: 7.5;
13
+ readonly SLIDE_16_9_WIDTH_EMU: 12192000;
14
+ readonly SLIDE_16_9_HEIGHT_EMU: 6858000;
15
+ readonly SLIDE_4_3_WIDTH_INCHES: 10;
16
+ readonly SLIDE_4_3_HEIGHT_INCHES: 7.5;
17
+ readonly SLIDE_4_3_WIDTH_EMU: 9144000;
18
+ readonly SLIDE_4_3_HEIGHT_EMU: 6858000;
19
+ };
20
+ type ElementType = 'container' | 'text' | 'image' | 'table';
21
+ type TextAlign = 'left' | 'center' | 'right' | 'justify';
22
+ /**
23
+ * Normalized bounding box in Inches.
24
+ */
25
+ interface BoundingBox {
26
+ x: number;
27
+ y: number;
28
+ w: number;
29
+ h: number;
30
+ }
31
+ /**
32
+ * Visual styling for rectangular containers and shapes.
33
+ */
34
+ interface ShapeStyle {
35
+ fillColor?: string;
36
+ fillOpacity?: number;
37
+ borderColor?: string;
38
+ borderWidth?: number;
39
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
40
+ radius?: number;
41
+ shadow?: {
42
+ color: string;
43
+ blur: number;
44
+ offsetX: number;
45
+ offsetY: number;
46
+ opacity?: number;
47
+ };
48
+ }
49
+ /**
50
+ * Individual formatted text run inside a paragraph (maps to OpenXML <a:r>).
51
+ */
52
+ interface TextRun {
53
+ content: string;
54
+ fontFamily?: string;
55
+ fontSize?: number;
56
+ color?: string;
57
+ bold?: boolean;
58
+ italic?: boolean;
59
+ underline?: boolean;
60
+ strikethrough?: boolean;
61
+ }
62
+ /**
63
+ * Paragraph containing one or more formatted text runs (maps to OpenXML <a:p>).
64
+ */
65
+ interface ParagraphIR {
66
+ align?: TextAlign;
67
+ lineHeight?: number;
68
+ spaceBefore?: number;
69
+ spaceAfter?: number;
70
+ runs: TextRun[];
71
+ }
72
+ /**
73
+ * Flat text style convenience interface (for simple, single-style text elements).
74
+ */
75
+ interface TextStyle {
76
+ fontFamily: string;
77
+ fontSize: number;
78
+ color: string;
79
+ bold?: boolean;
80
+ italic?: boolean;
81
+ underline?: boolean;
82
+ align?: TextAlign;
83
+ }
84
+ /**
85
+ * Primary Abstract Syntax Tree (AST) node.
86
+ */
87
+ interface IRNode {
88
+ id?: string | number;
89
+ name?: string;
90
+ type: ElementType;
91
+ box: BoundingBox;
92
+ zIndex?: number;
93
+ shapeStyle?: ShapeStyle;
94
+ content?: string;
95
+ textStyle?: TextStyle;
96
+ paragraphs?: ParagraphIR[];
97
+ children?: IRNode[];
98
+ }
99
+ /**
100
+ * Embedded font IR representing a portable font stream for OpenXML (.fntdata).
101
+ */
102
+ interface EmbeddedFontIR {
103
+ typeface: string;
104
+ fntData: Buffer;
105
+ }
106
+ /**
107
+ * Complete Intermediate Representation for a single slide.
108
+ */
109
+ interface SlideIR {
110
+ width: number;
111
+ height: number;
112
+ backgroundColor?: string;
113
+ elements: IRNode[];
114
+ fonts?: EmbeddedFontIR[];
115
+ }
116
+ /**
117
+ * Multi-slide presentation IR container with global presentation metadata.
118
+ */
119
+ interface PresentationIR {
120
+ slides: SlideIR[];
121
+ fonts?: EmbeddedFontIR[];
122
+ }
123
+
124
+ type SlideAspect = '16:9' | '4:3';
125
+ interface ViewportOptions {
126
+ width: number;
127
+ height: number;
128
+ deviceScaleFactor?: number;
129
+ }
130
+ interface EmbeddedFontOption {
131
+ /**
132
+ * Font family / typeface name (e.g. "Telkomsel Batik Sans").
133
+ */
134
+ typeface: string;
135
+ /**
136
+ * Source font file path (.ttf, .otf, .eot, .fntdata), HTTP(S) URL, data URI, or raw Buffer.
137
+ */
138
+ src: string | Buffer;
139
+ }
140
+ interface ConvertOptions {
141
+ /**
142
+ * Presentation aspect ratio. Defaults to '16:9'.
143
+ */
144
+ aspect?: SlideAspect;
145
+ /**
146
+ * Browser viewport dimensions for headless layout resolution.
147
+ * Defaults to 1920x1080 for 16:9, or 1024x768 for 4:3.
148
+ */
149
+ viewport?: ViewportOptions;
150
+ /**
151
+ * CSS selector for the root container element to capture as slide.
152
+ * Defaults to 'body'.
153
+ */
154
+ selector?: string;
155
+ /**
156
+ * Optional CSS selector to detect and extract multi-slide presentations.
157
+ * e.g., '.slide' or 'section.slide'. If matching elements are found,
158
+ * every slide will be extracted into a separate slide in the presentation.
159
+ */
160
+ slideSelector?: string;
161
+ /**
162
+ * Timeout in milliseconds for rendering/waiting.
163
+ * Defaults to 30000ms (30s).
164
+ */
165
+ timeout?: number;
166
+ /**
167
+ * Wait until specific condition before harvesting DOM.
168
+ * 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
169
+ */
170
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
171
+ /**
172
+ * Optional pre-existing Puppeteer browser instance.
173
+ * If supplied, html-native-pptx will reuse it rather than launching a new Chromium process.
174
+ */
175
+ browser?: Browser;
176
+ /**
177
+ * Optional WebSocket endpoint to connect to a remote Chromium (e.g. Browserless.io).
178
+ */
179
+ browserWSEndpoint?: string;
180
+ /**
181
+ * Optional list of custom fonts to embed into the PowerPoint presentation.
182
+ */
183
+ fonts?: EmbeddedFontOption[];
184
+ /**
185
+ * Whether to automatically detect @font-face rules in HTML/CSS and embed them.
186
+ * Defaults to true.
187
+ */
188
+ autoEmbedFonts?: boolean;
189
+ /**
190
+ * Base directory path used to resolve relative font paths and asset URLs.
191
+ * Defaults to process.cwd().
192
+ */
193
+ basePath?: string;
194
+ }
195
+
196
+ /**
197
+ * Convert pixels to inches given a DPI and optional coordinate scale factor.
198
+ */
199
+ declare function pxToInches(px: number, dpi?: number, scale?: number): number;
200
+ /**
201
+ * Convert inches to English Metric Units (EMU).
202
+ * 1 inch = 914,400 EMU.
203
+ */
204
+ declare function inchesToEmu(inches: number): number;
205
+ /**
206
+ * Direct conversion from pixels to EMU.
207
+ */
208
+ declare function pxToEmu(px: number, dpi?: number, scale?: number): number;
209
+ /**
210
+ * Convert pixel font size to points (pt).
211
+ * 1 inch = 72 pt = 96 px -> 1 px = 0.75 pt.
212
+ */
213
+ declare function pxToPt(px: number, dpi?: number): number;
214
+ /**
215
+ * Convert points to hundredths of a point (used by OpenXML sz attribute).
216
+ * e.g., 16pt -> 1600.
217
+ */
218
+ declare function ptToHundredthPt(pt: number): number;
219
+ /**
220
+ * Convert CSS border-radius (in pixels) to OpenXML rounded rectangle adjustment guide value (0 - 50000).
221
+ * In OpenXML, an adj value of 50000 represents a radius equal to half the shortest dimension.
222
+ */
223
+ declare function borderRadiusToGuide(radiusPx: number, widthPx: number, heightPx: number): number;
224
+
225
+ interface ColorResult {
226
+ hex: string;
227
+ opacity?: number;
228
+ }
229
+ /**
230
+ * Normalizes any CSS color string (rgb, rgba, hex, named) into a 6-character uppercase hex string.
231
+ * Returns undefined if transparent or invalid.
232
+ */
233
+ declare function normalizeHexColor(cssColor?: string): ColorResult | undefined;
234
+ /**
235
+ * Normalizes CSS font-weight into a boolean representing bold.
236
+ */
237
+ declare function normalizeFontWeight(fontWeight?: string | number): boolean;
238
+ /**
239
+ * Normalizes CSS font-style into a boolean representing italic.
240
+ */
241
+ declare function normalizeFontStyle(fontStyle?: string): boolean;
242
+ /**
243
+ * Normalizes CSS font-family string by extracting the primary font family without quotes.
244
+ */
245
+ declare function normalizeFontFamily(fontFamily?: string): string;
246
+ /**
247
+ * Normalizes CSS text-align to IR TextAlign.
248
+ */
249
+ declare function normalizeTextAlign(textAlign?: string): TextAlign;
250
+ /**
251
+ * Normalizes CSS border-style to supported IR border types.
252
+ */
253
+ declare function normalizeBorderStyle(borderStyle?: string): 'solid' | 'dashed' | 'dotted';
254
+
255
+ /**
256
+ * Normalizes a typeface name by stripping quotes and taking the primary family.
257
+ */
258
+ declare function cleanTypeface(name: string): string;
259
+ /**
260
+ * Checks if a buffer contains Microsoft Embedded OpenType (EOT) binary data.
261
+ */
262
+ declare function isEotBuffer(buf: Buffer): boolean;
263
+ /**
264
+ * Converts TrueType (TTF) or OpenType (OTF) font buffer into Microsoft EOT format.
265
+ */
266
+ declare function convertTtfToEot(buf: Buffer): Buffer;
267
+ /**
268
+ * Loads font data from a buffer, data URI, web URL, or local file path.
269
+ */
270
+ declare function loadFontBuffer(src: string | Buffer, basePath?: string): Promise<Buffer | null>;
271
+ /**
272
+ * Extracts @font-face rules from raw HTML string or CSS text.
273
+ */
274
+ declare function extractFontFacesFromHtml(html: string): Array<{
275
+ typeface: string;
276
+ src: string;
277
+ }>;
278
+ /**
279
+ * Resolves, deduplicates, and converts font options and discovered @font-face rules into EmbeddedFontIR items.
280
+ */
281
+ declare function resolveAndEmbedFonts(options: {
282
+ html?: string;
283
+ userFonts?: EmbeddedFontOption[];
284
+ autoEmbedFonts?: boolean;
285
+ basePath?: string;
286
+ discoveredFonts?: Array<{
287
+ typeface: string;
288
+ src: string;
289
+ }>;
290
+ }): Promise<EmbeddedFontIR[]>;
291
+
292
+ declare function harvestHtmlToIR(htmlOrUrl: string, options?: ConvertOptions): Promise<SlideIR | SlideIR[]>;
293
+
294
+ interface HarvestOptions {
295
+ selector?: string;
296
+ viewportWidth: number;
297
+ viewportHeight: number;
298
+ aspect?: '16:9' | '4:3';
299
+ }
300
+ /**
301
+ * In-browser evaluation function to harvest DOM tree and compile it to SlideIR.
302
+ * Designed to execute inside Puppeteer's page.evaluate().
303
+ */
304
+ declare function extractDomToSlideIR(options: HarvestOptions): SlideIR;
305
+
306
+ interface CompileOptions {
307
+ fonts?: EmbeddedFontIR[];
308
+ }
309
+ /**
310
+ * Compiles a single SlideIR, an array of SlideIRs, or a PresentationIR into a valid PowerPoint (.pptx) file Buffer using OpenXML and JSZip.
311
+ */
312
+ declare function compileSlideToPptx(slideOrSlidesOrPres: SlideIR | SlideIR[] | PresentationIR, options?: CompileOptions): Promise<Buffer>;
313
+
314
+ /**
315
+ * Compiles a container IRNode into OpenXML <p:sp> element.
316
+ */
317
+ declare function compileContainerShape(node: IRNode, id: number): string;
318
+
319
+ /**
320
+ * Compiles a text IRNode into an OpenXML <p:sp> textbox element with zero internal margins.
321
+ */
322
+ declare function compileTextShape(node: IRNode, id: number): string;
323
+
324
+ /**
325
+ * Main conversion API: Converts an HTML string or URL into a native, editable PowerPoint (.pptx) buffer.
326
+ *
327
+ * @param html - Raw HTML string or valid http(s) URL.
328
+ * @param options - Configuration options for viewport, aspect ratio, or browser instance.
329
+ * @returns Promise resolving to a Node.js Buffer representing the .pptx file.
330
+ */
331
+ declare function convertHtmlToPptx(html: string, options?: ConvertOptions): Promise<Buffer>;
332
+ /**
333
+ * Helper to construct a blank SlideIR with standard 16:9 or 4:3 dimensions.
334
+ */
335
+ declare function createSlideIR(aspect?: '16:9' | '4:3'): SlideIR;
336
+
337
+ export { type BoundingBox, type ColorResult, type ConvertOptions, type ElementType, type EmbeddedFontIR, type EmbeddedFontOption, type IRNode, type ParagraphIR, type PresentationIR, type ShapeStyle, type SlideAspect, type SlideIR, type TextAlign, type TextRun, type TextStyle, UNITS, type ViewportOptions, borderRadiusToGuide, cleanTypeface, compileContainerShape, compileSlideToPptx, compileTextShape, convertHtmlToPptx, convertTtfToEot, createSlideIR, extractDomToSlideIR, extractFontFacesFromHtml, harvestHtmlToIR, inchesToEmu, isEotBuffer, loadFontBuffer, normalizeBorderStyle, normalizeFontFamily, normalizeFontStyle, normalizeFontWeight, normalizeHexColor, normalizeTextAlign, ptToHundredthPt, pxToEmu, pxToInches, pxToPt, resolveAndEmbedFonts };