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
|
||||
* **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
|
||||
|
||||
|
|
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.
|
||||
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())) {
|
||||
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
|
||||
|
|
41
lib/rules.js
41
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
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -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);
|
||||
|
|
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