Can now read and write most PO files. Added simple test.

This commit is contained in:
Mike Holly 2011-12-22 16:12:01 -08:00
parent 5ea3f06a8c
commit 79b8009b2a
4 changed files with 132 additions and 14 deletions

View File

@ -1,12 +1,65 @@
var fs = require('fs'); var fs = require('fs')
, util = require('util');
var PO = function() { var PO = function() {
this.headers = {}; this.headers = {};
this.items = []; this.items = [];
}; };
PO.prototype.write = function(filename) { PO.prototype.save = function(filename, callback) {
var lines = ['msgid ""', 'msgstr ""']
, that = this;
var keys = Object.keys(this.headers);
keys.forEach(function(key){
lines.push(util.format('"%s: %s\\n"', key, that.headers[key]));
});
lines.push('');
var _processEach = function(keyword, text, i) {
var lines = []
, parts = text.split(/\n/)
, index = typeof i != 'undefined' ? util.format('[%d]', i) : '';
if (parts.length > 1) {
lines.push(util.format('%s%s ""', keyword, index));
parts.forEach(function(part){
lines.push(util.format('"%s"', part))
});
}
else {
lines.push(util.format('%s%s "%s"', keyword, index, text));
}
return lines;
}
this.items.forEach(function(item){
if (item.references.length > 0) {
item.references.forEach(function(ref){
lines.push(util.format('#: %s', ref));
});
['msgid', 'msgid_plural', 'msgstr'].forEach(function(keyword){
var text = item[keyword];
if (text != null) {
if (util.isArray(text) && text.length > 1) {
text.forEach(function(t, i){
lines = lines.concat(_processEach(keyword, t, i));
});
}
else {
text = util.isArray(text) ? text.join() : text;
lines = lines.concat(_processEach(keyword, text));
}
}
});
};
lines.push('');
});
fs.writeFile(filename, lines.join("\n"), function(err){
if (err) throw err;
callback && callback();
})
}; };
PO.load = function(filename, callback) { PO.load = function(filename, callback) {
@ -18,17 +71,21 @@ PO.load = function(filename, callback) {
headers.forEach(function(header){ headers.forEach(function(header){
if (header.match(/^"/)) { if (header.match(/^"/)) {
var p = header.split(/:/, 2); header = header.trim().replace(/^"/, '').replace(/\\n"$/, '');
po.headers[p[0].trim()] = p[1].trim(); var p = header.split(/:/)
, name = p.shift().trim()
, value = p.join(':').trim().replace(/n$/);
po.headers[name] = value;
} }
}); });
parts.forEach(function(part){ parts.forEach(function(part){
if (part.length < 1) return;
var item = PO.Item.parse(part); var item = PO.Item.parse(part);
po.items.push(item); po.items.push(item);
}); });
callback(po); callback && callback(po);
}); });
}; };
@ -44,7 +101,7 @@ PO.Item.parse = function(chunk) {
var item = new PO.Item(); var item = new PO.Item();
var parts = chunk.split(/\nmsg/); var parts = chunk.split(/\nmsg/);
var extract = function(string) { var _extract = function(string) {
var lines = string.split(/\n/); var lines = string.split(/\n/);
var value = ''; var value = '';
lines.forEach(function(line){ lines.forEach(function(line){
@ -59,19 +116,17 @@ PO.Item.parse = function(chunk) {
item.references.push(part.replace(/^#:\s/, '')); item.references.push(part.replace(/^#:\s/, ''));
} }
else if (part.match(/^id\s/)) { else if (part.match(/^id\s/)) {
item.msgid = extract(part); item.msgid = _extract(part);
} }
else if (part.match(/id_plural/)) { else if (part.match(/id_plural/)) {
item.msgid_plural = extract(part); item.msgid_plural = _extract(part);
} }
else if (part.match(/str/)) { else if (part.match(/str/)) {
item.msgstr.push(extract(part)); item.msgstr.push(_extract(part));
} }
}); });
return item; return item;
}; };
PO.load('extras.po', function(po){ module.exports = PO;
//console.log(po);
});

View File

@ -47,4 +47,3 @@ msgid "@count entry"
msgid_plural "@count entries" msgid_plural "@count entries"
msgstr[0] "@count entrada" msgstr[0] "@count entrada"
msgstr[1] "@count entradas" msgstr[1] "@count entradas"

15
tests/run.js Normal file
View File

@ -0,0 +1,15 @@
var po = require('../lib/po.js')
, fs = require('fs')
, assert = require('assert')
, exec = require('child_process').exec;
po.load('text.po', function(_po){
_po.save('copy.po', function(){
var orig = fs.readFileSync('text.po');
var data = fs.readFileSync('copy.po');
console.log(data == orig);
assert.equal(orig, data, 'Saved data is identical to original.');
});
});

49
tests/text.po Normal file
View File

@ -0,0 +1,49 @@
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2011-08-12 09:55-0700\n"
"PO-Revision-Date: 2011-12-21 22:30-0800\n"
"Last-Translator: Mike Holly <mikejholly@gmail.com>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n>1;\n"
#: strutta/strutta.admin.inc:11
msgid "CSV file"
msgstr "Archivo CVS"
#: strutta/strutta.admin.inc:12
msgid "Please make sure the file is formatted correctly (Name, E-mail)"
msgstr "Por favor asegúrese de que el archivo tenga el fomato correcto (Nombre, E-mail)"
#: strutta/strutta.admin.inc:18
msgid "From address"
msgstr "Dirección"
#: strutta/strutta.admin.inc:25
msgid "Plain text"
msgstr "Texto plano"
#: strutta/strutta.admin.inc:26
msgid "HTML markup"
msgstr "Formato HTML"
#: strutta/strutta.admin.inc:28
msgid "Content type"
msgstr "Tipo de contenido"
#: strutta_contests_client/strutta_contests_client.module:1381
msgid ""
"There is a limit of <strong>1 vote</strong> per entry over <strong>!period</strong>. \n"
" <br>Please come back and vote again in <strong>!retry</strong>."
msgstr ""
"Hay un límite de <strong>1 voto</strong> por entrada <strong>!period</strong>. \n"
" <br>Por favor vuelve más tarde para votar<strong>!retry</strong>.\""
#: strutta_submit/strutta_submit.module:113
msgid "@count entry"
msgid_plural "@count entries"
msgstr[0] "@count entrada"
msgstr[1] "@count entradas"