diff --git a/src/converters/xml-mathml-to-latex/XmlMathMLToLaTeX.ts b/src/converters/xml-mathml-to-latex/XmlMathMLToLaTeX.ts index 0cb4b73..6ca56fb 100755 --- a/src/converters/xml-mathml-to-latex/XmlMathMLToLaTeX.ts +++ b/src/converters/xml-mathml-to-latex/XmlMathMLToLaTeX.ts @@ -1,4 +1,4 @@ -import { MathML } from '../../interfaces/MathML'; +import { MathML } from '../../protocols/MathML'; import MathmlToLatex from './xml-to-mathml/mathml-to-latex'; import XmlToMathml from './xml-to-mathml'; diff --git a/src/converters/xml-mathml-to-latex/xml-to-mathml/ElementsToMathMLAdapter.ts b/src/converters/xml-mathml-to-latex/xml-to-mathml/ElementsToMathMLAdapter.ts index cba8c41..d3df220 100755 --- a/src/converters/xml-mathml-to-latex/xml-to-mathml/ElementsToMathMLAdapter.ts +++ b/src/converters/xml-mathml-to-latex/xml-to-mathml/ElementsToMathMLAdapter.ts @@ -1,4 +1,4 @@ -import { MathML } from '../../../interfaces/MathML'; +import { MathML } from '../../../protocols/MathML'; export class ElementsToMathMLAdapter { convert(els: Element[]): MathML[] { diff --git a/src/converters/xml-mathml-to-latex/xml-to-mathml/XmlToMathMLAdapter.ts b/src/converters/xml-mathml-to-latex/xml-to-mathml/XmlToMathMLAdapter.ts index 05d6a4a..57e5a52 100755 --- a/src/converters/xml-mathml-to-latex/xml-to-mathml/XmlToMathMLAdapter.ts +++ b/src/converters/xml-mathml-to-latex/xml-to-mathml/XmlToMathMLAdapter.ts @@ -2,7 +2,7 @@ import xmldom = require('xmldom'); import { DOMParser } from 'xmldom'; import { ErrorHandler } from './ErrorHandler'; -import { MathML } from '../../../interfaces/MathML'; +import { MathML } from '../../../protocols/MathML'; import { ElementsToMathMLAdapter } from './ElementsToMathMLAdapter'; export class XmlToMathMLAdapter { diff --git a/src/converters/xml-mathml-to-latex/xml-to-mathml/mathml-to-latex/MathMLToLaTeX.ts b/src/converters/xml-mathml-to-latex/xml-to-mathml/mathml-to-latex/MathMLToLaTeX.ts index b2ed7f3..d0b8980 100755 --- a/src/converters/xml-mathml-to-latex/xml-to-mathml/mathml-to-latex/MathMLToLaTeX.ts +++ b/src/converters/xml-mathml-to-latex/xml-to-mathml/mathml-to-latex/MathMLToLaTeX.ts @@ -1,4 +1,4 @@ -import { MathML } from '../../../../interfaces/MathML'; +import { MathML } from '../../../../protocols/MathML'; import Dispatcher from './mathml-to-latex'; import { MathMLTag } from './mathml-to-latex/mathml-tags'; diff --git a/src/converters/xml-to-mathml/ElementsToMathMLAdapter.ts b/src/converters/xml-to-mathml/ElementsToMathMLAdapter.ts new file mode 100644 index 0000000..16ec3fc --- /dev/null +++ b/src/converters/xml-to-mathml/ElementsToMathMLAdapter.ts @@ -0,0 +1,33 @@ +import { MathML } from '../../protocols/MathML'; + +export class ElementsToMathMLAdapter { + convert(els: Element[]): MathML[] { + return els.filter((el: Element) => el.tagName !== undefined).map((el: Element) => this._convertElement(el)); + } + + private _convertElement(el: Element): MathML { + return { + name: el.tagName, + attributes: el.attributes ? this._convertElementAttributes(el.attributes) : {}, + value: this._hasElementChild(el) ? '' : el.textContent || '', + children: this._hasElementChild(el) ? this.convert(Array.from(el.childNodes) as Element[]) : ([] as MathML[]), + }; + } + + private _convertElementAttributes(attributes: NamedNodeMap): Record { + return Array.from(attributes).reduce( + (acc, attr: Attr) => + Object.assign({ [attr.nodeName]: attr.nodeValue === attr.nodeName ? '' : attr.nodeValue }, acc), + {}, + ); + } + + private _hasElementChild(el: Element): boolean { + const childNodes = el.childNodes; + return !!childNodes && childNodes.length !== 0 && this._isThereAnyNoTextNode(childNodes); + } + + private _isThereAnyNoTextNode(children: NodeListOf): boolean { + return Array.from(children).some((child) => child.nodeName !== '#text'); + } +} diff --git a/src/converters/xml-to-mathml/XmlToMathMLAdapter.ts b/src/converters/xml-to-mathml/XmlToMathMLAdapter.ts new file mode 100644 index 0000000..2313621 --- /dev/null +++ b/src/converters/xml-to-mathml/XmlToMathMLAdapter.ts @@ -0,0 +1,42 @@ +import xmldom = require('xmldom'); + +import { DOMParser } from 'xmldom'; +import { ErrorHandler } from './ErrorHandler'; +import { MathML } from '../../protocols/MathML'; +import { ElementsToMathMLAdapter } from './ElementsToMathMLAdapter'; + +export class XmlToMathMLAdapter { + private _xmlDOM: DOMParser; + private _errorHandler: ErrorHandler; + private _elementsConvertor: ElementsToMathMLAdapter; + + constructor(private _xml: string) { + this._xml = this._removeLineBreaks(_xml); + + this._elementsConvertor = new ElementsToMathMLAdapter(); + this._errorHandler = new ErrorHandler(); + + this._xmlDOM = new xmldom.DOMParser({ + locator: this._errorHandler.errorLocator, + errorHandler: this._fixError.bind(this), + }); + } + + convert(): MathML[] { + return this._elementsConvertor.convert(this._mathMLElements); + } + + private _fixError(errorMessage: string): void { + this._xml = this._errorHandler.fixError(this._xml, errorMessage); + } + + private _removeLineBreaks(xml: string): string { + const LINE_BREAK = /\n|\r\n|\r/g; + return xml.replace(LINE_BREAK, ''); + } + + private get _mathMLElements(): Element[] { + const elements = this._xmlDOM.parseFromString(this._xml).getElementsByTagName('math'); + return Array.from(elements) as Element[]; + } +} diff --git a/src/interfaces/MathML.ts b/src/protocols/MathML.ts similarity index 100% rename from src/interfaces/MathML.ts rename to src/protocols/MathML.ts diff --git a/src/interfaces/index.ts b/src/protocols/index.ts similarity index 100% rename from src/interfaces/index.ts rename to src/protocols/index.ts