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.
Files changed (61) hide show
  1. package/.eslintrc.json +52 -275
  2. package/.travis.yml +2 -2
  3. package/LICENSE +1 -1
  4. package/README.md +54 -27
  5. package/doc/CustomRules.md +7 -2
  6. package/doc/Rules.md +120 -33
  7. package/example/standalone.js +2 -2
  8. package/helpers/LICENSE +21 -0
  9. package/helpers/README.md +50 -0
  10. package/{lib/shared.js → helpers/helpers.js} +91 -82
  11. package/helpers/package.json +18 -0
  12. package/lib/cache.js +24 -0
  13. package/lib/markdownlint.js +78 -45
  14. package/lib/md001.js +3 -3
  15. package/lib/md002.js +2 -2
  16. package/lib/md003.js +5 -4
  17. package/lib/md004.js +11 -9
  18. package/lib/md005.js +12 -10
  19. package/lib/md006.js +7 -5
  20. package/lib/md007.js +7 -5
  21. package/lib/md009.js +10 -8
  22. package/lib/md010.js +5 -5
  23. package/lib/md011.js +4 -4
  24. package/lib/md012.js +4 -3
  25. package/lib/md013.js +41 -32
  26. package/lib/md014.js +7 -6
  27. package/lib/md018.js +6 -4
  28. package/lib/md019.js +6 -5
  29. package/lib/md020.js +5 -4
  30. package/lib/md021.js +6 -5
  31. package/lib/md022.js +22 -22
  32. package/lib/md023.js +5 -4
  33. package/lib/md024.js +6 -6
  34. package/lib/md025.js +11 -5
  35. package/lib/md026.js +4 -4
  36. package/lib/md027.js +6 -6
  37. package/lib/md028.js +2 -2
  38. package/lib/md029.js +17 -9
  39. package/lib/md030.js +8 -6
  40. package/lib/md031.js +7 -6
  41. package/lib/md032.js +10 -12
  42. package/lib/md033.js +27 -26
  43. package/lib/md034.js +15 -10
  44. package/lib/md035.js +3 -3
  45. package/lib/md036.js +2 -2
  46. package/lib/md037.js +12 -9
  47. package/lib/md038.js +6 -5
  48. package/lib/md039.js +7 -6
  49. package/lib/md040.js +3 -3
  50. package/lib/md041.js +17 -19
  51. package/lib/md042.js +5 -4
  52. package/lib/md043.js +5 -4
  53. package/lib/md044.js +14 -13
  54. package/lib/md045.js +3 -3
  55. package/lib/md046.js +32 -0
  56. package/lib/md047.js +18 -0
  57. package/lib/rules.js +3 -1
  58. package/package.json +12 -11
  59. package/schema/build-config-schema.js +36 -2
  60. package/schema/markdownlint-config-schema.json +178 -14
  61. 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 shared = require("./shared");
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
- shared.filterTokens(params, "heading_open", function forToken(token) {
15
+ filterTokens(params, "heading_open", function forToken(token) {
15
16
  if (spaceBeforeHeadingRe.test(token.line)) {
16
- shared.addErrorContext(onError, token.lineNumber, token.line, null,
17
- null, shared.rangeFromRegExp(token.line, spaceBeforeHeadingRe));
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 shared = require("./shared");
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
- shared.forEachHeading(params, function forHeading(heading, content) {
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.indexOf(content) === -1) {
31
- knownContent.push(content);
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 shared = require("./shared");
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
- shared.filterTokens(params, "heading_open", function forToken(token) {
21
+ filterTokens(params, "heading_open", function forToken(token) {
16
22
  if (token.tag === tag) {
17
- if (hasTopLevelHeading) {
18
- shared.addErrorContext(onError, token.lineNumber,
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 shared = require("./shared");
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
- shared.forEachHeading(params, function forHeading(heading, content) {
14
+ forEachHeading(params, function forHeading(heading, content) {
15
15
  const match = trailingPunctuationRe.exec(content);
16
16
  if (match) {
17
- shared.addError(onError, heading.lineNumber,
17
+ addError(onError, heading.lineNumber,
18
18
  "Punctuation: '" + match[0] + "'", null,
19
- shared.rangeFromRegExp(heading.line, trailingPunctuationRe));
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 shared = require("./shared");
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
- shared.addErrorContext(onError, token.lineNumber, token.line, null,
31
- null, shared.rangeFromRegExp(token.line, spaceAfterBlockQuote));
30
+ addErrorContext(onError, token.lineNumber, token.line, null,
31
+ null, rangeFromRegExp(token.line, spaceAfterBlockQuote));
32
32
  }
33
- token.content.split(shared.newLineRe)
33
+ token.content.split(newLineRe)
34
34
  .forEach(function forLine(line, offset) {
35
35
  if (/^\s/.test(line)) {
36
- shared.addErrorContext(onError, token.lineNumber + offset,
36
+ addErrorContext(onError, token.lineNumber + offset,
37
37
  "> " + line, null, null,
38
- shared.rangeFromRegExp(line, spaceAfterBlockQuote));
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 shared = require("./shared");
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
- shared.addError(onError, token.lineNumber - 1);
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 shared = require("./shared");
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
- shared.flattenLists().forEach(function forList(list) {
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
- shared.orderedListItemMarkerRe.exec(list.items[1].line);
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(function forItem(item) {
23
- const match = shared.orderedListItemMarkerRe.exec(item.line);
24
- shared.addErrorDetailIf(onError, item.lineNumber,
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: " + (listStyle === "one" ? "1/1/1" : "1/2/3"),
27
- shared.rangeFromRegExp(item.line, shared.listItemMarkerRe));
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 shared = require("./shared");
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
- shared.flattenLists().forEach(function forList(list) {
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(function forItem(item) {
24
+ list.items.forEach((item) => {
23
25
  const match = /^[\s>]*\S+(\s+)/.exec(item.line);
24
- shared.addErrorDetailIf(onError, item.lineNumber,
25
- expectedSpaces, (match ? match[1].length : 0), null,
26
- shared.rangeFromRegExp(item.line, shared.listItemMarkerRe));
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 shared = require("./shared");
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.lines;
13
- shared.forEachLine(function forLine(line, i, inCode, onFence) {
14
- if (((onFence > 0) && (i - 1 >= 0) && lines[i - 1].length) ||
15
- ((onFence < 0) && (i + 1 < lines.length) && lines[i + 1].length)) {
16
- shared.addErrorContext(onError, i + 1, lines[i].trim());
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 shared = require("./shared");
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
- shared.flattenLists().filter((list) => !list.nesting).forEach((list) => {
15
- const firstLineIndex = list.open.map[0];
16
- if (!blankLineRe.test(params.lines[firstLineIndex - 1] || "")) {
17
- shared.addErrorContext(
18
- onError, firstLineIndex + 1, params.lines[firstLineIndex].trim());
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 bottomLineIndex = list.lastLineIndex - 1;
21
- if (!blankLineRe.test(params.lines[bottomLineIndex + 1] || "")) {
22
- shared.addErrorContext(
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 shared = require("./shared");
5
+ const { addError, bareUrlRe, forEachLine, unescapeMarkdown } =
6
+ require("../helpers");
7
+ const { lineMetadata } = require("./cache");
6
8
 
7
- const htmlRe = /<[^>]*>/;
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(function forElement(element) {
16
- return element.toLowerCase();
17
- });
18
- function forToken(token) {
19
- token.content.split(shared.newLineRe)
20
- .forEach(function forLine(line, offset) {
21
- const allowed = (line.match(/<[^/\s>!]*/g) || [])
22
- .filter(function forElement(element) {
23
- return element.length > 1;
24
- })
25
- .map(function forElement(element) {
26
- return element.slice(1).toLowerCase();
27
- })
28
- .filter(function forElement(element) {
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
- shared.filterTokens(params, "html_block", forToken);
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 shared = require("./shared");
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
- shared.filterTokens(params, "inline", function forToken(token) {
12
+ filterTokens(params, "inline", (token) => {
13
13
  let inLink = false;
14
- token.children.forEach(function forChild(child) {
14
+ token.children.forEach((child) => {
15
+ const { content, line, lineNumber, type } = child;
15
16
  let match = null;
16
- if (child.type === "link_open") {
17
+ if (type === "link_open") {
17
18
  inLink = true;
18
- } else if (child.type === "link_close") {
19
+ } else if (type === "link_close") {
19
20
  inLink = false;
20
- } else if ((child.type === "text") &&
21
- !inLink &&
22
- (match = shared.bareUrlRe.exec(child.content))) {
23
- shared.addErrorContext(onError, child.lineNumber, match[0], null,
24
- null, shared.rangeFromRegExp(child.line, shared.bareUrlRe));
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 shared = require("./shared");
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
- shared.filterTokens(params, "hr", function forToken(token) {
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
- shared.addErrorDetailIf(onError, token.lineNumber, style, lineTrim);
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 shared = require("./shared");
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
- shared.addErrorContext(onError, t.lineNumber,
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 shared = require("./shared");
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
- shared.forEachInlineChild(params, "text", function forToken(token) {
12
+ forEachInlineChild(params, "text", (token) => {
13
13
  let left = true;
14
- let match = /\s(\*\*?|__?)\s.+\1/.exec(token.content);
14
+ let match = /(?:^|\s)(\*\*?|__?)\s.*[^\\]\1/.exec(token.content);
15
15
  if (!match) {
16
16
  left = false;
17
- match = /(\*\*?|__?).+\s\1\s/.exec(token.content);
17
+ match = /(?:^|[^\\])(\*\*?|__?).+\s\1(?:\s|$)/.exec(token.content);
18
18
  }
19
19
  if (match) {
20
- const text = match[0].trim();
20
+ const fullText = match[0];
21
21
  const line = params.lines[token.lineNumber - 1];
22
- const column = line.indexOf(text) + 1;
23
- const length = text.length;
24
- shared.addErrorContext(onError, token.lineNumber,
25
- text, left, !left, [ column, length ]);
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 shared = require("./shared");
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
- shared.filterTokens(params, "inline", (token) => {
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
- shared.forEachInlineCodeSpan(
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(shared.newLineRe);
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
- shared.addErrorContext(
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 shared = require("./shared");
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
- shared.filterTokens(params, "inline", function forToken(token) {
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 = shared.trimLeft(linkText).length !== linkText.length;
24
- const right = shared.trimRight(linkText).length !== linkText.length;
24
+ const left = linkText.trimLeft().length !== linkText.length;
25
+ const right = linkText.trimRight().length !== linkText.length;
25
26
  if (left || right) {
26
- shared.addErrorContext(onError, token.lineNumber,
27
+ addErrorContext(onError, token.lineNumber,
27
28
  "[" + linkText + "]", left, right,
28
- shared.rangeFromRegExp(token.line, spaceInLinkRe));
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 shared = require("./shared");
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
- shared.filterTokens(params, "fence", function forToken(token) {
12
+ filterTokens(params, "fence", function forToken(token) {
13
13
  if (!token.info.trim()) {
14
- shared.addErrorContext(onError, token.lineNumber, token.line);
14
+ addErrorContext(onError, token.lineNumber, token.line);
15
15
  }
16
16
  });
17
17
  }