import fs from 'node:fs'; import path from 'node:path'; import JSZip from 'jszip'; import { glob } from 'glob'; function switchToStaticScripts(htmlContent) { // Look for the module script block and capture indentation const moduleScriptPattern = /(\s*)`); const replacement = '\n\n' + scriptTags.join('\n') + `\n${indentation}`; return htmlContent.replace(moduleScriptPattern, replacement); } /** * Replace paths to dynamic CSS/SCSS files with static ones. */ function switchToStaticStyles(htmlContent) { // Replace /css/* links with /dist/* htmlContent = htmlContent.replace(/href="css\/([^"]+\.(css|scss))"/g, (match, filePath) => { const cssPath = filePath.replace(/\.scss$/, '.css'); return `href="dist/${cssPath}"`; }); // Replace /plugin/* links with /dist/plugin/* htmlContent = htmlContent.replace(/href="plugin\/([^"]+\.(css|scss))"/g, (match, filePath) => { const cssPath = filePath.replace(/\.scss$/, '.css'); return `href="dist/plugin/${cssPath}"`; }); return htmlContent; } async function main() { // Parse command line arguments for HTML file target const args = process.argv.slice(2); const htmlTarget = args.length > 0 ? args[0] : 'index.html'; // Ensure the target has ./ prefix if it's a relative path const targetFile = htmlTarget.startsWith('./') ? htmlTarget : `./${htmlTarget}`; console.log(`Packaging presentation with target file: ${targetFile}`); // Read the HTML file let htmlContent = fs.readFileSync(targetFile, 'utf8'); // Switch from Vite's dynamic imports to static ones so that // this presentation can run anywhere (including offline via // file:// protocol) htmlContent = switchToStaticScripts(htmlContent); htmlContent = switchToStaticStyles(htmlContent); const zip = new JSZip(); const filesToInclude = ['./dist/**', './*/*.md']; if (fs.existsSync('./lib')) filesToInclude.push('./lib/**'); if (fs.existsSync('./images')) filesToInclude.push('./images/**'); if (fs.existsSync('./slides')) filesToInclude.push('./slides/**'); // Add the modified HTML file first const htmlFileName = htmlTarget.replace(/\.\//, ''); zip.file(htmlFileName, htmlContent); for (const pattern of filesToInclude) { const files = glob.sync(pattern, { nodir: true, dot: false, ignore: ['./examples/**', './test/**'], }); for (const file of files) { const filePath = path.resolve(file); const relativePath = path.relative(process.cwd(), filePath); const fileData = fs.readFileSync(filePath); zip.file(relativePath, fileData); } } const content = await zip.generateAsync({ type: 'nodebuffer' }); const zipFileName = `presentation.zip`; fs.writeFileSync(zipFileName, content); console.log(`Presentation packaged successfully: ${zipFileName}`); } main().catch((error) => { console.error('Error packaging presentation:', error); process.exit(1); });