eslint-markdown 0.8.0 → 0.9.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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/build/rules/index.d.ts +1 -1
- package/build/rules/no-double-punctuation.d.ts +6 -2
- package/package.json +5 -3
- package/src/rules/allow-heading.js +1 -1
- package/src/rules/allow-image-url.js +1 -1
- package/src/rules/allow-link-url.js +1 -1
- package/src/rules/code-lang-shorthand.js +1 -1
- package/src/rules/consistent-code-style.js +1 -1
- package/src/rules/consistent-delete-style.js +1 -1
- package/src/rules/consistent-emphasis-style.js +1 -1
- package/src/rules/consistent-inline-code-style.js +1 -1
- package/src/rules/consistent-strong-style.js +1 -1
- package/src/rules/consistent-thematic-break-style.js +1 -1
- package/src/rules/en-capitalization.js +1 -1
- package/src/rules/heading-id.js +1 -1
- package/src/rules/no-bold-paragraph.js +1 -1
- package/src/rules/no-control-character.js +1 -1
- package/src/rules/no-curly-quote.js +1 -1
- package/src/rules/no-double-punctuation.js +59 -3
- package/src/rules/no-double-space.js +1 -1
- package/src/rules/no-emoji.js +1 -1
- package/src/rules/no-git-conflict-marker.js +1 -1
- package/src/rules/no-irregular-dash.js +1 -1
- package/src/rules/no-irregular-whitespace.js +1 -1
- package/src/rules/no-tab.js +1 -1
- package/src/rules/no-url-trailing-slash.js +1 -1
- package/src/rules/require-image-title.js +1 -1
- package/src/rules/require-link-title.js +1 -1
- package/build/core/rule-tester.d.ts +0 -13
- package/build/rules/footnote-order.d.ts +0 -1
- package/src/core/rule-tester.js +0 -127
- package/src/rules/footnote-order.js +0 -2
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024-present
|
|
3
|
+
Copyright (c) 2024-present lumir(lumirlumir)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
> If you like this package, please give it a star on [GitHub](https://github.com/lumirlumir/npm-eslint-markdown)!⭐<br/>
|
|
14
14
|
> Your support helps us improve and maintain the project.
|
|
15
15
|
|
|
16
|
-
Lint your Markdown with ESLint
|
|
16
|
+
Lint your Markdown with ESLint. Additional rules for use with `@eslint/markdown`.🛠️
|
|
17
17
|
|
|
18
18
|
## Documentation
|
|
19
19
|
|
package/build/rules/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare const _default: {
|
|
|
11
11
|
'consistent-unordered-list-style': import("../core/types.js").RuleModule<import("./consistent-unordered-list-style.js").RuleOptions, "style">;
|
|
12
12
|
'no-control-character': import("../core/types.js").RuleModule<import("./no-control-character.js").RuleOptions, "noControlCharacter">;
|
|
13
13
|
'no-curly-quote': import("../core/types.js").RuleModule<import("./no-curly-quote.js").RuleOptions, "noCurlyQuote">;
|
|
14
|
-
'no-double-punctuation': import("../core/types.js").RuleModule<import("./no-double-punctuation.js").RuleOptions, "
|
|
14
|
+
'no-double-punctuation': import("../core/types.js").RuleModule<import("./no-double-punctuation.js").RuleOptions, import("./no-double-punctuation.js").MessageIds>;
|
|
15
15
|
'no-double-space': import("../core/types.js").RuleModule<import("./no-double-space.js").RuleOptions, import("./no-double-space.js").MessageIds>;
|
|
16
16
|
'no-emoji': import("../core/types.js").RuleModule<import("./no-emoji.js").RuleOptions, "noEmoji">;
|
|
17
17
|
'no-git-conflict-marker': import("../core/types.js").RuleModule<import("./no-git-conflict-marker.js").RuleOptions, "noGitConflictMarker">;
|
|
@@ -7,6 +7,8 @@ declare const _default: {
|
|
|
7
7
|
recommended: boolean;
|
|
8
8
|
stylistic: false;
|
|
9
9
|
};
|
|
10
|
+
fixable: "code";
|
|
11
|
+
hasSuggestions: true;
|
|
10
12
|
schema: {
|
|
11
13
|
type: "object";
|
|
12
14
|
properties: {
|
|
@@ -28,6 +30,8 @@ declare const _default: {
|
|
|
28
30
|
}];
|
|
29
31
|
messages: {
|
|
30
32
|
noDoublePunctuation: string;
|
|
33
|
+
suggestReplaceWithLeft: string;
|
|
34
|
+
suggestReplaceWithRight: string;
|
|
31
35
|
};
|
|
32
36
|
language: string;
|
|
33
37
|
dialects: string[];
|
|
@@ -37,7 +41,7 @@ declare const _default: {
|
|
|
37
41
|
Code: import("@eslint/markdown").MarkdownSourceCode;
|
|
38
42
|
RuleOptions: RuleOptions;
|
|
39
43
|
Node: import("mdast").Node;
|
|
40
|
-
MessageIds:
|
|
44
|
+
MessageIds: MessageIds;
|
|
41
45
|
}>): {
|
|
42
46
|
text(node: import("mdast").Text): void;
|
|
43
47
|
};
|
|
@@ -46,4 +50,4 @@ export default _default;
|
|
|
46
50
|
export type RuleOptions = [{
|
|
47
51
|
allow: string[];
|
|
48
52
|
}];
|
|
49
|
-
export type MessageIds = "noDoublePunctuation";
|
|
53
|
+
export type MessageIds = "noDoublePunctuation" | "suggestReplaceWithLeft" | "suggestReplaceWithRight";
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Lint your Markdown with ESLint. Additional rules for use with `@eslint/markdown`.🛠️",
|
|
6
7
|
"exports": {
|
|
7
8
|
".": {
|
|
8
9
|
"types": "./build/index.d.ts",
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
"LICENSE.md",
|
|
27
28
|
"README.md",
|
|
28
29
|
"!src/**/*.test.{js,ts}",
|
|
30
|
+
"!{src,build}/tests/**",
|
|
29
31
|
"!**/fixtures/**"
|
|
30
32
|
],
|
|
31
33
|
"keywords": [
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
"commonmark",
|
|
40
42
|
"gfm"
|
|
41
43
|
],
|
|
42
|
-
"author": "
|
|
44
|
+
"author": "lumir <rpfos@naver.com> (https://github.com/lumirlumir)",
|
|
43
45
|
"funding": "https://github.com/sponsors/lumirlumir",
|
|
44
46
|
"license": "MIT",
|
|
45
47
|
"homepage": "https://eslint-markdown.lumir.page",
|
package/src/rules/heading-id.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Rule to disallow double consecutive punctuation in text.
|
|
3
|
-
* @author
|
|
3
|
+
* @author lumir(lumirlumir)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// --------------------------------------------------------------------------------
|
|
@@ -16,7 +16,7 @@ import { URL_RULE_DOCS } from '../core/constants.js';
|
|
|
16
16
|
/**
|
|
17
17
|
* @import { RuleModule } from '../core/types.js';
|
|
18
18
|
* @typedef {[{ allow: string[] }]} RuleOptions
|
|
19
|
-
* @typedef {'noDoublePunctuation'} MessageIds
|
|
19
|
+
* @typedef {'noDoublePunctuation' | 'suggestReplaceWithLeft' | 'suggestReplaceWithRight'} MessageIds
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
// --------------------------------------------------------------------------------
|
|
@@ -45,6 +45,10 @@ export default {
|
|
|
45
45
|
stylistic: false,
|
|
46
46
|
},
|
|
47
47
|
|
|
48
|
+
fixable: 'code',
|
|
49
|
+
|
|
50
|
+
hasSuggestions: true,
|
|
51
|
+
|
|
48
52
|
schema: [
|
|
49
53
|
{
|
|
50
54
|
type: 'object',
|
|
@@ -72,6 +76,10 @@ export default {
|
|
|
72
76
|
|
|
73
77
|
messages: {
|
|
74
78
|
noDoublePunctuation: 'Double punctuation mark `{{ punctuation }}` is not allowed.',
|
|
79
|
+
suggestReplaceWithLeft:
|
|
80
|
+
'Replace `{{ punctuation }}` with the left punctuation mark `{{ leftPunctuation }}`.',
|
|
81
|
+
suggestReplaceWithRight:
|
|
82
|
+
'Replace `{{ punctuation }}` with the right punctuation mark `{{ rightPunctuation }}`.',
|
|
75
83
|
},
|
|
76
84
|
|
|
77
85
|
language: 'markdown',
|
|
@@ -96,7 +104,8 @@ export default {
|
|
|
96
104
|
|
|
97
105
|
if (allow.includes(punctuation)) continue;
|
|
98
106
|
|
|
99
|
-
|
|
107
|
+
const [leftPunctuation, rightPunctuation] = punctuation;
|
|
108
|
+
const violation = /** @type {const} */ ({
|
|
100
109
|
loc: {
|
|
101
110
|
start: sourceCode.getLocFromIndex(startOffset),
|
|
102
111
|
end: sourceCode.getLocFromIndex(endOffset),
|
|
@@ -108,6 +117,53 @@ export default {
|
|
|
108
117
|
|
|
109
118
|
messageId: 'noDoublePunctuation',
|
|
110
119
|
});
|
|
120
|
+
|
|
121
|
+
if (leftPunctuation === rightPunctuation) {
|
|
122
|
+
context.report({
|
|
123
|
+
...violation,
|
|
124
|
+
|
|
125
|
+
fix(fixer) {
|
|
126
|
+
return fixer.replaceTextRange([startOffset, endOffset], leftPunctuation);
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
} else {
|
|
130
|
+
context.report({
|
|
131
|
+
...violation,
|
|
132
|
+
|
|
133
|
+
suggest: [
|
|
134
|
+
{
|
|
135
|
+
messageId: 'suggestReplaceWithLeft',
|
|
136
|
+
|
|
137
|
+
data: {
|
|
138
|
+
punctuation,
|
|
139
|
+
leftPunctuation,
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
fix(fixer) {
|
|
143
|
+
return fixer.replaceTextRange(
|
|
144
|
+
[startOffset, endOffset],
|
|
145
|
+
leftPunctuation,
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
messageId: 'suggestReplaceWithRight',
|
|
151
|
+
|
|
152
|
+
data: {
|
|
153
|
+
punctuation,
|
|
154
|
+
rightPunctuation,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
fix(fixer) {
|
|
158
|
+
return fixer.replaceTextRange(
|
|
159
|
+
[startOffset, endOffset],
|
|
160
|
+
rightPunctuation,
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
111
167
|
}
|
|
112
168
|
},
|
|
113
169
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Rule to disallow double or multiple consecutive spaces in text, except for leading and trailing spaces.
|
|
3
|
-
* @author
|
|
3
|
+
* @author lumir(lumirlumir)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// --------------------------------------------------------------------------------
|
package/src/rules/no-emoji.js
CHANGED
package/src/rules/no-tab.js
CHANGED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Markdown rule tester.
|
|
3
|
-
* @param {string} ruleName Rule name.
|
|
4
|
-
* @param {RuleModule<RuleOptions, MessageIds>} rule Rule module.
|
|
5
|
-
* @param {Tests} tests Tests.
|
|
6
|
-
*/
|
|
7
|
-
export default function ruleTester(ruleName: string, rule: RuleModule<RuleOptions, MessageIds>, tests: Tests): void;
|
|
8
|
-
export type RuleOptions = MarkdownRuleDefinitionTypeOptions["RuleOptions"];
|
|
9
|
-
export type MessageIds = MarkdownRuleDefinitionTypeOptions["MessageIds"];
|
|
10
|
-
export type Tests = Parameters<RuleTester["run"]>[2];
|
|
11
|
-
import type { RuleModule } from './types.js';
|
|
12
|
-
import type { MarkdownRuleDefinitionTypeOptions } from '@eslint/markdown';
|
|
13
|
-
import { RuleTester } from 'eslint';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/core/rule-tester.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Markdown rule tester.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// --------------------------------------------------------------------------------
|
|
6
|
-
// Import
|
|
7
|
-
// --------------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
import { describe, it } from 'node:test';
|
|
10
|
-
import { match, ok } from 'node:assert';
|
|
11
|
-
import { RuleTester } from 'eslint';
|
|
12
|
-
import markdown from '@eslint/markdown';
|
|
13
|
-
|
|
14
|
-
// --------------------------------------------------------------------------------
|
|
15
|
-
// Typedef
|
|
16
|
-
// --------------------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @import { MarkdownRuleDefinitionTypeOptions } from '@eslint/markdown';
|
|
20
|
-
* @import { RuleModule } from './types.js';
|
|
21
|
-
* @typedef {MarkdownRuleDefinitionTypeOptions['RuleOptions']} RuleOptions
|
|
22
|
-
* @typedef {MarkdownRuleDefinitionTypeOptions['MessageIds']} MessageIds
|
|
23
|
-
* @typedef {Parameters<RuleTester['run']>[2]} Tests
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
// --------------------------------------------------------------------------------
|
|
27
|
-
// Helper
|
|
28
|
-
// --------------------------------------------------------------------------------
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Rule tester for CommonMark.
|
|
32
|
-
*/
|
|
33
|
-
const ruleTesterCommonmark = new RuleTester({
|
|
34
|
-
plugins: {
|
|
35
|
-
markdown,
|
|
36
|
-
},
|
|
37
|
-
language: 'markdown/commonmark',
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Rule tester for GFM.
|
|
42
|
-
*/
|
|
43
|
-
const ruleTesterGfm = new RuleTester({
|
|
44
|
-
plugins: {
|
|
45
|
-
markdown,
|
|
46
|
-
},
|
|
47
|
-
language: 'markdown/gfm',
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// --------------------------------------------------------------------------------
|
|
51
|
-
// Export
|
|
52
|
-
// --------------------------------------------------------------------------------
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Markdown rule tester.
|
|
56
|
-
* @param {string} ruleName Rule name.
|
|
57
|
-
* @param {RuleModule<RuleOptions, MessageIds>} rule Rule module.
|
|
58
|
-
* @param {Tests} tests Tests.
|
|
59
|
-
*/
|
|
60
|
-
export default function ruleTester(ruleName, rule, tests) {
|
|
61
|
-
const { meta } = rule;
|
|
62
|
-
|
|
63
|
-
describe(ruleName, () => {
|
|
64
|
-
describe('meta', () => {
|
|
65
|
-
it('`meta` should exist', () => {
|
|
66
|
-
ok(meta);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('`meta.type` should exist', () => {
|
|
70
|
-
ok(meta?.type);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('`meta.docs` should exist', () => {
|
|
74
|
-
ok(meta?.docs);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('`meta.docs.description` should exist and follow the convention', () => {
|
|
78
|
-
ok(meta?.docs?.description);
|
|
79
|
-
match(meta?.docs?.description, /^(?:Enforce|Require|Disallow) .+[^. ]$/);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('`meta.docs.url` should exist and end with the rule name', () => {
|
|
83
|
-
ok(meta?.docs?.url);
|
|
84
|
-
match(meta?.docs?.url, new RegExp(`${ruleName}$`));
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('`meta.messages` should exist', () => {
|
|
88
|
-
ok(meta?.messages);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('`meta.messages.messageId` should exist and value should follow the convention', () => {
|
|
92
|
-
// @ts-expect-error -- Required for testing.
|
|
93
|
-
Object.values(meta.messages).forEach(message => {
|
|
94
|
-
ok(message);
|
|
95
|
-
match(message, /^[^a-z].*\.$/);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("`meta.language` should exist and be `'markdown'`", () => {
|
|
100
|
-
ok(meta?.language);
|
|
101
|
-
match(meta?.language, /^markdown$/);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("`meta.dialects` should exist and be `'commonmark'` or `'gfm'`", () => {
|
|
105
|
-
ok(meta?.dialects);
|
|
106
|
-
ok(meta?.dialects.length > 0);
|
|
107
|
-
meta?.dialects.forEach(dialect => {
|
|
108
|
-
match(dialect, /^(?:commonmark|gfm)$/);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('rule', () => {
|
|
114
|
-
if (meta?.dialects?.includes('commonmark')) {
|
|
115
|
-
it('commonmark', () => {
|
|
116
|
-
ruleTesterCommonmark.run(ruleName, rule, tests);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (meta?.dialects?.includes('gfm')) {
|
|
121
|
-
it('gfm', () => {
|
|
122
|
-
ruleTesterGfm.run(ruleName, rule, tests);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|