|
@@ -1490,7 +1490,7 @@ var Tokenise = function (text) {
|
|
|
var controlSequence = NEXTCS.exec(text);
|
|
var controlSequence = NEXTCS.exec(text);
|
|
|
var nextSpecialPos = controlSequence === null ? idx : controlSequence.index;
|
|
var nextSpecialPos = controlSequence === null ? idx : controlSequence.index;
|
|
|
if (nextSpecialPos === idx) {
|
|
if (nextSpecialPos === idx) {
|
|
|
- Tokens.push([lineNumber, code, pos, idx + 1, text[idx]]);
|
|
|
|
|
|
|
+ Tokens.push([lineNumber, code, pos, idx + 1, text[idx], "control-symbol"]);
|
|
|
idx = SPECIAL.lastIndex = idx + 1;
|
|
idx = SPECIAL.lastIndex = idx + 1;
|
|
|
char = text[nextSpecialPos];
|
|
char = text[nextSpecialPos];
|
|
|
if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
|
|
if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
|
|
@@ -1508,12 +1508,7 @@ var Tokenise = function (text) {
|
|
|
} else if (code === "}") { // close group
|
|
} else if (code === "}") { // close group
|
|
|
Tokens.push([lineNumber, code, pos]);
|
|
Tokens.push([lineNumber, code, pos]);
|
|
|
} else if (code === "$") { // math mode
|
|
} else if (code === "$") { // math mode
|
|
|
- if (text[idx] === "$") {
|
|
|
|
|
- idx = SPECIAL.lastIndex = idx + 1;
|
|
|
|
|
- Tokens.push([lineNumber, "$$", pos]);
|
|
|
|
|
- } else {
|
|
|
|
|
- Tokens.push([lineNumber, code, pos]);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Tokens.push([lineNumber, code, pos]);
|
|
|
} else if (code === "&") { // tabalign
|
|
} else if (code === "&") { // tabalign
|
|
|
Tokens.push([lineNumber, code, pos]);
|
|
Tokens.push([lineNumber, code, pos]);
|
|
|
} else if (code === "#") { // macro parameter
|
|
} else if (code === "#") { // macro parameter
|
|
@@ -1559,6 +1554,25 @@ var read1arg = function (TokeniseResult, k, options) {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+var readLetDefinition = function (TokeniseResult, k) {
|
|
|
|
|
+
|
|
|
|
|
+ var Tokens = TokeniseResult.tokens;
|
|
|
|
|
+ var text = TokeniseResult.text;
|
|
|
|
|
+
|
|
|
|
|
+ var first = Tokens[k+1];
|
|
|
|
|
+ var second = Tokens[k+2];
|
|
|
|
|
+ var third = Tokens[k+3];
|
|
|
|
|
+
|
|
|
|
|
+ if(first && first[1] === "\\" && second && second[1] === "\\") {
|
|
|
|
|
+ return k + 2;
|
|
|
|
|
+ } else if(first && first[1] === "\\" &&
|
|
|
|
|
+ second && second[1] === "Text" && text.substring(second[2], second[3]) === "=" &&
|
|
|
|
|
+ third && third[1] === "\\") {
|
|
|
|
|
+ return k + 3;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
var read1name = function (TokeniseResult, k) {
|
|
var read1name = function (TokeniseResult, k) {
|
|
|
var Tokens = TokeniseResult.tokens;
|
|
var Tokens = TokeniseResult.tokens;
|
|
@@ -1594,19 +1608,88 @@ var read1name = function (TokeniseResult, k) {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+var read1filename = function (TokeniseResult, k) {
|
|
|
|
|
+ var Tokens = TokeniseResult.tokens;
|
|
|
|
|
+ var text = TokeniseResult.text;
|
|
|
|
|
+
|
|
|
|
|
+ var fileName = "";
|
|
|
|
|
+ for (var j = k + 1, tok; (tok = Tokens[j]); j++) {
|
|
|
|
|
+ if (tok[1] === "Text") {
|
|
|
|
|
+ var str = text.substring(tok[2], tok[3]);
|
|
|
|
|
+ if (!str.match(/^\S*$/)) { break; }
|
|
|
|
|
+ fileName = fileName + str;
|
|
|
|
|
+ } else if (tok[1] === "_") {
|
|
|
|
|
+ fileName = fileName + "_";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fileName.length > 0) {
|
|
|
|
|
+ return j; // advance past these tokens
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
var readOptionalParams = function(TokeniseResult, k) {
|
|
var readOptionalParams = function(TokeniseResult, k) {
|
|
|
var Tokens = TokeniseResult.tokens;
|
|
var Tokens = TokeniseResult.tokens;
|
|
|
var text = TokeniseResult.text;
|
|
var text = TokeniseResult.text;
|
|
|
|
|
|
|
|
var params = Tokens[k+1];
|
|
var params = Tokens[k+1];
|
|
|
-
|
|
|
|
|
if(params && params[1] === "Text") {
|
|
if(params && params[1] === "Text") {
|
|
|
var paramNum = text.substring(params[2], params[3]);
|
|
var paramNum = text.substring(params[2], params[3]);
|
|
|
if (paramNum.match(/^\[\d+\](\[[^\]]*\])*\s*$/)) {
|
|
if (paramNum.match(/^\[\d+\](\[[^\]]*\])*\s*$/)) {
|
|
|
return k + 1; // got it
|
|
return k + 1; // got it
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|
|
|
|
|
+ var count = 0;
|
|
|
|
|
+ var nextToken = Tokens[k+1];
|
|
|
|
|
+ var pos = nextToken[2];
|
|
|
|
|
+
|
|
|
|
|
+ for (var i = pos, end = text.length; i < end; i++) {
|
|
|
|
|
+ var char = text[i];
|
|
|
|
|
+ if (nextToken && i >= nextToken[2]) { k++; nextToken = Tokens[k+1];};
|
|
|
|
|
+ if (char === "[") { count++; }
|
|
|
|
|
+ if (char === "]") { count--; }
|
|
|
|
|
+ if (count === 0 && char === "{") { return k - 1; }
|
|
|
|
|
+ if (count > 0 && (char === '\r' || char === '\n')) { return null; }
|
|
|
|
|
+ };
|
|
|
|
|
+ return null;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+var readOptionalGeneric = function(TokeniseResult, k) {
|
|
|
|
|
+ var Tokens = TokeniseResult.tokens;
|
|
|
|
|
+ var text = TokeniseResult.text;
|
|
|
|
|
+
|
|
|
|
|
+ var params = Tokens[k+1];
|
|
|
|
|
+
|
|
|
|
|
+ if(params && params[1] === "Text") {
|
|
|
|
|
+ var paramNum = text.substring(params[2], params[3]);
|
|
|
|
|
+ if (paramNum.match(/^(\[[^\]]*\])+\s*$/)) {
|
|
|
|
|
+ return k + 1; // got it
|
|
|
|
|
+ };
|
|
|
|
|
+ };
|
|
|
|
|
+ return null;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+var readOptionalDef = function (TokeniseResult, k) {
|
|
|
|
|
+ var Tokens = TokeniseResult.tokens;
|
|
|
|
|
+ var text = TokeniseResult.text;
|
|
|
|
|
+
|
|
|
|
|
+ var defToken = Tokens[k];
|
|
|
|
|
+ var pos = defToken[3];
|
|
|
|
|
+
|
|
|
|
|
+ var openBrace = "{";
|
|
|
|
|
+ var nextToken = Tokens[k+1];
|
|
|
|
|
+ for (var i = pos, end = text.length; i < end; i++) {
|
|
|
|
|
+ var char = text[i];
|
|
|
|
|
+ if (nextToken && i >= nextToken[2]) { k++; nextToken = Tokens[k+1];};
|
|
|
|
|
+ if (char === openBrace) { return k - 1; }; // move back to the last token of the optional arguments
|
|
|
|
|
+ if (char === '\r' || char === '\n') { return null; }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
return null;
|
|
return null;
|
|
|
|
|
+
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
var readDefinition = function(TokeniseResult, k) {
|
|
var readDefinition = function(TokeniseResult, k) {
|
|
@@ -1697,7 +1780,6 @@ var readUrl = function(TokeniseResult, k) {
|
|
|
return null;
|
|
return null;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-
|
|
|
|
|
var InterpretTokens = function (TokeniseResult, ErrorReporter) {
|
|
var InterpretTokens = function (TokeniseResult, ErrorReporter) {
|
|
|
var Tokens = TokeniseResult.tokens;
|
|
var Tokens = TokeniseResult.tokens;
|
|
|
var linePosition = TokeniseResult.linePosition;
|
|
var linePosition = TokeniseResult.linePosition;
|
|
@@ -1706,11 +1788,30 @@ var InterpretTokens = function (TokeniseResult, ErrorReporter) {
|
|
|
|
|
|
|
|
var TokenErrorFromTo = ErrorReporter.TokenErrorFromTo;
|
|
var TokenErrorFromTo = ErrorReporter.TokenErrorFromTo;
|
|
|
var TokenError = ErrorReporter.TokenError;
|
|
var TokenError = ErrorReporter.TokenError;
|
|
|
- var Environments = [];
|
|
|
|
|
|
|
+ var Environments = new EnvHandler(ErrorReporter);
|
|
|
|
|
+
|
|
|
|
|
+ var nextGroupMathMode = null; // if the next group should have
|
|
|
|
|
+ var nextGroupMathModeStack = [] ; // tracking all nextGroupMathModes
|
|
|
|
|
+ var seenUserDefinedBeginEquation = false; // if we have seen macros like \beq
|
|
|
|
|
+ var seenUserDefinedEndEquation = false; // if we have seen macros like \eeq
|
|
|
|
|
|
|
|
for (var i = 0, len = Tokens.length; i < len; i++) {
|
|
for (var i = 0, len = Tokens.length; i < len; i++) {
|
|
|
var token = Tokens[i];
|
|
var token = Tokens[i];
|
|
|
var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
|
|
var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
|
|
|
|
|
+
|
|
|
|
|
+ if (type === "{") {
|
|
|
|
|
+ Environments.push({command:"{", token:token, mathMode: nextGroupMathMode});
|
|
|
|
|
+ nextGroupMathModeStack.push(nextGroupMathMode);
|
|
|
|
|
+ nextGroupMathMode = null;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ } else if (type === "}") {
|
|
|
|
|
+ Environments.push({command:"}", token:token});
|
|
|
|
|
+ nextGroupMathMode = nextGroupMathModeStack.pop();
|
|
|
|
|
+ continue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ nextGroupMathMode = null;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
if (type === "\\") {
|
|
if (type === "\\") {
|
|
|
if (seq === "begin" || seq === "end") {
|
|
if (seq === "begin" || seq === "end") {
|
|
|
var open = Tokens[i+1];
|
|
var open = Tokens[i+1];
|
|
@@ -1759,15 +1860,31 @@ var InterpretTokens = function (TokeniseResult, ErrorReporter) {
|
|
|
} else {
|
|
} else {
|
|
|
TokenError(token, "invalid environment command");
|
|
TokenError(token, "invalid environment command");
|
|
|
};
|
|
};
|
|
|
- }
|
|
|
|
|
- } else if (seq === "newcommand" || seq === "renewcommand" || seq === "def" || seq === "DeclareRobustCommand") {
|
|
|
|
|
- var newPos = read1arg(TokeniseResult, i, {allowStar: (seq != "def")});
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (typeof seq === "string" && seq.match(/^(be|beq|beqa|bea)$/i)) {
|
|
|
|
|
+ seenUserDefinedBeginEquation = true;
|
|
|
|
|
+ } else if (typeof seq === "string" && seq.match(/^(ee|eeq|eeqn|eeqa|eeqan|eea)$/i)) {
|
|
|
|
|
+ seenUserDefinedEndEquation = true;
|
|
|
|
|
+ } else if (seq === "newcommand" || seq === "renewcommand" || seq === "DeclareRobustCommand") {
|
|
|
|
|
+ var newPos = read1arg(TokeniseResult, i, {allowStar: true});
|
|
|
if (newPos === null) { continue; } else {i = newPos;};
|
|
if (newPos === null) { continue; } else {i = newPos;};
|
|
|
newPos = readOptionalParams(TokeniseResult, i);
|
|
newPos = readOptionalParams(TokeniseResult, i);
|
|
|
if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
newPos = readDefinition(TokeniseResult, i);
|
|
newPos = readDefinition(TokeniseResult, i);
|
|
|
if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
|
|
|
|
|
+ } else if (seq === "def") {
|
|
|
|
|
+ newPos = read1arg(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { continue; } else {i = newPos;};
|
|
|
|
|
+ newPos = readOptionalDef(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+
|
|
|
|
|
+ } else if (seq === "let") {
|
|
|
|
|
+ newPos = readLetDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { continue; } else {i = newPos;};
|
|
|
|
|
+
|
|
|
} else if (seq === "newcolumntype") {
|
|
} else if (seq === "newcolumntype") {
|
|
|
newPos = read1name(TokeniseResult, i);
|
|
newPos = read1name(TokeniseResult, i);
|
|
|
if (newPos === null) { continue; } else {i = newPos;};
|
|
if (newPos === null) { continue; } else {i = newPos;};
|
|
@@ -1791,128 +1908,435 @@ var InterpretTokens = function (TokeniseResult, ErrorReporter) {
|
|
|
} else if (seq === "url") {
|
|
} else if (seq === "url") {
|
|
|
newPos = readUrl(TokeniseResult, i);
|
|
newPos = readUrl(TokeniseResult, i);
|
|
|
if (newPos === null) { TokenError(token, "invalid url command"); } else {i = newPos;};
|
|
if (newPos === null) { TokenError(token, "invalid url command"); } else {i = newPos;};
|
|
|
|
|
+ } else if (seq === "left" || seq === "right") {
|
|
|
|
|
+ var nextToken = Tokens[i+1];
|
|
|
|
|
+ char = "";
|
|
|
|
|
+ if (nextToken && nextToken[1] === "Text") {
|
|
|
|
|
+ char = text.substring(nextToken[2], nextToken[2] + 1);
|
|
|
|
|
+ } else if (nextToken && nextToken[1] === "\\" && nextToken[5] == "control-symbol") {
|
|
|
|
|
+ char = nextToken[4];
|
|
|
|
|
+ } else if (nextToken && nextToken[1] === "\\") {
|
|
|
|
|
+ char = "unknown";
|
|
|
|
|
+ }
|
|
|
|
|
+ if (char === "" || (char !== "unknown" && "(){}[]<>/|\\.".indexOf(char) === -1)) {
|
|
|
|
|
+ TokenError(token, "invalid bracket command");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ i = i + 1;
|
|
|
|
|
+ Environments.push({command:seq, token:token});
|
|
|
|
|
+ };
|
|
|
|
|
+ } else if (seq === "(" || seq === ")" || seq === "[" || seq === "]") {
|
|
|
|
|
+ Environments.push({command:seq, token:token});
|
|
|
|
|
+ } else if (seq === "input") {
|
|
|
|
|
+ newPos = read1filename(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { continue; } else {i = newPos;};
|
|
|
|
|
+ } else if (seq === "hbox" || seq === "text" || seq === "mbox" || seq === "footnote" || seq === "intertext" || seq === "shortintertext" || seq === "textnormal" || seq === "tag" || seq === "reflectbox" || seq === "textrm") {
|
|
|
|
|
+ nextGroupMathMode = false;
|
|
|
|
|
+ } else if (seq === "rotatebox" || seq === "scalebox") {
|
|
|
|
|
+ newPos = readOptionalGeneric(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ nextGroupMathMode = false;
|
|
|
|
|
+ } else if (seq === "resizebox") {
|
|
|
|
|
+ newPos = readOptionalGeneric(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+
|
|
|
|
|
+ nextGroupMathMode = false;
|
|
|
|
|
+ } else if (seq === "DeclareMathOperator") {
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ } else if (seq === "DeclarePairedDelimiter") {
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ newPos = readDefinition(TokeniseResult, i);
|
|
|
|
|
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
|
|
|
|
|
+ } else if (typeof seq === "string" && seq.match(/^(alpha|beta|gamma|delta|epsilon|varepsilon|zeta|eta|theta|vartheta|iota|kappa|lambda|mu|nu|xi|pi|varpi|rho|varrho|sigma|varsigma|tau|upsilon|phi|varphi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)$/)) {
|
|
|
|
|
+ var currentMathMode = Environments.getMathMode() ; // returns null / $(inline) / $$(display)
|
|
|
|
|
+ if (currentMathMode === null) {
|
|
|
|
|
+ TokenError(token, type + seq + " must be inside math mode", {mathMode:true});
|
|
|
|
|
+ };
|
|
|
|
|
+ } else if (typeof seq === "string" && seq.match(/^(chapter|section|subsection|subsubsection)$/)) {
|
|
|
|
|
+ currentMathMode = Environments.getMathMode() ; // returns null / $(inline) / $$(display)
|
|
|
|
|
+ if (currentMathMode) {
|
|
|
|
|
+ TokenError(token, type + seq + " used inside math mode", {mathMode:true});
|
|
|
|
|
+ Environments.resetMathMode();
|
|
|
|
|
+ };
|
|
|
|
|
+ } else if (typeof seq === "string" && seq.match(/^[a-z]+$/)) {
|
|
|
|
|
+ nextGroupMathMode = undefined;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ } else if (type === "$") {
|
|
|
|
|
+ var lookAhead = Tokens[i+1];
|
|
|
|
|
+ var nextIsDollar = lookAhead && lookAhead[1] === "$";
|
|
|
|
|
+ currentMathMode = Environments.getMathMode() ; // returns null / $(inline) / $$(display)
|
|
|
|
|
+ if (nextIsDollar && (!currentMathMode || currentMathMode.command == "$$")) {
|
|
|
|
|
+ Environments.push({command:"$$", token:token});
|
|
|
|
|
+ i = i + 1;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Environments.push({command:"$", token:token});
|
|
|
}
|
|
}
|
|
|
- } else if (type === "{") {
|
|
|
|
|
- Environments.push({command:"{", token:token});
|
|
|
|
|
- } else if (type === "}") {
|
|
|
|
|
- Environments.push({command:"}", token:token});
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ } else if (type === "^" || type === "_") {
|
|
|
|
|
+ currentMathMode = Environments.getMathMode() ; // returns null / $(inline) / $$(display)
|
|
|
|
|
+ var insideGroup = Environments.insideGroup(); // true if inside {....}
|
|
|
|
|
+ if (currentMathMode === null && !insideGroup) {
|
|
|
|
|
+ TokenError(token, type + " must be inside math mode", {mathMode:true});
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (seenUserDefinedBeginEquation && seenUserDefinedEndEquation) {
|
|
|
|
|
+ ErrorReporter.filterMath = true;
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
return Environments;
|
|
return Environments;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-var CheckEnvironments = function (Environments, ErrorReporter) {
|
|
|
|
|
|
|
+var EnvHandler = function (ErrorReporter) {
|
|
|
var ErrorTo = ErrorReporter.EnvErrorTo;
|
|
var ErrorTo = ErrorReporter.EnvErrorTo;
|
|
|
var ErrorFromTo = ErrorReporter.EnvErrorFromTo;
|
|
var ErrorFromTo = ErrorReporter.EnvErrorFromTo;
|
|
|
var ErrorFrom = ErrorReporter.EnvErrorFrom;
|
|
var ErrorFrom = ErrorReporter.EnvErrorFrom;
|
|
|
|
|
|
|
|
|
|
+ var envs = [];
|
|
|
|
|
+
|
|
|
var state = [];
|
|
var state = [];
|
|
|
var documentClosed = null;
|
|
var documentClosed = null;
|
|
|
var inVerbatim = false;
|
|
var inVerbatim = false;
|
|
|
var verbatimRanges = [];
|
|
var verbatimRanges = [];
|
|
|
- for (var i = 0, len = Environments.length; i < len; i++) {
|
|
|
|
|
- var name = Environments[i].name ;
|
|
|
|
|
- if (name && name.match(/^(verbatim|boxedverbatim|lstlisting|minted)$/)) {
|
|
|
|
|
- Environments[i].verbatim = true;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ this.Environments = envs;
|
|
|
|
|
+
|
|
|
|
|
+ this.push = function (newEnv) {
|
|
|
|
|
+ this.setEnvProps(newEnv);
|
|
|
|
|
+ this.checkAndUpdateState(newEnv);
|
|
|
|
|
+ envs.push(newEnv);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this._endVerbatim = function (thisEnv) {
|
|
|
|
|
+ var lastEnv = state.pop();
|
|
|
|
|
+ if (lastEnv && lastEnv.name === thisEnv.name) {
|
|
|
|
|
+ inVerbatim = false;
|
|
|
|
|
+ verbatimRanges.push({start: lastEnv.token[2], end: thisEnv.token[2]});
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(lastEnv) { state.push(lastEnv); } ;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- for (i = 0, len = Environments.length; i < len; i++) {
|
|
|
|
|
- var thisEnv = Environments[i];
|
|
|
|
|
- if(thisEnv.command === "begin" || thisEnv.command === "{") {
|
|
|
|
|
- if (inVerbatim) { continue; } // ignore anything in verbatim environments
|
|
|
|
|
- if (thisEnv.verbatim) {inVerbatim = true;};
|
|
|
|
|
- state.push(thisEnv);
|
|
|
|
|
- } else if (thisEnv.command === "end" || thisEnv.command === "}") {
|
|
|
|
|
- var lastEnv = state.pop();
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- if (inVerbatim) {
|
|
|
|
|
- if (lastEnv && lastEnv.name === thisEnv.name) {
|
|
|
|
|
- inVerbatim = false;
|
|
|
|
|
- verbatimRanges.push({start: lastEnv.token[2], end: thisEnv.token[2]});
|
|
|
|
|
- continue;
|
|
|
|
|
- } else {
|
|
|
|
|
- if(lastEnv) { state.push(lastEnv); } ;
|
|
|
|
|
- continue; // ignore all other commands
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ var invalidEnvs = [];
|
|
|
|
|
+
|
|
|
|
|
+ this._end = function (thisEnv) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ var lastEnv = state.pop();
|
|
|
|
|
+ var retry = false;
|
|
|
|
|
+ var i;
|
|
|
|
|
|
|
|
- if (lastEnv && lastEnv.command === "{" && thisEnv.command === "}") {
|
|
|
|
|
- continue;
|
|
|
|
|
- } else if (lastEnv && lastEnv.name === thisEnv.name) {
|
|
|
|
|
- if (thisEnv.name === "document" && !documentClosed) {
|
|
|
|
|
|
|
+ if (closedBy(lastEnv, thisEnv)) {
|
|
|
|
|
+ if (thisEnv.command === "end" && thisEnv.name === "document" && !documentClosed) {
|
|
|
documentClosed = thisEnv;
|
|
documentClosed = thisEnv;
|
|
|
};
|
|
};
|
|
|
- continue;
|
|
|
|
|
|
|
+ return;
|
|
|
} else if (!lastEnv) {
|
|
} else if (!lastEnv) {
|
|
|
- if (thisEnv.command === "}") {
|
|
|
|
|
- if (documentClosed) {
|
|
|
|
|
- ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected end group }",{errorAtStart: true, type: "info"});
|
|
|
|
|
- } else {
|
|
|
|
|
- ErrorTo(thisEnv, "unexpected end group }");
|
|
|
|
|
- };
|
|
|
|
|
- } else if (thisEnv.command === "end") {
|
|
|
|
|
- if (documentClosed) {
|
|
|
|
|
- ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected content",{errorAtStart: true, type: "info"});
|
|
|
|
|
- } else {
|
|
|
|
|
- ErrorTo(thisEnv, "unexpected \\end{" + thisEnv.name + "}");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } else if (lastEnv.command === "begin" && thisEnv.command === "}") {
|
|
|
|
|
- ErrorFromTo(lastEnv, thisEnv, "unexpected end group } after \\begin{" + lastEnv.name +"}");
|
|
|
|
|
- state.push(lastEnv);
|
|
|
|
|
- } else if (lastEnv.command === "{" && thisEnv.command === "end") {
|
|
|
|
|
- ErrorFromTo(lastEnv, thisEnv,
|
|
|
|
|
- "unclosed group { found at \\end{" + thisEnv.name + "}",
|
|
|
|
|
- {suppressIfEditing:true, errorAtStart: true, type:"warning"});
|
|
|
|
|
- i--;
|
|
|
|
|
- } else if (lastEnv.command === "begin" && thisEnv.command === "end") {
|
|
|
|
|
- ErrorFromTo(lastEnv, thisEnv,
|
|
|
|
|
- "unclosed \\begin{" + lastEnv.name + "} found at \\end{" + thisEnv.name + "} " ,
|
|
|
|
|
- {errorAtStart: true});
|
|
|
|
|
- for (var j = i + 1; j < len; j++) {
|
|
|
|
|
- var futureEnv = Environments[j];
|
|
|
|
|
- if (futureEnv.command === "end" && futureEnv.name === lastEnv.name) {
|
|
|
|
|
- state.push(lastEnv);
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (documentClosed) {
|
|
|
|
|
+ ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected content",{errorAtStart: true, type: "info"});
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ErrorTo(thisEnv, "unexpected " + getName(thisEnv));
|
|
|
}
|
|
}
|
|
|
- lastEnv = state.pop();
|
|
|
|
|
- if(lastEnv) {
|
|
|
|
|
- if (thisEnv.name === lastEnv.name) {
|
|
|
|
|
- continue;
|
|
|
|
|
- } else {
|
|
|
|
|
- state.push(lastEnv);
|
|
|
|
|
|
|
+ } else if (invalidEnvs.length > 0 && (i = indexOfClosingEnvInArray(invalidEnvs, thisEnv) > -1)) {
|
|
|
|
|
+ invalidEnvs.splice(i, 1);
|
|
|
|
|
+ if (lastEnv) { state.push(lastEnv); } ;
|
|
|
|
|
+ return;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ var status = reportError(lastEnv, thisEnv);
|
|
|
|
|
+ if (envPrecedence(lastEnv) < envPrecedence(thisEnv)) {
|
|
|
|
|
+ invalidEnvs.push(lastEnv);
|
|
|
|
|
+ retry = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ var prevLastEnv = state.pop();
|
|
|
|
|
+ if(prevLastEnv) {
|
|
|
|
|
+ if (thisEnv.name === prevLastEnv.name) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ state.push(prevLastEnv);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ invalidEnvs.push(lastEnv);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+ } while (retry === true);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var CLOSING_DELIMITER = {
|
|
|
|
|
+ "{" : "}",
|
|
|
|
|
+ "left" : "right",
|
|
|
|
|
+ "[" : "]",
|
|
|
|
|
+ "(" : ")",
|
|
|
|
|
+ "$" : "$",
|
|
|
|
|
+ "$$": "$$"
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var closedBy = function (lastEnv, thisEnv) {
|
|
|
|
|
+ if (!lastEnv) {
|
|
|
|
|
+ return false ;
|
|
|
|
|
+ } else if (thisEnv.command === "end") {
|
|
|
|
|
+ return lastEnv.command === "begin" && lastEnv.name === thisEnv.name;
|
|
|
|
|
+ } else if (thisEnv.command === CLOSING_DELIMITER[lastEnv.command]) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var indexOfClosingEnvInArray = function (envs, thisEnv) {
|
|
|
|
|
+ for (var i = 0, n = envs.length; i < n ; i++) {
|
|
|
|
|
+ if (closedBy(envs[i], thisEnv)) {
|
|
|
|
|
+ return i;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- while (state.length > 0) {
|
|
|
|
|
- thisEnv = state.pop();
|
|
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var envPrecedence = function (env) {
|
|
|
|
|
+ var openScore = {
|
|
|
|
|
+ "{" : 1,
|
|
|
|
|
+ "left" : 2,
|
|
|
|
|
+ "$" : 3,
|
|
|
|
|
+ "$$" : 4,
|
|
|
|
|
+ "begin": 4
|
|
|
|
|
+ };
|
|
|
|
|
+ var closeScore = {
|
|
|
|
|
+ "}" : 1,
|
|
|
|
|
+ "right" : 2,
|
|
|
|
|
+ "$" : 3,
|
|
|
|
|
+ "$$" : 5,
|
|
|
|
|
+ "end": 4
|
|
|
|
|
+ };
|
|
|
|
|
+ if (env.command) {
|
|
|
|
|
+ return openScore[env.command] || closeScore[env.command];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var getName = function(env) {
|
|
|
|
|
+ var description = {
|
|
|
|
|
+ "{" : "open group {",
|
|
|
|
|
+ "}" : "close group }",
|
|
|
|
|
+ "[" : "open display math \\[",
|
|
|
|
|
+ "]" : "close display math \\]",
|
|
|
|
|
+ "(" : "open inline math \\(",
|
|
|
|
|
+ ")" : "close inline math \\)",
|
|
|
|
|
+ "$" : "$",
|
|
|
|
|
+ "$$" : "$$",
|
|
|
|
|
+ "left" : "\\left",
|
|
|
|
|
+ "right" : "\\right"
|
|
|
|
|
+ };
|
|
|
|
|
+ if (env.command === "begin" || env.command === "end") {
|
|
|
|
|
+ return "\\" + env.command + "{" + env.name + "}";
|
|
|
|
|
+ } else if (env.command in description) {
|
|
|
|
|
+ return description[env.command];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return env.command;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var EXTRA_CLOSE = 1;
|
|
|
|
|
+ var UNCLOSED_GROUP = 2;
|
|
|
|
|
+ var UNCLOSED_ENV = 3;
|
|
|
|
|
+
|
|
|
|
|
+ var reportError = function(lastEnv, thisEnv) {
|
|
|
|
|
+ if (!lastEnv) { // unexpected close, nothing was open!
|
|
|
|
|
+ if (documentClosed) {
|
|
|
|
|
+ ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected end group }",{errorAtStart: true, type: "info"});
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ErrorTo(thisEnv, "unexpected " + getName(thisEnv));
|
|
|
|
|
+ };
|
|
|
|
|
+ return EXTRA_CLOSE;
|
|
|
|
|
+ } else if (lastEnv.command === "{" && thisEnv.command === "end") {
|
|
|
|
|
+ ErrorFromTo(lastEnv, thisEnv, "unclosed " + getName(lastEnv) + " found at " + getName(thisEnv),
|
|
|
|
|
+ {suppressIfEditing:true, errorAtStart: true, type:"warning"});
|
|
|
|
|
+ return UNCLOSED_GROUP;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ var pLast = envPrecedence(lastEnv);
|
|
|
|
|
+ var pThis = envPrecedence(thisEnv);
|
|
|
|
|
+ if (pThis > pLast) {
|
|
|
|
|
+ ErrorFromTo(lastEnv, thisEnv, "unclosed " + getName(lastEnv) + " found at " + getName(thisEnv),
|
|
|
|
|
+ {suppressIfEditing:true, errorAtStart: true});
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ErrorFromTo(lastEnv, thisEnv, "unexpected " + getName(thisEnv) + " after " + getName(lastEnv));
|
|
|
|
|
+ }
|
|
|
|
|
+ return UNCLOSED_ENV;
|
|
|
|
|
+ };
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this._beginMathMode = function (thisEnv) {
|
|
|
|
|
+ var currentMathMode = this.getMathMode(); // undefined, null, $, $$, name of mathmode env
|
|
|
|
|
+ if (currentMathMode) {
|
|
|
|
|
+ ErrorFrom(thisEnv, thisEnv.name + " used inside existing math mode " + getName(currentMathMode),
|
|
|
|
|
+ {suppressIfEditing:true, errorAtStart: true, mathMode:true});
|
|
|
|
|
+ };
|
|
|
|
|
+ thisEnv.mathMode = thisEnv;
|
|
|
|
|
+ state.push(thisEnv);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this._toggleMathMode = function (thisEnv) {
|
|
|
|
|
+ var lastEnv = state.pop();
|
|
|
|
|
+ if (closedBy(lastEnv, thisEnv)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (lastEnv) {state.push(lastEnv);}
|
|
|
|
|
+ if (lastEnv && lastEnv.mathMode) {
|
|
|
|
|
+ this._end(thisEnv);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ thisEnv.mathMode = thisEnv;
|
|
|
|
|
+ state.push(thisEnv);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this.getMathMode = function () {
|
|
|
|
|
+ var n = state.length;
|
|
|
|
|
+ if (n > 0) {
|
|
|
|
|
+ return state[n-1].mathMode;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this.insideGroup = function () {
|
|
|
|
|
+ var n = state.length;
|
|
|
|
|
+ if (n > 0) {
|
|
|
|
|
+ return (state[n-1].command === "{");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ var resetMathMode = function () {
|
|
|
|
|
+ var n = state.length;
|
|
|
|
|
+ if (n > 0) {
|
|
|
|
|
+ var lastMathMode = state[n-1].mathMode;
|
|
|
|
|
+ do {
|
|
|
|
|
+ var lastEnv = state.pop();
|
|
|
|
|
+ } while (lastEnv && lastEnv !== lastMathMode);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this.resetMathMode = resetMathMode;
|
|
|
|
|
+
|
|
|
|
|
+ var getNewMathMode = function (currentMathMode, thisEnv) {
|
|
|
|
|
+ var newMathMode = null;
|
|
|
|
|
+
|
|
|
if (thisEnv.command === "{") {
|
|
if (thisEnv.command === "{") {
|
|
|
- ErrorFrom(thisEnv, "unclosed group {", {type:"warning"});
|
|
|
|
|
|
|
+ if (thisEnv.mathMode !== null) {
|
|
|
|
|
+ newMathMode = thisEnv.mathMode;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ newMathMode = currentMathMode;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (thisEnv.command === "left") {
|
|
|
|
|
+ if (currentMathMode === null) {
|
|
|
|
|
+ ErrorFrom(thisEnv, "\\left can only be used in math mode", {mathMode: true});
|
|
|
|
|
+ };
|
|
|
|
|
+ newMathMode = currentMathMode;
|
|
|
} else if (thisEnv.command === "begin") {
|
|
} else if (thisEnv.command === "begin") {
|
|
|
- ErrorFrom(thisEnv, "unclosed environment \\begin{" + thisEnv.name + "}");
|
|
|
|
|
|
|
+ var name = thisEnv.name;
|
|
|
|
|
+ if (name) {
|
|
|
|
|
+ if (name.match(/^(document|figure|center|enumerate|itemize|table|abstract|proof|lemma|theorem|definition|proposition|corollary|remark|notation|thebibliography)$/)) {
|
|
|
|
|
+ if (currentMathMode) {
|
|
|
|
|
+ ErrorFromTo(currentMathMode, thisEnv, thisEnv.name + " used inside " + getName(currentMathMode),
|
|
|
|
|
+ {suppressIfEditing:true, errorAtStart: true, mathMode: true});
|
|
|
|
|
+ resetMathMode();
|
|
|
|
|
+ };
|
|
|
|
|
+ newMathMode = null;
|
|
|
|
|
+ } else if (name.match(/^(array|gathered|split|aligned|alignedat)\*?$/)) {
|
|
|
|
|
+ if (currentMathMode === null) {
|
|
|
|
|
+ ErrorFrom(thisEnv, thisEnv.name + " not inside math mode", {mathMode: true});
|
|
|
|
|
+ };
|
|
|
|
|
+ newMathMode = currentMathMode;
|
|
|
|
|
+ } else if (name.match(/^(math|displaymath|equation|eqnarray|multline|align|gather|flalign|alignat)\*?$/)) {
|
|
|
|
|
+ if (currentMathMode) {
|
|
|
|
|
+ ErrorFromTo(currentMathMode, thisEnv, thisEnv.name + " used inside " + getName(currentMathMode),
|
|
|
|
|
+ {suppressIfEditing:true, errorAtStart: true, mathMode: true});
|
|
|
|
|
+ resetMathMode();
|
|
|
|
|
+ };
|
|
|
|
|
+ newMathMode = thisEnv;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ newMathMode = undefined; // undefined means we don't know if we are in math mode or not
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
- }
|
|
|
|
|
- var vlen = verbatimRanges.length;
|
|
|
|
|
- len = ErrorReporter.tokenErrors.length;
|
|
|
|
|
- if (vlen >0 && len > 0) {
|
|
|
|
|
- for (i = 0; i < len; i++) {
|
|
|
|
|
- var tokenError = ErrorReporter.tokenErrors[i];
|
|
|
|
|
- var startPos = tokenError.startPos;
|
|
|
|
|
- var endPos = tokenError.endPos;
|
|
|
|
|
- for (j = 0; j < vlen; j++) {
|
|
|
|
|
- if (startPos > verbatimRanges[j].start && startPos < verbatimRanges[j].end) {
|
|
|
|
|
- tokenError.ignore = true;
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ return newMathMode;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this.checkAndUpdateState = function (thisEnv) {
|
|
|
|
|
+ if (inVerbatim) {
|
|
|
|
|
+ if (thisEnv.command === "end") {
|
|
|
|
|
+ this._endVerbatim(thisEnv);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return; // ignore anything in verbatim environments
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(thisEnv.command === "begin" || thisEnv.command === "{" || thisEnv.command === "left") {
|
|
|
|
|
+ if (thisEnv.verbatim) {inVerbatim = true;};
|
|
|
|
|
+ var currentMathMode = this.getMathMode(); // undefined, null, $, $$, name of mathmode env
|
|
|
|
|
+ var newMathMode = getNewMathMode(currentMathMode, thisEnv);
|
|
|
|
|
+ thisEnv.mathMode = newMathMode;
|
|
|
|
|
+ state.push(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === "end") {
|
|
|
|
|
+ this._end(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === "(" || thisEnv.command === "[") {
|
|
|
|
|
+ this._beginMathMode(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === ")" || thisEnv.command === "]") {
|
|
|
|
|
+ this._end(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === "}") {
|
|
|
|
|
+ this._end(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === "right") {
|
|
|
|
|
+ this._end(thisEnv);
|
|
|
|
|
+ } else if (thisEnv.command === "$" || thisEnv.command === "$$") {
|
|
|
|
|
+ this._toggleMathMode(thisEnv);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ this.close = function () {
|
|
|
|
|
+ while (state.length > 0) {
|
|
|
|
|
+ var thisEnv = state.pop();
|
|
|
|
|
+ if (thisEnv.command === "{") {
|
|
|
|
|
+ ErrorFrom(thisEnv, "unclosed group {", {type:"warning"});
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ErrorFrom(thisEnv, "unclosed " + getName(thisEnv));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ var vlen = verbatimRanges.length;
|
|
|
|
|
+ var len = ErrorReporter.tokenErrors.length;
|
|
|
|
|
+ if (vlen >0 && len > 0) {
|
|
|
|
|
+ for (var i = 0; i < len; i++) {
|
|
|
|
|
+ var tokenError = ErrorReporter.tokenErrors[i];
|
|
|
|
|
+ var startPos = tokenError.startPos;
|
|
|
|
|
+ var endPos = tokenError.endPos;
|
|
|
|
|
+ for (var j = 0; j < vlen; j++) {
|
|
|
|
|
+ if (startPos > verbatimRanges[j].start && startPos < verbatimRanges[j].end) {
|
|
|
|
|
+ tokenError.ignore = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
|
|
+ this.setEnvProps = function (env) {
|
|
|
|
|
+ var name = env.name ;
|
|
|
|
|
+ if (name && name.match(/^(verbatim|boxedverbatim|lstlisting|minted|Verbatim)$/)) {
|
|
|
|
|
+ env.verbatim = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
};
|
|
};
|
|
|
var ErrorReporter = function (TokeniseResult) {
|
|
var ErrorReporter = function (TokeniseResult) {
|
|
|
var text = TokeniseResult.text;
|
|
var text = TokeniseResult.text;
|
|
@@ -1922,18 +2346,41 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
var errors = [], tokenErrors = [];
|
|
var errors = [], tokenErrors = [];
|
|
|
this.errors = errors;
|
|
this.errors = errors;
|
|
|
this.tokenErrors = tokenErrors;
|
|
this.tokenErrors = tokenErrors;
|
|
|
|
|
+ this.filterMath = false;
|
|
|
|
|
|
|
|
this.getErrors = function () {
|
|
this.getErrors = function () {
|
|
|
var returnedErrors = [];
|
|
var returnedErrors = [];
|
|
|
for (var i = 0, len = tokenErrors.length; i < len; i++) {
|
|
for (var i = 0, len = tokenErrors.length; i < len; i++) {
|
|
|
if (!tokenErrors[i].ignore) { returnedErrors.push(tokenErrors[i]); }
|
|
if (!tokenErrors[i].ignore) { returnedErrors.push(tokenErrors[i]); }
|
|
|
}
|
|
}
|
|
|
- return returnedErrors.concat(errors);
|
|
|
|
|
|
|
+ var allErrors = returnedErrors.concat(errors);
|
|
|
|
|
+ var result = [];
|
|
|
|
|
+ var mathErrorCount = 0;
|
|
|
|
|
+ for (i = 0, len = allErrors.length; i < len; i++) {
|
|
|
|
|
+ if (allErrors[i].mathMode) {
|
|
|
|
|
+ mathErrorCount++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (mathErrorCount > 10) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.filterMath && mathErrorCount > 0) {
|
|
|
|
|
+ for (i = 0, len = allErrors.length; i < len; i++) {
|
|
|
|
|
+ if (!allErrors[i].mathMode) {
|
|
|
|
|
+ result.push(allErrors[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return allErrors;
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- this.TokenError = function (token, message) {
|
|
|
|
|
|
|
+ this.TokenError = function (token, message, options) {
|
|
|
|
|
+ if(!options) { options = { suppressIfEditing:true } ; };
|
|
|
var line = token[0], type = token[1], start = token[2], end = token[3];
|
|
var line = token[0], type = token[1], start = token[2], end = token[3];
|
|
|
var start_col = start - linePosition[line];
|
|
var start_col = start - linePosition[line];
|
|
|
|
|
+ if (!end) { end = start + 1; } ;
|
|
|
var end_col = end - linePosition[line];
|
|
var end_col = end - linePosition[line];
|
|
|
tokenErrors.push({row: line,
|
|
tokenErrors.push({row: line,
|
|
|
column: start_col,
|
|
column: start_col,
|
|
@@ -1945,10 +2392,12 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
text:message,
|
|
text:message,
|
|
|
startPos: start,
|
|
startPos: start,
|
|
|
endPos: end,
|
|
endPos: end,
|
|
|
- suppressIfEditing:true});
|
|
|
|
|
|
|
+ suppressIfEditing:options.suppressIfEditing,
|
|
|
|
|
+ mathMode: options.mathMode});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- this.TokenErrorFromTo = function (fromToken, toToken, message) {
|
|
|
|
|
|
|
+ this.TokenErrorFromTo = function (fromToken, toToken, message, options) {
|
|
|
|
|
+ if(!options) { options = {suppressIfEditing:true } ; };
|
|
|
var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3];
|
|
var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3];
|
|
|
var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3];
|
|
var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3];
|
|
|
if (!toEnd) { toEnd = toStart + 1;};
|
|
if (!toEnd) { toEnd = toStart + 1;};
|
|
@@ -1965,7 +2414,8 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
text:message,
|
|
text:message,
|
|
|
startPos: fromStart,
|
|
startPos: fromStart,
|
|
|
endPos: toEnd,
|
|
endPos: toEnd,
|
|
|
- suppressIfEditing:true});
|
|
|
|
|
|
|
+ suppressIfEditing:options.suppressIfEditing,
|
|
|
|
|
+ mathMode: options.mathMode});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1986,7 +2436,8 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
end_col: end_col,
|
|
end_col: end_col,
|
|
|
type: options.type ? options.type : "error",
|
|
type: options.type ? options.type : "error",
|
|
|
text:message,
|
|
text:message,
|
|
|
- suppressIfEditing:options.suppressIfEditing});
|
|
|
|
|
|
|
+ suppressIfEditing:options.suppressIfEditing,
|
|
|
|
|
+ mathMode: options.mathMode});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
this.EnvErrorTo = function (toEnv, message, options) {
|
|
this.EnvErrorTo = function (toEnv, message, options) {
|
|
@@ -2002,7 +2453,8 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
end_row: line,
|
|
end_row: line,
|
|
|
end_col: end_col,
|
|
end_col: end_col,
|
|
|
type: options.type ? options.type : "error",
|
|
type: options.type ? options.type : "error",
|
|
|
- text:message};
|
|
|
|
|
|
|
+ text:message,
|
|
|
|
|
+ mathMode: options.mathMode};
|
|
|
errors.push(err);
|
|
errors.push(err);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -2019,7 +2471,8 @@ var ErrorReporter = function (TokeniseResult) {
|
|
|
end_row: lineNumber,
|
|
end_row: lineNumber,
|
|
|
end_col: end_col,
|
|
end_col: end_col,
|
|
|
type: options.type ? options.type : "error",
|
|
type: options.type ? options.type : "error",
|
|
|
- text:message});
|
|
|
|
|
|
|
+ text:message,
|
|
|
|
|
+ mathMode: options.mathMode});
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -2027,7 +2480,7 @@ var Parse = function (text) {
|
|
|
var TokeniseResult = Tokenise(text);
|
|
var TokeniseResult = Tokenise(text);
|
|
|
var Reporter = new ErrorReporter(TokeniseResult);
|
|
var Reporter = new ErrorReporter(TokeniseResult);
|
|
|
var Environments = InterpretTokens(TokeniseResult, Reporter);
|
|
var Environments = InterpretTokens(TokeniseResult, Reporter);
|
|
|
- CheckEnvironments(Environments, Reporter);
|
|
|
|
|
|
|
+ Environments.close();
|
|
|
return Reporter.getErrors();
|
|
return Reporter.getErrors();
|
|
|
};
|
|
};
|
|
|
|
|
|