Add MD037 with tests, improve handling of line numbers for inlines.

This commit is contained in:
David Anson 2015-04-15 17:50:01 -07:00
parent bd7e712728
commit b85e53a9c4
6 changed files with 108 additions and 21 deletions

View file

@ -67,6 +67,7 @@ cases come directly from that project.
* **MD034** - Bare URL used
* **MD035** - Horizontal rule style
* **MD036** - Emphasis used instead of a header
* **MD037** - Spaces inside emphasis markers
See [Rules.md](doc/Rules.md) for more details.
@ -78,7 +79,7 @@ See [Rules.md](doc/Rules.md) for more details.
* **blockquote** - MD027, MD028
* **bullet** - MD004, MD005, MD006, MD007, MD032
* **code** - MD014, MD031
* **emphasis** - MD036
* **emphasis** - MD036, MD037
* **hard_tab** - MD010
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
MD024, MD025, MD026, MD036
@ -91,7 +92,7 @@ See [Rules.md](doc/Rules.md) for more details.
* **spaces** - MD018, MD019, MD020, MD021, MD023
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
* **url** - MD034
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037
## API

View file

@ -794,3 +794,33 @@ sections:
Note: this rule looks for paragraphs that consist entirely of emphasized text.
It won't fire on emphasis used within regular text.
## MD037 - Spaces inside emphasis markers
Tags: whitespace, emphasis
This rule is triggered when emphasis markers (bold, italic) are used, but they
have spaces between the markers and the text:
Here is some ** bold ** text.
Here is some * italic * text.
Here is some more __ bold __ text.
Here is some more _ italic _ text.
To fix this, remove the spaces around the emphasis markers:
Here is some **bold** text.
Here is some *italic* text.
Here is some more __bold__ text.
Here is some more _italic_ text.
Rationale: Emphasis is only parsed as such when the asterisks/underscores
aren't completely surrounded by spaces. This rule attempts to detect where
they were surrounded by spaces, but it appears that emphasized text was
intended by the author.

View file

@ -72,6 +72,14 @@ function lintFile(file, config, synchronous, callback) {
while (!(lines[token.map[1] - 1].trim())) {
token.map[1]--;
}
// Annotate children with lineNumber
var lineNumber = token.lineNumber;
(token.children || []).forEach(function forChild(child) {
child.lineNumber = lineNumber;
if ((child.type === "softbreak") || (child.type === "hardbreak")) {
lineNumber++;
}
});
}
});
// Create parameters for rules

View file

@ -60,6 +60,15 @@ function forEachLine(params, callback) {
});
}
// Calls the provided function for each text token
function forEachText(params, callback) {
filterTokens(params.tokens, "inline")
.forEach(function forToken(token) {
filterTokens(token.children, "text")
.forEach(callback);
});
}
// Calls the provided function for each heading's content
function forEachHeading(params, callback) {
var heading = null;
@ -266,15 +275,11 @@ module.exports = [
"desc": "Reversed link syntax",
"tags": [ "links" ],
"func": function MD011(params, errors) {
filterTokens(params.tokens, "inline")
.forEach(function forToken(token) {
filterTokens(token.children, "text")
.forEach(function forChild(child) {
if (/\([^)]+\)\[[^\]]+\]/.test(child.content)) {
forEachText(params, function forToken(token) {
if (/\([^)]+\)\[[^\]]+\]/.test(token.content)) {
errors.push(token.lineNumber);
}
});
});
}
},
@ -631,7 +636,6 @@ module.exports = [
"func": function MD034(params, errors) {
filterTokens(params.tokens, "inline")
.forEach(function forToken(token) {
var lineNumber = token.lineNumber;
var inLink = false;
token.children.forEach(function forChild(child) {
if (child.type === "link_open") {
@ -641,10 +645,7 @@ module.exports = [
} else if ((child.type === "text") &&
!inLink &&
/https?:\/\//.test(child.content)) {
errors.push(lineNumber);
} else if ((child.type === "softbreak") ||
(child.type === "hardbreak")) {
lineNumber++;
errors.push(child.lineNumber);
}
});
});
@ -674,9 +675,7 @@ module.exports = [
"desc": "Emphasis used instead of a header",
"tags": [ "headers", "emphasis" ],
"func": function MD036(params, errors) {
var lineNumber = 0;
function base(token) {
lineNumber = token.lineNumber;
if (token.type === "paragraph_open") {
return function inParagraph(t) {
if ((t.type === "inline") &&
@ -684,7 +683,7 @@ module.exports = [
((t.children[0].type === "strong_open") ||
(t.children[0].type === "em_open")) &&
(t.children[1].type === "text")) {
errors.push(lineNumber);
errors.push(t.lineNumber);
}
};
} else if (token.type === "blockquote_open") {
@ -700,5 +699,19 @@ module.exports = [
state = state(token) || base;
});
}
},
{
"name": "MD037",
"desc": "Spaces inside emphasis markers",
"tags": [ "whitespace", "emphasis" ],
"func": function MD037(params, errors) {
forEachText(params, function forToken(token) {
if (/\s(\*\*?|__?)\s.+\1/.test(token.content) ||
/(\*\*?|__?).+\s\1\s/.test(token.content)) {
errors.push(token.lineNumber);
}
});
}
}
];

View file

@ -498,7 +498,7 @@ module.exports.badFileSync = function badFileSync(test) {
};
module.exports.readme = function readme(test) {
test.expect(86);
test.expect(88);
var tagToRules = {};
rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) {
@ -555,7 +555,7 @@ module.exports.readme = function readme(test) {
};
module.exports.doc = function doc(test) {
test.expect(131);
test.expect(135);
fs.readFile("doc/Rules.md", shared.utf8Encoding,
function readFile(err, contents) {
test.ifError(err);

View file

@ -0,0 +1,35 @@
Line with *Normal emphasis*
Line with **Normal strong**
Line with _Normal emphasis_
Line with __Normal strong__
Broken * emphasis * with spaces in {MD037}
Broken ** strong ** with spaces in {MD037}
Broken _ emphasis _ with spaces in {MD037}
Broken __ strong __ with spaces in {MD037}
Mixed *ok emphasis* and * broken emphasis * {MD037}
Mixed **ok strong** and ** broken strong ** {MD037}
Mixed _ok emphasis_ and _ broken emphasis _ {MD037}
Mixed __ok strong__ and __ broken strong __ {MD037}
Mixed *ok emphasis* **ok strong** * broken emphasis * {MD037}
Multiple * broken emphasis * _ broken emphasis _ {MD037}
One-sided *broken emphasis * {MD037}
One-sided * broken emphasis* {MD037}
Don't _flag on _words with underscores before them.
The same goes for words* with asterisks* after them.