Re-implement MD038 to handle multi-line spans better and rely less on RegExp.

This commit is contained in:
David Anson 2019-01-30 22:09:20 -08:00
parent 3b49414183
commit ff50da3b42
7 changed files with 235 additions and 40 deletions

View file

@ -239,6 +239,69 @@ module.exports.forEachHeading = function forEachHeading(params, callback) {
});
};
// Calls the provided function for each inline code span's content
module.exports.forEachInlineCodeSpan =
function forEachInlineCodeSpan(input, callback) {
let currentLine = 0;
let currentColumn = 0;
let index = 0;
while (index < input.length) {
let startIndex = -1;
let startLine = -1;
let startColumn = -1;
let tickCount = 0;
let currentTicks = 0;
// Deliberate <= so trailing 0 completes the last span (ex: "text `code`")
for (; index <= input.length; index++) {
const char = input[index];
if (char === "`") {
// Count backticks at start or end of code span
currentTicks++;
if ((startIndex === -1) || (startColumn === -1)) {
startIndex = index + 1;
}
} else {
if ((startIndex >= 0) &&
(startColumn >= 0) &&
(tickCount === currentTicks)) {
// Found end backticks; invoke callback for code span
callback(
input.substring(startIndex, index - currentTicks),
startLine, startColumn, tickCount);
startIndex = -1;
startColumn = -1;
} else if ((startIndex >= 0) && (startColumn === -1)) {
// Found start backticks
tickCount = currentTicks;
startLine = currentLine;
startColumn = currentColumn;
}
// Not in backticks
currentTicks = 0;
}
if (char === "\n") {
// On next line
currentLine++;
currentColumn = 0;
} else if ((char === "\\") &&
((startIndex === -1) || (startColumn === -1))) {
// Escape character outside code, skip next
index++;
currentColumn += 2;
} else {
// On next column
currentColumn++;
}
}
if (startIndex >= 0) {
// Restart loop after unmatched start backticks (ex: "`text``code``")
index = startIndex;
currentLine = startLine;
currentColumn = startColumn;
}
}
};
// Returns (nested) lists as a flat array (in order)
module.exports.flattenLists = function flattenLists() {
return tokenCache.flattenedLists;