-
-
Notifications
You must be signed in to change notification settings - Fork 32
/
remark.ts
126 lines (114 loc) · 3.52 KB
/
remark.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import path from 'node:path'
import type { Rule } from 'eslint'
import type { ParserOptions } from 'eslint-mdx'
import {
DEFAULT_EXTENSIONS,
MARKDOWN_EXTENSIONS,
getPhysicalFilename,
performSyncWork,
} from 'eslint-mdx'
import type { RemarkLintMessage } from './types'
export const remark: Rule.RuleModule = {
meta: {
type: 'layout',
docs: {
description: 'Linter integration with remark plugins',
category: 'Stylistic Issues',
recommended: true,
},
fixable: 'code',
},
create(context) {
// eslint-disable-next-line sonar/deprecation -- FIXME: ESLint 8.40+ required
const filename = context.getFilename()
const extname = path.extname(filename)
// eslint-disable-next-line sonar/deprecation -- FIXME: ESLint 8.40+ required
const sourceCode = context.getSourceCode()
const options = context.parserOptions as ParserOptions
const isMdx = [
...DEFAULT_EXTENSIONS,
...(options.extensions || []),
].includes(extname)
const isMarkdown = [
...MARKDOWN_EXTENSIONS,
...(options.markdownExtensions || []),
].includes(extname)
return {
// eslint-disable-next-line sonarjs/cognitive-complexity
Program(node) {
/* istanbul ignore if */
if (!isMdx && !isMarkdown) {
return
}
const ignoreRemarkConfig = Boolean(options.ignoreRemarkConfig)
const physicalFilename = getPhysicalFilename(filename)
const sourceText = sourceCode.getText(node)
const { messages, content: fixedText } = performSyncWork({
fileOptions: {
path: physicalFilename,
value: sourceText,
// eslint-disable-next-line sonar/deprecation -- FIXME: ESLint 8.40+ required
cwd: context.getCwd(),
},
physicalFilename,
isMdx,
process: true,
ignoreRemarkConfig,
})
let fixed = 0
for (const {
source,
reason,
ruleId,
fatal,
line,
column,
place,
} of messages) {
// https://github.com/remarkjs/remark-lint/issues/65#issuecomment-220800231
/* istanbul ignore next */
const severity = fatal ? 2 : fatal == null ? 0 : 1
/* istanbul ignore if */
if (!severity) {
// should never happen, just for robustness
continue
}
const message: RemarkLintMessage = {
reason,
source,
ruleId,
severity,
}
const point = {
line,
// ! eslint ast column is 0-indexed, but unified is 1-indexed
column: column - 1,
}
context.report({
// related to https://github.com/eslint/eslint/issues/14198
message: JSON.stringify(message),
loc:
/* istanbul ignore next */ place && 'start' in place
? {
...point,
start: { ...place.start, column: place.start.column - 1 },
end: { ...place.end, column: place.end.column - 1 },
}
: point,
node,
fix:
fixedText === sourceText
? null
: () =>
fixed++
? null
: {
range: [0, sourceText.length],
text: fixedText,
},
})
}
},
}
},
}