Generate a single xliff file for each language.

(Rather than one per source file per language).

This closes #156
This commit is contained in:
TimBarham 2016-09-27 22:15:13 +10:00
Родитель f1db78a152
Коммит fd5eda793b
2 изменённых файлов: 80 добавлений и 67 удалений

Просмотреть файл

@ -25,23 +25,26 @@ var langs = ['zh-CHS', 'zh-CHT', 'cs', 'de', 'es', 'fr', 'it', 'ja', 'ko', 'pl',
var htmlRootPath = path.resolve(__dirname, '../../src');
var htmlFiles = files.findFiles(path.join(htmlRootPath, 'plugins'), 'html');
// Reads and 'xlf' files under this directory
// Reads any 'xlf' files under this directory
var xliffRootPath = path.resolve(__dirname, 'xliff');
var xliffFiles = files.findFiles(xliffRootPath, 'xlf');
var xliffs = {};
xliffFiles.forEach(function (xliffFile) {
var xlfJson = xliffConv.parseXliffFile(xliffFile);
// Delete xliffFile if original HTML file no longer exists
if (htmlFiles.indexOf(path.resolve(htmlRootPath, xlfJson.original)) === -1) {
files.removeFileAndDirectoryIfEmpty(xliffFile);
} else {
xliffs[xlfJson.lang] = xliffs[xlfJson.lang] || {};
xliffs[xlfJson.lang][xlfJson.original] = xlfJson;
}
var xlfJsons = xliffConv.parseXliffFile(xliffFile);
xlfJsons.forEach(function (xlfJson) {
// Delete xliffFile if original HTML file no longer exists
if (htmlFiles.indexOf(path.resolve(htmlRootPath, xlfJson.original)) === -1) {
files.removeFileAndDirectoryIfEmpty(xliffFile);
} else {
xliffs[xlfJson.lang] = xliffs[xlfJson.lang] || {};
xliffs[xlfJson.lang][xlfJson.original] = xlfJson;
}
});
});
htmlFiles.forEach(function (htmlFile) {
var langXliffs = {};
Promise.all(htmlFiles.map(function (htmlFile) {
if (path.basename(htmlFile) === 'sim-host.html') {
return;
}
@ -73,21 +76,30 @@ htmlFiles.forEach(function (htmlFile) {
return previous;
}, {});
updateLanguageXlfJson(sourceHtmlRelativePath, strings).then(function (result) {
result.forEach(function (xlfJson) {
// Generate XLIFF file
var xlfFile = path.resolve(__dirname, 'xliff', xlfJson.lang, sourceHtmlRelativePath) + '.xlf';
var xliffDoc = xliffConv.parseJson(xlfJson);
files.writeFileSync(xlfFile, pd.xml(new XMLSerializer().serializeToString(xliffDoc)));
return updateLanguageXlfJson(sourceHtmlRelativePath, strings)
.then(function (result) {
result.forEach(function (xlfJson) {
// Add to the list of xlfJsons for this lang (so we can later build a single xlf file per lang)
var lang = xlfJson.lang;
langXliffs[lang] = langXliffs[lang] || [];
langXliffs[lang].push(xlfJson);
// Generate translated HTML file
var htmlFile = path.resolve(__dirname, '../../src/i18n', xlfJson.lang, sourceHtmlRelativePath);
applyTranslationsToDocument(xlfJson, stringsById);
files.writeFileSync(htmlFile, parse5.serialize(fragment, {treeAdapter: htmlparser2TreeAdapter}));
// Generate translated HTML file
var htmlFile = path.resolve(__dirname, '../../src/i18n', lang, sourceHtmlRelativePath);
applyTranslationsToDocument(xlfJson, stringsById);
files.writeFileSync(htmlFile, parse5.serialize(fragment, {treeAdapter: htmlparser2TreeAdapter}));
});
console.log('HTML files updated for ' + chalk.cyan(sourceHtmlRelativePath));
}).catch(function (err) {
console.log('ERROR in updateLanguageXlfJson():\n' + err.stack);
});
console.log('XLIFF and HTML files updated for ' + chalk.cyan(sourceHtmlRelativePath));
}).catch(function (err) {
console.log('ERROR in updateLanguageXlfJson():\n' + err.stack);
})).then(function () {
langs.forEach(function (lang) {
// Generate XLIFF file for this language
var xlfFile = path.resolve(__dirname, 'xliff', lang + '.xlf');
var xliffDoc = xliffConv.parseJson(langXliffs[lang]);
files.writeFileSync(xlfFile, pd.xml(new XMLSerializer().serializeToString(xliffDoc)));
console.log('XLIFF file updated for ' + chalk.cyan(lang));
});
});

Просмотреть файл

@ -8,30 +8,28 @@ function parseXliffFile(xliffFile) {
}
function parseXliff(xliff) {
var result = {};
var xliffDoc = new DOMParser().parseFromString(xliff, 'text/xml');
var xliffNode = xliffDoc.firstChild;
var fileNode = getElementChild(xliffNode, 'file');
return getElementChildren(xliffNode, 'file').map(function (fileNode) {
var result = {};
result.original = fileNode.getAttribute('original');
result.lang = fileNode.getAttribute('target-language');
var items = {};
result.items = items;
result.original = fileNode.getAttribute('original');
result.lang = fileNode.getAttribute('target-language');
var items = {};
result.items = items;
var bodyNode = getElementChild(fileNode, 'body');
var transUnitNodes = getElementChildren(bodyNode, 'trans-unit');
transUnitNodes.forEach(function (transUnitNode) {
var targetNode = getElementChild(transUnitNode, 'target');
items[transUnitNode.getAttribute('id')] = {
"text": getElementChild(transUnitNode, 'source').firstChild.data,
"state": targetNode.getAttribute('state'),
"stateQualifier": targetNode.getAttribute('state-qualifier'),
"translatedText": targetNode.firstChild.data
};
var bodyNode = getElementChild(fileNode, 'body');
var transUnitNodes = getElementChildren(bodyNode, 'trans-unit');
transUnitNodes.forEach(function (transUnitNode) {
var targetNode = getElementChild(transUnitNode, 'target');
items[transUnitNode.getAttribute('id')] = {
"text": getElementChild(transUnitNode, 'source').firstChild.data,
"state": targetNode.getAttribute('state'),
"stateQualifier": targetNode.getAttribute('state-qualifier'),
"translatedText": targetNode.firstChild.data
};
});
return result;
});
return result;
}
function getElementChild(node, tagName) {
@ -60,40 +58,43 @@ function getElementChildren(node, tagName) {
/**
*
* @param xlfJson
* @param xlfJsons
* @returns {Document}
*/
function parseJson(xlfJson) {
var targetLanguage = xlfJson.lang;
function parseJson(xlfJsons) {
var xliffDoc = new DOMParser().parseFromString('<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd" version="1.2"></xliff>', 'text/xml');
var xliffNode = xliffDoc.firstChild;
var fileNode = xliffDoc.createElement('file');
fileNode.setAttribute('original', xlfJson.original);
fileNode.setAttribute('source-language', 'en');
fileNode.setAttribute('target-language', targetLanguage);
xliffNode.appendChild(fileNode);
xlfJsons.forEach(function (xlfJson) {
var targetLanguage = xlfJson.lang;
var bodyNode = xliffDoc.createElement('body');
fileNode.appendChild(bodyNode);
var fileNode = xliffDoc.createElement('file');
fileNode.setAttribute('original', xlfJson.original);
fileNode.setAttribute('source-language', 'en');
fileNode.setAttribute('target-language', targetLanguage);
xliffNode.appendChild(fileNode);
var items = xlfJson.items;
var ids = Object.getOwnPropertyNames(items);
var bodyNode = xliffDoc.createElement('body');
fileNode.appendChild(bodyNode);
// Create an array of strings to be translated, for machine translation
var fromStrings = ids.map(function (id) {
return items[id].text;
});
var items = xlfJson.items;
var ids = Object.getOwnPropertyNames(items);
ids.forEach(function (id, index) {
var item = items[id];
// Create an array of strings to be translated, for machine translation
var fromStrings = ids.map(function (id) {
return items[id].text;
});
var transUnitNode = xliffDoc.createElement('trans-unit');
transUnitNode.setAttribute('id', id);
bodyNode.appendChild(transUnitNode);
ids.forEach(function (id, index) {
var item = items[id];
createSourceNode(xliffDoc, transUnitNode, 'en', item.text);
createTargetNode(xliffDoc, transUnitNode, targetLanguage, item.translatedText, item.state, item.stateQualifier);
var transUnitNode = xliffDoc.createElement('trans-unit');
transUnitNode.setAttribute('id', id);
bodyNode.appendChild(transUnitNode);
createSourceNode(xliffDoc, transUnitNode, 'en', item.text);
createTargetNode(xliffDoc, transUnitNode, targetLanguage, item.translatedText, item.state, item.stateQualifier);
});
});
return xliffDoc;
@ -125,4 +126,4 @@ module.exports = {
parseXliffFile: parseXliffFile,
parseXliff: parseXliff,
parseJson: parseJson
};
};