refactor: interfaces to protocols

This commit is contained in:
Alexandre Nunes 2020-09-20 16:56:17 -03:00
parent 8fcb04cf16
commit f0da2a4522
8 changed files with 79 additions and 4 deletions

@ -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';

@ -1,4 +1,4 @@
import { MathML } from '../../../interfaces/MathML';
import { MathML } from '../../../protocols/MathML';
export class ElementsToMathMLAdapter {
convert(els: Element[]): MathML[] {

@ -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 {

@ -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';

@ -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<string, string> {
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<ChildNode>): boolean {
return Array.from(children).some((child) => child.nodeName !== '#text');
}
}

@ -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[];
}
}