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.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +47 -47
  2. package/LICENSE +21 -21
  3. package/README.md +881 -868
  4. package/demo/markdownlint-browser.js +5438 -5306
  5. package/doc/CustomRules.md +313 -313
  6. package/doc/Rules.md +1847 -1795
  7. package/helpers/LICENSE +21 -21
  8. package/helpers/README.md +50 -50
  9. package/helpers/helpers.js +687 -627
  10. package/helpers/package.json +18 -18
  11. package/lib/cache.js +24 -24
  12. package/lib/markdownlint.d.ts +352 -352
  13. package/lib/markdownlint.js +1101 -1101
  14. package/lib/md001.js +22 -22
  15. package/lib/md002.js +22 -22
  16. package/lib/md003.js +42 -42
  17. package/lib/md004.js +43 -43
  18. package/lib/md005.js +69 -69
  19. package/lib/md006.js +34 -34
  20. package/lib/md007.js +47 -47
  21. package/lib/md009.js +77 -77
  22. package/lib/md010.js +38 -38
  23. package/lib/md011.js +38 -38
  24. package/lib/md012.js +32 -32
  25. package/lib/md013.js +99 -99
  26. package/lib/md014.js +53 -53
  27. package/lib/md018.js +34 -34
  28. package/lib/md019.js +39 -39
  29. package/lib/md020.js +62 -62
  30. package/lib/md021.js +60 -60
  31. package/lib/md022.js +56 -56
  32. package/lib/md023.js +38 -38
  33. package/lib/md024.js +38 -38
  34. package/lib/md025.js +32 -32
  35. package/lib/md026.js +40 -40
  36. package/lib/md027.js +56 -56
  37. package/lib/md028.js +38 -38
  38. package/lib/md029.js +66 -66
  39. package/lib/md030.js +50 -50
  40. package/lib/md031.js +39 -39
  41. package/lib/md032.js +50 -50
  42. package/lib/md033.js +45 -45
  43. package/lib/md034.js +61 -61
  44. package/lib/md035.js +21 -21
  45. package/lib/md036.js +56 -56
  46. package/lib/md037.js +150 -89
  47. package/lib/md038.js +68 -68
  48. package/lib/md039.js +64 -64
  49. package/lib/md040.js +18 -18
  50. package/lib/md041.js +31 -31
  51. package/lib/md042.js +41 -41
  52. package/lib/md043.js +45 -45
  53. package/lib/md044.js +77 -71
  54. package/lib/md045.js +18 -18
  55. package/lib/md046.js +32 -32
  56. package/lib/md047.js +28 -28
  57. package/lib/md048.js +29 -29
  58. package/lib/rules.js +61 -61
  59. package/package.json +73 -67
  60. package/schema/build-config-schema.js +405 -405
  61. package/schema/markdownlint-config-schema.json +1550 -1550
  62. package/style/all.json +5 -5
  63. package/style/cirosantilli.json +22 -22
  64. package/style/relaxed.json +13 -13
package/lib/md037.js CHANGED
@@ -1,89 +1,150 @@
1
- // @ts-check
2
-
3
- "use strict";
4
-
5
- const { addErrorContext, forEachLine } = require("../helpers");
6
- const { lineMetadata } = require("./cache");
7
-
8
- const emphasisRe = /(^|[^\\])(?:(\*\*?\*?)|(__?_?))/g;
9
- const asteriskListItemMarkerRe = /^(\s*)\*(\s+)/;
10
- const leftSpaceRe = /^\s+/;
11
- const rightSpaceRe = /\s+$/;
12
-
13
- module.exports = {
14
- "names": [ "MD037", "no-space-in-emphasis" ],
15
- "description": "Spaces inside emphasis markers",
16
- "tags": [ "whitespace", "emphasis" ],
17
- "function": function MD037(params, onError) {
18
- forEachLine(
19
- lineMetadata(),
20
- (line, lineIndex, inCode, onFence, inTable, inItem, inBreak) => {
21
- if (inCode || inBreak) {
22
- // Emphasis has no meaning here
23
- return;
24
- }
25
- if (inItem === 1) {
26
- // Trim overlapping '*' list item marker
27
- line = line.replace(asteriskListItemMarkerRe, "$1 $2");
28
- }
29
- let match = null;
30
- let emphasisIndex = -1;
31
- let emphasisLength = 0;
32
- let effectiveEmphasisLength = 0;
33
- // Match all emphasis-looking runs in the line...
34
- while ((match = emphasisRe.exec(line))) {
35
- const matchIndex = match.index + match[1].length;
36
- const matchLength = match[0].length - match[1].length;
37
- if (emphasisIndex === -1) {
38
- // New run
39
- emphasisIndex = matchIndex + matchLength;
40
- emphasisLength = matchLength;
41
- effectiveEmphasisLength = matchLength;
42
- } else if (matchLength === effectiveEmphasisLength) {
43
- // Close current run
44
- const content = line.substring(emphasisIndex, matchIndex);
45
- const leftSpace = leftSpaceRe.test(content);
46
- const rightSpace = rightSpaceRe.test(content);
47
- if (leftSpace || rightSpace) {
48
- // Report the violation
49
- const contextStart = emphasisIndex - emphasisLength;
50
- const contextEnd = matchIndex + effectiveEmphasisLength;
51
- const context = line.substring(contextStart, contextEnd);
52
- const column = contextStart + 1;
53
- const length = contextEnd - contextStart;
54
- const leftMarker = line.substring(contextStart, emphasisIndex);
55
- const rightMarker = match[2] || match[3];
56
- const fixedText = `${leftMarker}${content.trim()}${rightMarker}`;
57
- addErrorContext(
58
- onError,
59
- lineIndex + 1,
60
- context,
61
- leftSpace,
62
- rightSpace,
63
- [ column, length ],
64
- {
65
- "editColumn": column,
66
- "deleteCount": length,
67
- "insertText": fixedText
68
- }
69
- );
70
- }
71
- // Reset
72
- emphasisIndex = -1;
73
- emphasisLength = 0;
74
- effectiveEmphasisLength = 0;
75
- } else if (matchLength === 3) {
76
- // Swap internal run length (1->2 or 2->1)
77
- effectiveEmphasisLength = matchLength - effectiveEmphasisLength;
78
- } else if (effectiveEmphasisLength === 3) {
79
- // Downgrade internal run (3->1 or 3->2)
80
- effectiveEmphasisLength -= matchLength;
81
- } else {
82
- // Upgrade to internal run (1->3 or 2->3)
83
- effectiveEmphasisLength += matchLength;
84
- }
85
- }
86
- }
87
- );
88
- }
89
- };
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine } =
6
+ require("../helpers");
7
+ const { lineMetadata } = require("./cache");
8
+
9
+ const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g;
10
+ const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/;
11
+ const leftSpaceRe = /^\s+/;
12
+ const rightSpaceRe = /\s+$/;
13
+
14
+ module.exports = {
15
+ "names": [ "MD037", "no-space-in-emphasis" ],
16
+ "description": "Spaces inside emphasis markers",
17
+ "tags": [ "whitespace", "emphasis" ],
18
+ "function": function MD037(params, onError) {
19
+ // eslint-disable-next-line init-declarations
20
+ let effectiveEmphasisLength, emphasisIndex, emphasisKind, emphasisLength,
21
+ pendingError = null;
22
+ // eslint-disable-next-line jsdoc/require-jsdoc
23
+ function resetRunTracking() {
24
+ emphasisIndex = -1;
25
+ emphasisLength = 0;
26
+ emphasisKind = "";
27
+ effectiveEmphasisLength = 0;
28
+ pendingError = null;
29
+ }
30
+ // eslint-disable-next-line jsdoc/require-jsdoc
31
+ function handleRunEnd(line, lineIndex, contextLength, match, matchIndex) {
32
+ // Close current run
33
+ let content = line.substring(emphasisIndex, matchIndex);
34
+ if (!emphasisLength) {
35
+ content = content.trimStart();
36
+ }
37
+ if (!match) {
38
+ content = content.trimEnd();
39
+ }
40
+ const leftSpace = leftSpaceRe.test(content);
41
+ const rightSpace = rightSpaceRe.test(content);
42
+ if (leftSpace || rightSpace) {
43
+ // Report the violation
44
+ const contextStart = emphasisIndex - emphasisLength;
45
+ const contextEnd = matchIndex + contextLength;
46
+ const context = line.substring(contextStart, contextEnd);
47
+ const column = contextStart + 1;
48
+ const length = contextEnd - contextStart;
49
+ const leftMarker = line.substring(contextStart, emphasisIndex);
50
+ const rightMarker = match ? (match[2] || match[3]) : "";
51
+ const fixedText = `${leftMarker}${content.trim()}${rightMarker}`;
52
+ return [
53
+ onError,
54
+ lineIndex + 1,
55
+ context,
56
+ leftSpace,
57
+ rightSpace,
58
+ [ column, length ],
59
+ {
60
+ "editColumn": column,
61
+ "deleteCount": length,
62
+ "insertText": fixedText
63
+ }
64
+ ];
65
+ }
66
+ return null;
67
+ }
68
+ // Initialize
69
+ const ignoreMarkersByLine = emphasisMarkersInContent(params);
70
+ resetRunTracking();
71
+ forEachLine(
72
+ lineMetadata(),
73
+ (line, lineIndex, inCode, onFence, inTable, inItem, onBreak) => {
74
+ const onItemStart = (inItem === 1);
75
+ if (inCode || inTable || onBreak || onItemStart || isBlankLine(line)) {
76
+ // Emphasis resets when leaving a block
77
+ resetRunTracking();
78
+ }
79
+ if (inCode || onBreak) {
80
+ // Emphasis has no meaning here
81
+ return;
82
+ }
83
+ if (onItemStart) {
84
+ // Trim overlapping '*' list item marker
85
+ line = line.replace(asteriskListItemMarkerRe, "$1 $2");
86
+ }
87
+ let match = null;
88
+ // Match all emphasis-looking runs in the line...
89
+ while ((match = emphasisRe.exec(line))) {
90
+ const ignoreMarkersForLine = ignoreMarkersByLine[lineIndex] || [];
91
+ const matchIndex = match.index + match[1].length;
92
+ if (ignoreMarkersForLine.includes(matchIndex)) {
93
+ // Ignore emphasis markers inside code spans and links
94
+ continue;
95
+ }
96
+ const matchLength = match[0].length - match[1].length;
97
+ const matchKind = (match[2] || match[3])[0];
98
+ if (emphasisIndex === -1) {
99
+ // New run
100
+ emphasisIndex = matchIndex + matchLength;
101
+ emphasisLength = matchLength;
102
+ emphasisKind = matchKind;
103
+ effectiveEmphasisLength = matchLength;
104
+ } else if (matchKind === emphasisKind) {
105
+ // Matching emphasis markers
106
+ if (matchLength === effectiveEmphasisLength) {
107
+ // Ending an existing run, report any pending error
108
+ if (pendingError) {
109
+ addErrorContext(...pendingError);
110
+ pendingError = null;
111
+ }
112
+ const error = handleRunEnd(
113
+ line, lineIndex, effectiveEmphasisLength, match, matchIndex);
114
+ if (error) {
115
+ addErrorContext(...error);
116
+ }
117
+ // Reset
118
+ resetRunTracking();
119
+ } else if (matchLength === 3) {
120
+ // Swap internal run length (1->2 or 2->1)
121
+ effectiveEmphasisLength = matchLength - effectiveEmphasisLength;
122
+ } else if (effectiveEmphasisLength === 3) {
123
+ // Downgrade internal run (3->1 or 3->2)
124
+ effectiveEmphasisLength -= matchLength;
125
+ } else {
126
+ // Upgrade to internal run (1->3 or 2->3)
127
+ effectiveEmphasisLength += matchLength;
128
+ }
129
+ // Back up one character so RegExp has a chance to match the
130
+ // next marker (ex: "**star**_underscore_")
131
+ if (emphasisRe.lastIndex > 1) {
132
+ emphasisRe.lastIndex--;
133
+ }
134
+ } else if (emphasisRe.lastIndex > 1) {
135
+ // Back up one character so RegExp has a chance to match the
136
+ // mis-matched marker (ex: "*text_*")
137
+ emphasisRe.lastIndex--;
138
+ }
139
+ }
140
+ if (emphasisIndex !== -1) {
141
+ pendingError = pendingError ||
142
+ handleRunEnd(line, lineIndex, 0, null, line.length);
143
+ // Adjust for pending run on new line
144
+ emphasisIndex = 0;
145
+ emphasisLength = 0;
146
+ }
147
+ }
148
+ );
149
+ }
150
+ };
package/lib/md038.js CHANGED
@@ -1,68 +1,68 @@
1
- // @ts-check
2
-
3
- "use strict";
4
-
5
- const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } =
6
- require("../helpers");
7
-
8
- const leftSpaceRe = /^\s([^`]|$)/;
9
- const rightSpaceRe = /[^`]\s$/;
10
- const singleLeftRightSpaceRe = /^\s\S+\s$/;
11
-
12
- module.exports = {
13
- "names": [ "MD038", "no-space-in-code" ],
14
- "description": "Spaces inside code span elements",
15
- "tags": [ "whitespace", "code" ],
16
- "function": function MD038(params, onError) {
17
- filterTokens(params, "inline", (token) => {
18
- if (token.children.some((child) => child.type === "code_inline")) {
19
- const tokenLines = params.lines.slice(token.map[0], token.map[1]);
20
- forEachInlineCodeSpan(
21
- tokenLines.join("\n"),
22
- (code, lineIndex, columnIndex, tickCount) => {
23
- let rangeIndex = columnIndex - tickCount;
24
- let rangeLength = code.length + (2 * tickCount);
25
- let rangeLineOffset = 0;
26
- let fixIndex = columnIndex;
27
- let fixLength = code.length;
28
- const codeLines = code.split(newLineRe);
29
- const left = leftSpaceRe.test(code);
30
- const right = !left && rightSpaceRe.test(code);
31
- if (right && (codeLines.length > 1)) {
32
- rangeIndex = 0;
33
- rangeLineOffset = codeLines.length - 1;
34
- fixIndex = 0;
35
- }
36
- const allowed = singleLeftRightSpaceRe.test(code);
37
- if ((left || right) && !allowed) {
38
- const codeLinesRange = codeLines[rangeLineOffset];
39
- if (codeLines.length > 1) {
40
- rangeLength = codeLinesRange.length + tickCount;
41
- fixLength = codeLinesRange.length;
42
- }
43
- const context = tokenLines[lineIndex + rangeLineOffset]
44
- .substring(rangeIndex, rangeIndex + rangeLength);
45
- const codeLinesRangeTrim = codeLinesRange.trim();
46
- const fixText =
47
- (codeLinesRangeTrim.startsWith("`") ? " " : "") +
48
- codeLinesRangeTrim +
49
- (codeLinesRangeTrim.endsWith("`") ? " " : "");
50
- addErrorContext(
51
- onError,
52
- token.lineNumber + lineIndex + rangeLineOffset,
53
- context,
54
- left,
55
- right,
56
- [ rangeIndex + 1, rangeLength ],
57
- {
58
- "editColumn": fixIndex + 1,
59
- "deleteCount": fixLength,
60
- "insertText": fixText
61
- }
62
- );
63
- }
64
- });
65
- }
66
- });
67
- }
68
- };
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } =
6
+ require("../helpers");
7
+
8
+ const leftSpaceRe = /^\s([^`]|$)/;
9
+ const rightSpaceRe = /[^`]\s$/;
10
+ const singleLeftRightSpaceRe = /^\s(?:\S.*\S|\S)\s$/;
11
+
12
+ module.exports = {
13
+ "names": [ "MD038", "no-space-in-code" ],
14
+ "description": "Spaces inside code span elements",
15
+ "tags": [ "whitespace", "code" ],
16
+ "function": function MD038(params, onError) {
17
+ filterTokens(params, "inline", (token) => {
18
+ if (token.children.some((child) => child.type === "code_inline")) {
19
+ const tokenLines = params.lines.slice(token.map[0], token.map[1]);
20
+ forEachInlineCodeSpan(
21
+ tokenLines.join("\n"),
22
+ (code, lineIndex, columnIndex, tickCount) => {
23
+ let rangeIndex = columnIndex - tickCount;
24
+ let rangeLength = code.length + (2 * tickCount);
25
+ let rangeLineOffset = 0;
26
+ let fixIndex = columnIndex;
27
+ let fixLength = code.length;
28
+ const codeLines = code.split(newLineRe);
29
+ const left = leftSpaceRe.test(code);
30
+ const right = !left && rightSpaceRe.test(code);
31
+ if (right && (codeLines.length > 1)) {
32
+ rangeIndex = 0;
33
+ rangeLineOffset = codeLines.length - 1;
34
+ fixIndex = 0;
35
+ }
36
+ const allowed = singleLeftRightSpaceRe.test(code);
37
+ if ((left || right) && !allowed) {
38
+ const codeLinesRange = codeLines[rangeLineOffset];
39
+ if (codeLines.length > 1) {
40
+ rangeLength = codeLinesRange.length + tickCount;
41
+ fixLength = codeLinesRange.length;
42
+ }
43
+ const context = tokenLines[lineIndex + rangeLineOffset]
44
+ .substring(rangeIndex, rangeIndex + rangeLength);
45
+ const codeLinesRangeTrim = codeLinesRange.trim();
46
+ const fixText =
47
+ (codeLinesRangeTrim.startsWith("`") ? " " : "") +
48
+ codeLinesRangeTrim +
49
+ (codeLinesRangeTrim.endsWith("`") ? " " : "");
50
+ addErrorContext(
51
+ onError,
52
+ token.lineNumber + lineIndex + rangeLineOffset,
53
+ context,
54
+ left,
55
+ right,
56
+ [ rangeIndex + 1, rangeLength ],
57
+ {
58
+ "editColumn": fixIndex + 1,
59
+ "deleteCount": fixLength,
60
+ "insertText": fixText
61
+ }
62
+ );
63
+ }
64
+ });
65
+ }
66
+ });
67
+ }
68
+ };
package/lib/md039.js CHANGED
@@ -1,64 +1,64 @@
1
- // @ts-check
2
-
3
- "use strict";
4
-
5
- const { addErrorContext, filterTokens } = require("../helpers");
6
-
7
- const spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/;
8
-
9
- module.exports = {
10
- "names": [ "MD039", "no-space-in-links" ],
11
- "description": "Spaces inside link text",
12
- "tags": [ "whitespace", "links" ],
13
- "function": function MD039(params, onError) {
14
- filterTokens(params, "inline", (token) => {
15
- const { children } = token;
16
- let { lineNumber } = token;
17
- let inLink = false;
18
- let linkText = "";
19
- let lineIndex = 0;
20
- children.forEach((child) => {
21
- const { content, type } = child;
22
- if (type === "link_open") {
23
- inLink = true;
24
- linkText = "";
25
- } else if (type === "link_close") {
26
- inLink = false;
27
- const left = linkText.trimLeft().length !== linkText.length;
28
- const right = linkText.trimRight().length !== linkText.length;
29
- if (left || right) {
30
- const line = params.lines[lineNumber - 1];
31
- let range = null;
32
- let fixInfo = null;
33
- const match = line.slice(lineIndex).match(spaceInLinkRe);
34
- if (match) {
35
- const column = match.index + lineIndex + 1;
36
- const length = match[0].length;
37
- range = [ column, length ];
38
- fixInfo = {
39
- "editColumn": column + 1,
40
- "deleteCount": length - 2,
41
- "insertText": linkText.trim()
42
- };
43
- lineIndex = column + length - 1;
44
- }
45
- addErrorContext(
46
- onError,
47
- lineNumber,
48
- `[${linkText}]`,
49
- left,
50
- right,
51
- range,
52
- fixInfo
53
- );
54
- }
55
- } else if ((type === "softbreak") || (type === "hardbreak")) {
56
- lineNumber++;
57
- lineIndex = 0;
58
- } else if (inLink) {
59
- linkText += content;
60
- }
61
- });
62
- });
63
- }
64
- };
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, filterTokens } = require("../helpers");
6
+
7
+ const spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/;
8
+
9
+ module.exports = {
10
+ "names": [ "MD039", "no-space-in-links" ],
11
+ "description": "Spaces inside link text",
12
+ "tags": [ "whitespace", "links" ],
13
+ "function": function MD039(params, onError) {
14
+ filterTokens(params, "inline", (token) => {
15
+ const { children } = token;
16
+ let { lineNumber } = token;
17
+ let inLink = false;
18
+ let linkText = "";
19
+ let lineIndex = 0;
20
+ children.forEach((child) => {
21
+ const { content, type } = child;
22
+ if (type === "link_open") {
23
+ inLink = true;
24
+ linkText = "";
25
+ } else if (type === "link_close") {
26
+ inLink = false;
27
+ const left = linkText.trimLeft().length !== linkText.length;
28
+ const right = linkText.trimRight().length !== linkText.length;
29
+ if (left || right) {
30
+ const line = params.lines[lineNumber - 1];
31
+ let range = null;
32
+ let fixInfo = null;
33
+ const match = line.slice(lineIndex).match(spaceInLinkRe);
34
+ if (match) {
35
+ const column = match.index + lineIndex + 1;
36
+ const length = match[0].length;
37
+ range = [ column, length ];
38
+ fixInfo = {
39
+ "editColumn": column + 1,
40
+ "deleteCount": length - 2,
41
+ "insertText": linkText.trim()
42
+ };
43
+ lineIndex = column + length - 1;
44
+ }
45
+ addErrorContext(
46
+ onError,
47
+ lineNumber,
48
+ `[${linkText}]`,
49
+ left,
50
+ right,
51
+ range,
52
+ fixInfo
53
+ );
54
+ }
55
+ } else if ((type === "softbreak") || (type === "hardbreak")) {
56
+ lineNumber++;
57
+ lineIndex = 0;
58
+ } else if (inLink) {
59
+ linkText += content;
60
+ }
61
+ });
62
+ });
63
+ }
64
+ };
package/lib/md040.js CHANGED
@@ -1,18 +1,18 @@
1
- // @ts-check
2
-
3
- "use strict";
4
-
5
- const { addErrorContext, filterTokens } = require("../helpers");
6
-
7
- module.exports = {
8
- "names": [ "MD040", "fenced-code-language" ],
9
- "description": "Fenced code blocks should have a language specified",
10
- "tags": [ "code", "language" ],
11
- "function": function MD040(params, onError) {
12
- filterTokens(params, "fence", function forToken(token) {
13
- if (!token.info.trim()) {
14
- addErrorContext(onError, token.lineNumber, token.line);
15
- }
16
- });
17
- }
18
- };
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, filterTokens } = require("../helpers");
6
+
7
+ module.exports = {
8
+ "names": [ "MD040", "fenced-code-language" ],
9
+ "description": "Fenced code blocks should have a language specified",
10
+ "tags": [ "code", "language" ],
11
+ "function": function MD040(params, onError) {
12
+ filterTokens(params, "fence", function forToken(token) {
13
+ if (!token.info.trim()) {
14
+ addErrorContext(onError, token.lineNumber, token.line);
15
+ }
16
+ });
17
+ }
18
+ };
package/lib/md041.js CHANGED
@@ -1,31 +1,31 @@
1
- // @ts-check
2
-
3
- "use strict";
4
-
5
- const { addErrorContext, frontMatterHasTitle } = require("../helpers");
6
-
7
- module.exports = {
8
- "names": [ "MD041", "first-line-heading", "first-line-h1" ],
9
- "description": "First line in file should be a top level heading",
10
- "tags": [ "headings", "headers" ],
11
- "function": function MD041(params, onError) {
12
- const level = Number(params.config.level || 1);
13
- const tag = "h" + level;
14
- const foundFrontMatterTitle =
15
- frontMatterHasTitle(
16
- params.frontMatterLines,
17
- params.config.front_matter_title
18
- );
19
- if (!foundFrontMatterTitle) {
20
- params.tokens.every((token) => {
21
- if (token.type === "html_block") {
22
- return true;
23
- }
24
- if ((token.type !== "heading_open") || (token.tag !== tag)) {
25
- addErrorContext(onError, token.lineNumber, token.line);
26
- }
27
- return false;
28
- });
29
- }
30
- }
31
- };
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, frontMatterHasTitle } = require("../helpers");
6
+
7
+ module.exports = {
8
+ "names": [ "MD041", "first-line-heading", "first-line-h1" ],
9
+ "description": "First line in file should be a top level heading",
10
+ "tags": [ "headings", "headers" ],
11
+ "function": function MD041(params, onError) {
12
+ const level = Number(params.config.level || 1);
13
+ const tag = "h" + level;
14
+ const foundFrontMatterTitle =
15
+ frontMatterHasTitle(
16
+ params.frontMatterLines,
17
+ params.config.front_matter_title
18
+ );
19
+ if (!foundFrontMatterTitle) {
20
+ params.tokens.every((token) => {
21
+ if (token.type === "html_block") {
22
+ return true;
23
+ }
24
+ if ((token.type !== "heading_open") || (token.tag !== tag)) {
25
+ addErrorContext(onError, token.lineNumber, token.line);
26
+ }
27
+ return false;
28
+ });
29
+ }
30
+ }
31
+ };