Skip to content

Commit

Permalink
refactor: move getShortLang outside markdown processor (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin authored Mar 19, 2021
1 parent 1281f4f commit f5d288a
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 55 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [VSCode Extension](#vscode-extension)
- [Packages](#packages)
- [Install](#install)
- [Notice](#notice)
- [Usage](#usage)
- [Parser Options](#parser-options)
- [Rules](#rules)
Expand Down Expand Up @@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
npm i -D eslint-plugin-mdx
```

## Notice

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.

See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.

## Usage

1. In your ESLint config file:
Expand All @@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
}
}
```
Expand All @@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
},
"overrides": [
{
Expand Down Expand Up @@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
// optional, if you want to lint code blocks at the same time
settings: {
'mdx/code-blocks': true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
'mdx/language-mapper': {},
},
overrides: [
{
Expand Down
20 changes: 18 additions & 2 deletions packages/eslint-mdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [VSCode Extension](#vscode-extension)
- [Packages](#packages)
- [Install](#install)
- [Notice](#notice)
- [Usage](#usage)
- [Parser Options](#parser-options)
- [Rules](#rules)
Expand Down Expand Up @@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
npm i -D eslint-plugin-mdx
```

## Notice

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.

See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.

## Usage

1. In your ESLint config file:
Expand All @@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
}
}
```
Expand All @@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
},
"overrides": [
{
Expand Down Expand Up @@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
// optional, if you want to lint code blocks at the same time
settings: {
'mdx/code-blocks': true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
'mdx/language-mapper': {},
},
overrides: [
{
Expand Down
20 changes: 18 additions & 2 deletions packages/eslint-plugin-mdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [VSCode Extension](#vscode-extension)
- [Packages](#packages)
- [Install](#install)
- [Notice](#notice)
- [Usage](#usage)
- [Parser Options](#parser-options)
- [Rules](#rules)
Expand Down Expand Up @@ -67,6 +68,12 @@ yarn add -D eslint-plugin-mdx
npm i -D eslint-plugin-mdx
```

## Notice

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.

See [#251](https://github.com/mdx-js/eslint-mdx/issues/251#issuecomment-736139224) for more details.

## Usage

1. In your ESLint config file:
Expand All @@ -78,7 +85,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
}
}
```
Expand All @@ -90,7 +100,10 @@ npm i -D eslint-plugin-mdx
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
},
"overrides": [
{
Expand Down Expand Up @@ -127,6 +140,9 @@ npm i -D eslint-plugin-mdx
// optional, if you want to lint code blocks at the same time
settings: {
'mdx/code-blocks': true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
'mdx/language-mapper': {},
},
overrides: [
{
Expand Down
24 changes: 24 additions & 0 deletions packages/eslint-plugin-mdx/src/processors/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { last } from 'eslint-mdx'

export const DEFAULT_LANGUAGE_MAPPER: Record<string, string> = {
javascript: 'js',
javascriptreact: 'jsx',
typescript: 'ts',
typescriptreact: 'tsx',
markdown: 'md',
mdown: 'md',
mkdn: 'md',
}

export function getShortLang(
filename: string,
languageMapper?: false | Record<string, string>,
): string {
const language = last(filename.split('.'))
if (languageMapper === false) {
return language
}
languageMapper = { ...DEFAULT_LANGUAGE_MAPPER, ...languageMapper }
const lang = language.toLowerCase()
return languageMapper[language] || languageMapper[lang] || lang
}
1 change: 1 addition & 0 deletions packages/eslint-plugin-mdx/src/processors/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { markdown } from './markdown'
import { remark } from './remark'

export * from './helpers'
export * from './options'
export * from './types'

Expand Down
32 changes: 4 additions & 28 deletions packages/eslint-plugin-mdx/src/processors/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
*/

import type { Linter } from 'eslint'
import { last } from 'eslint-mdx'
import type { Node, Parent } from 'unist'

import { remarkProcessor } from '../rules'

import type { ESLintProcessor } from './types'
import type { ESLintProcessor, ESLinterProcessorFile } from './types'

export interface Block extends Node {
baseIndentText: string
Expand Down Expand Up @@ -229,36 +228,13 @@ function getBlockRangeMap(
return rangeMap
}

const LANGUAGES_MAPPER: Record<string, string> = {
javascript: 'js',
javascriptreact: 'jsx',
typescript: 'ts',
typescriptreact: 'tsx',
markdown: 'md',
mdown: 'md',
mkdn: 'md',
}

/**
* get short language
* @param lang original language
* @returns short language
*/
function getShortLang(lang: string): string {
const language = last(lang.split(/\s/u)[0].split('.')).toLowerCase()
return LANGUAGES_MAPPER[language] || language
}

/**
* Extracts lintable JavaScript code blocks from Markdown text.
* @param text The text of the file.
* @param filename The filename of the file
* @returns Source code strings to lint.
*/
function preprocess(
text: string,
filename: string,
): Array<string | { text: string; filename: string }> {
function preprocess(text: string, filename: string): ESLinterProcessorFile[] {
const ast = remarkProcessor.parse(text)
const blocks: Block[] = []

Expand Down Expand Up @@ -299,7 +275,7 @@ function preprocess(
})

return blocks.map((block, index) => ({
filename: `${index}.${getShortLang(block.lang as string)}`,
filename: `${index}.${block.lang as string}`,
text: [...block.comments, block.value, ''].join('\n'),
}))
}
Expand Down Expand Up @@ -405,7 +381,7 @@ function postprocess(
)
}

export const markdown: ESLintProcessor = {
export const markdown: ESLintProcessor<ESLinterProcessorFile> = {
preprocess,
postprocess,
supportsAutofix: SUPPORTS_AUTOFIX,
Expand Down
26 changes: 13 additions & 13 deletions packages/eslint-plugin-mdx/src/processors/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import type { Linter, SourceCode } from 'eslint'

import type { ProcessorOptions } from './types'
import type { ESLintMdxSettings, ProcessorOptions } from './types'

export const processorOptions = {} as ProcessorOptions

Expand Down Expand Up @@ -35,20 +35,20 @@ ESLinter.prototype.verify = function (
options?: string | Linter.LintOptions,
) {
// fetch settings
const settings =
(config &&
(typeof config.extractConfig === 'function'
? config.extractConfig(
/* istanbul ignore next */
typeof options === 'undefined' || typeof options === 'string'
? options
: options.filename,
)
: config
).settings) ||
{}
const settings = ((config &&
(typeof config.extractConfig === 'function'
? config.extractConfig(
/* istanbul ignore next */
typeof options === 'undefined' || typeof options === 'string'
? options
: options.filename,
)
: config
).settings) ||
{}) as ESLintMdxSettings

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

// call original Linter#verify
return verify.call(this, code, config, options as Linter.LintOptions)
Expand Down
12 changes: 11 additions & 1 deletion packages/eslint-plugin-mdx/src/processors/remark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Linter } from 'eslint'

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

import { getShortLang } from './helpers'
import { markdown } from './markdown'
import { processorOptions } from './options'
import type { ESLintProcessor } from './types'
Expand All @@ -13,7 +14,16 @@ export const remark: ESLintProcessor = {
return [text]
}

return [...markdown.preprocess(text, filename), text]
return [
...markdown.preprocess(text, filename).map(({ text, filename }) => ({
text,
filename:
filename.slice(0, filename.lastIndexOf('.')) +
'.' +
getShortLang(filename, processorOptions.languageMapper),
})),
text,
]
},
postprocess(lintMessages, filename) {
return markdown.postprocess(lintMessages, filename).map(lintMessage => {
Expand Down
20 changes: 15 additions & 5 deletions packages/eslint-plugin-mdx/src/processors/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import type { Linter } from 'eslint'

export interface ESLinterProcessorFile {
text: string
filename: string
}

// https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins
export interface ESLintProcessor {
export interface ESLintProcessor<
T extends string | ESLinterProcessorFile = string | ESLinterProcessorFile
> {
supportsAutofix?: boolean
preprocess?(
text: string,
filename: string,
): Array<string | { text: string; filename: string }>
preprocess?(text: string, filename: string): T[]
postprocess?(
messages: Linter.LintMessage[][],
filename: string,
): Linter.LintMessage[]
}

export interface ESLintMdxSettings {
'mdx/code-blocks': boolean
'mdx/language-mapper'?: false | Record<string, string>
}

export interface ProcessorOptions {
lintCodeBlocks: boolean
languageMapper?: false | Record<string, string>
}
2 changes: 1 addition & 1 deletion packages/eslint-plugin-mdx/src/rules/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const getRemarkProcessor = (searchFrom: string, isMdx: boolean) => {
/* istanbul ignore if */
if (
(err as { code?: string }).code !== 'ENOTDIR' ||
!/\d+_?\.[a-z]+$/.test(searchFrom)
!/[/\\]\d+_[^/\\]*\.[\da-z]+$/i.test(searchFrom)
) {
throw err
}
Expand Down
Loading

0 comments on commit f5d288a

Please sign in to comment.