Fix \operatorname (#1461)

* Fix operatorname

* Update MathML

* Update screenshots

* Fix lint error

* Pick up comment

* Remove duplicate lines

* Fix lint error

* Remove duplicate code

* Replace \pi with \Pi in test

* Revise RegEx

* Update RegEx
This commit is contained in:
Ron Kok
2018-07-16 10:08:41 -07:00
committed by ylemkimon
parent f0976ade26
commit 8f5239c272
6 changed files with 59 additions and 37 deletions

View File

@@ -25,64 +25,80 @@ defineFunction({
},
htmlBuilder: (group, options) => {
const output = [];
if (group.value.value.length > 0) {
let letter = "";
let mode = "";
const groupValue = group.value.value.map(child => {
const childValue = child.value;
// In the amsopn package, \newmcodes@ changes four
// characters, *-/:, from math operators back into text.
if (typeof childValue === "string" &&
"*-/:".indexOf(childValue) !== -1) {
if (typeof childValue === "string") {
return new ParseNode("textord", childValue, child.mode);
} else {
return child;
}
});
// Consolidate Greek letter function names into symbol characters.
const temp = html.buildExpression(
// Consolidate function names into symbol characters.
const expression = html.buildExpression(
groupValue, options.withFont("mathrm"), true);
// All we want from temp are the letters. With them, we'll
// create a text operator similar to \tan or \cos.
for (const child of temp) {
for (const child of expression) {
if (child instanceof domTree.symbolNode) {
letter = child.value;
// In the amsopn package, \newmcodes@ changes four
// characters, *-/:, from math operators back into text.
// Given what is in temp, we have to address two of them.
letter = letter.replace(/\u2212/, "-"); // minus => hyphen
letter = letter.replace(/\u2217/, "*");
// Use math mode for Greek letters
mode = (/[\u0391-\u03D7]/.test(letter) ? "math" : "text");
output.push(buildCommon.mathsym(letter, mode));
} else {
output.push(child);
// Per amsopn package,
// change minus to hyphen and \ast to asterisk
child.value = child.value.replace(/\u2212/, "-")
.replace(/\u2217/, "*");
}
}
return buildCommon.makeSpan(["mop"], expression, options);
} else {
return buildCommon.makeSpan(["mop"], [], options);
}
return buildCommon.makeSpan(["mop"], output, options);
},
mathmlBuilder: (group, options) => {
// The steps taken here are similar to the html version.
let output = [];
if (group.value.value.length > 0) {
const temp = mml.buildExpression(
group.value.value, options.withFont("mathrm"));
let expression = mml.buildExpression(
group.value.value, options.withFont("mathrm"));
let word = temp.map(node => node.toText()).join("");
word = word.replace(/\u2212/g, "-");
word = word.replace(/\u2217/g, "*");
// word has already been escaped by `node.toText()`
output = [new mathMLTree.TextNode(word, false)];
// Is expression a string or has it something like a fraction?
let isAllString = true; // default
for (const node of expression) {
if (node instanceof mathMLTree.SpaceNode) {
// Do nothing
} else {
switch (node.type) {
case "mi":
case "mn":
case "ms":
case "mspace":
case "mtext":
break; // Do nothing yet.
case "mo":
if (node.children.length === 1) {
if (node.children[0] instanceof mathMLTree.TextNode ===
false) {
isAllString = false;
} else {
node.children[0].text =
node.children[0].text.replace(/\u2212/, "-")
.replace(/\u2217/, "*");
}
} else {
isAllString = false;
}
break;
default:
isAllString = false;
}
}
}
const identifier = new mathMLTree.MathNode("mi", output);
if (isAllString) {
// Write a single TextNode instead of multiple nested tags.
const word = expression.map(node => node.toText()).join("");
// word has already been escaped by `node.toText()`
expression = [new mathMLTree.TextNode(word, false)];
}
const identifier = new mathMLTree.MathNode("mi", expression);
identifier.setAttribute("mathvariant", "normal");
// \u2061 is the same as ⁡

View File

@@ -2471,6 +2471,12 @@ describe("An aligned environment", function() {
});
});
describe("operatorname support", function() {
it("should not fail", function() {
expect("\\operatorname{x*Π∑\\Pi\\sum\\frac a b}").toBuild();
});
});
describe("An href command", function() {
it("should parse its input", function() {
expect("\\href{http://example.com/}{example here}").toParse();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB