|
1 | 1 | # remark-react
|
2 | 2 |
|
3 |
| -[](https://travis-ci.org/mapbox/remark-react) |
| 3 | +[![Build][build-badge]][build] |
| 4 | +[![Coverage][coverage-badge]][coverage] |
| 5 | +[![Downloads][downloads-badge]][downloads] |
| 6 | +[![Chat][chat-badge]][chat] |
4 | 7 |
|
5 |
| -**remark-react** compiles markdown to React. Built on [**remark**](https://github.com/wooorm/remark), |
6 |
| -an extensively tested and pluggable parser. |
| 8 | +Transform markdown to React with **[remark][]**, an extensively tested and |
| 9 | +pluggable parser. |
7 | 10 |
|
8 |
| -**Why?** Using innerHTML and [dangerouslySetInnerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html) in |
9 |
| -[React.js](http://facebook.github.io/react/) is a common cause of [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) |
10 |
| -attacks: user input can include script tags and other kinds of active |
11 |
| -content that reaches across domains and harms security. remark-react |
12 |
| -builds a DOM in React, using [React.createElement](https://facebook.github.io/react/docs/top-level-api.html): |
13 |
| -this means that you can display parsed & formatted Markdown content |
14 |
| -in an application without using `dangerouslySetInnerHTML`. |
| 11 | +**Why?** Using innerHTML and [dangerouslySetInnerHTML][] in [React][] is a |
| 12 | +common cause of [XSS][] attacks: user input can include script tags and other |
| 13 | +kinds of active content that reaches across domains and harms security. |
| 14 | +**remark-react** builds a DOM in React, using [React.createElement][h]: this |
| 15 | +means that you can display parsed & formatted Markdown content in an |
| 16 | +application without using `dangerouslySetInnerHTML`. |
15 | 17 |
|
16 | 18 | ## Installation
|
17 | 19 |
|
18 |
| -[npm](https://docs.npmjs.com/cli/install): |
| 20 | +[npm][]: |
19 | 21 |
|
20 | 22 | ```bash
|
21 | 23 | npm install remark-react
|
22 | 24 | ```
|
23 | 25 |
|
24 | 26 | ## Table of Contents
|
25 | 27 |
|
26 |
| -* [Programmatic](#programmatic) |
| 28 | +## Usage |
27 | 29 |
|
28 |
| - * [remark.use(react, options)](#remarkusereact-options) |
| 30 | +```js |
| 31 | +var React = require('react') |
| 32 | +var remark = require('remark') |
| 33 | +var remark2react = require('remark-react'); |
29 | 34 |
|
30 |
| -* [Configuration](#configuration) |
| 35 | +var App = React.createClass({ |
| 36 | + getInitialState() { |
| 37 | + return { text: '# hello world' }; |
| 38 | + }, |
| 39 | + onChange(e) { |
| 40 | + this.setState({ text: e.target.value }); |
| 41 | + }, |
| 42 | + render() { |
| 43 | + return ( |
| 44 | + <div> |
| 45 | + <textarea value={this.state.text} onChange={this.onChange} /> |
| 46 | + <div id='preview'> |
| 47 | + {remark().use(remark2react).processSync(this.state.text).contents} |
| 48 | + </div> |
| 49 | + </div> |
| 50 | + ); |
| 51 | + } |
| 52 | +}); |
31 | 53 |
|
32 |
| -* [Integrations](#integrations) |
| 54 | +React.render(<App />, document.getElementById('app')); |
| 55 | +``` |
33 | 56 |
|
34 |
| -* [License](#license) |
| 57 | +## API |
35 | 58 |
|
36 |
| -## Programmatic |
| 59 | +### `remark().use(react[, options])` |
37 | 60 |
|
38 |
| -### [remark](https://github.com/wooorm/remark#api).[use](https://github.com/wooorm/remark#remarkuseplugin-options)(react, [options](#configuration)) |
| 61 | +Transform markdown to React. |
39 | 62 |
|
40 |
| -**Parameters** |
| 63 | +##### Options |
41 | 64 |
|
42 |
| -* `react` — This plugin; |
43 |
| -* `options` (`Object?`) — See [below](#configuration). |
| 65 | +###### `options.createElement` |
44 | 66 |
|
45 |
| -Let’s say `example.js` looks as follows: |
| 67 | +How to create elements or components (`Function`). |
| 68 | +Default: `require('react').createElement`) |
46 | 69 |
|
47 |
| -```js |
48 |
| -var React = require('react'), |
49 |
| - remark = require('remark'), |
50 |
| - reactRenderer = require('remark-react'); |
| 70 | +###### `options.sanitize` |
51 | 71 |
|
52 |
| -var App = React.createClass({ |
53 |
| - getInitialState() { |
54 |
| - return { text: '# hello world' }; |
55 |
| - }, |
56 |
| - onChange(e) { |
57 |
| - this.setState({ text: e.target.value }); |
58 |
| - }, |
59 |
| - render() { |
60 |
| - return (<div> |
61 |
| - <textarea |
62 |
| - value={this.state.text} |
63 |
| - onChange={this.onChange} /> |
64 |
| - <div id='preview'> |
65 |
| - {remark().use(reactRenderer).processSync(this.state.text).contents} |
66 |
| - </div> |
67 |
| - </div>); |
68 |
| - } |
69 |
| -}); |
| 72 | +Sanitation schema to use (`object` or `boolean`, default: `undefined`). |
| 73 | +Passed to [`hast-util-sanitize`][sanitize]. |
| 74 | +The default schema, if none or `true` is passed, adheres to GitHub’s |
| 75 | +sanitation rules. |
| 76 | +Setting this to `false` is just as bad as using `dangerouslySetInnerHTML`. |
70 | 77 |
|
71 |
| -React.render(<App />, document.getElementById('app')); |
| 78 | +###### `options.prefix` |
| 79 | + |
| 80 | +React key (default: `h-`). |
| 81 | + |
| 82 | +###### `options.remarkReactComponents` |
| 83 | + |
| 84 | +Override default elements, such as `<a>`, `<p>`, etc by defining an object |
| 85 | +comprised of `element: Component` key-value pairs (`object`, default: |
| 86 | +`undefined`). |
| 87 | +For example, to output `<MyLink>` components instead of `<a>`, and |
| 88 | +`<MyParagraph>` instead of `<p>`: |
| 89 | + |
| 90 | +```javascript |
| 91 | +remarkReactComponents: { |
| 92 | + a: MyLink, |
| 93 | + p: MyParagraph |
| 94 | +} |
72 | 95 | ```
|
73 | 96 |
|
74 |
| -## Configuration |
| 97 | +###### `options.toHast` |
75 | 98 |
|
76 |
| -All options, including the `options` object itself, are optional: |
| 99 | +Configure how to transform [mdast][] to [hast][] (`object`, default: `{}`). |
| 100 | +Passed to [mdast-util-to-hast][to-hast]. |
77 | 101 |
|
78 |
| -* `sanitize` (`object` or `boolean`, default: `undefined`) |
79 |
| - — Sanitation schema to use. Passed to |
80 |
| - [hast-util-sanitize](https://github.com/wooorm/hast-util-sanitize). |
81 |
| - The default schema, if none or `true` is passed, adheres to GitHub’s |
82 |
| - sanitation rules. |
| 102 | +## Integrations |
83 | 103 |
|
84 |
| - **This means that non-standard HAST nodes and many |
85 |
| - HTML elements are *by default* santized out.** If you want to be more |
86 |
| - permissive, you should provide a value for `sanitize`. |
| 104 | +See how to integrate with other remark plugins in the [Integrations][] section |
| 105 | +of `remark-html`. |
87 | 106 |
|
88 |
| - If `false` is passed, it does not sanitize input. |
| 107 | +## License |
89 | 108 |
|
90 |
| -* `prefix` (`string`, default: `h-`) |
91 |
| - — React key. |
| 109 | +[MIT][license] © [Titus Wormer][author], modified by [Tom MacWright][tom] and |
| 110 | +[Mapbox][]. |
92 | 111 |
|
93 |
| -* `createElement` (`Function`, default: `require('react').createElement`) |
94 |
| - — Function to use to create elements. |
| 112 | +[build-badge]: https://img.shields.io/travis/mapbox/remark-react.svg |
95 | 113 |
|
96 |
| -* `remarkReactComponents` (`object`, default: `undefined`) |
97 |
| - — Provides a way to override default elements (`<a>`, `<p>`, etc) |
98 |
| - by defining an object comprised of `element: Component` key-value |
99 |
| - pairs. For example, to output `<MyLink>` components instead of |
100 |
| - `<a>`, and `<MyParagraph>` instead of `<p>`: |
| 114 | +[build]: https://travis-ci.org/mapbox/remark-react |
101 | 115 |
|
102 |
| - ```js |
103 |
| - remarkReactComponents: { |
104 |
| - a: MyLink, |
105 |
| - p: MyParagraph |
106 |
| - } |
107 |
| - ``` |
| 116 | +[coverage-badge]: https://img.shields.io/codecov/c/github/mapbox/remark-react.svg |
108 | 117 |
|
109 |
| -* `toHast` (`object`, default: `{}`) |
110 |
| - — Provides options for transforming MDAST document to HAST. |
111 |
| - See [mdast-util-to-hast](https://github.com/wooorm/mdast-util-to-hast#api) |
112 |
| - for settings. |
| 118 | +[coverage]: https://codecov.io/github/mapbox/remark-react |
113 | 119 |
|
114 |
| -These can passed to `remark.use()` as a second argument. |
| 120 | +[downloads-badge]: https://img.shields.io/npm/dm/remark-react.svg |
115 | 121 |
|
116 |
| -## Integrations |
| 122 | +[downloads]: https://www.npmjs.com/package/remark-react |
117 | 123 |
|
118 |
| -**remark-react** works great with: |
| 124 | +[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg |
119 | 125 |
|
120 |
| -* [**remark-toc**](https://github.com/wooorm/remark-toc), which generates |
121 |
| - tables of contents; |
| 126 | +[chat]: https://spectrum.chat/unified/remark |
122 | 127 |
|
123 |
| -* [**remark-github**](https://github.com/wooorm/remark-github), which |
124 |
| - generates references to GitHub issues, PRs, users, and more; |
| 128 | +[npm]: https://docs.npmjs.com/cli/install |
125 | 129 |
|
126 |
| -* ...and [more](https://github.com/wooorm/remark/blob/master/doc/plugins.md#list-of-plugins). |
| 130 | +[license]: license |
127 | 131 |
|
128 |
| -All [**remark** nodes](https://github.com/wooorm/mdast) |
129 |
| -can be compiled to HTML. In addition, **remark-react** looks for an |
130 |
| -`attributes` object on each node it compiles and adds the found properties |
131 |
| -as HTML attributes on the compiled tag. |
| 132 | +[author]: https://wooorm.com |
132 | 133 |
|
133 |
| -Additionally, syntax highlighting can be included (completely virtual) with |
134 |
| -[`remark-react-lowlight`](https://github.com/bebraw/remark-react-lowlight). |
| 134 | +[tom]: https://macwright.org |
135 | 135 |
|
136 |
| -## License |
| 136 | +[mdast]: https://github.com/syntax-tree/mdast |
| 137 | + |
| 138 | +[hast]: https://github.com/syntax-tree/hast |
| 139 | + |
| 140 | +[remark]: https://github.com/remarkjs/remark |
| 141 | + |
| 142 | +[mapbox]: https://www.mapbox.com |
| 143 | + |
| 144 | +[to-hast]: https://github.com/syntax-tree/mdast-util-to-hast#tohastnode-options |
| 145 | + |
| 146 | +[react]: http://facebook.github.io/react/ |
| 147 | + |
| 148 | +[dangerouslysetinnerhtml]: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml |
| 149 | + |
| 150 | +[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting |
| 151 | + |
| 152 | +[h]: https://reactjs.org/docs/react-api.html#createelement |
| 153 | + |
| 154 | +[sanitize]: https://github.com/syntax-tree/hast-util-sanitize |
137 | 155 |
|
138 |
| -[MIT](license) © [Titus Wormer](http://wooorm.com), modified by [Tom MacWright](http://www.macwright.org/) and [Mapbox](https://www.mapbox.com/) |
| 156 | +[integrations]: https://github.com/remarkjs/remark-html#integrations |
0 commit comments