v2.5.0 optimize l10n packs (bug 1144425)

This commit is contained in:
Kevin Ngo 2015-07-07 18:02:56 -07:00
Родитель 5ccb4abac3
Коммит 73eb4db043
4 изменённых файлов: 210 добавлений и 54 удалений

Просмотреть файл

@ -1,7 +1,21 @@
/*
Parses .po file, outputting a JS langpack.
Will output {'My String': 'El String'} for simple non-plural localizations.
Will output {'Result': ['El Resulto', 'Los Resultos']} for plural
localizations, where the first index is the singular localized string
and the second index is the plural localized string.
Will not output strings that don't contain a localization. The l10n
library should simply output the ID in that case.
Will not output strings where the localization is equivalent to the ID.
*/
var fs = require('fs');
var util = require('util');
var _ = require('lodash');
function sw(x, y) {return x.substr(0, y.length) === y;}
var S_ID = 'msgid ';
var S_STR = 'msgstr ';
var S_PLURAL = 'msgid_plural ';
@ -9,6 +23,15 @@ var S_PLURAL_STR = 'msgstr[';
var RE_PLURAL = /^msgstr\[([0-9]+)\] (\".*\")/;
var RE_PLURALIZER = /^Plural\-Forms: nplurals=[0-9]+; plural=(.+?);/;
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
};
}
function parse(po_content) {
var output = {};
var pluralizer = '0';
@ -16,18 +39,38 @@ function parse(po_content) {
var state = null;
var id = null;
var pluralId = null;
var last = null;
var last_plural = null;
var current_obj = {body: ''};
var currentLocalizedResult = '';
function store_current() {
if (id) {
// Don't save a copy of the headers in the langpack.
output[id] = current_obj;
var hasResult = !!currentLocalizedResult;
var hasResultPlural = currentLocalizedResult.constructor === String ||
_.filter(currentLocalizedResult).length > 0;
// Don't set strings that are identical to their keys.
var notIdentical = id !== currentLocalizedResult;
var notIdenticalPlural = currentLocalizedResult.constructor === String ||
currentLocalizedResult.length > 2 ||
currentLocalizedResult[0] !== id &&
currentLocalizedResult[1] !== pluralId;
if (currentLocalizedResult.constructor === Array &&
currentLocalizedResult.length === 1) {
currentLocalizedResult = currentLocalizedResult[0];
}
if (hasResult && hasResultPlural && notIdentical &&
notIdenticalPlural) {
// Set the string in our langpack if all conditions pass.
output[id] = currentLocalizedResult;
}
} else {
// If there's no IDs, it's probably the headers. If there's a
// pluralizer up there, use it.
var parsed_headers = current_obj.body.split('\n');
var parsed_headers = currentLocalizedResult.split('\n');
parsed_headers.forEach(function(v) {
var plex_match = RE_PLURALIZER.exec(v);
if (!plex_match) return;
@ -35,7 +78,7 @@ function parse(po_content) {
});
}
id = '';
current_obj = {body: ''};
currentLocalizedResult = null;
}
function got_id(new_id) {
@ -53,7 +96,7 @@ function parse(po_content) {
continue;
}
if (sw(line, S_ID)) {
if (line.startsWith(S_ID)) {
// console.log('...Storing existing id: ', id);
store_current();
@ -62,44 +105,40 @@ function parse(po_content) {
last = 'id';
continue;
}
if (sw(line, S_PLURAL_STR)) {
if (line.startsWith(S_PLURAL_STR)) {
// pl_match[0] is the index (0 for singular, 1 for plural).
// pl_match[2] is the matched string.
var pl_match = RE_PLURAL.exec(line);
if (!('plurals' in current_obj)) {
current_obj.plurals = [];
}
current_obj.plurals[pl_match[1]] = JSON.parse(pl_match[2]);
currentLocalizedResult = currentLocalizedResult || [];
currentLocalizedResult.push(JSON.parse(pl_match[2]));
last = 'plurals';
last_plural = pl_match[1];
continue;
}
if (sw(line, S_STR)) {
if (line.startsWith(S_STR)) {
last = 'body';
var body = JSON.parse(line.substr(S_STR.length));
// console.log(' > Storing body: ', body);
current_obj.body += body;
currentLocalizedResult = body;
continue;
}
if (sw(line, S_PLURAL)) {
if (line.startsWith(S_PLURAL)) {
last = 'plural';
var plural = JSON.parse(line.substr(S_PLURAL.length));
// console.log(' > Plural form: ', plural);
if (!('plural' in current_obj)) {
current_obj.plural = '';
}
current_obj.plural += plural;
pluralId = JSON.parse(line.substr(S_PLURAL.length));
currentLocalizedResult = currentLocalizedResult || [];
continue;
}
var line_val = JSON.parse(line);
if (last === 'plurals') {
// console.log(' >> Appending plural: ', line_val);
current_obj.plurals[last_plural] += line_val;
currentLocalizedResult.plurals.push(line_val);
} else if (last === 'id') {
// console.log(' >> Last was ID');
got_id(line_val);
} else {
// console.log(' >> (' + last + ':' + id + ') Appending : ', line_val);
current_obj[last] += line_val;
currentLocalizedResult += line_val;
}
}
@ -141,7 +180,7 @@ function process_file(path, lang, dest_path, callback) {
console.error('Unable to write language pack to: ' + dest_path, err);
}
if (callback) {
callback(err, compiled);
callback(err);
}
});
} else {

Просмотреть файл

@ -1,7 +1,7 @@
{
"name": "commonplace",
"description": "Reusable components for Firefox Marketplace frontend projects.",
"version": "2.4.0",
"version": "2.5.0",
"main": "lib/commonplace",
"preferGlobal": true,
"scripts": {
@ -17,6 +17,7 @@
},
"dependencies": {
"jshint": "2.3.x",
"lodash": "^3.10.0",
"nunjucks": "1.0.x"
},
"bin": {

Просмотреть файл

@ -4,7 +4,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-07-01T15:34:32.357Z\n"
"PO-Revision-Date: 2015-07-06 18:28+0000\n"
"Last-Translator: Tostitos <nobodoy@mozilla-hispano.org>\n"
"Last-Translator: Tostitos <nobody@mozilla.org>\n"
"Language-Team: Español (España) <nacho@cheese.com>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
@ -14,16 +14,59 @@ msgstr ""
"X-Generator: Pootle 2.5.0\n"
"X-POOTLE-MTIME: 1436207284.0\n"
#: /templates/search.html:7
msgid "plural"
msgid_plural "plurals"
msgstr[0] "onePlural"
msgstr[1] "twoPlurals"
#: /media/js/views/basic.js:46
msgid "My String"
msgstr "El String"
#: /media/js/views/settings.js:46
msgid "string"
msgstr "translatedString"
#: /templates/plural.html:7
msgid "Result"
msgid_plural "N Results"
msgstr[0] "Resulto"
msgstr[1] "N Resultos"
#: /media/js/views/app/abuse.js:18 /media/js/views/website/issue.js:17
msgid "noTranslations"
#: /templates/triple.html:7
msgid "Triple Result"
msgid_plural "Triple Results"
msgstr[0] "Un Resulto"
msgstr[1] "Dos Resultos"
msgstr[2] "Resultos"
#: /templates/partial.html:7
msgid "Partially Localized Plural String"
msgid_plural "Partially Localized Plural Strings"
msgstr[0] "PLPS"
msgstr[1] ""
msgstr[2] "PLPSes"
#: /templates/no_plural.html:7
msgid "No Plural Form String"
msgid_plural "No Plural Form Strings"
msgstr[0] "NPFS"
#: /media/js/non_localized:18 /media/js/lol.js:17
msgid "My Non-Localized String"
msgstr ""
#: /templates/non_localized_plural.html:7
msgid "Non-Localized Result"
msgid_plural "Non-Localized Results"
msgstr[0] ""
msgstr[1] ""
#: /templates/identical.html:7
msgid "Identical String"
msgstr "Identical String"
#: /templates/identical_plural.html:7
msgid "Identical Plural String"
msgid_plural "Identical Plural Strings"
msgstr[0] "Identical Plural String"
msgstr[1] "Identical Plural Strings"
#: /templates/partially_identical_plural.html:7
msgid "Partially Identical Plural String"
msgid_plural "Partially Identical Plural Strings"
msgstr[0] "Partially Identical Plural String"
msgstr[1] "Partially Identical Plural Strings"
msgstr[2] "Something Else"
msgstr[3] "Something Else"

Просмотреть файл

@ -4,44 +4,117 @@ var langpacks = require('../lib/generate_langpacks').process_file;
beforeEach(function() {
global.navigator = {l10n: undefined};
global.navigator = {l10n: undefined};
});
describe('generate_langpacks', function() {
it('sets navigator.l10n.language', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.equal(navigator.l10n.language, 'es');
done();
eval(data);
assert.equal(navigator.l10n.language, 'es');
done();
});
});
it('sets localized string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.equal(navigator.l10n.strings['string'].body,
'translatedString');
done();
eval(data);
assert.equal(navigator.l10n.strings['My String'],
'El String');
done();
});
});
it('sets plural string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.equal(navigator.l10n.strings['plural'].body, '');
assert.equal(navigator.l10n.strings['plural'].plural, 'plurals');
assert.deepEqual(navigator.l10n.strings['plural'].plurals,
['onePlural', 'twoPlurals']);
done();
eval(data);
assert.deepEqual(navigator.l10n.strings['Result'],
['Resulto', 'N Resultos']);
done();
});
});
it('sets non-localized string', function(done) {
it('sets plural string with three forms', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.equal(navigator.l10n.strings['noTranslations'].body, '');
done();
eval(data);
assert.deepEqual(navigator.l10n.strings['Triple Result'],
['Un Resulto', 'Dos Resultos', 'Resultos']);
done();
});
});
it('sets partially localized plural string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.deepEqual(
navigator.l10n.strings['Partially Localized Plural String'],
['PLPS', '', 'PLPSes']);
done();
});
});
it('sets partially identical plural strings', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.ok('Partially Identical Plural String' in navigator.l10n.strings);
assert.deepEqual(
navigator.l10n.strings['Partially Identical Plural String'],
['Partially Identical Plural String',
'Partially Identical Plural Strings',
'Something Else', 'Something Else']);
done();
});
});
it('sets no plural form string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.deepEqual(
navigator.l10n.strings['No Plural Form String'], 'NPFS');
done();
});
});
it('does not set non-localized string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.ok(!('My Non-Localized String' in navigator.l10n.strings));
done();
});
});
it('does not set non-localized plural string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.ok(!('Non-Localized Result' in navigator.l10n.strings));
done();
});
});
it('does not set identical string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.ok(!('Identical String' in navigator.l10n.strings));
done();
});
});
it('does not set identical plural string', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
eval(data);
assert.ok(!('Identical Plural String' in navigator.l10n.strings));
done();
});
});
it('sets pluralizer', function(done) {
langpacks('test/messages.po', 'es', null, function(err, data) {
assert.ok(!navigator.l10n);
eval(data);
assert.equal(navigator.l10n.pluralize.toString(),
'function (n) {\n return (n != 1);\n}');
done();
});
});
});