markdownlint 0.20.0 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +47 -47
- package/LICENSE +21 -21
- package/README.md +881 -868
- package/demo/markdownlint-browser.js +5438 -5306
- package/doc/CustomRules.md +313 -313
- package/doc/Rules.md +1847 -1795
- package/helpers/LICENSE +21 -21
- package/helpers/README.md +50 -50
- package/helpers/helpers.js +687 -627
- package/helpers/package.json +18 -18
- package/lib/cache.js +24 -24
- package/lib/markdownlint.d.ts +352 -352
- package/lib/markdownlint.js +1101 -1101
- package/lib/md001.js +22 -22
- package/lib/md002.js +22 -22
- package/lib/md003.js +42 -42
- package/lib/md004.js +43 -43
- package/lib/md005.js +69 -69
- package/lib/md006.js +34 -34
- package/lib/md007.js +47 -47
- package/lib/md009.js +77 -77
- package/lib/md010.js +38 -38
- package/lib/md011.js +38 -38
- package/lib/md012.js +32 -32
- package/lib/md013.js +99 -99
- package/lib/md014.js +53 -53
- package/lib/md018.js +34 -34
- package/lib/md019.js +39 -39
- package/lib/md020.js +62 -62
- package/lib/md021.js +60 -60
- package/lib/md022.js +56 -56
- package/lib/md023.js +38 -38
- package/lib/md024.js +38 -38
- package/lib/md025.js +32 -32
- package/lib/md026.js +40 -40
- package/lib/md027.js +56 -56
- package/lib/md028.js +38 -38
- package/lib/md029.js +66 -66
- package/lib/md030.js +50 -50
- package/lib/md031.js +39 -39
- package/lib/md032.js +50 -50
- package/lib/md033.js +45 -45
- package/lib/md034.js +61 -61
- package/lib/md035.js +21 -21
- package/lib/md036.js +56 -56
- package/lib/md037.js +150 -89
- package/lib/md038.js +68 -68
- package/lib/md039.js +64 -64
- package/lib/md040.js +18 -18
- package/lib/md041.js +31 -31
- package/lib/md042.js +41 -41
- package/lib/md043.js +45 -45
- package/lib/md044.js +77 -71
- package/lib/md045.js +18 -18
- package/lib/md046.js +32 -32
- package/lib/md047.js +28 -28
- package/lib/md048.js +29 -29
- package/lib/rules.js +61 -61
- package/package.json +73 -67
- package/schema/build-config-schema.js +405 -405
- package/schema/markdownlint-config-schema.json +1550 -1550
- package/style/all.json +5 -5
- package/style/cirosantilli.json +22 -22
- package/style/relaxed.json +13 -13
package/lib/md023.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addErrorContext, filterTokens } = require("../helpers");
|
|
6
|
-
|
|
7
|
-
const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/;
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
"names": [ "MD023", "heading-start-left", "header-start-left" ],
|
|
11
|
-
"description": "Headings must start at the beginning of the line",
|
|
12
|
-
"tags": [ "headings", "headers", "spaces" ],
|
|
13
|
-
"function": function MD023(params, onError) {
|
|
14
|
-
filterTokens(params, "heading_open", function forToken(token) {
|
|
15
|
-
const { lineNumber, line } = token;
|
|
16
|
-
const match = line.match(spaceBeforeHeadingRe);
|
|
17
|
-
if (match) {
|
|
18
|
-
const [ prefixAndFirstChar, prefix ] = match;
|
|
19
|
-
let deleteCount = prefix.length;
|
|
20
|
-
const prefixLengthNoSpace = prefix.trimRight().length;
|
|
21
|
-
if (prefixLengthNoSpace) {
|
|
22
|
-
deleteCount -= prefixLengthNoSpace - 1;
|
|
23
|
-
}
|
|
24
|
-
addErrorContext(
|
|
25
|
-
onError,
|
|
26
|
-
lineNumber,
|
|
27
|
-
line,
|
|
28
|
-
null,
|
|
29
|
-
null,
|
|
30
|
-
[ 1, prefixAndFirstChar.length ],
|
|
31
|
-
{
|
|
32
|
-
"editColumn": prefixLengthNoSpace + 1,
|
|
33
|
-
"deleteCount": deleteCount
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addErrorContext, filterTokens } = require("../helpers");
|
|
6
|
+
|
|
7
|
+
const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/;
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
"names": [ "MD023", "heading-start-left", "header-start-left" ],
|
|
11
|
+
"description": "Headings must start at the beginning of the line",
|
|
12
|
+
"tags": [ "headings", "headers", "spaces" ],
|
|
13
|
+
"function": function MD023(params, onError) {
|
|
14
|
+
filterTokens(params, "heading_open", function forToken(token) {
|
|
15
|
+
const { lineNumber, line } = token;
|
|
16
|
+
const match = line.match(spaceBeforeHeadingRe);
|
|
17
|
+
if (match) {
|
|
18
|
+
const [ prefixAndFirstChar, prefix ] = match;
|
|
19
|
+
let deleteCount = prefix.length;
|
|
20
|
+
const prefixLengthNoSpace = prefix.trimRight().length;
|
|
21
|
+
if (prefixLengthNoSpace) {
|
|
22
|
+
deleteCount -= prefixLengthNoSpace - 1;
|
|
23
|
+
}
|
|
24
|
+
addErrorContext(
|
|
25
|
+
onError,
|
|
26
|
+
lineNumber,
|
|
27
|
+
line,
|
|
28
|
+
null,
|
|
29
|
+
null,
|
|
30
|
+
[ 1, prefixAndFirstChar.length ],
|
|
31
|
+
{
|
|
32
|
+
"editColumn": prefixLengthNoSpace + 1,
|
|
33
|
+
"deleteCount": deleteCount
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
package/lib/md024.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addErrorContext, forEachHeading } = require("../helpers");
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
"names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ],
|
|
9
|
-
"description": "Multiple headings with the same content",
|
|
10
|
-
"tags": [ "headings", "headers" ],
|
|
11
|
-
"function": function MD024(params, onError) {
|
|
12
|
-
const siblingsOnly = !!params.config.siblings_only ||
|
|
13
|
-
!!params.config.allow_different_nesting || false;
|
|
14
|
-
const knownContents = [ null, [] ];
|
|
15
|
-
let lastLevel = 1;
|
|
16
|
-
let knownContent = knownContents[lastLevel];
|
|
17
|
-
forEachHeading(params, (heading, content) => {
|
|
18
|
-
if (siblingsOnly) {
|
|
19
|
-
const newLevel = heading.tag.slice(1);
|
|
20
|
-
while (lastLevel < newLevel) {
|
|
21
|
-
lastLevel++;
|
|
22
|
-
knownContents[lastLevel] = [];
|
|
23
|
-
}
|
|
24
|
-
while (lastLevel > newLevel) {
|
|
25
|
-
knownContents[lastLevel] = [];
|
|
26
|
-
lastLevel--;
|
|
27
|
-
}
|
|
28
|
-
knownContent = knownContents[newLevel];
|
|
29
|
-
}
|
|
30
|
-
if (knownContent.includes(content)) {
|
|
31
|
-
addErrorContext(onError, heading.lineNumber,
|
|
32
|
-
heading.line.trim());
|
|
33
|
-
} else {
|
|
34
|
-
knownContent.push(content);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addErrorContext, forEachHeading } = require("../helpers");
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
"names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ],
|
|
9
|
+
"description": "Multiple headings with the same content",
|
|
10
|
+
"tags": [ "headings", "headers" ],
|
|
11
|
+
"function": function MD024(params, onError) {
|
|
12
|
+
const siblingsOnly = !!params.config.siblings_only ||
|
|
13
|
+
!!params.config.allow_different_nesting || false;
|
|
14
|
+
const knownContents = [ null, [] ];
|
|
15
|
+
let lastLevel = 1;
|
|
16
|
+
let knownContent = knownContents[lastLevel];
|
|
17
|
+
forEachHeading(params, (heading, content) => {
|
|
18
|
+
if (siblingsOnly) {
|
|
19
|
+
const newLevel = heading.tag.slice(1);
|
|
20
|
+
while (lastLevel < newLevel) {
|
|
21
|
+
lastLevel++;
|
|
22
|
+
knownContents[lastLevel] = [];
|
|
23
|
+
}
|
|
24
|
+
while (lastLevel > newLevel) {
|
|
25
|
+
knownContents[lastLevel] = [];
|
|
26
|
+
lastLevel--;
|
|
27
|
+
}
|
|
28
|
+
knownContent = knownContents[newLevel];
|
|
29
|
+
}
|
|
30
|
+
if (knownContent.includes(content)) {
|
|
31
|
+
addErrorContext(onError, heading.lineNumber,
|
|
32
|
+
heading.line.trim());
|
|
33
|
+
} else {
|
|
34
|
+
knownContent.push(content);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
package/lib/md025.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addErrorContext, filterTokens, frontMatterHasTitle } =
|
|
6
|
-
require("../helpers");
|
|
7
|
-
|
|
8
|
-
module.exports = {
|
|
9
|
-
"names": [ "MD025", "single-title", "single-h1" ],
|
|
10
|
-
"description": "Multiple top level headings in the same document",
|
|
11
|
-
"tags": [ "headings", "headers" ],
|
|
12
|
-
"function": function MD025(params, onError) {
|
|
13
|
-
const level = Number(params.config.level || 1);
|
|
14
|
-
const tag = "h" + level;
|
|
15
|
-
const foundFrontMatterTitle =
|
|
16
|
-
frontMatterHasTitle(
|
|
17
|
-
params.frontMatterLines,
|
|
18
|
-
params.config.front_matter_title
|
|
19
|
-
);
|
|
20
|
-
let hasTopLevelHeading = false;
|
|
21
|
-
filterTokens(params, "heading_open", function forToken(token) {
|
|
22
|
-
if (token.tag === tag) {
|
|
23
|
-
if (hasTopLevelHeading || foundFrontMatterTitle) {
|
|
24
|
-
addErrorContext(onError, token.lineNumber,
|
|
25
|
-
token.line.trim());
|
|
26
|
-
} else if (token.lineNumber === 1) {
|
|
27
|
-
hasTopLevelHeading = true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addErrorContext, filterTokens, frontMatterHasTitle } =
|
|
6
|
+
require("../helpers");
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
"names": [ "MD025", "single-title", "single-h1" ],
|
|
10
|
+
"description": "Multiple top level headings in the same document",
|
|
11
|
+
"tags": [ "headings", "headers" ],
|
|
12
|
+
"function": function MD025(params, onError) {
|
|
13
|
+
const level = Number(params.config.level || 1);
|
|
14
|
+
const tag = "h" + level;
|
|
15
|
+
const foundFrontMatterTitle =
|
|
16
|
+
frontMatterHasTitle(
|
|
17
|
+
params.frontMatterLines,
|
|
18
|
+
params.config.front_matter_title
|
|
19
|
+
);
|
|
20
|
+
let hasTopLevelHeading = false;
|
|
21
|
+
filterTokens(params, "heading_open", function forToken(token) {
|
|
22
|
+
if (token.tag === tag) {
|
|
23
|
+
if (hasTopLevelHeading || foundFrontMatterTitle) {
|
|
24
|
+
addErrorContext(onError, token.lineNumber,
|
|
25
|
+
token.line.trim());
|
|
26
|
+
} else if (token.lineNumber === 1) {
|
|
27
|
+
hasTopLevelHeading = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
package/lib/md026.js
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addError, allPunctuation, escapeForRegExp, forEachHeading } =
|
|
6
|
-
require("../helpers");
|
|
7
|
-
|
|
8
|
-
module.exports = {
|
|
9
|
-
"names": [ "MD026", "no-trailing-punctuation" ],
|
|
10
|
-
"description": "Trailing punctuation in heading",
|
|
11
|
-
"tags": [ "headings", "headers" ],
|
|
12
|
-
"function": function MD026(params, onError) {
|
|
13
|
-
let punctuation = params.config.punctuation;
|
|
14
|
-
punctuation =
|
|
15
|
-
String((punctuation === undefined) ? allPunctuation : punctuation);
|
|
16
|
-
const trailingPunctuationRe =
|
|
17
|
-
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");
|
|
18
|
-
forEachHeading(params, (heading) => {
|
|
19
|
-
const { line, lineNumber } = heading;
|
|
20
|
-
const trimmedLine = line.replace(/[\s#]*$/, "");
|
|
21
|
-
const match = trailingPunctuationRe.exec(trimmedLine);
|
|
22
|
-
if (match) {
|
|
23
|
-
const fullMatch = match[0];
|
|
24
|
-
const column = match.index + 1;
|
|
25
|
-
const length = fullMatch.length;
|
|
26
|
-
addError(
|
|
27
|
-
onError,
|
|
28
|
-
lineNumber,
|
|
29
|
-
`Punctuation: '${fullMatch}'`,
|
|
30
|
-
null,
|
|
31
|
-
[ column, length ],
|
|
32
|
-
{
|
|
33
|
-
"editColumn": column,
|
|
34
|
-
"deleteCount": length
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addError, allPunctuation, escapeForRegExp, forEachHeading } =
|
|
6
|
+
require("../helpers");
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
"names": [ "MD026", "no-trailing-punctuation" ],
|
|
10
|
+
"description": "Trailing punctuation in heading",
|
|
11
|
+
"tags": [ "headings", "headers" ],
|
|
12
|
+
"function": function MD026(params, onError) {
|
|
13
|
+
let punctuation = params.config.punctuation;
|
|
14
|
+
punctuation =
|
|
15
|
+
String((punctuation === undefined) ? allPunctuation : punctuation);
|
|
16
|
+
const trailingPunctuationRe =
|
|
17
|
+
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");
|
|
18
|
+
forEachHeading(params, (heading) => {
|
|
19
|
+
const { line, lineNumber } = heading;
|
|
20
|
+
const trimmedLine = line.replace(/[\s#]*$/, "");
|
|
21
|
+
const match = trailingPunctuationRe.exec(trimmedLine);
|
|
22
|
+
if (match) {
|
|
23
|
+
const fullMatch = match[0];
|
|
24
|
+
const column = match.index + 1;
|
|
25
|
+
const length = fullMatch.length;
|
|
26
|
+
addError(
|
|
27
|
+
onError,
|
|
28
|
+
lineNumber,
|
|
29
|
+
`Punctuation: '${fullMatch}'`,
|
|
30
|
+
null,
|
|
31
|
+
[ column, length ],
|
|
32
|
+
{
|
|
33
|
+
"editColumn": column,
|
|
34
|
+
"deleteCount": length
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
package/lib/md027.js
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addErrorContext, newLineRe } = require("../helpers");
|
|
6
|
-
|
|
7
|
-
const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/;
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
"names": [ "MD027", "no-multiple-space-blockquote" ],
|
|
11
|
-
"description": "Multiple spaces after blockquote symbol",
|
|
12
|
-
"tags": [ "blockquote", "whitespace", "indentation" ],
|
|
13
|
-
"function": function MD027(params, onError) {
|
|
14
|
-
let blockquoteNesting = 0;
|
|
15
|
-
let listItemNesting = 0;
|
|
16
|
-
params.tokens.forEach((token) => {
|
|
17
|
-
const { content, lineNumber, type } = token;
|
|
18
|
-
if (type === "blockquote_open") {
|
|
19
|
-
blockquoteNesting++;
|
|
20
|
-
} else if (type === "blockquote_close") {
|
|
21
|
-
blockquoteNesting--;
|
|
22
|
-
} else if (type === "list_item_open") {
|
|
23
|
-
listItemNesting++;
|
|
24
|
-
} else if (type === "list_item_close") {
|
|
25
|
-
listItemNesting--;
|
|
26
|
-
} else if ((type === "inline") && blockquoteNesting) {
|
|
27
|
-
const lineCount = content.split(newLineRe).length;
|
|
28
|
-
for (let i = 0; i < lineCount; i++) {
|
|
29
|
-
const line = params.lines[lineNumber + i - 1];
|
|
30
|
-
const match = line.match(spaceAfterBlockQuoteRe);
|
|
31
|
-
if (match) {
|
|
32
|
-
const [
|
|
33
|
-
fullMatch,
|
|
34
|
-
{ "length": blockquoteLength },
|
|
35
|
-
{ "length": spaceLength }
|
|
36
|
-
] = match;
|
|
37
|
-
if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) {
|
|
38
|
-
addErrorContext(
|
|
39
|
-
onError,
|
|
40
|
-
lineNumber + i,
|
|
41
|
-
line,
|
|
42
|
-
null,
|
|
43
|
-
null,
|
|
44
|
-
[ 1, fullMatch.length ],
|
|
45
|
-
{
|
|
46
|
-
"editColumn": blockquoteLength + 1,
|
|
47
|
-
"deleteCount": spaceLength - 1
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addErrorContext, newLineRe } = require("../helpers");
|
|
6
|
+
|
|
7
|
+
const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/;
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
"names": [ "MD027", "no-multiple-space-blockquote" ],
|
|
11
|
+
"description": "Multiple spaces after blockquote symbol",
|
|
12
|
+
"tags": [ "blockquote", "whitespace", "indentation" ],
|
|
13
|
+
"function": function MD027(params, onError) {
|
|
14
|
+
let blockquoteNesting = 0;
|
|
15
|
+
let listItemNesting = 0;
|
|
16
|
+
params.tokens.forEach((token) => {
|
|
17
|
+
const { content, lineNumber, type } = token;
|
|
18
|
+
if (type === "blockquote_open") {
|
|
19
|
+
blockquoteNesting++;
|
|
20
|
+
} else if (type === "blockquote_close") {
|
|
21
|
+
blockquoteNesting--;
|
|
22
|
+
} else if (type === "list_item_open") {
|
|
23
|
+
listItemNesting++;
|
|
24
|
+
} else if (type === "list_item_close") {
|
|
25
|
+
listItemNesting--;
|
|
26
|
+
} else if ((type === "inline") && blockquoteNesting) {
|
|
27
|
+
const lineCount = content.split(newLineRe).length;
|
|
28
|
+
for (let i = 0; i < lineCount; i++) {
|
|
29
|
+
const line = params.lines[lineNumber + i - 1];
|
|
30
|
+
const match = line.match(spaceAfterBlockQuoteRe);
|
|
31
|
+
if (match) {
|
|
32
|
+
const [
|
|
33
|
+
fullMatch,
|
|
34
|
+
{ "length": blockquoteLength },
|
|
35
|
+
{ "length": spaceLength }
|
|
36
|
+
] = match;
|
|
37
|
+
if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) {
|
|
38
|
+
addErrorContext(
|
|
39
|
+
onError,
|
|
40
|
+
lineNumber + i,
|
|
41
|
+
line,
|
|
42
|
+
null,
|
|
43
|
+
null,
|
|
44
|
+
[ 1, fullMatch.length ],
|
|
45
|
+
{
|
|
46
|
+
"editColumn": blockquoteLength + 1,
|
|
47
|
+
"deleteCount": spaceLength - 1
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
};
|
package/lib/md028.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addError } = require("../helpers");
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
"names": [ "MD028", "no-blanks-blockquote" ],
|
|
9
|
-
"description": "Blank line inside blockquote",
|
|
10
|
-
"tags": [ "blockquote", "whitespace" ],
|
|
11
|
-
"function": function MD028(params, onError) {
|
|
12
|
-
let prevToken = {};
|
|
13
|
-
let prevLineNumber = null;
|
|
14
|
-
params.tokens.forEach(function forToken(token) {
|
|
15
|
-
if ((token.type === "blockquote_open") &&
|
|
16
|
-
(prevToken.type === "blockquote_close")) {
|
|
17
|
-
for (
|
|
18
|
-
let lineNumber = prevLineNumber;
|
|
19
|
-
lineNumber < token.lineNumber;
|
|
20
|
-
lineNumber++) {
|
|
21
|
-
addError(
|
|
22
|
-
onError,
|
|
23
|
-
lineNumber,
|
|
24
|
-
null,
|
|
25
|
-
null,
|
|
26
|
-
null,
|
|
27
|
-
{
|
|
28
|
-
"deleteCount": -1
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
prevToken = token;
|
|
33
|
-
if (token.type === "blockquote_open") {
|
|
34
|
-
prevLineNumber = token.map[1] + 1;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addError } = require("../helpers");
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
"names": [ "MD028", "no-blanks-blockquote" ],
|
|
9
|
+
"description": "Blank line inside blockquote",
|
|
10
|
+
"tags": [ "blockquote", "whitespace" ],
|
|
11
|
+
"function": function MD028(params, onError) {
|
|
12
|
+
let prevToken = {};
|
|
13
|
+
let prevLineNumber = null;
|
|
14
|
+
params.tokens.forEach(function forToken(token) {
|
|
15
|
+
if ((token.type === "blockquote_open") &&
|
|
16
|
+
(prevToken.type === "blockquote_close")) {
|
|
17
|
+
for (
|
|
18
|
+
let lineNumber = prevLineNumber;
|
|
19
|
+
lineNumber < token.lineNumber;
|
|
20
|
+
lineNumber++) {
|
|
21
|
+
addError(
|
|
22
|
+
onError,
|
|
23
|
+
lineNumber,
|
|
24
|
+
null,
|
|
25
|
+
null,
|
|
26
|
+
null,
|
|
27
|
+
{
|
|
28
|
+
"deleteCount": -1
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
prevToken = token;
|
|
33
|
+
if (token.type === "blockquote_open") {
|
|
34
|
+
prevLineNumber = token.map[1] + 1;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
package/lib/md029.js
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const { addErrorDetailIf, listItemMarkerRe, orderedListItemMarkerRe,
|
|
6
|
-
rangeFromRegExp } = require("../helpers");
|
|
7
|
-
const { flattenedLists } = require("./cache");
|
|
8
|
-
|
|
9
|
-
const listStyleExamples = {
|
|
10
|
-
"one": "1/1/1",
|
|
11
|
-
"ordered": "1/2/3",
|
|
12
|
-
"zero": "0/0/0"
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
module.exports = {
|
|
16
|
-
"names": [ "MD029", "ol-prefix" ],
|
|
17
|
-
"description": "Ordered list item prefix",
|
|
18
|
-
"tags": [ "ol" ],
|
|
19
|
-
"function": function MD029(params, onError) {
|
|
20
|
-
const style = String(params.config.style || "one_or_ordered");
|
|
21
|
-
flattenedLists().filter((list) => !list.unordered).forEach((list) => {
|
|
22
|
-
const { items } = list;
|
|
23
|
-
let current = 1;
|
|
24
|
-
let incrementing = false;
|
|
25
|
-
// Check for incrementing number pattern 1/2/3 or 0/1/2
|
|
26
|
-
if (items.length >= 2) {
|
|
27
|
-
const first = orderedListItemMarkerRe.exec(items[0].line);
|
|
28
|
-
const second = orderedListItemMarkerRe.exec(items[1].line);
|
|
29
|
-
if (first && second) {
|
|
30
|
-
const [ , firstNumber ] = first;
|
|
31
|
-
const [ , secondNumber ] = second;
|
|
32
|
-
if ((secondNumber !== "1") || (firstNumber === "0")) {
|
|
33
|
-
incrementing = true;
|
|
34
|
-
if (firstNumber === "0") {
|
|
35
|
-
current = 0;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Determine effective style
|
|
41
|
-
let listStyle = style;
|
|
42
|
-
if (listStyle === "one_or_ordered") {
|
|
43
|
-
listStyle = incrementing ? "ordered" : "one";
|
|
44
|
-
}
|
|
45
|
-
// Force expected value for 0/0/0 and 1/1/1 patterns
|
|
46
|
-
if (listStyle === "zero") {
|
|
47
|
-
current = 0;
|
|
48
|
-
} else if (listStyle === "one") {
|
|
49
|
-
current = 1;
|
|
50
|
-
}
|
|
51
|
-
// Validate each list item marker
|
|
52
|
-
items.forEach((item) => {
|
|
53
|
-
const match = orderedListItemMarkerRe.exec(item.line);
|
|
54
|
-
if (match) {
|
|
55
|
-
addErrorDetailIf(onError, item.lineNumber,
|
|
56
|
-
String(current), match[1],
|
|
57
|
-
"Style: " + listStyleExamples[listStyle], null,
|
|
58
|
-
rangeFromRegExp(item.line, listItemMarkerRe));
|
|
59
|
-
if (listStyle === "ordered") {
|
|
60
|
-
current++;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
};
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addErrorDetailIf, listItemMarkerRe, orderedListItemMarkerRe,
|
|
6
|
+
rangeFromRegExp } = require("../helpers");
|
|
7
|
+
const { flattenedLists } = require("./cache");
|
|
8
|
+
|
|
9
|
+
const listStyleExamples = {
|
|
10
|
+
"one": "1/1/1",
|
|
11
|
+
"ordered": "1/2/3",
|
|
12
|
+
"zero": "0/0/0"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
"names": [ "MD029", "ol-prefix" ],
|
|
17
|
+
"description": "Ordered list item prefix",
|
|
18
|
+
"tags": [ "ol" ],
|
|
19
|
+
"function": function MD029(params, onError) {
|
|
20
|
+
const style = String(params.config.style || "one_or_ordered");
|
|
21
|
+
flattenedLists().filter((list) => !list.unordered).forEach((list) => {
|
|
22
|
+
const { items } = list;
|
|
23
|
+
let current = 1;
|
|
24
|
+
let incrementing = false;
|
|
25
|
+
// Check for incrementing number pattern 1/2/3 or 0/1/2
|
|
26
|
+
if (items.length >= 2) {
|
|
27
|
+
const first = orderedListItemMarkerRe.exec(items[0].line);
|
|
28
|
+
const second = orderedListItemMarkerRe.exec(items[1].line);
|
|
29
|
+
if (first && second) {
|
|
30
|
+
const [ , firstNumber ] = first;
|
|
31
|
+
const [ , secondNumber ] = second;
|
|
32
|
+
if ((secondNumber !== "1") || (firstNumber === "0")) {
|
|
33
|
+
incrementing = true;
|
|
34
|
+
if (firstNumber === "0") {
|
|
35
|
+
current = 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Determine effective style
|
|
41
|
+
let listStyle = style;
|
|
42
|
+
if (listStyle === "one_or_ordered") {
|
|
43
|
+
listStyle = incrementing ? "ordered" : "one";
|
|
44
|
+
}
|
|
45
|
+
// Force expected value for 0/0/0 and 1/1/1 patterns
|
|
46
|
+
if (listStyle === "zero") {
|
|
47
|
+
current = 0;
|
|
48
|
+
} else if (listStyle === "one") {
|
|
49
|
+
current = 1;
|
|
50
|
+
}
|
|
51
|
+
// Validate each list item marker
|
|
52
|
+
items.forEach((item) => {
|
|
53
|
+
const match = orderedListItemMarkerRe.exec(item.line);
|
|
54
|
+
if (match) {
|
|
55
|
+
addErrorDetailIf(onError, item.lineNumber,
|
|
56
|
+
String(current), match[1],
|
|
57
|
+
"Style: " + listStyleExamples[listStyle], null,
|
|
58
|
+
rangeFromRegExp(item.line, listItemMarkerRe));
|
|
59
|
+
if (listStyle === "ordered") {
|
|
60
|
+
current++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
};
|