diff --git a/zip.js b/zip.js index 7fcbb562..9c2316d2 100644 --- a/zip.js +++ b/zip.js @@ -1,40 +1,116 @@ import fs from 'node:fs'; import path from 'node:path'; import JSZip from 'jszip'; -import {glob} from 'glob'; +import { glob } from 'glob'; -async function main() { - const zip = new JSZip(); - const filesToInclude = [ - './index.html', - './dist/**', - './*/*.md' - ]; +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); } -main().catch(error => { - console.error('Error packaging presentation:', error); - process.exit(1); +/** + * 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); });