markdownlint 0.23.0 → 0.25.1
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 +13 -3
- package/LICENSE +1 -1
- package/README.md +53 -16
- package/demo/markdownlint-browser.js +769 -461
- package/doc/CustomRules.md +15 -4
- package/doc/Prettier.md +23 -0
- package/doc/Rules.md +100 -12
- package/helpers/LICENSE +1 -1
- package/helpers/helpers.js +199 -39
- package/helpers/package.json +1 -1
- package/lib/cache.js +14 -5
- package/lib/constants.js +7 -0
- package/lib/markdownlint.d.ts +30 -10
- package/lib/markdownlint.js +326 -247
- package/lib/md007.js +4 -2
- package/lib/md010.js +25 -16
- package/lib/md011.js +31 -27
- package/lib/md033.js +12 -8
- package/lib/md035.js +4 -4
- package/lib/md037.js +19 -5
- package/lib/md039.js +2 -1
- package/lib/md043.js +8 -4
- package/lib/md044.js +54 -71
- package/lib/md049.js +45 -0
- package/lib/md050.js +45 -0
- package/lib/rules.js +4 -4
- package/package.json +44 -34
- package/schema/.markdownlint.jsonc +19 -3
- package/schema/.markdownlint.yaml +15 -1
- package/schema/markdownlint-config-schema.json +108 -4
- package/schema/build-config-example.js +0 -53
- package/schema/build-config-schema.js +0 -420
package/lib/md007.js
CHANGED
|
@@ -13,12 +13,14 @@ module.exports = {
|
|
|
13
13
|
"function": function MD007(params, onError) {
|
|
14
14
|
const indent = Number(params.config.indent || 2);
|
|
15
15
|
const startIndented = !!params.config.start_indented;
|
|
16
|
+
const startIndent = Number(params.config.start_indent || indent);
|
|
16
17
|
flattenedLists().forEach((list) => {
|
|
17
18
|
if (list.unordered && list.parentsUnordered) {
|
|
18
19
|
list.items.forEach((item) => {
|
|
19
20
|
const { lineNumber, line } = item;
|
|
20
|
-
const
|
|
21
|
-
|
|
21
|
+
const expectedIndent =
|
|
22
|
+
(startIndented ? startIndent : 0) +
|
|
23
|
+
(list.nesting * indent);
|
|
22
24
|
const actualIndent = indentFor(item);
|
|
23
25
|
let range = null;
|
|
24
26
|
let editColumn = 1;
|
package/lib/md010.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError, forEachLine } = require("../helpers");
|
|
6
|
-
const { lineMetadata } = require("./cache");
|
|
5
|
+
const { addError, forEachLine, overlapsAnyRange } = require("../helpers");
|
|
6
|
+
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache");
|
|
7
7
|
|
|
8
8
|
const tabRe = /\t+/g;
|
|
9
9
|
|
|
@@ -13,24 +13,33 @@ module.exports = {
|
|
|
13
13
|
"tags": [ "whitespace", "hard_tab" ],
|
|
14
14
|
"function": function MD010(params, onError) {
|
|
15
15
|
const codeBlocks = params.config.code_blocks;
|
|
16
|
-
const
|
|
16
|
+
const includeCode = (codeBlocks === undefined) ? true : !!codeBlocks;
|
|
17
|
+
const spacesPerTab = params.config.spaces_per_tab;
|
|
18
|
+
const spaceMultiplier = (spacesPerTab === undefined) ?
|
|
19
|
+
1 :
|
|
20
|
+
Math.max(0, Number(spacesPerTab));
|
|
21
|
+
const exclusions = includeCode ? [] : codeBlockAndSpanRanges();
|
|
17
22
|
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
|
18
|
-
if (
|
|
23
|
+
if (includeCode || !inCode) {
|
|
19
24
|
let match = null;
|
|
20
25
|
while ((match = tabRe.exec(line)) !== null) {
|
|
21
|
-
const
|
|
26
|
+
const { index } = match;
|
|
27
|
+
const column = index + 1;
|
|
22
28
|
const length = match[0].length;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
if (!overlapsAnyRange(exclusions, lineIndex, index, length)) {
|
|
30
|
+
addError(
|
|
31
|
+
onError,
|
|
32
|
+
lineIndex + 1,
|
|
33
|
+
"Column: " + column,
|
|
34
|
+
null,
|
|
35
|
+
[ column, length ],
|
|
36
|
+
{
|
|
37
|
+
"editColumn": column,
|
|
38
|
+
"deleteCount": length,
|
|
39
|
+
"insertText": "".padEnd(length * spaceMultiplier)
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
34
43
|
}
|
|
35
44
|
}
|
|
36
45
|
});
|
package/lib/md011.js
CHANGED
|
@@ -2,40 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError,
|
|
6
|
-
|
|
5
|
+
const { addError, forEachLine, overlapsAnyRange } = require("../helpers");
|
|
6
|
+
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache");
|
|
7
7
|
|
|
8
|
-
const reversedLinkRe =
|
|
8
|
+
const reversedLinkRe =
|
|
9
|
+
/(^|[^\\])\(([^)]+)\)\[([^\]^][^\]]*)](?!\()/g;
|
|
9
10
|
|
|
10
11
|
module.exports = {
|
|
11
12
|
"names": [ "MD011", "no-reversed-links" ],
|
|
12
13
|
"description": "Reversed link syntax",
|
|
13
14
|
"tags": [ "links" ],
|
|
14
15
|
"function": function MD011(params, onError) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
16
|
+
const exclusions = codeBlockAndSpanRanges();
|
|
17
|
+
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence) => {
|
|
18
|
+
if (!inCode && !onFence) {
|
|
19
|
+
let match = null;
|
|
20
|
+
while ((match = reversedLinkRe.exec(line)) !== null) {
|
|
21
|
+
const [ reversedLink, preChar, linkText, linkDestination ] = match;
|
|
22
|
+
const index = match.index + preChar.length;
|
|
23
|
+
const length = match[0].length - preChar.length;
|
|
24
|
+
if (
|
|
25
|
+
!linkText.endsWith("\\") &&
|
|
26
|
+
!linkDestination.endsWith("\\") &&
|
|
27
|
+
!overlapsAnyRange(exclusions, lineIndex, index, length)
|
|
28
|
+
) {
|
|
29
|
+
addError(
|
|
30
|
+
onError,
|
|
31
|
+
lineIndex + 1,
|
|
32
|
+
reversedLink.slice(preChar.length),
|
|
33
|
+
null,
|
|
34
|
+
[ index + 1, length ],
|
|
35
|
+
{
|
|
36
|
+
"editColumn": index + 1,
|
|
37
|
+
"deleteCount": length,
|
|
38
|
+
"insertText": `[${linkText}](${linkDestination})`
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
});
|
|
41
45
|
}
|
package/lib/md033.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const {
|
|
6
|
-
|
|
5
|
+
const {
|
|
6
|
+
addError, forEachLine, overlapsAnyRange, unescapeMarkdown
|
|
7
|
+
} = require("../helpers");
|
|
8
|
+
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache");
|
|
7
9
|
|
|
8
10
|
const htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^>]*)?)\/?>/g;
|
|
9
11
|
const linkDestinationRe = /]\(\s*$/;
|
|
10
|
-
const inlineCodeRe = /^[^`]*(`+[^`]+`+[^`]+)*`+[^`]*$/;
|
|
11
12
|
// See https://spec.commonmark.org/0.29/#autolinks
|
|
12
13
|
const emailAddressRe =
|
|
13
14
|
// eslint-disable-next-line max-len
|
|
@@ -21,19 +22,22 @@ module.exports = {
|
|
|
21
22
|
let allowedElements = params.config.allowed_elements;
|
|
22
23
|
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
|
23
24
|
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
|
25
|
+
const exclusions = codeBlockAndSpanRanges();
|
|
24
26
|
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
|
25
27
|
let match = null;
|
|
26
28
|
// eslint-disable-next-line no-unmodified-loop-condition
|
|
27
29
|
while (!inCode && ((match = htmlElementRe.exec(line)) !== null)) {
|
|
28
30
|
const [ tag, content, element ] = match;
|
|
29
|
-
if (
|
|
31
|
+
if (
|
|
32
|
+
!allowedElements.includes(element.toLowerCase()) &&
|
|
30
33
|
!tag.endsWith("\\>") &&
|
|
31
|
-
!emailAddressRe.test(content)
|
|
34
|
+
!emailAddressRe.test(content) &&
|
|
35
|
+
!overlapsAnyRange(exclusions, lineIndex, match.index, match[0].length)
|
|
36
|
+
) {
|
|
32
37
|
const prefix = line.substring(0, match.index);
|
|
33
|
-
if (!linkDestinationRe.test(prefix)
|
|
38
|
+
if (!linkDestinationRe.test(prefix)) {
|
|
34
39
|
const unescaped = unescapeMarkdown(prefix + "<", "_");
|
|
35
|
-
if (!unescaped.endsWith("_")
|
|
36
|
-
((unescaped + "`").match(/`/g).length % 2)) {
|
|
40
|
+
if (!unescaped.endsWith("_")) {
|
|
37
41
|
addError(onError, lineIndex + 1, "Element: " + element,
|
|
38
42
|
null, [ match.index + 1, tag.length ]);
|
|
39
43
|
}
|
package/lib/md035.js
CHANGED
|
@@ -10,12 +10,12 @@ module.exports = {
|
|
|
10
10
|
"tags": [ "hr" ],
|
|
11
11
|
"function": function MD035(params, onError) {
|
|
12
12
|
let style = String(params.config.style || "consistent");
|
|
13
|
-
filterTokens(params, "hr",
|
|
14
|
-
const
|
|
13
|
+
filterTokens(params, "hr", (token) => {
|
|
14
|
+
const { lineNumber, markup } = token;
|
|
15
15
|
if (style === "consistent") {
|
|
16
|
-
style =
|
|
16
|
+
style = markup;
|
|
17
17
|
}
|
|
18
|
-
addErrorDetailIf(onError,
|
|
18
|
+
addErrorDetailIf(onError, lineNumber, style, markup);
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
};
|
package/lib/md037.js
CHANGED
|
@@ -7,6 +7,7 @@ const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine } =
|
|
|
7
7
|
const { lineMetadata } = require("./cache");
|
|
8
8
|
|
|
9
9
|
const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g;
|
|
10
|
+
const embeddedUnderscoreRe = /([A-Za-z0-9])_([A-Za-z0-9])/g;
|
|
10
11
|
const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/;
|
|
11
12
|
const leftSpaceRe = /^\s+/;
|
|
12
13
|
const rightSpaceRe = /\s+$/;
|
|
@@ -78,22 +79,35 @@ module.exports = {
|
|
|
78
79
|
lineMetadata(),
|
|
79
80
|
(line, lineIndex, inCode, onFence, inTable, inItem, onBreak, inMath) => {
|
|
80
81
|
const onItemStart = (inItem === 1);
|
|
81
|
-
if (
|
|
82
|
+
if (
|
|
83
|
+
inCode ||
|
|
84
|
+
onFence ||
|
|
85
|
+
inTable ||
|
|
86
|
+
onBreak ||
|
|
87
|
+
onItemStart ||
|
|
88
|
+
isBlankLine(line)
|
|
89
|
+
) {
|
|
82
90
|
// Emphasis resets when leaving a block
|
|
83
91
|
resetRunTracking();
|
|
84
92
|
}
|
|
85
|
-
if (
|
|
93
|
+
if (
|
|
94
|
+
inCode ||
|
|
95
|
+
onFence ||
|
|
96
|
+
onBreak ||
|
|
97
|
+
inMath
|
|
98
|
+
) {
|
|
86
99
|
// Emphasis has no meaning here
|
|
87
100
|
return;
|
|
88
101
|
}
|
|
102
|
+
let patchedLine = line.replace(embeddedUnderscoreRe, "$1 $2");
|
|
89
103
|
if (onItemStart) {
|
|
90
104
|
// Trim overlapping '*' list item marker
|
|
91
|
-
|
|
105
|
+
patchedLine = patchedLine.replace(asteriskListItemMarkerRe, "$1 $2");
|
|
92
106
|
}
|
|
93
107
|
let match = null;
|
|
94
108
|
// Match all emphasis-looking runs in the line...
|
|
95
|
-
while ((match = emphasisRe.exec(
|
|
96
|
-
const ignoreMarkersForLine = ignoreMarkersByLine[lineIndex]
|
|
109
|
+
while ((match = emphasisRe.exec(patchedLine))) {
|
|
110
|
+
const ignoreMarkersForLine = ignoreMarkersByLine[lineIndex];
|
|
97
111
|
const matchIndex = match.index + match[1].length;
|
|
98
112
|
if (ignoreMarkersForLine.includes(matchIndex)) {
|
|
99
113
|
// Ignore emphasis markers inside code spans and links
|
package/lib/md039.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
const { addErrorContext, filterTokens } = require("../helpers");
|
|
6
6
|
|
|
7
|
-
const spaceInLinkRe =
|
|
7
|
+
const spaceInLinkRe =
|
|
8
|
+
/\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=((?:\([^)]*\))|(?:\[[^\]]*\])))/;
|
|
8
9
|
|
|
9
10
|
module.exports = {
|
|
10
11
|
"names": [ "MD039", "no-space-in-links" ],
|
package/lib/md043.js
CHANGED
|
@@ -20,7 +20,6 @@ module.exports = {
|
|
|
20
20
|
let matchAny = false;
|
|
21
21
|
let hasError = false;
|
|
22
22
|
let anyHeadings = false;
|
|
23
|
-
// eslint-disable-next-line func-style
|
|
24
23
|
const getExpected = () => requiredHeadings[i++] || "[None]";
|
|
25
24
|
forEachHeading(params, (heading, content) => {
|
|
26
25
|
if (!hasError) {
|
|
@@ -28,8 +27,11 @@ module.exports = {
|
|
|
28
27
|
const actual = levels[heading.tag] + " " + content;
|
|
29
28
|
const expected = getExpected();
|
|
30
29
|
if (expected === "*") {
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const nextExpected = getExpected();
|
|
31
|
+
if (nextExpected.toLowerCase() !== actual.toLowerCase()) {
|
|
32
|
+
matchAny = true;
|
|
33
|
+
i--;
|
|
34
|
+
}
|
|
33
35
|
} else if (expected === "+") {
|
|
34
36
|
matchAny = true;
|
|
35
37
|
} else if (expected.toLowerCase() === actual.toLowerCase()) {
|
|
@@ -43,9 +45,11 @@ module.exports = {
|
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
});
|
|
48
|
+
const extraHeadings = requiredHeadings.length - i;
|
|
46
49
|
if (
|
|
47
50
|
!hasError &&
|
|
48
|
-
(
|
|
51
|
+
((extraHeadings > 1) ||
|
|
52
|
+
((extraHeadings === 1) && (requiredHeadings[i] !== "*"))) &&
|
|
49
53
|
(anyHeadings || !requiredHeadings.every((heading) => heading === "*"))
|
|
50
54
|
) {
|
|
51
55
|
addErrorContext(onError, params.lines.length,
|
package/lib/md044.js
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf, bareUrlRe, escapeForRegExp,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const startNonWordRe = /^\W/;
|
|
9
|
-
const endNonWordRe = /\W$/;
|
|
5
|
+
const { addErrorDetailIf, bareUrlRe, escapeForRegExp, forEachLine,
|
|
6
|
+
overlapsAnyRange, linkRe, linkReferenceRe } = require("../helpers");
|
|
7
|
+
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache");
|
|
10
8
|
|
|
11
9
|
module.exports = {
|
|
12
10
|
"names": [ "MD044", "proper-names" ],
|
|
@@ -15,80 +13,65 @@ module.exports = {
|
|
|
15
13
|
"function": function MD044(params, onError) {
|
|
16
14
|
let names = params.config.names;
|
|
17
15
|
names = Array.isArray(names) ? names : [];
|
|
16
|
+
names.sort((a, b) => (b.length - a.length) || a.localeCompare(b));
|
|
18
17
|
const codeBlocks = params.config.code_blocks;
|
|
19
18
|
const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} else if (type === "link_close") {
|
|
29
|
-
inAutoLink = false;
|
|
30
|
-
} else if ((type === "text") && inAutoLink) {
|
|
31
|
-
autolinkText.add(child);
|
|
19
|
+
const exclusions = [];
|
|
20
|
+
forEachLine(lineMetadata(), (line, lineIndex) => {
|
|
21
|
+
if (linkReferenceRe.test(line)) {
|
|
22
|
+
exclusions.push([ lineIndex, 0, line.length ]);
|
|
23
|
+
} else {
|
|
24
|
+
let match = null;
|
|
25
|
+
while ((match = bareUrlRe.exec(line)) !== null) {
|
|
26
|
+
exclusions.push([ lineIndex, match.index, match[0].length ]);
|
|
32
27
|
}
|
|
33
|
-
|
|
28
|
+
while ((match = linkRe.exec(line)) !== null) {
|
|
29
|
+
const [ , text, destination ] = match;
|
|
30
|
+
if (destination) {
|
|
31
|
+
exclusions.push(
|
|
32
|
+
[ lineIndex, match.index + text.length, destination.length ]
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
34
37
|
});
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
if (!includeCodeBlocks) {
|
|
39
|
+
exclusions.push(...codeBlockAndSpanRanges());
|
|
40
|
+
}
|
|
41
|
+
for (const name of names) {
|
|
37
42
|
const escapedName = escapeForRegExp(name);
|
|
38
|
-
const startNamePattern =
|
|
39
|
-
const endNamePattern =
|
|
43
|
+
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
|
44
|
+
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
|
40
45
|
const namePattern =
|
|
41
|
-
`(${startNamePattern})(${escapedName})
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const fixInfo = (matchIndex === -1) ?
|
|
64
|
-
null :
|
|
65
|
-
{
|
|
66
|
-
"editColumn": matchIndex + 1,
|
|
67
|
-
"deleteCount": matchLength,
|
|
68
|
-
"insertText": name
|
|
69
|
-
};
|
|
70
|
-
addErrorDetailIf(
|
|
71
|
-
onError,
|
|
72
|
-
lineNumber,
|
|
73
|
-
name,
|
|
74
|
-
nameMatch,
|
|
75
|
-
null,
|
|
76
|
-
null,
|
|
77
|
-
range,
|
|
78
|
-
fixInfo
|
|
79
|
-
);
|
|
46
|
+
`(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
47
|
+
const nameRe = new RegExp(namePattern, "gi");
|
|
48
|
+
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence) => {
|
|
49
|
+
if (includeCodeBlocks || (!inCode && !onFence)) {
|
|
50
|
+
let match = null;
|
|
51
|
+
while ((match = nameRe.exec(line)) !== null) {
|
|
52
|
+
const [ , leftMatch, nameMatch ] = match;
|
|
53
|
+
const index = match.index + leftMatch.length;
|
|
54
|
+
const length = nameMatch.length;
|
|
55
|
+
if (!overlapsAnyRange(exclusions, lineIndex, index, length)) {
|
|
56
|
+
addErrorDetailIf(
|
|
57
|
+
onError,
|
|
58
|
+
lineIndex + 1,
|
|
59
|
+
name,
|
|
60
|
+
nameMatch,
|
|
61
|
+
null,
|
|
62
|
+
null,
|
|
63
|
+
[ index + 1, length ],
|
|
64
|
+
{
|
|
65
|
+
"editColumn": index + 1,
|
|
66
|
+
"deleteCount": length,
|
|
67
|
+
"insertText": name
|
|
80
68
|
}
|
|
81
|
-
|
|
69
|
+
);
|
|
82
70
|
}
|
|
83
|
-
|
|
71
|
+
exclusions.push([ lineIndex, index, length ]);
|
|
72
|
+
}
|
|
84
73
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (includeCodeBlocks) {
|
|
88
|
-
forEachInlineChild(params, "code_inline", forToken);
|
|
89
|
-
filterTokens(params, "code_block", forToken);
|
|
90
|
-
filterTokens(params, "fence", forToken);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
93
76
|
}
|
|
94
77
|
};
|
package/lib/md049.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addError, emphasisOrStrongStyleFor, forEachInlineChild,
|
|
6
|
+
getNextChildToken, getRangeAndFixInfoIfFound } = require("../helpers");
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
"names": [ "MD049", "emphasis-style" ],
|
|
10
|
+
"description": "Emphasis style should be consistent",
|
|
11
|
+
"tags": [ "emphasis" ],
|
|
12
|
+
"function": function MD049(params, onError) {
|
|
13
|
+
let expectedStyle = String(params.config.style || "consistent");
|
|
14
|
+
forEachInlineChild(params, "em_open", (token, parent) => {
|
|
15
|
+
const { lineNumber, markup } = token;
|
|
16
|
+
const markupStyle = emphasisOrStrongStyleFor(markup);
|
|
17
|
+
if (expectedStyle === "consistent") {
|
|
18
|
+
expectedStyle = markupStyle;
|
|
19
|
+
}
|
|
20
|
+
if (expectedStyle !== markupStyle) {
|
|
21
|
+
let rangeAndFixInfo = {};
|
|
22
|
+
const contentToken = getNextChildToken(
|
|
23
|
+
parent, token, "text", "em_close"
|
|
24
|
+
);
|
|
25
|
+
if (contentToken) {
|
|
26
|
+
const { content } = contentToken;
|
|
27
|
+
const actual = `${markup}${content}${markup}`;
|
|
28
|
+
const expectedMarkup = (expectedStyle === "asterisk") ? "*" : "_";
|
|
29
|
+
const expected = `${expectedMarkup}${content}${expectedMarkup}`;
|
|
30
|
+
rangeAndFixInfo = getRangeAndFixInfoIfFound(
|
|
31
|
+
params.lines, lineNumber - 1, actual, expected
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
addError(
|
|
35
|
+
onError,
|
|
36
|
+
lineNumber,
|
|
37
|
+
`Expected: ${expectedStyle}; Actual: ${markupStyle}`,
|
|
38
|
+
null,
|
|
39
|
+
rangeAndFixInfo.range,
|
|
40
|
+
rangeAndFixInfo.fixInfo
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
package/lib/md050.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { addError, emphasisOrStrongStyleFor, forEachInlineChild,
|
|
6
|
+
getNextChildToken, getRangeAndFixInfoIfFound } = require("../helpers");
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
"names": [ "MD050", "strong-style" ],
|
|
10
|
+
"description": "Strong style should be consistent",
|
|
11
|
+
"tags": [ "emphasis" ],
|
|
12
|
+
"function": function MD050(params, onError) {
|
|
13
|
+
let expectedStyle = String(params.config.style || "consistent");
|
|
14
|
+
forEachInlineChild(params, "strong_open", (token, parent) => {
|
|
15
|
+
const { lineNumber, markup } = token;
|
|
16
|
+
const markupStyle = emphasisOrStrongStyleFor(markup);
|
|
17
|
+
if (expectedStyle === "consistent") {
|
|
18
|
+
expectedStyle = markupStyle;
|
|
19
|
+
}
|
|
20
|
+
if (expectedStyle !== markupStyle) {
|
|
21
|
+
let rangeAndFixInfo = {};
|
|
22
|
+
const contentToken = getNextChildToken(
|
|
23
|
+
parent, token, "text", "strong_close"
|
|
24
|
+
);
|
|
25
|
+
if (contentToken) {
|
|
26
|
+
const { content } = contentToken;
|
|
27
|
+
const actual = `${markup}${content}${markup}`;
|
|
28
|
+
const expectedMarkup = (expectedStyle === "asterisk") ? "**" : "__";
|
|
29
|
+
const expected = `${expectedMarkup}${content}${expectedMarkup}`;
|
|
30
|
+
rangeAndFixInfo = getRangeAndFixInfoIfFound(
|
|
31
|
+
params.lines, lineNumber - 1, actual, expected
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
addError(
|
|
35
|
+
onError,
|
|
36
|
+
lineNumber,
|
|
37
|
+
`Expected: ${expectedStyle}; Actual: ${markupStyle}`,
|
|
38
|
+
null,
|
|
39
|
+
rangeAndFixInfo.range,
|
|
40
|
+
rangeAndFixInfo.fixInfo
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
package/lib/rules.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const homepage = packageJson.homepage;
|
|
7
|
-
const version = packageJson.version;
|
|
5
|
+
const { homepage, version } = require("./constants");
|
|
8
6
|
|
|
9
7
|
const rules = [
|
|
10
8
|
require("./md001"),
|
|
@@ -50,7 +48,9 @@ const rules = [
|
|
|
50
48
|
require("./md045"),
|
|
51
49
|
require("./md046"),
|
|
52
50
|
require("./md047"),
|
|
53
|
-
require("./md048")
|
|
51
|
+
require("./md048"),
|
|
52
|
+
require("./md049"),
|
|
53
|
+
require("./md050")
|
|
54
54
|
];
|
|
55
55
|
rules.forEach((rule) => {
|
|
56
56
|
const name = rule.names[0].toLowerCase();
|