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