in gulpfile.js [430:611]
function handoff(callback) {
// create a key->value map of default strings and comments for localizers
//
// resjson-style resources:
// "greeting": "Hello",
// "_greeting.comment": "A welcome greeting.",
//
// for more details about resjson: https://msdn.microsoft.com/en-us/library/windows/apps/hh465254.aspx
try {
var allLibJson = shell.find(path.join(__dirname, 'Extensions'))
.filter(function (file) {
return file.match(/(\/|\\)lib\.json$/);
});
allLibJson.forEach(function (libJson) {
console.log('Generating xliff for ' + libJson);
var defaultStrings = {};
var comments = {};
var lib = JSON.parse(fs.readFileSync(libJson));
if (lib.messages) {
for (var key of Object.keys(lib.messages)) {
if (!key) {
throw new Error('key cannot be empty: lib.messages.<key>');
}
if (key.match(/^_.+\.comment$/)) {
var commentKey = key;
var valueKey = commentKey.substr( // trim leading "_"
'_'.length, // trim trailing ".comment"
commentKey.length - '_.comment'.length);
comments[`loc.messages.${valueKey}`] = lib.messages[commentKey];
continue;
}
else {
defaultStrings[`loc.messages.${key}`] = lib.messages[key];
}
}
}
// create or update the culture-specific xlf files
for (var culture of cultures) {
if (culture.toUpperCase() == 'EN-US') {
continue;
}
// test whether xliff file exists
var xliffPath = path.join(path.dirname(libJson), 'xliff', `${culture}.xlf`);
var stats;
try {
stats = fs.statSync(xliffPath);
}
catch (err) {
if (err.code != 'ENOENT') {
throw err;
}
}
var xliff;
if (stats) {
// parse the file
var parser = new xml2js.Parser();
parser.parseString(
fs.readFileSync(xliffPath),
function (err, result) {
if (err) {
throw err;
}
xliff = result;
}
)
}
else {
// create the initial xliff object
xliff = {
"xliff": {
"$": {
"version": "1.2"
},
"file": [
{
"$": {
"original": "lib.json",
"source-language": "en-US",
"target-language": culture,
"datatype": "plaintext"
},
"body": [
{
"trans-unit": []
}
]
}
]
}
}
}
// create a map of trans-unit
var unitMap = {};
for (var unit of xliff.xliff.file[0].body[0]['trans-unit']) {
unitMap[unit['$'].id] = unit;
}
for (var key of Object.keys(defaultStrings)) {
// add the trans-unit
if (!unitMap.hasOwnProperty(key)) {
unitMap[key] = {
"$": {
"id": key
},
"source": [
defaultStrings[key]
],
"target": [
{
"$": {
"state": "new"
},
"_": ""
}
]
};
}
// update the source, target state, and note
else if (unitMap[key].source[0] != defaultStrings[key]) {
unitMap[key].source = [
defaultStrings[key]
];
if (unitMap[key].target[0]['$'].state != 'new') {
unitMap[key].target[0]['$'].state = "needs-translation";
}
}
// always update the note
unitMap[key].note = [
(comments[key] || "")
];
}
for (var key of Object.keys(unitMap)) {
// delete the trans-unit
if (!defaultStrings.hasOwnProperty(key)) {
delete unitMap[key];
}
}
// update the body of the xliff object
xliff.xliff.file[0].body[0]['trans-unit'] = [];
for (var key of Object.keys(unitMap).sort()) {
xliff.xliff.file[0].body[0]['trans-unit'].push(unitMap[key]);
}
// write the xliff file
var options = {
"renderOpts": {
"pretty": true,
"indent": " ",
"newline": os.EOL
},
"xmldec": {
"version": "1.0",
"encoding": "utf-8"
}
};
var builder = new xml2js.Builder(options);
var xml = builder.buildObject(xliff);
shell.mkdir('-p', path.dirname(xliffPath));
fs.writeFileSync(xliffPath, '\ufeff' + xml);
}
});
}
catch (err) {
console.log('error:' + err.message);
callback(new gutil.PluginError('compileTasks', err.message));
throw err;
}
}