172 lines
5.3 KiB
JavaScript
172 lines
5.3 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Build custom highlight.js bundle by downloading and combining CDN files
|
||
|
|
* This creates a single local file with all required languages
|
||
|
|
*
|
||
|
|
* Usage:
|
||
|
|
* node scripts/build-highlight-bundle.js
|
||
|
|
*
|
||
|
|
* This generates a bundle at public/js/highlight-bundle.min.js
|
||
|
|
*/
|
||
|
|
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
const https = require('https');
|
||
|
|
|
||
|
|
// Languages we want to include (in addition to core languages)
|
||
|
|
const additionalLanguages = [
|
||
|
|
'rust',
|
||
|
|
'typescript',
|
||
|
|
'bash',
|
||
|
|
'yaml',
|
||
|
|
'dockerfile',
|
||
|
|
'sql',
|
||
|
|
'python',
|
||
|
|
'ini', // For TOML-like syntax
|
||
|
|
'properties', // Also TOML-like syntax
|
||
|
|
'markdown'
|
||
|
|
];
|
||
|
|
|
||
|
|
const CDN_BASE = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0';
|
||
|
|
|
||
|
|
function downloadFile(url) {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
https.get(url, (response) => {
|
||
|
|
if (response.statusCode !== 200) {
|
||
|
|
reject(new Error(`HTTP ${response.statusCode}: ${url}`));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
let data = '';
|
||
|
|
response.on('data', (chunk) => data += chunk);
|
||
|
|
response.on('end', () => resolve(data));
|
||
|
|
}).on('error', reject);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async function buildBundle() {
|
||
|
|
try {
|
||
|
|
// Ensure output directory exists first
|
||
|
|
const outputDir = path.join(__dirname, '../public/js');
|
||
|
|
if (!fs.existsSync(outputDir)) {
|
||
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if bundle already exists and is recent (less than 24 hours old)
|
||
|
|
const outputPath = path.join(outputDir, 'highlight-bundle.min.js');
|
||
|
|
|
||
|
|
if (fs.existsSync(outputPath)) {
|
||
|
|
const stats = fs.statSync(outputPath);
|
||
|
|
const fileAge = Date.now() - stats.mtime.getTime();
|
||
|
|
const maxAge = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
|
||
|
|
|
||
|
|
if (fileAge < maxAge) {
|
||
|
|
const fileSizeKB = Math.round(stats.size / 1024);
|
||
|
|
const ageHours = Math.round(fileAge / (60 * 60 * 1000));
|
||
|
|
|
||
|
|
console.log('✅ Highlight.js bundle already exists and is recent!');
|
||
|
|
console.log(`📁 File: ${outputPath}`);
|
||
|
|
console.log(`📊 Size: ${fileSizeKB}KB`);
|
||
|
|
console.log(`⏰ Age: ${ageHours}h (created: ${stats.mtime.toLocaleString()})`);
|
||
|
|
console.log('🎯 Languages: Core JS/HTML/CSS/JSON/XML + ' + additionalLanguages.join(', '));
|
||
|
|
console.log('💡 To force rebuild, delete the file or wait 24 hours');
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
console.log('🔄 Bundle exists but is older than 24 hours, rebuilding...');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('🔨 Building highlight.js bundle from CDN...');
|
||
|
|
console.log(`📦 Including core + ${additionalLanguages.length} additional languages: ${additionalLanguages.join(', ')}`);
|
||
|
|
|
||
|
|
// Download core highlight.js
|
||
|
|
console.log('📥 Downloading core highlight.js...');
|
||
|
|
const coreJs = await downloadFile(`${CDN_BASE}/highlight.min.js`);
|
||
|
|
|
||
|
|
let bundleContent = `/*! Custom Highlight.js Bundle for Rustelo
|
||
|
|
* Generated on ${new Date().toISOString()}
|
||
|
|
* Core + Additional Languages: ${additionalLanguages.join(', ')}
|
||
|
|
* Based on Highlight.js 11.9.0 from CDN
|
||
|
|
*/
|
||
|
|
|
||
|
|
// Core highlight.js
|
||
|
|
${coreJs}
|
||
|
|
|
||
|
|
// Additional language definitions
|
||
|
|
(function() {
|
||
|
|
if (typeof hljs === 'undefined') {
|
||
|
|
console.error('Highlight.js core not available');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
`;
|
||
|
|
|
||
|
|
// Download and add each language
|
||
|
|
console.log('📝 Downloading language definitions...');
|
||
|
|
|
||
|
|
for (const lang of additionalLanguages) {
|
||
|
|
try {
|
||
|
|
console.log(` 📥 Downloading: ${lang}`);
|
||
|
|
const langJs = await downloadFile(`${CDN_BASE}/languages/${lang}.min.js`);
|
||
|
|
|
||
|
|
// Wrap the language code to register it properly
|
||
|
|
bundleContent += `
|
||
|
|
// Language: ${lang}
|
||
|
|
(function() {
|
||
|
|
${langJs}
|
||
|
|
})();
|
||
|
|
`;
|
||
|
|
console.log(` ✅ Added: ${lang}`);
|
||
|
|
} catch (error) {
|
||
|
|
console.log(` ❌ Failed to download ${lang}: ${error.message}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Close the bundle
|
||
|
|
bundleContent += `
|
||
|
|
})();
|
||
|
|
|
||
|
|
// Auto-initialize when DOM is ready
|
||
|
|
if (typeof document !== 'undefined') {
|
||
|
|
if (document.readyState === 'loading') {
|
||
|
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
|
if (typeof hljs !== 'undefined' && hljs.highlightAll) {
|
||
|
|
hljs.configure({ ignoreUnescapedHTML: true });
|
||
|
|
hljs.highlightAll();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
// DOM already ready
|
||
|
|
if (typeof hljs !== 'undefined' && hljs.highlightAll) {
|
||
|
|
hljs.configure({ ignoreUnescapedHTML: true });
|
||
|
|
hljs.highlightAll();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
`;
|
||
|
|
|
||
|
|
// Write the bundle (directory already created at the start)
|
||
|
|
fs.writeFileSync(outputPath, bundleContent);
|
||
|
|
|
||
|
|
// Get file size
|
||
|
|
const stats = fs.statSync(outputPath);
|
||
|
|
const fileSizeKB = Math.round(stats.size / 1024);
|
||
|
|
|
||
|
|
console.log(`✅ Highlight.js bundle created successfully!`);
|
||
|
|
console.log(`📁 Output: ${outputPath}`);
|
||
|
|
console.log(`📊 Size: ${fileSizeKB}KB`);
|
||
|
|
console.log(`🎯 Languages: Core JS/HTML/CSS/JSON/XML + ${additionalLanguages.join(', ')}`);
|
||
|
|
console.log('');
|
||
|
|
console.log('🚀 Ready to use! The bundle includes:');
|
||
|
|
console.log(' - Auto-initialization on DOM ready');
|
||
|
|
console.log(' - All required languages pre-registered');
|
||
|
|
console.log(' - Single HTTP request instead of multiple CDN calls');
|
||
|
|
|
||
|
|
} catch (error) {
|
||
|
|
console.error('❌ Error building bundle:', error.message);
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
buildBundle();
|