Move "mclass" node logic to functions/mclass. (#1325)

* Move "mclass" node logic to functions/mclass.
This commit is contained in:
Ashish Myles
2018-05-18 12:44:28 -04:00
committed by GitHub
parent 73e0c13d10
commit f49a524da7
4 changed files with 101 additions and 76 deletions

View File

@@ -571,12 +571,6 @@ export const groupTypes = {
return makeSpan(["mrel", "x-arrow"], [vlist], options);
},
mclass(group, options) {
const elements = buildExpression(group.value.value, options, true);
return makeSpan([group.value.mclass], elements, options);
},
raisebox(group, options) {
const body = groupTypes.sizing({value: {
value: [{

View File

@@ -275,11 +275,6 @@ groupTypes.xArrow = function(group, options) {
return node;
};
groupTypes.mclass = function(group, options) {
const inner = buildExpression(group.value.value, options);
return new mathMLTree.MathNode("mstyle", inner);
};
groupTypes.raisebox = function(group, options) {
const node = new mathMLTree.MathNode(
"mpadded", [buildGroup(group.value.body, options)]);

View File

@@ -1,7 +1,6 @@
// @flow
/** Include this to ensure that all functions are defined. */
import ParseError from "./ParseError";
import ParseNode from "./ParseNode";
import {
default as _defineFunction,
ordargument,
@@ -51,70 +50,7 @@ import "./functions/kern";
import "./functions/phantom";
// Math class commands except \mathop
defineFunction("mclass", [
"\\mathord", "\\mathbin", "\\mathrel", "\\mathopen",
"\\mathclose", "\\mathpunct", "\\mathinner",
], {
numArgs: 1,
}, function(context, args) {
const body = args[0];
return {
type: "mclass",
mclass: "m" + context.funcName.substr(5),
value: ordargument(body),
};
});
// Build a relation or stacked op by placing one symbol on top of another
defineFunction("mclass", ["\\stackrel", "\\overset", "\\underset"], {
numArgs: 2,
}, function(context, args) {
const baseArg = args[1];
const shiftedArg = args[0];
let mclass = "mrel"; // default. May change below.
if (context.funcName !== "\\stackrel") {
// LaTeX applies \binrel spacing to \overset and \underset.
// \binrel spacing varies with (bin|rel|ord) of the atom in the argument.
// We'll do the same.
let atomType = "";
if (baseArg.type === "ordgroup") {
atomType = baseArg.value[0].type;
} else {
atomType = baseArg.type;
}
if (/^(bin|rel)$/.test(atomType)) {
mclass = "m" + atomType;
} else {
// This may capture some instances in which the baseArg is more than
// just a single symbol. Say a \overset inside an \overset.
// TODO: A more comprehensive way to determine the baseArg type.
mclass = "mord";
}
}
const baseOp = new ParseNode("op", {
type: "op",
limits: true,
alwaysHandleSupSub: true,
symbol: false,
suppressBaseShift: context.funcName !== "\\stackrel",
value: ordargument(baseArg),
}, baseArg.mode);
const supsub = new ParseNode("supsub", {
base: baseOp,
sup: context.funcName === "\\underset" ? null : shiftedArg,
sub: context.funcName === "\\underset" ? shiftedArg : null,
}, shiftedArg.mode);
return {
type: "mclass",
mclass: mclass,
value: [supsub],
};
});
import "./functions/mclass";
import "./functions/mod";

100
src/functions/mclass.js Normal file
View File

@@ -0,0 +1,100 @@
// @flow
import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
const makeSpan = buildCommon.makeSpan;
function htmlBuilder(group, options) {
const elements = html.buildExpression(group.value.value, options, true);
return makeSpan([group.value.mclass], elements, options);
}
function mathmlBuilder(group, options) {
const inner = mml.buildExpression(group.value.value, options);
return new mathMLTree.MathNode("mstyle", inner);
}
// Math class commands except \mathop
defineFunction({
type: "mclass",
names: [
"\\mathord", "\\mathbin", "\\mathrel", "\\mathopen",
"\\mathclose", "\\mathpunct", "\\mathinner",
],
props: {
numArgs: 1,
},
handler(context, args) {
const body = args[0];
return {
type: "mclass",
mclass: "m" + context.funcName.substr(5),
value: ordargument(body),
};
},
htmlBuilder,
mathmlBuilder,
});
// Build a relation or stacked op by placing one symbol on top of another
defineFunction({
type: "mclass",
names: ["\\stackrel", "\\overset", "\\underset"],
props: {
numArgs: 2,
},
handler(context, args) {
const baseArg = args[1];
const shiftedArg = args[0];
let mclass = "mrel"; // default. May change below.
if (context.funcName !== "\\stackrel") {
// LaTeX applies \binrel spacing to \overset and \underset. \binrel
// spacing varies with (bin|rel|ord) of the atom in the argument.
// We'll do the same.
let atomType = "";
if (baseArg.type === "ordgroup") {
atomType = baseArg.value[0].type;
} else {
atomType = baseArg.type;
}
if (/^(bin|rel)$/.test(atomType)) {
mclass = "m" + atomType;
} else {
// This may capture some instances in which the baseArg is more
// than just a single symbol. Say a \overset inside an \overset.
// TODO: A more comprehensive way to determine the baseArg type.
mclass = "mord";
}
}
const baseOp = new ParseNode("op", {
type: "op",
limits: true,
alwaysHandleSupSub: true,
symbol: false,
suppressBaseShift: context.funcName !== "\\stackrel",
value: ordargument(baseArg),
}, baseArg.mode);
const supsub = new ParseNode("supsub", {
base: baseOp,
sup: context.funcName === "\\underset" ? null : shiftedArg,
sub: context.funcName === "\\underset" ? shiftedArg : null,
}, shiftedArg.mode);
return {
type: "mclass",
mclass: mclass,
value: [supsub],
};
},
htmlBuilder,
mathmlBuilder,
});