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