markdownlint 0.12.0 → 0.14.2
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/.eslintrc.json +52 -275
- package/.travis.yml +2 -2
- package/LICENSE +1 -1
- package/README.md +54 -27
- package/doc/CustomRules.md +7 -2
- package/doc/Rules.md +120 -33
- package/example/standalone.js +2 -2
- package/helpers/LICENSE +21 -0
- package/helpers/README.md +50 -0
- package/{lib/shared.js → helpers/helpers.js} +91 -82
- package/helpers/package.json +18 -0
- package/lib/cache.js +24 -0
- package/lib/markdownlint.js +78 -45
- package/lib/md001.js +3 -3
- package/lib/md002.js +2 -2
- package/lib/md003.js +5 -4
- package/lib/md004.js +11 -9
- package/lib/md005.js +12 -10
- package/lib/md006.js +7 -5
- package/lib/md007.js +7 -5
- package/lib/md009.js +10 -8
- package/lib/md010.js +5 -5
- package/lib/md011.js +4 -4
- package/lib/md012.js +4 -3
- package/lib/md013.js +41 -32
- package/lib/md014.js +7 -6
- package/lib/md018.js +6 -4
- package/lib/md019.js +6 -5
- package/lib/md020.js +5 -4
- package/lib/md021.js +6 -5
- package/lib/md022.js +22 -22
- package/lib/md023.js +5 -4
- package/lib/md024.js +6 -6
- package/lib/md025.js +11 -5
- package/lib/md026.js +4 -4
- package/lib/md027.js +6 -6
- package/lib/md028.js +2 -2
- package/lib/md029.js +17 -9
- package/lib/md030.js +8 -6
- package/lib/md031.js +7 -6
- package/lib/md032.js +10 -12
- package/lib/md033.js +27 -26
- package/lib/md034.js +15 -10
- package/lib/md035.js +3 -3
- package/lib/md036.js +2 -2
- package/lib/md037.js +12 -9
- package/lib/md038.js +6 -5
- package/lib/md039.js +7 -6
- package/lib/md040.js +3 -3
- package/lib/md041.js +17 -19
- package/lib/md042.js +5 -4
- package/lib/md043.js +5 -4
- package/lib/md044.js +14 -13
- package/lib/md045.js +3 -3
- package/lib/md046.js +32 -0
- package/lib/md047.js +18 -0
- package/lib/rules.js +3 -1
- package/package.json +12 -11
- package/schema/build-config-schema.js +36 -2
- package/schema/markdownlint-config-schema.json +178 -14
- package/style/cirosantilli.json +1 -1
package/lib/md023.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, filterTokens, rangeFromRegExp } =
|
|
6
|
+
require("../helpers");
|
|
6
7
|
|
|
7
8
|
const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/;
|
|
8
9
|
|
|
@@ -11,10 +12,10 @@ module.exports = {
|
|
|
11
12
|
"description": "Headings must start at the beginning of the line",
|
|
12
13
|
"tags": [ "headings", "headers", "spaces" ],
|
|
13
14
|
"function": function MD023(params, onError) {
|
|
14
|
-
|
|
15
|
+
filterTokens(params, "heading_open", function forToken(token) {
|
|
15
16
|
if (spaceBeforeHeadingRe.test(token.line)) {
|
|
16
|
-
|
|
17
|
-
null,
|
|
17
|
+
addErrorContext(onError, token.lineNumber, token.line, null,
|
|
18
|
+
null, rangeFromRegExp(token.line, spaceBeforeHeadingRe));
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
21
|
}
|
package/lib/md024.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, forEachHeading } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ],
|
|
@@ -14,7 +14,7 @@ module.exports = {
|
|
|
14
14
|
const knownContents = [ null, [] ];
|
|
15
15
|
let lastLevel = 1;
|
|
16
16
|
let knownContent = knownContents[lastLevel];
|
|
17
|
-
|
|
17
|
+
forEachHeading(params, (heading, content) => {
|
|
18
18
|
if (siblingsOnly) {
|
|
19
19
|
const newLevel = heading.tag.slice(1);
|
|
20
20
|
while (lastLevel < newLevel) {
|
|
@@ -27,11 +27,11 @@ module.exports = {
|
|
|
27
27
|
}
|
|
28
28
|
knownContent = knownContents[newLevel];
|
|
29
29
|
}
|
|
30
|
-
if (knownContent.
|
|
31
|
-
|
|
32
|
-
} else {
|
|
33
|
-
shared.addErrorContext(onError, heading.lineNumber,
|
|
30
|
+
if (knownContent.includes(content)) {
|
|
31
|
+
addErrorContext(onError, heading.lineNumber,
|
|
34
32
|
heading.line.trim());
|
|
33
|
+
} else {
|
|
34
|
+
knownContent.push(content);
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
}
|
package/lib/md025.js
CHANGED
|
@@ -2,20 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, filterTokens, frontMatterHasTitle } =
|
|
6
|
+
require("../helpers");
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
|
-
"names": [ "MD025", "single-h1" ],
|
|
9
|
+
"names": [ "MD025", "single-title", "single-h1" ],
|
|
9
10
|
"description": "Multiple top level headings in the same document",
|
|
10
11
|
"tags": [ "headings", "headers" ],
|
|
11
12
|
"function": function MD025(params, onError) {
|
|
12
13
|
const level = params.config.level || 1;
|
|
13
14
|
const tag = "h" + level;
|
|
15
|
+
const foundFrontMatterTitle =
|
|
16
|
+
frontMatterHasTitle(
|
|
17
|
+
params.frontMatterLines,
|
|
18
|
+
params.config.front_matter_title
|
|
19
|
+
);
|
|
14
20
|
let hasTopLevelHeading = false;
|
|
15
|
-
|
|
21
|
+
filterTokens(params, "heading_open", function forToken(token) {
|
|
16
22
|
if (token.tag === tag) {
|
|
17
|
-
if (hasTopLevelHeading) {
|
|
18
|
-
|
|
23
|
+
if (hasTopLevelHeading || foundFrontMatterTitle) {
|
|
24
|
+
addErrorContext(onError, token.lineNumber,
|
|
19
25
|
token.line.trim());
|
|
20
26
|
} else if (token.lineNumber === 1) {
|
|
21
27
|
hasTopLevelHeading = true;
|
package/lib/md026.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addError, forEachHeading, rangeFromRegExp } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD026", "no-trailing-punctuation" ],
|
|
@@ -11,12 +11,12 @@ module.exports = {
|
|
|
11
11
|
"function": function MD026(params, onError) {
|
|
12
12
|
const punctuation = params.config.punctuation || ".,;:!?";
|
|
13
13
|
const trailingPunctuationRe = new RegExp("[" + punctuation + "]$");
|
|
14
|
-
|
|
14
|
+
forEachHeading(params, function forHeading(heading, content) {
|
|
15
15
|
const match = trailingPunctuationRe.exec(content);
|
|
16
16
|
if (match) {
|
|
17
|
-
|
|
17
|
+
addError(onError, heading.lineNumber,
|
|
18
18
|
"Punctuation: '" + match[0] + "'", null,
|
|
19
|
-
|
|
19
|
+
rangeFromRegExp(heading.line, trailingPunctuationRe));
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
}
|
package/lib/md027.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, newLineRe, rangeFromRegExp } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
const spaceAfterBlockQuote = /^\s*(?:>\s+)+\S/;
|
|
8
8
|
|
|
@@ -27,15 +27,15 @@ module.exports = {
|
|
|
27
27
|
/^(\s*>)+\s\s+>/.test(token.line) :
|
|
28
28
|
/^(\s*>)+\s\s/.test(token.line);
|
|
29
29
|
if (multipleSpaces) {
|
|
30
|
-
|
|
31
|
-
null,
|
|
30
|
+
addErrorContext(onError, token.lineNumber, token.line, null,
|
|
31
|
+
null, rangeFromRegExp(token.line, spaceAfterBlockQuote));
|
|
32
32
|
}
|
|
33
|
-
token.content.split(
|
|
33
|
+
token.content.split(newLineRe)
|
|
34
34
|
.forEach(function forLine(line, offset) {
|
|
35
35
|
if (/^\s/.test(line)) {
|
|
36
|
-
|
|
36
|
+
addErrorContext(onError, token.lineNumber + offset,
|
|
37
37
|
"> " + line, null, null,
|
|
38
|
-
|
|
38
|
+
rangeFromRegExp(line, spaceAfterBlockQuote));
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
}
|
package/lib/md028.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addError } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD028", "no-blanks-blockquote" ],
|
|
@@ -13,7 +13,7 @@ module.exports = {
|
|
|
13
13
|
params.tokens.forEach(function forToken(token) {
|
|
14
14
|
if ((token.type === "blockquote_open") &&
|
|
15
15
|
(prevToken.type === "blockquote_close")) {
|
|
16
|
-
|
|
16
|
+
addError(onError, token.lineNumber - 1);
|
|
17
17
|
}
|
|
18
18
|
prevToken = token;
|
|
19
19
|
});
|
package/lib/md029.js
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
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
|
+
};
|
|
6
14
|
|
|
7
15
|
module.exports = {
|
|
8
16
|
"names": [ "MD029", "ol-prefix" ],
|
|
@@ -10,21 +18,21 @@ module.exports = {
|
|
|
10
18
|
"tags": [ "ol" ],
|
|
11
19
|
"function": function MD029(params, onError) {
|
|
12
20
|
const style = params.config.style || "one_or_ordered";
|
|
13
|
-
|
|
21
|
+
flattenedLists().forEach((list) => {
|
|
14
22
|
if (!list.unordered) {
|
|
15
23
|
let listStyle = style;
|
|
16
24
|
if (listStyle === "one_or_ordered") {
|
|
17
25
|
const second = (list.items.length > 1) &&
|
|
18
|
-
|
|
26
|
+
orderedListItemMarkerRe.exec(list.items[1].line);
|
|
19
27
|
listStyle = (second && (second[1] !== "1")) ? "ordered" : "one";
|
|
20
28
|
}
|
|
21
|
-
let number = 1;
|
|
22
|
-
list.items.forEach(
|
|
23
|
-
const match =
|
|
24
|
-
|
|
29
|
+
let number = (listStyle === "zero") ? 0 : 1;
|
|
30
|
+
list.items.forEach((item) => {
|
|
31
|
+
const match = orderedListItemMarkerRe.exec(item.line);
|
|
32
|
+
addErrorDetailIf(onError, item.lineNumber,
|
|
25
33
|
String(number), !match || match[1],
|
|
26
|
-
"Style: " +
|
|
27
|
-
|
|
34
|
+
"Style: " + listStyleExamples[listStyle], null,
|
|
35
|
+
rangeFromRegExp(item.line, listItemMarkerRe));
|
|
28
36
|
if (listStyle === "ordered") {
|
|
29
37
|
number++;
|
|
30
38
|
}
|
package/lib/md030.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorDetailIf, listItemMarkerRe, rangeFromRegExp } =
|
|
6
|
+
require("../helpers");
|
|
7
|
+
const { flattenedLists } = require("./cache");
|
|
6
8
|
|
|
7
9
|
module.exports = {
|
|
8
10
|
"names": [ "MD030", "list-marker-space" ],
|
|
@@ -13,17 +15,17 @@ module.exports = {
|
|
|
13
15
|
const olSingle = params.config.ol_single || 1;
|
|
14
16
|
const ulMulti = params.config.ul_multi || 1;
|
|
15
17
|
const olMulti = params.config.ol_multi || 1;
|
|
16
|
-
|
|
18
|
+
flattenedLists().forEach((list) => {
|
|
17
19
|
const lineCount = list.lastLineIndex - list.open.map[0];
|
|
18
20
|
const allSingle = lineCount === list.items.length;
|
|
19
21
|
const expectedSpaces = list.unordered ?
|
|
20
22
|
(allSingle ? ulSingle : ulMulti) :
|
|
21
23
|
(allSingle ? olSingle : olMulti);
|
|
22
|
-
list.items.forEach(
|
|
24
|
+
list.items.forEach((item) => {
|
|
23
25
|
const match = /^[\s>]*\S+(\s+)/.exec(item.line);
|
|
24
|
-
|
|
25
|
-
expectedSpaces, (match ? match[1].length : 0), null,
|
|
26
|
-
|
|
26
|
+
addErrorDetailIf(onError, item.lineNumber,
|
|
27
|
+
expectedSpaces, (match ? match[1].length : 0), null, null,
|
|
28
|
+
rangeFromRegExp(item.line, listItemMarkerRe));
|
|
27
29
|
});
|
|
28
30
|
});
|
|
29
31
|
}
|
package/lib/md031.js
CHANGED
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, forEachLine, isBlankLine } = require("../helpers");
|
|
6
|
+
const { lineMetadata } = require("./cache");
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
"names": [ "MD031", "blanks-around-fences" ],
|
|
9
10
|
"description": "Fenced code blocks should be surrounded by blank lines",
|
|
10
11
|
"tags": [ "code", "blank_lines" ],
|
|
11
12
|
"function": function MD031(params, onError) {
|
|
12
|
-
const lines = params
|
|
13
|
-
|
|
14
|
-
if (((onFence > 0) && (
|
|
15
|
-
((onFence < 0) && (
|
|
16
|
-
|
|
13
|
+
const { lines } = params;
|
|
14
|
+
forEachLine(lineMetadata(), (line, i, inCode, onFence) => {
|
|
15
|
+
if (((onFence > 0) && !isBlankLine(lines[i - 1])) ||
|
|
16
|
+
((onFence < 0) && !isBlankLine(lines[i + 1]))) {
|
|
17
|
+
addErrorContext(onError, i + 1, lines[i].trim());
|
|
17
18
|
}
|
|
18
19
|
});
|
|
19
20
|
}
|
package/lib/md032.js
CHANGED
|
@@ -2,25 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const blankLineRe = /^[\s>]*$/;
|
|
5
|
+
const { addErrorContext, isBlankLine } = require("../helpers");
|
|
6
|
+
const { flattenedLists } = require("./cache");
|
|
8
7
|
|
|
9
8
|
module.exports = {
|
|
10
9
|
"names": [ "MD032", "blanks-around-lists" ],
|
|
11
10
|
"description": "Lists should be surrounded by blank lines",
|
|
12
11
|
"tags": [ "bullet", "ul", "ol", "blank_lines" ],
|
|
13
12
|
"function": function MD032(params, onError) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const { lines } = params;
|
|
14
|
+
flattenedLists().filter((list) => !list.nesting).forEach((list) => {
|
|
15
|
+
const firstIndex = list.open.map[0];
|
|
16
|
+
if (!isBlankLine(lines[firstIndex - 1])) {
|
|
17
|
+
addErrorContext(onError, firstIndex + 1, lines[firstIndex].trim());
|
|
19
18
|
}
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
22
|
-
|
|
23
|
-
onError, bottomLineIndex + 1, params.lines[bottomLineIndex].trim());
|
|
19
|
+
const lastIndex = list.lastLineIndex - 1;
|
|
20
|
+
if (!isBlankLine(lines[lastIndex + 1])) {
|
|
21
|
+
addErrorContext(onError, lastIndex + 1, lines[lastIndex].trim());
|
|
24
22
|
}
|
|
25
23
|
});
|
|
26
24
|
}
|
package/lib/md033.js
CHANGED
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addError, bareUrlRe, forEachLine, unescapeMarkdown } =
|
|
6
|
+
require("../helpers");
|
|
7
|
+
const { lineMetadata } = require("./cache");
|
|
6
8
|
|
|
7
|
-
const
|
|
9
|
+
const htmlElementRe = /<(([\w-]+)(?:[\s/][^>]*)?)>/g;
|
|
10
|
+
const linkDestinationRe = /]\(\s*$/;
|
|
11
|
+
const inlineCodeRe = /^[^`]*(`+[^`]+`+[^`]+)*`+[^`]*$/;
|
|
12
|
+
// See https://spec.commonmark.org/0.29/#autolinks
|
|
13
|
+
const emailAddressRe =
|
|
14
|
+
// eslint-disable-next-line max-len
|
|
15
|
+
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
8
16
|
|
|
9
17
|
module.exports = {
|
|
10
18
|
"names": [ "MD033", "no-inline-html" ],
|
|
@@ -12,30 +20,23 @@ module.exports = {
|
|
|
12
20
|
"tags": [ "html" ],
|
|
13
21
|
"function": function MD033(params, onError) {
|
|
14
22
|
const allowedElements = (params.config.allowed_elements || [])
|
|
15
|
-
.map(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return allowedElements.indexOf(element) === -1;
|
|
30
|
-
});
|
|
31
|
-
if (allowed.length) {
|
|
32
|
-
shared.addError(onError, token.lineNumber + offset,
|
|
33
|
-
"Element: " + allowed[0], null,
|
|
34
|
-
shared.rangeFromRegExp(token.line, htmlRe));
|
|
23
|
+
.map((element) => element.toLowerCase());
|
|
24
|
+
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
|
25
|
+
let match = null;
|
|
26
|
+
// eslint-disable-next-line no-unmodified-loop-condition
|
|
27
|
+
while (!inCode && (match = htmlElementRe.exec(line))) {
|
|
28
|
+
const [ tag, content, element ] = match;
|
|
29
|
+
if (!allowedElements.includes(element.toLowerCase()) &&
|
|
30
|
+
!tag.endsWith("\\>") && !bareUrlRe.test(content) &&
|
|
31
|
+
!emailAddressRe.test(content)) {
|
|
32
|
+
const prefix = line.substring(0, match.index);
|
|
33
|
+
if (!linkDestinationRe.test(prefix) && !inlineCodeRe.test(prefix) &&
|
|
34
|
+
!unescapeMarkdown(prefix + "<", "_").endsWith("_")) {
|
|
35
|
+
addError(onError, lineIndex + 1, "Element: " + element,
|
|
36
|
+
null, [ match.index + 1, tag.length ]);
|
|
35
37
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
shared.forEachInlineChild(params, "html_inline", forToken);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
40
41
|
}
|
|
41
42
|
};
|
package/lib/md034.js
CHANGED
|
@@ -2,26 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, bareUrlRe, filterTokens } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD034", "no-bare-urls" ],
|
|
9
9
|
"description": "Bare URL used",
|
|
10
10
|
"tags": [ "links", "url" ],
|
|
11
11
|
"function": function MD034(params, onError) {
|
|
12
|
-
|
|
12
|
+
filterTokens(params, "inline", (token) => {
|
|
13
13
|
let inLink = false;
|
|
14
|
-
token.children.forEach(
|
|
14
|
+
token.children.forEach((child) => {
|
|
15
|
+
const { content, line, lineNumber, type } = child;
|
|
15
16
|
let match = null;
|
|
16
|
-
if (
|
|
17
|
+
if (type === "link_open") {
|
|
17
18
|
inLink = true;
|
|
18
|
-
} else if (
|
|
19
|
+
} else if (type === "link_close") {
|
|
19
20
|
inLink = false;
|
|
20
|
-
} else if ((
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
} else if ((type === "text") && !inLink &&
|
|
22
|
+
(match = bareUrlRe.exec(content))) {
|
|
23
|
+
const [ bareUrl ] = match;
|
|
24
|
+
const index = line.indexOf(content);
|
|
25
|
+
const range = (index === -1) ? null : [
|
|
26
|
+
line.indexOf(content) + match.index + 1,
|
|
27
|
+
bareUrl.length
|
|
28
|
+
];
|
|
29
|
+
addErrorContext(onError, lineNumber, bareUrl, null, null, range);
|
|
25
30
|
}
|
|
26
31
|
});
|
|
27
32
|
});
|
package/lib/md035.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorDetailIf, filterTokens } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD035", "hr-style" ],
|
|
@@ -10,12 +10,12 @@ module.exports = {
|
|
|
10
10
|
"tags": [ "hr" ],
|
|
11
11
|
"function": function MD035(params, onError) {
|
|
12
12
|
let style = params.config.style || "consistent";
|
|
13
|
-
|
|
13
|
+
filterTokens(params, "hr", function forToken(token) {
|
|
14
14
|
const lineTrim = token.line.trim();
|
|
15
15
|
if (style === "consistent") {
|
|
16
16
|
style = lineTrim;
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
addErrorDetailIf(onError, token.lineNumber, style, lineTrim);
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
};
|
package/lib/md036.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ],
|
|
@@ -24,7 +24,7 @@ module.exports = {
|
|
|
24
24
|
(children[0].type === "em_open")) &&
|
|
25
25
|
(children[1].type === "text") &&
|
|
26
26
|
!re.test(children[1].content)) {
|
|
27
|
-
|
|
27
|
+
addErrorContext(onError, t.lineNumber,
|
|
28
28
|
children[1].content);
|
|
29
29
|
}
|
|
30
30
|
return base;
|
package/lib/md037.js
CHANGED
|
@@ -2,27 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, forEachInlineChild } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD037", "no-space-in-emphasis" ],
|
|
9
9
|
"description": "Spaces inside emphasis markers",
|
|
10
10
|
"tags": [ "whitespace", "emphasis" ],
|
|
11
11
|
"function": function MD037(params, onError) {
|
|
12
|
-
|
|
12
|
+
forEachInlineChild(params, "text", (token) => {
|
|
13
13
|
let left = true;
|
|
14
|
-
let match =
|
|
14
|
+
let match = /(?:^|\s)(\*\*?|__?)\s.*[^\\]\1/.exec(token.content);
|
|
15
15
|
if (!match) {
|
|
16
16
|
left = false;
|
|
17
|
-
match = /(\*\*?|__?).+\s\1
|
|
17
|
+
match = /(?:^|[^\\])(\*\*?|__?).+\s\1(?:\s|$)/.exec(token.content);
|
|
18
18
|
}
|
|
19
19
|
if (match) {
|
|
20
|
-
const
|
|
20
|
+
const fullText = match[0];
|
|
21
21
|
const line = params.lines[token.lineNumber - 1];
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
if (line.includes(fullText)) {
|
|
23
|
+
const text = fullText.trim();
|
|
24
|
+
const column = line.indexOf(text) + 1;
|
|
25
|
+
const length = text.length;
|
|
26
|
+
addErrorContext(onError, token.lineNumber,
|
|
27
|
+
text, left, !left, [ column, length ]);
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
});
|
|
28
31
|
}
|
package/lib/md038.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } =
|
|
6
|
+
require("../helpers");
|
|
6
7
|
|
|
7
8
|
const startRe = /^\s([^`]|$)/;
|
|
8
9
|
const endRe = /[^`]\s$/;
|
|
@@ -12,16 +13,16 @@ module.exports = {
|
|
|
12
13
|
"description": "Spaces inside code span elements",
|
|
13
14
|
"tags": [ "whitespace", "code" ],
|
|
14
15
|
"function": function MD038(params, onError) {
|
|
15
|
-
|
|
16
|
+
filterTokens(params, "inline", (token) => {
|
|
16
17
|
if (token.children.some((child) => child.type === "code_inline")) {
|
|
17
18
|
const tokenLines = params.lines.slice(token.map[0], token.map[1]);
|
|
18
|
-
|
|
19
|
+
forEachInlineCodeSpan(
|
|
19
20
|
tokenLines.join("\n"),
|
|
20
21
|
(code, lineIndex, columnIndex, tickCount) => {
|
|
21
22
|
let rangeIndex = columnIndex - tickCount;
|
|
22
23
|
let rangeLength = code.length + (2 * tickCount);
|
|
23
24
|
let rangeLineOffset = 0;
|
|
24
|
-
const codeLines = code.split(
|
|
25
|
+
const codeLines = code.split(newLineRe);
|
|
25
26
|
const left = startRe.test(code);
|
|
26
27
|
const right = !left && endRe.test(code);
|
|
27
28
|
if (right && (codeLines.length > 1)) {
|
|
@@ -34,7 +35,7 @@ module.exports = {
|
|
|
34
35
|
}
|
|
35
36
|
const context = tokenLines[lineIndex + rangeLineOffset]
|
|
36
37
|
.substring(rangeIndex, rangeIndex + rangeLength);
|
|
37
|
-
|
|
38
|
+
addErrorContext(
|
|
38
39
|
onError, token.lineNumber + lineIndex + rangeLineOffset,
|
|
39
40
|
context, left, right, [ rangeIndex + 1, rangeLength ]);
|
|
40
41
|
}
|
package/lib/md039.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, filterTokens, rangeFromRegExp } =
|
|
6
|
+
require("../helpers");
|
|
6
7
|
|
|
7
8
|
const spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/;
|
|
8
9
|
|
|
@@ -11,7 +12,7 @@ module.exports = {
|
|
|
11
12
|
"description": "Spaces inside link text",
|
|
12
13
|
"tags": [ "whitespace", "links" ],
|
|
13
14
|
"function": function MD039(params, onError) {
|
|
14
|
-
|
|
15
|
+
filterTokens(params, "inline", function forToken(token) {
|
|
15
16
|
let inLink = false;
|
|
16
17
|
let linkText = "";
|
|
17
18
|
token.children.forEach(function forChild(child) {
|
|
@@ -20,12 +21,12 @@ module.exports = {
|
|
|
20
21
|
linkText = "";
|
|
21
22
|
} else if (child.type === "link_close") {
|
|
22
23
|
inLink = false;
|
|
23
|
-
const left =
|
|
24
|
-
const right =
|
|
24
|
+
const left = linkText.trimLeft().length !== linkText.length;
|
|
25
|
+
const right = linkText.trimRight().length !== linkText.length;
|
|
25
26
|
if (left || right) {
|
|
26
|
-
|
|
27
|
+
addErrorContext(onError, token.lineNumber,
|
|
27
28
|
"[" + linkText + "]", left, right,
|
|
28
|
-
|
|
29
|
+
rangeFromRegExp(token.line, spaceInLinkRe));
|
|
29
30
|
}
|
|
30
31
|
} else if (inLink) {
|
|
31
32
|
linkText += child.content;
|
package/lib/md040.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const { addErrorContext, filterTokens } = require("../helpers");
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
"names": [ "MD040", "fenced-code-language" ],
|
|
9
9
|
"description": "Fenced code blocks should have a language specified",
|
|
10
10
|
"tags": [ "code", "language" ],
|
|
11
11
|
"function": function MD040(params, onError) {
|
|
12
|
-
|
|
12
|
+
filterTokens(params, "fence", function forToken(token) {
|
|
13
13
|
if (!token.info.trim()) {
|
|
14
|
-
|
|
14
|
+
addErrorContext(onError, token.lineNumber, token.line);
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
17
|
}
|