markdownlint 0.31.1 → 0.32.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/CONTRIBUTING.md +2 -2
  3. package/README.md +19 -28
  4. package/demo/markdownlint-browser.js +521 -352
  5. package/doc/Rules.md +146 -127
  6. package/doc/md001.md +2 -2
  7. package/doc/md003.md +2 -2
  8. package/doc/md007.md +3 -4
  9. package/doc/md013.md +0 -3
  10. package/doc/md018.md +1 -1
  11. package/doc/md019.md +1 -1
  12. package/doc/md020.md +1 -1
  13. package/doc/md021.md +1 -1
  14. package/doc/md022.md +2 -2
  15. package/doc/md023.md +9 -2
  16. package/doc/md024.md +2 -2
  17. package/doc/md025.md +1 -1
  18. package/doc/md026.md +1 -1
  19. package/doc/md036.md +2 -2
  20. package/doc/md041.md +1 -1
  21. package/doc/md043.md +2 -5
  22. package/doc/md045.md +6 -0
  23. package/doc/md049.md +1 -1
  24. package/doc/md050.md +1 -1
  25. package/doc/md053.md +3 -3
  26. package/doc/md054.md +100 -0
  27. package/helpers/helpers.js +27 -7
  28. package/helpers/micromark.cjs +62 -15
  29. package/helpers/package.json +2 -1
  30. package/helpers/shared.js +3 -0
  31. package/lib/configuration.d.ts +1152 -0
  32. package/lib/constants.js +7 -7
  33. package/lib/markdownlint.d.ts +2 -4
  34. package/lib/markdownlint.js +9 -8
  35. package/lib/md001.js +2 -2
  36. package/lib/md003.js +2 -2
  37. package/lib/md005.js +21 -17
  38. package/lib/md007.js +62 -25
  39. package/lib/md013.js +1 -4
  40. package/lib/md018.js +1 -1
  41. package/lib/md019.js +1 -1
  42. package/lib/md020.js +1 -1
  43. package/lib/md021.js +1 -1
  44. package/lib/md022.js +4 -4
  45. package/lib/md023.js +2 -2
  46. package/lib/md024.js +2 -2
  47. package/lib/md025.js +1 -1
  48. package/lib/md026.js +1 -1
  49. package/lib/md030.js +33 -22
  50. package/lib/md032.js +1 -4
  51. package/lib/md033.js +1 -3
  52. package/lib/md034.js +31 -25
  53. package/lib/md036.js +2 -2
  54. package/lib/md037.js +2 -2
  55. package/lib/md038.js +7 -5
  56. package/lib/md041.js +1 -1
  57. package/lib/md043.js +3 -3
  58. package/lib/md045.js +33 -3
  59. package/lib/md049-md050.js +2 -2
  60. package/lib/md051.js +8 -6
  61. package/lib/md053.js +1 -1
  62. package/lib/md054.js +125 -0
  63. package/lib/rules.js +5 -3
  64. package/package.json +18 -16
  65. package/schema/.markdownlint.jsonc +63 -60
  66. package/schema/.markdownlint.yaml +62 -59
  67. package/schema/markdownlint-config-schema.json +840 -186
  68. package/style/relaxed.json +0 -1
  69. package/doc/md002.md +0 -37
  70. package/doc/md006.md +0 -46
  71. package/lib/md002.js +0 -22
  72. package/lib/md006.js +0 -34
package/lib/constants.js CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- module.exports.deprecatedRuleNames = [ "MD002", "MD006" ];
5
+ module.exports.deprecatedRuleNames = [];
6
6
  module.exports.fixableRuleNames = [
7
- "MD004", "MD005", "MD006", "MD007", "MD009", "MD010",
8
- "MD011", "MD012", "MD014", "MD018", "MD019", "MD020",
9
- "MD021", "MD022", "MD023", "MD026", "MD027", "MD030",
10
- "MD031", "MD032", "MD034", "MD037", "MD038", "MD039",
11
- "MD044", "MD047", "MD049", "MD050", "MD051", "MD053"
7
+ "MD004", "MD005", "MD007", "MD009", "MD010", "MD011",
8
+ "MD012", "MD014", "MD018", "MD019", "MD020", "MD021",
9
+ "MD022", "MD023", "MD026", "MD027", "MD030", "MD031",
10
+ "MD032", "MD034", "MD037", "MD038", "MD039", "MD044",
11
+ "MD047", "MD049", "MD050", "MD051", "MD053", "MD054"
12
12
  ];
13
13
  module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
14
- module.exports.version = "0.31.1";
14
+ module.exports.version = "0.32.1";
@@ -358,12 +358,10 @@ type FixInfo = {
358
358
  */
359
359
  type LintContentCallback = (error: Error | null, result?: LintError[]) => void;
360
360
  /**
361
- * Configuration object for linting rules. For a detailed schema, see
361
+ * Configuration object for linting rules. For the JSON schema, see
362
362
  * {@link ../schema/markdownlint-config-schema.json}.
363
363
  */
364
- type Configuration = {
365
- [x: string]: RuleConfiguration;
366
- };
364
+ type Configuration = import("./configuration").Configuration;
367
365
  /**
368
366
  * Rule configuration.
369
367
  */
@@ -6,13 +6,13 @@ const path = require("node:path");
6
6
  const { promisify } = require("node:util");
7
7
  const markdownit = require("markdown-it");
8
8
  const micromark = require("../helpers/micromark.cjs");
9
- const { deprecatedRuleNames } = require("./constants");
9
+ // const { deprecatedRuleNames } = require("./constants");
10
10
  const rules = require("./rules");
11
11
  const helpers = require("../helpers");
12
12
  const cache = require("./cache");
13
13
 
14
14
  // @ts-ignore
15
- // eslint-disable-next-line camelcase, max-len, no-inline-comments, no-undef
15
+ // eslint-disable-next-line camelcase, no-inline-comments, no-undef
16
16
  const dynamicRequire = (typeof __non_webpack_require__ === "undefined") ? require : /* c8 ignore next */ __non_webpack_require__;
17
17
  // Capture native require implementation for dynamic loading of modules
18
18
 
@@ -317,14 +317,15 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
317
317
  (key) => key.toUpperCase() === "DEFAULT"
318
318
  );
319
319
  const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]];
320
+ /** @type {Configuration} */
320
321
  const effectiveConfig = {};
321
322
  for (const rule of ruleList) {
322
323
  const ruleName = rule.names[0].toUpperCase();
323
324
  effectiveConfig[ruleName] = ruleDefault;
324
325
  }
325
- for (const ruleName of deprecatedRuleNames) {
326
- effectiveConfig[ruleName] = false;
327
- }
326
+ // for (const ruleName of deprecatedRuleNames) {
327
+ // effectiveConfig[ruleName] = false;
328
+ // }
328
329
  for (const key of Object.keys(config)) {
329
330
  let value = config[key];
330
331
  if (value) {
@@ -604,7 +605,7 @@ function lintContent(
604
605
  // eslint-disable-next-line jsdoc/require-jsdoc
605
606
  function throwError(property) {
606
607
  throw new Error(
607
- "Property '" + property + "' of onError parameter is incorrect.");
608
+ `Value of '${property}' passed to onError by '${ruleName}' is incorrect for '${name}'.`);
608
609
  }
609
610
  // eslint-disable-next-line jsdoc/require-jsdoc
610
611
  function onError(errorInfo) {
@@ -1436,10 +1437,10 @@ module.exports = markdownlint;
1436
1437
  */
1437
1438
 
1438
1439
  /**
1439
- * Configuration object for linting rules. For a detailed schema, see
1440
+ * Configuration object for linting rules. For the JSON schema, see
1440
1441
  * {@link ../schema/markdownlint-config-schema.json}.
1441
1442
  *
1442
- * @typedef {Object.<string, RuleConfiguration>} Configuration
1443
+ * @typedef {import("./configuration").Configuration} Configuration
1443
1444
  */
1444
1445
 
1445
1446
  /**
package/lib/md001.js CHANGED
@@ -5,9 +5,9 @@
5
5
  const { addErrorDetailIf, filterTokens } = require("../helpers");
6
6
 
7
7
  module.exports = {
8
- "names": [ "MD001", "heading-increment", "header-increment" ],
8
+ "names": [ "MD001", "heading-increment" ],
9
9
  "description": "Heading levels should only increment by one level at a time",
10
- "tags": [ "headings", "headers" ],
10
+ "tags": [ "headings" ],
11
11
  "function": function MD001(params, onError) {
12
12
  let prevLevel = 0;
13
13
  filterTokens(params, "heading_open", function forToken(token) {
package/lib/md003.js CHANGED
@@ -6,9 +6,9 @@ const { addErrorDetailIf, filterTokens, headingStyleFor } =
6
6
  require("../helpers");
7
7
 
8
8
  module.exports = {
9
- "names": [ "MD003", "heading-style", "header-style" ],
9
+ "names": [ "MD003", "heading-style" ],
10
10
  "description": "Heading style",
11
- "tags": [ "headings", "headers" ],
11
+ "tags": [ "headings" ],
12
12
  "function": function MD003(params, onError) {
13
13
  let style = String(params.config.style || "consistent");
14
14
  filterTokens(params, "heading_open", function forToken(token) {
package/lib/md005.js CHANGED
@@ -2,25 +2,30 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const { addError, addErrorDetailIf, indentFor, listItemMarkerRe,
6
- orderedListItemMarkerRe, rangeFromRegExp } = require("../helpers");
7
- const { flattenedLists } = require("./cache");
5
+ const { addError, addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes, inHtmlFlow } = require("../helpers/micromark.cjs");
8
7
 
9
8
  module.exports = {
10
9
  "names": [ "MD005", "list-indent" ],
11
10
  "description": "Inconsistent indentation for list items at the same level",
12
11
  "tags": [ "bullet", "ul", "indentation" ],
13
12
  "function": function MD005(params, onError) {
14
- for (const list of flattenedLists()) {
15
- const expectedIndent = list.indent;
13
+ const lists = filterByTypes(
14
+ params.parsers.micromark.tokens,
15
+ [ "listOrdered", "listUnordered" ]
16
+ ).filter((list) => !inHtmlFlow(list));
17
+ for (const list of lists) {
18
+ const expectedIndent = list.startColumn - 1;
16
19
  let expectedEnd = 0;
17
- let actualEnd = -1;
18
20
  let endMatching = false;
19
- for (const item of list.items) {
20
- const { line, lineNumber } = item;
21
- const actualIndent = indentFor(item);
22
- let match = null;
23
- if (list.unordered) {
21
+ const listItemPrefixes =
22
+ list.children.filter((token) => (token.type === "listItemPrefix"));
23
+ for (const listItemPrefix of listItemPrefixes) {
24
+ const lineNumber = listItemPrefix.startLine;
25
+ const actualIndent = listItemPrefix.startColumn - 1;
26
+ const markerLength = listItemPrefix.text.trim().length;
27
+ const range = [ 1, listItemPrefix.startColumn + markerLength ];
28
+ if (list.type === "listUnordered") {
24
29
  addErrorDetailIf(
25
30
  onError,
26
31
  lineNumber,
@@ -28,13 +33,12 @@ module.exports = {
28
33
  actualIndent,
29
34
  null,
30
35
  null,
31
- rangeFromRegExp(line, listItemMarkerRe)
36
+ range
32
37
  // No fixInfo; MD007 handles this scenario better
33
38
  );
34
- } else if ((match = orderedListItemMarkerRe.exec(line))) {
35
- actualEnd = match[0].length;
39
+ } else {
40
+ const actualEnd = range[1] - 1;
36
41
  expectedEnd = expectedEnd || actualEnd;
37
- const markerLength = match[1].length + 1;
38
42
  if ((expectedIndent !== actualIndent) || endMatching) {
39
43
  if (expectedEnd === actualEnd) {
40
44
  endMatching = true;
@@ -52,8 +56,8 @@ module.exports = {
52
56
  onError,
53
57
  lineNumber,
54
58
  detail,
55
- null,
56
- rangeFromRegExp(line, listItemMarkerRe),
59
+ undefined,
60
+ range,
57
61
  {
58
62
  "editColumn": Math.min(actual, expected) + 1,
59
63
  "deleteCount": Math.max(actual - expected, 0),
package/lib/md007.js CHANGED
@@ -2,9 +2,18 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const { addErrorDetailIf, indentFor, listItemMarkerRe } =
6
- require("../helpers");
7
- const { flattenedLists } = require("./cache");
5
+ const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes, getTokenParentOfType, inHtmlFlow } =
7
+ require("../helpers/micromark.cjs");
8
+
9
+ /**
10
+ * @typedef {import("../helpers/micromark.cjs").Token} Token
11
+ */
12
+
13
+ const unorderedListTypes =
14
+ [ "blockQuotePrefix", "listItemPrefix", "listUnordered" ];
15
+ const unorderedParentTypes =
16
+ [ "blockQuote", "listOrdered", "listUnordered" ];
8
17
 
9
18
  module.exports = {
10
19
  "names": [ "MD007", "ul-indent" ],
@@ -14,34 +23,62 @@ module.exports = {
14
23
  const indent = Number(params.config.indent || 2);
15
24
  const startIndented = !!params.config.start_indented;
16
25
  const startIndent = Number(params.config.start_indent || indent);
17
- for (const list of flattenedLists()) {
18
- if (list.unordered && list.parentsUnordered) {
19
- for (const item of list.items) {
20
- const { lineNumber, line } = item;
21
- const expectedIndent =
22
- (startIndented ? startIndent : 0) +
23
- (list.nesting * indent);
24
- const actualIndent = indentFor(item);
25
- let range = null;
26
- let editColumn = 1;
27
- const match = line.match(listItemMarkerRe);
28
- if (match) {
29
- range = [ 1, match[0].length ];
30
- editColumn += match[1].length - actualIndent;
26
+ const unorderedListNesting = new Map();
27
+ let lastBlockQuotePrefix = null;
28
+ const tokens = filterByTypes(
29
+ params.parsers.micromark.tokens,
30
+ unorderedListTypes
31
+ );
32
+ for (const token of tokens) {
33
+ const { parent, startColumn, startLine, type } = token;
34
+ if (type === "blockQuotePrefix") {
35
+ lastBlockQuotePrefix = token;
36
+ } else if (type === "listUnordered") {
37
+ let nesting = 0;
38
+ /** @type {Token | null} */
39
+ let current = token;
40
+ while (
41
+ (current = getTokenParentOfType(current, unorderedParentTypes))
42
+ ) {
43
+ if (current.type === "listUnordered") {
44
+ nesting++;
45
+ continue;
46
+ } else if (current.type === "listOrdered") {
47
+ nesting = -1;
31
48
  }
49
+ break;
50
+ }
51
+ if (nesting >= 0) {
52
+ unorderedListNesting.set(token, nesting);
53
+ }
54
+ } else if (!inHtmlFlow(token)) {
55
+ // listItemPrefix
56
+ const nesting = unorderedListNesting.get(parent);
57
+ if (nesting !== undefined) {
58
+ // listItemPrefix for listUnordered
59
+ const expectedIndent =
60
+ (startIndented ? startIndent : 0) + (nesting * indent);
61
+ const blockQuoteAdjustment =
62
+ (lastBlockQuotePrefix?.endLine === startLine) ?
63
+ (lastBlockQuotePrefix.endColumn - 1) :
64
+ 0;
65
+ const actualIndent = startColumn - 1 - blockQuoteAdjustment;
66
+ const range = [ 1, startColumn + 1 ];
67
+ const fixInfo = {
68
+ "editColumn": startColumn - actualIndent,
69
+ "deleteCount": Math.max(actualIndent - expectedIndent, 0),
70
+ "insertText": "".padEnd(Math.max(expectedIndent - actualIndent, 0))
71
+ };
32
72
  addErrorDetailIf(
33
73
  onError,
34
- lineNumber,
74
+ startLine,
35
75
  expectedIndent,
36
76
  actualIndent,
37
- null,
38
- null,
77
+ undefined,
78
+ undefined,
39
79
  range,
40
- {
41
- editColumn,
42
- "deleteCount": actualIndent,
43
- "insertText": "".padEnd(expectedIndent)
44
- });
80
+ fixInfo
81
+ );
45
82
  }
46
83
  }
47
84
  }
package/lib/md013.js CHANGED
@@ -46,10 +46,7 @@ module.exports = {
46
46
  const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
47
47
  const tables = params.config.tables;
48
48
  const includeTables = (tables === undefined) ? true : !!tables;
49
- let headings = params.config.headings;
50
- if (headings === undefined) {
51
- headings = params.config.headers;
52
- }
49
+ const headings = params.config.headings;
53
50
  const includeHeadings = (headings === undefined) ? true : !!headings;
54
51
  const headingLineNumbers = [];
55
52
  forEachHeading(params, (heading) => {
package/lib/md018.js CHANGED
@@ -8,7 +8,7 @@ const { lineMetadata } = require("./cache");
8
8
  module.exports = {
9
9
  "names": [ "MD018", "no-missing-space-atx" ],
10
10
  "description": "No space after hash on atx style heading",
11
- "tags": [ "headings", "headers", "atx", "spaces" ],
11
+ "tags": [ "headings", "atx", "spaces" ],
12
12
  "function": function MD018(params, onError) {
13
13
  forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
14
14
  if (!inCode &&
package/lib/md019.js CHANGED
@@ -8,7 +8,7 @@ const { addErrorContext, filterTokens, headingStyleFor } =
8
8
  module.exports = {
9
9
  "names": [ "MD019", "no-multiple-space-atx" ],
10
10
  "description": "Multiple spaces after hash on atx style heading",
11
- "tags": [ "headings", "headers", "atx", "spaces" ],
11
+ "tags": [ "headings", "atx", "spaces" ],
12
12
  "function": function MD019(params, onError) {
13
13
  filterTokens(params, "heading_open", (token) => {
14
14
  if (headingStyleFor(token) === "atx") {
package/lib/md020.js CHANGED
@@ -8,7 +8,7 @@ const { lineMetadata } = require("./cache");
8
8
  module.exports = {
9
9
  "names": [ "MD020", "no-missing-space-closed-atx" ],
10
10
  "description": "No space inside hashes on closed atx style heading",
11
- "tags": [ "headings", "headers", "atx_closed", "spaces" ],
11
+ "tags": [ "headings", "atx_closed", "spaces" ],
12
12
  "function": function MD020(params, onError) {
13
13
  forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
14
14
  if (!inCode) {
package/lib/md021.js CHANGED
@@ -10,7 +10,7 @@ const closedAtxRe = /^(#+)([ \t]+)([^ \t]|[^ \t].*[^ \t])([ \t]+)(#+)(\s*)$/;
10
10
  module.exports = {
11
11
  "names": [ "MD021", "no-multiple-space-closed-atx" ],
12
12
  "description": "Multiple spaces inside hashes on closed atx style heading",
13
- "tags": [ "headings", "headers", "atx_closed", "spaces" ],
13
+ "tags": [ "headings", "atx_closed", "spaces" ],
14
14
  "function": function MD021(params, onError) {
15
15
  filterTokens(params, "heading_open", (token) => {
16
16
  if (headingStyleFor(token) === "atx_closed") {
package/lib/md022.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  const { addErrorDetailIf, blockquotePrefixRe, isBlankLine } =
6
6
  require("../helpers");
7
- const { filterByTypes, getHeadingLevel } =
7
+ const { filterByTypes, getHeadingLevel, inHtmlFlow } =
8
8
  require("../helpers/micromark.cjs");
9
9
 
10
10
  const defaultLines = 1;
@@ -32,9 +32,9 @@ const getBlockQuote = (str, count) => (
32
32
  );
33
33
 
34
34
  module.exports = {
35
- "names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ],
35
+ "names": [ "MD022", "blanks-around-headings" ],
36
36
  "description": "Headings should be surrounded by blank lines",
37
- "tags": [ "headings", "headers", "blank_lines" ],
37
+ "tags": [ "headings", "blank_lines" ],
38
38
  "function": function MD022(params, onError) {
39
39
  const getLinesAbove = getLinesFunction(params.config.lines_above);
40
40
  const getLinesBelow = getLinesFunction(params.config.lines_below);
@@ -42,7 +42,7 @@ module.exports = {
42
42
  const headings = filterByTypes(
43
43
  parsers.micromark.tokens,
44
44
  [ "atxHeading", "setextHeading" ]
45
- );
45
+ ).filter((heading) => !inHtmlFlow(heading));
46
46
  for (const heading of headings) {
47
47
  const { startLine, endLine } = heading;
48
48
  const line = lines[startLine - 1].trim();
package/lib/md023.js CHANGED
@@ -7,9 +7,9 @@ const { addErrorContext, filterTokens } = require("../helpers");
7
7
  const spaceBeforeHeadingRe = /^(\s+|[>\s]+\s\s)[^>\s]/;
8
8
 
9
9
  module.exports = {
10
- "names": [ "MD023", "heading-start-left", "header-start-left" ],
10
+ "names": [ "MD023", "heading-start-left" ],
11
11
  "description": "Headings must start at the beginning of the line",
12
- "tags": [ "headings", "headers", "spaces" ],
12
+ "tags": [ "headings", "spaces" ],
13
13
  "function": function MD023(params, onError) {
14
14
  filterTokens(params, "heading_open", function forToken(token) {
15
15
  const { lineNumber, line } = token;
package/lib/md024.js CHANGED
@@ -5,9 +5,9 @@
5
5
  const { addErrorContext, forEachHeading } = require("../helpers");
6
6
 
7
7
  module.exports = {
8
- "names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ],
8
+ "names": [ "MD024", "no-duplicate-heading" ],
9
9
  "description": "Multiple headings with the same content",
10
- "tags": [ "headings", "headers" ],
10
+ "tags": [ "headings" ],
11
11
  "function": function MD024(params, onError) {
12
12
  const siblingsOnly = !!params.config.siblings_only ||
13
13
  !!params.config.allow_different_nesting || false;
package/lib/md025.js CHANGED
@@ -8,7 +8,7 @@ const { addErrorContext, filterTokens, frontMatterHasTitle } =
8
8
  module.exports = {
9
9
  "names": [ "MD025", "single-title", "single-h1" ],
10
10
  "description": "Multiple top-level headings in the same document",
11
- "tags": [ "headings", "headers" ],
11
+ "tags": [ "headings" ],
12
12
  "function": function MD025(params, onError) {
13
13
  const level = Number(params.config.level || 1);
14
14
  const tag = "h" + level;
package/lib/md026.js CHANGED
@@ -10,7 +10,7 @@ const { filterByTypes } = require("../helpers/micromark.cjs");
10
10
  module.exports = {
11
11
  "names": [ "MD026", "no-trailing-punctuation" ],
12
12
  "description": "Trailing punctuation in heading",
13
- "tags": [ "headings", "headers" ],
13
+ "tags": [ "headings" ],
14
14
  "function": function MD026(params, onError) {
15
15
  let punctuation = params.config.punctuation;
16
16
  punctuation = String(
package/lib/md030.js CHANGED
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorDetailIf } = require("../helpers");
6
- const { flattenedLists } = require("./cache");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
7
7
 
8
8
  module.exports = {
9
9
  "names": [ "MD030", "list-marker-space" ],
@@ -14,33 +14,44 @@ module.exports = {
14
14
  const olSingle = Number(params.config.ol_single || 1);
15
15
  const ulMulti = Number(params.config.ul_multi || 1);
16
16
  const olMulti = Number(params.config.ol_multi || 1);
17
- for (const list of flattenedLists()) {
18
- const lineCount = list.lastLineIndex - list.open.map[0];
19
- const allSingle = lineCount === list.items.length;
20
- const expectedSpaces = list.unordered ?
21
- (allSingle ? ulSingle : ulMulti) :
22
- (allSingle ? olSingle : olMulti);
23
- for (const item of list.items) {
24
- const { line, lineNumber } = item;
25
- const match = /^[\s>]*\S+(\s*)/.exec(line);
26
- const [ { "length": matchLength }, { "length": actualSpaces } ] = match;
27
- if (matchLength < line.length) {
28
- let fixInfo = null;
29
- if (expectedSpaces !== actualSpaces) {
30
- fixInfo = {
31
- "editColumn": matchLength - actualSpaces + 1,
32
- "deleteCount": actualSpaces,
33
- "insertText": "".padEnd(expectedSpaces)
34
- };
35
- }
17
+ const lists = filterByTypes(
18
+ params.parsers.micromark.tokens,
19
+ [ "listOrdered", "listUnordered" ]
20
+ );
21
+ for (const list of lists) {
22
+ const ordered = (list.type === "listOrdered");
23
+ const listItemPrefixes =
24
+ list.children.filter((token) => (token.type === "listItemPrefix"));
25
+ const allSingleLine =
26
+ (list.endLine - list.startLine + 1) === listItemPrefixes.length;
27
+ const expectedSpaces = ordered ?
28
+ (allSingleLine ? olSingle : olMulti) :
29
+ (allSingleLine ? ulSingle : ulMulti);
30
+ for (const listItemPrefix of listItemPrefixes) {
31
+ const range = [
32
+ listItemPrefix.startColumn,
33
+ listItemPrefix.endColumn - listItemPrefix.startColumn
34
+ ];
35
+ const listItemPrefixWhitespaces = listItemPrefix.children.filter(
36
+ (token) => (token.type === "listItemPrefixWhitespace")
37
+ );
38
+ for (const listItemPrefixWhitespace of listItemPrefixWhitespaces) {
39
+ const { endColumn, startColumn, startLine } =
40
+ listItemPrefixWhitespace;
41
+ const actualSpaces = endColumn - startColumn;
42
+ const fixInfo = {
43
+ "editColumn": startColumn,
44
+ "deleteCount": actualSpaces,
45
+ "insertText": "".padEnd(expectedSpaces)
46
+ };
36
47
  addErrorDetailIf(
37
48
  onError,
38
- lineNumber,
49
+ startLine,
39
50
  expectedSpaces,
40
51
  actualSpaces,
41
52
  null,
42
53
  null,
43
- [ 1, matchLength ],
54
+ range,
44
55
  fixInfo
45
56
  );
46
57
  }
package/lib/md032.js CHANGED
@@ -60,10 +60,7 @@ module.exports = {
60
60
 
61
61
  // Find the "visual" end of the list
62
62
  let endLine = list.endLine;
63
- const flattenedChildren = filterByPredicate(
64
- list.children,
65
- () => true
66
- );
63
+ const flattenedChildren = filterByPredicate(list.children);
67
64
  for (const child of flattenedChildren.reverse()) {
68
65
  if (!nonContentTokens.has(child.type)) {
69
66
  endLine = child.endLine;
package/lib/md033.js CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const { addError } = require("../helpers");
5
+ const { addError, nextLinesRe } = require("../helpers");
6
6
  const { filterByTypes, getHtmlTagInfo } =
7
7
  require("../helpers/micromark.cjs");
8
8
 
9
- const nextLinesRe = /[\r\n][\s\S]*$/;
10
-
11
9
  module.exports = {
12
10
  "names": [ "MD033", "no-inline-html" ],
13
11
  "description": "Inline HTML",
package/lib/md034.js CHANGED
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorContext } = require("../helpers");
6
- const { filterByPredicate, filterByTypes, getHtmlTagInfo, parse } =
6
+ const { filterByPredicate, filterByTypes, getHtmlTagInfo, inHtmlFlow, parse } =
7
7
  require("../helpers/micromark.cjs");
8
8
 
9
9
  module.exports = {
@@ -11,35 +11,41 @@ module.exports = {
11
11
  "description": "Bare URL used",
12
12
  "tags": [ "links", "url" ],
13
13
  "function": function MD034(params, onError) {
14
- const literalAutolinks = (tokens) => {
15
- const flattened = filterByPredicate(tokens, () => true);
16
- const result = [];
17
- for (let i = 0; i < flattened.length; i++) {
18
- const current = flattened[i];
19
- const openTagInfo = getHtmlTagInfo(current);
20
- if (openTagInfo && !openTagInfo.close) {
21
- let count = 1;
22
- for (let j = i + 1; j < flattened.length; j++) {
23
- const candidate = flattened[j];
24
- const closeTagInfo = getHtmlTagInfo(candidate);
25
- if (closeTagInfo && (openTagInfo.name === closeTagInfo.name)) {
26
- if (closeTagInfo.close) {
27
- count--;
28
- if (count === 0) {
29
- i = j;
30
- break;
14
+ const literalAutolinks = (tokens) => (
15
+ filterByPredicate(
16
+ tokens,
17
+ (token) => (token.type === "literalAutolink") && !inHtmlFlow(token),
18
+ (token) => {
19
+ const { children } = token;
20
+ const result = [];
21
+ for (let i = 0; i < children.length; i++) {
22
+ const current = children[i];
23
+ const openTagInfo = getHtmlTagInfo(current);
24
+ if (openTagInfo && !openTagInfo.close) {
25
+ let count = 1;
26
+ for (let j = i + 1; j < children.length; j++) {
27
+ const candidate = children[j];
28
+ const closeTagInfo = getHtmlTagInfo(candidate);
29
+ if (closeTagInfo && (openTagInfo.name === closeTagInfo.name)) {
30
+ if (closeTagInfo.close) {
31
+ count--;
32
+ if (count === 0) {
33
+ i = j;
34
+ break;
35
+ }
36
+ } else {
37
+ count++;
38
+ }
31
39
  }
32
- } else {
33
- count++;
34
40
  }
41
+ } else {
42
+ result.push(current);
35
43
  }
36
44
  }
37
- } else {
38
- result.push(current);
45
+ return result;
39
46
  }
40
- }
41
- return result.filter((token) => token.type === "literalAutolink");
42
- };
47
+ )
48
+ );
43
49
  const autoLinks = filterByTypes(
44
50
  params.parsers.micromark.tokens,
45
51
  [ "literalAutolink" ]
package/lib/md036.js CHANGED
@@ -5,9 +5,9 @@
5
5
  const { addErrorContext, allPunctuation } = require("../helpers");
6
6
 
7
7
  module.exports = {
8
- "names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ],
8
+ "names": [ "MD036", "no-emphasis-as-heading" ],
9
9
  "description": "Emphasis used instead of a heading",
10
- "tags": [ "headings", "headers", "emphasis" ],
10
+ "tags": [ "headings", "emphasis" ],
11
11
  "function": function MD036(params, onError) {
12
12
  let punctuation = params.config.punctuation;
13
13
  punctuation =
package/lib/md037.js CHANGED
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
 
5
5
  const { addError } = require("../helpers");
6
- const { filterByPredicate } = require("../helpers/micromark.cjs");
6
+ const { filterByPredicate, inHtmlFlow } = require("../helpers/micromark.cjs");
7
7
 
8
8
  module.exports = {
9
9
  "names": [ "MD037", "no-space-in-emphasis" ],
@@ -31,7 +31,7 @@ module.exports = {
31
31
  const { text, type } = child;
32
32
  if ((type === "data") && (text.length <= 3)) {
33
33
  const emphasisTokens = emphasisTokensByMarker.get(text);
34
- if (emphasisTokens) {
34
+ if (emphasisTokens && !inHtmlFlow(child)) {
35
35
  emphasisTokens.push(child);
36
36
  }
37
37
  }