blob: 8611b48ca165e0295f063c8d434b80daefd91644 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
module.exports = Catalog;
var formatError = require('./format');
function Catalog() {
this.formats = {};
}
function baseLang(lang) {
return lang.split('-')[0];
}
/**
* lookups the language/msgId pair in the catalog.
*
* @private
* @param {string} lang the language code
* @param {string} msgId the id of the error
* @returns {string|null} the format string for the lang/msgId pair or null.
*/
Catalog.prototype._lookup = function(lang, msgId) {
var langMap = this.formats[lang];
if (!langMap) {
return null;
}
return langMap[msgId];
};
/**
* lookups the language/msgId pair in the catalog. If there is no match
* on the full language the string the base language (i.e 'en' for 'en-US') is
* looked up instead.
*
* @private
* @param {string} lang the language code
* @param {string} msgId the id of the error
* @returns {string} the format string for the lang/msgId pair.
*/
Catalog.prototype.lookup = function(lang, msgId) {
var defaultFormat = msgId + '{:_}';
return this._lookup(lang, msgId) ||
this._lookup(baseLang(lang), msgId) ||
defaultFormat;
};
Catalog.prototype.format = function(lang, msgId, args) {
return formatError(this.lookup(lang, msgId), args);
};
/**
* sets the format for the lang/msgId pair
* @private
* @param {string} lang the language code
* @param {string} msgId the id of the error
* @param {string} format the format of the message
*/
Catalog.prototype.set = function(lang, msgId, format) {
var langs = this.formats[lang];
if (!langs) {
this.formats[lang] = {};
langs = this.formats[lang];
}
langs[msgId] = format;
};
/**
* sets the format for the lang/msgId pair. Also sets the format for
* the base of the language if no format exists for it.
* @private
* @param {string} lang the language code
* @param {string} msgId the id of the error
* @param {string} format the format of the message
*/
Catalog.prototype.setWithBase = function (lang, msgId, format) {
this.set(lang, msgId, format);
var base = baseLang(lang);
if (!this._lookup(base, msgId, format)) {
this.set(base, msgId, format);
}
};
var escapedStringRe = /"([^"\\]|\\.)*"/;
/**
* Merges the catalog data passed in.
* Each valid line will have three parts. It will be:
* <langId> <msgId> "<format>"
* format will be enclosed in quotes and escaped properly.
* If the line begins with '#' or is malformed, it is ignored.
* @private
* @param {string} data the language code
*/
Catalog.prototype.merge = function(data) {
var catalog = this;
data.split('\n').forEach(function(line) {
var parts = line.split(/\s+/);
if (parts.length < 3) {
return;
}
var langId = parts[0];
if (langId[0] === '#') {
return;
}
var msgId = parts[1];
// The message is quoted, so we need to unquote it.
var message = parts.splice(2).join(' ');
var match = escapedStringRe.exec(message);
if (!match) {
return;
}
try {
message = JSON.parse(match[0]);
} catch (e) {
return;
}
catalog.setWithBase(langId, msgId, message);
});
};