Implemented mfrac tag use cases
This commit is contained in:
parent
397f0f1a49
commit
d18ad4e912
@ -395,4 +395,77 @@ describe('#convert', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('given mfrac tag', () => {
|
||||
describe('containing single char contents', () => {
|
||||
test('convert mfrac wrap inside \\frac command', () => {
|
||||
const mathml = `
|
||||
<root>
|
||||
<math>
|
||||
<mfrac>
|
||||
<mi>x</mi>
|
||||
<mn>3</mn>
|
||||
</mfrac>
|
||||
</math>
|
||||
</root>
|
||||
`;
|
||||
|
||||
const result = MathMLToLaTeX.convert(mathml);
|
||||
|
||||
expect(result).toMatch('\\frac{x}{3}');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('containing multiple char contents', () => {
|
||||
test('convert mfrac wrap inside \\frac command', () => {
|
||||
const mathml = `
|
||||
<root>
|
||||
<math>
|
||||
<mfrac>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
<mo>+</mo>
|
||||
<mi>2</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mi>b</mi>
|
||||
<mo>-</mo>
|
||||
<mi>3</mi>
|
||||
</mrow>
|
||||
</mfrac>
|
||||
</math>
|
||||
</root>
|
||||
`;
|
||||
|
||||
const result = MathMLToLaTeX.convert(mathml);
|
||||
|
||||
expect(result).toMatch('\\frac{a + 2}{b - 3}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('containing two contents with bevelled attribute marked as true', () => {
|
||||
test('convert mfrac joining its two char contents with //', () => {
|
||||
const mathml = `
|
||||
<root>
|
||||
<math>
|
||||
<mfrac bevelled="true">
|
||||
<mn>1</mn>
|
||||
<mrow>
|
||||
<msup>
|
||||
<mi>x</mi>
|
||||
<mn>3</mn>
|
||||
</msup>
|
||||
<mo>+</mo>
|
||||
<mn>3</mn>
|
||||
</mrow>
|
||||
</mfrac>
|
||||
</math>
|
||||
</root>
|
||||
`;
|
||||
|
||||
const result = MathMLToLaTeX.convert(mathml);
|
||||
expect(result).toMatch('1/\\left(x^{3} + 3\\right)');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Math, MathMLTag, MI, MO, MN, MSqrt, MRow, MSup, MFenced } from './mathml-tags';
|
||||
import { Math, MathMLTag, MI, MO, MN, MSqrt, MRow, MSup, MFenced, MFrac } from './mathml-tags';
|
||||
|
||||
export class Dispatcher {
|
||||
private _name: string;
|
||||
@ -31,6 +31,8 @@ export class Dispatcher {
|
||||
return new MSup(this._value, this._attributes, this._children);
|
||||
case 'mfenced':
|
||||
return new MFenced(this._value, this._attributes, this._children);
|
||||
case 'mfrac':
|
||||
return new MFrac(this._value, this._attributes, this._children);
|
||||
default:
|
||||
return new MathMLTag(this._name, this._value, this._attributes, this._children);
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
import { MathMLTag } from './MathMLTag';
|
||||
import { InvalidNumberOfChild } from '../../../../errors';
|
||||
import { ParenthesisWrapper } from '../../../../../utils/wrappers';
|
||||
|
||||
export class MFrac extends MathMLTag {
|
||||
constructor(value: string, attributes: Record<string, string>, children: MathMLTag[]) {
|
||||
super('mfrac', value, attributes, children);
|
||||
}
|
||||
|
||||
convert(): string {
|
||||
if (this._children.length !== 2) throw new InvalidNumberOfChild(this._name, 2, this._children.length);
|
||||
|
||||
const num = this._children[0].convert();
|
||||
const den = this._children[1].convert();
|
||||
|
||||
if (this._isBevelled) return `${this._wrapIfMoreThanOneChar(num)}/${this._wrapIfMoreThanOneChar(den)}`;
|
||||
|
||||
return `\\frac{${num}}{${den}}`;
|
||||
}
|
||||
|
||||
private _wrapIfMoreThanOneChar(str: string): string {
|
||||
return new ParenthesisWrapper().wrapIfMoreThanOneChar(str);
|
||||
}
|
||||
|
||||
private get _isBevelled(): boolean {
|
||||
return !!this._attributes.bevelled;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { MathMLTag } from './MathMLTag';
|
||||
import { BracketWrapper, ParenthesisWrapper } from '../../../../../utils/wrappers';
|
||||
import { InvalidNumberOfChild } from '../../../../errors';
|
||||
|
||||
export class MSup extends MathMLTag {
|
||||
constructor(value: string, attributes: Record<string, string>, children: MathMLTag[]) {
|
||||
@ -7,7 +8,7 @@ export class MSup extends MathMLTag {
|
||||
}
|
||||
|
||||
convert(): string {
|
||||
if (this._children.length !== 2) throw new InvalidNumberOfChild(this._children.length);
|
||||
if (this._children.length !== 2) throw new InvalidNumberOfChild(this._name, 2, this._children.length);
|
||||
|
||||
const base = this._children[0].convert();
|
||||
const exponent = this._children[1].convert();
|
||||
@ -15,9 +16,3 @@ export class MSup extends MathMLTag {
|
||||
return `${new ParenthesisWrapper().wrapIfMoreThanOneChar(base)}^${new BracketWrapper().wrap(exponent)}`;
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidNumberOfChild extends Error {
|
||||
constructor(numberOfChild: number) {
|
||||
super(`msup tag must have exactly 2 children. It's actually ${numberOfChild}`);
|
||||
}
|
||||
}
|
||||
|
@ -7,3 +7,4 @@ export { MSqrt } from './MSqrt';
|
||||
export { MRow } from './MRow';
|
||||
export { MSup } from './MSup';
|
||||
export { MFenced } from './MFenced';
|
||||
export { MFrac } from './MFrac';
|
||||
|
5
src/errors/InvalidNumberOfChild.ts
Normal file
5
src/errors/InvalidNumberOfChild.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class InvalidNumberOfChild extends Error {
|
||||
constructor(tagName: string, expectedNumberOfChild: number, currentNumberOfChild: number) {
|
||||
super(`${tagName} tag must have exactly ${expectedNumberOfChild} children. It's actually ${currentNumberOfChild}`);
|
||||
}
|
||||
}
|
1
src/errors/index.ts
Normal file
1
src/errors/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { InvalidNumberOfChild } from './InvalidNumberOfChild';
|
Loading…
Reference in New Issue
Block a user