import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const WFRP4E_DIR = '/home/morr/work/foundryvtt/WFRP4e-FoundryVTT/scripts'; const FR_DIR = path.join(__dirname, 'scripts'); const TRANSLATIONS_FILE = path.join(__dirname, 'auto-translations-applied.json'); // Charger le mapping de traductions const translations = JSON.parse(fs.readFileSync(TRANSLATIONS_FILE, 'utf8')); // Fonction pour générer le diff d'un fichier function generateFileDiff(file) { const frPath = path.join(FR_DIR, file); const enPath = path.join(WFRP4E_DIR, file); if (!fs.existsSync(frPath) || !fs.existsSync(enPath)) { return null; } const frContent = fs.readFileSync(frPath, 'utf8'); const enContent = fs.readFileSync(enPath, 'utf8'); const changes = []; // Trouver les traductions appliquées dans ce fichier for (const [en, fr] of Object.entries(translations)) { if (frContent.includes(fr) && enContent.includes(en)) { changes.push({ en, fr }); } } return { file, changes, frLines: frContent.split('\n').length, enLines: enContent.split('\n').length }; } // Générer le rapport console.log('Génération du rapport de traduction...\n'); const modifiedFiles = []; // Lire tous les fichiers JS du répertoire FR const files = fs.readdirSync(FR_DIR).filter(f => f.endsWith('.js')); files.forEach(file => { const diff = generateFileDiff(file); if (diff && diff.changes.length > 0) { modifiedFiles.push(diff); } }); // Trier par nombre de changements (décroissant) modifiedFiles.sort((a, b) => b.changes.length - a.changes.length); // Générer le rapport Markdown let report = `# Rapport de Traduction Automatique\n\n`; report += `**Date**: ${new Date().toLocaleDateString('fr-FR')}\n\n`; report += `**Fichiers modifiés**: ${modifiedFiles.length}\n`; report += `**Traductions uniques appliquées**: ${Object.keys(translations).length}\n\n`; report += `---\n\n`; // Statistiques globales const totalChanges = modifiedFiles.reduce((sum, file) => sum + file.changes.length, 0); report += `## Statistiques\n\n`; report += `- **Total de fichiers analysés**: ${files.length}\n`; report += `- **Fichiers modifiés**: ${modifiedFiles.length}\n`; report += `- **Total de changements**: ${totalChanges}\n`; report += `- **Moyenne de changements par fichier**: ${(totalChanges / modifiedFiles.length).toFixed(2)}\n\n`; // Top 20 des fichiers les plus modifiés report += `## Top 20 des fichiers les plus modifiés\n\n`; report += `| Fichier | Changements |\n`; report += `|---------|-------------|\n`; modifiedFiles.slice(0, 20).forEach(({ file, changes }) => { report += `| ${file} | ${changes.length} |\n`; }); report += `\n`; // Traductions les plus fréquentes const translationFrequency = new Map(); modifiedFiles.forEach(({ changes }) => { changes.forEach(({ en, fr }) => { const key = `${en} → ${fr}`; translationFrequency.set(key, (translationFrequency.get(key) || 0) + 1); }); }); const sortedTranslations = Array.from(translationFrequency.entries()) .sort((a, b) => b[1] - a[1]) .slice(0, 30); report += `## Top 30 des traductions les plus appliquées\n\n`; report += `| Traduction | Occurrences |\n`; report += `|------------|-------------|\n`; sortedTranslations.forEach(([translation, count]) => { const [en, fr] = translation.split(' → '); const enShort = en.length > 60 ? en.substring(0, 57) + '...' : en; const frShort = fr.length > 60 ? fr.substring(0, 57) + '...' : fr; report += `| \`${enShort}\` → \`${frShort}\` | ${count} |\n`; }); report += `\n`; // Détails par fichier (exemples significatifs) report += `## Exemples de modifications détaillées\n\n`; report += `Voici quelques exemples de fichiers avec leurs traductions appliquées :\n\n`; modifiedFiles.slice(0, 10).forEach(({ file, changes }) => { report += `### ${file}\n\n`; report += `**Nombre de traductions**: ${changes.length}\n\n`; changes.slice(0, 5).forEach(({ en, fr }) => { const enDisplay = en.length > 80 ? en.substring(0, 77) + '...' : en; const frDisplay = fr.length > 80 ? fr.substring(0, 77) + '...' : fr; report += `- ✏️ \`${enDisplay}\`\n`; report += ` → \`${frDisplay}\`\n\n`; }); if (changes.length > 5) { report += `... et ${changes.length - 5} autre(s) traduction(s)\n\n`; } }); // Traductions potentiellement problématiques report += `## ⚠️ Traductions à vérifier\n\n`; report += `Certaines traductions automatiques peuvent nécessiter une révision manuelle :\n\n`; const problematicPatterns = [ { pattern: /effet\./, reason: "Vérifier que 'effect' -> 'effet' est approprié dans le contexte" }, { pattern: /Retiré/, reason: "Vérifier l'accord (retiré/retirée/retirés/retirées)" }, { pattern: /Ajouté/, reason: "Vérifier l'accord (ajouté/ajoutée/ajoutés/ajoutées)" }, { pattern: /Appliqué/, reason: "Vérifier l'accord (appliqué/appliquée/appliqués/appliquées)" }, ]; const filesToReview = new Map(); modifiedFiles.forEach(({ file, changes }) => { changes.forEach(({ fr }) => { problematicPatterns.forEach(({ pattern, reason }) => { if (pattern.test(fr)) { if (!filesToReview.has(reason)) { filesToReview.set(reason, []); } filesToReview.get(reason).push({ file, translation: fr }); } }); }); }); for (const [reason, items] of filesToReview.entries()) { report += `### ${reason}\n\n`; const uniqueItems = [...new Map(items.map(item => [item.file, item])).values()].slice(0, 10); uniqueItems.forEach(({ file, translation }) => { const transShort = translation.length > 80 ? translation.substring(0, 77) + '...' : translation; report += `- **${file}**: \`${transShort}\`\n`; }); if (items.length > 10) { report += `\n... et ${items.length - 10} autre(s) occurrence(s)\n`; } report += `\n`; } // Recommandations report += `## 📋 Recommandations\n\n`; report += `1. **Vérifier les accords grammaticaux** : Les participes passés (ajouté, retiré, appliqué) doivent s'accorder avec leur sujet.\n`; report += `2. **Vérifier les contextes** : Certains mots comme "effect" peuvent être du code (à ne pas traduire) ou du texte (à traduire).\n`; report += `3. **Tester en jeu** : Vérifier que les messages affichés aux joueurs sont grammaticalement corrects.\n`; report += `4. **Révision manuelle** : Consulter les fichiers avec le plus de changements pour s'assurer de la cohérence.\n\n`; // Sauvegarder le rapport const reportFile = path.join(__dirname, 'rapport-traduction-automatique.md'); fs.writeFileSync(reportFile, report, 'utf8'); console.log('='.repeat(60)); console.log('Rapport généré avec succès !'); console.log('='.repeat(60)); console.log(`Fichier : rapport-traduction-automatique.md`); console.log(`\nStatistiques :`); console.log(`- ${modifiedFiles.length} fichiers modifiés`); console.log(`- ${totalChanges} changements au total`); console.log(`- ${Object.keys(translations).length} traductions uniques`); console.log('='.repeat(60)); // Afficher un aperçu du rapport console.log('\n📄 APERÇU DU RAPPORT\n'); console.log(report.split('\n').slice(0, 50).join('\n')); console.log('\n... (voir le fichier complet pour plus de détails)');