File size: 4,883 Bytes
eebc40f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env node

import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import cliProgress from 'cli-progress';
import chalk from 'chalk';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Configuration
const SVGS_DIR = path.join(__dirname, 'output', 'svgs');
const DATA_DIR = path.join(__dirname, 'output', 'data');
const SPRITES_DIR = path.join(__dirname, 'output', 'sprites');
const OUTPUT_SPRITE = path.join(SPRITES_DIR, 'font-sprite.svg');

// Configuration de la barre de progression
const progressBar = new cliProgress.SingleBar({
  format: chalk.cyan('{bar}') + ' | {percentage}% | {value}/{total} | {fileName}',
  barCompleteChar: '\u2588',
  barIncompleteChar: '\u2591',
  hideCursor: true
});

/**
 * Génère le sprite SVG à partir de tous les fichiers SVG
 */
async function generateSvgSprite() {
  console.log(chalk.blue.bold('🎨 Génération du sprite SVG...\n'));

  try {
    // Lire tous les fichiers SVG (seulement les lettres A)
    const files = await fs.readdir(SVGS_DIR);
    const svgFiles = files.filter(file => file.endsWith('_a.svg'));

    if (svgFiles.length === 0) {
      throw new Error(`Aucun fichier SVG trouvé dans ${SVGS_DIR}`);
    }

    console.log(chalk.cyan(`📁 ${svgFiles.length} fichiers SVG trouvés\n`));

    let sprites = [];
    let processedCount = 0;
    let errorCount = 0;

    // Traiter chaque SVG
    for (let i = 0; i < svgFiles.length; i++) {
      const file = svgFiles[i];
      
      // Démarrer la barre de progression
      progressBar.start(1, 0, { fileName: file });
      
      try {
        const filePath = path.join(SVGS_DIR, file);
        const content = await fs.readFile(filePath, 'utf-8');

        // Extraire le contenu SVG (sans les balises <svg>)
        const match = content.match(/<svg[^>]*>(.*?)<\/svg>/s);
        if (!match) {
          errorCount++;
          progressBar.update(1, { fileName: file });
          progressBar.stop();
          console.warn(chalk.yellow(`⚠️  Contenu SVG invalide: ${file}`));
          continue;
        }

        const innerContent = match[1].trim();
        if (!innerContent) {
          errorCount++;
          progressBar.update(1, { fileName: file });
          progressBar.stop();
          console.warn(chalk.yellow(`⚠️  Contenu Empty SVG: ${file}`));
          continue;
        }

        // Créer l'ID du symbole à partir du nom de fichier
        const symbolId = file.replace('.svg', '');

        // Extraire le viewBox s'il est présent
        const viewBoxMatch = content.match(/viewBox=["']([^"']+)["']/);
        const viewBox = viewBoxMatch ? viewBoxMatch[1] : '0 0 80 80';

        // Créer le symbole
        sprites.push(`  <symbol id="${symbolId}" viewBox="${viewBox}">
    ${innerContent}
  </symbol>`);

        processedCount++;
        progressBar.update(1, { fileName: file });
        progressBar.stop();

        // Afficher le progrès
        if (processedCount % 100 === 0) {
          console.log(chalk.yellow(`⚡ ${processedCount}/${svgFiles.length} SVG traités...`));
        }

      } catch (error) {
        errorCount++;
        progressBar.update(1, { fileName: file });
        progressBar.stop();
        console.warn(chalk.red(`⚠️  Erreur avec ${file}:`), error.message);
      }
    }

    // Créer le sprite final
    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 directory si nécessaire
    await fs.mkdir(path.dirname(OUTPUT_SPRITE), { recursive: true });
    console.log(chalk.green(`📁 Directory created : ${SPRITES_DIR}`));

    // Write file sprite
    await fs.writeFile(OUTPUT_SPRITE, spriteContent, 'utf-8');

    console.log(chalk.green(`✅ Sprite SVG généré avec ${sprites.length} symboles`));
    console.log(chalk.blue(`📍 Fichier : ${OUTPUT_SPRITE}`));
    console.log(chalk.blue(`📊 Taille : ${(spriteContent.length / 1024).toFixed(1)} KB`));

    // Plus besoin de mapping - on utilise directement fontId + "_a"
    console.log(chalk.green(`🗺️  Mapping supprimé - utilisation directe des IDs`));

    // Statistics finales
    console.log(chalk.cyan('\n📊 Summary :'));
    console.log(chalk.white(`   - ${processedCount} symboles générés avec succès`));
    console.log(chalk.white(`   - ${errorCount} erreurs`));
    console.log(chalk.white(`   - ${svgFiles.length} fichiers traités`));
    console.log(chalk.white(`   - Taille du sprite : ${(spriteContent.length / 1024).toFixed(1)} KB`));

  } catch (error) {
    console.error(chalk.red('❌ Error during la génération :'), error.message);
    process.exit(1);
  }
}

// Lancer le script
generateSvgSprite();