Comparing version 0.3.0 to 0.3.1
{ | ||
"name": "marked", | ||
"version": "0.2.10", | ||
"version": "0.3.1", | ||
"repo": "chjj/marked", | ||
@@ -5,0 +5,0 @@ "description": "A markdown parser built for speed", |
@@ -44,3 +44,3 @@ /** | ||
+ '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' | ||
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b'; | ||
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b'; | ||
@@ -519,2 +519,3 @@ block.html = replace(block.html) | ||
this.renderer = this.options.renderer || new Renderer; | ||
this.renderer.options = this.options; | ||
@@ -740,9 +741,9 @@ if (!this.links) { | ||
function Renderer() {} | ||
function Renderer(options) { | ||
this.options = options || {}; | ||
} | ||
Renderer.prototype.code = function(code, lang, escaped, options) { | ||
options = options || {}; | ||
if (options.highlight) { | ||
var out = options.highlight(code, lang); | ||
Renderer.prototype.code = function(code, lang, escaped) { | ||
if (this.options.highlight) { | ||
var out = this.options.highlight(code, lang); | ||
if (out != null && out !== code) { | ||
@@ -761,6 +762,6 @@ escaped = true; | ||
return '<pre><code class="' | ||
+ options.langPrefix | ||
+ lang | ||
+ this.options.langPrefix | ||
+ escape(lang, true) | ||
+ '">' | ||
+ (escaped ? code : escape(code)) | ||
+ (escaped ? code : escape(code, true)) | ||
+ '\n</code></pre>\n'; | ||
@@ -777,7 +778,7 @@ }; | ||
Renderer.prototype.heading = function(text, level, raw, options) { | ||
Renderer.prototype.heading = function(text, level, raw) { | ||
return '<h' | ||
+ level | ||
+ ' id="' | ||
+ options.headerPrefix | ||
+ this.options.headerPrefix | ||
+ raw.toLowerCase().replace(/[^\w]+/g, '-') | ||
@@ -853,2 +854,14 @@ + '">' | ||
Renderer.prototype.link = function(href, title, text) { | ||
if (this.options.sanitize) { | ||
try { | ||
var prot = decodeURIComponent(unescape(href)) | ||
.replace(/[^\w:]/g, '') | ||
.toLowerCase(); | ||
} catch (e) { | ||
return ''; | ||
} | ||
if (prot.indexOf('javascript:') === 0) { | ||
return ''; | ||
} | ||
} | ||
var out = '<a href="' + href + '"'; | ||
@@ -881,2 +894,3 @@ if (title) { | ||
this.renderer = this.options.renderer; | ||
this.renderer.options = this.options; | ||
} | ||
@@ -955,5 +969,3 @@ | ||
this.token.depth, | ||
this.token.text, | ||
this.options | ||
); | ||
this.token.text); | ||
} | ||
@@ -963,4 +975,3 @@ case 'code': { | ||
this.token.lang, | ||
this.token.escaped, | ||
this.options); | ||
this.token.escaped); | ||
} | ||
@@ -1069,2 +1080,15 @@ case 'table': { | ||
function unescape(html) { | ||
return html.replace(/&([#\w]+);/g, function(_, n) { | ||
n = n.toLowerCase(); | ||
if (n === 'colon') return ':'; | ||
if (n.charAt(0) === '#') { | ||
return n.charAt(1) === 'x' | ||
? String.fromCharCode(parseInt(n.substring(2), 16)) | ||
: String.fromCharCode(+n.substring(1)); | ||
} | ||
return ''; | ||
}); | ||
} | ||
function replace(regex, opt) { | ||
@@ -1071,0 +1095,0 @@ regex = regex.source; |
@@ -5,3 +5,3 @@ { | ||
"author": "Christopher Jeffrey", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"main": "./lib/marked.js", | ||
@@ -14,2 +14,3 @@ "bin": "./bin/marked", | ||
"bugs": { "url": "http://github.com/chjj/marked/issues" }, | ||
"license": "MIT", | ||
"keywords": ["markdown", "markup", "html"], | ||
@@ -16,0 +17,0 @@ "tags": ["markdown", "markup", "html"], |
322
README.md
# marked | ||
> A full-featured markdown parser and compiler, written in javascript. Built | ||
> A full-featured markdown parser and compiler, written in JavaScript. Built | ||
> for speed. | ||
@@ -19,2 +19,3 @@ | ||
```js | ||
var marked = require('marked'); | ||
console.log(marked('I am using __markdown__.')); | ||
@@ -24,6 +25,8 @@ // Outputs: <p>I am using <strong>markdown</strong>.</p> | ||
Example using all options: | ||
Example setting options with default values: | ||
```js | ||
var marked = require('marked'); | ||
marked.setOptions({ | ||
renderer: new marked.Renderer(), | ||
gfm: true, | ||
@@ -35,17 +38,13 @@ tables: true, | ||
smartLists: true, | ||
smartypants: false, | ||
smartypants: false | ||
}); | ||
// Using async version of marked | ||
marked('I am using __markdown__.', function (err, content) { | ||
if (err) throw err; | ||
console.log(content); | ||
}); | ||
console.log(marked('I am using __markdown__.')); | ||
``` | ||
## marked(markdownString, [options], [callback]) | ||
## marked(markdownString [,options] [,callback]) | ||
### markdownString | ||
Type: `String` | ||
Type: `string` | ||
@@ -56,3 +55,3 @@ String of markdown source to be compiled. | ||
Type: `Object` | ||
Type: `object` | ||
@@ -64,13 +63,143 @@ Hash of options. Can also be set using the `marked.setOptions` method as seen | ||
Type: `Function` | ||
Type: `function` | ||
Function called when the `markdownString` has been fully parsed when using | ||
async highlighting. If the `options` argument is omitted, this can be used as | ||
the second argument as seen above: | ||
the second argument. | ||
## Options | ||
### highlight | ||
Type: `function` | ||
A function to highlight code blocks. The first example below uses async highlighting with | ||
[node-pygmentize-bundled][pygmentize], and the second is a synchronous example using | ||
[highlight.js][highlight]: | ||
```js | ||
var marked = require('marked'); | ||
var markdownString = '```js\n console.log("hello"); \n```'; | ||
// Async highlighting with pygmentize-bundled | ||
marked.setOptions({ | ||
highlight: function (code, lang, callback) { | ||
require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) { | ||
callback(err, result.toString()); | ||
}); | ||
} | ||
}); | ||
// Using async version of marked | ||
marked(markdownString, function (err, content) { | ||
if (err) throw err; | ||
console.log(content); | ||
}); | ||
// Synchronous highlighting with highlight.js | ||
marked.setOptions({ | ||
highlight: function (code) { | ||
return require('highlight.js').highlightAuto(code).value; | ||
} | ||
}); | ||
console.log(marked(markdownString)); | ||
``` | ||
#### highlight arguments | ||
`code` | ||
Type: `string` | ||
The section of code to pass to the highlighter. | ||
`lang` | ||
Type: `string` | ||
The programming language specified in the code block. | ||
`callback` | ||
Type: `function` | ||
The callback function to call when using an async highlighter. | ||
### renderer | ||
Type: `object` | ||
Default: `new Renderer()` | ||
An object containing functions to render tokens to HTML. | ||
#### Overriding renderer methods | ||
The renderer option allows you to render tokens in a custom manor. Here is an | ||
example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub: | ||
```javascript | ||
var marked = require('marked'); | ||
var renderer = new marked.Renderer(); | ||
renderer.heading = function (text, level) { | ||
var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-'); | ||
return '<h' + level + '><a name="' + | ||
escapedText + | ||
'" class="anchor" href="#' + | ||
escapedText + | ||
'"><span class="header-link"></span></a>' + | ||
text + '</h' + level + '>'; | ||
}, | ||
console.log(marked('# heading+', { renderer: renderer })); | ||
``` | ||
This code will output the following HTML: | ||
```html | ||
<h1> | ||
<a name="heading-" class="anchor" href="#heading-"> | ||
<span class="header-link"></span> | ||
</a> | ||
heading+ | ||
</h1> | ||
``` | ||
#### Block level renderer methods | ||
- code(*string* code, *string* language) | ||
- blockquote(*string* quote) | ||
- html(*string* html) | ||
- heading(*string* text, *number* level) | ||
- hr() | ||
- list(*string* body, *boolean* ordered) | ||
- listitem(*string* text) | ||
- paragraph(*string* text) | ||
- table(*string* header, *string* body) | ||
- tablerow(*string* content) | ||
- tablecell(*string* content, *object* flags) | ||
`flags` has the following properties: | ||
```js | ||
{ | ||
header: true || false, | ||
align: 'center' || 'left' || 'right' | ||
} | ||
``` | ||
#### Inline level renderer methods | ||
- strong(*string* text) | ||
- em(*string* text) | ||
- codespan(*string* code) | ||
- br() | ||
- del(*string* text) | ||
- link(*string* href, *string* title, *string* text) | ||
- image(*string* href, *string* title, *string* text) | ||
### gfm | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `true` | ||
@@ -82,3 +211,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `true` | ||
@@ -91,3 +220,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `false` | ||
@@ -100,3 +229,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `false` | ||
@@ -109,3 +238,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `false` | ||
@@ -117,3 +246,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `true` | ||
@@ -126,3 +255,3 @@ | ||
Type: `Boolean` | ||
Type: `boolean` | ||
Default: `false` | ||
@@ -132,59 +261,2 @@ | ||
### renderer | ||
Type: `Renderer` | ||
Default: `new Renderer()` | ||
A renderer instance for rendering ast to html. Learn more on the Renderer | ||
section. | ||
## Renderer | ||
Renderer is a the new way for rendering tokens to html. Here is a simple | ||
example: | ||
```javascript | ||
var r = new marked.Renderer() | ||
r.blockcode = function(code, lang) { | ||
return highlight(lang, code).value; | ||
} | ||
console.log(marked(text, {renderer: r})) | ||
``` | ||
You can control anything you want. | ||
### Block Level | ||
- code(code, language) | ||
- blockquote(quote) | ||
- html(html) | ||
- heading(text, level) | ||
- hr() | ||
- list(body, ordered) | ||
- listitem(text) | ||
- paragraph(text) | ||
- table(header, body) | ||
- tablerow(content) | ||
- tablecell(content, flags) | ||
`flags` is an object like this: | ||
``` | ||
{ | ||
header: true, | ||
align: 'center' | ||
} | ||
``` | ||
### Span Level | ||
- strong(text) | ||
- em(text) | ||
- codespan(code) | ||
- br() | ||
- del(text) | ||
- link(href, title, text) | ||
- image(href, title, text) | ||
## Access to lexer and parser | ||
@@ -216,48 +288,4 @@ | ||
## Benchmarks | ||
## Philosophy behind marked | ||
node v0.4.x | ||
``` bash | ||
$ node test --bench | ||
marked completed in 12071ms. | ||
showdown (reuse converter) completed in 27387ms. | ||
showdown (new converter) completed in 75617ms. | ||
markdown-js completed in 70069ms. | ||
``` | ||
node v0.6.x | ||
``` bash | ||
$ node test --bench | ||
marked completed in 6448ms. | ||
marked (gfm) completed in 7357ms. | ||
marked (pedantic) completed in 6092ms. | ||
discount completed in 7314ms. | ||
showdown (reuse converter) completed in 16018ms. | ||
showdown (new converter) completed in 18234ms. | ||
markdown-js completed in 24270ms. | ||
``` | ||
__Marked is now faster than Discount, which is written in C.__ | ||
For those feeling skeptical: These benchmarks run the entire markdown test suite | ||
1000 times. The test suite tests every feature. It doesn't cater to specific | ||
aspects. | ||
node v0.8.x | ||
``` bash | ||
$ node test --bench | ||
marked completed in 3411ms. | ||
marked (gfm) completed in 3727ms. | ||
marked (pedantic) completed in 3201ms. | ||
robotskirt completed in 808ms. | ||
showdown (reuse converter) completed in 11954ms. | ||
showdown (new converter) completed in 17774ms. | ||
markdown-js completed in 17191ms. | ||
``` | ||
## Another Javascript Markdown Parser | ||
The point of marked was to create a markdown compiler where it was possible to | ||
@@ -281,43 +309,21 @@ frequently parse huge chunks of markdown without having to worry about | ||
### High level | ||
## Benchmarks | ||
You can customize the result with a customized renderer. | ||
node v0.8.x | ||
``` js | ||
var renderer = new marked.Renderer() | ||
renderer.heading = function(text, level) { | ||
return '<div class="h-' + level + '">' + text + '</div>' | ||
} | ||
var parse = function(src, options) { | ||
options = options || {}; | ||
options.renderer = renderer | ||
return marked.parser(marked.lexer(src, options), options); | ||
} | ||
console.log(parse('# h1')) | ||
``` bash | ||
$ node test --bench | ||
marked completed in 3411ms. | ||
marked (gfm) completed in 3727ms. | ||
marked (pedantic) completed in 3201ms. | ||
robotskirt completed in 808ms. | ||
showdown (reuse converter) completed in 11954ms. | ||
showdown (new converter) completed in 17774ms. | ||
markdown-js completed in 17191ms. | ||
``` | ||
The renderer API: | ||
__Marked is now faster than Discount, which is written in C.__ | ||
``` | ||
code: function(code, lang) | ||
blockquote: function(text) | ||
html: function(html) | ||
For those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects. | ||
heading: function(text, level) | ||
paragraph: function(text) | ||
hr: function() | ||
list: function(contents, isOrdered) | ||
listitem: function(text) | ||
table: function(header, body) | ||
tablerow: function(content) | ||
tablecell: function(text, flags) | ||
// flags: {header: false, align: 'center'} | ||
``` | ||
### Pro level | ||
@@ -384,3 +390,3 @@ | ||
Copyright (c) 2011-2013, Christopher Jeffrey. (MIT License) | ||
Copyright (c) 2011-2014, Christopher Jeffrey. (MIT License) | ||
@@ -387,0 +393,0 @@ See LICENSE for more info. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
44664
1058
387