jspaint/localization/parse-rc-file.js

146 lines
3.7 KiB
JavaScript

// Based on: https://github.com/evernote/serge/blob/master/lib/Serge/Engine/Plugin/parse_rc.pm
module.exports = function parse_rc_file(rc_file_text, callback, lang) {
// if (!callback) {
// throw new TypeError('callback not specified');
// }
// fetch().text() assumes utf8; hack to make it more readable (not needed in Node.js)
// rc_file_text = rc_file_text.replace(/\0/g, "");
let strings = [];
// let translated_text = "";
// Finding translatable strings in file
let menu;
let dialog;
let stringtable;
let block_level = 0;
let id_str;
let dialog_id;
for (let line of rc_file_text.split(/\r?\n/g)) {
// let hint;
let orig_str;
// let translated_str;
// normalize line
let norm_line = line.trim()
.replace(/[\t ]+/g, " ")
.replace(/\/\/.*$/g, "");
if (norm_line.match(/ MENU$/)) {
menu = true;
}
const dialog_match = norm_line.match(/^(\w+) (DIALOG|DIALOGEX) /);
if (dialog_match) {
dialog_id = dialog_match[1];
dialog = true;
}
if (norm_line === 'STRINGTABLE') {
stringtable = true;
}
if (norm_line === 'BEGIN') {
block_level++;
}
if (norm_line === 'END') {
block_level--;
if (block_level == 0) {
menu = undefined;
dialog = undefined;
dialog_id = undefined;
stringtable = undefined;
}
}
// console.log(`${line}\n`);
// console.log(`[m=${menu},d=${dialog},s=${stringtable},b=${block_level}]\n`);
// console.log(`[${norm_line}]\n`);
// DIALOG header contents
if (dialog && !block_level) {
const match = line.match(/^[\t ]*(CAPTION)[\t ]+(L?"(.*?("")*)*?")/);
if (match) {
id_str = `${dialog_id}:${match[1]}`;
hint = `${dialog_id} ${match[1]}`;
orig_str = match[2];
}
// MENU and DIALOGEX BEGIN...END block contents
} else if ((menu || dialog) && block_level) {
const match = line.match(/^[\t ]*(\w+)[\t ]+(L?"([^"]*?("")*)*?")(,[\t ]*(\w+)){0,1}/);
if (match) {
id_str = match[6];
hint = match[6] ? `${match[1]} ${match[6]}` : match[1];
orig_str = match[2];
}
// STRINGTABLE BEGIN...END block contents
// } else if (stringtable && block_level) {
// actually just do any time, find any strings
} {
// let match = line.match(/^[\t ]*(\w+)[\t ]+(L?"([^"]*?("")*)*?")/);
let match = line.match(/(L?"(.*)")/);
if (match) { // test for one-line string definitions
// id_str = match[1];
// hint = match[1];
// orig_str = match[2];
orig_str = match[0];
} else {
// test for the first line (id) of the two-line string definitions
match = line.match(/^[\t ]*(\w+)[\t ]*(\/\/.*)*$/);
if (match) {
id_str = match[1];
} else {
match = line.match(/^[\t ]*(L?"(.*)")/);
if (id_str && match) { // test for the second line (string) of the two-line string definitions
hint = id_str;
orig_str = match[1];
} else {
id_str = undefined;
}
}
}
}
if (orig_str) {
let str = orig_str;
let wide = str.match(/^L/);
str = str.replace(/^L?"(.*)"$/g, "$1");
str = str.replace(/\\r/g, "\r");
str = str.replace(/\\n/g, "\n");
str = str.replace(/\\t/g, "\t");
str = str.replace(/\\"/g, '"');
if (wide) {
str = str.replace(/\\x([0-9a-fA-F]{4})/g, (_, hex) => String.fromCodePoint(parseInt(hex, 16)));
}
strings.push(str);
// translated_str = callback(str, hint, lang, id_str);
// if (lang) {
// translated_str = translated_str.replace(/"/g, '""');
// translated_str = translated_str.replace(/\n/g, "\\n");
// line = line.replace(orig_str, translated_str);
// }
id_str = undefined;
hint = undefined;
orig_str = undefined;
}
// if (lang) {
// translated_text += `${line}\n`;
// }
}
return strings;
// return translated_text;
}