mirror of https://github.com/espruino/BangleApps
Add menu option for language translations (fix #136)
parent
5a4f15435f
commit
85be6af02e
|
@ -2,15 +2,20 @@
|
|||
/* Scans for strings that may be in English in each app, and
|
||||
outputs a list of strings that have been found.
|
||||
|
||||
Early work towards internationalisation.
|
||||
See https://github.com/espruino/BangleApps/issues/136
|
||||
See https://github.com/espruino/BangleApps/issues/1311
|
||||
*/
|
||||
|
||||
var IGNORE_STRINGS = [
|
||||
"5x5",
|
||||
"5x9Numeric7Seg",
|
||||
"Vector"
|
||||
];
|
||||
|
||||
var BASEDIR = __dirname+"/../";
|
||||
Espruino = require(BASEDIR+"core/lib/espruinotools.js");
|
||||
var fs = require("fs");
|
||||
|
||||
var APPSDIR = BASEDIR+"apps/";
|
||||
|
||||
function ERROR(s) {
|
||||
console.error("ERROR: "+s);
|
||||
process.exit(1);
|
||||
|
@ -18,6 +23,9 @@ function ERROR(s) {
|
|||
function WARN(s) {
|
||||
console.log("Warning: "+s);
|
||||
}
|
||||
function log(s) {
|
||||
console.log(s);
|
||||
}
|
||||
|
||||
var appsFile, apps;
|
||||
try {
|
||||
|
@ -39,31 +47,65 @@ function isNotString(s) {
|
|||
if (s.endsWith(".json") || s.endsWith(".img")) return true; // a filename
|
||||
if (s.endsWith("=")) return true; // probably base64
|
||||
if (s.startsWith("BTN")) return true; // button name
|
||||
if (IGNORE_STRINGS.includes(s)) return true; // one we know to ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
var textStrings = [];
|
||||
// A string that *could* be translated?
|
||||
var untranslatedStrings = [];
|
||||
// Strings that are marked with 'LANG'
|
||||
var translatedStrings = [];
|
||||
|
||||
console.log("Scanning...");
|
||||
console.log("Scanning apps...");
|
||||
apps.forEach((app,appIdx) => {
|
||||
var appDir = APPSDIR+app.id+"/";
|
||||
app.storage.forEach((file) => {
|
||||
if (!file.url || !file.name.endsWith(".js")) return;
|
||||
var fileContents = fs.readFileSync(appDir+file.url).toString();
|
||||
var lex = Espruino.Core.Utils.getLexer(fileContents);
|
||||
var lastIdx = 0;
|
||||
var tok = lex.next();
|
||||
while (tok!==undefined) {
|
||||
var previousString = fileContents.substring(lastIdx, tok.startIdx);
|
||||
if (tok.type=="STRING") {
|
||||
if (previousString.includes("/*LANG*/")) { // translated!
|
||||
if (!translatedStrings.includes(tok.value))
|
||||
translatedStrings.push(tok.value);
|
||||
} else { // untranslated - potential to translate?
|
||||
if (!isNotString(tok.value)) {
|
||||
//console.log(tok.str);
|
||||
if (!textStrings.includes(tok.value))
|
||||
textStrings.push(tok.value);
|
||||
if (!untranslatedStrings.includes(tok.value))
|
||||
untranslatedStrings.push(tok.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastIdx = tok.endIdx;
|
||||
tok = lex.next();
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log("Done");
|
||||
textStrings.sort();
|
||||
console.log(textStrings.join("\n"));
|
||||
untranslatedStrings.sort();
|
||||
translatedStrings.sort();
|
||||
|
||||
var report = "";
|
||||
/* // too many! don't output these
|
||||
log("Possible English Strings that could be translated");
|
||||
log("=================================================================");
|
||||
log("");
|
||||
log("Add these to IGNORE_STRINGS if the don't make sense...");
|
||||
log("");
|
||||
log(untranslatedStrings.map(s=>JSON.stringify(s)).join(",\n"));*/
|
||||
log("");
|
||||
|
||||
var languages = JSON.parse(fs.readFileSync(BASEDIR+"/lang/index.json").toString());
|
||||
languages.forEach(language => {
|
||||
console.log("Scanning "+language.code);
|
||||
log(language.code);
|
||||
log("==========");
|
||||
var translations = JSON.parse(fs.readFileSync(BASEDIR+"/lang/"+language.url).toString());
|
||||
translatedStrings.forEach(str => {
|
||||
if (!translations.GLOBAL[str])
|
||||
console.log(`Missing translation for ${JSON.stringify(str)}`);
|
||||
});
|
||||
log("");
|
||||
});
|
||||
console.log("Done.");
|
||||
|
|
|
@ -141,6 +141,11 @@
|
|||
<input type="checkbox" id="settings-settime">
|
||||
<i class="form-icon"></i> Always update time when we connect
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<select class="form-select form-inline" id="settings-lang" style="width: 10em">
|
||||
<option value="">None (English)</option>
|
||||
</select> <span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>)</span>
|
||||
</div>
|
||||
<button class="btn" id="defaultsettings">Default settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"//":"British English language translations - the default strings in apps are all english anyway, so no need to have translations for most things",
|
||||
"GLOBAL": {
|
||||
"//":"Translations that apply for all apps",
|
||||
"//":"Translations that apply for all apps"
|
||||
},
|
||||
"alarm": {
|
||||
"//":"App-specific overrides",
|
||||
"//":"App-specific overrides"
|
||||
}
|
||||
}
|
||||
|
|
42
loader.js
42
loader.js
|
@ -164,6 +164,48 @@ window.addEventListener('load', (event) => {
|
|||
showToast("App Install failed, "+err,"error");
|
||||
});
|
||||
});
|
||||
|
||||
// Load language list
|
||||
httpGet("lang/index.json").then(languagesJSON=>{
|
||||
var languages;
|
||||
try {
|
||||
languages = JSON.parse(languagesJSON);
|
||||
} catch(e) {
|
||||
console.error("lang/index.json Corrupted", e);
|
||||
}
|
||||
|
||||
function reloadLanguage() {
|
||||
LANGUAGE = undefined;
|
||||
if (SETTINGS.language) {
|
||||
var language = languages.find(l=>l.code==SETTINGS.language);
|
||||
if (language) {
|
||||
var langURL = "lang/"+language.url;
|
||||
httpGet(langURL).then(languageJSON=>{
|
||||
try {
|
||||
LANGUAGE = JSON.parse(languageJSON);
|
||||
console.log(`${langURL} loaded successfully`);
|
||||
} catch(e) {
|
||||
console.error(`${langURL} Corrupted`, e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error(`Language code ${JSON.stringify(SETTINGS.language)} not found in lang/index.json`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectLang = document.getElementById("settings-lang");
|
||||
console.log(languages);
|
||||
languages.forEach(lang => {
|
||||
selectLang.innerHTML += `<option value="${lang.code}" ${SETTINGS.language==lang.code?"selected":""}>${lang.name} (${lang.code})</option>`;
|
||||
});
|
||||
selectLang.addEventListener("change",event=>{
|
||||
SETTINGS.language = event.target.value;
|
||||
reloadLanguage();
|
||||
saveSettings();
|
||||
});
|
||||
reloadLanguage();
|
||||
});
|
||||
});
|
||||
|
||||
function onAppJSONLoaded() {
|
||||
|
|
Loading…
Reference in New Issue