remark-stringify
Advanced tools
Comparing version 10.0.1 to 10.0.2
{ | ||
"name": "remark-stringify", | ||
"version": "10.0.1", | ||
"description": "remark plugin to compile markdown", | ||
"version": "10.0.2", | ||
"description": "remark plugin to add support for serializing markdown", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
361
readme.md
@@ -7,18 +7,63 @@ # remark-stringify | ||
[![Size][size-badge]][size] | ||
[![Chat][chat-badge]][chat] | ||
[![Sponsors][sponsors-badge]][collective] | ||
[![Backers][backers-badge]][collective] | ||
[![Chat][chat-badge]][chat] | ||
[Compiler][] for [**unified**][unified]. | ||
Serializes [**mdast**][mdast] syntax trees to markdown. | ||
Used in the [**remark** processor][remark] but can be used on its own as well. | ||
Can be [extended][extend] to change how markdown is serialized. | ||
**[remark][]** plugin to add support for serializing markdown. | ||
## Contents | ||
* [What is this?](#what-is-this) | ||
* [When should I use this?](#when-should-i-use-this) | ||
* [Install](#install) | ||
* [Use](#use) | ||
* [API](#api) | ||
* [`unified().use(remarkStringify[, options])`](#unifieduseremarkstringify-options) | ||
* [Syntax](#syntax) | ||
* [Syntax tree](#syntax-tree) | ||
* [Types](#types) | ||
* [Security](#security) | ||
* [Contribute](#contribute) | ||
* [Sponsor](#sponsor) | ||
* [License](#license) | ||
## What is this? | ||
This package is a [unified][] ([remark][]) plugin that defines how to take a | ||
syntax tree as input and turn it into serialized markdown. | ||
This plugin is built on [`mdast-util-to-markdown`][mdast-util-to-markdown], | ||
which turns [mdast][] syntax trees into a string. | ||
remark focusses on making it easier to transform content by abstracting such | ||
internals away. | ||
**unified** is a project that transforms content with abstract syntax trees | ||
(ASTs). | ||
**remark** adds support for markdown to unified. | ||
**mdast** is the markdown AST that remark uses. | ||
This is a remark plugin that defines how mdast is turned into markdown. | ||
## When should I use this? | ||
This plugin adds support to unified for serializing markdown. | ||
You can alternatively use [`remark`][remark-core] instead, which combines | ||
unified, [`remark-parse`][remark-parse], and this plugin. | ||
You can combine this plugin with other plugins to add syntax extensions. | ||
Notable examples that deeply integrate with it are | ||
[`remark-gfm`][remark-gfm], | ||
[`remark-mdx`][remark-mdx], | ||
[`remark-frontmatter`][remark-frontmatter], | ||
[`remark-math`][remark-math], and | ||
[`remark-directive`][remark-directive]. | ||
You can also use any other [remark plugin][plugin] before `remark-stringify`. | ||
If you want to handle syntax trees manually, you can use | ||
[`mdast-util-to-markdown`][mdast-util-to-markdown]. | ||
## Install | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). | ||
In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: | ||
[npm][]: | ||
```sh | ||
@@ -28,4 +73,20 @@ npm install remark-stringify | ||
In Deno with [Skypack][]: | ||
```js | ||
import remarkStringify from 'https://cdn.skypack.dev/remark-stringify@10?dts' | ||
``` | ||
In browsers with [Skypack][]: | ||
```html | ||
<script type="module"> | ||
import remarkStringify from 'https://cdn.skypack.dev/remark-stringify@10?min' | ||
</script> | ||
``` | ||
## Use | ||
Say we have the following module `example.js`: | ||
```js | ||
@@ -37,18 +98,21 @@ import {unified} from 'unified' | ||
unified() | ||
.use(rehypeParse) | ||
.use(rehypeRemark) | ||
.use(remarkStringify, { | ||
bullet: '*', | ||
fence: '~', | ||
fences: true, | ||
incrementListMarker: false | ||
}) | ||
.process('<h1>Hello, world!</h1>') | ||
.then((file) => { | ||
console.log(String(file)) | ||
}) | ||
main() | ||
async function main() { | ||
const file = await unified() | ||
.use(rehypeParse) | ||
.use(rehypeRemark) | ||
.use(remarkStringify, { | ||
bullet: '*', | ||
fence: '~', | ||
fences: true, | ||
incrementListMarker: false | ||
}) | ||
.process('<h1>Hello, world!</h1>') | ||
console.log(String(file)) | ||
} | ||
``` | ||
Yields: | ||
Running that with `node example.js` yields: | ||
@@ -59,8 +123,4 @@ ```markdown | ||
[See **unified** for more examples »][unified] | ||
## API | ||
[See **unified** for API docs »][unified] | ||
This package exports no identifiers. | ||
@@ -71,35 +131,150 @@ The default export is `remarkStringify`. | ||
Configure the `processor` to serialize [**mdast**][mdast] syntax trees to | ||
markdown. | ||
Add support for serializing markdown. | ||
Options are passed to [`mdast-util-to-markdown`][mdast-util-to-markdown]: | ||
all formatting options are supported. | ||
###### `options` | ||
##### `options` | ||
Options can be passed directly or passed later through | ||
[`processor.data()`][data]. | ||
Configuration (optional). | ||
All the formatting options of [`mdast-util-to-markdown`][to-markdown-options] | ||
are supported and will be passed through. | ||
###### `options.bullet` | ||
## Extending the compiler | ||
Marker to use for bullets of items in unordered lists (`'*'`, `'+'`, or `'-'`, | ||
default: `'*'`). | ||
See [`mdast-util-to-markdown`][to-markdown]. | ||
Then create a wrapper plugin such as [`remark-gfm`][remark-gfm]. | ||
###### `options.bulletOther` | ||
Marker to use in certain cases where the primary bullet doesn’t work (`'*'`, | ||
`'+'`, or `'-'`, default: depends). | ||
See [`mdast-util-to-markdown`][mdast-util-to-markdown] for more information. | ||
###### `options.bulletOrdered` | ||
Marker to use for bullets of items in ordered lists (`'.'` or `')'`, default: | ||
`'.'`). | ||
###### `options.bulletOrderedOther` | ||
Marker to use in certain cases where the primary bullet for ordered items | ||
doesn’t work (`'.'` or `')'`, default: none). | ||
See [`mdast-util-to-markdown`][mdast-util-to-markdown] for more information. | ||
###### `options.closeAtx` | ||
Whether to add the same number of number signs (`#`) at the end of an ATX | ||
heading as the opening sequence (`boolean`, default: `false`). | ||
###### `options.emphasis` | ||
Marker to use for emphasis (`'*'` or `'_'`, default: `'*'`). | ||
###### `options.fence` | ||
Marker to use for fenced code (``'`'`` or `'~'`, default: ``'`'``). | ||
###### `options.fences` | ||
Whether to use fenced code always (`boolean`, default: `false`). | ||
The default is to use fenced code if there is a language defined, if the code is | ||
empty, or if it starts or ends in blank lines. | ||
###### `options.incrementListMarker` | ||
Whether to increment the counter of ordered lists items (`boolean`, default: | ||
`true`). | ||
###### `options.listItemIndent` | ||
How to indent the content of list items (`'one'`, `'tab'`, or `'mixed'`, | ||
default: `'tab'`). | ||
Either with the size of the bullet plus one space (when `'one'`), a tab stop | ||
(`'tab'`), or depending on the item and its parent list (`'mixed'`, uses `'one'` | ||
if the item and list are tight and `'tab'` otherwise). | ||
###### `options.quote` | ||
Marker to use for titles (`'"'` or `"'"`, default: `'"'`). | ||
###### `options.resourceLink` | ||
Whether to always use resource links (`boolean`, default: `false`). | ||
The default is to use autolinks (`<https://example.com>`) when possible | ||
and resource links (`[text](url)`) otherwise. | ||
###### `options.rule` | ||
Marker to use for thematic breaks (`'*'`, `'-'`, or `'_'`, default: `'*'`). | ||
###### `options.ruleRepetition` | ||
Number of markers to use for thematic breaks (`number`, default: | ||
`3`, min: `3`). | ||
###### `options.ruleSpaces` | ||
Whether to add spaces between markers in thematic breaks (`boolean`, default: | ||
`false`). | ||
###### `options.setext` | ||
Whether to use setext headings when possible (`boolean`, default: `false`). | ||
The default is to always use ATX headings (`# heading`) instead of setext | ||
headings (`heading\n=======`). | ||
Setext headings can’t be used for empty headings or headings with a rank of | ||
three or more. | ||
###### `options.strong` | ||
Marker to use for strong (`'*'` or `'_'`, default: `'*'`). | ||
###### `options.tightDefinitions` | ||
Whether to join definitions without a blank line (`boolean`, default: `false`). | ||
The default is to add blank lines between any flow (“block”) construct. | ||
###### `options.handlers` | ||
This option is a bit advanced as it requires knowledge of ASTs, so we defer | ||
to the documentation available in | ||
[`mdast-util-to-markdown`][mdast-util-to-markdown]. | ||
###### `options.join` | ||
This option is a bit advanced as it requires knowledge of ASTs, so we defer | ||
to the documentation available in | ||
[`mdast-util-to-markdown`][mdast-util-to-markdown]. | ||
###### `options.unsafe` | ||
This option is a bit advanced as it requires deep knowledge of markdown, so we | ||
defer to the documentation available in | ||
[`mdast-util-to-markdown`][mdast-util-to-markdown]. | ||
## Syntax | ||
Markdown is serialized according to CommonMark but care is taken to format in | ||
such a way that the resulting markdown should work with most markdown parsers. | ||
Other plugins can add support for syntax extensions. | ||
## Syntax tree | ||
The syntax tree format used in remark is [mdast][]. | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
An `Options` type is exported, which models the interface of accepted options. | ||
## Security | ||
`remark-stringify` will do its best to serialize markdown to match the syntax | ||
tree, but there are several cases where that is impossible. | ||
It’ll do its best, but complete roundtripping is impossible given that any | ||
value could be injected into the tree. | ||
As markdown can be turned into HTML and improper use of HTML can open you up to | ||
[cross-site scripting (XSS)][xss] attacks, use of remark can be unsafe. | ||
When going to HTML, you will likely combine remark with **[rehype][]**, in which | ||
case you should use [`rehype-sanitize`][rehype-sanitize]. | ||
As markdown is sometimes used for HTML, and improper use of HTML can open you up | ||
to a [cross-site scripting (XSS)][xss] attack, use of `remark-stringify` and | ||
parsing it again later can potentially be unsafe. | ||
When parsing markdown afterwards, use remark in combination with the | ||
[**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make | ||
the tree safe. | ||
Use of remark plugins could also open you up to other attacks. | ||
Carefully assess each plugin and the risks involved in using them. | ||
For info on how to submit a report, see our [security policy][security]. | ||
## Contribute | ||
@@ -110,7 +285,4 @@ | ||
See [`support.md`][support] for ways to get help. | ||
Ideas for new plugins and tools can be posted in [`remarkjs/ideas`][ideas]. | ||
Join us in [Discussions][chat] to chat with the community and contributors. | ||
A curated list of awesome remark resources can be found in [**awesome | ||
remark**][awesome]. | ||
This project has a [code of conduct][coc]. | ||
@@ -128,11 +300,19 @@ By interacting with this repository, organization, or community you agree to | ||
<tr valign="middle"> | ||
<td width="20%" align="center" colspan="2"> | ||
<a href="https://www.gatsbyjs.org">Gatsby</a> 🥇<br><br> | ||
<td width="20%" align="center" rowspan="2" colspan="2"> | ||
<a href="https://vercel.com">Vercel</a><br><br> | ||
<a href="https://vercel.com"><img src="https://avatars1.githubusercontent.com/u/14985020?s=256&v=4" width="128"></a> | ||
</td> | ||
<td width="20%" align="center" rowspan="2" colspan="2"> | ||
<a href="https://motif.land">Motif</a><br><br> | ||
<a href="https://motif.land"><img src="https://avatars1.githubusercontent.com/u/74457950?s=256&v=4" width="128"></a> | ||
</td> | ||
<td width="20%" align="center" rowspan="2" colspan="2"> | ||
<a href="https://www.hashicorp.com">HashiCorp</a><br><br> | ||
<a href="https://www.hashicorp.com"><img src="https://avatars1.githubusercontent.com/u/761456?s=256&v=4" width="128"></a> | ||
</td> | ||
<td width="20%" align="center" rowspan="2" colspan="2"> | ||
<a href="https://www.gatsbyjs.org">Gatsby</a><br><br> | ||
<a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=256&v=4" width="128"></a> | ||
</td> | ||
<td width="20%" align="center" colspan="2"> | ||
<a href="https://vercel.com">Vercel</a> 🥇<br><br> | ||
<a href="https://vercel.com"><img src="https://avatars1.githubusercontent.com/u/14985020?s=256&v=4" width="128"></a> | ||
</td> | ||
<td width="20%" align="center" colspan="2"> | ||
<td width="20%" align="center" rowspan="2" colspan="2"> | ||
<a href="https://www.netlify.com">Netlify</a><br><br> | ||
@@ -142,5 +322,9 @@ <!--OC has a sharper image--> | ||
</td> | ||
</tr> | ||
<tr valign="middle"> | ||
</tr> | ||
<tr valign="middle"> | ||
<td width="10%" align="center"> | ||
<a href="https://www.holloway.com">Holloway</a><br><br> | ||
<a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=128&v=4" width="64"></a> | ||
<a href="https://www.coinbase.com">Coinbase</a><br><br> | ||
<a href="https://www.coinbase.com"><img src="https://avatars1.githubusercontent.com/u/1885080?s=256&v=4" width="64"></a> | ||
</td> | ||
@@ -152,2 +336,6 @@ <td width="10%" align="center"> | ||
<td width="10%" align="center"> | ||
<a href="https://expo.io">Expo</a><br><br> | ||
<a href="https://expo.io"><img src="https://avatars1.githubusercontent.com/u/12504344?s=128&v=4" width="64"></a> | ||
</td> | ||
<td width="10%" align="center"> | ||
<a href="https://boosthub.io">Boost Hub</a><br><br> | ||
@@ -157,5 +345,10 @@ <a href="https://boosthub.io"><img src="https://images.opencollective.com/boosthub/6318083/logo/128.png" width="64"></a> | ||
<td width="10%" align="center"> | ||
<a href="https://expo.io">Expo</a><br><br> | ||
<a href="https://expo.io"><img src="https://avatars1.githubusercontent.com/u/12504344?s=128&v=4" width="64"></a> | ||
<a href="https://www.holloway.com">Holloway</a><br><br> | ||
<a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=128&v=4" width="64"></a> | ||
</td> | ||
<td width="10%"></td> | ||
<td width="10%"></td> | ||
<td width="10%"></td> | ||
<td width="10%"></td> | ||
<td width="10%"></td> | ||
</tr> | ||
@@ -203,14 +396,12 @@ <tr valign="middle"> | ||
[security]: https://github.com/remarkjs/.github/blob/main/security.md | ||
[health]: https://github.com/remarkjs/.github | ||
[contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md | ||
[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md | ||
[support]: https://github.com/remarkjs/.github/blob/HEAD/support.md | ||
[support]: https://github.com/remarkjs/.github/blob/main/support.md | ||
[coc]: https://github.com/remarkjs/.github/blob/HEAD/code-of-conduct.md | ||
[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md | ||
[ideas]: https://github.com/remarkjs/ideas | ||
[awesome]: https://github.com/remarkjs/awesome-remark | ||
[license]: https://github.com/remarkjs/remark/blob/main/license | ||
@@ -222,10 +413,8 @@ | ||
[skypack]: https://www.skypack.dev | ||
[unified]: https://github.com/unifiedjs/unified | ||
[data]: https://github.com/unifiedjs/unified#processordatakey-value | ||
[remark]: https://github.com/remarkjs/remark | ||
[remark]: https://github.com/remarkjs/remark/tree/main/packages/remark | ||
[compiler]: https://github.com/unifiedjs/unified#processorcompiler | ||
[mdast]: https://github.com/syntax-tree/mdast | ||
@@ -235,12 +424,24 @@ | ||
[typescript]: https://www.typescriptlang.org | ||
[rehype]: https://github.com/rehypejs/rehype | ||
[sanitize]: https://github.com/rehypejs/rehype-sanitize | ||
[rehype-sanitize]: https://github.com/rehypejs/rehype-sanitize | ||
[to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown | ||
[mdast-util-to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown | ||
[to-markdown-options]: https://github.com/syntax-tree/mdast-util-to-markdown#formatting-options | ||
[remark-gfm]: https://github.com/remarkjs/remark-gfm | ||
[extend]: #extending-the-compiler | ||
[remark-mdx]: https://github.com/mdx-js/mdx/tree/main/packages/remark-mdx | ||
[remark-gfm]: https://github.com/remarkjs/remark-gfm | ||
[remark-frontmatter]: https://github.com/remarkjs/remark-frontmatter | ||
[remark-math]: https://github.com/remarkjs/remark-math | ||
[remark-directive]: https://github.com/remarkjs/remark-directive | ||
[remark-parse]: ../remark-parse/ | ||
[remark-core]: ../remark/ | ||
[plugin]: https://github.com/remarkjs/remark#plugin |
17829
435