]> git.proxmox.com Git - mirror_novnc.git/blob - po/xgettext-html
Process input type submit for translations
[mirror_novnc.git] / po / xgettext-html
1 #!/usr/bin/env node
2 /*
3 * xgettext-html: HTML gettext parser
4 * Copyright (C) 2016 Pierre Ossman
5 * Licensed under MPL 2.0 (see LICENSE.txt)
6 */
7
8 var getopt = require('node-getopt');
9
10 var jsdom = require("jsdom");
11 var fs = require("fs");
12
13 opt = getopt.create([
14 ['o' , 'output=FILE' , 'write output to specified file'],
15 ['h' , 'help' , 'display this help'],
16 ]).bindHelp().parseSystem();
17
18 var strings = {};
19
20 function addString(str, location) {
21 if (str.length == 0) {
22 return;
23 }
24
25 if (strings[str] === undefined) {
26 strings[str] = {}
27 }
28 strings[str][location] = null;
29 }
30
31 // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
32 function process(elem, locator, enabled) {
33 function isAnyOf(searchElement, items) {
34 return items.indexOf(searchElement) !== -1;
35 }
36
37 if (elem.hasAttribute("translate")) {
38 if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
39 enabled = true;
40 } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
41 enabled = false;
42 }
43 }
44
45 if (enabled) {
46 if (elem.hasAttribute("abbr") &&
47 elem.tagName === "TH") {
48 addString(elem.getAttribute("abbr"), locator(elem));
49 }
50 if (elem.hasAttribute("alt") &&
51 isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
52 addString(elem.getAttribute("alt"), locator(elem));
53 }
54 if (elem.hasAttribute("download") &&
55 isAnyOf(elem.tagName, ["A", "AREA"])) {
56 addString(elem.getAttribute("download"), locator(elem));
57 }
58 if (elem.hasAttribute("label") &&
59 isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
60 "OPTION", "TRACK"])) {
61 addString(elem.getAttribute("label"), locator(elem));
62 }
63 if (elem.hasAttribute("placeholder") &&
64 isAnyOf(elem.tagName in ["INPUT", "TEXTAREA"])) {
65 addString(elem.getAttribute("placeholder"), locator(elem));
66 }
67 if (elem.hasAttribute("title")) {
68 addString(elem.getAttribute("title"), locator(elem));
69 }
70 if (elem.hasAttribute("value") &&
71 elem.tagName === "INPUT" &&
72 isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
73 addString(elem.getAttribute("value"), locator(elem));
74 }
75 }
76
77 for (var i = 0;i < elem.childNodes.length;i++) {
78 node = elem.childNodes[i];
79 if (node.nodeType === node.ELEMENT_NODE) {
80 process(node, locator, enabled);
81 } else if (node.nodeType === node.TEXT_NODE && enabled) {
82 addString(node.data.trim(), locator(node));
83 }
84 }
85 }
86
87 for (var i = 0;i < opt.argv.length;i++) {
88 var file;
89
90 fn = opt.argv[i];
91 file = fs.readFileSync(fn, "utf8");
92 dom = new jsdom.JSDOM(file, { includeNodeLocations: true });
93 body = dom.window.document.body;
94
95 locator = function (elem) {
96 offset = dom.nodeLocation(elem).startOffset;
97 line = file.slice(0, offset).split("\n").length;
98 return fn + ":" + line;
99 };
100
101 process(body, locator, true);
102 }
103
104 var output = "";
105
106 for (str in strings) {
107 output += "#:";
108 for (location in strings[str]) {
109 output += " " + location;
110 }
111 output += "\n";
112
113 output += "msgid " + JSON.stringify(str) + "\n";
114 output += "msgstr \"\"\n";
115 output += "\n";
116 }
117
118 fs.writeFileSync(opt.options.output, output);