Skip to content

Commit acea39e

Browse files
authored
Allow inline math inside display math (#857)
1 parent 4042c12 commit acea39e

2 files changed

Lines changed: 63 additions & 24 deletions

File tree

SETUP/tests/jsTests/formatPreviewTests.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,12 @@ QUnit.module("Format preview test", function() {
467467
issueTest(assert, 1, 8, 2, "misMatchTag", 1);
468468
});
469469

470+
QUnit.test("inline math inside display math", function (assert) {
471+
text = "\\[e=mc^2 \\text{abc \\(x=y\\)}\\]";
472+
issArray = analyse(text, mathConfig).issues;
473+
noIssueTest(assert);
474+
});
475+
470476
QUnit.test("missing maths end tag", function (assert) {
471477
text = "\\[e=mc^2\\(";
472478
issArray = analyse(text, mathConfig).issues;

tools/proofers/preview.js

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -706,42 +706,75 @@ $(function () {
706706
}
707707
}
708708

709-
// check that math delimiters \[ \], \( \) are correctly matched
709+
// check that math delimiters \[ \], \( \) are matched
710+
// allow inline math inside display math (in text{})
710711
function checkMath() {
711-
let mathRe = /\\\[|\\\]|\\\(|\\\)/g;
712+
var tagStack = []; // holds start tag [ or (
713+
var stackTop;
714+
const mathRe = /\\\[|\\\]|\\\(|\\\)/g;
712715
let result;
713-
let tag, openTag = false;
714-
let openStart = 0;
716+
let tag;
717+
let start;
715718
while((result = mathRe.exec(txt)) !== null) {
719+
start = result.index;
716720
tag = result[0].charAt(1);
717-
// if no open tag and ( or [ set open else error
718-
if (!openTag) {
721+
if (tagStack.length === 0) {
722+
// no tags on stack
719723
if ((tag === '(') || (tag === '[')) {
720-
openTag = tag;
721-
openStart = result.index;
724+
tagStack.push({tag: tag, start: start});
722725
} else {
723-
reportIssue(result.index, 2, "noStartTag");
726+
reportIssue(start, 2, "noStartTag");
724727
}
725728
} else {
726-
if (((openTag === '(') && (tag === ')')) || ((openTag === '[') && (tag === ']'))) {
727-
// correctly matched
728-
openTag = false;
729-
} else if (((openTag === '(') && (tag === ']')) || ((openTag === '[') && (tag === ')'))) {
730-
// mismatched
731-
openTag = false;
732-
reportIssue(openStart, 2, "misMatchTag");
733-
reportIssue(result.index, 2, "misMatchTag");
729+
// there are tags in the stack
730+
stackTop = tagStack[tagStack.length - 1];
731+
if(stackTop.tag === '[') {
732+
// ] or ( ok, [ or ) error
733+
switch(tag) {
734+
case ']':
735+
tagStack.pop();
736+
break;
737+
case '(':
738+
tagStack.push({tag: tag, start: start});
739+
break;
740+
case '[':
741+
// report error for stack tag push the new one
742+
tagStack.pop();
743+
tagStack.push({tag: tag, start: start});
744+
reportIssue(stackTop.start, 2, "noEndTag");
745+
break;
746+
case ')':
747+
tagStack.pop();
748+
reportIssue(stackTop.start, 2, "misMatchTag");
749+
reportIssue(start, 2, "misMatchTag");
750+
break;
751+
}
734752
} else {
735-
// a start tag of either sort follows a start tag
736-
reportIssue(openStart, 2, "noEndTag");
737-
openTag = tag;
738-
openStart = result.index;
753+
// stacktop is (, ) ok else error
754+
switch(tag) {
755+
case ')':
756+
tagStack.pop();
757+
break;
758+
case '(':
759+
case '[':
760+
// report error for stack tag push the new one
761+
tagStack.pop();
762+
tagStack.push({tag: tag, start: start});
763+
reportIssue(stackTop.start, 2, "noEndTag");
764+
break;
765+
case ']':
766+
tagStack.pop();
767+
reportIssue(stackTop.start, 2, "misMatchTag");
768+
reportIssue(start, 2, "misMatchTag");
769+
break;
770+
}
739771
}
740772
}
741773
}
742-
// if there is a tag open mark it as an error
743-
if (openTag) {
744-
reportIssue(openStart, 2, "noEndTag");
774+
// if there are any tags on the stack mark them as errors
775+
while (tagStack.length !== 0) {
776+
stackTop = tagStack.pop();
777+
reportIssue(stackTop.start, 2, "noEndTag");
745778
}
746779
}
747780

0 commit comments

Comments
 (0)