Skip to content

Commit

Permalink
Add goup handling in JSON transformations. (#50)
Browse files Browse the repository at this point in the history
* Add goup handling in JSON transformations.

* Handle nested groups and multiple notes.

* Update readme.

* Fix an issue in createjs.

* Fix multiple note conversion from xliff to js.

* Add additional tests for nested groups and multiple notes.

* Remove obsolete tests.
  • Loading branch information
marmarosi committed Jan 2, 2022
1 parent 7b05dcc commit 2dc2ff3
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 67 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ const res = targetOfjs(js)
// {
// "key1": "Hallo",
// "key2": "Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten",
// "key.nested": "XLIFF Daten Manager"
// "key.nested": "XLIFF Daten Manager",
// "group": {
// "groupUnit": "Gruppe"
// }
// }

import sourceOfjs from 'xliff/sourceOfjs'
Expand All @@ -125,7 +128,10 @@ const res = sourceOfjs(js)
// {
// "key1": "Hello",
// "key2": "An application to manipulate and process XLIFF documents",
// "key.nested": "XLIFF Data Manager"
// "key.nested": "XLIFF Data Manager",
// "group": {
// "groupUnit": "Group"
// }
// }

import createjs from 'xliff/createjs'
Expand Down
43 changes: 27 additions & 16 deletions lib/createjs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
function setSegment (category, srcObj, trgObj, ntObj, key) {
const srcValue = srcObj[key] || ''
const trgValue = trgObj[key] || ''

if (typeof srcValue === 'object' && typeof trgValue === 'object') {
category[key] = { groupUnits: {} }
const grpObj = category[key].groupUnits

Object.keys(srcValue).forEach(grpKey => {
setSegment(grpObj, srcObj[key], trgObj[key], ntObj[key], grpKey)

if (ntObj && ntObj[key] && ntObj[key][grpKey]) {
category[key].note = ntObj[key][grpKey]
}
})
} else {
category[key] = { source: srcValue, target: trgValue }

if (ntObj && ntObj[key]) {
category[key].note = ntObj[key]
}
}
}

const createjsClb = (srcLng, trgLng, srcKeys, trgKeys, ntKeys, ns, cb) => {
const js = {
sourceLanguage: srcLng,
Expand All @@ -14,16 +38,10 @@ const createjsClb = (srcLng, trgLng, srcKeys, trgKeys, ntKeys, ns, cb) => {

if (ns && typeof ns === 'string') {
js.resources[ns] = {}
const nsObj = js.resources[ns]

Object.keys(srcKeys).forEach((srcKey) => {
js.resources[ns][srcKey] = {
source: srcKeys[srcKey] || '',
target: trgKeys[srcKey] || ''
}

if (ntKeys && ntKeys[srcKey]) {
js.resources[ns][srcKey].note = ntKeys[srcKey]
}
setSegment(nsObj, srcKeys, trgKeys, ntKeys, srcKey)
})

if (cb) cb(null, js)
Expand All @@ -34,14 +52,7 @@ const createjsClb = (srcLng, trgLng, srcKeys, trgKeys, ntKeys, ns, cb) => {
js.resources[ns] = {}

Object.keys(srcKeys[ns]).forEach((srcKey) => {
js.resources[ns][srcKey] = {
source: srcKeys[ns][srcKey] || '',
target: trgKeys[ns][srcKey] || ''
}

if (ntKeys && ntKeys[ns] && ntKeys[ns][srcKey]) {
js.resources[ns][srcKey].note = ntKeys[ns][srcKey]
}
setSegment(js.resources[ns], srcKeys[ns], trgKeys[ns], ntKeys && ntKeys[ns], srcKey)
})
})

Expand Down
19 changes: 18 additions & 1 deletion lib/js2xliff.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,29 @@ function createUnitTag (id, unit) {
if (unit.target !== undefined) segment.elements.push(makeElement('target', null, makeValue(unit.target, ElementTypes2)))
const subEle = [segment]
if ('note' in unit) {
subEle.unshift(makeElement('notes', null, [makeElement('note', null, [makeText(unit.note)])]))
const noteElms = []
createNoteObjects(unit.note).forEach(noteObj => {
noteElms.push(makeElement('note', null, [noteObj]))
})
subEle.unshift(makeElement('notes', null, noteElms))
}
const additionalAttributes = unit.additionalAttributes != null ? unit.additionalAttributes : {}
return makeElement('unit', Object.assign({ id: escape(id) }, additionalAttributes), subEle)
}

function createNoteObjects (note) {
const arrNote = []
const baseNote = makeText(note)
if (Array.isArray(baseNote.text)) {
baseNote.text.forEach(text => {
arrNote.push({ type: baseNote.type, text })
})
} else {
arrNote.push(baseNote)
}
return arrNote
}

const js2xliff = (obj, opt, cb) => {
if (!cb && opt === undefined) {
return new Promise((resolve, reject) => js2xliffClb(obj, opt, (err, ret) => err ? reject(err) : resolve(ret)))
Expand Down
17 changes: 16 additions & 1 deletion lib/jsToXliff12.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,27 @@ function createTransUnitTag (key, resource, obj, options) {
u.elements.push(makeElement('target', targetAttributes, makeValue(resource.target, ElementTypes12)))
}
if ('note' in resource) {
u.elements.push(makeElement('note', null, [makeText(resource.note)]))
createNoteObjects(resource.note).forEach(noteObj => {
u.elements.push(makeElement('note', null, [noteObj]))
})
}

return u
}

function createNoteObjects (note) {
const arrNote = []
const baseNote = makeText(note)
if (Array.isArray(baseNote.text)) {
baseNote.text.forEach(text => {
arrNote.push({ type: baseNote.type, text })
})
} else {
arrNote.push(baseNote)
}
return arrNote
}

const jsToXliff12 = (obj, opt, cb) => {
if (!cb && opt === undefined) {
return new Promise((resolve, reject) => jsToXliff12Clb(obj, opt, (err, ret) => err ? reject(err) : resolve(ret)))
Expand Down
22 changes: 18 additions & 4 deletions lib/ofjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ export default function ofjs (js, what, cb) {
const ns = js.resources[nsKeys[0]]
const keys = Object.keys(ns)
keys.forEach((key) => {
if (ns[key][what] === undefined) return
res[key] = ns[key][what]
const value = getSegment(ns[key], what)
if (value === undefined) return
res[key] = value
})
if (cb) return cb(null, res)
return res
Expand All @@ -19,10 +20,23 @@ export default function ofjs (js, what, cb) {
const ns = js.resources[nsKey]
const keys = Object.keys(ns)
keys.forEach((key) => {
if (ns[key][what] === undefined) return
res[nsKey][key] = ns[key][what]
const value = getSegment(ns[key], what)
if (value !== undefined) res[nsKey][key] = value
})
})
if (cb) return cb(null, res)
return res
}

function getSegment (category, what) {
let value = category[what]
if (value === undefined && category.groupUnits) {
value = {}
const groupKeys = Object.keys(category.groupUnits)
groupKeys.forEach(groupKey => {
const groupValue = getSegment(category.groupUnits[groupKey], what)
if (groupValue !== undefined) value[groupKey] = groupValue
})
}
return value
}
12 changes: 11 additions & 1 deletion lib/xliff12ToJs.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,21 @@ function createUnits (childElements) {

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':
unit[element.name] = extractValue(element.elements, ElementTypes12)
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
}

Expand Down
12 changes: 11 additions & 1 deletion lib/xliff2js.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,21 @@ function createUnit (unit, initValues) {
return unit.elements.reduce((unit, segment) => {
if (['segment', 'notes'].indexOf(segment.name) < 0) return unit
segment.elements.forEach((element) => {
const value = extractValue(element.elements, ElementTypes2)
switch (element.name) {
case 'source':
case 'target':
unit[element.name] = value
break
case 'note':
unit[element.name] = extractValue(element.elements, ElementTypes2)
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
}
})
Expand Down
20 changes: 19 additions & 1 deletion test/fixtures/example_note.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,30 @@
"key2": {
"source": "An application to manipulate and process XLIFF documents",
"target": "Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten",
"note": "Description note"
"note": ["Description note", "Developer note"]
},
"key.nested": {
"source": "XLIFF Data Manager",
"target": "XLIFF Daten Manager",
"note": "Nested note"
},
"group1": {
"groupUnits": {
"in-group": {
"source": "An application to manipulate and process XLIFF documents",
"target": "Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten",
"note": "Group note"
},
"nested-group1": {
"groupUnits": {
"in-nested-group": {
"source": "XLIFF Data Manager",
"target": "XLIFF Daten Manager",
"note": "Nested group note"
}
}
}
}
}
},
"namespace2": {
Expand Down
23 changes: 23 additions & 0 deletions test/fixtures/example_note.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<unit id="key2">
<notes>
<note>Description note</note>
<note>Developer note</note>
</notes>
<segment>
<source>An application to manipulate and process XLIFF documents</source>
Expand All @@ -27,6 +28,28 @@
<target>XLIFF Daten Manager</target>
</segment>
</unit>
<group id="group1">
<unit id="in-group">
<notes>
<note>Group note</note>
</notes>
<segment>
<source>An application to manipulate and process XLIFF documents</source>
<target>Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten</target>
</segment>
</unit>
<group id="nested-group1">
<unit id="in-nested-group">
<notes>
<note>Nested group note</note>
</notes>
<segment>
<source>XLIFF Data Manager</source>
<target>XLIFF Daten Manager</target>
</segment>
</unit>
</group>
</group>
</file>
<file id="namespace2">
<unit id="k">
Expand Down
15 changes: 15 additions & 0 deletions test/fixtures/example_note12.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,27 @@
<source xml:lang="en-US">An application to manipulate and process XLIFF documents</source>
<target xml:lang="de-CH">Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten</target>
<note>Description note</note>
<note>Developer note</note>
</trans-unit>
<trans-unit id="key.nested">
<source xml:lang="en-US">XLIFF Data Manager</source>
<target xml:lang="de-CH">XLIFF Daten Manager</target>
<note>Nested note</note>
</trans-unit>
<group id="group1">
<trans-unit id="in-group">
<source>An application to manipulate and process XLIFF documents</source>
<target>Eine Applikation um XLIFF Dokumente zu manipulieren und verarbeiten</target>
<note>Group note</note>
</trans-unit>
<group id="nested-group1">
<trans-unit id="in-nested-group">
<source>XLIFF Data Manager</source>
<target>XLIFF Daten Manager</target>
<note>Nested group note</note>
</trans-unit>
</group>
</group>
</body>
</file>
<file original="namespace2">
Expand Down
20 changes: 20 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,23 @@ describe('single', () => {
test('targetOfjs', (fn) => () => {
const res = fn(fixtures.example.js)
expect(res['key.nested']).to.eql(fixtures.example.js.resources.namespace1['key.nested'].target)
const res2 = fn(fixtures.example_groups.js)
expect(res2['standalone']).to.eql(fixtures.example_groups.js.resources.namespace1['standalone'].target)
expect(res2['group1']['in-group']).to.eql(
fixtures.example_groups.js.resources.namespace1['group1'].groupUnits['in-group'].target)
expect(res2['group1']['nested-group1']['in-nested-group']).to.eql(
fixtures.example_groups.js.resources.namespace1['group1'].groupUnits['nested-group1'].groupUnits['in-nested-group'].target)
})

test('sourceOfjs', (fn) => () => {
const res = fn(fixtures.example.js)
expect(res['key.nested']).to.eql(fixtures.example.js.resources.namespace1['key.nested'].source)
const res2 = fn(fixtures.example_groups.js)
expect(res2['standalone']).to.eql(fixtures.example_groups.js.resources.namespace1['standalone'].source)
expect(res2['group1']['in-group']).to.eql(
fixtures.example_groups.js.resources.namespace1['group1'].groupUnits['in-group'].source)
expect(res2['group1']['nested-group1']['in-nested-group']).to.eql(
fixtures.example_groups.js.resources.namespace1['group1'].groupUnits['nested-group1'].groupUnits['in-nested-group'].source)
})

test('createjs', (fn) => (done) => {
Expand Down Expand Up @@ -284,12 +296,20 @@ describe('with notes', () => {
const res = fn(fixtures.example_note.js)
expect(res.namespace1['key.nested']).to.eql(fixtures.example_note.js.resources.namespace1['key.nested'].target)
expect(res.namespace2.k).to.eql(fixtures.example_note.js.resources.namespace2.k.target)
expect(res.namespace1['group1']['in-group']).to.eql(
fixtures.example_note.js.resources.namespace1['group1'].groupUnits['in-group'].target)
expect(res.namespace1['group1']['nested-group1']['in-nested-group']).to.eql(
fixtures.example_note.js.resources.namespace1['group1'].groupUnits['nested-group1'].groupUnits['in-nested-group'].target)
})

test('sourceOfjs', (fn) => () => {
const res = fn(fixtures.example_note.js)
expect(res.namespace1['key.nested']).to.eql(fixtures.example_note.js.resources.namespace1['key.nested'].source)
expect(res.namespace2.k).to.eql(fixtures.example_note.js.resources.namespace2.k.source)
expect(res.namespace1['group1']['in-group']).to.eql(
fixtures.example_note.js.resources.namespace1['group1'].groupUnits['in-group'].source)
expect(res.namespace1['group1']['nested-group1']['in-nested-group']).to.eql(
fixtures.example_note.js.resources.namespace1['group1'].groupUnits['nested-group1'].groupUnits['in-nested-group'].source)
})
})

Expand Down
Loading

0 comments on commit 2dc2ff3

Please sign in to comment.