Support \mathop, \mathrel, \mathbin, \mathpunct, etc. class commands.
These commands set their arguments in a given TeX math class. Use the existing "op" type for \mathop (to support \limits); introduce a new "mclass" type for the other classes. Fixes #482. Tests borrowed from #485 (cbreeden).
This commit is contained in:
parent
982e7be597
commit
6bb62b11b4
|
@ -786,6 +786,11 @@ groupTypes.op = function(group, options) {
|
||||||
|
|
||||||
// The slant of the symbol is just its italic correction.
|
// The slant of the symbol is just its italic correction.
|
||||||
slant = base.italic;
|
slant = base.italic;
|
||||||
|
} else if (group.value.value) {
|
||||||
|
// If this is a list, compose that list.
|
||||||
|
var inner = buildExpression(group.value.value, options, true);
|
||||||
|
|
||||||
|
base = makeSpan(["mop"], inner, options);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, this is a text operator. Build the text from the
|
// Otherwise, this is a text operator. Build the text from the
|
||||||
// operator's name.
|
// operator's name.
|
||||||
|
@ -1399,6 +1404,12 @@ groupTypes.phantom = function(group, options) {
|
||||||
return new buildCommon.makeFragment(elements);
|
return new buildCommon.makeFragment(elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
groupTypes.mclass = function(group, options) {
|
||||||
|
var elements = buildExpression(group.value.value, options, true);
|
||||||
|
|
||||||
|
return makeSpan([group.value.mclass], elements, options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buildGroup is the function that takes a group and calls the correct groupType
|
* buildGroup is the function that takes a group and calls the correct groupType
|
||||||
* function for it. It also handles the interaction of size and style changes
|
* function for it. It also handles the interaction of size and style changes
|
||||||
|
|
|
@ -316,7 +316,7 @@ groupTypes.spacing = function(group) {
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
groupTypes.op = function(group) {
|
groupTypes.op = function(group, options) {
|
||||||
var node;
|
var node;
|
||||||
|
|
||||||
// TODO(emily): handle big operators using the `largeop` attribute
|
// TODO(emily): handle big operators using the `largeop` attribute
|
||||||
|
@ -325,6 +325,10 @@ groupTypes.op = function(group) {
|
||||||
// This is a symbol. Just add the symbol.
|
// This is a symbol. Just add the symbol.
|
||||||
node = new mathMLTree.MathNode(
|
node = new mathMLTree.MathNode(
|
||||||
"mo", [makeText(group.value.body, group.mode)]);
|
"mo", [makeText(group.value.body, group.mode)]);
|
||||||
|
} else if (group.value.value) {
|
||||||
|
// This is an operator with children. Add them.
|
||||||
|
node = new mathMLTree.MathNode(
|
||||||
|
"mo", buildExpression(group.value.value, options));
|
||||||
} else {
|
} else {
|
||||||
// This is a text operator. Add all of the characters from the
|
// This is a text operator. Add all of the characters from the
|
||||||
// operator's name.
|
// operator's name.
|
||||||
|
@ -475,6 +479,11 @@ groupTypes.phantom = function(group, options) {
|
||||||
return new mathMLTree.MathNode("mphantom", inner);
|
return new mathMLTree.MathNode("mphantom", inner);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
groupTypes.mclass = function(group, options) {
|
||||||
|
var inner = buildExpression(group.value.value, options);
|
||||||
|
return new mathMLTree.MathNode("mstyle", inner);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a list of nodes, builds them, and returns a list of the generated
|
* Takes a list of nodes, builds them, and returns a list of the generated
|
||||||
* MathML nodes. A little simpler than the HTML version because we don't do any
|
* MathML nodes. A little simpler than the HTML version because we don't do any
|
||||||
|
|
|
@ -100,6 +100,16 @@ function defineFunction(names, props, handler) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since the corresponding buildHTML/buildMathML function expects a
|
||||||
|
// list of elements, we normalize for different kinds of arguments
|
||||||
|
var ordargument = function(arg) {
|
||||||
|
if (arg.type === "ordgroup") {
|
||||||
|
return arg.value;
|
||||||
|
} else {
|
||||||
|
return [arg];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// A normal square root
|
// A normal square root
|
||||||
defineFunction("\\sqrt", {
|
defineFunction("\\sqrt", {
|
||||||
numArgs: 1,
|
numArgs: 1,
|
||||||
|
@ -121,19 +131,9 @@ defineFunction("\\text", {
|
||||||
greediness: 2,
|
greediness: 2,
|
||||||
}, function(context, args) {
|
}, function(context, args) {
|
||||||
var body = args[0];
|
var body = args[0];
|
||||||
// Since the corresponding buildHTML/buildMathML function expects a
|
|
||||||
// list of elements, we normalize for different kinds of arguments
|
|
||||||
// TODO(emily): maybe this should be done somewhere else
|
|
||||||
var inner;
|
|
||||||
if (body.type === "ordgroup") {
|
|
||||||
inner = body.value;
|
|
||||||
} else {
|
|
||||||
inner = [body];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "text",
|
type: "text",
|
||||||
body: inner,
|
body: ordargument(body),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -146,18 +146,10 @@ defineFunction("\\color", {
|
||||||
}, function(context, args) {
|
}, function(context, args) {
|
||||||
var color = args[0];
|
var color = args[0];
|
||||||
var body = args[1];
|
var body = args[1];
|
||||||
// Normalize the different kinds of bodies (see \text above)
|
|
||||||
var inner;
|
|
||||||
if (body.type === "ordgroup") {
|
|
||||||
inner = body.value;
|
|
||||||
} else {
|
|
||||||
inner = [body];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "color",
|
type: "color",
|
||||||
color: color.value,
|
color: color.value,
|
||||||
value: inner,
|
value: ordargument(body),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -223,16 +215,24 @@ defineFunction("\\phantom", {
|
||||||
numArgs: 1,
|
numArgs: 1,
|
||||||
}, function(context, args) {
|
}, function(context, args) {
|
||||||
var body = args[0];
|
var body = args[0];
|
||||||
var inner;
|
|
||||||
if (body.type === "ordgroup") {
|
|
||||||
inner = body.value;
|
|
||||||
} else {
|
|
||||||
inner = [body];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "phantom",
|
type: "phantom",
|
||||||
value: inner,
|
value: ordargument(body),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Math class commands except \mathop
|
||||||
|
defineFunction([
|
||||||
|
"\\mathord", "\\mathbin", "\\mathrel", "\\mathopen",
|
||||||
|
"\\mathclose", "\\mathpunct", "\\mathinner",
|
||||||
|
], {
|
||||||
|
numArgs: 1,
|
||||||
|
}, function(context, args) {
|
||||||
|
var body = args[0];
|
||||||
|
return {
|
||||||
|
type: "mclass",
|
||||||
|
mclass: "m" + context.funcName.substr(5),
|
||||||
|
value: ordargument(body),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -298,17 +298,10 @@ defineFunction([
|
||||||
greediness: 3,
|
greediness: 3,
|
||||||
}, function(context, args) {
|
}, function(context, args) {
|
||||||
var body = args[0];
|
var body = args[0];
|
||||||
var atoms;
|
|
||||||
if (body.type === "ordgroup") {
|
|
||||||
atoms = body.value;
|
|
||||||
} else {
|
|
||||||
atoms = [body];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "color",
|
type: "color",
|
||||||
color: "katex-" + context.funcName.slice(1),
|
color: "katex-" + context.funcName.slice(1),
|
||||||
value: atoms,
|
value: ordargument(body),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -378,6 +371,19 @@ defineFunction([
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// \mathop class command
|
||||||
|
defineFunction("\\mathop", {
|
||||||
|
numArgs: 1,
|
||||||
|
}, function(context, args) {
|
||||||
|
var body = args[0];
|
||||||
|
return {
|
||||||
|
type: "op",
|
||||||
|
limits: false,
|
||||||
|
symbol: false,
|
||||||
|
value: ordargument(body),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// Fractions
|
// Fractions
|
||||||
defineFunction([
|
defineFunction([
|
||||||
"\\dfrac", "\\frac", "\\tfrac",
|
"\\dfrac", "\\frac", "\\tfrac",
|
||||||
|
|
BIN
test/screenshotter/images/MathAtom-chrome.png
Normal file
BIN
test/screenshotter/images/MathAtom-chrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
BIN
test/screenshotter/images/MathAtom-firefox.png
Normal file
BIN
test/screenshotter/images/MathAtom-firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
BIN
test/screenshotter/images/MathAtom2-chrome.png
Normal file
BIN
test/screenshotter/images/MathAtom2-chrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
BIN
test/screenshotter/images/MathAtom2-firefox.png
Normal file
BIN
test/screenshotter/images/MathAtom2-firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
|
@ -79,6 +79,8 @@ LeftRightStyleSizing: |
|
||||||
LimitControls: |
|
LimitControls: |
|
||||||
\displaystyle\int\limits_2^3 3x^2\,dx + \sum\nolimits^n_{i=1}i +
|
\displaystyle\int\limits_2^3 3x^2\,dx + \sum\nolimits^n_{i=1}i +
|
||||||
\textstyle\int\limits_x^y z
|
\textstyle\int\limits_x^y z
|
||||||
|
MathAtom: a\mathrel{\mathop{=}\limits^{\blue ?}}b
|
||||||
|
MathAtom2: \mathop{\overline\mathrm{lim}}\limits_{x\to\infty}f(x)
|
||||||
MathDefaultFonts: Ax2k\breve{a}\omega\Omega\imath+\KaTeX
|
MathDefaultFonts: Ax2k\breve{a}\omega\Omega\imath+\KaTeX
|
||||||
MathBb: \mathbb{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
MathBb: \mathbb{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||||
MathBf: \mathbf{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
MathBf: \mathbf{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user