UNPKG

xliff

Version:

xliff2js and js2xliff converter xliff utils

129 lines (106 loc) 3.78 kB
import convert from 'xml-js' import ElementTypes12 from './inline-elements/ElementTypes12.js' import { extractValue } from './xml-js/xmlToObject.js' const xliff12ToJsClb = (str, options, cb) => { if (typeof options === 'function') { cb = options options = {} } options = options || { captureSpacesBetweenElements: false } if (typeof str !== 'string') { const err = new Error('The first parameter was not a string') if (cb) return cb(err) return err } const result = {} let xmlObj try { xmlObj = convert.xml2js(str, options) } catch (err) { if (cb) return cb(err) return err } const xliffRoot = xmlObj.elements.find((ele) => ele.name === 'xliff') if (xliffRoot.elements && xliffRoot.elements.length) { const elements = xliffRoot.elements.filter((e) => e.type === 'element') const srcLang = elements[0].attributes['source-language'] || xliffRoot.attributes.srcLang const trgLang = elements[0].attributes['target-language'] || xliffRoot.attributes.trgLang result.sourceLanguage = srcLang result.targetLanguage = trgLang if (!result.targetLanguage) delete result.targetLanguage result.resources = elements.reduce((resources, file) => { const namespace = options.namespace || file.attributes.original const body = file.elements.filter((e) => e.type === 'element').find((e) => e.name === 'body') body.elements = body.elements || [] const bodyChildren = body.elements.filter( (child) => child.type !== 'comment' && child.type === 'element' ) // namespace resources[namespace] = createUnits(bodyChildren) return resources }, {}) } else { result.resources = {} } if (cb) return cb(null, result) return result } function createUnits (childElements) { return childElements.reduce((parent, child) => { const key = child.attributes.id if (!child.elements) return parent const children = child.elements.filter((e) => e.name === 'trans-unit' || e.name === 'group') if (children.length) { parent[key] = createGroupTag(child, children) } else { parent[key] = createTransUnitTag(child) } return parent }, {}) } function createTransUnitTag (transUnit) { const jsUnit = transUnit.elements.reduce((unit, element) => { const 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 }, { /* source: '' */ }) return addAdditionalAttributes(jsUnit, transUnit.attributes) } function createGroupTag (groupUnit, children) { const jsGroupUnit = { groupUnits: createUnits(children) } return addAdditionalAttributes(jsGroupUnit, groupUnit.attributes) } function addAdditionalAttributes (jsUnit, attributes) { const additionalAttributes = attributes delete additionalAttributes.id if (Object.keys(additionalAttributes).length) { Object.assign(jsUnit, { additionalAttributes }) } return jsUnit } export default function xliff12ToJs (str, options, cb) { if (!cb && options === undefined) { return new Promise((resolve, reject) => xliff12ToJsClb(str, options, (err, ret) => err ? reject(err) : resolve(ret))) } if (!cb && typeof options !== 'function') { return new Promise((resolve, reject) => xliff12ToJsClb(str, options, (err, ret) => err ? reject(err) : resolve(ret))) } xliff12ToJsClb(str, options, cb) }