making language scan pop up more useful info

master
Gordon Williams 2022-01-19 11:30:18 +00:00
parent 1b266f7279
commit bb8c291755
1 changed files with 46 additions and 19 deletions

View File

@ -6,19 +6,26 @@ See https://github.com/espruino/BangleApps/issues/1311
*/ */
var IGNORE_STRINGS = [ var IGNORE_STRINGS = [
"5x5","6x8","6x8:2","12x20","---","...", "5x5","6x8","6x8:2","4x6","12x20","6x15","5x9Numeric7Seg", "Vector", // fonts
"5x9Numeric7Seg", "---","...","*","##","00","GPS","ram",
"Vector", "12hour","rising","falling","title",
"sortorder","tl","tr" "sortorder","tl","tr",
"function","object", // typeof===
"txt", // layout styles
"play","stop","pause", // music state
]; ];
var IGNORE_FUNCTION_PARAMS = [ var IGNORE_FUNCTION_PARAMS = [
"read", "read",
"readJSON", "readJSON",
"require", "require",
"setFont", "setFont","setUI","setLCDMode",
"on", "on",
"RegExp", "RegExp","sendCommand",
"print","log"
];
var IGNORE_ARRAY_ACCESS = [
"WIDGETS"
]; ];
var BASEDIR = __dirname+"/../"; var BASEDIR = __dirname+"/../";
@ -50,9 +57,11 @@ try{
} }
// Given a string value, work out if it's obviously not a text string // Given a string value, work out if it's obviously not a text string
function isNotString(s, wasFnCall) { function isNotString(s, wasFnCall, wasArrayAccess) {
if (s=="") return true;
// wasFnCall is set to the function name if 's' is the first argument to a function // wasFnCall is set to the function name if 's' is the first argument to a function
if (wasFnCall && IGNORE_FUNCTION_PARAMS.includes(wasFnCall)) return true; if (wasFnCall && IGNORE_FUNCTION_PARAMS.includes(wasFnCall)) return true;
if (wasArrayAccess && IGNORE_ARRAY_ACCESS.includes(wasArrayAccess)) return true;
if (s=="Storage") console.log("isNotString",s,wasFnCall); if (s=="Storage") console.log("isNotString",s,wasFnCall);
if (s.length<2) return true; // too short if (s.length<2) return true; // too short
@ -66,7 +75,7 @@ function isNotString(s, wasFnCall) {
} }
function getTextFromString(s) { function getTextFromString(s) {
return s.replace(/^([.<>\- ]*)([^<>\!\?]*?)([.<>\!\?\- ]*)$/,"$2"); return s.replace(/^([.<>\-\n ]*)([^<>\!\?]*?)([.<>\!\?\-\n ]*)$/,"$2");
} }
// A string that *could* be translated? // A string that *could* be translated?
@ -93,24 +102,32 @@ apps.forEach((app,appIdx) => {
app.storage.forEach((file) => { app.storage.forEach((file) => {
if (!file.url || !file.name.endsWith(".js")) return; if (!file.url || !file.name.endsWith(".js")) return;
var filePath = appDir+file.url; var filePath = appDir+file.url;
var shortFilePath = "apps/"+app.id+"/"+file.url;
var fileContents = fs.readFileSync(filePath).toString(); var fileContents = fs.readFileSync(filePath).toString();
var lex = Espruino.Core.Utils.getLexer(fileContents); var lex = Espruino.Core.Utils.getLexer(fileContents);
var lastIdx = 0; var lastIdx = 0;
var wasFnCall = undefined; // set to 'setFont' if we're at soemthing like setFont(".." var wasFnCall = undefined; // set to 'setFont' if we're at something like setFont(".."
var wasArrayAccess = undefined; // set to 'WIDGETS' if we're at something like WIDGETS[".."
var tok = lex.next(); var tok = lex.next();
while (tok!==undefined) { while (tok!==undefined) {
var previousString = fileContents.substring(lastIdx, tok.startIdx); var previousString = fileContents.substring(lastIdx, tok.startIdx);
//console.log(wasFnCall,tok.type,tok.value);
if (tok.type=="STRING") { if (tok.type=="STRING") {
if (previousString.includes("/*LANG*/")) { // translated! if (previousString.includes("/*LANG*/")) { // translated!
addString(translatedStrings, tok.value, filePath); addString(translatedStrings, tok.value, shortFilePath);
} else { // untranslated - potential to translate? } else { // untranslated - potential to translate?
if (!isNotString(tok.value, wasFnCall)) { if (!isNotString(tok.value, wasFnCall, wasArrayAccess)) {
addString(untranslatedStrings, tok.value, filePath); addString(untranslatedStrings, tok.value, shortFilePath);
} }
} }
} else if (tok.value!="(") wasFnCall=undefined; } else {
if (tok.type=="ID") wasFnCall=tok.value; if (tok.value!="(") wasFnCall=undefined;
if (tok.value!="[") wasArrayAccess=undefined;
}
//console.log(wasFnCall,tok.type,tok.value);
if (tok.type=="ID") {
wasFnCall = tok.value;
wasArrayAccess = tok.value;
}
lastIdx = tok.endIdx; lastIdx = tok.endIdx;
tok = lex.next(); tok = lex.next();
} }
@ -118,17 +135,27 @@ apps.forEach((app,appIdx) => {
}); });
untranslatedStrings.sort((a,b)=>a.uses - b.uses); untranslatedStrings.sort((a,b)=>a.uses - b.uses);
translatedStrings.sort((a,b)=>a.uses - b.uses); translatedStrings.sort((a,b)=>a.uses - b.uses);
untranslatedStrings.filter(e => e.uses>2); // ignore individual uses
var report = ""; var report = "";
// too many! don't output these
log("Translated Strings that are not tagged with LANG");
log("=================================================================");
log("");
log("Maybe we should add /*LANG*/ to these automatically?");
log("");
log(untranslatedStrings.filter(e => translatedStrings.find(t=>t.str==e.str)).map(e=>`${JSON.stringify(e.str)} (${e.files.join(",")})`).join("\n"));
log("");
//process.exit(1);
log("Possible English Strings that could be translated"); log("Possible English Strings that could be translated");
log("================================================================="); log("=================================================================");
log(""); log("");
log("Add these to IGNORE_STRINGS if the don't make sense..."); log("Add these to IGNORE_STRINGS if they don't make sense...");
log(""); log("");
log(untranslatedStrings.map(e=>`${JSON.stringify(e.str)} (${e.uses} uses)`).join("\n")); // ignore ones only used once or twice
log(untranslatedStrings.filter(e => e.uses>2).filter(e => !translatedStrings.find(t=>t.str==e.str)).map(e=>`${JSON.stringify(e.str)} (${e.uses} uses)`).join("\n"));
log(""); log("");
//process.exit(1);
var languages = JSON.parse(fs.readFileSync(BASEDIR+"/lang/index.json").toString()); var languages = JSON.parse(fs.readFileSync(BASEDIR+"/lang/index.json").toString());
languages.forEach(language => { languages.forEach(language => {