Files
foundryvtt-wh4-lang-fr-fr/tools/find-english-texts.js

217 lines
7.3 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 FR_DIR = path.join(__dirname, 'scripts');
// Mots anglais communs pour détecter du texte en anglais
const englishWords = [
'the', 'and', 'or', 'to', 'from', 'with', 'without', 'has', 'have', 'had',
'is', 'are', 'was', 'were', 'been', 'being', 'will', 'would', 'should',
'can', 'could', 'may', 'might', 'must', 'shall',
'this', 'that', 'these', 'those', 'what', 'which', 'who', 'when', 'where',
'not', 'all', 'any', 'each', 'every', 'some', 'other', 'another',
'gain', 'gained', 'lose', 'lost', 'add', 'added', 'remove', 'removed',
'take', 'taken', 'give', 'given', 'make', 'made', 'find', 'found',
'get', 'got', 'set', 'put', 'use', 'used', 'using',
'apply', 'applied', 'test', 'tested', 'roll', 'rolled',
'if', 'else', 'while', 'for', 'return', // Mots-clés JS à ignorer dans le code
'failed', 'passed', 'success', 'failure', 'check', 'checked',
'attack', 'damage', 'heal', 'healed', 'wound', 'wounded',
'spell', 'cast', 'casting', 'magic', 'effect', 'affected',
'target', 'targets', 'hit', 'miss', 'critical',
'weapon', 'armour', 'armor', 'shield', 'equipped',
'skill', 'talent', 'trait', 'ability', 'bonus',
'enter', 'choose', 'select', 'click', 'press',
'must', 'need', 'require', 'required', 'cannot', 'unable',
'ignore', 'ignored', 'prevent', 'prevented', 'resist', 'resisted',
'duration', 'permanent', 'temporary', 'condition', 'status',
'character', 'actor', 'creature', 'enemy', 'ally',
'during', 'until', 'after', 'before', 'when', 'while'
];
// Patterns de textes techniques à ignorer (clés, IDs, etc.)
const technicalPatterns = [
/^[a-z]+$/, // Tout en minuscules (probablement une clé)
/^[0-9]+$/, // Que des chiffres
/^[0-9a-f]{16}$/i, // Hash/ID
/^[a-z_]+$/, // snake_case (clé technique)
/^[a-z][a-zA-Z]+$/, // camelCase (clé technique)
/^\$\{.*\}$/, // Template literal variable
/^system\./, // Chemin système
/^wfrp4e/, // Préfixe système
/^@/, // Référence (ex: @Condition)
/^[A-Z]{2,}$/, // Acronymes courts
/^[\w-]{1,10}$/, // Clés courtes
];
// Fonction pour extraire les chaînes d'un fichier
function extractStrings(content) {
const strings = new Set();
// Patterns pour capturer les chaînes entre guillemets
// On évite les template literals complexes avec interpolation
const patterns = [
/"([^"]{3,})"/g, // Double quotes
/'([^']{3,})'/g, // Single quotes
];
patterns.forEach(pattern => {
const matches = content.matchAll(pattern);
for (const match of matches) {
const str = match[1].trim();
if (str.length > 2) {
strings.add(str);
}
}
});
// Pour les template literals, on cherche ceux sans interpolation ou simples
const backtickPattern = /`([^`\$]{3,})`/g;
const backtickMatches = content.matchAll(backtickPattern);
for (const match of backtickMatches) {
const str = match[1].trim();
if (str.length > 2) {
strings.add(str);
}
}
return Array.from(strings);
}
// Fonction pour détecter si une chaîne est probablement du texte en anglais
function isEnglishText(str) {
// Ignorer les patterns techniques
for (const pattern of technicalPatterns) {
if (pattern.test(str)) {
return false;
}
}
// Ignorer les chaînes trop courtes
if (str.length < 3) {
return false;
}
// Convertir en minuscules pour la comparaison
const lowerStr = str.toLowerCase();
// Vérifier la présence de mots anglais
const words = lowerStr.split(/\W+/);
const englishWordCount = words.filter(word =>
englishWords.includes(word) && word.length > 1
).length;
// Si au moins 1 mot anglais significatif est trouvé, c'est probablement de l'anglais
if (englishWordCount > 0) {
return true;
}
// Patterns de phrases anglaises typiques
const englishPhrases = [
/\b(the|a|an)\s+\w+/i,
/\b(cannot|can't|won't|don't|doesn't)\b/i,
/\b(must|should|will|would)\s+\w+/i,
/\b(has|have|had)\s+(been|gained|lost|acquired)/i,
/\b(enter|choose|select)\s+\w+/i,
/\b(rolled?|passed?|failed?)\b/i,
];
for (const pattern of englishPhrases) {
if (pattern.test(str)) {
return true;
}
}
return false;
}
// Fonction pour filtrer les faux positifs évidents
function shouldIgnore(str) {
// Ignorer les chemins et références système
if (str.includes('Compendium.') || str.includes('UUID[')) {
return true;
}
// Ignorer les noms de propriétés système
if (str.match(/^(system|flags|data|items|effects|actor|token)\./)) {
return true;
}
// Ignorer les expressions JavaScript
if (str.match(/^(let|const|var|function|return|if|else|for|while)\b/)) {
return true;
}
return false;
}
// Analyser tous les fichiers
function analyzeScripts() {
const files = fs.readdirSync(FR_DIR).filter(f => f.endsWith('.js'));
const results = [];
console.log(`Analyse de ${files.length} fichiers...\n`);
files.forEach(file => {
const filePath = path.join(FR_DIR, file);
const content = fs.readFileSync(filePath, 'utf8');
const strings = extractStrings(content);
const englishStrings = strings.filter(str => {
if (shouldIgnore(str)) return false;
return isEnglishText(str);
});
if (englishStrings.length > 0) {
results.push({
file,
count: englishStrings.length,
strings: englishStrings
});
}
});
return results;
}
// Main
console.log('Recherche des textes anglais dans les scripts FR...\n');
console.log('='.repeat(60));
const results = analyzeScripts();
console.log('\n' + '='.repeat(60));
console.log(`Fichiers avec du texte anglais : ${results.length}\n`);
// Trier par nombre de chaînes anglaises (décroissant)
results.sort((a, b) => b.count - a.count);
// Afficher les résultats
let totalStrings = 0;
results.forEach(({ file, count, strings }) => {
totalStrings += count;
console.log(`\n${file} (${count} texte(s) anglais) :`);
console.log('-'.repeat(60));
strings.forEach(str => {
// Limiter la longueur affichée
const displayStr = str.length > 80 ? str.substring(0, 77) + '...' : str;
console.log(`${displayStr}`);
});
});
console.log('\n' + '='.repeat(60));
console.log('Résumé :');
console.log('-'.repeat(60));
console.log(`Fichiers avec texte anglais : ${results.length}/${fs.readdirSync(FR_DIR).filter(f => f.endsWith('.js')).length}`);
console.log(`Total de textes anglais détectés : ${totalStrings}`);
console.log('='.repeat(60));
// Sauvegarder dans un fichier JSON
const outputFile = path.join(__dirname, 'english-texts-found.json');
fs.writeFileSync(outputFile, JSON.stringify(results, null, 2), 'utf8');
console.log(`\nRésultats sauvegardés dans : english-texts-found.json`);