petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans with async, HTTP, database, and testing support
228 lines (192 loc) • 8.07 kB
JavaScript
/**
* PetCareScript Icon Generator
* Converts SVG icon to different formats for file association
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
class IconGenerator {
constructor() {
this.svgPath = './assets/icone.svg';
this.outputDir = './icons';
this.sizes = [16, 32, 48, 64, 128, 256];
}
generate() {
console.log('🎨 Generating icons for file association...');
this.createOutputDirectory();
this.generatePNGIcons();
this.generateICOIcon();
this.generateICNSIcon();
this.copyOriginalSVG();
console.log('✅ Icons generated successfully!');
}
createOutputDirectory() {
if (!fs.existsSync(this.outputDir)) {
fs.mkdirSync(this.outputDir, { recursive: true });
}
}
generatePNGIcons() {
console.log('📸 Generating PNG icons...');
// Check if we have ImageMagick or other conversion tools
const hasMagick = this.hasCommand('convert');
const hasInkscape = this.hasCommand('inkscape');
const hasRsvg = this.hasCommand('rsvg-convert');
if (!hasMagick && !hasInkscape && !hasRsvg) {
console.warn('⚠️ No SVG conversion tool found. Installing sharp for conversion...');
this.generatePNGWithSharp();
return;
}
for (const size of this.sizes) {
const outputPath = path.join(this.outputDir, `petcarescript-${size}.png`);
try {
if (hasInkscape) {
execSync(`inkscape "${this.svgPath}" --export-png="${outputPath}" --export-width=${size} --export-height=${size}`);
} else if (hasRsvg) {
execSync(`rsvg-convert -w ${size} -h ${size} "${this.svgPath}" -o "${outputPath}"`);
} else if (hasMagick) {
execSync(`convert -background transparent "${this.svgPath}" -resize ${size}x${size} "${outputPath}"`);
}
console.log(` ✓ Generated ${size}x${size} PNG`);
} catch (error) {
console.warn(` ⚠️ Failed to generate ${size}x${size} PNG: ${error.message}`);
}
}
}
generatePNGWithSharp() {
// Fallback method using Node.js sharp library
const sharpCode = `
const sharp = require('sharp');
const fs = require('fs');
async function generatePNGs() {
const svgBuffer = fs.readFileSync('${this.svgPath}');
const sizes = [16, 32, 48, 64, 128, 256];
for (const size of sizes) {
try {
await sharp(svgBuffer)
.resize(size, size)
.png()
.toFile('${this.outputDir}/petcarescript-' + size + '.png');
console.log('Generated ' + size + 'x' + size + ' PNG');
} catch (error) {
console.error('Failed to generate ' + size + 'x' + size + ' PNG:', error.message);
}
}
}
generatePNGs();
`;
fs.writeFileSync(path.join(__dirname, 'generate-pngs-temp.js'), sharpCode);
try {
// Try to install sharp if not present
execSync('npm install sharp --no-save', { stdio: 'ignore' });
execSync(`node ${path.join(__dirname, 'generate-pngs-temp.js')}`);
} catch (error) {
console.warn('⚠️ Could not generate PNGs with sharp. Manual conversion may be needed.');
} finally {
// Clean up temp file
try {
fs.unlinkSync(path.join(__dirname, 'generate-pngs-temp.js'));
} catch (e) {}
}
}
generateICOIcon() {
console.log('🪟 Generating ICO icon for Windows...');
const hasMagick = this.hasCommand('convert');
if (hasMagick) {
try {
// Generate multi-size ICO file
const pngFiles = this.sizes.map(size =>
path.join(this.outputDir, `petcarescript-${size}.png`)
).filter(file => fs.existsSync(file));
if (pngFiles.length > 0) {
const icoPath = path.join(this.outputDir, 'petcarescript.ico');
execSync(`convert ${pngFiles.join(' ')} "${icoPath}"`);
console.log(' ✓ Generated ICO file');
} else {
console.warn(' ⚠️ No PNG files found for ICO generation');
}
} catch (error) {
console.warn(` ⚠️ Failed to generate ICO: ${error.message}`);
}
} else {
console.warn(' ⚠️ ImageMagick not found. ICO generation skipped.');
// Create a fallback batch script for Windows
this.createWindowsIconFallback();
}
}
generateICNSIcon() {
console.log('🍎 Generating ICNS icon for macOS...');
const hasIconutil = this.hasCommand('iconutil');
if (hasIconutil && process.platform === 'darwin') {
try {
// Create iconset directory
const iconsetDir = path.join(this.outputDir, 'petcarescript.iconset');
if (!fs.existsSync(iconsetDir)) {
fs.mkdirSync(iconsetDir);
}
// Copy PNGs with proper naming for iconset
const iconsetSizes = [
{ size: 16, name: 'icon_16x16.png' },
{ size: 32, name: 'icon_16x16@2x.png' },
{ size: 32, name: 'icon_32x32.png' },
{ size: 64, name: 'icon_32x32@2x.png' },
{ size: 128, name: 'icon_128x128.png' },
{ size: 256, name: 'icon_128x128@2x.png' },
{ size: 256, name: 'icon_256x256.png' },
];
iconsetSizes.forEach(({ size, name }) => {
const sourcePath = path.join(this.outputDir, `petcarescript-${size}.png`);
const destPath = path.join(iconsetDir, name);
if (fs.existsSync(sourcePath)) {
fs.copyFileSync(sourcePath, destPath);
}
});
// Generate ICNS
const icnsPath = path.join(this.outputDir, 'petcarescript.icns');
execSync(`iconutil -c icns "${iconsetDir}" -o "${icnsPath}"`);
console.log(' ✓ Generated ICNS file');
} catch (error) {
console.warn(` ⚠️ Failed to generate ICNS: ${error.message}`);
}
} else {
console.warn(' ⚠️ iconutil not available. ICNS generation skipped.');
}
}
createWindowsIconFallback() {
// Create a simple HTML file that can be used to create ICO manually
const htmlContent = `<!DOCTYPE html>
<html>
<head>
<title>PetCareScript Icon Converter</title>
</head>
<body>
<h1>Convert SVG to ICO</h1>
<p>Use an online converter like:</p>
<ul>
<li><a href="https://convertio.co/svg-ico/" target="_blank">Convertio</a></li>
<li><a href="https://cloudconvert.com/svg-to-ico" target="_blank">CloudConvert</a></li>
</ul>
<p>Upload the file: assets/icone.svg</p>
</body>
</html>`;
fs.writeFileSync(path.join(this.outputDir, 'convert-instructions.html'), htmlContent);
}
copyOriginalSVG() {
const destPath = path.join(this.outputDir, 'petcarescript.svg');
fs.copyFileSync(this.svgPath, destPath);
console.log('📄 Copied original SVG to icons directory');
}
hasCommand(command) {
try {
execSync(`which ${command}`, { stdio: 'ignore' });
return true;
} catch (error) {
return false;
}
}
}
// Execute if run directly
if (require.main === module) {
const generator = new IconGenerator();
generator.generate();
}
module.exports = IconGenerator;