eslint-markdown 0.1.0 → 0.2.0
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/stylistic.d.ts +1 -0
- package/build/rules/index.d.ts +1 -0
- package/build/rules/no-control-character.d.ts +9 -0
- package/build/rules/no-irregular-dash.d.ts +9 -0
- package/build/rules/no-irregular-whitespace.d.ts +9 -0
- package/build/rules/no-tab.d.ts +56 -0
- package/package.json +1 -1
- package/src/configs/all.js +1 -0
- package/src/configs/stylistic.js +1 -0
- package/src/rules/index.js +2 -0
- package/src/rules/no-control-character.js +12 -2
- package/src/rules/no-irregular-dash.js +12 -2
- package/src/rules/no-irregular-whitespace.js +12 -2
- package/src/rules/no-tab.js +128 -0
package/build/configs/all.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export default function all(plugin: ESLint.Plugin): {
|
|
|
28
28
|
readonly 'md/no-git-conflict-marker': "error";
|
|
29
29
|
readonly 'md/no-irregular-dash': "error";
|
|
30
30
|
readonly 'md/no-irregular-whitespace': "error";
|
|
31
|
+
readonly 'md/no-tab': "error";
|
|
31
32
|
readonly 'md/no-url-trailing-slash': "error";
|
|
32
33
|
readonly 'md/require-image-title': "error";
|
|
33
34
|
readonly 'md/require-link-title': "error";
|
|
@@ -18,6 +18,7 @@ export default function stylistic(plugin: ESLint.Plugin): {
|
|
|
18
18
|
readonly 'md/consistent-emphasis-style': "error";
|
|
19
19
|
readonly 'md/consistent-strong-style': "error";
|
|
20
20
|
readonly 'md/consistent-thematic-break-style': "error";
|
|
21
|
+
readonly 'md/no-tab': "error";
|
|
21
22
|
};
|
|
22
23
|
};
|
|
23
24
|
import type { ESLint } from "eslint";
|
package/build/rules/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ declare const _default: {
|
|
|
13
13
|
'no-git-conflict-marker': import("../core/types.js").RuleModule<import("./no-git-conflict-marker.js").RuleOptions, "noGitConflictMarker">;
|
|
14
14
|
'no-irregular-dash': import("../core/types.js").RuleModule<import("./no-irregular-dash.js").RuleOptions, "noIrregularDash">;
|
|
15
15
|
'no-irregular-whitespace': import("../core/types.js").RuleModule<import("./no-irregular-whitespace.js").RuleOptions, "noIrregularWhitespace">;
|
|
16
|
+
'no-tab': import("../core/types.js").RuleModule<import("./no-tab.js").RuleOptions, "noTab">;
|
|
16
17
|
'no-url-trailing-slash': import("../core/types.js").RuleModule<[], "noUrlTrailingSlash">;
|
|
17
18
|
'require-image-title': import("../core/types.js").RuleModule<import("./require-image-title.js").RuleOptions, "requireImageTitle">;
|
|
18
19
|
'require-link-title': import("../core/types.js").RuleModule<import("./require-link-title.js").RuleOptions, "requireLinkTitle">;
|
|
@@ -10,6 +10,13 @@ declare const _default: {
|
|
|
10
10
|
schema: {
|
|
11
11
|
type: "object";
|
|
12
12
|
properties: {
|
|
13
|
+
allow: {
|
|
14
|
+
type: "array";
|
|
15
|
+
items: {
|
|
16
|
+
type: "string";
|
|
17
|
+
};
|
|
18
|
+
uniqueItems: true;
|
|
19
|
+
};
|
|
13
20
|
skipCode: {
|
|
14
21
|
type: "boolean";
|
|
15
22
|
};
|
|
@@ -20,6 +27,7 @@ declare const _default: {
|
|
|
20
27
|
additionalProperties: false;
|
|
21
28
|
}[];
|
|
22
29
|
defaultOptions: [{
|
|
30
|
+
allow: never[];
|
|
23
31
|
skipCode: true;
|
|
24
32
|
skipInlineCode: true;
|
|
25
33
|
}];
|
|
@@ -43,6 +51,7 @@ declare const _default: {
|
|
|
43
51
|
};
|
|
44
52
|
export default _default;
|
|
45
53
|
export type RuleOptions = [{
|
|
54
|
+
allow: string[];
|
|
46
55
|
skipCode: boolean;
|
|
47
56
|
skipInlineCode: boolean;
|
|
48
57
|
}];
|
|
@@ -10,6 +10,13 @@ declare const _default: {
|
|
|
10
10
|
schema: {
|
|
11
11
|
type: "object";
|
|
12
12
|
properties: {
|
|
13
|
+
allow: {
|
|
14
|
+
type: "array";
|
|
15
|
+
items: {
|
|
16
|
+
type: "string";
|
|
17
|
+
};
|
|
18
|
+
uniqueItems: true;
|
|
19
|
+
};
|
|
13
20
|
skipCode: {
|
|
14
21
|
type: "boolean";
|
|
15
22
|
};
|
|
@@ -20,6 +27,7 @@ declare const _default: {
|
|
|
20
27
|
additionalProperties: false;
|
|
21
28
|
}[];
|
|
22
29
|
defaultOptions: [{
|
|
30
|
+
allow: never[];
|
|
23
31
|
skipCode: true;
|
|
24
32
|
skipInlineCode: true;
|
|
25
33
|
}];
|
|
@@ -43,6 +51,7 @@ declare const _default: {
|
|
|
43
51
|
};
|
|
44
52
|
export default _default;
|
|
45
53
|
export type RuleOptions = [{
|
|
54
|
+
allow: string[];
|
|
46
55
|
skipCode: boolean;
|
|
47
56
|
skipInlineCode: boolean;
|
|
48
57
|
}];
|
|
@@ -10,6 +10,13 @@ declare const _default: {
|
|
|
10
10
|
schema: {
|
|
11
11
|
type: "object";
|
|
12
12
|
properties: {
|
|
13
|
+
allow: {
|
|
14
|
+
type: "array";
|
|
15
|
+
items: {
|
|
16
|
+
type: "string";
|
|
17
|
+
};
|
|
18
|
+
uniqueItems: true;
|
|
19
|
+
};
|
|
13
20
|
skipCode: {
|
|
14
21
|
type: "boolean";
|
|
15
22
|
};
|
|
@@ -20,6 +27,7 @@ declare const _default: {
|
|
|
20
27
|
additionalProperties: false;
|
|
21
28
|
}[];
|
|
22
29
|
defaultOptions: [{
|
|
30
|
+
allow: never[];
|
|
23
31
|
skipCode: true;
|
|
24
32
|
skipInlineCode: true;
|
|
25
33
|
}];
|
|
@@ -43,6 +51,7 @@ declare const _default: {
|
|
|
43
51
|
};
|
|
44
52
|
export default _default;
|
|
45
53
|
export type RuleOptions = [{
|
|
54
|
+
allow: string[];
|
|
46
55
|
skipCode: boolean;
|
|
47
56
|
skipInlineCode: boolean;
|
|
48
57
|
}];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
meta: {
|
|
3
|
+
type: "problem";
|
|
4
|
+
docs: {
|
|
5
|
+
description: string;
|
|
6
|
+
url: string;
|
|
7
|
+
recommended: boolean;
|
|
8
|
+
stylistic: true;
|
|
9
|
+
};
|
|
10
|
+
fixable: "whitespace";
|
|
11
|
+
schema: {
|
|
12
|
+
type: "object";
|
|
13
|
+
properties: {
|
|
14
|
+
skipCode: {
|
|
15
|
+
type: "boolean";
|
|
16
|
+
};
|
|
17
|
+
skipInlineCode: {
|
|
18
|
+
type: "boolean";
|
|
19
|
+
};
|
|
20
|
+
tabWidth: {
|
|
21
|
+
type: "integer";
|
|
22
|
+
minimum: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
additionalProperties: false;
|
|
26
|
+
}[];
|
|
27
|
+
defaultOptions: [{
|
|
28
|
+
skipCode: true;
|
|
29
|
+
skipInlineCode: true;
|
|
30
|
+
tabWidth: number;
|
|
31
|
+
}];
|
|
32
|
+
messages: {
|
|
33
|
+
noTab: string;
|
|
34
|
+
};
|
|
35
|
+
language: string;
|
|
36
|
+
dialects: string[];
|
|
37
|
+
};
|
|
38
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
39
|
+
LangOptions: import("@eslint/markdown").MarkdownLanguageOptions;
|
|
40
|
+
Code: import("@eslint/markdown").MarkdownSourceCode;
|
|
41
|
+
RuleOptions: RuleOptions;
|
|
42
|
+
Node: import("mdast").Node;
|
|
43
|
+
MessageIds: "noTab";
|
|
44
|
+
}>): {
|
|
45
|
+
code(node: import("mdast").Code): void;
|
|
46
|
+
inlineCode(node: import("mdast").InlineCode): void;
|
|
47
|
+
'root:exit'(): void;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export default _default;
|
|
51
|
+
export type RuleOptions = [{
|
|
52
|
+
skipCode: boolean;
|
|
53
|
+
skipInlineCode: boolean;
|
|
54
|
+
tabWidth: number;
|
|
55
|
+
}];
|
|
56
|
+
export type MessageIds = "noTab";
|
package/package.json
CHANGED
package/src/configs/all.js
CHANGED
|
@@ -52,6 +52,7 @@ export default function all(plugin) {
|
|
|
52
52
|
'md/no-git-conflict-marker': 'error',
|
|
53
53
|
'md/no-irregular-dash': 'error',
|
|
54
54
|
'md/no-irregular-whitespace': 'error',
|
|
55
|
+
'md/no-tab': 'error',
|
|
55
56
|
'md/no-url-trailing-slash': 'error',
|
|
56
57
|
'md/require-image-title': 'error',
|
|
57
58
|
'md/require-link-title': 'error',
|
package/src/configs/stylistic.js
CHANGED
package/src/rules/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import noEmoji from './no-emoji.js';
|
|
|
20
20
|
import noGitConflictMarker from './no-git-conflict-marker.js';
|
|
21
21
|
import noIrregularDash from './no-irregular-dash.js';
|
|
22
22
|
import noIrregularWhitespace from './no-irregular-whitespace.js';
|
|
23
|
+
import noTab from './no-tab.js';
|
|
23
24
|
import noUrlTrailingSlash from './no-url-trailing-slash.js';
|
|
24
25
|
import requireImageTitle from './require-image-title.js';
|
|
25
26
|
import requireLinkTitle from './require-link-title.js';
|
|
@@ -43,6 +44,7 @@ export default {
|
|
|
43
44
|
'no-git-conflict-marker': noGitConflictMarker,
|
|
44
45
|
'no-irregular-dash': noIrregularDash,
|
|
45
46
|
'no-irregular-whitespace': noIrregularWhitespace,
|
|
47
|
+
'no-tab': noTab,
|
|
46
48
|
'no-url-trailing-slash': noUrlTrailingSlash,
|
|
47
49
|
'require-image-title': requireImageTitle,
|
|
48
50
|
'require-link-title': requireLinkTitle,
|
|
@@ -16,7 +16,7 @@ import { URL_RULE_DOCS } from '../core/constants.js';
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @import { RuleModule } from '../core/types.js';
|
|
19
|
-
* @typedef {[{ skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
19
|
+
* @typedef {[{ allow: string[], skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
20
20
|
* @typedef {'noControlCharacter'} MessageIds
|
|
21
21
|
*/
|
|
22
22
|
|
|
@@ -47,6 +47,13 @@ export default {
|
|
|
47
47
|
{
|
|
48
48
|
type: 'object',
|
|
49
49
|
properties: {
|
|
50
|
+
allow: {
|
|
51
|
+
type: 'array',
|
|
52
|
+
items: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
},
|
|
55
|
+
uniqueItems: true,
|
|
56
|
+
},
|
|
50
57
|
skipCode: {
|
|
51
58
|
type: 'boolean',
|
|
52
59
|
},
|
|
@@ -60,6 +67,7 @@ export default {
|
|
|
60
67
|
|
|
61
68
|
defaultOptions: [
|
|
62
69
|
{
|
|
70
|
+
allow: [],
|
|
63
71
|
skipCode: true,
|
|
64
72
|
skipInlineCode: true,
|
|
65
73
|
},
|
|
@@ -76,7 +84,7 @@ export default {
|
|
|
76
84
|
|
|
77
85
|
create(context) {
|
|
78
86
|
const { sourceCode } = context;
|
|
79
|
-
const [{ skipCode, skipInlineCode }] = context.options;
|
|
87
|
+
const [{ allow, skipCode, skipInlineCode }] = context.options;
|
|
80
88
|
|
|
81
89
|
const skipRanges = new SkipRanges();
|
|
82
90
|
|
|
@@ -95,6 +103,8 @@ export default {
|
|
|
95
103
|
for (const match of matches) {
|
|
96
104
|
const controlCharacter = match[0];
|
|
97
105
|
|
|
106
|
+
if (allow.includes(controlCharacter)) continue;
|
|
107
|
+
|
|
98
108
|
const startOffset = match.index;
|
|
99
109
|
const endOffset = startOffset + controlCharacter.length;
|
|
100
110
|
|
|
@@ -16,7 +16,7 @@ import { URL_RULE_DOCS } from '../core/constants.js';
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @import { RuleModule } from '../core/types.js';
|
|
19
|
-
* @typedef {[{ skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
19
|
+
* @typedef {[{ allow: string[], skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
20
20
|
* @typedef {'noIrregularDash'} MessageIds
|
|
21
21
|
*/
|
|
22
22
|
|
|
@@ -47,6 +47,13 @@ export default {
|
|
|
47
47
|
{
|
|
48
48
|
type: 'object',
|
|
49
49
|
properties: {
|
|
50
|
+
allow: {
|
|
51
|
+
type: 'array',
|
|
52
|
+
items: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
},
|
|
55
|
+
uniqueItems: true,
|
|
56
|
+
},
|
|
50
57
|
skipCode: {
|
|
51
58
|
type: 'boolean',
|
|
52
59
|
},
|
|
@@ -60,6 +67,7 @@ export default {
|
|
|
60
67
|
|
|
61
68
|
defaultOptions: [
|
|
62
69
|
{
|
|
70
|
+
allow: [],
|
|
63
71
|
skipCode: true,
|
|
64
72
|
skipInlineCode: true,
|
|
65
73
|
},
|
|
@@ -76,7 +84,7 @@ export default {
|
|
|
76
84
|
|
|
77
85
|
create(context) {
|
|
78
86
|
const { sourceCode } = context;
|
|
79
|
-
const [{ skipCode, skipInlineCode }] = context.options;
|
|
87
|
+
const [{ allow, skipCode, skipInlineCode }] = context.options;
|
|
80
88
|
|
|
81
89
|
const skipRanges = new SkipRanges();
|
|
82
90
|
|
|
@@ -95,6 +103,8 @@ export default {
|
|
|
95
103
|
for (const match of matches) {
|
|
96
104
|
const irregularDash = match[0];
|
|
97
105
|
|
|
106
|
+
if (allow.includes(irregularDash)) continue;
|
|
107
|
+
|
|
98
108
|
const startOffset = match.index;
|
|
99
109
|
const endOffset = startOffset + irregularDash.length;
|
|
100
110
|
|
|
@@ -16,7 +16,7 @@ import { URL_RULE_DOCS } from '../core/constants.js';
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @import { RuleModule } from '../core/types.js';
|
|
19
|
-
* @typedef {[{ skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
19
|
+
* @typedef {[{ allow: string[], skipCode: boolean, skipInlineCode: boolean }]} RuleOptions
|
|
20
20
|
* @typedef {'noIrregularWhitespace'} MessageIds
|
|
21
21
|
*/
|
|
22
22
|
|
|
@@ -47,6 +47,13 @@ export default {
|
|
|
47
47
|
{
|
|
48
48
|
type: 'object',
|
|
49
49
|
properties: {
|
|
50
|
+
allow: {
|
|
51
|
+
type: 'array',
|
|
52
|
+
items: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
},
|
|
55
|
+
uniqueItems: true,
|
|
56
|
+
},
|
|
50
57
|
skipCode: {
|
|
51
58
|
type: 'boolean',
|
|
52
59
|
},
|
|
@@ -60,6 +67,7 @@ export default {
|
|
|
60
67
|
|
|
61
68
|
defaultOptions: [
|
|
62
69
|
{
|
|
70
|
+
allow: [],
|
|
63
71
|
skipCode: true,
|
|
64
72
|
skipInlineCode: true,
|
|
65
73
|
},
|
|
@@ -77,7 +85,7 @@ export default {
|
|
|
77
85
|
|
|
78
86
|
create(context) {
|
|
79
87
|
const { sourceCode } = context;
|
|
80
|
-
const [{ skipCode, skipInlineCode }] = context.options;
|
|
88
|
+
const [{ allow, skipCode, skipInlineCode }] = context.options;
|
|
81
89
|
|
|
82
90
|
const skipRanges = new SkipRanges();
|
|
83
91
|
|
|
@@ -96,6 +104,8 @@ export default {
|
|
|
96
104
|
for (const match of matches) {
|
|
97
105
|
const irregularWhitespace = match[0];
|
|
98
106
|
|
|
107
|
+
if (allow.includes(irregularWhitespace)) continue;
|
|
108
|
+
|
|
99
109
|
const startOffset = match.index;
|
|
100
110
|
const endOffset = startOffset + irregularWhitespace.length;
|
|
101
111
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow tab characters.
|
|
3
|
+
* @author 루밀LuMir(lumirlumir)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// --------------------------------------------------------------------------------
|
|
7
|
+
// Import
|
|
8
|
+
// --------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
import { SkipRanges } from '../core/ast/index.js';
|
|
11
|
+
import { URL_RULE_DOCS } from '../core/constants.js';
|
|
12
|
+
|
|
13
|
+
// --------------------------------------------------------------------------------
|
|
14
|
+
// Typedef
|
|
15
|
+
// --------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @import { RuleModule } from '../core/types.js';
|
|
19
|
+
* @typedef {[{ skipCode: boolean, skipInlineCode: boolean, tabWidth: number }]} RuleOptions
|
|
20
|
+
* @typedef {'noTab'} MessageIds
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// --------------------------------------------------------------------------------
|
|
24
|
+
// Helper
|
|
25
|
+
// --------------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
const tabRegex = /\t/gu;
|
|
28
|
+
|
|
29
|
+
// --------------------------------------------------------------------------------
|
|
30
|
+
// Rule Definition
|
|
31
|
+
// --------------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
/** @type {RuleModule<RuleOptions, MessageIds>} */
|
|
34
|
+
export default {
|
|
35
|
+
meta: {
|
|
36
|
+
type: 'problem',
|
|
37
|
+
|
|
38
|
+
docs: {
|
|
39
|
+
description: 'Disallow tab characters',
|
|
40
|
+
url: URL_RULE_DOCS('no-tab'),
|
|
41
|
+
recommended: false,
|
|
42
|
+
stylistic: true,
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
fixable: 'whitespace',
|
|
46
|
+
|
|
47
|
+
schema: [
|
|
48
|
+
{
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
skipCode: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
},
|
|
54
|
+
skipInlineCode: {
|
|
55
|
+
type: 'boolean',
|
|
56
|
+
},
|
|
57
|
+
tabWidth: {
|
|
58
|
+
type: 'integer',
|
|
59
|
+
minimum: 1,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
|
|
66
|
+
defaultOptions: [
|
|
67
|
+
{
|
|
68
|
+
skipCode: true,
|
|
69
|
+
skipInlineCode: true,
|
|
70
|
+
tabWidth: 4,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
|
|
74
|
+
messages: {
|
|
75
|
+
noTab: 'Tab character is not allowed. Please use spaces instead.',
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
language: 'markdown',
|
|
79
|
+
|
|
80
|
+
dialects: ['commonmark', 'gfm'],
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
create(context) {
|
|
84
|
+
const { sourceCode } = context;
|
|
85
|
+
const [{ skipCode, skipInlineCode, tabWidth }] = context.options;
|
|
86
|
+
|
|
87
|
+
const skipRanges = new SkipRanges();
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
code(node) {
|
|
91
|
+
if (skipCode) skipRanges.push(sourceCode.getRange(node)); // Store range information of `Code`.
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
inlineCode(node) {
|
|
95
|
+
if (skipInlineCode) skipRanges.push(sourceCode.getRange(node)); // Store range information of `InlineCode`.
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
'root:exit'() {
|
|
99
|
+
const matches = sourceCode.text.matchAll(tabRegex);
|
|
100
|
+
|
|
101
|
+
for (const match of matches) {
|
|
102
|
+
const tab = match[0];
|
|
103
|
+
|
|
104
|
+
const startOffset = match.index;
|
|
105
|
+
const endOffset = startOffset + tab.length;
|
|
106
|
+
|
|
107
|
+
if (skipRanges.includes(startOffset)) continue;
|
|
108
|
+
|
|
109
|
+
context.report({
|
|
110
|
+
loc: {
|
|
111
|
+
start: sourceCode.getLocFromIndex(startOffset),
|
|
112
|
+
end: sourceCode.getLocFromIndex(endOffset),
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
messageId: 'noTab',
|
|
116
|
+
|
|
117
|
+
fix(fixer) {
|
|
118
|
+
return fixer.replaceTextRange(
|
|
119
|
+
[startOffset, endOffset],
|
|
120
|
+
' '.repeat(tabWidth),
|
|
121
|
+
);
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
};
|