mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 14:00:13 +01:00
Add MD034 with tests, improve validation of README and Rules.
This commit is contained in:
parent
495fbac6fd
commit
0e24df7cf7
7 changed files with 104 additions and 34 deletions
|
|
@ -64,6 +64,7 @@ cases come directly from that project.
|
|||
* **MD031** - Fenced code blocks should be surrounded by blank lines
|
||||
* **MD032** - Lists should be surrounded by blank lines
|
||||
* **MD033** - Inline HTML
|
||||
* **MD034** - Bare URL used
|
||||
|
||||
See [Rules.md](doc/Rules.md) for more details.
|
||||
|
||||
|
|
@ -78,12 +79,14 @@ See [Rules.md](doc/Rules.md) for more details.
|
|||
* **hard_tab** - MD010
|
||||
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
||||
MD024, MD025, MD026
|
||||
* **html** - MD033
|
||||
* **indentation** - MD005, MD006, MD007, MD027
|
||||
* **line_length** - MD013
|
||||
* **links** - MD011
|
||||
* **links** - MD011, MD034
|
||||
* **ol** - MD029, MD030, MD032
|
||||
* **spaces** - MD018, MD019, MD020, MD021, MD023
|
||||
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
|
||||
* **url** - MD034
|
||||
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030
|
||||
|
||||
## API
|
||||
|
|
|
|||
22
doc/Rules.md
22
doc/Rules.md
|
|
@ -698,3 +698,25 @@ To fix this, use 'pure' markdown instead of including raw HTML:
|
|||
Rationale: Raw HTML is allowed in markdown, but this rule is included for
|
||||
those who want their documents to only include "pure" markdown, or for those
|
||||
who are rendering markdown documents in something other than HTML.
|
||||
|
||||
## MD034 - Bare URL used
|
||||
|
||||
Tags: links, url
|
||||
|
||||
This rule is triggered whenever a URL is given that isn't surrounded by angle
|
||||
brackets:
|
||||
|
||||
For more information, see http://www.example.com/.
|
||||
|
||||
To fix this, add angle brackets around the URL:
|
||||
|
||||
For more information, see <http://www.example.com/>.
|
||||
|
||||
Rationale: Without angle brackets, the URL isn't converted into a link in many
|
||||
markdown parsers.
|
||||
|
||||
Note: if you do want a bare URL without it being converted into a link,
|
||||
enclose it in a code block, otherwise in some markdown parsers it _will_ be
|
||||
converted:
|
||||
|
||||
`http://www.example.com`
|
||||
|
|
|
|||
27
lib/rules.js
27
lib/rules.js
|
|
@ -619,5 +619,32 @@ module.exports = [
|
|||
errors.push(token.lineNumber);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "MD034",
|
||||
"desc": "Bare URL used",
|
||||
"tags": [ "links", "url" ],
|
||||
"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") {
|
||||
inLink = true;
|
||||
} else if (child.type === "link_close") {
|
||||
inLink = false;
|
||||
} else if ((child.type === "text") &&
|
||||
!inLink &&
|
||||
/https?:\/\//.test(child.content)) {
|
||||
errors.push(lineNumber);
|
||||
} else if ((child.type === "softbreak") ||
|
||||
(child.type === "hardbreak")) {
|
||||
lineNumber++;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@
|
|||
"line_length": false,
|
||||
"MD006": false,
|
||||
"MD007": false,
|
||||
"MD033": false
|
||||
"MD033": false,
|
||||
"MD034": false
|
||||
}
|
||||
|
|
|
|||
9
test/links.md
Normal file
9
test/links.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Link test
|
||||
|
||||
For more information, please see the
|
||||
following page: http://www.example.com/ {MD034}
|
||||
which will tell you all you want to know.
|
||||
|
||||
http://www.google.com/ {MD034}
|
||||
|
||||
This link should be fine: <http://www.google.com/>
|
||||
|
|
@ -498,7 +498,15 @@ module.exports.badFileSync = function badFileSync(test) {
|
|||
};
|
||||
|
||||
module.exports.readme = function readme(test) {
|
||||
test.expect(144);
|
||||
test.expect(80);
|
||||
var tagToRules = {};
|
||||
rules.forEach(function forRule(rule) {
|
||||
rule.tags.forEach(function forTag(tag) {
|
||||
var tagRules = tagToRules[tag] || [];
|
||||
tagRules.push(rule.name);
|
||||
tagToRules[tag] = tagRules;
|
||||
});
|
||||
});
|
||||
fs.readFile("README.md", shared.utf8Encoding,
|
||||
function readFile(err, contents) {
|
||||
test.ifError(err);
|
||||
|
|
@ -507,8 +515,6 @@ module.exports.readme = function readme(test) {
|
|||
var inRules = false;
|
||||
var seenTags = false;
|
||||
var inTags = false;
|
||||
var docTags = [];
|
||||
var usedTags = [];
|
||||
md.parse(contents, {}).forEach(function forToken(token) {
|
||||
if (token.type === "bullet_list_open") {
|
||||
if (!seenRules) {
|
||||
|
|
@ -524,38 +530,32 @@ module.exports.readme = function readme(test) {
|
|||
} else if (token.type === "inline") {
|
||||
if (inRules) {
|
||||
var rule = rulesLeft.shift();
|
||||
var expected = "**" + rule.name + "** - " + rule.desc;
|
||||
test.equal(token.content, expected, "Rule mismatch.");
|
||||
test.ok(rule,
|
||||
"Missing rule implementation for " + token.content + ".");
|
||||
if (rule) {
|
||||
var expected = "**" + rule.name + "** - " + rule.desc;
|
||||
test.equal(token.content, expected, "Rule mismatch.");
|
||||
}
|
||||
} else if (inTags) {
|
||||
var parts = token.content.replace(/\*\*/g, "").split(/ - |, |,\n/);
|
||||
var tag = parts.shift();
|
||||
docTags.push(tag);
|
||||
parts.forEach(function forPart(part) {
|
||||
var found = rules.some(function forRule(r) {
|
||||
if (r.name === part) {
|
||||
test.ok(r.tags.indexOf(tag) !== -1, "Missing tag.");
|
||||
r.tags.forEach(function forTag(t) {
|
||||
if (usedTags.indexOf(t) === -1) {
|
||||
usedTags.push(t);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
test.ok(found, "Unknown rule." + part);
|
||||
});
|
||||
test.deepEqual(parts, tagToRules[tag] || [],
|
||||
"Rule mismatch for tag " + tag + ".");
|
||||
delete tagToRules[tag];
|
||||
}
|
||||
}
|
||||
});
|
||||
test.ok(!rulesLeft.length, "Missing rule.");
|
||||
test.deepEqual(docTags, usedTags.sort(), "Tag mismatch.");
|
||||
var ruleLeft = rulesLeft.shift();
|
||||
test.ok(!ruleLeft,
|
||||
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
|
||||
var tagLeft = Object.keys(tagToRules).shift();
|
||||
test.ok(!tagLeft, "Undocumented tag " + tagLeft + ".");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.doc = function doc(test) {
|
||||
test.expect(90);
|
||||
test.expect(123);
|
||||
fs.readFile("doc/Rules.md", shared.utf8Encoding,
|
||||
function readFile(err, contents) {
|
||||
test.ifError(err);
|
||||
|
|
@ -569,19 +569,27 @@ module.exports.doc = function doc(test) {
|
|||
inHeading = false;
|
||||
} else if (token.type === "inline") {
|
||||
if (inHeading) {
|
||||
test.ok(!rule, "Missing tags.");
|
||||
test.ok(!rule,
|
||||
"Missing tags for rule " + (rule || {}).name + ".");
|
||||
rule = rulesLeft.shift();
|
||||
var expected = rule.name + " - " + rule.desc;
|
||||
test.equal(token.content, expected, "Rule mismatch.");
|
||||
} else if (/^Tags: /.test(token.content)) {
|
||||
test.ok(rule,
|
||||
"Missing rule implementation for " + token.content + ".");
|
||||
if (rule) {
|
||||
var expected = rule.name + " - " + rule.desc;
|
||||
test.equal(token.content, expected, "Rule mismatch.");
|
||||
}
|
||||
} else if (/^Tags: /.test(token.content) && rule) {
|
||||
var tags = token.content.split(/, |: | /).slice(1);
|
||||
test.deepEqual(tags, rule.tags, "Tag mismatch.");
|
||||
test.deepEqual(tags, rule.tags,
|
||||
"Tag mismatch for rule " + rule.name + ".");
|
||||
rule = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
test.ok(!rulesLeft.length, "Missing rule.");
|
||||
test.ok(!rule, "Missing tags.");
|
||||
var ruleLeft = rulesLeft.shift();
|
||||
test.ok(!ruleLeft,
|
||||
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
|
||||
test.ok(!rule, "Missing tags for rule " + (rule || {}).name + ".");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Go to (this website)[http://www.example.com] {MD011}
|
||||
Go to (this website)[http://www.example.com] {MD011} {MD034}
|
||||
|
||||
However, this shouldn't trigger inside code blocks:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue