Skip to content

Commit 5a6cf40

Browse files
committed
app pre-translation support - espruino/BangleApps#136
1 parent b033af0 commit 5a6cf40

File tree

3 files changed

+67
-9
lines changed

3 files changed

+67
-9
lines changed

js/appinfo.js

+44-4
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,53 @@ function toJS(txt) {
4242
return js;
4343
}
4444

45+
// Translate any strings in the app that are prefixed with /*LANG*/
46+
// see https://github.com/espruino/BangleApps/issues/136
47+
function translateJS(options, app, code) {
48+
var lex = Espruino.Core.Utils.getLexer(code);
49+
var outjs = "";
50+
var lastIdx = 0;
51+
var tok = lex.next();
52+
while (tok!==undefined) {
53+
var previousString = code.substring(lastIdx, tok.startIdx);
54+
var tokenString = code.substring(tok.startIdx, tok.endIdx);
55+
if (tok.type=="STRING" && previousString.includes("/*LANG*/")) {
56+
previousString=previousString.replace("/*LANG*/","");
57+
var language = options.language;
58+
if (language[app.id] && language[app.id][tok.value]) {
59+
tokenString = JSON.stringify(language.GLOBAL[tok.value]);
60+
} else if (language.GLOBAL[tok.value]) {
61+
tokenString = JSON.stringify(language.GLOBAL[tok.value]);
62+
} else {
63+
// Unhandled translation...
64+
//console.log("Untranslated ",tokenString);
65+
}
66+
}
67+
outjs += previousString+tokenString;
68+
lastIdx = tok.endIdx;
69+
tok = lex.next();
70+
}
71+
72+
/*console.log("==================== IN");
73+
console.log(code);
74+
console.log("==================== OUT");
75+
console.log(outjs);*/
76+
return outjs;
77+
}
78+
4579
// Run JS through EspruinoTools to pull in modules/etc
46-
function parseJS(storageFile, options) {
80+
function parseJS(storageFile, options, app) {
4781
if (storageFile.url && storageFile.url.endsWith(".js") && !storageFile.url.endsWith(".min.js")) {
4882
// if original file ends in '.js'...
83+
var js = storageFile.content;
84+
// check for language translations
85+
if (options.language)
86+
js = translateJS(options, app, js);
87+
// handle modules
4988
let localModulesURL = "modules";
5089
if (typeof window!=="undefined")
5190
localModulesURL = window.location.origin + window.location.pathname.replace(/[^/]*$/,"") + "modules";
52-
return Espruino.transform(storageFile.content, {
91+
return Espruino.transform(js, {
5392
SET_TIME_ON_WRITE : false,
5493
PRETOKENISE : options.settings.pretokenise,
5594
MODULE_URL : localModulesURL+"|https://www.espruino.com/modules",
@@ -69,6 +108,7 @@ var AppInfo = {
69108
fileGetter : callback for getting URL,
70109
settings : global settings object
71110
device : { id : ..., version : ... } info about the currently connected device
111+
language : object of translations, eg 'lang/de_DE.json'
72112
}
73113
*/
74114
getFiles : (app,options) => {
@@ -91,7 +131,7 @@ var AppInfo = {
91131

92132
Promise.all(appFiles.map(storageFile => {
93133
if (storageFile.content!==undefined)
94-
return Promise.resolve(storageFile).then(storageFile => parseJS(storageFile,options));
134+
return Promise.resolve(storageFile).then(storageFile => parseJS(storageFile,options,app));
95135
else if (storageFile.url)
96136
return options.fileGetter(`apps/${app.id}/${storageFile.url}`).then(content => {
97137
return {
@@ -100,7 +140,7 @@ var AppInfo = {
100140
content : content,
101141
evaluate : storageFile.evaluate,
102142
noOverwrite : storageFile.noOverwrite
103-
}}).then(storageFile => parseJS(storageFile,options));
143+
}}).then(storageFile => parseJS(storageFile,options,app));
104144
else return Promise.resolve();
105145
})).then(fileContents => { // now we just have a list of files + contents...
106146
// filter out empty files

js/comms.js

+2
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@ const Comms = {
5757
/* app : an apps.json structure (i.e. with `storage`)
5858
options : { skipReset : bool, // don't reset first
5959
device : { id : ..., version : ... } info about the currently connected device
60+
language : object of translations, eg 'lang/de_DE.json'
6061
} */
6162
Progress.show({title:`Uploading ${app.name}`,sticky:true});
6263
return AppInfo.getFiles(app, {
6364
fileGetter : httpGet,
6465
settings : SETTINGS,
66+
language : options.language,
6567
device : options.device
6668
}).then(fileContents => {
6769
return new Promise((resolve,reject) => {

js/index.js

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
let appJSON = []; // List of apps and info from apps.json
22
let appSortInfo = {}; // list of data to sort by, from appdates.csv { created, modified }
33
let files = []; // list of files on the Espruimo Device
4-
let DEFAULTSETTINGS = {
4+
const DEFAULTSETTINGS = {
55
pretokenise : true,
66
favourites : ["boot","launch","setting"]
77
};
8-
let SETTINGS = JSON.parse(JSON.stringify(DEFAULTSETTINGS)); // clone
8+
var SETTINGS = JSON.parse(JSON.stringify(DEFAULTSETTINGS)); // clone
99

1010
let device = {
1111
id : undefined, // The Espruino device ID of this device, eg. BANGLEJS
@@ -14,7 +14,23 @@ let device = {
1414
connected : false, // are we connected via BLE right now?
1515
appsInstalled : [] // list of app {id,version} of installed apps
1616
};
17-
17+
// FOR TESTING ONLY
18+
/*let LANGUAGE = {
19+
"//":"German language translations",
20+
"GLOBAL": {
21+
"//":"Translations that apply for all apps",
22+
"Alarm" : "Wecker",
23+
"Hours" : "Stunden",
24+
"Minutes" : "Minuten",
25+
"Enabled" : "Aktiviert",
26+
"Settings" : "Einstellungen"
27+
},
28+
"alarm": {
29+
"//":"App-specific overrides",
30+
"Alarm" : "Alarm"
31+
}
32+
};*/
33+
var LANGUAGE = undefined;
1834

1935

2036
httpGet("apps.json").then(apps=>{
@@ -135,7 +151,7 @@ function handleCustomApp(appTemplate) {
135151
console.log("Received custom app", app);
136152
modal.remove();
137153
checkDependencies(app)
138-
.then(()=>Comms.uploadApp(app,{device:device}))
154+
.then(()=>Comms.uploadApp(app,{device:device, language:LANGUAGE}))
139155
.then(()=>{
140156
Progress.hide({sticky:true});
141157
resolve();
@@ -423,7 +439,7 @@ function uploadApp(app) {
423439
return updateApp(app);
424440
}
425441
checkDependencies(app)
426-
.then(()=>Comms.uploadApp(app,{device:device}))
442+
.then(()=>Comms.uploadApp(app,{device:device, language:LANGUAGE}))
427443
.then((appJSON) => {
428444
Progress.hide({ sticky: true });
429445
if (appJSON) {

0 commit comments

Comments
 (0)