Can now read and write most PO files. Added simple test.
This commit is contained in:
		
							
								
								
									
										79
									
								
								lib/po.js
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								lib/po.js
									
									
									
									
									
								
							| @@ -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); |  | ||||||
| }); |  | ||||||
| @@ -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
									
								
							
							
						
						
									
										15
									
								
								tests/run.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										49
									
								
								tests/text.po
									
									
									
									
									
										Normal 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" | ||||||
		Reference in New Issue
	
	Block a user