From 2925af7e59af9493d4cb9f219d7f52a35cc1e7c0 Mon Sep 17 00:00:00 2001 From: JounQin Date: Thu, 18 Mar 2021 23:32:50 +0800 Subject: [PATCH] refactor: move getShortLang outside markdown processor https://github.com/eslint/eslint-plugin-markdown/pull/178\#issuecomment-801821377 --- README.md | 20 ++++++++++-- packages/eslint-mdx/README.md | 20 ++++++++++-- packages/eslint-plugin-mdx/README.md | 20 ++++++++++-- .../src/processors/helpers.ts | 24 ++++++++++++++ .../eslint-plugin-mdx/src/processors/index.ts | 1 + .../src/processors/markdown.ts | 32 +++---------------- .../src/processors/options.ts | 3 ++ .../src/processors/remark.ts | 12 ++++++- .../eslint-plugin-mdx/src/processors/types.ts | 15 ++++++--- test/helpers.test.ts | 9 +++++- 10 files changed, 115 insertions(+), 41 deletions(-) create mode 100644 packages/eslint-plugin-mdx/src/processors/helpers.ts diff --git a/README.md b/README.md index 5125d7bd..6d2ed39d 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ - [VSCode Extension](#vscode-extension) - [Packages](#packages) - [Install](#install) +- [Notice](#notice) - [Usage](#usage) - [Parser Options](#parser-options) - [Rules](#rules) @@ -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: @@ -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": {} } } ``` @@ -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": [ { @@ -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: [ { diff --git a/packages/eslint-mdx/README.md b/packages/eslint-mdx/README.md index 5125d7bd..6d2ed39d 100644 --- a/packages/eslint-mdx/README.md +++ b/packages/eslint-mdx/README.md @@ -32,6 +32,7 @@ - [VSCode Extension](#vscode-extension) - [Packages](#packages) - [Install](#install) +- [Notice](#notice) - [Usage](#usage) - [Parser Options](#parser-options) - [Rules](#rules) @@ -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: @@ -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": {} } } ``` @@ -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": [ { @@ -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: [ { diff --git a/packages/eslint-plugin-mdx/README.md b/packages/eslint-plugin-mdx/README.md index 5125d7bd..6d2ed39d 100644 --- a/packages/eslint-plugin-mdx/README.md +++ b/packages/eslint-plugin-mdx/README.md @@ -32,6 +32,7 @@ - [VSCode Extension](#vscode-extension) - [Packages](#packages) - [Install](#install) +- [Notice](#notice) - [Usage](#usage) - [Parser Options](#parser-options) - [Rules](#rules) @@ -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: @@ -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": {} } } ``` @@ -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": [ { @@ -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: [ { diff --git a/packages/eslint-plugin-mdx/src/processors/helpers.ts b/packages/eslint-plugin-mdx/src/processors/helpers.ts new file mode 100644 index 00000000..a89b0eec --- /dev/null +++ b/packages/eslint-plugin-mdx/src/processors/helpers.ts @@ -0,0 +1,24 @@ +import { last } from 'eslint-mdx' + +export const DEFAULT_LANGUAGE_MAPPER: Record = { + javascript: 'js', + javascriptreact: 'jsx', + typescript: 'ts', + typescriptreact: 'tsx', + markdown: 'md', + mdown: 'md', + mkdn: 'md', +} + +export function getShortLang( + filename: string, + languageMapper?: false | Record, +): 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 +} diff --git a/packages/eslint-plugin-mdx/src/processors/index.ts b/packages/eslint-plugin-mdx/src/processors/index.ts index d28ee584..c642dc64 100644 --- a/packages/eslint-plugin-mdx/src/processors/index.ts +++ b/packages/eslint-plugin-mdx/src/processors/index.ts @@ -1,6 +1,7 @@ import { markdown } from './markdown' import { remark } from './remark' +export * from './helpers' export * from './options' export * from './types' diff --git a/packages/eslint-plugin-mdx/src/processors/markdown.ts b/packages/eslint-plugin-mdx/src/processors/markdown.ts index bab45d44..2cb6977e 100644 --- a/packages/eslint-plugin-mdx/src/processors/markdown.ts +++ b/packages/eslint-plugin-mdx/src/processors/markdown.ts @@ -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 @@ -229,36 +228,13 @@ function getBlockRangeMap( return rangeMap } -const LANGUAGES_MAPPER: Record = { - 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 { +function preprocess(text: string, filename: string): ESLinterProcessorFile[] { const ast = remarkProcessor.parse(text) const blocks: Block[] = [] @@ -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'), })) } @@ -405,7 +381,7 @@ function postprocess( ) } -export const markdown: ESLintProcessor = { +export const markdown: ESLintProcessor = { preprocess, postprocess, supportsAutofix: SUPPORTS_AUTOFIX, diff --git a/packages/eslint-plugin-mdx/src/processors/options.ts b/packages/eslint-plugin-mdx/src/processors/options.ts index 9607a38f..2494859e 100644 --- a/packages/eslint-plugin-mdx/src/processors/options.ts +++ b/packages/eslint-plugin-mdx/src/processors/options.ts @@ -49,6 +49,9 @@ ESLinter.prototype.verify = function ( {} processorOptions.lintCodeBlocks = settings['mdx/code-blocks'] === true + processorOptions.languageMapper = settings[ + 'mdx/language-mapper' + ] as ProcessorOptions['languageMapper'] // call original Linter#verify return verify.call(this, code, config, options as Linter.LintOptions) diff --git a/packages/eslint-plugin-mdx/src/processors/remark.ts b/packages/eslint-plugin-mdx/src/processors/remark.ts index 8d38649b..cb1ac783 100644 --- a/packages/eslint-plugin-mdx/src/processors/remark.ts +++ b/packages/eslint-plugin-mdx/src/processors/remark.ts @@ -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' @@ -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 => { diff --git a/packages/eslint-plugin-mdx/src/processors/types.ts b/packages/eslint-plugin-mdx/src/processors/types.ts index 6541618d..666df344 100644 --- a/packages/eslint-plugin-mdx/src/processors/types.ts +++ b/packages/eslint-plugin-mdx/src/processors/types.ts @@ -1,12 +1,16 @@ 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 + preprocess?(text: string, filename: string): T[] postprocess?( messages: Linter.LintMessage[][], filename: string, @@ -15,4 +19,5 @@ export interface ESLintProcessor { export interface ProcessorOptions { lintCodeBlocks: boolean + languageMapper?: false | Record } diff --git a/test/helpers.test.ts b/test/helpers.test.ts index ff62d354..db9fc580 100644 --- a/test/helpers.test.ts +++ b/test/helpers.test.ts @@ -1,7 +1,7 @@ import path from 'path' import { arrayify } from 'eslint-mdx' -import { getGlobals, requirePkg } from 'eslint-plugin-mdx' +import { getGlobals, getShortLang, requirePkg } from 'eslint-plugin-mdx' describe('Helpers', () => { it('should arrayify items correctly', () => { @@ -11,6 +11,13 @@ describe('Helpers', () => { expect(arrayify([1, 2], [1, 2])).toEqual([1, 2, 1, 2]) }) + it('should short lang for filename correctly', () => { + expect(getShortLang('1.Markdown')).toBe('md') + expect(getShortLang('2.Markdown', false)).toBe('Markdown') + expect(getShortLang('3.Markdown', { Markdown: 'mkdn' })).toBe('mkdn') + expect(getShortLang('4.Markdown', { markdown: 'mkdn' })).toBe('mkdn') + }) + it('should resolve globals correctly', () => { expect(getGlobals({})).toEqual({}) expect(getGlobals(['a', 'b'])).toEqual({