Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-markdown

Package Overview
Dependencies
Maintainers
4
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-markdown - npm Package Compare versions

Comparing version 3.0.1 to 4.0.1

91

lib/index.js

@@ -9,6 +9,37 @@ /**

const processor = require("./processor");
const pkg = require("../package.json");
module.exports = {
const rulesConfig = {
// The Markdown parser automatically trims trailing
// newlines from code blocks.
"eol-last": "off",
// In code snippets and examples, these rules are often
// counterproductive to clarity and brevity.
"no-undef": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"padded-blocks": "off",
// Adding a "use strict" directive at the top of every
// code block is tedious and distracting. The config
// opts into strict mode parsing without the directive.
strict: "off",
// The processor will not receive a Unicode Byte Order
// Mark from the Markdown parser.
"unicode-bom": "off"
};
const plugin = {
meta: {
name: pkg.name,
version: pkg.version
},
processors: {
markdown: processor
},
configs: {
recommended: {
"recommended-legacy": {
plugins: ["markdown"],

@@ -33,22 +64,3 @@ overrides: [

rules: {
// The Markdown parser automatically trims trailing
// newlines from code blocks.
"eol-last": "off",
// In code snippets and examples, these rules are often
// counterproductive to clarity and brevity.
"no-undef": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"padded-blocks": "off",
// Adding a "use strict" directive at the top of every
// code block is tedious and distracting. The config
// opts into strict mode parsing without the directive.
strict: "off",
// The processor will not receive a Unicode Byte Order
// Mark from the Markdown parser.
"unicode-bom": "off"
...rulesConfig
}

@@ -58,6 +70,35 @@ }

}
}
};
plugin.configs.recommended = [
{
plugins: {
markdown: plugin
}
},
processors: {
markdown: processor
{
files: ["**/*.md"],
processor: "markdown/markdown"
},
{
files: ["**/*.md/**"],
languageOptions: {
parserOptions: {
ecmaFeatures: {
// Adding a "use strict" directive at the top of
// every code block is tedious and distracting, so
// opt into strict mode parsing without the
// directive.
impliedStrict: true
}
}
},
rules: {
...rulesConfig
}
}
};
];
module.exports = plugin;

@@ -8,7 +8,5 @@ /**

* @typedef {import('eslint/lib/shared/types').LintMessage} Message
*
* @typedef {Object} ASTNode
* @property {string} type
* @property {string} [lang]
*
* @property {string} type The type of node.
* @property {string} [lang] The language that the node is in
* @typedef {Object} RangeMap

@@ -21,8 +19,9 @@ * @property {number} indent Number of code block indent characters trimmed from

* original Markdown.
*
* @typedef {Object} BlockBase
* @property {string} baseIndentText
* @property {string[]} comments
* @property {RangeMap[]} rangeMap
*
* @property {string} baseIndentText Leading whitespace text for the block.
* @property {string[]} comments Comments inside of the JavaScript code.
* @property {RangeMap[]} rangeMap A list of offset-based adjustments, where
* lookups are done based on the `js` key, which represents the range in the
* linted JS, and the `md` key is the offset delta that, when added to the JS
* range, returns the corresponding location in the original Markdown source.
* @typedef {ASTNode & BlockBase} Block

@@ -34,7 +33,8 @@ */

const parse = require("mdast-util-from-markdown");
const pkg = require("../package.json");
const UNSATISFIABLE_RULES = [
const UNSATISFIABLE_RULES = new Set([
"eol-last", // The Markdown parser strips trailing newlines in code fences
"unicode-bom" // Code blocks will begin in the middle of Markdown files
];
]);
const SUPPORTS_AUTOFIX = true;

@@ -382,3 +382,3 @@

function excludeUnsatisfiableRules(message) {
return message && UNSATISFIABLE_RULES.indexOf(message.ruleId) < 0;
return message && !UNSATISFIABLE_RULES.has(message.ruleId);
}

@@ -398,10 +398,14 @@

return [].concat(...messages.map((group, i) => {
return messages.flatMap((group, i) => {
const adjust = adjustBlock(blocks[i]);
return group.map(adjust).filter(excludeUnsatisfiableRules);
}));
});
}
module.exports = {
meta: {
name: `${pkg.name}/markdown`,
version: pkg.version
},
preprocess,

@@ -408,0 +412,0 @@ postprocess,

{
"name": "eslint-plugin-markdown",
"version": "3.0.1",
"version": "4.0.1",
"description": "An ESLint plugin to lint JavaScript in Markdown code fences.",

@@ -23,11 +23,10 @@ "license": "MIT",

"scripts": {
"lint": "eslint --ext js,md .",
"lint": "eslint .",
"prepare": "node ./npm-prepare.js",
"test": "npm run lint && npm run test-cov",
"test-cov": "nyc _mocha -- -c tests/{examples,lib}/**/*.js",
"generate-release": "eslint-generate-release",
"generate-alpharelease": "eslint-generate-prerelease alpha",
"generate-betarelease": "eslint-generate-prerelease beta",
"generate-rcrelease": "eslint-generate-prerelease rc",
"publish-release": "eslint-publish-release"
"release:generate:latest": "eslint-generate-release",
"release:generate:alpha": "eslint-generate-prerelease alpha",
"release:generate:beta": "eslint-generate-prerelease beta",
"release:generate:rc": "eslint-generate-prerelease rc",
"release:publish": "eslint-publish-release",
"test": "nyc _mocha -- -c tests/{examples,lib}/**/*.js --timeout 30000"
},

@@ -41,8 +40,8 @@ "main": "index.js",

"devDependencies": {
"@eslint/js": "^8.56.0",
"chai": "^4.2.0",
"eslint": "^7.32.0",
"eslint-config-eslint": "^7.0.0",
"eslint-plugin-jsdoc": "^37.0.3",
"eslint-plugin-node": "^11.1.0",
"eslint": "^8.56.0",
"eslint-config-eslint": "^9.0.0",
"eslint-release": "^3.1.2",
"globals": "^13.24.0",
"mocha": "^6.2.2",

@@ -55,7 +54,7 @@ "nyc": "^14.1.1"

"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
"eslint": ">=8"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
}

@@ -20,3 +20,3 @@ # eslint-plugin-markdown

Install the plugin alongside ESLint v6 or greater:
Install the plugin alongside ESLint v8 or greater:

@@ -29,8 +29,21 @@ ```sh

Extending the `plugin:markdown/recommended` config will enable the Markdown processor on all `.md` files:
In your `eslint.config.js` file, import `eslint-plugin-markdown` and include the recommended config to enable the Markdown processor on all `.md` files:
```js
// eslint.config.js
import markdown from "eslint-plugin-markdown";
export default [
...markdown.configs.recommended
// your other configs here
];
```
If you are still using the deprecated `.eslintrc.js` file format for ESLint, you can extend the `plugin:markdown/recommended-legacy` config to enable the Markdown processor on all `.md` files:
```js
// .eslintrc.js
module.exports = {
extends: "plugin:markdown/recommended"
extends: "plugin:markdown/recommended-legacy"
};

@@ -41,9 +54,45 @@ ```

Add the plugin to your `.eslintrc` and use the `processor` option in an `overrides` entry to enable the plugin's `markdown/markdown` processor on Markdown files.
You can manually include the Markdown processor by setting the `processor` option in your configuration file for all `.md` files.
Each fenced code block inside a Markdown document has a virtual filename appended to the Markdown file's path.
The virtual filename's extension will match the fenced code block's syntax tag, so for example, <code>```js</code> code blocks in <code>README.md</code> would match <code>README.md/*.js</code>.
[`overrides` glob patterns](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) for these virtual filenames can customize configuration for code blocks without affecting regular code.
You can use glob patterns for these virtual filenames to customize configuration for code blocks without affecting regular code.
For more information on configuring processors, refer to the [ESLint documentation](https://eslint.org/docs/user-guide/configuring#specifying-processor).
Here's an example:
```js
// eslint.config.js
import markdown from "eslint-plugin-markdown";
export default [
{
// 1. Add the plugin
plugins: {
markdown
}
},
{
// 2. Enable the Markdown processor for all .md files.
files: ["**/*.md"],
processor: "markdown/markdown"
},
{
// 3. Optionally, customize the configuration ESLint uses for ```js
// fenced code blocks inside .md files.
files: ["**/*.md/*.js"],
// ...
rules: {
// ...
}
}
// your other configs here
];
```
In the deprecated `.eslintrc.js` format:
```js
// .eslintrc.js

@@ -76,3 +125,3 @@ module.exports = {

For example, `no-undef` would flag variables that are declared outside of a code snippet because they aren't relevant to the example.
The `plugin:markdown/recommended` config disables these rules in Markdown files:
The `markdown.configs.recommended` config disables these rules in Markdown files:

@@ -84,10 +133,44 @@ - [`no-undef`](https://eslint.org/docs/rules/no-undef)

Use [`overrides` glob patterns](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) to disable more rules just for Markdown code blocks:
Use glob patterns to disable more rules just for Markdown code blocks:
```js
// / eslint.config.js
import markdown from "eslint-plugin-markdown";
export default [
{
plugins: {
markdown
}
},
{
files: ["**/*.md"],
processor: "markdown/markdown"
},
{
// 1. Target ```js code blocks in .md files.
files: ["**/*.md/*.js"],
rules: {
// 2. Disable other rules.
"no-console": "off",
"import/no-unresolved": "off"
}
}
// your other configs here
];
```
And in the deprecated `.eslintrc.js` format:
```js
// .eslintrc.js
module.exports = {
// ...
plugins: ["markdown"],
overrides: [
// ...
{
files: ["**/*.md"],
processor: "markdown/markdown"
},
{
// 1. Target ```js code blocks in .md files.

@@ -108,3 +191,3 @@ files: ["**/*.md/*.js"],

`"use strict"` directives in every code block would be annoying.
The `plugin:markdown/recommended` config enables the [`impliedStrict` parser option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) and disables the [`strict` rule](https://eslint.org/docs/rules/strict) in Markdown files.
The `markdown.configs.recommended` config enables the [`impliedStrict` parser option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) and disables the [`strict` rule](https://eslint.org/docs/rules/strict) in Markdown files.
This opts into strict mode parsing without repeated `"use strict"` directives.

@@ -115,3 +198,3 @@

Markdown code blocks are not real files, so ESLint's file-format rules do not apply.
The `plugin:markdown/recommended` config disables these rules in Markdown files:
The `markdown.configs.recommended` config disables these rules in Markdown files:

@@ -121,107 +204,9 @@ - [`eol-last`](https://eslint.org/docs/rules/eol-last): The Markdown parser trims trailing newlines from code blocks.

#### Migrating from `eslint-plugin-markdown` v1
`eslint-plugin-markdown` v1 used an older version of ESLint's processor API.
The Markdown processor automatically ran on `.md`, `.mkdn`, `.mdown`, and `.markdown` files, and it only extracted fenced code blocks marked with `js`, `javascript`, `jsx`, or `node` syntax.
Configuration specifically for fenced code blocks went inside an `overrides` entry with a `files` pattern matching the containing Markdown document's filename that applied to all fenced code blocks inside the file.
```js
// .eslintrc.js for eslint-plugin-markdown v1
module.exports = {
plugins: ["markdown"],
overrides: [
{
files: ["**/*.md"],
// In v1, configuration for fenced code blocks went inside an
// `overrides` entry with a .md pattern, for example:
parserOptions: {
ecmaFeatures: {
impliedStrict: true
}
},
rules: {
"no-console": "off"
}
}
]
};
```
[RFC3](https://github.com/eslint/rfcs/blob/master/designs/2018-processors-improvements/README.md) designed a new processor API to remove these limitations, and the new API was [implemented](https://github.com/eslint/eslint/pull/11552) as part of ESLint v6.
`eslint-plugin-markdown` v2 uses this new API.
```bash
$ npm install --save-dev eslint@latest eslint-plugin-markdown@latest
```
All of the Markdown file extensions that were previously hard-coded are now fully configurable in `.eslintrc.js`.
Use the new `processor` option to apply the `markdown/markdown` processor on any Markdown documents matching a `files` pattern.
Each fenced code block inside a Markdown document has a virtual filename appended to the Markdown file's path.
The virtual filename's extension will match the fenced code block's syntax tag, so for example, <code>```js</code> code blocks in <code>README.md</code> would match <code>README.md/*.js</code>.
```js
// eslintrc.js for eslint-plugin-markdown v2
module.exports = {
plugins: ["markdown"],
overrides: [
{
// In v2, explicitly apply eslint-plugin-markdown's `markdown`
// processor on any Markdown files you want to lint.
files: ["**/*.md"],
processor: "markdown/markdown"
},
{
// In v2, configuration for fenced code blocks is separate from the
// containing Markdown file. Each code block has a virtual filename
// appended to the Markdown file's path.
files: ["**/*.md/*.js"],
// Configuration for fenced code blocks goes with the override for
// the code block's virtual filename, for example:
parserOptions: {
ecmaFeatures: {
impliedStrict: true
}
},
rules: {
"no-console": "off"
}
}
]
};
```
If you need to precisely mimic the behavior of v1 with the hard-coded Markdown extensions and fenced code block syntaxes, you can use those as glob patterns in `overrides[].files`:
```js
// eslintrc.js for v2 mimicking v1 behavior
module.exports = {
plugins: ["markdown"],
overrides: [
{
files: ["**/*.{md,mkdn,mdown,markdown}"],
processor: "markdown/markdown"
},
{
files: ["**/*.{md,mkdn,mdown,markdown}/*.{js,javascript,jsx,node}"]
// ...
}
]
};
```
### Running
#### ESLint v7
If you are using an `eslint.config.js` file, then you can run ESLint as usual and it will pick up file patterns in your config file. The `--ext` option is not available when using flat config.
You can run ESLint as usual and do not need to use the `--ext` option.
ESLint v7 [automatically lints file extensions specified in `overrides[].files` patterns in config files](https://github.com/eslint/rfcs/blob/0253e3a95511c65d622eaa387eb73f824249b467/designs/2019-additional-lint-targets/README.md).
If you are using an `.eslintrc.*` file, then you can run ESLint as usual and it will pick up file extensions specified in `overrides[].files` patterns in config files.
#### ESLint v6
Use the [`--ext` option](https://eslint.org/docs/user-guide/command-line-interface#ext) to include `.js` and `.md` extensions in ESLint's file search:
```sh
eslint --ext js,md .
```
### Autofixing

@@ -261,4 +246,4 @@

```jsx
// This can be linted too if you add `.jsx` files to `overrides` in ESLint v7
// or pass `--ext jsx` in ESLint v6.
// This can be linted too if you add `.jsx` files to file patterns in the `eslint.config.js`.
// Or `overrides[].files` in `eslintrc.*`.
var div = <div className="jsx"></div>;

@@ -276,11 +261,4 @@ ```

Unless a fenced code block's syntax appears as a file extension in `overrides[].files` in ESLint v7, it will be ignored.
If using ESLint v6, you must also include the extension with the `--ext` option.
Unless a fenced code block's syntax appears as a file extension in file patterns in your config file, it will be ignored.
````markdown
```python
print("This doesn't get linted either.")
```
````
## Configuration Comments

@@ -292,6 +270,6 @@

This example enables the `browser` environment, disables the `no-alert` rule, and configures the `quotes` rule to prefer single quotes:
This example enables the `alert` global variable, disables the `no-alert` rule, and configures the `quotes` rule to prefer single quotes:
````markdown
<!-- eslint-env browser -->
<!-- global alert -->
<!-- eslint-disable no-alert -->

@@ -308,5 +286,5 @@ <!-- eslint quotes: ["error", "single"] -->

````markdown
Assuming `no-alert` is enabled in `.eslintrc`, the first code block will have no error from `no-alert`:
Assuming `no-alert` is enabled in `eslint.config.js`, the first code block will have no error from `no-alert`:
<!-- eslint-env browser -->
<!-- global alert -->
<!-- eslint-disable no-alert -->

@@ -320,3 +298,3 @@

<!-- eslint-env browser -->
<!-- global alert -->

@@ -323,0 +301,0 @@ ```js

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc