Parser
class
new Parser() extends Filter
This class parsees the input and returns
the i18n string depending on the parser specified
class Parser extends Filter {
constructor(input, core) {
super(input);
log
.debug(`class: ${Parser.name}`, `process: constructor`)
.debug('filtered input:', (this.input = super.filter()));
// Set locale
this.locale = core.header.getLocale();
// Set options
this.options = core.options;
var result = new Type(this.input, core);
switch (result.parse().type) {
case 'phrase':
this.input.phrase = this.preparse(result.getPhrase());
log
.debug('type', 'phrase')
.debug('phrase :', this.input.phrase);
break;
case 'bracket':
this.input.phrase = this.preparse(result.getBracket());
log
.debug('type', 'bracket')
.debug('phrase :', this.input.phrase);
break;
case 'dot':
this.input.phrase = this.preparse(result.getDot());
log
.debug('type', 'dot')
.debug('phrase :', this.input.phrase);
break;
}
}
parse
method
Parser.prototype.parse()
Starts the engine and parses the input
parse() {
log
.debug(`class: ${Parser.name}`, `process: parse`)
.info('parsing phrase:', this.input.phrase);
if (_.isUndefined(this.input.phrase)) return '';
else {
var _format, _default;
try {
// Parse both at once
_format = this.formatParser();
_default = this.defaultParser();
} catch (error) {
log.error(error.stack || String(error));
}
log.info('selected parser: ',
this.input.keywords.parser || this.options.parser.type);
// Determine if the user specified a parser
switch (this.input.keywords.parser || this.options.parser.type) {
case 'default':
log.info('parse result - default:', _default);
// Render default
return _default || '';
case 'format':
log.info('parse result - format:', _format);
// Render format
return _format || '';
case '*':
if (!S(_format).isEmpty() && !S(_default).isEmpty()) {
var result = '';
// If interpolation failed for default
if (/\{[\s\S]*\}/g.test(_default)) {
result = _format;
}
// If interpolation failed for format
if (/\{[\s\S]*\}/g.test(_format)) {
result = _default;
}
// If all fails then we tried so
// return the default since it could
// possibly be that _default and _format
// are the same.
if (S(result).isEmpty()) result = _default;
log.info('parse result:', result);
return result;
}
// If formatted string was empty, then it could be
// in the default string else just return an empty
// string.
else if (!S(_format).isEmpty() && !_default) {
log.info('parse result - format:', _format);
return _format;
} else if (!S(_default).isEmpty() && !_format) {
log.info('parse result - default:', _default);
return _default;
} else return '';
break;
}
}
}
defaultParser
method
Parser.prototype.defaultParser()
The default parser
defaultParser(str) {
log.debug(`class: ${Parser.name}`, `process: defaultParser`);
var phrase = str || this.input.phrase;
var {
markdown, template, sprintf
} = this.options.parser;
try {
// Check if markdown is enabled
if (markdown.enabled) phrase = this.markdown(phrase);
// Apply interpolation
if (!_.isEmpty(this.input.template) && template.enabled)
phrase = this.template(phrase);
// Apply vsprintf
if (!_.isEmpty(this.input.arguments) && sprintf.enabled)
phrase = this.vsprintf(phrase);
} catch (error) {
log.error(error.stack || String(error));
}
log.debug('result:', phrase);
return phrase;
}
formatParser
method
Parser.prototype.formatParser()
The message formatting parser
formatParser(str) {
log.debug(`class: ${Parser.name}`, `process: formatParser`);
var phrase = str || this.input.phrase,
result;
var {
markdown
} = this.options.parser;
try {
// Check if markdown is enabled
if (markdown.enabled) phrase = this.markdown(phrase);
// Try to apply message format
result = this.messageFormat(phrase).format(this.input.template);
} catch (error) {
log.error(error.stack || String(error));
}
phrase = result;
log.debug('result:', phrase);
return phrase;
}
preparse
method
Parser.prototype.preparse()
Option name | Type | Description |
---|---|---|
Object | ||
return | String |
Finds the translated phrase in the dictionary
preparse(object) {
var {
parser, header
} = this.options;
var key = (
this.locale.toLowerCase() ===
header.default.toLowerCase() ?
parser.keywords.default : parser.keywords.translated);
if (!object) return '';
// If the object is already a string then return
if (_.isString(object)) return object;
// If it's an object
if (_.isPlainObject(object)) {
// Check if already contains the key 'default' or 'translated'
if (_.has(object, key)) {
return _.has(object, key) ? object[key] : object;
}
}
}
messageFormat
method
Parser.prototype.messageFormat()
Messageformat
messageFormat(str) {
str = this.preparse(str);
return !S(str).isEmpty() || !str ?
new MessageFormat(str, this.locale) : '';
}
markdown
method
Parser.prototype.markdown()
Markdown
markdown(str) {
return new Markdown(_.omit(this.options.markdown,
'enabled')).renderInline(str);
}
vsprintf
method
Parser.prototype.vsprintf()
Sprintf
vsprintf(str) {
return vsprintf(str, this.input.arguments);
}
template
method
Parser.prototype.template()
Interpolation
template(str) {
var phrase = str;
var {
parser
} = this.options;
// Get the opening and closing template
// from options
var open = parser.template.open,
close = parser.template.close;
if (S(phrase).include(open) && S(phrase).include(close)) {
var opening = open;
var closing = close;
open = opening.replace(/[-[\]()*\s]/g, '\\$&').replace(/\$/g, '\\$');
close = closing.replace(/[-[\]()*\s]/g, '\\$&').replace(/\$/g, '\\$');
var r = new RegExp(open + '(.+?)' + close, 'g');
// Process the interpolation
var matches = phrase.match(r) || [];
_.forEach(matches, match => {
var keys = match.substring(opening.length,
// Chop {{ and }}
match.length - closing.length).trim().split('.');
var value = Find.findR(this.input.template, keys);
phrase = phrase.replace(match, value);
});
}
return phrase;
}
}
export default Parser;