Download services/slides/src/render.ts from wassemgtk/glm-5.2-visual-runtime: direct link, hf CLI and curl.
- Browser
- Download file 2.49 kB
-
https://huggingface.co/wassemgtk/glm-5.2-visual-runtime/resolve/main/services/slides/src/render.ts
- Command line
-
hf download hf://wassemgtk/glm-5.2-visual-runtime/services/slides/src/render.ts
-
curl -L -o render.ts https://huggingface.co/wassemgtk/glm-5.2-visual-runtime/resolve/main/services/slides/src/render.ts
2.49 kB
| import * as PptxModule from "pptxgenjs"; | |
| import { cleanHex, normalizeTheme } from "./themes.js"; | |
| export type SlideSpec = { | |
| layout: "title" | "section" | "bullets" | "chart_and_insight" | "image_reference"; | |
| title: string; | |
| subtitle?: string; | |
| bullets?: string[]; | |
| insights?: string[]; | |
| notes?: string; | |
| }; | |
| export type PresentationSpec = { | |
| title: string; | |
| theme: Record<string, unknown>; | |
| slides: SlideSpec[]; | |
| provenance?: Record<string, unknown>[]; | |
| }; | |
| export async function renderPresentation(spec: PresentationSpec): Promise<Buffer> { | |
| const PptxGenJS = ((PptxModule as unknown as { default?: unknown }).default ?? PptxModule) as new () => any; | |
| const pptx = new PptxGenJS(); | |
| pptx.layout = "LAYOUT_WIDE"; | |
| pptx.author = "GLM Visual Variable Runtime"; | |
| pptx.subject = "Generated from visual evidence"; | |
| pptx.title = spec.title; | |
| const theme = normalizeTheme(spec.theme); | |
| pptx.defineSlideMaster({ | |
| title: "VVR_MASTER", | |
| background: { color: cleanHex(theme.background) }, | |
| objects: [ | |
| { rect: { x: 0, y: 0, w: 13.333, h: 0.12, fill: { color: cleanHex(theme.accent) }, line: { color: cleanHex(theme.accent) } } } | |
| ], | |
| slideNumber: { x: 12.3, y: 7.15, color: cleanHex(theme.secondary) } | |
| }); | |
| const slides = spec.slides.length ? spec.slides : [{ layout: "title" as const, title: spec.title }]; | |
| for (const item of slides) { | |
| const slide = pptx.addSlide("VVR_MASTER"); | |
| slide.addText(item.title, { | |
| x: 0.7, | |
| y: 0.65, | |
| w: 11.9, | |
| h: 0.6, | |
| fontFace: "Aptos Display", | |
| fontSize: item.layout === "title" ? 34 : 26, | |
| bold: true, | |
| color: cleanHex(theme.primary), | |
| margin: 0 | |
| }); | |
| if (item.subtitle) { | |
| slide.addText(item.subtitle, { x: 0.75, y: 1.35, w: 11.7, h: 0.4, fontSize: 16, color: cleanHex(theme.secondary) }); | |
| } | |
| const bullets = [...(item.bullets ?? []), ...(item.insights ?? [])]; | |
| if (bullets.length) { | |
| slide.addText(bullets.map((text) => ({ text, options: { bullet: { indent: 14 }, hanging: 4 } })), { | |
| x: 0.9, | |
| y: 2.0, | |
| w: 11.4, | |
| h: 4.6, | |
| fontSize: 18, | |
| color: cleanHex(theme.text_dark), | |
| breakLine: false, | |
| fit: "shrink" | |
| }); | |
| } | |
| if (item.notes || spec.provenance?.length) { | |
| slide.addNotes(`Provenance: ${JSON.stringify(spec.provenance ?? [])}\n${item.notes ?? ""}`); | |
| } | |
| } | |
| const data = await pptx.write({ outputType: "nodebuffer" }); | |
| return Buffer.from(data as ArrayBuffer); | |
| } | |