UNPKG

angular-t9n

Version:

A translation tool for Angular i18n

102 lines (87 loc) 3.58 kB
import { Injectable } from '@nestjs/common'; import { TranslationSourceUnit, TranslationTargetUnit } from '../models'; import { XlfDeserializerBase } from './xlf-deserializer-base'; import { XmlParser } from './xml-parser'; @Injectable() export class Xlf2Deserializer extends XlfDeserializerBase { constructor(parser: XmlParser) { super(parser); } deserializeSource(content: string) { const doc = this._createDocument(content); const language = doc.documentElement.getAttribute('srcLang')!; const fileNode = this._getFileNode(doc); const unitMap = Array.from(fileNode.childNodes) .filter((c) => c.nodeName === 'unit') .map((u) => this._deserializeSourceUnit(u as Element)) .reduce( (current, next) => current.set(next.id, next), new Map<string, TranslationSourceUnit>(), ); return { language, unitMap }; } deserializeTarget(content: string) { const doc = this._createDocument(content); const language = doc.documentElement.getAttribute('trgLang')!; this._assertTargetLanguage(language); const fileNode = this._getFileNode(doc); const unitMap = Array.from(fileNode.childNodes) .filter((c) => c.nodeName === 'unit') .map((u) => this._deserializeTargetUnit(u as Element)) .reduce( (current, next) => current.set(next.id, next), new Map<string, TranslationTargetUnit>(), ); return { language, unitMap }; } protected _assertXliff(doc: Document) { super._assertXliff(doc); if (doc.documentElement.getAttribute('version') !== '2.0') { throw new Error( `Expected the xliff tag to have a version attribute with value '2.0' (<xliff version="2.0" ...)`, ); } else if (!doc.documentElement.getAttribute('srcLang')) { throw new Error( `Expected the xliff tag to have a srcLang attribute (e.g. <xliff srcLang="en" ...)`, ); } } private _deserializeTargetUnit(unit: Element): TranslationTargetUnit { const segment = unit.getElementsByTagName('segment')[0]; return { ...this._deserializeSourceUnit(unit), target: this._extractTarget(segment), state: this._extractState(segment), }; } private _deserializeSourceUnit(unitElement: Element): TranslationSourceUnit { const unit: TranslationSourceUnit = { id: unitElement.getAttribute('id')!, source: this._extractSource(unitElement.getElementsByTagName('segment')[0]), }; const notesElement = unitElement.getElementsByTagName('notes')[0]; if (!notesElement) { return unit; } unit.description = this._extractNote(notesElement, 'description')[0]; unit.meaning = this._extractNote(notesElement, 'meaning')[0]; const locations = this._extractNote(notesElement, 'location'); unit.locations = locations.length ? locations : undefined; return unit; } private _extractSource(segment: Element) { return this._convertToString(segment.getElementsByTagName('source')[0]); } private _extractTarget(segment: Element) { return this._convertToString(segment.getElementsByTagName('target')[0]); } private _extractNote(notes: Element, category: string): string[] { return Array.from(notes.getElementsByTagName('note')) .filter((n) => n.getAttribute('category') === category && n.textContent) .map((n) => n.textContent!); } private _extractState(segment: Element) { const state = segment.getAttribute('state'); return state === 'translated' || state === 'reviewed' || state === 'final' ? state : 'initial'; } }