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 |
|
10 | Command 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 |
|
30 | This package is a command line interface (CLI) that you can use in your terminal
|
31 | or in npm scripts and the like to inspect and change markdown files.
|
32 | This CLI is built around remark, which is an ecosystem of plugins that work with
|
33 | markdown as structured data, specifically ASTs (abstract syntax trees).
|
34 | You can choose from the 150+ existing plugins or make your own.
|
35 |
|
36 | See [the monorepo readme][remark] for info on what the remark ecosystem is.
|
37 |
|
38 | ## When should I use this?
|
39 |
|
40 | You can use this package when you want to work with the markdown files in your
|
41 | project from the command line.
|
42 | `remark-cli` has many options and you can combine it with many plugins, so it
|
43 | should be possible to do what you want.
|
44 | If not, you can always use [`remark`][remark-core] itself manually in a script.
|
45 |
|
46 | ## Install
|
47 |
|
48 | This package is [ESM only][esm].
|
49 | In Node.js (version 16+), install with [npm][]:
|
50 |
|
51 | ```sh
|
52 | npm install remark-cli
|
53 | ```
|
54 |
|
55 | ## Use
|
56 |
|
57 | Add a table of contents with [`remark-toc`][remark-toc] to `readme.md`:
|
58 |
|
59 | ```sh
|
60 | remark readme.md --output --use remark-toc
|
61 | ```
|
62 |
|
63 | Lint all markdown files in the current directory according to the markdown style
|
64 | guide with [`remark-preset-lint-markdown-style-guide`][markdown-style-guide].
|
65 |
|
66 | ```sh
|
67 | remark . --use remark-preset-lint-markdown-style-guide
|
68 | ```
|
69 |
|
70 | ## CLI
|
71 |
|
72 | The interface of `remark-cli` is explained as follows on its help page
|
73 | (`remark --help`):
|
74 |
|
75 | ```txt
|
76 | Usage: remark [options] [path | glob ...]
|
77 |
|
78 | CLI to process markdown with remark
|
79 |
|
80 | Options:
|
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 |
|
109 | Examples:
|
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 |
|
121 | More info on all these options is available at [`unified-args`][unified-args],
|
122 | which 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 |
|
138 | This example checks and formats markdown with `remark-cli`.
|
139 | It assumes you’re in a Node.js package.
|
140 |
|
141 | Install the CLI and plugins:
|
142 |
|
143 | ```sh
|
144 | npm 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 |
|
161 | The above change adds a `format` script, which can be run with
|
162 | `npm run format`.
|
163 | It runs remark on all markdown files (`.`) and rewrites them (`--output`).
|
164 | Run `./node_modules/.bin/remark --help` for more info on the CLI.
|
165 |
|
166 | Then, 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 |
|
193 | Finally, you can run the npm script to check and format markdown files in your
|
194 | project:
|
195 |
|
196 | ```sh
|
197 | npm run format
|
198 | ```
|
199 |
|
200 | ### Example: config files (JSON, YAML, JS)
|
201 |
|
202 | In the previous example, we saw that `remark-cli` was configured from within a
|
203 | `package.json` file.
|
204 | That’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
|
206 | JSON).
|
207 |
|
208 | You can also define configuration in separate files in different languages.
|
209 | With the `package.json` config as inspiration, here’s a JavaScript version that
|
210 | can be placed in `.remarkrc.js`:
|
211 |
|
212 | ```js
|
213 | import remarkPresetLintConsistent from 'remark-preset-lint-consistent'
|
214 | import remarkPresetLintRecommended from 'remark-preset-lint-recommended'
|
215 | import remarkToc from 'remark-toc'
|
216 |
|
217 | const 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 |
|
230 | export default remarkConfig
|
231 | ```
|
232 |
|
233 | This is the same configuration in YAML, which can be placed in `.remarkrc.yml`:
|
234 |
|
235 | ```yml
|
236 | settings:
|
237 | bullet: "*"
|
238 | plugins:
|
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 |
|
248 | When `remark-cli` is about to process a markdown file it’ll search the file
|
249 | system upwards for configuration files starting at the folder where that file
|
250 | exists.
|
251 | Take the following file structure as an illustration:
|
252 |
|
253 | ```txt
|
254 | folder/
|
255 | ├─ subfolder/
|
256 | │ ├─ .remarkrc.json
|
257 | │ └─ file.md
|
258 | ├─ .remarkrc.js
|
259 | ├─ package.json
|
260 | └─ readme.md
|
261 | ```
|
262 |
|
263 | When `folder/subfolder/file.md` is processed, the closest config file is
|
264 | `folder/subfolder/.remarkrc.json`.
|
265 | For `folder/readme.md`, it’s `folder/.remarkrc.js`.
|
266 |
|
267 | The order of precedence is as follows.
|
268 | Earlier wins (so in the above file structure `folder/.remarkrc.js` wins over
|
269 | `folder/package.json`):
|
270 |
|
271 | 1. `.remarkrc` (JSON)
|
272 | 2. `.remarkrc.cjs` (CJS)
|
273 | 3. `.remarkrc.js` (CJS or ESM, depending on `type: 'module'` in `package.json`)
|
274 | 4. `.remarkrc.json` (JSON)
|
275 | 5. `.remarkrc.mjs` (ESM)
|
276 | 6. `.remarkrc.yaml` (YAML)
|
277 | 7. `.remarkrc.yml` (YAML)
|
278 | 8. `package.json` with `remarkConfig` field
|
279 |
|
280 | ## Compatibility
|
281 |
|
282 | Projects maintained by the unified collective are compatible with maintained
|
283 | versions of Node.js.
|
284 |
|
285 | When we cut a new major release, we drop support for unmaintained versions of
|
286 | Node.
|
287 | This means we try to keep the current release line, `remark-cli@^12`,
|
288 | compatible with Node.js 16.
|
289 |
|
290 | ## Security
|
291 |
|
292 | As 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.
|
294 | When going to HTML, you will likely combine remark with **[rehype][]**, in which
|
295 | case you should use [`rehype-sanitize`][rehype-sanitize].
|
296 |
|
297 | Use of remark plugins could also open you up to other attacks.
|
298 | Carefully assess each plugin and the risks involved in using them.
|
299 |
|
300 | For info on how to submit a report, see our [security policy][security].
|
301 |
|
302 | ## Contribute
|
303 |
|
304 | See [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways
|
305 | to get started.
|
306 | See [`support.md`][support] for ways to get help.
|
307 | Join us in [Discussions][chat] to chat with the community and contributors.
|
308 |
|
309 | This project has a [code of conduct][coc].
|
310 | By interacting with this repository, organization, or community you agree to
|
311 | abide by its terms.
|
312 |
|
313 | ## Sponsor
|
314 |
|
315 | Support 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 |
|
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 |
|
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
|