MSIBuild/PO.js
Simon Rozman 346a627292 Update Copyright year
Signed-off-by: Simon Rozman <simon@rozman.si>
2022-01-07 11:19:14 +01:00

269 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 1991-2022 Amebis
Copyright © 2016 GÉANT
*/
/*@cc_on @*/
/*@if (! @_escapePO_JS__) @*/
/*@set @_escapePO_JS__ = true @*/
var escapePO_stat = null;
function escapePO(str)
{
if (!escapePO_stat) {
escapePO_stat = {
"re_bslash": new RegExp("\\\\", "g"),
"re_bs": new RegExp("\b", "g"),
"re_ff": new RegExp("\f", "g"),
"re_lf": new RegExp("\n", "g"),
"re_cr": new RegExp("\r", "g"),
"re_tab": new RegExp("\t", "g"),
"re_quot": new RegExp("\"", "g")
};
}
if (str == null) return null;
switch (typeof(str)) {
case "string": break;
case "undefined": return null;
default: try { str = str.toString(); } catch (err) { return null; }
}
return str.replace(escapePO_stat.re_bslash, "\\\\").replace(escapePO_stat.re_bs, "\\b").replace(escapePO_stat.re_ff, "\\f").replace(escapePO_stat.re_lf, "\\n").replace(escapePO_stat.re_cr, "\\r").replace(escapePO_stat.re_tab, "\\t").replace(escapePO_stat.re_quot, "\\\"");
}
var unescapePO_stat = null;
function unescapePO(str)
{
if (!unescapePO_stat) {
unescapePO_stat = {
"re_esc": new RegExp("\\\\(.)", "g"),
"fn_esc": function($0, $1) {
switch ($1) {
case "\\": return "\\";
case "b" : return "\b";
case "f" : return "\f";
case "n" : return "\n";
case "r" : return "\r";
case "t" : return "\t";
case "\'": return "\'";
case "\"": return "\"";
default : return $0;
}
}
};
}
if (str == null) return null;
switch (typeof(str)) {
case "string": break;
case "undefined": return null;
default: try { str = str.toString(); } catch (err) { return null; }
}
return str.replace(unescapePO_stat.re_esc, unescapePO_stat.fn_esc);
}
function POCatalog()
{
this.charset = "utf-8";
this.data = new Array();
if (arguments.length) {
var
path = arguments[0];
// Open file.
var dat = new ActiveXObject("ADODB.Stream");
dat.Open();
try {
// PO catalogue is text file, uses Unix line breaks and UTF-8.
dat.Type = adTypeText;
dat.LineSeparator = adLF;
dat.Charset = this.charset;
// Load file.
dat.LoadFromFile(path);
// Prepare regular expressions for catalogue parsing.
var regexp = {
"fuzzy": new RegExp("^\\s*#,\\s*fuzzy", "i"),
"comment": new RegExp("^\\s*#", ""),
"record": new RegExp("^\\s*(\\w*)\\s*\"(.*)\"\\s*$", "")
};
var getNext = function() {
var
id = null,
rec = new Array();
while (!dat.EOS) {
var
s = Trim(dat.ReadText(adReadLine)),
m;
// The line is empty => end of record.
if (s == "" && "msgid" in rec)
break;
// The record is marked as "fuzzy".
if (s.search(regexp.fuzzy) != -1) {
rec["fuzzy"] = true;
continue;
}
// Concatenate comments.
if (s.search(regexp.comment) != -1) {
if ("#" in rec)
rec["#"] += s + "\n";
else
rec["#"] = s + "\n";
continue;
}
m = s.match(regexp.record);
if (m) {
// Record found.
if (m[1] != "")
id = new String(m[1]);
if (id in rec)
rec[id] += new String(m[2]);
else
rec[id] = new String(m[2]);
continue;
}
}
// Unescape messages now that they are concatenated.
for (id in rec)
rec[id] = unescapePO(rec[id]);
return "msgid" in rec ? rec : null;
}
// Read header record.
var rec = getNext();
if (rec == null)
return;
if (rec.msgid == "") {
// Parse charset.
m = rec.msgstr.match(new RegExp("^\\s*Content-Type\\s*:\\s*([-\\w]+/[-\\w]+)\\s*(;\\s*charset\\s*=\\s*([-\\w]+))?$", "im"));
if (m && m.length >= 4) {
this.charset = m[3];
// Rewind and reconfigure code page.
dat.Position = 0;
dat.Charset = this.charset;
// Re-read header.
rec = getNext();
}
}
// Load header and all the records.
this.push(rec.msgid, rec.msgstr, rec.fuzzy, "#" in rec ? rec["#"] : null);
while ((rec = getNext()) != null)
this.push(rec.msgid, rec.msgstr, rec.fuzzy, "#" in rec ? rec["#"] : null);
} finally {
dat.Close();
}
}
}
POCatalog.prototype.push = function(key, trans, fuzzy, comment)
{
var rec = {
"msgstr" : trans,
"fuzzy" : fuzzy ? true : false
};
if (comment)
rec["#"] = comment;
this.data[key] = rec;
}
POCatalog.prototype.search = function(key)
{
return (key in this.data) ? this.data[key] : null;
}
POCatalog.prototype.translate = function(key)
{
if (!(key in this.data)) {
// No translation found.
return key;
}
var rec = this.data[key];
if (rec.msgstr == "" || rec.fuzzy) {
// Translation is blank (untranslated) or fuzzy.
return key;
}
return rec.msgstr;
}
POCatalog.prototype.save = function(path)
{
// Open PO file in memory.
var dat = new ActiveXObject("ADODB.Stream");
dat.Open();
try {
// PO is text file, uses Unix line breaks and given encoding.
dat.Type = adTypeText;
dat.LineSeparator = adLF;
dat.Charset = this.charset;
var writeRec = function(key, rec) {
if (rec.fuzzy)
dat.WriteText("#, fuzzy", adWriteLine);
if ("#" in rec)
dat.WriteText(rec["#"], adWriteLine);
dat.WriteText("msgid \"" + escapePO(key ) + "\"", adWriteLine);
dat.WriteText("msgstr \"" + escapePO(rec.msgstr) + "\"", adWriteLine);
dat.WriteText("", adWriteLine);
}
// Write header first.
if ("" in this.data)
writeRec("", this.data[""]);
// Write records, skip header.
for (var key in this.data) {
if (key == "") continue;
writeRec(key, this.data[key]);
}
if (this.charset.toLowerCase() == "utf-8") {
// Write to file without UTF-8 BOM.
var dat_nobom = new ActiveXObject("ADODB.Stream");
dat_nobom.Type = adTypeBinary;
dat_nobom.Mode = adModeReadWrite;
dat_nobom.Open();
try {
// Skip BOM (first three bytes) and copy the rest.
dat.Position = 3;
dat.CopyTo(dat_nobom);
dat_nobom.SaveToFile(path, adSaveCreateOverWrite);
} finally {
dat_nobom.Close();
}
} else {
dat.SaveToFile(path, adSaveCreateOverWrite);
}
} finally {
dat.Close();
}
}
/*@end @*/