Skip to content

Commit

Permalink
feat: add support of linting plain markdown files
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed Aug 22, 2019
1 parent 43e73c7 commit 9979c79
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 54 deletions.
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ module.exports = {
extends: ['@1stg'],
overrides: [
...overrides,
{
files: '*.md',
extends: ['plugin:mdx/recommended'],
rules: {
'prettier/prettier': 0, // FIXME: should be supported
},
},
{
files: '*.ts',
rules: {
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org)
[![codechecks.io](https://raw.githubusercontent.com/codechecks/docs/master/images/badges/badge-default.svg?sanitize=true)](https://codechecks.io)

> [ESLint] Parser/Plugin for [MDX], helps you lint all ES syntaxes excluding `code` block of course.
> [ESLint][] Parser/Plugin for [MDX][], helps you lint all ES syntaxes excluding `code` block of course.
> Work perfectly with `eslint-plugin-import`, `eslint-plugin-prettier` or any other eslint plugins.
> And also can be integrated with [remark] plugins to lint non ES syntaxes.
> And also can be integrated with [remark][] plugins to lint non ES syntaxes.
## TOC <!-- omit in toc -->

Expand All @@ -45,11 +45,11 @@

[![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/JounQin.vscode-mdx)](https://marketplace.visualstudio.com/items?itemName=JounQin.vscode-mdx)

[VSCode MDX]\: Integrates with [VSCode ESLint], syntaxes highlighting and error reporting.
[VSCode MDX][]\: Integrates with [VSCode ESLint][], syntaxes highlighting and error reporting.

## Packages

This repository is a monorepo managed by [Lerna] what means we actually publish several packages to npm from same codebase, including:
This repository is a monorepo managed by [Lerna][] what means we actually publish several packages to npm from same codebase, including:

| Package | Description | Version | Peer Dependencies | Dependencies |
| -------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down Expand Up @@ -124,6 +124,8 @@ npm i -D eslint-plugin-mdx

2. `extensions` (`string | string[]`): `eslint-mdx` will only resolve `.mdx` files by default, files with other extensions will be resolved by the `parser` option. If you want to resolve other extensions as like `.mdx`, you can use this option.

3. `markdownExtensions` (`string | string[]`): `eslint-mdx` will only treat `.md` files as plain markdown by default, and will lint them via remark plugins. If you want to resolve other extensions as like `.md`, you can use this option.

## Rules

### mdx/no-jsx-html-comments
Expand All @@ -132,25 +134,25 @@ _Fixable_: HTML style comments in jsx block is invalid, this rule will help you

### mdx/no-unescaped-entities

Inline JSX like `Inline <Component />` is supported by [MDX], but rule `react/no-unescaped-entities` from [eslint-plugin-react] is incompatible with it, `mdx/no-unescaped-entities` is the replacement.
Inline JSX like `Inline <Component />` is supported by [MDX][], but rule `react/no-unescaped-entities` from [eslint-plugin-react][] is incompatible with it, `mdx/no-unescaped-entities` is the replacement.

### mdx/no-unused-expressions

[MDX] can render `jsx` block automatically without exporting them, but [ESLint] will report `no-unused-expressions` issue which could be unexpected, this rule is a replacement of it, so make sure that you've turned off the original `no-unused-expressions` rule.
[MDX][] can render `jsx` block automatically without exporting them, but [ESLint][] will report `no-unused-expressions` issue which could be unexpected, this rule is a replacement of it, so make sure that you've turned off the original `no-unused-expressions` rule.

### mdx/remark

_possible fixable depends on your remark plugins_:

Integration with [remark] plugins without [remark-lint], it will read [remark's configuration](https://github.com/remarkjs/remark/tree/master/packages/remark-cli#remark-cli) automatically via [cosmiconfig]. But `.remarkignore` will not be respected, you should use `.eslintignore` instead.
Integration with [remark][] plugins without [remark-lint][], it will read [remark's configuration](https://github.com/remarkjs/remark/tree/master/packages/remark-cli#remark-cli) automatically via [cosmiconfig][]. But `.remarkignore` will not be respected, you should use `.eslintignore` instead.

## Changelog

Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.md).

## License

[MIT] © [JounQin]@[1stG.me]
[MIT][] © [JounQin][]@[1stG.me][]

[1stg.me]: https://www.1stg.me
[cosmiconfig]: https://github.com/davidtheclark/cosmiconfig
Expand All @@ -160,7 +162,6 @@ Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.m
[lerna]: https://github.com/lerna/lerna
[mdx]: https://github.com/mdx-js/mdx
[mit]: http://opensource.org/licenses/MIT
[markdownlint]: https://github.com/markdownlint/markdownlint
[remark]: https://github.com/remarkjs/remark
[remark-lint]: https://github.com/remarkjs/remark-lint
[vscode eslint]: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
Expand Down
30 changes: 24 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"scripts": {
"build": "tsc -b",
"test": "ts-node -T node_modules/.bin/jest",
"lint": "EFF_NO_LINK_RULES=true eslint . --ext js,mdx,ts,tsx -f friendly",
"lint": "EFF_NO_LINK_RULES=true eslint . --ext js,md,mdx,ts,tsx -f friendly",
"type-coverage": "type-coverage --cache --ignore-catch --detail --ignore-files *.d.ts --strict"
},
"devDependencies": {
Expand Down Expand Up @@ -58,7 +58,9 @@
]
},
"eslintIgnore": [
"**/fixtures/**/*.md",
"**/fixtures/**/*.mdx",
"CHANGELOG.md",
"coverage",
"lib",
"node_modules"
Expand All @@ -80,13 +82,29 @@
},
"prettier": "@1stg/prettier-config",
"remarkConfig": {
"settings": {
"emphasis": "*",
"strong": "*"
},
"plugins": [
"preset-lint-recommended",
"preset-lint-markdown-style-guide"
"preset-lint-markdown-style-guide",
[
"lint-list-item-spacing",
false
],
[
"lint-list-item-indent",
false
],
[
"lint-ordered-list-marker-value",
false
],
[
"lint-emphasis-marker",
"_"
],
[
"lint-maximum-line-length",
false
]
]
},
"renovate": {
Expand Down
19 changes: 10 additions & 9 deletions packages/eslint-mdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org)
[![codechecks.io](https://raw.githubusercontent.com/codechecks/docs/master/images/badges/badge-default.svg?sanitize=true)](https://codechecks.io)

> [ESLint] Parser/Plugin for [MDX], helps you lint all ES syntaxes excluding `code` block of course.
> [ESLint][] Parser/Plugin for [MDX][], helps you lint all ES syntaxes excluding `code` block of course.
> Work perfectly with `eslint-plugin-import`, `eslint-plugin-prettier` or any other eslint plugins.
> And also can be integrated with [remark] plugins to lint non ES syntaxes.
> And also can be integrated with [remark][] plugins to lint non ES syntaxes.
## TOC <!-- omit in toc -->

Expand All @@ -45,11 +45,11 @@

[![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/JounQin.vscode-mdx)](https://marketplace.visualstudio.com/items?itemName=JounQin.vscode-mdx)

[VSCode MDX]\: Integrates with [VSCode ESLint], syntaxes highlighting and error reporting.
[VSCode MDX][]\: Integrates with [VSCode ESLint][], syntaxes highlighting and error reporting.

## Packages

This repository is a monorepo managed by [Lerna] what means we actually publish several packages to npm from same codebase, including:
This repository is a monorepo managed by [Lerna][] what means we actually publish several packages to npm from same codebase, including:

| Package | Description | Version | Peer Dependencies | Dependencies |
| -------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down Expand Up @@ -124,6 +124,8 @@ npm i -D eslint-plugin-mdx

2. `extensions` (`string | string[]`): `eslint-mdx` will only resolve `.mdx` files by default, files with other extensions will be resolved by the `parser` option. If you want to resolve other extensions as like `.mdx`, you can use this option.

3. `markdownExtensions` (`string | string[]`): `eslint-mdx` will only treat `.md` files as plain markdown by default, and will lint them via remark plugins. If you want to resolve other extensions as like `.md`, you can use this option.

## Rules

### mdx/no-jsx-html-comments
Expand All @@ -132,25 +134,25 @@ _Fixable_: HTML style comments in jsx block is invalid, this rule will help you

### mdx/no-unescaped-entities

Inline JSX like `Inline <Component />` is supported by [MDX], but rule `react/no-unescaped-entities` from [eslint-plugin-react] is incompatible with it, `mdx/no-unescaped-entities` is the replacement.
Inline JSX like `Inline <Component />` is supported by [MDX][], but rule `react/no-unescaped-entities` from [eslint-plugin-react][] is incompatible with it, `mdx/no-unescaped-entities` is the replacement.

### mdx/no-unused-expressions

[MDX] can render `jsx` block automatically without exporting them, but [ESLint] will report `no-unused-expressions` issue which could be unexpected, this rule is a replacement of it, so make sure that you've turned off the original `no-unused-expressions` rule.
[MDX][] can render `jsx` block automatically without exporting them, but [ESLint][] will report `no-unused-expressions` issue which could be unexpected, this rule is a replacement of it, so make sure that you've turned off the original `no-unused-expressions` rule.

### mdx/remark

_possible fixable depends on your remark plugins_:

Integration with [remark] plugins without [remark-lint], it will read [remark's configuration](https://github.com/remarkjs/remark/tree/master/packages/remark-cli#remark-cli) automatically via [cosmiconfig]. But `.remarkignore` will not be respected, you should use `.eslintignore` instead.
Integration with [remark][] plugins without [remark-lint][], it will read [remark's configuration](https://github.com/remarkjs/remark/tree/master/packages/remark-cli#remark-cli) automatically via [cosmiconfig][]. But `.remarkignore` will not be respected, you should use `.eslintignore` instead.

## Changelog

Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.md).

## License

[MIT] © [JounQin]@[1stG.me]
[MIT][] © [JounQin][]@[1stG.me][]

[1stg.me]: https://www.1stg.me
[cosmiconfig]: https://github.com/davidtheclark/cosmiconfig
Expand All @@ -160,7 +162,6 @@ Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.m
[lerna]: https://github.com/lerna/lerna
[mdx]: https://github.com/mdx-js/mdx
[mit]: http://opensource.org/licenses/MIT
[markdownlint]: https://github.com/markdownlint/markdownlint
[remark]: https://github.com/remarkjs/remark
[remark-lint]: https://github.com/remarkjs/remark-lint
[vscode eslint]: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
Expand Down
36 changes: 21 additions & 15 deletions packages/eslint-mdx/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const ES_NODE_TYPES: readonly string[] = ['export', 'import', 'jsx']
export const LOC_ERROR_PROPERTIES = ['column', 'index', 'lineNumber'] as const

export const DEFAULT_EXTENSIONS: readonly string[] = ['.mdx']
export const MARKDOWN_EXTENSIONS: readonly string[] = ['.md']

export const DEFAULT_PARSER_OPTIONS: ParserOptions = {
comment: true,
Expand Down Expand Up @@ -140,11 +141,14 @@ export class Parser {
}

parseForESLint(code: string, options: ParserOptions) {
if (
!DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(
path.extname(options.filePath),
)
) {
const extname = path.extname(options.filePath)
const isMdx = DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(
extname,
)
const isMarkdown = MARKDOWN_EXTENSIONS.concat(
options.markdownExtensions || [],
).includes(extname)
if (!isMdx && !isMarkdown) {
return this._eslintParse(code, options)
}

Expand All @@ -163,17 +167,19 @@ export class Parser {
JSXElementsWithHTMLComments: [],
}

traverse(root, {
enter: (node, parent) => {
if (!ES_NODE_TYPES.includes(node.type)) {
return
}
if (isMdx) {
traverse(root, {
enter: (node, parent) => {
if (!ES_NODE_TYPES.includes(node.type)) {
return
}

let normalized = this.normalizeJsxNode(node, parent)
normalized = Array.isArray(normalized) ? normalized : [normalized]
normalized.forEach(node => this._nodeToAst(node, options))
},
})
let normalized = this.normalizeJsxNode(node, parent)
normalized = Array.isArray(normalized) ? normalized : [normalized]
normalized.forEach(node => this._nodeToAst(node, options))
},
})
}

return {
ast: this._ast,
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-mdx/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface LocationError {

export interface ParserOptions extends Linter.ParserOptions {
extensions?: string | string[]
markdownExtensions?: string | string[]
filePath?: string
parser?: string | ParserConfig | ParserFn
}
Expand Down
Loading

0 comments on commit 9979c79

Please sign in to comment.