#!/usr/bin/env node import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Configuration const TYPOGRAPHY_BASE = __dirname; const GENERATED_DIR = path.join(TYPOGRAPHY_BASE, 'generated'); const SVGS_DIR = path.join(GENERATED_DIR, 'svgs'); const DATA_DIR = path.join(GENERATED_DIR, 'data'); const SPRITES_DIR = path.join(GENERATED_DIR, 'sprites'); const OUTPUT_SPRITE = path.join(SPRITES_DIR, 'font-sprite.svg'); async function generateSvgSprite() { console.log('🎨 Generating SVG sprite...'); try { // Read all SVG files const files = await fs.readdir(SVGS_DIR); const svgFiles = files.filter(file => file.endsWith('.svg')); console.log(`πŸ“ Found ${svgFiles.length} SVG files`); let sprites = []; let processedCount = 0; // Process each SVG for (const file of svgFiles) { try { const filePath = path.join(SVGS_DIR, file); const content = await fs.readFile(filePath, 'utf-8'); // Extract SVG content (without tags) const match = content.match(/]*>(.*?)<\/svg>/s); if (!match) continue; const innerContent = match[1].trim(); if (!innerContent) continue; // Create symbol ID from filename const symbolId = file.replace('.svg', ''); // Extract viewBox if present const viewBoxMatch = content.match(/viewBox=["']([^"']+)["']/); const viewBox = viewBoxMatch ? viewBoxMatch[1] : '0 0 80 80'; // Create symbol sprites.push(` ${innerContent} `); processedCount++; if (processedCount % 100 === 0) { console.log(`⚑ Processed ${processedCount}/${svgFiles.length} SVGs...`); } } catch (error) { console.warn(`⚠️ Error with ${file}:`, error.message); } } // Create final sprite const spriteContent = ` ${sprites.join('\n')} `; // Create output folder if necessary await fs.mkdir(path.dirname(OUTPUT_SPRITE), { recursive: true }); // Write sprite file await fs.writeFile(OUTPUT_SPRITE, spriteContent, 'utf-8'); console.log(`βœ… SVG sprite generated with ${sprites.length} symbols`); console.log(`πŸ“ File: ${OUTPUT_SPRITE}`); console.log(`πŸ“Š Size: ${(spriteContent.length / 1024).toFixed(1)} KB`); // Also generate mapping file for easier usage const mapping = {}; svgFiles.forEach(file => { const fontName = file.replace('_a.svg', '').replace(/_/g, ' '); const symbolId = file.replace('.svg', ''); mapping[fontName] = symbolId; }); const mappingFile = path.join(DATA_DIR, 'font-sprite-mapping.json'); await fs.writeFile(mappingFile, JSON.stringify(mapping, null, 2)); console.log(`πŸ—ΊοΈ Mapping generated: ${mappingFile}`); } catch (error) { console.error('❌ Error during generation:', error); process.exit(1); } } // Execute script if (import.meta.url === `file://${process.argv[1]}`) { generateSvgSprite(); } export { generateSvgSprite };