mirror of
https://github.com/moodle/moodle.git
synced 2025-07-26 08:50:30 +02:00
This change renames the generator and has it generate the language strings for all available languages for easier import into AMOS.
140 lines
4.5 KiB
JavaScript
140 lines
4.5 KiB
JavaScript
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import {readdir, readFile, writeFile, mkdir} from 'fs/promises';
|
|
import {join as joinPath} from 'path';
|
|
|
|
const fullyTranslatedLanguage = 'de';
|
|
const maxStringIdentifierLength = 90;
|
|
|
|
const readStringsFromLanguages = async (language) => {
|
|
const fileContent = await readFile(`./langs/${language}.js`, 'utf-8');
|
|
|
|
let translations = {};
|
|
const tinymce = {
|
|
addI18n: (language, strings) => {
|
|
translations = strings;
|
|
},
|
|
};
|
|
|
|
eval(fileContent);
|
|
|
|
return Object.keys(translations).sort().reduce((sortedTranslations, key) => {
|
|
sortedTranslations[key] = translations[key];
|
|
return sortedTranslations;
|
|
}, {});
|
|
};
|
|
|
|
const getStringMap = (strings) => {
|
|
const stringMap = {};
|
|
|
|
const getUniqueKeyForString = (string, modifier = 0) => {
|
|
let stringKey = string.toLowerCase()
|
|
.replaceAll(' ', '_')
|
|
.replaceAll(/\{(\d)\}/g, '$1')
|
|
.replaceAll('#', 'hash')
|
|
.replaceAll(/[^a-z0-9_\-\.]/g, '')
|
|
;
|
|
|
|
if (stringKey === '') {
|
|
throw new Error(`The calculated key for '${string}' was empty`);
|
|
}
|
|
|
|
stringKey = `tiny:${stringKey}`;
|
|
|
|
if (stringKey.length > maxStringIdentifierLength) {
|
|
const modifierLength = modifier === 0 ? 0 : `${modifier}`.length;
|
|
stringKey = stringKey.slice(0, maxStringIdentifierLength - modifierLength);
|
|
}
|
|
|
|
if (modifier > 0) {
|
|
stringKey = `${stringKey}${modifier}`;
|
|
}
|
|
|
|
if (typeof stringMap[stringKey] !== 'undefined') {
|
|
return getUniqueKeyForString(string, ++modifier);
|
|
}
|
|
|
|
return stringKey;
|
|
};
|
|
|
|
strings.forEach((string) => {
|
|
const stringKey = getUniqueKeyForString(string);
|
|
if (typeof stringMap[stringKey] !== 'undefined') {
|
|
throw new Error(`Found existing key ${stringKey}`);
|
|
}
|
|
|
|
stringMap[stringKey] = string;
|
|
});
|
|
|
|
return stringMap;
|
|
};
|
|
|
|
const getPhpStrings = (stringMap, translatedStrings) => Object.entries(stringMap).map(([stringKey, englishString]) => {
|
|
if (translatedStrings[englishString].length === 0) {
|
|
return null;
|
|
}
|
|
return `$string['${stringKey}'] = '${translatedStrings[englishString].replaceAll("'", "\\\'")}';`
|
|
})
|
|
.filter((value) => value !== null)
|
|
.join("\n");
|
|
|
|
const storeEnglishStrings = async(stringMap) => {
|
|
const englishStrings = Object.entries(stringMap).map(([stringKey, stringValue]) => {
|
|
return `$string['${stringKey}'] = '${stringValue.replace("'", "\\\'")}';`
|
|
}).join("\n");
|
|
await writeFile('./strings.php', englishStrings + "\n");
|
|
await writeFile('./tinystrings.json', JSON.stringify(stringMap, null, ' '));
|
|
}
|
|
|
|
const constructTranslationFile = async(language, englishStringMap = null) => {
|
|
const strings = await readStringsFromLanguages(language);
|
|
console.log(`Generating translation data for ${language} with ${Object.keys(strings).length} strings`);
|
|
const stringMap = englishStringMap === null ? getStringMap(Object.keys(strings)) : englishStringMap;
|
|
|
|
const langDir = joinPath('lang', language);
|
|
await mkdir(langDir, {recursive: true});
|
|
|
|
const fileContent = `<?php
|
|
|
|
${getPhpStrings(stringMap, strings)}
|
|
`;
|
|
|
|
await writeFile(joinPath(langDir, `editor_tiny.php`), fileContent);
|
|
|
|
return {
|
|
strings,
|
|
stringMap,
|
|
};
|
|
};
|
|
|
|
const constructTranslationFiles = async() => {
|
|
const {stringMap} = await constructTranslationFile(fullyTranslatedLanguage);
|
|
storeEnglishStrings(stringMap);
|
|
|
|
readdir('./langs/').then((files) => {
|
|
files.forEach(async(file) => {
|
|
const langIdent = file.replace('.js', '');
|
|
if (langIdent === fullyTranslatedLanguage) {
|
|
// This language is already done.
|
|
return;
|
|
}
|
|
await constructTranslationFile(langIdent, stringMap);
|
|
});
|
|
});
|
|
}
|
|
|
|
constructTranslationFiles();
|