]>
git.proxmox.com Git - mirror_novnc.git/blob - po/xgettext-html
3 * xgettext-html: HTML gettext parser
4 * Copyright (C) 2016 Pierre Ossman
5 * Licensed under MPL 2.0 (see LICENSE.txt)
8 const getopt
= require('node-getopt');
9 const jsdom
= require("jsdom");
10 const fs
= require("fs");
12 const opt
= getopt
.create([
13 ['o' , 'output=FILE' , 'write output to specified file'],
14 ['h' , 'help' , 'display this help'],
15 ]).bindHelp().parseSystem();
19 function addString(str
, location
) {
20 if (str
.length
== 0) {
24 if (strings
[str
] === undefined) {
27 strings
[str
][location
] = null;
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;
36 if (elem
.hasAttribute("translate")) {
37 if (isAnyOf(elem
.getAttribute("translate"), ["", "yes"])) {
39 } else if (isAnyOf(elem
.getAttribute("translate"), ["no"])) {
45 if (elem
.hasAttribute("abbr") &&
46 elem
.tagName
=== "TH") {
47 addString(elem
.getAttribute("abbr"), locator(elem
));
49 if (elem
.hasAttribute("alt") &&
50 isAnyOf(elem
.tagName
, ["AREA", "IMG", "INPUT"])) {
51 addString(elem
.getAttribute("alt"), locator(elem
));
53 if (elem
.hasAttribute("download") &&
54 isAnyOf(elem
.tagName
, ["A", "AREA"])) {
55 addString(elem
.getAttribute("download"), locator(elem
));
57 if (elem
.hasAttribute("label") &&
58 isAnyOf(elem
.tagName
, ["MENUITEM", "MENU", "OPTGROUP",
59 "OPTION", "TRACK"])) {
60 addString(elem
.getAttribute("label"), locator(elem
));
62 if (elem
.hasAttribute("placeholder") &&
63 isAnyOf(elem
.tagName
in ["INPUT", "TEXTAREA"])) {
64 addString(elem
.getAttribute("placeholder"), locator(elem
));
66 if (elem
.hasAttribute("title")) {
67 addString(elem
.getAttribute("title"), locator(elem
));
69 if (elem
.hasAttribute("value") &&
70 elem
.tagName
=== "INPUT" &&
71 isAnyOf(elem
.getAttribute("type"), ["reset", "button", "submit"])) {
72 addString(elem
.getAttribute("value"), locator(elem
));
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
));
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
;
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
;
98 process(body
, locator
, true);
103 for (str
in strings
) {
105 for (location
in strings
[str
]) {
106 output
+= " " + location
;
110 output
+= "msgid " + JSON
.stringify(str
) + "\n";
111 output
+= "msgstr \"\"\n";
115 fs
.writeFileSync(opt
.options
.output
, output
);