eslint-markdown 0.17.1 → 0.18.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/build/configs/all.d.ts +1 -0
- package/build/configs/all.js +1 -0
- package/build/configs/stylistic.d.ts +1 -0
- package/build/configs/stylistic.js +1 -0
- package/build/core/constants.d.ts +11 -0
- package/build/core/constants.js +11 -0
- package/build/core/utils/get-heading-style.d.ts +14 -0
- package/build/core/utils/get-heading-style.js +26 -0
- package/build/core/utils/index.d.ts +1 -0
- package/build/core/utils/index.js +1 -0
- package/build/rules/consistent-code-style.d.ts +3 -3
- package/build/rules/consistent-code-style.js +5 -1
- package/build/rules/consistent-heading-style.d.ts +18 -5
- package/build/rules/consistent-heading-style.js +6 -21
- package/build/rules/index.d.ts +64 -3
- package/build/rules/index.js +2 -0
- package/build/rules/no-consecutive-blank-line.d.ts +10 -0
- package/build/rules/no-consecutive-blank-line.js +9 -1
- package/build/rules/no-double-punctuation.js +8 -2
- package/build/rules/no-emoji.d.ts +14 -1
- package/build/rules/no-emoji.js +10 -3
- package/build/rules/no-multiple-atx-heading-space.d.ts +55 -0
- package/build/rules/no-multiple-atx-heading-space.js +101 -0
- package/build/rules/no-tab.d.ts +20 -0
- package/build/rules/no-tab.js +17 -1
- package/build/rules/no-trailing-heading-punctuation.js +2 -10
- package/package.json +1 -1
package/build/configs/all.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export default function all(plugin: ESLint.Plugin): {
|
|
|
37
37
|
readonly 'md/no-git-conflict-marker': "error";
|
|
38
38
|
readonly 'md/no-irregular-dash': "error";
|
|
39
39
|
readonly 'md/no-irregular-whitespace': "error";
|
|
40
|
+
readonly 'md/no-multiple-atx-heading-space': "error";
|
|
40
41
|
readonly 'md/no-shell-dollar': "error";
|
|
41
42
|
readonly 'md/no-tab': "error";
|
|
42
43
|
readonly 'md/no-trailing-heading-punctuation': "error";
|
package/build/configs/all.js
CHANGED
|
@@ -45,6 +45,7 @@ export default function all(plugin) {
|
|
|
45
45
|
'md/no-git-conflict-marker': 'error',
|
|
46
46
|
'md/no-irregular-dash': 'error',
|
|
47
47
|
'md/no-irregular-whitespace': 'error',
|
|
48
|
+
'md/no-multiple-atx-heading-space': 'error',
|
|
48
49
|
'md/no-shell-dollar': 'error',
|
|
49
50
|
'md/no-tab': 'error',
|
|
50
51
|
'md/no-trailing-heading-punctuation': 'error',
|
|
@@ -25,6 +25,7 @@ export default function stylistic(plugin: ESLint.Plugin): {
|
|
|
25
25
|
readonly 'md/consistent-thematic-break-style': "error";
|
|
26
26
|
readonly 'md/consistent-unordered-list-style': "error";
|
|
27
27
|
readonly 'md/no-consecutive-blank-line': "error";
|
|
28
|
+
readonly 'md/no-multiple-atx-heading-space': "error";
|
|
28
29
|
readonly 'md/no-tab': "error";
|
|
29
30
|
readonly 'md/no-trailing-heading-punctuation': "error";
|
|
30
31
|
};
|
|
@@ -33,6 +33,7 @@ export default function stylistic(plugin) {
|
|
|
33
33
|
'md/consistent-thematic-break-style': 'error',
|
|
34
34
|
'md/consistent-unordered-list-style': 'error',
|
|
35
35
|
'md/no-consecutive-blank-line': 'error',
|
|
36
|
+
'md/no-multiple-atx-heading-space': 'error',
|
|
36
37
|
'md/no-tab': 'error',
|
|
37
38
|
'md/no-trailing-heading-punctuation': 'error',
|
|
38
39
|
},
|
|
@@ -40,3 +40,14 @@ export declare const escapedTrailingBackslashRegex: RegExp;
|
|
|
40
40
|
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/helpers/helpers.cjs#L36-L38
|
|
41
41
|
*/
|
|
42
42
|
export declare const gemojiRegex: RegExp;
|
|
43
|
+
/**
|
|
44
|
+
* Regular expression for identifying an HTML entity.
|
|
45
|
+
* - NOTE: This pattern is based on `markdownlint`.
|
|
46
|
+
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/helpers/helpers.cjs#L32-L34
|
|
47
|
+
*/
|
|
48
|
+
export declare const htmlEntityRegex: RegExp;
|
|
49
|
+
/**
|
|
50
|
+
* Matches the closing sequence of a closed ATX heading.
|
|
51
|
+
* @see https://spec.commonmark.org/0.31.2/#atx-headings
|
|
52
|
+
*/
|
|
53
|
+
export declare const trailingAtxHeadingHashRegex: RegExp;
|
package/build/core/constants.js
CHANGED
|
@@ -59,5 +59,16 @@ export const escapedTrailingBackslashRegex = /(?<=(?<!\\)(?:\\{2})*)\\$/u;
|
|
|
59
59
|
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/helpers/helpers.cjs#L36-L38
|
|
60
60
|
*/
|
|
61
61
|
export const gemojiRegex = /:(?:[abmovx]|[-+]1|100|1234|(?:1st|2nd|3rd)_place_medal|8ball|clock\d{1,4}|e-mail|non-potable_water|o2|t-rex|u5272|u5408|u55b6|u6307|u6708|u6709|u6e80|u7121|u7533|u7981|u7a7a|[a-z]{2,15}2?|[a-z]{1,14}(?:_[a-z\d]{1,16})+):/;
|
|
62
|
+
/**
|
|
63
|
+
* Regular expression for identifying an HTML entity.
|
|
64
|
+
* - NOTE: This pattern is based on `markdownlint`.
|
|
65
|
+
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/helpers/helpers.cjs#L32-L34
|
|
66
|
+
*/
|
|
67
|
+
export const htmlEntityRegex = /(?<=(?<!\\)(?:\\{2})*)&(?:#\d+|#[xX][\da-fA-F]+|[a-zA-Z]{2,31}|blk\d{2}|emsp1[34]|frac\d{2}|sup\d|there4);/;
|
|
68
|
+
/**
|
|
69
|
+
* Matches the closing sequence of a closed ATX heading.
|
|
70
|
+
* @see https://spec.commonmark.org/0.31.2/#atx-headings
|
|
71
|
+
*/
|
|
72
|
+
export const trailingAtxHeadingHashRegex = /[ \t]#+[ \t]*$/;
|
|
62
73
|
// #endregion regex
|
|
63
74
|
// --------------------------------------------------------------------------------
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Get the style of a Markdown heading.
|
|
3
|
+
*/
|
|
4
|
+
import type { MarkdownSourceCode } from '@eslint/markdown';
|
|
5
|
+
import type { Heading } from 'mdast';
|
|
6
|
+
export type HeadingStyle = (typeof HEADING_STYLE)[number];
|
|
7
|
+
export declare const HEADING_STYLE: readonly ["atx", "atx-closed", "setext"];
|
|
8
|
+
/**
|
|
9
|
+
* Gets the style of a Markdown heading.
|
|
10
|
+
* @param node The heading node.
|
|
11
|
+
* @param sourceCode The Markdown source code.
|
|
12
|
+
* @returns The heading style.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getHeadingStyle(node: Heading, sourceCode: MarkdownSourceCode): HeadingStyle;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Get the style of a Markdown heading.
|
|
3
|
+
*/
|
|
4
|
+
import { trailingAtxHeadingHashRegex } from '../constants.js';
|
|
5
|
+
// --------------------------------------------------------------------------------
|
|
6
|
+
// Export
|
|
7
|
+
// --------------------------------------------------------------------------------
|
|
8
|
+
export const HEADING_STYLE = ['atx', 'atx-closed', 'setext'];
|
|
9
|
+
/**
|
|
10
|
+
* Gets the style of a Markdown heading.
|
|
11
|
+
* @param node The heading node.
|
|
12
|
+
* @param sourceCode The Markdown source code.
|
|
13
|
+
* @returns The heading style.
|
|
14
|
+
*/
|
|
15
|
+
export function getHeadingStyle(node, sourceCode) {
|
|
16
|
+
const { start, end } = sourceCode.getLoc(node);
|
|
17
|
+
if (start.line !== end.line /* Multiline Heading */) {
|
|
18
|
+
return 'setext';
|
|
19
|
+
}
|
|
20
|
+
else if (trailingAtxHeadingHashRegex.test(sourceCode.getText(node))) {
|
|
21
|
+
return 'atx-closed';
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return 'atx';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @fileoverview Rule to enforce consistent code style.
|
|
3
3
|
* @author lumir(lumirlumir)
|
|
4
4
|
*/
|
|
5
|
-
import { type CodeStyle } from '../core/utils/index.js';
|
|
6
5
|
/**
|
|
7
6
|
* Options for the `consistent-code-style` rule.
|
|
8
7
|
*/
|
|
@@ -12,7 +11,7 @@ type RuleOptions = [
|
|
|
12
11
|
* When `style` is set to `'consistent'`, the rule enforces that all code blocks in the document use the same style as the first one encountered.
|
|
13
12
|
* @default 'consistent'
|
|
14
13
|
*/
|
|
15
|
-
style:
|
|
14
|
+
style: (typeof EXTENDED_CODE_STYLE)[number];
|
|
16
15
|
/**
|
|
17
16
|
* Require a specific number of blank lines above each fenced code block.
|
|
18
17
|
* @default false
|
|
@@ -26,6 +25,7 @@ type RuleOptions = [
|
|
|
26
25
|
}
|
|
27
26
|
];
|
|
28
27
|
type MessageIds = 'style' | 'blankLineAbove' | 'blankLineBelow';
|
|
28
|
+
declare const EXTENDED_CODE_STYLE: readonly ["consistent", "indent", "fence-backtick", "fence-tilde"];
|
|
29
29
|
declare const _default: {
|
|
30
30
|
readonly meta: {
|
|
31
31
|
readonly type: "layout";
|
|
@@ -39,7 +39,7 @@ declare const _default: {
|
|
|
39
39
|
readonly type: "object";
|
|
40
40
|
readonly properties: {
|
|
41
41
|
readonly style: {
|
|
42
|
-
readonly enum: ["consistent", "indent", "fence-backtick", "fence-tilde"];
|
|
42
|
+
readonly enum: readonly ["consistent", "indent", "fence-backtick", "fence-tilde"];
|
|
43
43
|
};
|
|
44
44
|
readonly blankLineAbove: {
|
|
45
45
|
readonly oneOf: [{
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
import { CODE_STYLE, getCodeStyle, isBlankLine, } from '../core/utils/index.js';
|
|
18
18
|
import { URL_RULE_DOCS } from '../core/constants.js';
|
|
19
19
|
// --------------------------------------------------------------------------------
|
|
20
|
+
// Helper
|
|
21
|
+
// --------------------------------------------------------------------------------
|
|
22
|
+
const EXTENDED_CODE_STYLE = ['consistent', ...CODE_STYLE];
|
|
23
|
+
// --------------------------------------------------------------------------------
|
|
20
24
|
// Rule Definition
|
|
21
25
|
// --------------------------------------------------------------------------------
|
|
22
26
|
export default {
|
|
@@ -35,7 +39,7 @@ export default {
|
|
|
35
39
|
type: 'object',
|
|
36
40
|
properties: {
|
|
37
41
|
style: {
|
|
38
|
-
enum:
|
|
42
|
+
enum: EXTENDED_CODE_STYLE,
|
|
39
43
|
},
|
|
40
44
|
blankLineAbove: {
|
|
41
45
|
oneOf: [
|
|
@@ -5,12 +5,25 @@
|
|
|
5
5
|
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/lib/md003.mjs
|
|
6
6
|
*/
|
|
7
7
|
import type { Heading } from 'mdast';
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
type RuleOptions = [
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* When `style` is set to `'consistent'`, the rule enforces that all headings in the document use the same style as the first one encountered.
|
|
12
|
+
*
|
|
13
|
+
* You can also specify a particular style by setting `style` to one of the following values:
|
|
14
|
+
*
|
|
15
|
+
* - `'atx'`: Require ATX headings at every level, such as `## Heading`.
|
|
16
|
+
* - `'atx-closed'`: Require closed ATX headings at every level, such as `## Heading ##`.
|
|
17
|
+
* - `'setext'`: Require Setext headings at levels 1 and 2. Headings at levels 3 through 6 are reported because Setext does not support those levels.
|
|
18
|
+
* - `'setext-with-atx'`: Require Setext headings at levels 1 and 2, and ATX headings at levels 3 through 6.
|
|
19
|
+
* - `'setext-with-atx-closed'`: Require Setext headings at levels 1 and 2, and closed ATX headings at levels 3 through 6.
|
|
20
|
+
* @default 'consistent'
|
|
21
|
+
*/
|
|
22
|
+
style: (typeof EXTENDED_HEADING_STYLE)[number];
|
|
23
|
+
}
|
|
24
|
+
];
|
|
12
25
|
type MessageIds = 'style' | 'suggestAtxToSetext' | 'suggestAtxClosedToSetext';
|
|
13
|
-
declare const
|
|
26
|
+
declare const EXTENDED_HEADING_STYLE: readonly ["consistent", "atx", "atx-closed", "setext", "setext-with-atx", "setext-with-atx-closed"];
|
|
14
27
|
declare const _default: {
|
|
15
28
|
readonly meta: {
|
|
16
29
|
readonly type: "layout";
|
|
@@ -4,24 +4,18 @@
|
|
|
4
4
|
* @author lumir(lumirlumir)
|
|
5
5
|
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/lib/md003.mjs
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { HEADING_STYLE, getHeadingStyle } from '../core/utils/index.js';
|
|
8
|
+
import { URL_RULE_DOCS, trailingAtxHeadingHashRegex } from '../core/constants.js';
|
|
8
9
|
// --------------------------------------------------------------------------------
|
|
9
10
|
// Helper
|
|
10
11
|
// --------------------------------------------------------------------------------
|
|
11
12
|
const SETEXT_MAX_DEPTH = 2;
|
|
12
|
-
const
|
|
13
|
+
const EXTENDED_HEADING_STYLE = [
|
|
13
14
|
'consistent',
|
|
14
|
-
|
|
15
|
-
'atx-closed',
|
|
16
|
-
'setext',
|
|
15
|
+
...HEADING_STYLE,
|
|
17
16
|
'setext-with-atx',
|
|
18
17
|
'setext-with-atx-closed',
|
|
19
18
|
];
|
|
20
|
-
/**
|
|
21
|
-
* Matches the closing sequence of a closed ATX heading.
|
|
22
|
-
* @see https://spec.commonmark.org/0.31.2/#atx-headings
|
|
23
|
-
*/
|
|
24
|
-
const trailingAtxHeadingHashRegex = /[ \t]#+[ \t]*$/;
|
|
25
19
|
/**
|
|
26
20
|
* Returns the setext marker for the given heading depth.
|
|
27
21
|
* @param depth The depth of the heading (`1` or `2`).
|
|
@@ -49,7 +43,7 @@ export default {
|
|
|
49
43
|
type: 'object',
|
|
50
44
|
properties: {
|
|
51
45
|
style: {
|
|
52
|
-
enum:
|
|
46
|
+
enum: EXTENDED_HEADING_STYLE,
|
|
53
47
|
},
|
|
54
48
|
},
|
|
55
49
|
additionalProperties: false,
|
|
@@ -88,16 +82,7 @@ export default {
|
|
|
88
82
|
return {
|
|
89
83
|
// The `heading` selector is more general, so it is visited before the other `heading[xxx]` selectors.
|
|
90
84
|
heading(node) {
|
|
91
|
-
|
|
92
|
-
if (start.line !== end.line /* Multiline Heading */) {
|
|
93
|
-
currentHeadingStyle = 'setext';
|
|
94
|
-
}
|
|
95
|
-
else if (trailingAtxHeadingHashRegex.test(sourceCode.getText(node))) {
|
|
96
|
-
currentHeadingStyle = 'atx-closed';
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
currentHeadingStyle = 'atx';
|
|
100
|
-
}
|
|
85
|
+
currentHeadingStyle = getHeadingStyle(node, sourceCode);
|
|
101
86
|
if (headingStyle === null) {
|
|
102
87
|
headingStyle = currentHeadingStyle;
|
|
103
88
|
}
|
package/build/rules/index.d.ts
CHANGED
|
@@ -445,7 +445,7 @@ declare const _default: {
|
|
|
445
445
|
readonly type: "object";
|
|
446
446
|
readonly properties: {
|
|
447
447
|
readonly style: {
|
|
448
|
-
readonly enum: ["consistent", "indent", "fence-backtick", "fence-tilde"];
|
|
448
|
+
readonly enum: readonly ["consistent", "indent", "fence-backtick", "fence-tilde"];
|
|
449
449
|
};
|
|
450
450
|
readonly blankLineAbove: {
|
|
451
451
|
readonly oneOf: [{
|
|
@@ -481,7 +481,7 @@ declare const _default: {
|
|
|
481
481
|
};
|
|
482
482
|
readonly create: (context: import("../core/types.js").RuleContext<{
|
|
483
483
|
RuleOptions: [{
|
|
484
|
-
style: "
|
|
484
|
+
style: "indent" | "fence-backtick" | "fence-tilde" | "consistent";
|
|
485
485
|
blankLineAbove: number | false;
|
|
486
486
|
blankLineBelow: number | false;
|
|
487
487
|
}];
|
|
@@ -599,7 +599,7 @@ declare const _default: {
|
|
|
599
599
|
};
|
|
600
600
|
readonly create: (context: import("../core/types.js").RuleContext<{
|
|
601
601
|
RuleOptions: [{
|
|
602
|
-
style: "
|
|
602
|
+
style: "atx" | "atx-closed" | "setext" | "consistent" | "setext-with-atx" | "setext-with-atx-closed";
|
|
603
603
|
}];
|
|
604
604
|
MessageIds: "style" | "suggestAtxToSetext" | "suggestAtxClosedToSetext";
|
|
605
605
|
}>) => {
|
|
@@ -774,12 +774,16 @@ declare const _default: {
|
|
|
774
774
|
readonly uniqueItems: true;
|
|
775
775
|
}];
|
|
776
776
|
};
|
|
777
|
+
readonly skipMath: {
|
|
778
|
+
readonly type: "boolean";
|
|
779
|
+
};
|
|
777
780
|
};
|
|
778
781
|
readonly additionalProperties: false;
|
|
779
782
|
}];
|
|
780
783
|
readonly defaultOptions: [{
|
|
781
784
|
readonly max: 1;
|
|
782
785
|
readonly skipCode: true;
|
|
786
|
+
readonly skipMath: true;
|
|
783
787
|
}];
|
|
784
788
|
readonly messages: {
|
|
785
789
|
readonly noConsecutiveBlankLine: "More than {{ max }} consecutive blank line(s) are not allowed.";
|
|
@@ -791,10 +795,12 @@ declare const _default: {
|
|
|
791
795
|
RuleOptions: [{
|
|
792
796
|
max: number;
|
|
793
797
|
skipCode: boolean | string[];
|
|
798
|
+
skipMath: boolean;
|
|
794
799
|
}];
|
|
795
800
|
MessageIds: "noConsecutiveBlankLine";
|
|
796
801
|
}>) => {
|
|
797
802
|
code(node: import("mdast").Code): void;
|
|
803
|
+
math(node: import("mdast-util-math").Math): void;
|
|
798
804
|
'root:exit'(): void;
|
|
799
805
|
};
|
|
800
806
|
};
|
|
@@ -1016,11 +1022,15 @@ declare const _default: {
|
|
|
1016
1022
|
};
|
|
1017
1023
|
readonly uniqueItems: true;
|
|
1018
1024
|
};
|
|
1025
|
+
readonly style: {
|
|
1026
|
+
readonly enum: ["emoji", "gemoji"];
|
|
1027
|
+
};
|
|
1019
1028
|
};
|
|
1020
1029
|
readonly additionalProperties: false;
|
|
1021
1030
|
}];
|
|
1022
1031
|
readonly defaultOptions: [{
|
|
1023
1032
|
readonly allow: [];
|
|
1033
|
+
readonly style: "emoji";
|
|
1024
1034
|
}];
|
|
1025
1035
|
readonly messages: {
|
|
1026
1036
|
readonly noEmoji: "Emojis are not allowed.";
|
|
@@ -1031,6 +1041,7 @@ declare const _default: {
|
|
|
1031
1041
|
readonly create: (context: import("../core/types.js").RuleContext<{
|
|
1032
1042
|
RuleOptions: [{
|
|
1033
1043
|
allow: string[];
|
|
1044
|
+
style: "emoji" | "gemoji";
|
|
1034
1045
|
}];
|
|
1035
1046
|
MessageIds: "noEmoji";
|
|
1036
1047
|
}>) => {
|
|
@@ -1245,6 +1256,44 @@ declare const _default: {
|
|
|
1245
1256
|
'root:exit'(): void;
|
|
1246
1257
|
};
|
|
1247
1258
|
};
|
|
1259
|
+
'no-multiple-atx-heading-space': {
|
|
1260
|
+
readonly meta: {
|
|
1261
|
+
readonly type: "layout";
|
|
1262
|
+
readonly docs: {
|
|
1263
|
+
readonly description: "Disallow multiple spaces around ATX heading markers";
|
|
1264
|
+
readonly url: string;
|
|
1265
|
+
readonly recommended: false;
|
|
1266
|
+
readonly stylistic: true;
|
|
1267
|
+
};
|
|
1268
|
+
readonly fixable: "whitespace";
|
|
1269
|
+
readonly schema: [{
|
|
1270
|
+
readonly type: "object";
|
|
1271
|
+
readonly properties: {
|
|
1272
|
+
readonly checkClosedHeading: {
|
|
1273
|
+
readonly type: "boolean";
|
|
1274
|
+
};
|
|
1275
|
+
};
|
|
1276
|
+
readonly additionalProperties: false;
|
|
1277
|
+
}];
|
|
1278
|
+
readonly defaultOptions: [{
|
|
1279
|
+
readonly checkClosedHeading: true;
|
|
1280
|
+
}];
|
|
1281
|
+
readonly messages: {
|
|
1282
|
+
readonly noMultipleAtxHeadingSpace: "Multiple spaces after opening ATX heading markers are not allowed.";
|
|
1283
|
+
readonly noMultipleAtxClosedHeadingSpace: "Multiple spaces before closing ATX heading markers are not allowed.";
|
|
1284
|
+
};
|
|
1285
|
+
readonly language: "markdown";
|
|
1286
|
+
readonly dialects: ["commonmark", "gfm"];
|
|
1287
|
+
};
|
|
1288
|
+
readonly create: (context: import("../core/types.js").RuleContext<{
|
|
1289
|
+
RuleOptions: [{
|
|
1290
|
+
checkClosedHeading: boolean;
|
|
1291
|
+
}];
|
|
1292
|
+
MessageIds: "noMultipleAtxHeadingSpace" | "noMultipleAtxClosedHeadingSpace";
|
|
1293
|
+
}>) => {
|
|
1294
|
+
heading(node: import("mdast").Heading): void;
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1248
1297
|
'no-shell-dollar': {
|
|
1249
1298
|
readonly meta: {
|
|
1250
1299
|
readonly type: "problem";
|
|
@@ -1313,6 +1362,12 @@ declare const _default: {
|
|
|
1313
1362
|
readonly skipInlineCode: {
|
|
1314
1363
|
readonly type: "boolean";
|
|
1315
1364
|
};
|
|
1365
|
+
readonly skipMath: {
|
|
1366
|
+
readonly type: "boolean";
|
|
1367
|
+
};
|
|
1368
|
+
readonly skipInlineMath: {
|
|
1369
|
+
readonly type: "boolean";
|
|
1370
|
+
};
|
|
1316
1371
|
readonly tabWidth: {
|
|
1317
1372
|
readonly type: "integer";
|
|
1318
1373
|
readonly minimum: 1;
|
|
@@ -1323,6 +1378,8 @@ declare const _default: {
|
|
|
1323
1378
|
readonly defaultOptions: [{
|
|
1324
1379
|
readonly skipCode: true;
|
|
1325
1380
|
readonly skipInlineCode: true;
|
|
1381
|
+
readonly skipMath: true;
|
|
1382
|
+
readonly skipInlineMath: true;
|
|
1326
1383
|
readonly tabWidth: 4;
|
|
1327
1384
|
}];
|
|
1328
1385
|
readonly messages: {
|
|
@@ -1335,12 +1392,16 @@ declare const _default: {
|
|
|
1335
1392
|
RuleOptions: [{
|
|
1336
1393
|
skipCode: boolean | string[];
|
|
1337
1394
|
skipInlineCode: boolean;
|
|
1395
|
+
skipMath: boolean;
|
|
1396
|
+
skipInlineMath: boolean;
|
|
1338
1397
|
tabWidth: number;
|
|
1339
1398
|
}];
|
|
1340
1399
|
MessageIds: "noTab";
|
|
1341
1400
|
}>) => {
|
|
1342
1401
|
code(node: import("mdast").Code): void;
|
|
1343
1402
|
inlineCode(node: import("mdast").InlineCode): void;
|
|
1403
|
+
math(node: import("mdast-util-math").Math): void;
|
|
1404
|
+
inlineMath(node: import("mdast-util-math").InlineMath): void;
|
|
1344
1405
|
'root:exit'(): void;
|
|
1345
1406
|
};
|
|
1346
1407
|
};
|
package/build/rules/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import noEmoji from './no-emoji.js';
|
|
|
22
22
|
import noGitConflictMarker from './no-git-conflict-marker.js';
|
|
23
23
|
import noIrregularDash from './no-irregular-dash.js';
|
|
24
24
|
import noIrregularWhitespace from './no-irregular-whitespace.js';
|
|
25
|
+
import noMultipleAtxHeadingSpace from './no-multiple-atx-heading-space.js';
|
|
25
26
|
import noShellDollar from './no-shell-dollar.js';
|
|
26
27
|
import noTab from './no-tab.js';
|
|
27
28
|
import noTrailingHeadingPunctuation from './no-trailing-heading-punctuation.js';
|
|
@@ -52,6 +53,7 @@ export default {
|
|
|
52
53
|
'no-git-conflict-marker': noGitConflictMarker,
|
|
53
54
|
'no-irregular-dash': noIrregularDash,
|
|
54
55
|
'no-irregular-whitespace': noIrregularWhitespace,
|
|
56
|
+
'no-multiple-atx-heading-space': noMultipleAtxHeadingSpace,
|
|
55
57
|
'no-shell-dollar': noShellDollar,
|
|
56
58
|
'no-tab': noTab,
|
|
57
59
|
'no-trailing-heading-punctuation': noTrailingHeadingPunctuation,
|
|
@@ -20,6 +20,11 @@ type RuleOptions = [
|
|
|
20
20
|
* @default true
|
|
21
21
|
*/
|
|
22
22
|
skipCode: boolean | string[];
|
|
23
|
+
/**
|
|
24
|
+
* `true` allows consecutive blank lines in all math blocks.
|
|
25
|
+
* @default true
|
|
26
|
+
*/
|
|
27
|
+
skipMath: boolean;
|
|
23
28
|
}
|
|
24
29
|
];
|
|
25
30
|
declare const _default: {
|
|
@@ -50,12 +55,16 @@ declare const _default: {
|
|
|
50
55
|
readonly uniqueItems: true;
|
|
51
56
|
}];
|
|
52
57
|
};
|
|
58
|
+
readonly skipMath: {
|
|
59
|
+
readonly type: "boolean";
|
|
60
|
+
};
|
|
53
61
|
};
|
|
54
62
|
readonly additionalProperties: false;
|
|
55
63
|
}];
|
|
56
64
|
readonly defaultOptions: [{
|
|
57
65
|
readonly max: 1;
|
|
58
66
|
readonly skipCode: true;
|
|
67
|
+
readonly skipMath: true;
|
|
59
68
|
}];
|
|
60
69
|
readonly messages: {
|
|
61
70
|
readonly noConsecutiveBlankLine: "More than {{ max }} consecutive blank line(s) are not allowed.";
|
|
@@ -68,6 +77,7 @@ declare const _default: {
|
|
|
68
77
|
MessageIds: "noConsecutiveBlankLine";
|
|
69
78
|
}>) => {
|
|
70
79
|
code(node: import("mdast").Code): void;
|
|
80
|
+
math(node: import("mdast-util-math").Math): void;
|
|
71
81
|
'root:exit'(): void;
|
|
72
82
|
};
|
|
73
83
|
};
|
|
@@ -43,6 +43,9 @@ export default {
|
|
|
43
43
|
},
|
|
44
44
|
],
|
|
45
45
|
},
|
|
46
|
+
skipMath: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
},
|
|
46
49
|
},
|
|
47
50
|
additionalProperties: false,
|
|
48
51
|
},
|
|
@@ -51,6 +54,7 @@ export default {
|
|
|
51
54
|
{
|
|
52
55
|
max: 1,
|
|
53
56
|
skipCode: true,
|
|
57
|
+
skipMath: true,
|
|
54
58
|
},
|
|
55
59
|
],
|
|
56
60
|
messages: {
|
|
@@ -61,7 +65,7 @@ export default {
|
|
|
61
65
|
},
|
|
62
66
|
create(context) {
|
|
63
67
|
const { options, sourceCode } = context;
|
|
64
|
-
const [{ max, skipCode }] = options;
|
|
68
|
+
const [{ max, skipCode, skipMath }] = options;
|
|
65
69
|
const { lines, text } = sourceCode;
|
|
66
70
|
const skipRanges = new SkipRanges();
|
|
67
71
|
return {
|
|
@@ -69,6 +73,10 @@ export default {
|
|
|
69
73
|
if (Array.isArray(skipCode) ? node.lang && skipCode.includes(node.lang) : skipCode)
|
|
70
74
|
skipRanges.push(sourceCode.getRange(node)); // Store range information of `Code`.
|
|
71
75
|
},
|
|
76
|
+
math(node) {
|
|
77
|
+
if (skipMath)
|
|
78
|
+
skipRanges.push(sourceCode.getRange(node)); // Store range information of `Math`.
|
|
79
|
+
},
|
|
72
80
|
'root:exit'() {
|
|
73
81
|
let consecutiveBlankLineCount = 0;
|
|
74
82
|
for (let currentLineIdx = 0; currentLineIdx < lines.length; currentLineIdx++) {
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
// Import
|
|
7
7
|
// --------------------------------------------------------------------------------
|
|
8
8
|
import { escapeStringRegexp } from '../core/utils/index.js';
|
|
9
|
-
import { URL_RULE_DOCS, asciiPunctuationWithQuestionMark } from '../core/constants.js';
|
|
9
|
+
import { URL_RULE_DOCS, asciiPunctuationWithQuestionMark, gemojiRegex as originalGemojiRegex, htmlEntityRegex as originalHtmlEntityRegex, } from '../core/constants.js';
|
|
10
10
|
// --------------------------------------------------------------------------------
|
|
11
11
|
// Helper
|
|
12
12
|
// --------------------------------------------------------------------------------
|
|
13
13
|
const escapedAsciiPunctuationWithQuestionMark = escapeStringRegexp(asciiPunctuationWithQuestionMark.join(''));
|
|
14
|
+
const gemojiRegex = new RegExp(originalGemojiRegex.source, 'g');
|
|
15
|
+
const htmlEntityRegex = new RegExp(originalHtmlEntityRegex.source, 'g');
|
|
14
16
|
/**
|
|
15
17
|
* This pattern is based on the punctuation list used by `remark-lint`.
|
|
16
18
|
* @see https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-heading-punctuation#parameters
|
|
@@ -67,7 +69,11 @@ export default {
|
|
|
67
69
|
return {
|
|
68
70
|
text(node) {
|
|
69
71
|
const [nodeStartOffset] = sourceCode.getRange(node);
|
|
70
|
-
const matches = sourceCode
|
|
72
|
+
const matches = sourceCode
|
|
73
|
+
.getText(node) // Mask HTML entities and gemoji without changing their offsets in the original text.
|
|
74
|
+
.replace(gemojiRegex, match => ' '.repeat(match.length))
|
|
75
|
+
.replace(htmlEntityRegex, match => ' '.repeat(match.length))
|
|
76
|
+
.matchAll(doublePunctuationRegex);
|
|
71
77
|
for (const match of matches) {
|
|
72
78
|
const punctuation = match[0];
|
|
73
79
|
const startOffset = nodeStartOffset + match.index;
|
|
@@ -10,10 +10,19 @@ type RuleOptions = [
|
|
|
10
10
|
/**
|
|
11
11
|
* When specified, specific emoji sequences are allowed if they match one of the strings in this array.
|
|
12
12
|
*
|
|
13
|
-
* This is useful when a document intentionally uses a small set of raw Unicode emojis
|
|
13
|
+
* This is useful when a document intentionally uses a small set of raw Unicode emojis or shortcode style emojis
|
|
14
|
+
* while still disallowing all others. When `style` is `'gemoji'`, list shortcodes instead (e.g. `':smiley:'`).
|
|
14
15
|
* @default []
|
|
15
16
|
*/
|
|
16
17
|
allow: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Specifies the style of emojis to disallow.
|
|
20
|
+
*
|
|
21
|
+
* - `'emoji'`: Raw Unicode emojis (`😃`).
|
|
22
|
+
* - `'gemoji'`: Shortcode style emojis (`:smiley:`).
|
|
23
|
+
* @default 'emoji'
|
|
24
|
+
*/
|
|
25
|
+
style: 'emoji' | 'gemoji';
|
|
17
26
|
}
|
|
18
27
|
];
|
|
19
28
|
declare const _default: {
|
|
@@ -35,11 +44,15 @@ declare const _default: {
|
|
|
35
44
|
};
|
|
36
45
|
readonly uniqueItems: true;
|
|
37
46
|
};
|
|
47
|
+
readonly style: {
|
|
48
|
+
readonly enum: ["emoji", "gemoji"];
|
|
49
|
+
};
|
|
38
50
|
};
|
|
39
51
|
readonly additionalProperties: false;
|
|
40
52
|
}];
|
|
41
53
|
readonly defaultOptions: [{
|
|
42
54
|
readonly allow: [];
|
|
55
|
+
readonly style: "emoji";
|
|
43
56
|
}];
|
|
44
57
|
readonly messages: {
|
|
45
58
|
readonly noEmoji: "Emojis are not allowed.";
|
package/build/rules/no-emoji.js
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
// --------------------------------------------------------------------------------
|
|
6
6
|
// Import
|
|
7
7
|
// --------------------------------------------------------------------------------
|
|
8
|
-
import { URL_RULE_DOCS } from '../core/constants.js';
|
|
8
|
+
import { URL_RULE_DOCS, gemojiRegex as originalGemojiRegex } from '../core/constants.js';
|
|
9
9
|
// --------------------------------------------------------------------------------
|
|
10
10
|
// Helper
|
|
11
11
|
// --------------------------------------------------------------------------------
|
|
12
12
|
const emojiRegex = /\p{RGI_Emoji}/gv;
|
|
13
|
+
const gemojiRegex = new RegExp(originalGemojiRegex.source, 'g');
|
|
13
14
|
// --------------------------------------------------------------------------------
|
|
14
15
|
// Rule Definition
|
|
15
16
|
// --------------------------------------------------------------------------------
|
|
@@ -33,6 +34,9 @@ export default {
|
|
|
33
34
|
},
|
|
34
35
|
uniqueItems: true,
|
|
35
36
|
},
|
|
37
|
+
style: {
|
|
38
|
+
enum: ['emoji', 'gemoji'],
|
|
39
|
+
},
|
|
36
40
|
},
|
|
37
41
|
additionalProperties: false,
|
|
38
42
|
},
|
|
@@ -40,6 +44,7 @@ export default {
|
|
|
40
44
|
defaultOptions: [
|
|
41
45
|
{
|
|
42
46
|
allow: [],
|
|
47
|
+
style: 'emoji',
|
|
43
48
|
},
|
|
44
49
|
],
|
|
45
50
|
messages: {
|
|
@@ -50,11 +55,13 @@ export default {
|
|
|
50
55
|
},
|
|
51
56
|
create(context) {
|
|
52
57
|
const { sourceCode } = context;
|
|
53
|
-
const [{ allow }] = context.options;
|
|
58
|
+
const [{ allow, style }] = context.options;
|
|
54
59
|
return {
|
|
55
60
|
text(node) {
|
|
56
61
|
const [nodeStartOffset] = sourceCode.getRange(node);
|
|
57
|
-
const matches = sourceCode
|
|
62
|
+
const matches = sourceCode
|
|
63
|
+
.getText(node)
|
|
64
|
+
.matchAll(style === 'emoji' ? emojiRegex : gemojiRegex);
|
|
58
65
|
for (const match of matches) {
|
|
59
66
|
const emoji = match[0];
|
|
60
67
|
if (allow.includes(emoji))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow multiple spaces around ATX heading markers.
|
|
3
|
+
* @author Ga eun Lee(tooth-is-silver)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Options for the `no-multiple-atx-heading-space` rule.
|
|
7
|
+
*/
|
|
8
|
+
type RuleOptions = [
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* When `checkClosedHeading` is set to `false`, this rule stops checking for multiple
|
|
12
|
+
* consecutive spaces or tabs before the closing hash characters in closed ATX headings.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
checkClosedHeading: boolean;
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
type MessageIds = 'noMultipleAtxHeadingSpace' | 'noMultipleAtxClosedHeadingSpace';
|
|
19
|
+
declare const _default: {
|
|
20
|
+
readonly meta: {
|
|
21
|
+
readonly type: "layout";
|
|
22
|
+
readonly docs: {
|
|
23
|
+
readonly description: "Disallow multiple spaces around ATX heading markers";
|
|
24
|
+
readonly url: string;
|
|
25
|
+
readonly recommended: false;
|
|
26
|
+
readonly stylistic: true;
|
|
27
|
+
};
|
|
28
|
+
readonly fixable: "whitespace";
|
|
29
|
+
readonly schema: [{
|
|
30
|
+
readonly type: "object";
|
|
31
|
+
readonly properties: {
|
|
32
|
+
readonly checkClosedHeading: {
|
|
33
|
+
readonly type: "boolean";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
readonly additionalProperties: false;
|
|
37
|
+
}];
|
|
38
|
+
readonly defaultOptions: [{
|
|
39
|
+
readonly checkClosedHeading: true;
|
|
40
|
+
}];
|
|
41
|
+
readonly messages: {
|
|
42
|
+
readonly noMultipleAtxHeadingSpace: "Multiple spaces after opening ATX heading markers are not allowed.";
|
|
43
|
+
readonly noMultipleAtxClosedHeadingSpace: "Multiple spaces before closing ATX heading markers are not allowed.";
|
|
44
|
+
};
|
|
45
|
+
readonly language: "markdown";
|
|
46
|
+
readonly dialects: ["commonmark", "gfm"];
|
|
47
|
+
};
|
|
48
|
+
readonly create: (context: import("../core/types.js").RuleContext<{
|
|
49
|
+
RuleOptions: RuleOptions;
|
|
50
|
+
MessageIds: MessageIds;
|
|
51
|
+
}>) => {
|
|
52
|
+
heading(node: import("mdast").Heading): void;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export default _default;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow multiple spaces around ATX heading markers.
|
|
3
|
+
* @author Ga eun Lee(tooth-is-silver)
|
|
4
|
+
*/
|
|
5
|
+
// --------------------------------------------------------------------------------
|
|
6
|
+
// Import
|
|
7
|
+
// --------------------------------------------------------------------------------
|
|
8
|
+
import { getHeadingStyle } from '../core/utils/index.js';
|
|
9
|
+
import { URL_RULE_DOCS } from '../core/constants.js';
|
|
10
|
+
// --------------------------------------------------------------------------------
|
|
11
|
+
// Helper
|
|
12
|
+
// --------------------------------------------------------------------------------
|
|
13
|
+
const multipleSpacesRegex = /^[ \t]{2,}/u;
|
|
14
|
+
// --------------------------------------------------------------------------------
|
|
15
|
+
// Rule Definition
|
|
16
|
+
// --------------------------------------------------------------------------------
|
|
17
|
+
export default {
|
|
18
|
+
meta: {
|
|
19
|
+
type: 'layout',
|
|
20
|
+
docs: {
|
|
21
|
+
description: 'Disallow multiple spaces around ATX heading markers',
|
|
22
|
+
url: URL_RULE_DOCS('no-multiple-atx-heading-space'),
|
|
23
|
+
recommended: false,
|
|
24
|
+
stylistic: true,
|
|
25
|
+
},
|
|
26
|
+
fixable: 'whitespace',
|
|
27
|
+
schema: [
|
|
28
|
+
{
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
checkClosedHeading: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
defaultOptions: [
|
|
39
|
+
{
|
|
40
|
+
checkClosedHeading: true,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
messages: {
|
|
44
|
+
noMultipleAtxHeadingSpace: 'Multiple spaces after opening ATX heading markers are not allowed.',
|
|
45
|
+
noMultipleAtxClosedHeadingSpace: 'Multiple spaces before closing ATX heading markers are not allowed.',
|
|
46
|
+
},
|
|
47
|
+
language: 'markdown',
|
|
48
|
+
dialects: ['commonmark', 'gfm'],
|
|
49
|
+
},
|
|
50
|
+
create(context) {
|
|
51
|
+
const { sourceCode } = context;
|
|
52
|
+
const [{ checkClosedHeading }] = context.options;
|
|
53
|
+
/**
|
|
54
|
+
* @param text Text starting immediately after an opening sequence or heading content.
|
|
55
|
+
* @param textStartOffset Start offset of the text.
|
|
56
|
+
* @param messageId Message for the opening or closing sequence.
|
|
57
|
+
*/
|
|
58
|
+
function report(text, textStartOffset, messageId) {
|
|
59
|
+
const spacesMatch = multipleSpacesRegex.exec(text)?.[0];
|
|
60
|
+
if (!spacesMatch)
|
|
61
|
+
return;
|
|
62
|
+
// Empty ATX headings keep no whitespace; otherwise, keep the first character.
|
|
63
|
+
const startOffset = textStartOffset + Number(spacesMatch.length !== text.length);
|
|
64
|
+
const endOffset = textStartOffset + spacesMatch.length;
|
|
65
|
+
context.report({
|
|
66
|
+
loc: {
|
|
67
|
+
start: sourceCode.getLocFromIndex(startOffset),
|
|
68
|
+
end: sourceCode.getLocFromIndex(endOffset),
|
|
69
|
+
},
|
|
70
|
+
messageId,
|
|
71
|
+
fix(fixer) {
|
|
72
|
+
return fixer.removeRange([startOffset, endOffset]);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
heading(node) {
|
|
78
|
+
const currentHeadingStyle = getHeadingStyle(node, sourceCode);
|
|
79
|
+
if (currentHeadingStyle === 'setext') {
|
|
80
|
+
// Early returns when the heading is a Setext heading, as this rule only applies to ATX headings.
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const lastChildNode = node.children.at(-1);
|
|
84
|
+
const isClosedHeading = currentHeadingStyle === 'atx-closed';
|
|
85
|
+
const isEmptyHeading = !lastChildNode;
|
|
86
|
+
if (!checkClosedHeading && isClosedHeading && isEmptyHeading) {
|
|
87
|
+
// When closing checks are disabled, skip closed headings with no content
|
|
88
|
+
// (e.g., `'## ##'`), where opening and closing whitespace overlap.
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const text = sourceCode.getText(node);
|
|
92
|
+
const [nodeStartOffset] = sourceCode.getRange(node);
|
|
93
|
+
report(text.slice(node.depth), nodeStartOffset + node.depth, 'noMultipleAtxHeadingSpace');
|
|
94
|
+
if (checkClosedHeading && isClosedHeading && !isEmptyHeading) {
|
|
95
|
+
const [, lastChildNodeEndOffset] = sourceCode.getRange(lastChildNode);
|
|
96
|
+
report(text.slice(lastChildNodeEndOffset - nodeStartOffset), lastChildNodeEndOffset, 'noMultipleAtxClosedHeadingSpace');
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
};
|
package/build/rules/no-tab.d.ts
CHANGED
|
@@ -17,6 +17,16 @@ type RuleOptions = [
|
|
|
17
17
|
* @default true
|
|
18
18
|
*/
|
|
19
19
|
skipInlineCode: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* `true` allows tabs in all math blocks.
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
skipMath: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* `true` allows tabs in all inline math.
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
skipInlineMath: boolean;
|
|
20
30
|
/**
|
|
21
31
|
* Number of spaces to replace each tab with when applying an autofix.
|
|
22
32
|
* @default 4
|
|
@@ -51,6 +61,12 @@ declare const _default: {
|
|
|
51
61
|
readonly skipInlineCode: {
|
|
52
62
|
readonly type: "boolean";
|
|
53
63
|
};
|
|
64
|
+
readonly skipMath: {
|
|
65
|
+
readonly type: "boolean";
|
|
66
|
+
};
|
|
67
|
+
readonly skipInlineMath: {
|
|
68
|
+
readonly type: "boolean";
|
|
69
|
+
};
|
|
54
70
|
readonly tabWidth: {
|
|
55
71
|
readonly type: "integer";
|
|
56
72
|
readonly minimum: 1;
|
|
@@ -61,6 +77,8 @@ declare const _default: {
|
|
|
61
77
|
readonly defaultOptions: [{
|
|
62
78
|
readonly skipCode: true;
|
|
63
79
|
readonly skipInlineCode: true;
|
|
80
|
+
readonly skipMath: true;
|
|
81
|
+
readonly skipInlineMath: true;
|
|
64
82
|
readonly tabWidth: 4;
|
|
65
83
|
}];
|
|
66
84
|
readonly messages: {
|
|
@@ -75,6 +93,8 @@ declare const _default: {
|
|
|
75
93
|
}>) => {
|
|
76
94
|
code(node: import("mdast").Code): void;
|
|
77
95
|
inlineCode(node: import("mdast").InlineCode): void;
|
|
96
|
+
math(node: import("mdast-util-math").Math): void;
|
|
97
|
+
inlineMath(node: import("mdast-util-math").InlineMath): void;
|
|
78
98
|
'root:exit'(): void;
|
|
79
99
|
};
|
|
80
100
|
};
|
package/build/rules/no-tab.js
CHANGED
|
@@ -45,6 +45,12 @@ export default {
|
|
|
45
45
|
skipInlineCode: {
|
|
46
46
|
type: 'boolean',
|
|
47
47
|
},
|
|
48
|
+
skipMath: {
|
|
49
|
+
type: 'boolean',
|
|
50
|
+
},
|
|
51
|
+
skipInlineMath: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
},
|
|
48
54
|
tabWidth: {
|
|
49
55
|
type: 'integer',
|
|
50
56
|
minimum: 1,
|
|
@@ -57,6 +63,8 @@ export default {
|
|
|
57
63
|
{
|
|
58
64
|
skipCode: true,
|
|
59
65
|
skipInlineCode: true,
|
|
66
|
+
skipMath: true,
|
|
67
|
+
skipInlineMath: true,
|
|
60
68
|
tabWidth: 4,
|
|
61
69
|
},
|
|
62
70
|
],
|
|
@@ -68,7 +76,7 @@ export default {
|
|
|
68
76
|
},
|
|
69
77
|
create(context) {
|
|
70
78
|
const { sourceCode } = context;
|
|
71
|
-
const [{ skipCode, skipInlineCode, tabWidth }] = context.options;
|
|
79
|
+
const [{ skipCode, skipInlineCode, skipMath, skipInlineMath, tabWidth }] = context.options;
|
|
72
80
|
const skipRanges = new SkipRanges();
|
|
73
81
|
return {
|
|
74
82
|
code(node) {
|
|
@@ -79,6 +87,14 @@ export default {
|
|
|
79
87
|
if (skipInlineCode)
|
|
80
88
|
skipRanges.push(sourceCode.getRange(node)); // Store range information of `InlineCode`.
|
|
81
89
|
},
|
|
90
|
+
math(node) {
|
|
91
|
+
if (skipMath)
|
|
92
|
+
skipRanges.push(sourceCode.getRange(node)); // Store range information of `Math`.
|
|
93
|
+
},
|
|
94
|
+
inlineMath(node) {
|
|
95
|
+
if (skipInlineMath)
|
|
96
|
+
skipRanges.push(sourceCode.getRange(node)); // Store range information of `InlineMath`.
|
|
97
|
+
},
|
|
82
98
|
'root:exit'() {
|
|
83
99
|
const matches = sourceCode.text.matchAll(tabRegex);
|
|
84
100
|
for (const match of matches) {
|
|
@@ -6,20 +6,12 @@
|
|
|
6
6
|
// Import
|
|
7
7
|
// --------------------------------------------------------------------------------
|
|
8
8
|
import { escapeStringRegexp } from '../core/utils/index.js';
|
|
9
|
-
import { URL_RULE_DOCS, punctuation as defaultPunctuation, escapedTrailingBackslashRegex, gemojiRegex, } from '../core/constants.js';
|
|
9
|
+
import { URL_RULE_DOCS, punctuation as defaultPunctuation, escapedTrailingBackslashRegex, gemojiRegex, htmlEntityRegex, } from '../core/constants.js';
|
|
10
10
|
// --------------------------------------------------------------------------------
|
|
11
11
|
// Helper
|
|
12
12
|
// --------------------------------------------------------------------------------
|
|
13
|
-
/**
|
|
14
|
-
* Regular expression for identifying a GitHub emoji code at the end of a line.
|
|
15
|
-
*/
|
|
16
13
|
const trailingGemojiRegex = new RegExp(`${gemojiRegex.source}$`, gemojiRegex.flags);
|
|
17
|
-
|
|
18
|
-
* Regular expression for identifying an HTML entity at the end of a line.
|
|
19
|
-
* - NOTE: These patterns are based on the `markdownlint`.
|
|
20
|
-
* @see https://github.com/DavidAnson/markdownlint/blob/v0.41.1/helpers/helpers.cjs#L32-L34
|
|
21
|
-
*/
|
|
22
|
-
const trailingHtmlEntityRegex = /&(?:#\d+|#[xX][\da-fA-F]+|[a-zA-Z]{2,31}|blk\d{2}|emsp1[34]|frac\d{2}|sup\d|there4);$/;
|
|
14
|
+
const trailingHtmlEntityRegex = new RegExp(`${htmlEntityRegex.source}$`, htmlEntityRegex.flags);
|
|
23
15
|
// --------------------------------------------------------------------------------
|
|
24
16
|
// Rule Definition
|
|
25
17
|
// --------------------------------------------------------------------------------
|