Skip to content

Commit f5d288a

Browse files
authored
refactor: move getShortLang outside markdown processor (#291)
1 parent 1281f4f commit f5d288a

File tree

11 files changed

+131
-55
lines changed

11 files changed

+131
-55
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [VSCode Extension](#vscode-extension)
3333
- [Packages](#packages)
3434
- [Install](#install)
35+
- [Notice](#notice)
3536
- [Usage](#usage)
3637
- [Parser Options](#parser-options)
3738
- [Rules](#rules)
@@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
6768
npm i -D eslint-plugin-mdx
6869
```
6970

71+
## Notice
72+
73+
If you're using multi languages, `js/jsx/ts/tsx/vue`, etc for example, you'd better to always use [`overrides`](https://eslint.org/docs/user-guide/configuring/configuration-files#how-do-overrides-work) feature of ESLint, because configs may be overridden by following configs.
74+
75+
See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.
76+
7077
## Usage
7178

7279
1. In your ESLint config file:
@@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
7885
"extends": ["plugin:mdx/recommended"],
7986
// optional, if you want to lint code blocks at the same time
8087
"settings": {
81-
"mdx/code-blocks": true
88+
"mdx/code-blocks": true,
89+
// optional, if you want to disable language mapper, set it to `false`
90+
// if you want to override the default language mapper inside, you can provide your own
91+
"mdx/language-mapper": {}
8292
}
8393
}
8494
```
@@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
90100
"extends": ["plugin:mdx/recommended"],
91101
// optional, if you want to lint code blocks at the same time
92102
"settings": {
93-
"mdx/code-blocks": true
103+
"mdx/code-blocks": true,
104+
// optional, if you want to disable language mapper, set it to `false`
105+
// if you want to override the default language mapper inside, you can provide your own
106+
"mdx/language-mapper": {}
94107
},
95108
"overrides": [
96109
{
@@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
127140
// optional, if you want to lint code blocks at the same time
128141
settings: {
129142
'mdx/code-blocks': true,
143+
// optional, if you want to disable language mapper, set it to `false`
144+
// if you want to override the default language mapper inside, you can provide your own
145+
'mdx/language-mapper': {},
130146
},
131147
overrides: [
132148
{

packages/eslint-mdx/README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [VSCode Extension](#vscode-extension)
3333
- [Packages](#packages)
3434
- [Install](#install)
35+
- [Notice](#notice)
3536
- [Usage](#usage)
3637
- [Parser Options](#parser-options)
3738
- [Rules](#rules)
@@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
6768
npm i -D eslint-plugin-mdx
6869
```
6970

71+
## Notice
72+
73+
If you're using multi languages, `js/jsx/ts/tsx/vue`, etc for example, you'd better to always use [`overrides`](https://eslint.org/docs/user-guide/configuring/configuration-files#how-do-overrides-work) feature of ESLint, because configs may be overridden by following configs.
74+
75+
See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.
76+
7077
## Usage
7178

7279
1. In your ESLint config file:
@@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
7885
"extends": ["plugin:mdx/recommended"],
7986
// optional, if you want to lint code blocks at the same time
8087
"settings": {
81-
"mdx/code-blocks": true
88+
"mdx/code-blocks": true,
89+
// optional, if you want to disable language mapper, set it to `false`
90+
// if you want to override the default language mapper inside, you can provide your own
91+
"mdx/language-mapper": {}
8292
}
8393
}
8494
```
@@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
90100
"extends": ["plugin:mdx/recommended"],
91101
// optional, if you want to lint code blocks at the same time
92102
"settings": {
93-
"mdx/code-blocks": true
103+
"mdx/code-blocks": true,
104+
// optional, if you want to disable language mapper, set it to `false`
105+
// if you want to override the default language mapper inside, you can provide your own
106+
"mdx/language-mapper": {}
94107
},
95108
"overrides": [
96109
{
@@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
127140
// optional, if you want to lint code blocks at the same time
128141
settings: {
129142
'mdx/code-blocks': true,
143+
// optional, if you want to disable language mapper, set it to `false`
144+
// if you want to override the default language mapper inside, you can provide your own
145+
'mdx/language-mapper': {},
130146
},
131147
overrides: [
132148
{

packages/eslint-plugin-mdx/README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [VSCode Extension](#vscode-extension)
3333
- [Packages](#packages)
3434
- [Install](#install)
35+
- [Notice](#notice)
3536
- [Usage](#usage)
3637
- [Parser Options](#parser-options)
3738
- [Rules](#rules)
@@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
6768
npm i -D eslint-plugin-mdx
6869
```
6970

71+
## Notice
72+
73+
If you're using multi languages, `js/jsx/ts/tsx/vue`, etc for example, you'd better to always use [`overrides`](https://eslint.org/docs/user-guide/configuring/configuration-files#how-do-overrides-work) feature of ESLint, because configs may be overridden by following configs.
74+
75+
See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.
76+
7077
## Usage
7178

7279
1. In your ESLint config file:
@@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
7885
"extends": ["plugin:mdx/recommended"],
7986
// optional, if you want to lint code blocks at the same time
8087
"settings": {
81-
"mdx/code-blocks": true
88+
"mdx/code-blocks": true,
89+
// optional, if you want to disable language mapper, set it to `false`
90+
// if you want to override the default language mapper inside, you can provide your own
91+
"mdx/language-mapper": {}
8292
}
8393
}
8494
```
@@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
90100
"extends": ["plugin:mdx/recommended"],
91101
// optional, if you want to lint code blocks at the same time
92102
"settings": {
93-
"mdx/code-blocks": true
103+
"mdx/code-blocks": true,
104+
// optional, if you want to disable language mapper, set it to `false`
105+
// if you want to override the default language mapper inside, you can provide your own
106+
"mdx/language-mapper": {}
94107
},
95108
"overrides": [
96109
{
@@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
127140
// optional, if you want to lint code blocks at the same time
128141
settings: {
129142
'mdx/code-blocks': true,
143+
// optional, if you want to disable language mapper, set it to `false`
144+
// if you want to override the default language mapper inside, you can provide your own
145+
'mdx/language-mapper': {},
130146
},
131147
overrides: [
132148
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { last } from 'eslint-mdx'
2+
3+
export const DEFAULT_LANGUAGE_MAPPER: Record<string, string> = {
4+
javascript: 'js',
5+
javascriptreact: 'jsx',
6+
typescript: 'ts',
7+
typescriptreact: 'tsx',
8+
markdown: 'md',
9+
mdown: 'md',
10+
mkdn: 'md',
11+
}
12+
13+
export function getShortLang(
14+
filename: string,
15+
languageMapper?: false | Record<string, string>,
16+
): string {
17+
const language = last(filename.split('.'))
18+
if (languageMapper === false) {
19+
return language
20+
}
21+
languageMapper = { ...DEFAULT_LANGUAGE_MAPPER, ...languageMapper }
22+
const lang = language.toLowerCase()
23+
return languageMapper[language] || languageMapper[lang] || lang
24+
}

packages/eslint-plugin-mdx/src/processors/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { markdown } from './markdown'
22
import { remark } from './remark'
33

4+
export * from './helpers'
45
export * from './options'
56
export * from './types'
67

packages/eslint-plugin-mdx/src/processors/markdown.ts

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
*/
77

88
import type { Linter } from 'eslint'
9-
import { last } from 'eslint-mdx'
109
import type { Node, Parent } from 'unist'
1110

1211
import { remarkProcessor } from '../rules'
1312

14-
import type { ESLintProcessor } from './types'
13+
import type { ESLintProcessor, ESLinterProcessorFile } from './types'
1514

1615
export interface Block extends Node {
1716
baseIndentText: string
@@ -229,36 +228,13 @@ function getBlockRangeMap(
229228
return rangeMap
230229
}
231230

232-
const LANGUAGES_MAPPER: Record<string, string> = {
233-
javascript: 'js',
234-
javascriptreact: 'jsx',
235-
typescript: 'ts',
236-
typescriptreact: 'tsx',
237-
markdown: 'md',
238-
mdown: 'md',
239-
mkdn: 'md',
240-
}
241-
242-
/**
243-
* get short language
244-
* @param lang original language
245-
* @returns short language
246-
*/
247-
function getShortLang(lang: string): string {
248-
const language = last(lang.split(/\s/u)[0].split('.')).toLowerCase()
249-
return LANGUAGES_MAPPER[language] || language
250-
}
251-
252231
/**
253232
* Extracts lintable JavaScript code blocks from Markdown text.
254233
* @param text The text of the file.
255234
* @param filename The filename of the file
256235
* @returns Source code strings to lint.
257236
*/
258-
function preprocess(
259-
text: string,
260-
filename: string,
261-
): Array<string | { text: string; filename: string }> {
237+
function preprocess(text: string, filename: string): ESLinterProcessorFile[] {
262238
const ast = remarkProcessor.parse(text)
263239
const blocks: Block[] = []
264240

@@ -299,7 +275,7 @@ function preprocess(
299275
})
300276

301277
return blocks.map((block, index) => ({
302-
filename: `${index}.${getShortLang(block.lang as string)}`,
278+
filename: `${index}.${block.lang as string}`,
303279
text: [...block.comments, block.value, ''].join('\n'),
304280
}))
305281
}
@@ -405,7 +381,7 @@ function postprocess(
405381
)
406382
}
407383

408-
export const markdown: ESLintProcessor = {
384+
export const markdown: ESLintProcessor<ESLinterProcessorFile> = {
409385
preprocess,
410386
postprocess,
411387
supportsAutofix: SUPPORTS_AUTOFIX,

packages/eslint-plugin-mdx/src/processors/options.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import type { Linter, SourceCode } from 'eslint'
66

7-
import type { ProcessorOptions } from './types'
7+
import type { ESLintMdxSettings, ProcessorOptions } from './types'
88

99
export const processorOptions = {} as ProcessorOptions
1010

@@ -35,20 +35,20 @@ ESLinter.prototype.verify = function (
3535
options?: string | Linter.LintOptions,
3636
) {
3737
// fetch settings
38-
const settings =
39-
(config &&
40-
(typeof config.extractConfig === 'function'
41-
? config.extractConfig(
42-
/* istanbul ignore next */
43-
typeof options === 'undefined' || typeof options === 'string'
44-
? options
45-
: options.filename,
46-
)
47-
: config
48-
).settings) ||
49-
{}
38+
const settings = ((config &&
39+
(typeof config.extractConfig === 'function'
40+
? config.extractConfig(
41+
/* istanbul ignore next */
42+
typeof options === 'undefined' || typeof options === 'string'
43+
? options
44+
: options.filename,
45+
)
46+
: config
47+
).settings) ||
48+
{}) as ESLintMdxSettings
5049

5150
processorOptions.lintCodeBlocks = settings['mdx/code-blocks'] === true
51+
processorOptions.languageMapper = settings['mdx/language-mapper']
5252

5353
// call original Linter#verify
5454
return verify.call(this, code, config, options as Linter.LintOptions)

packages/eslint-plugin-mdx/src/processors/remark.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Linter } from 'eslint'
22

33
import type { RemarkLintMessage } from '../rules'
44

5+
import { getShortLang } from './helpers'
56
import { markdown } from './markdown'
67
import { processorOptions } from './options'
78
import type { ESLintProcessor } from './types'
@@ -13,7 +14,16 @@ export const remark: ESLintProcessor = {
1314
return [text]
1415
}
1516

16-
return [...markdown.preprocess(text, filename), text]
17+
return [
18+
...markdown.preprocess(text, filename).map(({ text, filename }) => ({
19+
text,
20+
filename:
21+
filename.slice(0, filename.lastIndexOf('.')) +
22+
'.' +
23+
getShortLang(filename, processorOptions.languageMapper),
24+
})),
25+
text,
26+
]
1727
},
1828
postprocess(lintMessages, filename) {
1929
return markdown.postprocess(lintMessages, filename).map(lintMessage => {
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
import type { Linter } from 'eslint'
22

3+
export interface ESLinterProcessorFile {
4+
text: string
5+
filename: string
6+
}
7+
38
// https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins
4-
export interface ESLintProcessor {
9+
export interface ESLintProcessor<
10+
T extends string | ESLinterProcessorFile = string | ESLinterProcessorFile
11+
> {
512
supportsAutofix?: boolean
6-
preprocess?(
7-
text: string,
8-
filename: string,
9-
): Array<string | { text: string; filename: string }>
13+
preprocess?(text: string, filename: string): T[]
1014
postprocess?(
1115
messages: Linter.LintMessage[][],
1216
filename: string,
1317
): Linter.LintMessage[]
1418
}
1519

20+
export interface ESLintMdxSettings {
21+
'mdx/code-blocks': boolean
22+
'mdx/language-mapper'?: false | Record<string, string>
23+
}
24+
1625
export interface ProcessorOptions {
1726
lintCodeBlocks: boolean
27+
languageMapper?: false | Record<string, string>
1828
}

packages/eslint-plugin-mdx/src/rules/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const getRemarkProcessor = (searchFrom: string, isMdx: boolean) => {
5959
/* istanbul ignore if */
6060
if (
6161
(err as { code?: string }).code !== 'ENOTDIR' ||
62-
!/\d+_?\.[a-z]+$/.test(searchFrom)
62+
!/[/\\]\d+_[^/\\]*\.[\da-z]+$/i.test(searchFrom)
6363
) {
6464
throw err
6565
}

0 commit comments

Comments
 (0)