mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Add MD037 with tests, improve handling of line numbers for inlines.
This commit is contained in:
parent
bd7e712728
commit
b85e53a9c4
6 changed files with 108 additions and 21 deletions
|
@ -67,6 +67,7 @@ cases come directly from that project.
|
||||||
* **MD034** - Bare URL used
|
* **MD034** - Bare URL used
|
||||||
* **MD035** - Horizontal rule style
|
* **MD035** - Horizontal rule style
|
||||||
* **MD036** - Emphasis used instead of a header
|
* **MD036** - Emphasis used instead of a header
|
||||||
|
* **MD037** - Spaces inside emphasis markers
|
||||||
|
|
||||||
See [Rules.md](doc/Rules.md) for more details.
|
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
|
* **blockquote** - MD027, MD028
|
||||||
* **bullet** - MD004, MD005, MD006, MD007, MD032
|
* **bullet** - MD004, MD005, MD006, MD007, MD032
|
||||||
* **code** - MD014, MD031
|
* **code** - MD014, MD031
|
||||||
* **emphasis** - MD036
|
* **emphasis** - MD036, MD037
|
||||||
* **hard_tab** - MD010
|
* **hard_tab** - MD010
|
||||||
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
||||||
MD024, MD025, MD026, MD036
|
MD024, MD025, MD026, MD036
|
||||||
|
@ -91,7 +92,7 @@ See [Rules.md](doc/Rules.md) for more details.
|
||||||
* **spaces** - MD018, MD019, MD020, MD021, MD023
|
* **spaces** - MD018, MD019, MD020, MD021, MD023
|
||||||
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
|
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
|
||||||
* **url** - MD034
|
* **url** - MD034
|
||||||
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030
|
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
|
30
doc/Rules.md
30
doc/Rules.md
|
@ -794,3 +794,33 @@ sections:
|
||||||
|
|
||||||
Note: this rule looks for paragraphs that consist entirely of emphasized text.
|
Note: this rule looks for paragraphs that consist entirely of emphasized text.
|
||||||
It won't fire on emphasis used within regular 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.
|
||||||
|
|
|
@ -72,6 +72,14 @@ function lintFile(file, config, synchronous, callback) {
|
||||||
while (!(lines[token.map[1] - 1].trim())) {
|
while (!(lines[token.map[1] - 1].trim())) {
|
||||||
token.map[1]--;
|
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
|
// Create parameters for rules
|
||||||
|
|
47
lib/rules.js
47
lib/rules.js
|
@ -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
|
// Calls the provided function for each heading's content
|
||||||
function forEachHeading(params, callback) {
|
function forEachHeading(params, callback) {
|
||||||
var heading = null;
|
var heading = null;
|
||||||
|
@ -266,15 +275,11 @@ module.exports = [
|
||||||
"desc": "Reversed link syntax",
|
"desc": "Reversed link syntax",
|
||||||
"tags": [ "links" ],
|
"tags": [ "links" ],
|
||||||
"func": function MD011(params, errors) {
|
"func": function MD011(params, errors) {
|
||||||
filterTokens(params.tokens, "inline")
|
forEachText(params, function forToken(token) {
|
||||||
.forEach(function forToken(token) {
|
if (/\([^)]+\)\[[^\]]+\]/.test(token.content)) {
|
||||||
filterTokens(token.children, "text")
|
errors.push(token.lineNumber);
|
||||||
.forEach(function forChild(child) {
|
}
|
||||||
if (/\([^)]+\)\[[^\]]+\]/.test(child.content)) {
|
});
|
||||||
errors.push(token.lineNumber);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -631,7 +636,6 @@ module.exports = [
|
||||||
"func": function MD034(params, errors) {
|
"func": function MD034(params, errors) {
|
||||||
filterTokens(params.tokens, "inline")
|
filterTokens(params.tokens, "inline")
|
||||||
.forEach(function forToken(token) {
|
.forEach(function forToken(token) {
|
||||||
var lineNumber = token.lineNumber;
|
|
||||||
var inLink = false;
|
var inLink = false;
|
||||||
token.children.forEach(function forChild(child) {
|
token.children.forEach(function forChild(child) {
|
||||||
if (child.type === "link_open") {
|
if (child.type === "link_open") {
|
||||||
|
@ -641,10 +645,7 @@ module.exports = [
|
||||||
} else if ((child.type === "text") &&
|
} else if ((child.type === "text") &&
|
||||||
!inLink &&
|
!inLink &&
|
||||||
/https?:\/\//.test(child.content)) {
|
/https?:\/\//.test(child.content)) {
|
||||||
errors.push(lineNumber);
|
errors.push(child.lineNumber);
|
||||||
} else if ((child.type === "softbreak") ||
|
|
||||||
(child.type === "hardbreak")) {
|
|
||||||
lineNumber++;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -674,9 +675,7 @@ module.exports = [
|
||||||
"desc": "Emphasis used instead of a header",
|
"desc": "Emphasis used instead of a header",
|
||||||
"tags": [ "headers", "emphasis" ],
|
"tags": [ "headers", "emphasis" ],
|
||||||
"func": function MD036(params, errors) {
|
"func": function MD036(params, errors) {
|
||||||
var lineNumber = 0;
|
|
||||||
function base(token) {
|
function base(token) {
|
||||||
lineNumber = token.lineNumber;
|
|
||||||
if (token.type === "paragraph_open") {
|
if (token.type === "paragraph_open") {
|
||||||
return function inParagraph(t) {
|
return function inParagraph(t) {
|
||||||
if ((t.type === "inline") &&
|
if ((t.type === "inline") &&
|
||||||
|
@ -684,7 +683,7 @@ module.exports = [
|
||||||
((t.children[0].type === "strong_open") ||
|
((t.children[0].type === "strong_open") ||
|
||||||
(t.children[0].type === "em_open")) &&
|
(t.children[0].type === "em_open")) &&
|
||||||
(t.children[1].type === "text")) {
|
(t.children[1].type === "text")) {
|
||||||
errors.push(lineNumber);
|
errors.push(t.lineNumber);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else if (token.type === "blockquote_open") {
|
} else if (token.type === "blockquote_open") {
|
||||||
|
@ -700,5 +699,19 @@ module.exports = [
|
||||||
state = state(token) || base;
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -498,7 +498,7 @@ module.exports.badFileSync = function badFileSync(test) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.readme = function readme(test) {
|
module.exports.readme = function readme(test) {
|
||||||
test.expect(86);
|
test.expect(88);
|
||||||
var tagToRules = {};
|
var tagToRules = {};
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
rule.tags.forEach(function forTag(tag) {
|
rule.tags.forEach(function forTag(tag) {
|
||||||
|
@ -555,7 +555,7 @@ module.exports.readme = function readme(test) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.doc = function doc(test) {
|
module.exports.doc = function doc(test) {
|
||||||
test.expect(131);
|
test.expect(135);
|
||||||
fs.readFile("doc/Rules.md", shared.utf8Encoding,
|
fs.readFile("doc/Rules.md", shared.utf8Encoding,
|
||||||
function readFile(err, contents) {
|
function readFile(err, contents) {
|
||||||
test.ifError(err);
|
test.ifError(err);
|
||||||
|
|
35
test/spaces_inside_emphasis_markers.md
Normal file
35
test/spaces_inside_emphasis_markers.md
Normal 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.
|
Loading…
Add table
Add a link
Reference in a new issue