Files
foundryvtt-wh4-lang-fr-fr/tools/translate-scripts.js

178 lines
7.1 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);
// Mappings de traduction basés sur fr.json
const translations = {
// Choose phrases
"Choose 12 Arcane Spells": "Choisissez 12 Sorts d'Arcane",
"Choose 1 Necromancy Spell": "Choisissez 1 Sort de Nécromancie",
"Choose 2 Arcane Spells": "Choisissez 2 Sorts d'Arcane",
"Choose 2 Skills to add +20": "Choisissez 2 Compétences pour ajouter +20",
"Choose 3 Arcane Spells": "Choisissez 3 Sorts d'Arcane",
"Choose 3 from the Lore of Necromancy": "Choisissez 3 dans le Savoir de Nécromancie",
"Choose 3 Petty Spells": "Choisissez 3 Sorts Mineurs",
"Choose 4 Petty Spells": "Choisissez 4 Sorts Mineurs",
"Choose 6 Arcane Spells": "Choisissez 6 Sorts d'Arcane",
"Choose 6 Petty Spells": "Choisissez 6 Sorts Mineurs",
"Choose 7 taken from any combination of spells from Colour Magic Lore, the Lore of Witchcraft, or Lore of Dark Magic": "Choisissez 7 Sorts parmi toute combinaison de Magie de Couleur, Sorcellerie ou Magie Noire",
"Choose 8 Arcane Spells & Lore of Death": "Choisissez 8 Sorts d'Arcane et Savoir de la Mort",
"Choose 9 Arcane Spells": "Choisissez 9 Sorts d'Arcane",
"Choose a characteristic": "Choisissez une caractéristique",
"Choose an appropriate Polearm or Two-Handed Weapon": "Choisissez une arme d'hast ou une arme à deux mains appropriée",
"Choose Chanty": "Choisissez un Chant",
"Choose Double Life Career": "Choisissez une Carrière de Double Vie",
"Choose Lore": "Choisissez un Savoir",
"Choose Rune": "Choisissez une Rune",
"Choose Sense": "Choisissez un Sens",
// Enter phrases
"Enter Armour value": "Entrez la valeur d'Armure",
"Enter Etiquette Group": "Entrez le Groupe d'Étiquette",
"Enter Fear value": "Entrez la valeur de Peur",
"Enter Hatred Group": "Entrez le Groupe de Haine",
"Enter Resistance": "Entrez la Résistance",
"Enter Spellcasting Lore": "Entrez le Savoir d'Incantation",
"Enter Target Species": "Entrez l'Espèce Cible",
"Enter Target Species (singular)": "Entrez l'Espèce Cible (singulier)",
"Enter Terror value": "Entrez la valeur de Terreur",
"Enter the Armoured value": "Entrez la valeur d'Armure",
"Enter the number of diseases/poisons cured": "Entrez le nombre de maladies/poisons soignés",
"Enter the Sturdy value": "Entrez la valeur de Robustesse",
"Enter Venom Strength": "Entrez la Force du Venin",
"Enter Ward value": "Entrez la valeur de Protection",
"Enter Wounds Lost to gain SL": "Entrez les Blessures Perdues pour gagner DR",
// Select phrases
"Select Column": "Sélectionnez une Colonne",
"Select Rune": "Sélectionnez une Rune",
"Select Target": "Sélectionnez une Cible",
"Select Target for Hatred": "Sélectionnez une Cible pour la Haine",
"Select the column to roll on to determine Beast Head": "Sélectionnez la colonne de lancer pour déterminer la Tête de Bête",
// Damage/Combat terms
"Add Metal AP to Damage": "Ajouter PA de métal aux Dégâts",
"Blunt Damage Reduction": "Réduction des Dégâts Contondants",
"Critical (if successful attack)": "Critique (si attaque réussie)",
"Damage Increase": "Augmentation des Dégâts",
"Damage Reduction": "Réduction des Dégâts",
"Remove Damage Rating": "Retirer l'Indice de Dégâts",
"Double Wounds + 4": "Blessures Doublées + 4",
"Double Wounds vs Dragons": "Blessures Doublées vs Dragons",
// Status/Values
"Armoured Value": "Valeur d'Armure",
"Halved": "Divisé par deux",
"Hatred Group": "Groupe de Haine",
"Sturdy Value": "Valeur de Robustesse",
// Equipment
"Mail": "Mailles",
"Mail & Leather": "Mailles et Cuir",
"Two-Handed": "A deux mains",
// Actions
"Misfire": "Raté",
"Misfire (Supercharged)": "Raté (Surchargé)",
"Roll": "Lancer",
// Misc
"Basic": "Base",
"Choice": "Choix",
"Provide an tattooist Actor (close to skip Tests)": "Fournissez un Acteur tatoueur (fermer pour ignorer les Tests)",
"Skill": "Compétence",
"Target has Aethyric Attunement or Second Sight": "La Cible possède Harmonisation Aethyrique ou Seconde Vue",
"Victory Notes for Experience Log": "Notes de Victoire pour le Journal d'Expérience"
};
// Fonction pour échapper les caractères spéciaux pour regex
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// Fonction pour traiter un fichier
function translateFile(filePath) {
let content = fs.readFileSync(filePath, 'utf8');
let modified = false;
// Appliquer chaque traduction
for (const [english, french] of Object.entries(translations)) {
const escapedEnglish = escapeRegExp(english);
// Patterns pour détecter les contextes (label, text, title, details, message)
const patterns = [
new RegExp(`(label\\s*:\\s*["'\`])${escapedEnglish}(["'\`])`, 'g'),
new RegExp(`(text\\s*:\\s*["'\`])${escapedEnglish}(["'\`])`, 'g'),
new RegExp(`(title\\s*:\\s*["'\`])${escapedEnglish}(["'\`])`, 'g'),
new RegExp(`(details\\s*:\\s*["'\`])${escapedEnglish}(["'\`])`, 'g'),
new RegExp(`(message\\s*:\\s*["'\`])${escapedEnglish}(["'\`])`, 'g'),
];
patterns.forEach(pattern => {
if (pattern.test(content)) {
content = content.replace(pattern, `$1${french}$2`);
modified = true;
}
});
}
if (modified) {
fs.writeFileSync(filePath, content, 'utf8');
return true;
}
return false;
}
// Fonction pour traiter récursivement un répertoire
function processDirectory(dirPath) {
const files = fs.readdirSync(dirPath);
let stats = {
total: 0,
modified: 0,
errors: 0
};
files.forEach(file => {
const filePath = path.join(dirPath, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
const subStats = processDirectory(filePath);
stats.total += subStats.total;
stats.modified += subStats.modified;
stats.errors += subStats.errors;
} else if (file.endsWith('.js')) {
stats.total++;
try {
if (translateFile(filePath)) {
stats.modified++;
console.log(`${path.relative(process.cwd(), filePath)}`);
}
} catch (error) {
stats.errors++;
console.error(`${path.relative(process.cwd(), filePath)}: ${error.message}`);
}
}
});
return stats;
}
// Main
console.log('Début de la traduction des scripts...\n');
const scriptsDir = path.join(__dirname, 'scripts');
const stats = processDirectory(scriptsDir);
console.log('\n' + '='.repeat(60));
console.log('Traduction terminée !');
console.log('='.repeat(60));
console.log(`Fichiers traités : ${stats.total}`);
console.log(`Fichiers modifiés : ${stats.modified}`);
console.log(`Erreurs : ${stats.errors}`);
console.log('='.repeat(60));