Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix problems with verification and repair of malformed mtables. #779

Merged
merged 4 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions ts/core/MmlTree/MmlNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ export interface MmlNode extends Node {
* @param {string} message The error message to use
* @param {PropertyList} options The options telling how much to verify
* @param {boolean} short True means use just the kind if not using full errors
* @return {MmlNode} The construted merror
*/
mError(message: string, options: PropertyList, short?: boolean): void;
mError(message: string, options: PropertyList, short?: boolean): MmlNode;

/**
* Check integrity of MathML structure
Expand Down Expand Up @@ -797,12 +798,14 @@ export abstract class AbstractMmlNode extends AbstractNode implements MmlNode {
* @param {string} message The error message to use
* @param {PropertyList} options The options telling how much to verify
* @param {boolean} short True means use just the kind if not using full errors
* @return {MmlNode} The constructed merror
*/
public mError(message: string, options: PropertyList, short: boolean = false) {
public mError(message: string, options: PropertyList, short: boolean = false): MmlNode {
if (this.parent && this.parent.isKind('merror')) {
return null;
}
let merror = this.factory.create('merror');
merror.attributes.set('data-mjx-message', message);
if (options['fullErrors'] || short) {
let mtext = this.factory.create('mtext');
let text = this.factory.create('text') as TextNode;
Expand Down Expand Up @@ -1189,7 +1192,9 @@ export abstract class AbstractMmlEmptyNode extends AbstractEmptyNode implements
/**
* @override
*/
public mError(_message: string, _options: PropertyList, _short: boolean = false) {}
public mError(_message: string, _options: PropertyList, _short: boolean = false) {
return null as MmlNode;
}

}

Expand Down
16 changes: 12 additions & 4 deletions ts/core/MmlTree/MmlNodes/mtable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,18 @@ export class MmlMtable extends AbstractMmlNode {
* @override
*/
protected verifyChildren(options: PropertyList) {
if (!options['fixMtables']) {
for (const child of this.childNodes) {
if (!child.isKind('mtr')) {
this.mError('Children of ' + this.kind + ' must be mtr or mlabeledtr', options);
for (const child of this.childNodes) {
if (!child.isKind('mtr')) {
const isMtd = child.isKind('mtd');
const factory = this.factory;
let mtr = this.replaceChild(factory.create('mtr'), child) as MmlNode;
mtr.appendChild(isMtd ? child : factory.create('mtd', {}, [child]));
if (!options['fixMtables']) {
child.parent.childNodes = []; // remove the child from the parent...
child.parent = this; // ... and make it think it is a child of the table again
isMtd && mtr.appendChild(factory.create('mtd')); // child will be replaced, so make sure there is an mtd
const merror = child.mError('Children of ' + this.kind + ' must be mtr or mlabeledtr', options, isMtd);
mtr.childNodes[0].appendChild(merror); // append the error to the mtd in the mtr
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions ts/core/MmlTree/MmlNodes/mtr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ export class MmlMtr extends AbstractMmlNode {
this.mError(this.kind + ' can only be a child of an mtable', options, true);
return;
}
if (!options['fixMtables']) {
for (const child of this.childNodes) {
if (!child.isKind('mtd')) {
let mtr = this.replaceChild(this.factory.create('mtr'), child) as MmlNode;
mtr.mError('Children of ' + this.kind + ' must be mtd', options, true);
for (const child of this.childNodes) {
if (!child.isKind('mtd')) {
let mtd = this.replaceChild(this.factory.create('mtd'), child) as MmlNode;
mtd.appendChild(child);
if (!options['fixMtables']) {
child.mError('Children of ' + this.kind + ' must be mtd', options);
}
}
}
Expand Down