Spaces:
Running
Running
File size: 3,637 Bytes
1ee6ce7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#!/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 <svg> tags)
const match = content.match(/<svg[^>]*>(.*?)<\/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(` <symbol id="${symbolId}" viewBox="${viewBox}">
${innerContent}
</symbol>`);
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 = `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
<defs>
${sprites.join('\n')}
</defs>
</svg>`;
// 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 };
|