Update MD037/no-space-in-emphasis to avoid crash, handle more scenarios.

This commit is contained in:
David Anson 2020-04-11 12:33:28 -07:00
parent a0afba972c
commit 5c60e00a90
3 changed files with 58 additions and 24 deletions

View file

@ -29,34 +29,31 @@ module.exports = {
let match = null;
let emphasisIndex = -1;
let emphasisLength = 0;
let effectiveEmphasisLength = 0;
// Match all emphasis-looking runs in the line...
while ((match = emphasisRe.exec(line))) {
const matchIndex = match.index + match[1].length;
const matchLength = match[0].length - match[1].length;
if (emphasisIndex === -1) {
// New run
emphasisIndex = matchIndex + matchLength;
emphasisLength = matchLength;
emphasisIndex = matchIndex + emphasisLength;
} else {
// Already in a run
if (matchLength !== emphasisLength) {
// Looks like a run within a run, reset to embedded run
emphasisLength += matchLength;
emphasisIndex = matchIndex + emphasisLength;
}
// Extract emphasized content
effectiveEmphasisLength = matchLength;
} else if (matchLength === effectiveEmphasisLength) {
// Close current run
const content = line.substring(emphasisIndex, matchIndex);
const leftSpace = leftSpaceRe.test(content);
const rightSpace = rightSpaceRe.test(content);
if (leftSpace || rightSpace) {
// Report the violation
const contextStart = emphasisIndex - emphasisLength;
const contextEnd = matchIndex + emphasisLength;
const contextEnd = matchIndex + effectiveEmphasisLength;
const context = line.substring(contextStart, contextEnd);
const column = contextStart + 1;
const length = contextEnd - contextStart;
const marker = match[2] || match[3];
const fixedText = `${marker}${content.trim()}${marker}`;
const leftMarker = line.substring(contextStart, emphasisIndex);
const rightMarker = match[2] || match[3];
const fixedText = `${leftMarker}${content.trim()}${rightMarker}`;
addErrorContext(
onError,
lineIndex + 1,
@ -71,11 +68,19 @@ module.exports = {
}
);
}
// Update the run
emphasisLength -= matchLength;
if (!emphasisLength) {
// Reset
emphasisIndex = -1;
}
emphasisLength = 0;
effectiveEmphasisLength = 0;
} else if (matchLength === 3) {
// Swap internal run length (1->2 or 2->1)
effectiveEmphasisLength = matchLength - effectiveEmphasisLength;
} else if (effectiveEmphasisLength === 3) {
// Downgrade internal run (3->1 or 3->2)
effectiveEmphasisLength -= matchLength;
} else {
// Upgrade to internal run (1->3 or 2->3)
effectiveEmphasisLength += matchLength;
}
}
}

View file

@ -18,16 +18,16 @@ Escaped underscores _ should \_ be ignored by MD037.
## Double-character markers, start
All should be reported because they are valid single-character
marker emphasis without spaces.
All *could* be reported because they are valid single-character
marker emphasis when no spaces are present.
Escaped asterisks \** should ** be ignored by MD037. {MD037}
Escaped asterisks \** should ** be ignored by MD037.
Escaped asterisks *\* should ** be ignored by MD037. {MD037}
Escaped asterisks *\* should ** be ignored by MD037.
Escaped underscores \__ should __ be ignored by MD037. {MD037}
Escaped underscores \__ should __ be ignored by MD037.
Escaped underscores _\_ should __ be ignored by MD037. {MD037}
Escaped underscores _\_ should __ be ignored by MD037.
## Double-character markers, end

View file

@ -115,13 +115,42 @@ This is * an ambiguous * scenario {MD037}
with *space * problems {MD037}
throughout * the * content {MD037}
Uncommon scenarios from the CommonMark specification:
Uncommon scenarios from the CommonMark specification (and some variations):
***strong emph***
***strong** in emph*
***emph* in strong**
**in strong *emph***
*in emph **strong***
*** strong emph*** {MD037}
*** strong** in emph* {MD037}
*** emph* in strong** {MD037}
** in strong *emph*** {MD037}
***strong emph *** {MD037}
***strong** in emph * {MD037}
***emph* in strong ** {MD037}
**in strong *emph *** {MD037}
*in emph **strong *** {MD037}
** *strong emph*** {MD037}
** *strong** in emph* {MD037}
** *emph* in strong** {MD037}
**in strong * emph*** (internal spaces are not detected)
*in emph ** strong*** (internal spaces are not detected)
***strong emph* ** {MD037}
***strong ** in emph* (internal spaces are not detected)
***emph * in strong** (internal spaces are not detected)
**in strong *emph* ** {MD037}
*in emph **strong* ** {MD037}
Text *emph***strong** text
Text * emph***strong** text {MD037}
Text *emph ***strong** text (internal spaces are not detected)
Text *emph*** strong** text (internal spaces are not detected)
Text *emph***strong ** text {MD037}
```markdown
Violations * are * allowed in code blocks where emphasis does not apply.
```