Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add improved docs #276

Merged
merged 1 commit into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .remarkrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import listOfRules from './script/plugin/list-of-rules.js'
const plugins = [
remarkPresetLintRecommended,
remarkPresetLintConsistent,
[remarkToc, {tight: true, maxDepth: 2, heading: 'contents'}],
[remarkToc, {tight: true, maxDepth: 3, heading: 'contents'}],
remarkCommentConfig,
[remarkGfm, {tablePipeAlign: false}],
remarkGithub,
Expand Down
6 changes: 4 additions & 2 deletions doc/comparison-to-markdownlint.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# [markdownlint](https://github.com/mivok/markdownlint)
# [markdownlint](https://github.com/markdownlint/markdownlint)

> ⚠️ **Important**: this comparison hasn’t been updated in years.

This table documents the similarity and difference between
[**markdownlint**](https://github.com/mivok/markdownlint/blob/HEAD/docs/RULES.md)
[**markdownlint**](https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md)
rules and **remark-lint**’s rules.

| markdownlint | remark | note |
Expand Down
104 changes: 65 additions & 39 deletions doc/create-a-custom-rule.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Create a custom `remark-lint` rule

This guide is part of [a step-by-step tutorial](https://dev.to/floroz/how-to-create-a-custom-lint-rule-for-markdown-and-mdx-using-remark-and-eslint-2jim), and will help you getting started to create your first linting plugin for `remark`.
This guide is part of [a step-by-step tutorial][tutorial], and will help you
getting started to create your first linting plugin for `remark`.

## Contents

Expand Down Expand Up @@ -31,8 +32,10 @@ Now we can start installing our dependencies:
npm install remark-lint remark-cli
```

* [`remark-lint`](https://github.com/remarkjs/remark-lint): Core lint plugin
* [`remark-cli`](https://github.com/remarkjs/remark/tree/main/packages/remark-cli): Command-line interface
* [`remark-lint`][remark-lint]
— core lint plugin
* [`remark-cli`][remark-cli]
— command line interface

We will also use some utilities:

Expand All @@ -42,13 +45,12 @@ npm install unified-lint-rule unist-util-generated unist-util-visit

These will help us creating and managing our custom rules.

[Back to Top](#contents)

## Set up remark

With everything installed, we can now create a `.remarkrc.js` that will contain the plugins we’ll use.
With everything installed, we can now create a `.remarkrc.js` that will contain
the plugins we’ll use.

For more info on configuration, see [Configuring `remark-lint`](https://github.com/remarkjs/remark-lint#configuring-remark-lint).
For more info on configuration, see [Examples in `remark-lint`][examples].

```sh
touch .remarkrc.js
Expand All @@ -61,7 +63,8 @@ module.exports = {
}
```

Then, in our `package.json`, add the following script to process all the markdown files in our project:
Then, in our `package.json`, add the following script to process all the
markdown files in our project:

```json
"scripts": {
Expand All @@ -87,34 +90,35 @@ Some funny images of our favorite pets
![a lovely dog](lovely-dog.png)
```

At this point, we have a working `remark` configuration and a markdown file in the project.
At this point, we have a working `remark` configuration and a markdown file in
the project.

If we run `npm run lint` we should expect to see in our terminal:

```sh
doc.md: no issues found
```

All good, the file has been processed, and because we haven’t specified any plugins nor lint rules, no issues are found.

[Back to Top](#contents)
All good, the file has been processed, and because we haven’t specified any
plugins nor lint rules, no issues are found.

## The `no-invalid-gif` rule

Let’s imagine we want to write a rule that checks whether a `.gif` file is used as an image.
Given the content of our `doc.md` file declared above, we would expect an *error* or *warning* pointing to:
Let’s imagine we want to write a rule that checks whether a `.gif` file is used
as an image.
Given the content of our `doc.md` file declared above, we would expect an
*error* or *warning* pointing to:

```markdown
![a funny cat](funny-cat.gif)
```

Because the file extension `.gif` in the image violates our rule.

[Back to Top](#contents)

## Create the custom rule

Let’s create a new folder `rules` under the root directory, where we will place all of our custom rules, and create a new file in it named `no-gif-allowed.js`.
Let’s create a new folder `rules` under the root directory, where we will place
all of our custom rules, and create a new file in it named `no-gif-allowed.js`.

```sh
mkdir rules
Expand All @@ -123,11 +127,14 @@ touch no-gif-allowed.js
cd .. # return to project root
```

*Note*: the name of folders and files, and where to place them within your project, is up to you.
*Note*: the name of folders and files, and where to place them within your
project, is up to you.

In `./rules/no-gif-allowed.js`, let’s import `unified-lint-rule`.

We then export the result of calling `rule` by providing the *namespace and rule name* (`remark-lint:no-gif-allowed`) as the first argument, and our implementation of the rule (`noGifAllowed`) as the second argument.
We then export the result of calling `rule` by providing the *namespace and rule
name* (`remark-lint:no-gif-allowed`) as the first argument, and our
implementation of the rule (`noGifAllowed`) as the second argument.

```js
// rules/no-gif-allowed.js
Expand All @@ -143,7 +150,8 @@ const remarkLintNoGifAllowed = lintRule(
export default remarkLintNoGifAllowed
```

Let’s say you want all your custom rules to be defined as part of your project namespace.
Let’s say you want all your custom rules to be defined as part of your project
namespace.
If your project was named `my-project`, then you can export your rule as:

```js
Expand All @@ -152,9 +160,8 @@ const remarkLintNoGifAllowed = lintRule('my-project-name:no-gif-allowed', () =>
const remarkLintNoGifAllowed = lintRule('my-npm-published-package:no-gif-allowed', () => {})
```

This can help you when wanting to create a group of rules under the same *namespace*.

[Back to Top](#contents)
This can help you when wanting to create a group of rules under the same
*namespace*.

## Rule arguments

Expand All @@ -164,17 +171,20 @@ Your rule function will receive three arguments:
(tree, file, options) => {}
```

* `tree` (*required*): [mdast](https://github.com/syntax-tree/mdast)
* `file` (*required*): [virtual file](https://github.com/vfile/vfile)
* `options` (*optional*): additional information passed to the rule by users

[Back to Top](#contents)
* `tree` (*required*): [mdast][]
* `file` (*required*): [virtual file][vfile]
* `options` (*optional*): additional info passed to the rule by users

## Rule implementation

Because we will be inspecting [mdast](https://github.com/syntax-tree/mdast), which is a markdown abstract syntax tree built upon [unist](https://github.com/syntax-tree/unist), we can take advantage of the many existing [unist utilities](https://github.com/syntax-tree/unist#utilities) to inspect our tree’s nodes.
Because we will be inspecting [mdast][], which is a markdown abstract syntax
tree built upon [unist][], we can take advantage of the many existing
[unist utilities][unist-util] to inspect our tree’s nodes.

For this example, we will use [`unist-util-visit`](https://github.com/syntax-tree/unist-util-visit) to recursively inspect all the image nodes, and [`unist-util-generated`](https://github.com/syntax-tree/unist-util-generated) to ensure we are not inspecting nodes that we have generated ourselves and do not belong to the `doc.md`.
For this example, we will use [`unist-util-visit`][unist-util-visit] to
recursively inspect all the image nodes, and
[`unist-util-generated`][unist-util-generated] to ensure we are not inspecting
nodes that we have generated ourselves and do not belong to the `doc.md`.

```js
import {lintRule} from 'unified-lint-rule'
Expand Down Expand Up @@ -205,7 +215,7 @@ const remarkLintNoGifAllowed = lintRule(
// Remember to provide the node as second argument to the message,
// in order to obtain the position and column where the violation occurred.
file.message(
'Invalid image file extentions. Please do not use gifs',
'Invalid image file extensions. Please do not use gifs',
node
)
}
Expand All @@ -217,11 +227,10 @@ const remarkLintNoGifAllowed = lintRule(
export default remarkLintNoGifAllowed
```

[Back to Top](#contents)

## Import the rule in your remark config

Now that our custom rule is defined and ready to be used we need to add it to our `remark` configuration.
Now that our custom rule is defined and ready to be used we need to add it to
our `remark` configuration.

You can do that by importing your rule and adding it in `plugins` array:

Expand All @@ -238,16 +247,33 @@ const preset = {plugins}
export default preset
```

[Back to Top](#contents)

## Apply the rule on the Markdown file

If you run `npm run lint`, you should see the following message in the terminal:

```text
5:1-5:30 warning Invalid image file extentions. Please do not use gifs no-gif-allowed remark-lint
5:1-5:30 warning Invalid image file extensions. Please do not use gifs no-gif-allowed remark-lint
```

**Congratulations! The rule works!**
**Congratulations!
The rule works!**

[tutorial]: https://dev.to/floroz/how-to-create-a-custom-lint-rule-for-markdown-and-mdx-using-remark-and-eslint-2jim

[remark-lint]: https://github.com/remarkjs/remark-lint

[remark-cli]: https://github.com/remarkjs/remark/tree/main/packages/remark-cli

[examples]: https://github.com/remarkjs/remark-lint#examples

[mdast]: https://github.com/syntax-tree/mdast

[vfile]: https://github.com/vfile/vfile

[unist]: https://github.com/syntax-tree/unist

[unist-util]: https://github.com/syntax-tree/unist#utilities

[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit

[Back to Top](#contents)
[unist-util-generated]: https://github.com/syntax-tree/unist-util-generated
Loading