/**=====LICENSE STATEMENT START=====
Translator++
CAT (Computer-Assisted Translation) tools and framework to create quality
translations and localizations efficiently.
Copyright (C) 2018 Dreamsavior<dreamsavior@gmail.com>
This program 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.
This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
=====LICENSE STATEMENT END=====*/
class ScriptParser extends require("www/js/ParserBase.js").ParserBase {
constructor(script, options, callback) {
super(script, options, callback);
options = options || {};
this.debugLevel = options.debugLevel;
this.currentEntryPoint = {};
this.language = options.language;
this.currentOffset = 0;
this.hook = {};
this.captureTypes = options.captureTypes||["string", "string-literal"]
this.transData = {
data:[],
context:[],
tags:[],
parameters:[],
indexIds:{}
};
}
}
ScriptParser.stringEnclosure = {
ruby:[
{
start:'"',
end:'"'
},
{
start:"'",
end:"'"
},
{
start:"%/",
end:"/"
}
]
}
ScriptParser.prototype.on = function(label, fn) {
if (typeof fn !== "function") return this;
this.hook[label] = fn;
return this;
}
ScriptParser.prototype.off = function(label) {
if (!label) return;
delete this.hook[label];
return this;
}
ScriptParser.prototype.trigger = function(label) {
if (typeof this.hook[label] !== "function") return this;
var args = [];
for (var i=1; i<arguments.length; i++) {
args.push(arguments[i]);
}
return this.hook[label].apply(this, args);
}
ScriptParser.prototype.getCurrentOffset = function() {
return this.writableData.join("").length;
}
ScriptParser.prototype.parseToken = function(token, parentType = "", options = {}) {
if (typeof token == "string") {
if (this.captureTypes.includes(parentType)) {
var result = this.trigger("beforeRegisterString", arguments);
if (common.isHalt(result)) return this;
if (!common.isThru(result)) this.registerString(token, [this.currentOffset], {start:this.currentOffset, end:this.currentOffset+token.length});
result = this.trigger("afterRegisterString", arguments);
if (!common.isThru(result)) this.currentOffset += token.length;
} else {
this.register(token);
this.currentOffset += token.length;
}
return this;
}
if (Array.isArray(token.content)) {
for (var i=0; i < token.content.length; i++) {
this.parseToken(token.content[i], token.type, {
index:i,
siblingNumber:token.content.length,
members:token.content,
parent:token
});
}
} else {
this.parseToken(token.content, token.type, {siblingNumber:0, parent:token, members:[]});
}
return this;
}
ScriptParser.prototype.parse = function(data, language) {
data = data || this.script;
language = language || this.language;
this.currentOffset = 0;
if (Boolean(Prism.languages[language]) == false) return console.warn("Unknown language:", language);
this.tokens = Prism.tokenize(data, Prism.languages[language])
for (var i=0; i<this.tokens.length; i++) {
this.parseToken(this.tokens[i]);
}
return this;
}
module.exports = ScriptParser;