Add MD026, MD027 with tests.

This commit is contained in:
David Anson 2015-03-11 18:40:46 -07:00
parent 1112ac729d
commit 285a30e124
5 changed files with 109 additions and 15 deletions

View file

@ -53,6 +53,19 @@ function forEachLine(params, callback) {
});
}
function forEachHeading(params, callback) {
var heading = null;
params.tokens.forEach(function forToken(token) {
if (token.type === "heading_open") {
heading = token;
} else if (token.type === "heading_close") {
heading = null;
} else if ((token.type === "inline") && heading) {
callback(heading, token.content);
}
});
}
function flattenLists(tokens, filterBy) {
var lists = [];
var stack = [];
@ -273,8 +286,7 @@ module.exports = [
"func": function MD014(params, errors) {
filterTokens(params.tokens, "code_block", "fence")
.forEach(function forToken(token) {
if (token.content && token.content
.split(shared.newLineRe)
if (token.content && token.content.split(shared.newLineRe)
.filter(function filterLine(line) {
return line;
}).every(function forLine(line) {
@ -392,19 +404,12 @@ module.exports = [
"name": "MD024",
"desc": "Multiple headers with the same content",
"func": function MD024(params, errors) {
var content = [];
var inHeading = false;
params.tokens.forEach(function forToken(token) {
if (token.type === "heading_open") {
inHeading = true;
} else if (token.type === "heading_close") {
inHeading = false;
} else if ((token.type === "inline") && inHeading) {
if (content.indexOf(token.content) === -1) {
content.push(token.content);
} else {
errors.push(token.lineNumber);
}
var knownContent = [];
forEachHeading(params, function forHeading(heading, content) {
if (knownContent.indexOf(content) === -1) {
knownContent.push(content);
} else {
errors.push(heading.lineNumber);
}
});
}
@ -428,6 +433,43 @@ module.exports = [
}
},
{
"name": "MD026",
"desc": "Trailing punctuation in header",
"func": function MD026(params, errors) {
var punctuation = params.options.punctuation || ".,;:!?";
var re = new RegExp("[" + punctuation + "]$");
forEachHeading(params, function forHeading(heading, content) {
if (re.test(content)) {
errors.push(heading.lineNumber);
}
});
}
},
{
"name": "MD027",
"desc": "Multiple spaces after blockquote symbol",
"func": function MD027(params, errors) {
var inBlockquote = false;
params.tokens.forEach(function forToken(token) {
if (token.type === "blockquote_open") {
inBlockquote = true;
} else if (token.type === "blockquote_close") {
inBlockquote = false;
} else if ((token.type === "inline") && inBlockquote) {
token.content.split(shared.newLineRe)
.forEach(function forLine(line, offset) {
if (/^\s/.test(line) ||
(!offset && /^\s*>\s\s/.test(token.line))) {
errors.push(token.lineNumber + offset);
}
});
}
});
}
},
{
"name": "MD028",
"desc": "Blank line inside blockquote",

21
test/blockquote_spaces.md Normal file
View file

@ -0,0 +1,21 @@
Some text
> Hello world
> Foo {MD027}
> Bar {MD027}
This tests other things embedded in the blockquote:
> *Hello world*
> *foo* {MD027}
> **bar** {MD027}
> "Baz" {MD027}
> *foo*
> **bar**
> 'baz'
Test the first line being indented too much:
> Foo {MD027}
> Bar {MD027}
> Baz

View file

@ -0,0 +1,11 @@
# Heading 1 {MD026}.
## Heading 2 {MD026},
## Heading 3 {MD026}!
## Heading 4 {MD026}:
## Heading 5 {MD026};
## Heading 6 {MD026}?

View file

@ -0,0 +1,6 @@
{
"default": true,
"MD026": {
"punctuation": ".,;:!"
}
}

View file

@ -0,0 +1,14 @@
# Heading 1 {MD026}.
## Heading 2 {MD026},
## Heading 3 {MD026}!
## Heading 4 {MD026}:
## Heading 5 {MD026};
## Heading 6?
The rule has been customized to allow question marks while disallowing
everything else.