Bring up to date with cockpit starter kit
This encompasses a number of changes to the build process.
This commit is contained in:
parent
a0fffde59d
commit
235f110ec7
32 changed files with 533 additions and 1172 deletions
15
po/de.po
15
po/de.po
|
|
@ -4,27 +4,20 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: starter-kit 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-08-29 00:14+0200\n"
|
||||
"POT-Creation-Date: 2022-03-09 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"Language: de\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"
|
||||
|
||||
#: src/index.html:20
|
||||
msgid "Cockpit Starter Kit"
|
||||
msgstr "Cockpit Bausatz"
|
||||
|
||||
#: src/app.jsx:42
|
||||
#: src/app.jsx:43
|
||||
msgid "Running on $0"
|
||||
msgstr "Läuft auf $0"
|
||||
|
||||
#: src/manifest.json
|
||||
msgid "Starter Kit"
|
||||
msgstr "Bausatz"
|
||||
|
||||
#: src/app.jsx:29
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
|
|
|||
264
po/html2po
264
po/html2po
|
|
@ -1,264 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
* Extracts translatable strings from HTML files in the following forms:
|
||||
*
|
||||
* <tag translate>String</tag>
|
||||
* <tag translate context="value">String</tag>
|
||||
* <tag translate="...">String</tag>
|
||||
* <tag translate-attr attr="String"></tag>
|
||||
*
|
||||
* Supports the following Glade compatible forms:
|
||||
*
|
||||
* <tag translatable="yes">String</tag>
|
||||
* <tag translatable="yes" context="value">String</tag>
|
||||
*
|
||||
* Supports the following angular-gettext compatible forms:
|
||||
*
|
||||
* <translate>String</translate>
|
||||
* <tag translate-plural="Plural">Singular</tag>
|
||||
*
|
||||
* Note that some of the use of the translated may not support all the strings
|
||||
* depending on the code actually using these strings to translate the HTML.
|
||||
*/
|
||||
|
||||
|
||||
function fatal(message, code) {
|
||||
console.log((filename || "html2po") + ": " + message);
|
||||
process.exit(code || 1);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
console.log("usage: html2po input output");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var fs, htmlparser, path, stdio;
|
||||
|
||||
try {
|
||||
fs = require('fs');
|
||||
path = require('path');
|
||||
htmlparser = require('htmlparser');
|
||||
stdio = require('stdio');
|
||||
} catch (ex) {
|
||||
fatal(ex.message, 127); /* missing looks for this */
|
||||
}
|
||||
|
||||
var opts = stdio.getopt({
|
||||
directory: { key: "d", args: 1, description: "Base directory for input files" },
|
||||
output: { key: "o", args: 1, description: "Output file" },
|
||||
from: { key: "f", args: 1, description: "File containing list of input files" },
|
||||
});
|
||||
|
||||
if (!opts.from && opts.args.length < 1) {
|
||||
usage();
|
||||
}
|
||||
|
||||
var input = opts.args;
|
||||
var entries = { };
|
||||
|
||||
/* Filename being parsed and offset of line number */
|
||||
var filename = null;
|
||||
var offsets = 0;
|
||||
|
||||
/* The HTML parser we're using */
|
||||
var handler = new htmlparser.DefaultHandler(function(error, dom) {
|
||||
if (error)
|
||||
fatal(error);
|
||||
else
|
||||
walk(dom);
|
||||
});
|
||||
|
||||
prepare();
|
||||
|
||||
/* Decide what input files to process */
|
||||
function prepare() {
|
||||
if (opts.from) {
|
||||
fs.readFile(opts.from, { encoding: "utf-8"}, function(err, data) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
input = data.split("\n").filter(function(value) {
|
||||
return !!value;
|
||||
}).concat(input);
|
||||
step();
|
||||
});
|
||||
} else {
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
/* Now process each file in turn */
|
||||
function step() {
|
||||
filename = input.shift();
|
||||
if (filename === undefined) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Qualify the filename if necessary */
|
||||
var full = filename;
|
||||
if (opts.directory)
|
||||
full = path.join(opts.directory, filename);
|
||||
|
||||
fs.readFile(full, { encoding: "utf-8"}, function(err, data) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
|
||||
var parser = new htmlparser.Parser(handler, { includeLocation: true });
|
||||
parser.parseComplete(data);
|
||||
step();
|
||||
});
|
||||
}
|
||||
|
||||
/* Process an array of nodes */
|
||||
function walk(children) {
|
||||
if (!children)
|
||||
return;
|
||||
|
||||
children.forEach(function(child) {
|
||||
var line = (child.location || { }).line || 0;
|
||||
var offset = line - 1;
|
||||
|
||||
/* Scripts get their text processed as HTML */
|
||||
if (child.type == 'script' && child.children) {
|
||||
var parser = new htmlparser.Parser(handler, { includeLocation: true });
|
||||
|
||||
/* Make note of how far into the outer HTML file we are */
|
||||
offsets += offset;
|
||||
|
||||
child.children.forEach(function(node) {
|
||||
parser.parseChunk(node.raw);
|
||||
});
|
||||
parser.done();
|
||||
|
||||
offsets -= offset;
|
||||
|
||||
/* Tags get extracted as usual */
|
||||
} else if (child.type == 'tag') {
|
||||
tag(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Process a single loaded tag */
|
||||
function tag(node) {
|
||||
|
||||
var tasks, line, entry;
|
||||
var attrs = node.attribs || { };
|
||||
var nest = true;
|
||||
|
||||
/* Extract translate strings */
|
||||
if ("translate" in attrs || "translatable" in attrs) {
|
||||
tasks = (attrs["translate"] || attrs["translatable"] || "yes").split(" ");
|
||||
|
||||
/* Calculate the line location taking into account nested parsing */
|
||||
line = (node.location || { })["line"] || 0;
|
||||
line += offsets;
|
||||
|
||||
entry = {
|
||||
msgctxt: attrs['translate-context'] || attrs['context'],
|
||||
msgid_plural: attrs['translate-plural'],
|
||||
locations: [ filename + ":" + line ]
|
||||
};
|
||||
|
||||
/* For each thing listed */
|
||||
tasks.forEach(function(task) {
|
||||
var copy = Object.assign({}, entry);
|
||||
|
||||
/* The element text itself */
|
||||
if (task == "yes" || task == "translate") {
|
||||
copy.msgid = extract(node.children);
|
||||
nest = false;
|
||||
|
||||
/* An attribute */
|
||||
} else if (task) {
|
||||
copy.msgid = attrs[task];
|
||||
}
|
||||
|
||||
if (copy.msgid)
|
||||
push(copy);
|
||||
});
|
||||
}
|
||||
|
||||
/* Walk through all the children */
|
||||
if (nest)
|
||||
walk(node.children);
|
||||
}
|
||||
|
||||
/* Push an entry onto the list */
|
||||
function push(entry) {
|
||||
var key = entry.msgid + "\0" + entry.msgid_plural + "\0" + entry.msgctxt;
|
||||
var prev = entries[key];
|
||||
if (prev) {
|
||||
prev.locations = prev.locations.concat(entry.locations);
|
||||
} else {
|
||||
entries[key] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the given text */
|
||||
function extract(children) {
|
||||
if (!children)
|
||||
return null;
|
||||
|
||||
var i, len, node, str = [];
|
||||
children.forEach(function(node) {
|
||||
if (node.type == 'tag' && node.children)
|
||||
str.push(extract(node.children))
|
||||
else if (node.type == 'text' && node.data)
|
||||
str.push(node.data);
|
||||
});
|
||||
|
||||
return str.join("");
|
||||
}
|
||||
|
||||
/* Escape a string for inclusion in po file */
|
||||
function escape(string) {
|
||||
var bs = string.split('\\').join('\\\\').split('"').join('\\"');
|
||||
return bs.split("\n").map(function(line) {
|
||||
return '"' + line + '"';
|
||||
}).join("\n");
|
||||
}
|
||||
|
||||
/* Finish by writing out the strings */
|
||||
function finish() {
|
||||
var result = [
|
||||
'msgid ""',
|
||||
'msgstr ""',
|
||||
'"Project-Id-Version: PACKAGE_VERSION\\n"',
|
||||
'"MIME-Version: 1.0\\n"',
|
||||
'"Content-Type: text/plain; charset=UTF-8\\n"',
|
||||
'"Content-Transfer-Encoding: 8bit\\n"',
|
||||
'"X-Generator: Cockpit html2po\\n"',
|
||||
'',
|
||||
];
|
||||
|
||||
var msgid, entry;
|
||||
for (msgid in entries) {
|
||||
entry = entries[msgid];
|
||||
result.push('#: ' + entry.locations.join(" "));
|
||||
if (entry.msgctxt)
|
||||
result.push('msgctxt ' + escape(entry.msgctxt));
|
||||
result.push('msgid ' + escape(entry.msgid));
|
||||
if (entry.msgid_plural) {
|
||||
result.push('msgid_plural ' + escape(entry.msgid_plural));
|
||||
result.push('msgstr[0] ""');
|
||||
result.push('msgstr[1] ""');
|
||||
} else {
|
||||
result.push('msgstr ""');
|
||||
}
|
||||
result.push('');
|
||||
}
|
||||
|
||||
var data = result.join('\n');
|
||||
if (!opts.output) {
|
||||
process.stdout.write(data);
|
||||
process.exit(0);
|
||||
} else {
|
||||
fs.writeFile(opts.output, data, function(err) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
185
po/manifest2po
185
po/manifest2po
|
|
@ -1,185 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
* Extracts translatable strings from manifest.json files.
|
||||
*
|
||||
*/
|
||||
|
||||
function fatal(message, code) {
|
||||
console.log((filename || "manifest2po") + ": " + message);
|
||||
process.exit(code || 1);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
console.log("usage: manifest2po [-o output] input...");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var fs, path, stdio;
|
||||
|
||||
try {
|
||||
fs = require('fs');
|
||||
path = require('path');
|
||||
stdio = require('stdio');
|
||||
} catch (ex) {
|
||||
fatal(ex.message, 127); /* missing looks for this */
|
||||
}
|
||||
|
||||
var opts = stdio.getopt({
|
||||
directory: { key: "d", args: 1, description: "Base directory for input files" },
|
||||
output: { key: "o", args: 1, description: "Output file" },
|
||||
from: { key: "f", args: 1, description: "File containing list of input files" },
|
||||
});
|
||||
|
||||
if (!opts.from && opts.args.length < 1) {
|
||||
usage();
|
||||
}
|
||||
|
||||
var input = opts.args;
|
||||
var entries = { };
|
||||
|
||||
/* Filename being parsed */
|
||||
var filename = null;
|
||||
|
||||
prepare();
|
||||
|
||||
/* Decide what input files to process */
|
||||
function prepare() {
|
||||
if (opts.from) {
|
||||
fs.readFile(opts.from, { encoding: "utf-8"}, function(err, data) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
input = data.split("\n").filter(function(value) {
|
||||
return !!value;
|
||||
}).concat(input);
|
||||
step();
|
||||
});
|
||||
} else {
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
/* Now process each file in turn */
|
||||
function step() {
|
||||
filename = input.shift();
|
||||
if (filename === undefined) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (path.basename(filename) != "manifest.json")
|
||||
return step();
|
||||
|
||||
fs.readFile(filename, { encoding: "utf-8"}, function(err, data) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
|
||||
process_manifest(JSON.parse(data));
|
||||
|
||||
return step();
|
||||
});
|
||||
}
|
||||
|
||||
function process_manifest(manifest) {
|
||||
if (manifest.menu)
|
||||
process_menu(manifest.menu);
|
||||
if (manifest.tools)
|
||||
process_menu(manifest.tools);
|
||||
}
|
||||
|
||||
function process_keywords(keywords) {
|
||||
keywords.forEach(v => {
|
||||
v.matches.forEach(keyword =>
|
||||
push({
|
||||
msgid: keyword,
|
||||
locations: [ filename ]
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function process_docs(docs) {
|
||||
docs.forEach(doc => {
|
||||
push({
|
||||
msgid: doc.label,
|
||||
locations: [ filename ]
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function process_menu(menu) {
|
||||
for (var m in menu) {
|
||||
if (menu[m].label) {
|
||||
push({
|
||||
msgid: menu[m].label,
|
||||
locations: [ filename ]
|
||||
});
|
||||
}
|
||||
if (menu[m].keywords)
|
||||
process_keywords(menu[m].keywords);
|
||||
if (menu[m].docs)
|
||||
process_docs(menu[m].docs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Push an entry onto the list */
|
||||
function push(entry) {
|
||||
var key = entry.msgid + "\0" + entry.msgid_plural + "\0" + entry.msgctxt;
|
||||
var prev = entries[key];
|
||||
if (prev) {
|
||||
prev.locations = prev.locations.concat(entry.locations);
|
||||
} else {
|
||||
entries[key] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Escape a string for inclusion in po file */
|
||||
function escape(string) {
|
||||
var bs = string.split('\\').join('\\\\').split('"').join('\\"');
|
||||
return bs.split("\n").map(function(line) {
|
||||
return '"' + line + '"';
|
||||
}).join("\n");
|
||||
}
|
||||
|
||||
/* Finish by writing out the strings */
|
||||
function finish() {
|
||||
var result = [
|
||||
'msgid ""',
|
||||
'msgstr ""',
|
||||
'"Project-Id-Version: PACKAGE_VERSION\\n"',
|
||||
'"MIME-Version: 1.0\\n"',
|
||||
'"Content-Type: text/plain; charset=UTF-8\\n"',
|
||||
'"Content-Transfer-Encoding: 8bit\\n"',
|
||||
'"X-Generator: Cockpit manifest2po\\n"',
|
||||
'',
|
||||
];
|
||||
|
||||
var msgid, entry;
|
||||
for (msgid in entries) {
|
||||
entry = entries[msgid];
|
||||
result.push('#: ' + entry.locations.join(" "));
|
||||
if (entry.msgctxt)
|
||||
result.push('msgctxt ' + escape(entry.msgctxt));
|
||||
result.push('msgid ' + escape(entry.msgid));
|
||||
if (entry.msgid_plural) {
|
||||
result.push('msgid_plural ' + escape(entry.msgid_plural));
|
||||
result.push('msgstr[0] ""');
|
||||
result.push('msgstr[1] ""');
|
||||
} else {
|
||||
result.push('msgstr ""');
|
||||
}
|
||||
result.push('');
|
||||
}
|
||||
|
||||
var data = result.join('\n');
|
||||
if (!opts.output) {
|
||||
process.stdout.write(data);
|
||||
process.exit(0);
|
||||
} else {
|
||||
fs.writeFile(opts.output, data, function(err) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
(function (root, data) {
|
||||
var loaded, module;
|
||||
|
||||
/* Load into Cockpit locale */
|
||||
if (typeof cockpit === 'object') {
|
||||
cockpit.locale(data)
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
if (!loaded)
|
||||
root.po = data;
|
||||
|
||||
/* The syntax of this line is important by po2json */
|
||||
}(this, {"":{"language":"en"}}));
|
||||
127
po/po2json
127
po/po2json
|
|
@ -1,127 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
function fatal(message, code) {
|
||||
console.log((filename || "html2po") + ": " + message);
|
||||
process.exit(code || 1);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
console.log("usage: po2json [--module=template.js] input output");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var fs, po2json, Jed, stdio;
|
||||
|
||||
try {
|
||||
fs = require('fs');
|
||||
po2json = require('po2json');
|
||||
Jed = require('jed');
|
||||
stdio = require('stdio');
|
||||
} catch(ex) {
|
||||
fatal(ex.message, 127); /* missing looks for this */
|
||||
}
|
||||
|
||||
var argi = 2;
|
||||
var filename = null;
|
||||
|
||||
var opts = stdio.getopt({
|
||||
module: { key: "m", args: 1, description: "Module template to include" },
|
||||
output: { key: "o", args: 1, description: "Output file" },
|
||||
});
|
||||
|
||||
if (opts.args.length != 1) {
|
||||
usage();
|
||||
}
|
||||
|
||||
parse();
|
||||
|
||||
function prepareHeader(header) {
|
||||
var body, statement, plurals = header["plural-forms"], ret = null;
|
||||
if (plurals) {
|
||||
try {
|
||||
/* Check that the plural forms isn't being sneaky since we build a function here */
|
||||
Jed.PF.parse(plurals);
|
||||
} catch(ex) {
|
||||
fatal("bad plural forms: " + ex.message, 1);
|
||||
}
|
||||
|
||||
/* A function for the front end */
|
||||
statement = header["plural-forms"];
|
||||
if (statement[statement.length - 1] != ';')
|
||||
statement += ';';
|
||||
ret = 'function(n) {\nvar nplurals, plural;\n' + statement + '\nreturn plural;\n}';
|
||||
|
||||
/* Added back in later */
|
||||
delete header["plural-forms"];
|
||||
}
|
||||
|
||||
/* We don't need to be transferring this */
|
||||
delete header["project-id-version"];
|
||||
delete header["report-msgid-bugs-to"];
|
||||
delete header["pot-creation-date"];
|
||||
delete header["po-revision-date"];
|
||||
delete header["last-translator"];
|
||||
delete header["language-team"];
|
||||
delete header["mime-version"];
|
||||
delete header["content-type"];
|
||||
delete header["content-transfer-encoding"];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse and process the po data */
|
||||
function parse() {
|
||||
filename = opts.args[0];
|
||||
po2json.parseFile(opts.args[0], { "fuzzy": true }, function(err, jsonData) {
|
||||
var plurals, pos;
|
||||
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
|
||||
var header = jsonData[""];
|
||||
if (header)
|
||||
plurals = prepareHeader(header);
|
||||
|
||||
var data = JSON.stringify(jsonData, null, 1);
|
||||
|
||||
/* We know the brace in is the location to insert our function */
|
||||
if (plurals) {
|
||||
pos = data.indexOf('{', 1);
|
||||
data = data.substr(0, pos + 1) + "'plural-forms':" + String(plurals) + "," + data.substr(pos + 1);
|
||||
}
|
||||
|
||||
if (data == JSON.stringify({}))
|
||||
finish("");
|
||||
else
|
||||
wrap(data);
|
||||
});
|
||||
}
|
||||
|
||||
/* Wrap the data if desired */
|
||||
function wrap(data) {
|
||||
if (opts.module) {
|
||||
filename = opts.module;
|
||||
fs.readFile(opts.module, { encoding: "utf-8" }, function(err, template) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
data = template.replace('{"":{"language":"en"}}', data);
|
||||
finish(data);
|
||||
});
|
||||
} else {
|
||||
finish(data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write it out */
|
||||
function finish(data) {
|
||||
if (opts.output) {
|
||||
fs.writeFile(opts.output, data, function(err) {
|
||||
if (err)
|
||||
fatal(err.message);
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
process.stdout.write(data);
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue