const fs = require('fs/promises'); const path = require('path'); const { chromium } = require('playwright'); const pptxgen = require('pptxgenjs'); const inputUrl = process.argv[2]; const imageDir = process.argv[3]; const outputPptx = process.argv[4]; async function extractNotes(url) { const launchOptions = { headless: true }; if (process.env.BROWSER_EXE) { launchOptions.executablePath = process.env.BROWSER_EXE; } const browser = await chromium.launch(launchOptions); const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); const baseUrl = url.includes('#') ? url.slice(0, url.indexOf('#')) : url; await page.goto(`${baseUrl}#1`, { waitUntil: 'load', timeout: 30000 }); await page.waitForSelector('#speaker-notes', { state: 'attached', timeout: 10000 }); const notes = await page.evaluate(() => JSON.parse(document.getElementById('speaker-notes').textContent)); await browser.close(); return notes; } (async () => { if (!inputUrl || !imageDir || !outputPptx) { throw new Error('Usage: node html_to_ppt_with_notes.js '); } const notes = await extractNotes(inputUrl); const images = (await fs.readdir(imageDir)) .filter((name) => /^slide_\d+\.png$/i.test(name)) .sort() .map((name) => path.join(imageDir, name)); if (notes.length !== images.length) { throw new Error(`Notes count (${notes.length}) does not match image count (${images.length})`); } await fs.mkdir(path.dirname(outputPptx), { recursive: true }); await fs.writeFile( path.join(path.dirname(outputPptx), 'Generative_Image_Dynamics.notes.json'), JSON.stringify(notes.map((text, index) => ({ slide: index + 1, text })), null, 2), 'utf8', ); const pptx = new pptxgen(); pptx.layout = 'LAYOUT_WIDE'; pptx.author = 'Codex'; pptx.subject = 'Generative Image Dynamics — CVPR 2024'; pptx.title = 'Generative Image Dynamics'; pptx.company = ''; pptx.lang = 'en-US'; pptx.theme = { headFontFace: 'Aptos', bodyFontFace: 'Aptos', lang: 'en-US', }; for (let i = 0; i < images.length; i += 1) { const slide = pptx.addSlide(); slide.background = { color: '000000' }; slide.addImage({ path: images[i], x: 0, y: 0, w: 13.333333, h: 7.5 }); slide.addNotes(notes[i]); } await pptx.writeFile({ fileName: outputPptx }); console.log(`pptx=${outputPptx}`); console.log(`slides=${images.length}`); console.log(`notes=${notes.length}`); })().catch((err) => { console.error(err); process.exit(1); });