diff --git a/src/buildHTML.js b/src/buildHTML.js index 15859ea..d30bbde 100644 --- a/src/buildHTML.js +++ b/src/buildHTML.js @@ -105,66 +105,20 @@ var buildExpression = function(expression, options, isRealGroup) { return groups; }; -// List of types used by getTypeOfGroup, -// see https://github.com/Khan/KaTeX/wiki/Examining-TeX#group-types -var groupToType = { - mathord: "mord", - textord: "mord", - bin: "mbin", - rel: "mrel", - text: "mord", - open: "mopen", - close: "mclose", - inner: "minner", - genfrac: "mord", - array: "mord", - spacing: "mord", - punct: "mpunct", - ordgroup: "mord", - op: "mop", - katex: "mord", - overline: "mord", - underline: "mord", - rule: "mord", - leftright: "minner", - sqrt: "mord", - accent: "mord", - llap: "mord", - rlap: "mord", -}; - -/** - * Gets the final math type of an expression, given its group type. This type is - * used to determine spacing between elements, and affects bin elements by - * causing them to change depending on what types are around them. This type - * must be attached to the outermost node of an element as a CSS class so that - * spacing with its surrounding elements works correctly. - * - * Some elements can be mapped one-to-one from group type to math type, and - * those are listed in the `groupToType` table. - * - * Others (usually elements that wrap around other elements) often have - * recursive definitions, and thus call `getTypeOfGroup` on their inner - * elements. - */ -var getTypeOfGroup = function(group) { - if (group == null) { - // Like when typesetting $^3$ - return groupToType.mathord; - } else if (group.type === "supsub") { - return getTypeOfGroup(group.value.base); - } else if (group.type === "color" || group.type === "sizing" - || group.type === "styling") { - // Return type of rightmost element of group. - var atoms = group.value.value; - return getTypeOfGroup(atoms[atoms.length - 1]); - } else if (group.type === "font") { - return getTypeOfGroup(group.value.body); - } else if (group.type === "delimsizing") { - return groupToType[group.value.delimType]; +// Return math atom class (mclass) of a domTree. +var getTypeOfDomTree = function(node) { + if (node instanceof domTree.documentFragment) { + if (node.children.length) { + return getTypeOfDomTree( + node.children[node.children.length - 1]); + } } else { - return groupToType[group.type]; + if (utils.contains(["mord", "mop", "mbin", "mrel", "mopen", "mclose", + "mpunct", "minner"], node.classes[0])) { + return node.classes[0]; + } } + return null; }; /** @@ -437,7 +391,8 @@ groupTypes.supsub = function(group, options) { } // We ensure to wrap the supsub vlist in a span.msupsub to reset text-align - return makeSpan([getTypeOfGroup(group.value.base)], + var mclass = getTypeOfDomTree(base) || "mord"; + return makeSpan([mclass], [base, makeSpan(["msupsub"], [supsub])], options); }; @@ -1200,13 +1155,13 @@ groupTypes.delimsizing = function(group, options) { if (delim === ".") { // Empty delimiters still count as elements, even though they don't // show anything. - return makeSpan([groupToType[group.value.delimType]]); + return makeSpan([group.value.mclass]); } // Use delimiter.sizedDelim to generate the delimiter. return delimiter.sizedDelim( delim, group.value.size, options, group.mode, - [groupToType[group.value.delimType]]); + [group.value.mclass]); }; groupTypes.leftright = function(group, options) { diff --git a/src/buildMathML.js b/src/buildMathML.js index 4a75d92..5b10fac 100644 --- a/src/buildMathML.js +++ b/src/buildMathML.js @@ -358,10 +358,10 @@ groupTypes.delimsizing = function(group) { var node = new mathMLTree.MathNode("mo", children); - if (group.value.delimType === "open" || - group.value.delimType === "close") { + if (group.value.mclass === "mopen" || + group.value.mclass === "mclose") { // Only some of the delimsizing functions act as fences, and they - // return "open" or "close" delimTypes. + // return "mopen" or "mclose" mclass. node.setAttribute("fence", "true"); } else { // Explicitly disable fencing if it's not a fence, to override the diff --git a/src/functions.js b/src/functions.js index 7888242..dc8a392 100644 --- a/src/functions.js +++ b/src/functions.js @@ -238,22 +238,22 @@ defineFunction("\\phantom", { // Extra data needed for the delimiter handler down below var delimiterSizes = { - "\\bigl" : {type: "open", size: 1}, - "\\Bigl" : {type: "open", size: 2}, - "\\biggl": {type: "open", size: 3}, - "\\Biggl": {type: "open", size: 4}, - "\\bigr" : {type: "close", size: 1}, - "\\Bigr" : {type: "close", size: 2}, - "\\biggr": {type: "close", size: 3}, - "\\Biggr": {type: "close", size: 4}, - "\\bigm" : {type: "rel", size: 1}, - "\\Bigm" : {type: "rel", size: 2}, - "\\biggm": {type: "rel", size: 3}, - "\\Biggm": {type: "rel", size: 4}, - "\\big" : {type: "textord", size: 1}, - "\\Big" : {type: "textord", size: 2}, - "\\bigg" : {type: "textord", size: 3}, - "\\Bigg" : {type: "textord", size: 4}, + "\\bigl" : {mclass: "mopen", size: 1}, + "\\Bigl" : {mclass: "mopen", size: 2}, + "\\biggl": {mclass: "mopen", size: 3}, + "\\Biggl": {mclass: "mopen", size: 4}, + "\\bigr" : {mclass: "mclose", size: 1}, + "\\Bigr" : {mclass: "mclose", size: 2}, + "\\biggr": {mclass: "mclose", size: 3}, + "\\Biggr": {mclass: "mclose", size: 4}, + "\\bigm" : {mclass: "mrel", size: 1}, + "\\Bigm" : {mclass: "mrel", size: 2}, + "\\biggm": {mclass: "mrel", size: 3}, + "\\Biggm": {mclass: "mrel", size: 4}, + "\\big" : {mclass: "mord", size: 1}, + "\\Big" : {mclass: "mord", size: 2}, + "\\bigg" : {mclass: "mord", size: 3}, + "\\Bigg" : {mclass: "mord", size: 4}, }; var delimiters = [ @@ -472,7 +472,7 @@ defineFunction([ return { type: "delimsizing", size: delimiterSizes[context.funcName].size, - delimType: delimiterSizes[context.funcName].type, + mclass: delimiterSizes[context.funcName].mclass, value: delim.value, }; } diff --git a/test/katex-spec.js b/test/katex-spec.js index 122c8db..b2fa955 100644 --- a/test/katex-spec.js +++ b/test/katex-spec.js @@ -883,8 +883,8 @@ describe("A delimiter sizing parser", function() { var leftParse = getParsed(normalDelim)[0]; var rightParse = getParsed(bigDelim)[0]; - expect(leftParse.value.delimType).toEqual("open"); - expect(rightParse.value.delimType).toEqual("close"); + expect(leftParse.value.mclass).toEqual("mopen"); + expect(rightParse.value.mclass).toEqual("mclose"); }); it("should parse the correct size delimiter", function() {