UNPKG

15.4 kBMarkdownView Raw
1# remark-cli
2
3[![Build][build-badge]][build]
4[![Coverage][coverage-badge]][coverage]
5[![Downloads][downloads-badge]][downloads]
6[![Sponsors][sponsors-badge]][collective]
7[![Backers][backers-badge]][collective]
8[![Chat][chat-badge]][chat]
9
10Command line interface to inspect and change markdown files with **[remark][]**.
11
12## Contents
13
14* [What is this?](#what-is-this)
15* [When should I use this?](#when-should-i-use-this)
16* [Install](#install)
17* [Use](#use)
18* [CLI](#cli)
19* [Examples](#examples)
20 * [Example: checking and formatting markdown on the CLI](#example-checking-and-formatting-markdown-on-the-cli)
21 * [Example: config files (JSON, YAML, JS)](#example-config-files-json-yaml-js)
22* [Compatibility](#compatibility)
23* [Security](#security)
24* [Contribute](#contribute)
25* [Sponsor](#sponsor)
26* [License](#license)
27
28## What is this?
29
30This package is a command line interface (CLI) that you can use in your terminal
31or in npm scripts and the like to inspect and change markdown files.
32This CLI is built around remark, which is an ecosystem of plugins that work with
33markdown as structured data, specifically ASTs (abstract syntax trees).
34You can choose from the 150+ existing plugins or make your own.
35
36See [the monorepo readme][remark] for info on what the remark ecosystem is.
37
38## When should I use this?
39
40You can use this package when you want to work with the markdown files in your
41project from the command line.
42`remark-cli` has many options and you can combine it with many plugins, so it
43should be possible to do what you want.
44If not, you can always use [`remark`][remark-core] itself manually in a script.
45
46## Install
47
48This package is [ESM only][esm].
49In Node.js (version 16+), install with [npm][]:
50
51```sh
52npm install remark-cli
53```
54
55## Use
56
57Add a table of contents with [`remark-toc`][remark-toc] to `readme.md`:
58
59```sh
60remark readme.md --output --use remark-toc
61```
62
63Lint all markdown files in the current directory according to the markdown style
64guide with [`remark-preset-lint-markdown-style-guide`][markdown-style-guide].
65
66```sh
67remark . --use remark-preset-lint-markdown-style-guide
68```
69
70## CLI
71
72The interface of `remark-cli` is explained as follows on its help page
73(`remark --help`):
74
75```txt
76Usage: remark [options] [path | glob ...]
77
78 CLI to process markdown with remark
79
80Options:
81
82 --[no-]color specify color in report (on by default)
83 --[no-]config search for configuration files (on by default)
84 -e --ext <extensions> specify extensions
85 --file-path <path> specify path to process as
86 -f --frail exit with 1 on warnings
87 -h --help output usage information
88 --[no-]ignore search for ignore files (on by default)
89 -i --ignore-path <path> specify ignore file
90 --ignore-path-resolve-from cwd|dir resolve patterns in `ignore-path` from its directory or cwd
91 --ignore-pattern <globs> specify ignore patterns
92 --inspect output formatted syntax tree
93 -o --output [path] specify output location
94 -q --quiet output only warnings and errors
95 -r --rc-path <path> specify configuration file
96 --report <reporter> specify reporter
97 -s --setting <settings> specify settings
98 -S --silent output only errors
99 --silently-ignore do not fail when given ignored files
100 --[no-]stdout specify writing to stdout (on by default)
101 -t --tree specify input and output as syntax tree
102 --tree-in specify input as syntax tree
103 --tree-out output syntax tree
104 -u --use <plugins> use plugins
105 --verbose report extra info for messages
106 -v --version output version number
107 -w --watch watch for changes and reprocess
108
109Examples:
110
111 # Process `input.md`
112 $ remark input.md -o output.md
113
114 # Pipe
115 $ remark < input.md > output.md
116
117 # Rewrite all applicable files
118 $ remark . -o
119```
120
121More info on all these options is available at [`unified-args`][unified-args],
122which does the work.
123`remark-cli` is `unified-args` preconfigured to:
124
125* load `remark-` plugins
126* search for markdown extensions
127 ([`.md`, `.markdown`, etc][markdown-extensions])
128* ignore paths found in [`.remarkignore` files][ignore-file]
129* load configuration from
130 [`.remarkrc`, `.remarkrc.js`, etc files][config-file]
131* use configuration from
132 [`remarkConfig` fields in `package.json` files][config-file]
133
134## Examples
135
136### Example: checking and formatting markdown on the CLI
137
138This example checks and formats markdown with `remark-cli`.
139It assumes you’re in a Node.js package.
140
141Install the CLI and plugins:
142
143```sh
144npm install remark-cli remark-preset-lint-consistent remark-preset-lint-recommended remark-toc --save-dev
145```
146
147…then add an npm script in your `package.json`:
148
149```js
150 /* … */
151 "scripts": {
152 /* … */
153 "format": "remark . --output",
154 /* … */
155 },
156 /* … */
157```
158
159> 💡 **Tip**: add ESLint and such in the `format` script too.
160
161The above change adds a `format` script, which can be run with
162`npm run format`.
163It runs remark on all markdown files (`.`) and rewrites them (`--output`).
164Run `./node_modules/.bin/remark --help` for more info on the CLI.
165
166Then, add a `remarkConfig` to your `package.json` to configure remark:
167
168```js
169 /* … */
170 "remarkConfig": {
171 "settings": {
172 "bullet": "*", // Use `*` for list item bullets (default)
173 // See <https://github.com/remarkjs/remark/tree/main/packages/remark-stringify> for more options.
174 },
175 "plugins": [
176 "remark-preset-lint-consistent", // Check that markdown is consistent.
177 "remark-preset-lint-recommended", // Few recommended rules.
178 [
179 // Generate a table of contents in `## Contents`
180 "remark-toc",
181 {
182 "heading": "contents"
183 }
184 ]
185 ]
186 },
187 /* … */
188```
189
190> 👉 **Note**: you must remove the comments in the above examples when
191> copy/pasting them as comments are not supported in `package.json` files.
192
193Finally, you can run the npm script to check and format markdown files in your
194project:
195
196```sh
197npm run format
198```
199
200### Example: config files (JSON, YAML, JS)
201
202In the previous example, we saw that `remark-cli` was configured from within a
203`package.json` file.
204That’s a good place when the configuration is relatively short, when you have a
205`package.json`, and when you don’t need comments (which are not allowed in
206JSON).
207
208You can also define configuration in separate files in different languages.
209With the `package.json` config as inspiration, here’s a JavaScript version that
210can be placed in `.remarkrc.js`:
211
212```js
213import remarkPresetLintConsistent from 'remark-preset-lint-consistent'
214import remarkPresetLintRecommended from 'remark-preset-lint-recommended'
215import remarkToc from 'remark-toc'
216
217const remarkConfig = {
218 settings: {
219 bullet: '*', // Use `*` for list item bullets (default)
220 // See <https://github.com/remarkjs/remark/tree/main/packages/remark-stringify> for more options.
221 },
222 plugins: [
223 remarkPresetLintConsistent, // Check that markdown is consistent.
224 remarkPresetLintRecommended, // Few recommended rules.
225 // Generate a table of contents in `## Contents`
226 [remarkToc, {heading: 'contents'}]
227 ]
228}
229
230export default remarkConfig
231```
232
233This is the same configuration in YAML, which can be placed in `.remarkrc.yml`:
234
235```yml
236settings:
237 bullet: "*"
238plugins:
239 # Check that markdown is consistent.
240 - remark-preset-lint-consistent
241 # Few recommended rules.
242 - remark-preset-lint-recommended
243 # Generate a table of contents in `## Contents`
244 - - remark-toc
245 - heading: contents
246```
247
248When `remark-cli` is about to process a markdown file it’ll search the file
249system upwards for configuration files starting at the folder where that file
250exists.
251Take the following file structure as an illustration:
252
253```txt
254folder/
255├─ subfolder/
256│ ├─ .remarkrc.json
257│ └─ file.md
258├─ .remarkrc.js
259├─ package.json
260└─ readme.md
261```
262
263When `folder/subfolder/file.md` is processed, the closest config file is
264`folder/subfolder/.remarkrc.json`.
265For `folder/readme.md`, it’s `folder/.remarkrc.js`.
266
267The order of precedence is as follows.
268Earlier wins (so in the above file structure `folder/.remarkrc.js` wins over
269`folder/package.json`):
270
2711. `.remarkrc` (JSON)
2722. `.remarkrc.cjs` (CJS)
2733. `.remarkrc.js` (CJS or ESM, depending on `type: 'module'` in `package.json`)
2744. `.remarkrc.json` (JSON)
2755. `.remarkrc.mjs` (ESM)
2766. `.remarkrc.yaml` (YAML)
2777. `.remarkrc.yml` (YAML)
2788. `package.json` with `remarkConfig` field
279
280## Compatibility
281
282Projects maintained by the unified collective are compatible with maintained
283versions of Node.js.
284
285When we cut a new major release, we drop support for unmaintained versions of
286Node.
287This means we try to keep the current release line, `remark-cli@^12`,
288compatible with Node.js 16.
289
290## Security
291
292As markdown can be turned into HTML and improper use of HTML can open you up to
293[cross-site scripting (XSS)][xss] attacks, use of remark can be unsafe.
294When going to HTML, you will likely combine remark with **[rehype][]**, in which
295case you should use [`rehype-sanitize`][rehype-sanitize].
296
297Use of remark plugins could also open you up to other attacks.
298Carefully assess each plugin and the risks involved in using them.
299
300For info on how to submit a report, see our [security policy][security].
301
302## Contribute
303
304See [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways
305to get started.
306See [`support.md`][support] for ways to get help.
307Join us in [Discussions][chat] to chat with the community and contributors.
308
309This project has a [code of conduct][coc].
310By interacting with this repository, organization, or community you agree to
311abide by its terms.
312
313## Sponsor
314
315Support this effort and give back by sponsoring on [OpenCollective][collective]!
316
317<table>
318<tr valign="middle">
319<td width="20%" align="center" rowspan="2" colspan="2">
320 <a href="https://vercel.com">Vercel</a><br><br>
321 <a href="https://vercel.com"><img src="https://avatars1.githubusercontent.com/u/14985020?s=256&v=4" width="128"></a>
322</td>
323<td width="20%" align="center" rowspan="2" colspan="2">
324 <a href="https://motif.land">Motif</a><br><br>
325 <a href="https://motif.land"><img src="https://avatars1.githubusercontent.com/u/74457950?s=256&v=4" width="128"></a>
326</td>
327<td width="20%" align="center" rowspan="2" colspan="2">
328 <a href="https://www.hashicorp.com">HashiCorp</a><br><br>
329 <a href="https://www.hashicorp.com"><img src="https://avatars1.githubusercontent.com/u/761456?s=256&v=4" width="128"></a>
330</td>
331<td width="20%" align="center" rowspan="2" colspan="2">
332 <a href="https://www.gitbook.com">GitBook</a><br><br>
333 <a href="https://www.gitbook.com"><img src="https://avatars1.githubusercontent.com/u/7111340?s=256&v=4" width="128"></a>
334</td>
335<td width="20%" align="center" rowspan="2" colspan="2">
336 <a href="https://www.gatsbyjs.org">Gatsby</a><br><br>
337 <a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=256&v=4" width="128"></a>
338</td>
339</tr>
340<tr valign="middle">
341</tr>
342<tr valign="middle">
343<td width="20%" align="center" rowspan="2" colspan="2">
344 <a href="https://www.netlify.com">Netlify</a><br><br>
345 <!--OC has a sharper image-->
346 <a href="https://www.netlify.com"><img src="https://images.opencollective.com/netlify/4087de2/logo/256.png" width="128"></a>
347</td>
348<td width="10%" align="center">
349 <a href="https://www.coinbase.com">Coinbase</a><br><br>
350 <a href="https://www.coinbase.com"><img src="https://avatars1.githubusercontent.com/u/1885080?s=256&v=4" width="64"></a>
351</td>
352<td width="10%" align="center">
353 <a href="https://themeisle.com">ThemeIsle</a><br><br>
354 <a href="https://themeisle.com"><img src="https://avatars1.githubusercontent.com/u/58979018?s=128&v=4" width="64"></a>
355</td>
356<td width="10%" align="center">
357 <a href="https://expo.io">Expo</a><br><br>
358 <a href="https://expo.io"><img src="https://avatars1.githubusercontent.com/u/12504344?s=128&v=4" width="64"></a>
359</td>
360<td width="10%" align="center">
361 <a href="https://boostnote.io">Boost Note</a><br><br>
362 <a href="https://boostnote.io"><img src="https://images.opencollective.com/boosthub/6318083/logo/128.png" width="64"></a>
363</td>
364<td width="10%" align="center">
365 <a href="https://markdown.space">Markdown Space</a><br><br>
366 <a href="https://markdown.space"><img src="https://images.opencollective.com/markdown-space/e1038ed/logo/128.png" width="64"></a>
367</td>
368<td width="10%" align="center">
369 <a href="https://www.holloway.com">Holloway</a><br><br>
370 <a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=128&v=4" width="64"></a>
371</td>
372<td width="10%"></td>
373<td width="10%"></td>
374</tr>
375<tr valign="middle">
376<td width="100%" align="center" colspan="8">
377 <br>
378 <a href="https://opencollective.com/unified"><strong>You?</strong></a>
379 <br><br>
380</td>
381</tr>
382</table>
383
384## License
385
386[MIT][license] © [Titus Wormer][author]
387
388<!-- Definitions -->
389
390[build-badge]: https://github.com/remarkjs/remark/workflows/main/badge.svg
391
392[build]: https://github.com/remarkjs/remark/actions
393
394[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark.svg
395
396[coverage]: https://codecov.io/github/remarkjs/remark
397
398[downloads-badge]: https://img.shields.io/npm/dm/remark-cli.svg
399
400[downloads]: https://www.npmjs.com/package/remark-cli
401
402[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
403
404[backers-badge]: https://opencollective.com/unified/backers/badge.svg
405
406[collective]: https://opencollective.com/unified
407
408[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
409
410[chat]: https://github.com/remarkjs/remark/discussions
411
412[security]: https://github.com/remarkjs/.github/blob/main/security.md
413
414[health]: https://github.com/remarkjs/.github
415
416[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md
417
418[support]: https://github.com/remarkjs/.github/blob/main/support.md
419
420[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md
421
422[license]: https://github.com/remarkjs/remark/blob/main/license
423
424[author]: https://wooorm.com
425
426[npm]: https://docs.npmjs.com/cli/install
427
428[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
429
430[markdown-extensions]: https://github.com/sindresorhus/markdown-extensions
431
432[rehype]: https://github.com/rehypejs/rehype
433
434[rehype-sanitize]: https://github.com/rehypejs/rehype-sanitize
435
436[remark]: https://github.com/remarkjs/remark
437
438[remark-core]: ../remark/
439
440[remark-toc]: https://github.com/remarkjs/remark-toc
441
442[config-file]: https://github.com/unifiedjs/unified-engine#config-files
443
444[ignore-file]: https://github.com/unifiedjs/unified-engine#ignore-files
445
446[unified-args]: https://github.com/unifiedjs/unified-args#cli
447
448[markdown-style-guide]: https://github.com/remarkjs/remark-lint/tree/main/packages/remark-preset-lint-markdown-style-guide
449
450[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting