xliff
Version:
xliff2js and js2xliff converter xliff utils
153 lines • 5.06 kB
JavaScript
import convert from 'xml-js';
import ElementTypes12 from './inline-elements/ElementTypes12.js';
import { extractValue } from './xml-js/xmlToObject.js';
var xliff12ToJsClb = function xliff12ToJsClb(str, options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
}
options = options || {
captureSpacesBetweenElements: false
};
if (typeof str !== 'string') {
var err = new Error('The first parameter was not a string');
if (cb) return cb(err);
return err;
}
var result = {};
var xmlObj;
try {
xmlObj = convert.xml2js(str, options);
} catch (err) {
if (cb) return cb(err);
return err;
}
var xliffRoot = xmlObj.elements.find(function (ele) {
return ele.name === 'xliff';
});
var version = xliffRoot.attributes && xliffRoot.attributes.version;
if (version && version !== '1.2') {
result.xliffVersion = version;
}
if (xliffRoot.elements && xliffRoot.elements.length) {
var elements = xliffRoot.elements.filter(function (e) {
return e.type === 'element';
});
var srcLang = elements[0].attributes['source-language'] || xliffRoot.attributes.srcLang;
var trgLang = elements[0].attributes['target-language'] || xliffRoot.attributes.trgLang;
result.sourceLanguage = srcLang;
result.targetLanguage = trgLang;
if (!result.targetLanguage) delete result.targetLanguage;
var files = [];
var headerExtras = [];
elements.forEach(function (child) {
if (child.name === 'file') {
files.push(child);
} else {
headerExtras.push(child);
}
});
if (headerExtras.length) result.headerExtras = headerExtras;
result.resources = files.reduce(function (resources, file) {
var namespace = options.namespace || file.attributes.original;
var body = file.elements.filter(function (e) {
return e.type === 'element';
}).find(function (e) {
return e.name === 'body';
});
body.elements = body.elements || [];
var bodyChildren = body.elements.filter(function (child) {
return child.type !== 'comment' && child.type === 'element';
});
resources[namespace] = createUnits(bodyChildren);
return resources;
}, {});
} else {
result.resources = {};
}
if (cb) return cb(null, result);
return result;
};
function createUnits(childElements) {
return childElements.reduce(function (parent, child) {
if (!child.attributes || !child.attributes.id) return parent;
var key = child.attributes.id;
if (!child.elements) return parent;
var children = child.elements.filter(function (e) {
return e.name === 'trans-unit' || e.name === 'group';
});
if (children.length) {
parent[key] = createGroupTag(child, children);
} else {
parent[key] = createTransUnitTag(child);
}
if (child.attributes.ref) {
if (!parent[key].additionalAttributes) parent[key].additionalAttributes = {};
parent[key].additionalAttributes.ref = child.attributes.ref;
}
var known = ['trans-unit', 'group', 'source', 'target', 'note', 'body'];
var additionalElements = child.elements.filter(function (e) {
return !known.includes(e.name);
});
if (additionalElements.length) {
parent[key].additionalElements = additionalElements;
}
return parent;
}, {});
}
function createTransUnitTag(transUnit) {
var jsUnit = transUnit.elements.reduce(function (unit, element) {
var value = extractValue(element.elements, ElementTypes12);
switch (element.name) {
case 'source':
case 'target':
unit[element.name] = value;
break;
case 'note':
if (unit[element.name]) {
if (!Array.isArray(unit[element.name])) {
unit[element.name] = [unit[element.name]];
}
unit[element.name].push(value);
} else {
unit[element.name] = value;
}
break;
}
return unit;
}, {});
return addAdditionalAttributes(jsUnit, transUnit.attributes);
}
function createGroupTag(groupUnit, children) {
var jsGroupUnit = {
groupUnits: createUnits(children)
};
return addAdditionalAttributes(jsGroupUnit, groupUnit.attributes);
}
function addAdditionalAttributes(jsUnit, attributes) {
var additionalAttributes = attributes;
delete additionalAttributes.id;
if (Object.keys(additionalAttributes).length) {
Object.assign(jsUnit, {
additionalAttributes: additionalAttributes
});
}
return jsUnit;
}
export default function xliff12ToJs(str, options, cb) {
if (!cb && options === undefined) {
return new Promise(function (resolve, reject) {
return xliff12ToJsClb(str, options, function (err, ret) {
return err ? reject(err) : resolve(ret);
});
});
}
if (!cb && typeof options !== 'function') {
return new Promise(function (resolve, reject) {
return xliff12ToJsClb(str, options, function (err, ret) {
return err ? reject(err) : resolve(ret);
});
});
}
xliff12ToJsClb(str, options, cb);
}