feat: add nested mtable use case and fix matrix logic
This commit is contained in:
parent
059880a354
commit
dd49c00bc0
@ -397,6 +397,228 @@ export const mfencedAsPartialFunction = `
|
||||
</root>
|
||||
`;
|
||||
|
||||
export const mfencedWithNestedMtables = `
|
||||
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
|
||||
<mfenced separators="|">
|
||||
<mrow>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>11</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>12</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mo>…</mo>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mo>…</mo>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>21</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>22</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mo>⋱</mo>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mi></mi>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>2</mn>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mo>⋮</mo>
|
||||
<mi></mi>
|
||||
<mi></mi>
|
||||
<mi></mi>
|
||||
<mi></mi>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mo>⋮</mo>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mi>m</mi>
|
||||
<mn>1</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mi>m</mi>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mi></mi>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mo>⋱</mo>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mo>…</mo>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mo>…</mo>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mo>⋮</mo>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<msub>
|
||||
<mrow>
|
||||
<mi>a</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mi>m</mi>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</msub>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mrow>
|
||||
</mfenced>
|
||||
<mi></mi>
|
||||
</math>
|
||||
`;
|
||||
|
||||
export const mfrac = `
|
||||
<root>
|
||||
<math>
|
||||
|
@ -41,37 +41,69 @@ class Vector {
|
||||
}
|
||||
|
||||
class Matrix {
|
||||
private readonly _open: string;
|
||||
private readonly _close: string;
|
||||
private readonly _separators: Separators;
|
||||
private readonly _genericCommand = 'matrix';
|
||||
|
||||
constructor(open: string, close: string) {
|
||||
this._separators = new Separators(open, close);
|
||||
}
|
||||
|
||||
apply(latex: string): string {
|
||||
const command = this._command;
|
||||
const matrix = `\\begin{${command}}\n${latex}\n\\end{${command}}`;
|
||||
|
||||
return command === this._genericCommand ? this._separators.wrap(matrix) : matrix;
|
||||
}
|
||||
|
||||
private get _command(): string {
|
||||
if (this._separators.areParentheses()) return 'pmatrix';
|
||||
if (this._separators.areSquareBrackets()) return 'bmatrix';
|
||||
if (this._separators.areBrackets()) return 'Bmatrix';
|
||||
if (this._separators.areDivides()) return 'vmatrix';
|
||||
if (this._separators.areParallels()) return 'Vmatrix';
|
||||
if (this._separators.areNotEqual()) return this._genericCommand;
|
||||
return 'bmatrix';
|
||||
}
|
||||
}
|
||||
|
||||
class Separators {
|
||||
readonly _open: string;
|
||||
readonly _close: string;
|
||||
|
||||
constructor(open: string, close: string) {
|
||||
this._open = open;
|
||||
this._close = close;
|
||||
}
|
||||
|
||||
apply(latex: string): string {
|
||||
if (this._close || !this._open)
|
||||
return `\\begin{${this._customCommand}}\n` + latex + `\n\\end{${this._customCommand}}`;
|
||||
|
||||
const matrix = `\\begin{${this._genericCommand}}\n` + latex + `\n\\end{${this._genericCommand}}`;
|
||||
return new GenericWrapper(this._open, this._close).wrap(matrix);
|
||||
wrap(str: string): string {
|
||||
return new GenericWrapper(this._open, this._close).wrap(str);
|
||||
}
|
||||
|
||||
private get _customCommand(): string {
|
||||
switch (this._open) {
|
||||
case '(':
|
||||
return 'pmatrix';
|
||||
case '|':
|
||||
return 'vmatrix';
|
||||
case '||':
|
||||
return 'Vmatrix';
|
||||
case '[':
|
||||
return 'bmatrix';
|
||||
case '{':
|
||||
return 'Bmatrix';
|
||||
default:
|
||||
return this._genericCommand;
|
||||
}
|
||||
areParentheses(): boolean {
|
||||
return this._compare('(', ')');
|
||||
}
|
||||
|
||||
areSquareBrackets(): boolean {
|
||||
return this._compare('[', ']');
|
||||
}
|
||||
|
||||
areBrackets(): boolean {
|
||||
return this._compare('{', '}');
|
||||
}
|
||||
|
||||
areDivides(): boolean {
|
||||
return this._compare('|', '|');
|
||||
}
|
||||
|
||||
areParallels(): boolean {
|
||||
return this._compare('||', '||');
|
||||
}
|
||||
|
||||
areNotEqual(): boolean {
|
||||
return this._open !== this._close;
|
||||
}
|
||||
|
||||
private _compare(openToCompare: string, closeToCompare: string): boolean {
|
||||
return this._open === openToCompare && this._close === closeToCompare;
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,15 @@ import { MathMLTag } from './MathMLTag';
|
||||
export class MTable extends MathMLTag {
|
||||
constructor(value: string, attributes: Record<string, string>, children: MathMLTag[]) {
|
||||
super('mtable', value, attributes, children);
|
||||
this.addFlagRecursiveIfClassName(this.constructor.name, 'innerTable');
|
||||
}
|
||||
|
||||
convert(): string {
|
||||
return this._mapChildrenToLaTeX().join(' \\\\\n');
|
||||
const tableContent = this._mapChildrenToLaTeX().join(' \\\\\n');
|
||||
return this.hasFlag('innerTable') ? this._wrap(tableContent) : tableContent;
|
||||
}
|
||||
|
||||
private _wrap(latex: string): string {
|
||||
return `\\begin{matrix}${latex}\\end{matrix}`;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ export class MathMLTag {
|
||||
protected _value: string;
|
||||
protected _attributes: Record<string, string>;
|
||||
protected _children: MathMLTag[];
|
||||
protected _flags: string[] = [];
|
||||
|
||||
constructor(name: string, value: string, attributes: Record<string, string>, children: MathMLTag[]) {
|
||||
this._name = name;
|
||||
@ -29,4 +30,19 @@ export class MathMLTag {
|
||||
|
||||
return firstChild.constructor.name === className || firstChild.isThere(className);
|
||||
}
|
||||
|
||||
addFlag(flag: string): void {
|
||||
if (!this._flags.includes(flag)) this._flags.push(flag);
|
||||
}
|
||||
|
||||
addFlagRecursiveIfClassName(className: string, flag: string): void {
|
||||
this._children.forEach((child) => {
|
||||
if (child.constructor.name === className) child.addFlag(flag);
|
||||
child.addFlagRecursiveIfClassName(className, flag);
|
||||
});
|
||||
}
|
||||
|
||||
hasFlag(flag: string): boolean {
|
||||
return this._flags.includes(flag);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user