Ajout de la commande /voyage et grosse MAJK de la commande /auberge
This commit is contained in:
219
tools/auto-translate-english.js
Normal file
219
tools/auto-translate-english.js
Normal file
@@ -0,0 +1,219 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const FR_DIR = path.join(__dirname, 'scripts');
|
||||
const ENGLISH_TEXTS_FILE = path.join(__dirname, 'english-texts-found.json');
|
||||
const FR_JSON_FILE = path.join(__dirname, 'fr.json');
|
||||
|
||||
// Charger les données
|
||||
const englishTexts = JSON.parse(fs.readFileSync(ENGLISH_TEXTS_FILE, 'utf8'));
|
||||
const frJson = JSON.parse(fs.readFileSync(FR_JSON_FILE, 'utf8'));
|
||||
|
||||
// Créer un mapping de traductions basé sur fr.json et les patterns connus
|
||||
const translations = {
|
||||
// Patterns déjà traduits dans le système
|
||||
"Choose Training": "Choisir un Entraînement",
|
||||
"Lore (Magic)": "Savoir (Magie)",
|
||||
"Dark Magic (Necromancy)": "Magie Noire (Nécromancie)",
|
||||
"Lore (Theology)": "Savoir (Théologie)",
|
||||
"Lore (Runes)": "Savoir (Runes)",
|
||||
"Sail (Skycraft)": "Voile (Aéronavale)",
|
||||
"all forms": "toutes formes",
|
||||
|
||||
// Messages utilisateur
|
||||
"Skipping Tests to apply the tattoos": "Tests ignorés pour appliquer les tatouages",
|
||||
"Apply Ward of Grimnir effect?": "Appliquer l'effet Rune de Grimnir ?",
|
||||
"No Lore (Theology) skill found, cannot pass.": "Compétence Savoir (Théologie) introuvable, impossible de continuer.",
|
||||
"No Lore (Runes) skill found, cannot pass.": "Compétence Savoir (Runes) introuvable, impossible de continuer.",
|
||||
"One or more Tests to apply the tattoos failed.": "Un ou plusieurs Tests pour appliquer les tatouages ont échoué.",
|
||||
"Must provide a Master Rune": "Doit fournir une Rune Maîtresse",
|
||||
"Must provide a Rune (non-Master)": "Doit fournir une Rune (non-Maîtresse)",
|
||||
|
||||
// Effets et conditions
|
||||
"Removed Broken": "Condition Brisé supprimée",
|
||||
"Added Bleeding": "Saignement ajouté",
|
||||
"Applied after effects": "Effets secondaires appliqués",
|
||||
"Does not need to make Peur or Terror tests": "N'a pas besoin de faire de tests de Peur ou de Terreur",
|
||||
"Automatically passes any": "Réussit automatiquement tout",
|
||||
|
||||
// Fragments de code courants (contextuels)
|
||||
"action-link critical": "action-link critical", // Classe CSS, ne pas traduire
|
||||
"></i> Critical</a>": "></i> Critique</a>",
|
||||
|
||||
// Patterns génériques
|
||||
"|| this.item.getFlag(": "|| this.item.getFlag(", // Code JS, ne pas traduire
|
||||
',"info")': ',"info")', // Code JS, ne pas traduire
|
||||
};
|
||||
|
||||
// Fonction pour obtenir la fréquence de chaque texte anglais
|
||||
function getTextFrequencies() {
|
||||
const frequencies = new Map();
|
||||
|
||||
englishTexts.forEach(({ strings }) => {
|
||||
strings.forEach(str => {
|
||||
frequencies.set(str, (frequencies.get(str) || 0) + 1);
|
||||
});
|
||||
});
|
||||
|
||||
return frequencies;
|
||||
}
|
||||
|
||||
// Fonction pour proposer des traductions automatiques
|
||||
function proposeTranslations(text) {
|
||||
// Si déjà dans le mapping, retourner
|
||||
if (translations[text]) {
|
||||
return translations[text];
|
||||
}
|
||||
|
||||
// Patterns de remplacement simples basés sur fr.json
|
||||
let translated = text;
|
||||
|
||||
// Mots courants du vocabulaire WFRP
|
||||
const vocabulary = {
|
||||
"Choose": "Choisir",
|
||||
"Select": "Sélectionner",
|
||||
"Enter": "Entrer",
|
||||
"Critical": "Critique",
|
||||
"Wounds": "Blessures",
|
||||
"Bleeding": "Saignement",
|
||||
"Broken": "Brisé",
|
||||
"Removed": "Retiré",
|
||||
"Added": "Ajouté",
|
||||
"Applied": "Appliqué",
|
||||
"Failed": "Échoué",
|
||||
"Passed": "Réussi",
|
||||
"Cannot": "Impossible de",
|
||||
"Must": "Doit",
|
||||
"Need": "Besoin",
|
||||
"Automatically": "Automatiquement",
|
||||
"any": "tout",
|
||||
"all": "tout",
|
||||
"Test": "Test",
|
||||
"Tests": "Tests",
|
||||
"Skill": "Compétence",
|
||||
"effect": "effet",
|
||||
"after effects": "effets secondaires",
|
||||
};
|
||||
|
||||
// Appliquer les remplacements de vocabulaire
|
||||
for (const [en, fr] of Object.entries(vocabulary)) {
|
||||
const regex = new RegExp(`\\b${en}\\b`, 'gi');
|
||||
translated = translated.replace(regex, (match) => {
|
||||
// Conserver la casse
|
||||
if (match[0] === match[0].toUpperCase()) {
|
||||
return fr.charAt(0).toUpperCase() + fr.slice(1);
|
||||
}
|
||||
return fr;
|
||||
});
|
||||
}
|
||||
|
||||
// Si rien n'a changé, ne pas proposer de traduction
|
||||
if (translated === text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return translated;
|
||||
}
|
||||
|
||||
// Analyser et créer le mapping complet
|
||||
console.log('Création du mapping de traductions...\n');
|
||||
|
||||
const frequencies = getTextFrequencies();
|
||||
const autoTranslations = new Map();
|
||||
|
||||
// Trier par fréquence décroissante
|
||||
const sortedTexts = Array.from(frequencies.entries())
|
||||
.sort((a, b) => b[1] - a[1]);
|
||||
|
||||
let proposedCount = 0;
|
||||
let existingCount = 0;
|
||||
|
||||
sortedTexts.forEach(([text, freq]) => {
|
||||
if (translations[text]) {
|
||||
autoTranslations.set(text, translations[text]);
|
||||
existingCount++;
|
||||
} else {
|
||||
const proposed = proposeTranslations(text);
|
||||
if (proposed && proposed !== text) {
|
||||
autoTranslations.set(text, proposed);
|
||||
proposedCount++;
|
||||
if (proposedCount <= 10) {
|
||||
console.log(`"${text}" → "${proposed}" (${freq}x)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`\n${existingCount} traductions existantes`);
|
||||
console.log(`${proposedCount} traductions proposées automatiquement`);
|
||||
console.log(`${sortedTexts.length - existingCount - proposedCount} textes ignorés (code/technique)`);
|
||||
|
||||
// Appliquer les traductions
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('Application des traductions...\n');
|
||||
|
||||
let stats = {
|
||||
filesProcessed: 0,
|
||||
filesModified: 0,
|
||||
replacementsMade: 0,
|
||||
errors: 0
|
||||
};
|
||||
|
||||
englishTexts.forEach(({ file, strings }) => {
|
||||
const filePath = path.join(FR_DIR, file);
|
||||
stats.filesProcessed++;
|
||||
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
let modified = false;
|
||||
let replacementsInFile = 0;
|
||||
|
||||
strings.forEach(text => {
|
||||
const translation = autoTranslations.get(text);
|
||||
if (translation && content.includes(text)) {
|
||||
// Remplacement simple
|
||||
const newContent = content.split(text).join(translation);
|
||||
|
||||
if (newContent !== content) {
|
||||
const count = content.split(text).length - 1;
|
||||
content = newContent;
|
||||
modified = true;
|
||||
replacementsInFile += count;
|
||||
stats.replacementsMade += count;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (modified) {
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
stats.filesModified++;
|
||||
console.log(`✓ ${file} : ${replacementsInFile} remplacement(s)`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`✗ ${file} : ${error.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('Traduction automatique terminée !');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Fichiers traités : ${stats.filesProcessed}`);
|
||||
console.log(`Fichiers modifiés : ${stats.filesModified}`);
|
||||
console.log(`Remplacements effectués : ${stats.replacementsMade}`);
|
||||
console.log(`Erreurs : ${stats.errors}`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// Sauvegarder le mapping de traductions
|
||||
const mappingFile = path.join(__dirname, 'auto-translations-applied.json');
|
||||
fs.writeFileSync(
|
||||
mappingFile,
|
||||
JSON.stringify(Object.fromEntries(autoTranslations), null, 2),
|
||||
'utf8'
|
||||
);
|
||||
console.log(`\nMapping de traductions sauvegardé dans : auto-translations-applied.json`);
|
||||
Reference in New Issue
Block a user