1 | # marked
|
2 |
|
3 | > A full-featured markdown parser and compiler, written in JavaScript. Built
|
4 | > for speed.
|
5 |
|
6 | [![NPM version](https://badge.fury.io/js/marked.svg)][badge]
|
7 |
|
8 | ## Install
|
9 |
|
10 | ``` bash
|
11 | npm install marked --save
|
12 | ```
|
13 |
|
14 | or if you want to use the `marked` CLI tool (not necessary when using npm run-scripts):
|
15 |
|
16 | ``` bash
|
17 | npm install -g marked
|
18 | ```
|
19 |
|
20 | ## Usage
|
21 |
|
22 | Minimal usage:
|
23 |
|
24 | ```js
|
25 | var marked = require('marked');
|
26 | console.log(marked('I am using __markdown__.'));
|
27 | // Outputs: <p>I am using <strong>markdown</strong>.</p>
|
28 | ```
|
29 |
|
30 | Example setting options with default values:
|
31 |
|
32 | ```js
|
33 | var marked = require('marked');
|
34 | marked.setOptions({
|
35 | renderer: new marked.Renderer(),
|
36 | gfm: true,
|
37 | tables: true,
|
38 | breaks: false,
|
39 | pedantic: false,
|
40 | sanitize: false,
|
41 | smartLists: true,
|
42 | smartypants: false
|
43 | });
|
44 |
|
45 | console.log(marked('I am using __markdown__.'));
|
46 | ```
|
47 |
|
48 | ### Browser
|
49 |
|
50 | ```html
|
51 | <!doctype html>
|
52 | <html>
|
53 | <head>
|
54 | <meta charset="utf-8"/>
|
55 | <title>Marked in the browser</title>
|
56 | <script src="lib/marked.js"></script>
|
57 | </head>
|
58 | <body>
|
59 | <div id="content"></div>
|
60 | <script>
|
61 | document.getElementById('content').innerHTML =
|
62 | marked('# Marked in browser\n\nRendered by **marked**.');
|
63 | </script>
|
64 | </body>
|
65 | </html>
|
66 | ```
|
67 |
|
68 | ## marked(markdownString [,options] [,callback])
|
69 |
|
70 | ### markdownString
|
71 |
|
72 | Type: `string`
|
73 |
|
74 | String of markdown source to be compiled.
|
75 |
|
76 | ### options
|
77 |
|
78 | Type: `object`
|
79 |
|
80 | Hash of options. Can also be set using the `marked.setOptions` method as seen
|
81 | above.
|
82 |
|
83 | ### callback
|
84 |
|
85 | Type: `function`
|
86 |
|
87 | Function called when the `markdownString` has been fully parsed when using
|
88 | async highlighting. If the `options` argument is omitted, this can be used as
|
89 | the second argument.
|
90 |
|
91 | ## Options
|
92 |
|
93 | ### highlight
|
94 |
|
95 | Type: `function`
|
96 |
|
97 | A function to highlight code blocks. The first example below uses async highlighting with
|
98 | [node-pygmentize-bundled][pygmentize], and the second is a synchronous example using
|
99 | [highlight.js][highlight]:
|
100 |
|
101 | ```js
|
102 | var marked = require('marked');
|
103 |
|
104 | var markdownString = '```js\n console.log("hello"); \n```';
|
105 |
|
106 | // Async highlighting with pygmentize-bundled
|
107 | marked.setOptions({
|
108 | highlight: function (code, lang, callback) {
|
109 | require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
|
110 | callback(err, result.toString());
|
111 | });
|
112 | }
|
113 | });
|
114 |
|
115 | // Using async version of marked
|
116 | marked(markdownString, function (err, content) {
|
117 | if (err) throw err;
|
118 | console.log(content);
|
119 | });
|
120 |
|
121 | // Synchronous highlighting with highlight.js
|
122 | marked.setOptions({
|
123 | highlight: function (code) {
|
124 | return require('highlight.js').highlightAuto(code).value;
|
125 | }
|
126 | });
|
127 |
|
128 | console.log(marked(markdownString));
|
129 | ```
|
130 |
|
131 | #### highlight arguments
|
132 |
|
133 | `code`
|
134 |
|
135 | Type: `string`
|
136 |
|
137 | The section of code to pass to the highlighter.
|
138 |
|
139 | `lang`
|
140 |
|
141 | Type: `string`
|
142 |
|
143 | The programming language specified in the code block.
|
144 |
|
145 | `callback`
|
146 |
|
147 | Type: `function`
|
148 |
|
149 | The callback function to call when using an async highlighter.
|
150 |
|
151 | ### renderer
|
152 |
|
153 | Type: `object`
|
154 | Default: `new Renderer()`
|
155 |
|
156 | An object containing functions to render tokens to HTML.
|
157 |
|
158 | #### Overriding renderer methods
|
159 |
|
160 | The renderer option allows you to render tokens in a custom manner. Here is an
|
161 | example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub:
|
162 |
|
163 | ```javascript
|
164 | var marked = require('marked');
|
165 | var renderer = new marked.Renderer();
|
166 |
|
167 | renderer.heading = function (text, level) {
|
168 | var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
|
169 |
|
170 | return '<h' + level + '><a name="' +
|
171 | escapedText +
|
172 | '" class="anchor" href="#' +
|
173 | escapedText +
|
174 | '"><span class="header-link"></span></a>' +
|
175 | text + '</h' + level + '>';
|
176 | };
|
177 |
|
178 | console.log(marked('# heading+', { renderer: renderer }));
|
179 | ```
|
180 | This code will output the following HTML:
|
181 | ```html
|
182 | <h1>
|
183 | <a name="heading-" class="anchor" href="#heading-">
|
184 | <span class="header-link"></span>
|
185 | </a>
|
186 | heading+
|
187 | </h1>
|
188 | ```
|
189 |
|
190 | #### Block level renderer methods
|
191 |
|
192 | - code(*string* code, *string* language)
|
193 | - blockquote(*string* quote)
|
194 | - html(*string* html)
|
195 | - heading(*string* text, *number* level)
|
196 | - hr()
|
197 | - list(*string* body, *boolean* ordered)
|
198 | - listitem(*string* text)
|
199 | - paragraph(*string* text)
|
200 | - table(*string* header, *string* body)
|
201 | - tablerow(*string* content)
|
202 | - tablecell(*string* content, *object* flags)
|
203 |
|
204 | `flags` has the following properties:
|
205 |
|
206 | ```js
|
207 | {
|
208 | header: true || false,
|
209 | align: 'center' || 'left' || 'right'
|
210 | }
|
211 | ```
|
212 |
|
213 | #### Inline level renderer methods
|
214 |
|
215 | - strong(*string* text)
|
216 | - em(*string* text)
|
217 | - codespan(*string* code)
|
218 | - br()
|
219 | - del(*string* text)
|
220 | - link(*string* href, *string* title, *string* text)
|
221 | - image(*string* href, *string* title, *string* text)
|
222 | - text(*string* text)
|
223 |
|
224 | ### gfm
|
225 |
|
226 | Type: `boolean`
|
227 | Default: `true`
|
228 |
|
229 | Enable [GitHub flavored markdown][gfm].
|
230 |
|
231 | ### tables
|
232 |
|
233 | Type: `boolean`
|
234 | Default: `true`
|
235 |
|
236 | Enable GFM [tables][tables].
|
237 | This option requires the `gfm` option to be true.
|
238 |
|
239 | ### breaks
|
240 |
|
241 | Type: `boolean`
|
242 | Default: `false`
|
243 |
|
244 | Enable GFM [line breaks][breaks].
|
245 | This option requires the `gfm` option to be true.
|
246 |
|
247 | ### pedantic
|
248 |
|
249 | Type: `boolean`
|
250 | Default: `false`
|
251 |
|
252 | Conform to obscure parts of `markdown.pl` as much as possible. Don't fix any of
|
253 | the original markdown bugs or poor behavior.
|
254 |
|
255 | ### sanitize
|
256 |
|
257 | Type: `boolean`
|
258 | Default: `false`
|
259 |
|
260 | Sanitize the output. Ignore any HTML that has been input.
|
261 |
|
262 | ### smartLists
|
263 |
|
264 | Type: `boolean`
|
265 | Default: `true`
|
266 |
|
267 | Use smarter list behavior than the original markdown. May eventually be
|
268 | default with the old behavior moved into `pedantic`.
|
269 |
|
270 | ### smartypants
|
271 |
|
272 | Type: `boolean`
|
273 | Default: `false`
|
274 |
|
275 | Use "smart" typographic punctuation for things like quotes and dashes.
|
276 |
|
277 | ## Access to lexer and parser
|
278 |
|
279 | You also have direct access to the lexer and parser if you so desire.
|
280 |
|
281 | ``` js
|
282 | var tokens = marked.lexer(text, options);
|
283 | console.log(marked.parser(tokens));
|
284 | ```
|
285 |
|
286 | ``` js
|
287 | var lexer = new marked.Lexer(options);
|
288 | var tokens = lexer.lex(text);
|
289 | console.log(tokens);
|
290 | console.log(lexer.rules);
|
291 | ```
|
292 |
|
293 | ## CLI
|
294 |
|
295 | ``` bash
|
296 | $ marked -o hello.html
|
297 | hello world
|
298 | ^D
|
299 | $ cat hello.html
|
300 | <p>hello world</p>
|
301 | ```
|
302 |
|
303 | ## Philosophy behind marked
|
304 |
|
305 | The point of marked was to create a markdown compiler where it was possible to
|
306 | frequently parse huge chunks of markdown without having to worry about
|
307 | caching the compiled output somehow...or blocking for an unnecessarily long time.
|
308 |
|
309 | marked is very concise and still implements all markdown features. It is also
|
310 | now fully compatible with the client-side.
|
311 |
|
312 | marked more or less passes the official markdown test suite in its
|
313 | entirety. This is important because a surprising number of markdown compilers
|
314 | cannot pass more than a few tests. It was very difficult to get marked as
|
315 | compliant as it is. It could have cut corners in several areas for the sake
|
316 | of performance, but did not in order to be exactly what you expect in terms
|
317 | of a markdown rendering. In fact, this is why marked could be considered at a
|
318 | disadvantage in the benchmarks.
|
319 |
|
320 | Along with implementing every markdown feature, marked also implements [GFM
|
321 | features][gfmf].
|
322 |
|
323 | ## Benchmarks
|
324 |
|
325 | node v8.9.4
|
326 |
|
327 | ``` bash
|
328 | $ npm run bench
|
329 | marked completed in 3408ms.
|
330 | marked (gfm) completed in 3465ms.
|
331 | marked (pedantic) completed in 3032ms.
|
332 | showdown (reuse converter) completed in 21444ms.
|
333 | showdown (new converter) completed in 23058ms.
|
334 | markdown-it completed in 3364ms.
|
335 | markdown.js completed in 12090ms.
|
336 | ```
|
337 |
|
338 | ### Pro level
|
339 |
|
340 | You also have direct access to the lexer and parser if you so desire.
|
341 |
|
342 | ``` js
|
343 | var tokens = marked.lexer(text, options);
|
344 | console.log(marked.parser(tokens));
|
345 | ```
|
346 |
|
347 | ``` js
|
348 | var lexer = new marked.Lexer(options);
|
349 | var tokens = lexer.lex(text);
|
350 | console.log(tokens);
|
351 | console.log(lexer.rules);
|
352 | ```
|
353 |
|
354 | ``` bash
|
355 | $ node
|
356 | > require('marked').lexer('> i am using marked.')
|
357 | [ { type: 'blockquote_start' },
|
358 | { type: 'paragraph',
|
359 | text: 'i am using marked.' },
|
360 | { type: 'blockquote_end' },
|
361 | links: {} ]
|
362 | ```
|
363 |
|
364 | ## Running Tests & Contributing
|
365 |
|
366 | If you want to submit a pull request, make sure your changes pass the test
|
367 | suite. If you're adding a new feature, be sure to add your own test.
|
368 |
|
369 | The marked test suite is set up slightly strangely: `test/new` is for all tests
|
370 | that are not part of the original markdown.pl test suite (this is where your
|
371 | test should go if you make one). `test/original` is only for the original
|
372 | markdown.pl tests.
|
373 |
|
374 | In other words, if you have a test to add, add it to `test/new/`. If your test
|
375 | uses a certain feature, for example, maybe it assumes GFM is *not* enabled, you
|
376 | can add [front-matter](https://www.npmjs.com/package/front-matter) to the top of
|
377 | your `.md` file
|
378 |
|
379 | ``` yml
|
380 | ---
|
381 | gfm: false
|
382 | ---
|
383 | ```
|
384 |
|
385 | To run the tests:
|
386 |
|
387 | ``` bash
|
388 | npm run test
|
389 | ```
|
390 |
|
391 | ### Contribution and License Agreement
|
392 |
|
393 | If you contribute code to this project, you are implicitly allowing your code
|
394 | to be distributed under the MIT license. You are also implicitly verifying that
|
395 | all code is your original work. `</legalese>`
|
396 |
|
397 | ## License
|
398 |
|
399 | Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
|
400 |
|
401 | See LICENSE for more info.
|
402 |
|
403 | [gfm]: https://help.github.com/articles/github-flavored-markdown
|
404 | [gfmf]: http://github.github.com/github-flavored-markdown/
|
405 | [pygmentize]: https://github.com/rvagg/node-pygmentize-bundled
|
406 | [highlight]: https://github.com/isagalaev/highlight.js
|
407 | [badge]: http://badge.fury.io/js/marked
|
408 | [tables]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables
|
409 | [breaks]: https://help.github.com/articles/github-flavored-markdown#newlines
|