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);
});