forked from public/foundryvtt-wh4-lang-fr-fr
194 lines
7.4 KiB
JavaScript
194 lines
7.4 KiB
JavaScript
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)');
|