diff --git a/Antedit/build.json b/Antedit/build.json index d230099..32bd2f7 100644 --- a/Antedit/build.json +++ b/Antedit/build.json @@ -40,6 +40,20 @@ } ] }, + "locale": { + "require": ["locale"], + "jobs": [ + { + "name":"locale-gen", + "data": { + "src": "", + "exclude": ["build/", "css/"], + "locale": "en_GB", + "dest": "package.json" + } + } + ] + }, "uglify": { "require": ["terser"], "jobs": [ diff --git a/Antedit/package.json b/Antedit/package.json index e01e187..5e061a2 100644 --- a/Antedit/package.json +++ b/Antedit/package.json @@ -1,24 +1,89 @@ { "pkgname": "Antedit", - "app":"Antedit", - "name":"Antos Editor", - "description":"Antos text/code editor", - "info":{ + "app": "Antedit", + "name": "Antos Editor", + "description": "Antos text/code editor", + "info": { "author": "Xuan Sang LE", "email": "mrsang@iohub.dev" }, - "version":"0.1.8-a", - "category":"Development", - "iconclass":"bi bi-journal-code", - "mimes":[ + "version": "0.1.8-a", + "category": "Development", + "iconclass": "bi bi-journal-code", + "mimes": [ "text/.*", "[^/]*/json.*", "[^/]*/.*ml", "[^/]*/javascript", "dir" ], - "dependencies":[ + "dependencies": [ "MonacoCore@0.23.0-r" ], - "locale": {} + "locale": { + "en_GB": { + "Output": "Output", + "Close tab": "Close tab", + "Close without saving ?": "Close without saving ?", + "Unable to open: {0}": "Unable to open: {0}", + "Unable to save file: {0}": "Unable to save file: {0}", + "Save as": "Save as", + "New extension at": "New extension at", + "Select extension archive": "Select extension archive", + "Current folder is not found": "Current folder is not found", + "Select build directory": "Select build directory", + "Unable to read meta-data": "Unable to read meta-data", + "ExtensionName": "ExtensionName", + "Files generated in {0}": "Files generated in {0}", + "Unable to build extension:{0}": "Unable to build extension:{0}", + "Unable to read meta-data:{0}": "Unable to read meta-data:{0}", + "Invalid extension meta-data": "Invalid extension meta-data", + "Unable to run extension:{0}": "Unable to run extension:{0}", + "Archive created at {0}": "Archive created at {0}", + "Unable to read meta-data: {0}": "Unable to read meta-data: {0}", + "Extension installed": "Extension installed", + "Unable to install extension: {0}": "Unable to install extension: {0}", + "Enter URI": "Enter URI", + "Please enter extension URI:": "Please enter extension URI:", + "Unable to create extension directories: {0}": "Unable to create extension directories: {0}", + "New file": "New file", + "New folder": "New folder", + "Rename": "Rename", + "Delete": "Delete", + "File name": "File name", + "Folder name": "Folder name", + "Quit": "Quit", + "View": "View", + "Toggle bottom bar": "Toggle bottom bar", + "Toggle split view": "Toggle split view", + "Unable to move file/folder": "Unable to move file/folder", + "Editor": "Editor", + "Change language mode": "Change language mode", + "Select language": "Select language", + "Unable to disable split view: Please save changes of modified files on the right panel": "Unable to disable split view: Please save changes of modified files on the right panel", + "File": "File", + "New": "New", + "Open Recent": "Open Recent", + "Open": "Open", + "Open Folder": "Open Folder", + "Save": "Save", + "Fail to create: {0}": "Fail to create: {0}", + "Fail to rename: {0}": "Fail to rename: {0}", + "Fail to delete: {0}": "Fail to delete: {0}", + "Open file": "Open file", + "Open folder": "Open folder", + "Cannot load extension meta data": "Cannot load extension meta data", + "unable to load extension: {0}": "unable to load extension: {0}", + "Unable to find extension: {0}": "Unable to find extension: {0}", + "Unable to find action: {0}": "Unable to find action: {0}", + "Unable to preload extension": "Unable to preload extension", + "Example action": "Example action", + "New Extension": "New Extension", + "Build": "Build", + "Run": "Run", + "Build release": "Build release", + "Install extension from file": "Install extension from file", + "Install extension from URL": "Install extension from URL" + } + } } \ No newline at end of file diff --git a/Antedit/ts/EditorExtensionMaker.ts b/Antedit/ts/EditorExtensionMaker.ts index c7e6cd1..b0636c8 100644 --- a/Antedit/ts/EditorExtensionMaker.ts +++ b/Antedit/ts/EditorExtensionMaker.ts @@ -150,7 +150,7 @@ namespace OS { this.logger().clear(); this.app .openDialog("FileDialog", { - title: "__(New CodePad extension at)", + title: "__(New extension at)", file: { basename: __("ExtensionName") }, mimes: ["dir"], }) diff --git a/libantosdk/build/debug/core/locale.worker.js b/libantosdk/build/debug/core/locale.worker.js new file mode 100644 index 0000000..3215a6c --- /dev/null +++ b/libantosdk/build/debug/core/locale.worker.js @@ -0,0 +1,154 @@ +importScripts('coffeescript.js'); + +class LocaleJob extends AntOSDKBaseJob { + constructor(data) + { + super(data); + } + execute() + { + switch (this.job.cmd) { + case 'locale-gen': + /** + * { + * src: source folder, + * exclude: exclude search rules + * include: include search rules + * locale: e.g. en_GB + * dest: destination file/ folder + * } + */ + this.gen() + .then(d =>this.result(d)) + .catch(e => this.error(e)); + break; + default: + const err_msg = `Unkown job ${this.job.cmd}`; + this.log_error(err_msg); + return this.error(err_msg); + } + } + ck_rules(path, rules) + { + for(const rule of rules) + { + const reg = new RegExp(rule); + if(path.match(reg)) + { + return true; + } + } + return false; + } + genlang(file, options) + { + // check if include or exclude + return new Promise(async (resolve, reject) => { + try{ + if( options.include && this.ck_rules(file,options.include) === false) + { + this.log_info(`locale-gen: ${file} is excluded`); + return resolve([]); + } + if( options.exclude && this.ck_rules(file,options.exclude) === true) + { + this.log_info(`locale-gen: ${file} is excluded`); + return resolve([]); + } + // check if file or folder + const meta = await this.meta(file); + if(meta.type === "dir") + { + const promises = []; + const entries = await this.scandir(file); + for(const entry of entries) + { + promises.push(this.genlang(`${file}/${entry.filename}`,options)); + } + const results = await Promise.all(promises); + let ret = []; + for(const el of results) + { + ret = ret.concat(el); + } + return resolve(ret); + } + else + { + const contents = await this.read_files([file]); + // find all matches + let regs = [ + "\"\s*__\\(([^\"]*)\\)\s*\"", + "__\\(\s*[\"'](.*)[\"'].*\\)" + ]; + let ret = []; + for(const reg of regs) + { + let matches = contents[0].match(new RegExp(reg,'g')); + if(matches) + { + for(const match of matches) + { + ret.push(match.match(new RegExp(reg))[1]); + } + } + } + if(ret.length > 0) + { + this.log_info(`locale-gen: Found in ${file}: \n${ret.join("\n")}`); + } + + return resolve(ret); + } + } + catch(error) + { + this.log_error(`${file}: ${error.toString()}`); + reject(error); + } + }); + } + + gen(){ + return new Promise(async (resolve, reject) => { + try { + const results = await this.genlang(this.job.data.src,this.job.data); + const locale = {}; + locale[this.job.data.locale] = {}; + for(const str of results) + { + locale[this.job.data.locale][str] = str; + } + // check destination + // if it a file, assume that it is a meta file + const meta = await this.meta(this.job.data.dest); + if(meta.type === "dir") + { + const file = `${this.job.data.dest}/${this.job.data.locale}.json`; + // save data + const result = await this.save_file(file,locale[this.job.data.locale],"object"); + this.log_info(`locale-gen: locale file generated at ${file}`); + resolve(result); + } + else + { + // read the meta file + const contents = await this.read_files([this.job.data.dest]); + const pkg = JSON.parse(contents[0]); + pkg.locale = locale; + // save data + const result = await this.save_file(this.job.data.dest,pkg,"object"); + this.log_info(`locale-gen: locale file generated at ${this.job.data.dest}`); + resolve(result); + } + } + catch(error) + { + this.log_error(error.toString()); + reject(error); + } + }); + } +} + +API.jobhandle["locale-gen"] = LocaleJob; \ No newline at end of file diff --git a/libantosdk/core/locale.worker.js b/libantosdk/core/locale.worker.js new file mode 100644 index 0000000..3215a6c --- /dev/null +++ b/libantosdk/core/locale.worker.js @@ -0,0 +1,154 @@ +importScripts('coffeescript.js'); + +class LocaleJob extends AntOSDKBaseJob { + constructor(data) + { + super(data); + } + execute() + { + switch (this.job.cmd) { + case 'locale-gen': + /** + * { + * src: source folder, + * exclude: exclude search rules + * include: include search rules + * locale: e.g. en_GB + * dest: destination file/ folder + * } + */ + this.gen() + .then(d =>this.result(d)) + .catch(e => this.error(e)); + break; + default: + const err_msg = `Unkown job ${this.job.cmd}`; + this.log_error(err_msg); + return this.error(err_msg); + } + } + ck_rules(path, rules) + { + for(const rule of rules) + { + const reg = new RegExp(rule); + if(path.match(reg)) + { + return true; + } + } + return false; + } + genlang(file, options) + { + // check if include or exclude + return new Promise(async (resolve, reject) => { + try{ + if( options.include && this.ck_rules(file,options.include) === false) + { + this.log_info(`locale-gen: ${file} is excluded`); + return resolve([]); + } + if( options.exclude && this.ck_rules(file,options.exclude) === true) + { + this.log_info(`locale-gen: ${file} is excluded`); + return resolve([]); + } + // check if file or folder + const meta = await this.meta(file); + if(meta.type === "dir") + { + const promises = []; + const entries = await this.scandir(file); + for(const entry of entries) + { + promises.push(this.genlang(`${file}/${entry.filename}`,options)); + } + const results = await Promise.all(promises); + let ret = []; + for(const el of results) + { + ret = ret.concat(el); + } + return resolve(ret); + } + else + { + const contents = await this.read_files([file]); + // find all matches + let regs = [ + "\"\s*__\\(([^\"]*)\\)\s*\"", + "__\\(\s*[\"'](.*)[\"'].*\\)" + ]; + let ret = []; + for(const reg of regs) + { + let matches = contents[0].match(new RegExp(reg,'g')); + if(matches) + { + for(const match of matches) + { + ret.push(match.match(new RegExp(reg))[1]); + } + } + } + if(ret.length > 0) + { + this.log_info(`locale-gen: Found in ${file}: \n${ret.join("\n")}`); + } + + return resolve(ret); + } + } + catch(error) + { + this.log_error(`${file}: ${error.toString()}`); + reject(error); + } + }); + } + + gen(){ + return new Promise(async (resolve, reject) => { + try { + const results = await this.genlang(this.job.data.src,this.job.data); + const locale = {}; + locale[this.job.data.locale] = {}; + for(const str of results) + { + locale[this.job.data.locale][str] = str; + } + // check destination + // if it a file, assume that it is a meta file + const meta = await this.meta(this.job.data.dest); + if(meta.type === "dir") + { + const file = `${this.job.data.dest}/${this.job.data.locale}.json`; + // save data + const result = await this.save_file(file,locale[this.job.data.locale],"object"); + this.log_info(`locale-gen: locale file generated at ${file}`); + resolve(result); + } + else + { + // read the meta file + const contents = await this.read_files([this.job.data.dest]); + const pkg = JSON.parse(contents[0]); + pkg.locale = locale; + // save data + const result = await this.save_file(this.job.data.dest,pkg,"object"); + this.log_info(`locale-gen: locale file generated at ${this.job.data.dest}`); + resolve(result); + } + } + catch(error) + { + this.log_error(error.toString()); + reject(error); + } + }); + } +} + +API.jobhandle["locale-gen"] = LocaleJob; \ No newline at end of file