/
githubmirror
/
reveal.js
Обзор
Документация
Войти
/
githubmirror
/
reveal.js
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
scripts/zip.js
147 строк
5 KB
Hakim El Hattab
prevent test false positive, zip packager now handles additional formats for script sub
25 фев 2026, 23:43
25 фев 2026, 23:43
abdad1c
Код
Авторство
О чём код?
import fs from 'node:fs'; import path from 'node:path'; import JSZip from 'jszip'; import { globSync } from 'glob'; function switchToStaticScripts(htmlContent) { // Look for the module script block and capture indentation const moduleScriptPattern = /(\s*)<script type="module">([\s\S]*?)<\/script>/; const match = htmlContent.match(moduleScriptPattern); if (!match) return htmlContent; const indentation = match[1].replace(/\n/g, ''); let moduleCode = match[2]; const scriptPaths = []; const pluginAliasMap = new Map(); const moduleAliasMap = new Map(); const addScriptPath = (scriptPath) => { if (!scriptPaths.includes(scriptPath)) { scriptPaths.push(scriptPath); } }; const replaceIdentifier = (code, identifier, replacement) => { if (!identifier || identifier === replacement) return code; const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); return code.replace(new RegExp(`\\b${escaped}\\b`, 'g'), replacement); }; // Replace main reveal.js import. moduleCode = moduleCode.replace( /^\s*import\s+(\w+)\s+from\s+['"]reveal\.js['"]\s*;?\s*$/gm, (match, revealVar) => { addScriptPath('dist/reveal.js'); moduleAliasMap.set(revealVar, 'Reveal'); return ''; } ); // Replace plugin imports moduleCode = moduleCode.replace( /^\s*import\s+(\w+)\s+from\s+['"]reveal\.js\/plugin\/(\w+)['"]\s*;?\s*$/gm, (match, pluginVar, pluginName) => { const pluginGlobal = `Reveal${pluginName.charAt(0).toUpperCase()}${pluginName.slice(1)}`; addScriptPath(`dist/plugin/${pluginName}.js`); pluginAliasMap.set(pluginVar, pluginGlobal); return ''; } ); for (const [pluginVar, pluginGlobal] of pluginAliasMap) { moduleCode = replaceIdentifier(moduleCode, pluginVar, pluginGlobal); } for (const [moduleVar, moduleGlobal] of moduleAliasMap) { moduleCode = replaceIdentifier(moduleCode, moduleVar, moduleGlobal); } // Clean up any remaining empty lines and trim moduleCode = moduleCode.replace(/^\s*[\r\n]/gm, '').trim(); const scriptTags = scriptPaths.map((scriptPath) => `${indentation}<script src="${scriptPath}"></script>`); const replacement = '\n\n' + scriptTags.join('\n') + `\n${indentation}<script>\n${indentation}\t${moduleCode}\n${indentation}</script>`; 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 relative paths are read from cwd while keeping absolute paths intact const targetFile = path.isAbsolute(htmlTarget) ? htmlTarget : 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 = globSync(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); });