forked from public/foundryvtt-wh4-lang-fr-fr
217 lines
7.3 KiB
JavaScript
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`);
|