diff --git a/source files/marked.js b/source files/marked.js
index 2e8d6d4..6c637c8 100644
--- a/source files/marked.js
+++ b/source files/marked.js
@@ -1,6 +1,6 @@
/**
- * marked - a markdown parser
- * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
+ * marked - a markdown parser - v0.3.3
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
* https://github.com/chjj/marked
*/
@@ -18,9 +18,9 @@ var block = {
heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
nptable: noop,
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
- blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
- list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
- html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
+ blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
+ list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+ html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
def: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
table: noop,
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
@@ -35,13 +35,18 @@ block.item = replace(block.item, 'gm')
block.list = replace(block.list)
(/bull/g, block.bullet)
- ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)
+ ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
+ ('def', '\\n+(?=' + block.def.source + ')')
+ ();
+
+block.blockquote = replace(block.blockquote)
+ ('def', block.def)
();
block._tag = '(?!(?:'
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+ '|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';
block.html = replace(block.html)
('comment', //)
@@ -70,8 +75,9 @@ block.normal = merge({}, block);
*/
block.gfm = merge({}, block.normal, {
- fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
- paragraph: /^/
+ fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+ paragraph: /^/,
+ heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
});
block.gfm.paragraph = replace(block.paragraph)
@@ -141,7 +147,7 @@ Lexer.prototype.lex = function(src) {
* Lexing
*/
-Lexer.prototype.token = function(src, top) {
+Lexer.prototype.token = function(src, top, bq) {
var src = src.replace(/^ +$/gm, '')
, next
, loose
@@ -264,7 +270,7 @@ Lexer.prototype.token = function(src, top) {
// Pass `top` to keep the current
// "toplevel" state. This is exactly
// how markdown.pl works.
- this.token(cap, top);
+ this.token(cap, top, true);
this.tokens.push({
type: 'blockquote_end'
@@ -333,7 +339,7 @@ Lexer.prototype.token = function(src, top) {
});
// Recurse.
- this.token(item, false);
+ this.token(item, false, bq);
this.tokens.push({
type: 'list_item_end'
@@ -354,14 +360,15 @@ Lexer.prototype.token = function(src, top) {
type: this.options.sanitize
? 'paragraph'
: 'html',
- pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+ pre: !this.options.sanitizer
+ && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
text: cap[0]
});
continue;
}
// def
- if (top && (cap = this.rules.def.exec(src))) {
+ if ((!bq && top) && (cap = this.rules.def.exec(src))) {
src = src.substring(cap[0].length);
this.tokens.links[cap[1].toLowerCase()] = {
href: cap[2],
@@ -514,6 +521,8 @@ function InlineLexer(links, options) {
this.options = options || marked.defaults;
this.links = links;
this.rules = inline.normal;
+ this.renderer = this.options.renderer || new Renderer;
+ this.renderer.options = this.options;
if (!this.links) {
throw new
@@ -577,43 +586,44 @@ InlineLexer.prototype.output = function(src) {
text = escape(cap[1]);
href = text;
}
- out += ''
- + text
- + '';
+ out += this.renderer.link(href, null, text);
continue;
}
// url (gfm)
- if (cap = this.rules.url.exec(src)) {
+ if (!this.inLink && (cap = this.rules.url.exec(src))) {
src = src.substring(cap[0].length);
text = escape(cap[1]);
href = text;
- out += ''
- + text
- + '';
+ out += this.renderer.link(href, null, text);
continue;
}
// tag
if (cap = this.rules.tag.exec(src)) {
+ if (!this.inLink && /^/i.test(cap[0])) {
+ this.inLink = false;
+ }
src = src.substring(cap[0].length);
out += this.options.sanitize
- ? escape(cap[0])
- : cap[0];
+ ? this.options.sanitizer
+ ? this.options.sanitizer(cap[0])
+ : escape(cap[0])
+ : cap[0]
continue;
}
// link
if (cap = this.rules.link.exec(src)) {
src = src.substring(cap[0].length);
+ this.inLink = true;
out += this.outputLink(cap, {
href: cap[2],
title: cap[3]
});
+ this.inLink = false;
continue;
}
@@ -628,57 +638,51 @@ InlineLexer.prototype.output = function(src) {
src = cap[0].substring(1) + src;
continue;
}
+ this.inLink = true;
out += this.outputLink(cap, link);
+ this.inLink = false;
continue;
}
// strong
if (cap = this.rules.strong.exec(src)) {
src = src.substring(cap[0].length);
- out += ''
- + this.output(cap[2] || cap[1])
- + '';
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
continue;
}
// em
if (cap = this.rules.em.exec(src)) {
src = src.substring(cap[0].length);
- out += ''
- + this.output(cap[2] || cap[1])
- + '';
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
continue;
}
// code
if (cap = this.rules.code.exec(src)) {
src = src.substring(cap[0].length);
- out += ''
- + escape(cap[2], true)
- + '
';
+ out += this.renderer.codespan(escape(cap[2], true));
continue;
}
// br
if (cap = this.rules.br.exec(src)) {
src = src.substring(cap[0].length);
- out += '
';
+ out += this.renderer.br();
continue;
}
// del (gfm)
if (cap = this.rules.del.exec(src)) {
src = src.substring(cap[0].length);
- out += ''
- + this.output(cap[1])
- + '';
+ out += this.renderer.del(this.output(cap[1]));
continue;
}
// text
if (cap = this.rules.text.exec(src)) {
src = src.substring(cap[0].length);
- out += escape(this.smartypants(cap[0]));
+ out += this.renderer.text(escape(this.smartypants(cap[0])));
continue;
}
@@ -696,31 +700,12 @@ InlineLexer.prototype.output = function(src) {
*/
InlineLexer.prototype.outputLink = function(cap, link) {
- if (cap[0].charAt(0) !== '!') {
- return ''
- + this.output(cap[1])
- + '';
- } else {
- return '';
- }
+ var href = escape(link.href)
+ , title = link.title ? escape(link.title) : null;
+
+ return cap[0].charAt(0) !== '!'
+ ? this.renderer.link(href, title, this.output(cap[1]))
+ : this.renderer.image(href, title, escape(cap[1]));
};
/**
@@ -731,7 +716,9 @@ InlineLexer.prototype.smartypants = function(text) {
if (!this.options.smartypants) return text;
return text
// em-dashes
- .replace(/--/g, '\u2014')
+ .replace(/---/g, '\u2014')
+ // en-dashes
+ .replace(/--/g, '\u2013')
// opening singles
.replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
// closing singles & apostrophes
@@ -749,6 +736,7 @@ InlineLexer.prototype.smartypants = function(text) {
*/
InlineLexer.prototype.mangle = function(text) {
+ if (!this.options.mangle) return text;
var out = ''
, l = text.length
, i = 0
@@ -765,6 +753,153 @@ InlineLexer.prototype.mangle = function(text) {
return out;
};
+/**
+ * Renderer
+ */
+
+function Renderer(options) {
+ this.options = options || {};
+}
+
+Renderer.prototype.code = function(code, lang, escaped) {
+ if (this.options.highlight) {
+ var out = this.options.highlight(code, lang);
+ if (out != null && out !== code) {
+ escaped = true;
+ code = out;
+ }
+ }
+
+ if (!lang) {
+ return '
'
+ + (escaped ? code : escape(code, true))
+ + '\n
';
+ }
+
+ return ''
+ + (escaped ? code : escape(code, true))
+ + '\n
\n';
+};
+
+Renderer.prototype.blockquote = function(quote) {
+ return '\n' + quote + '\n'; +}; + +Renderer.prototype.html = function(html) { + return html; +}; + +Renderer.prototype.heading = function(text, level, raw) { + return '
' + text + '
\n'; +}; + +Renderer.prototype.table = function(header, body) { + return '' + text + '
';
+};
+
+Renderer.prototype.br = function() {
+ return this.options.xhtml ? ''
- + this.token.text
- + '
\n';
+ return this.renderer.code(this.token.text,
+ this.token.lang,
+ this.token.escaped);
}
case 'table': {
- var body = ''
- , heading
+ var header = ''
+ , body = ''
, i
, row
, cell
+ , flags
, j;
// header
- body += '\n\n' - + body - + '\n'; + return this.renderer.blockquote(body); } case 'list_start': { - var type = this.token.ordered ? 'ol' : 'ul' - , body = ''; + var body = '' + , ordered = this.token.ordered; while (this.next().type !== 'list_end') { body += this.tok(); } - return '<' - + type - + '>\n' - + body - + '' - + type - + '>\n'; + return this.renderer.list(body, ordered); } case 'list_item_start': { var body = ''; @@ -954,9 +1054,7 @@ Parser.prototype.tok = function() { : this.tok(); } - return '
' - + this.inline.output(this.token.text) - + '
\n'; + return this.renderer.paragraph(this.inline.output(this.token.text)); } case 'text': { - return '' - + this.parseText() - + '
\n'; + return this.renderer.paragraph(this.parseText()); } } }; @@ -1000,6 +1093,19 @@ function escape(html, encode) { .replace(/'/g, '''); } +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) { regex = regex.source; opt = opt || ''; @@ -1032,6 +1138,7 @@ function merge(obj) { return obj; } + /** * Marked */ @@ -1058,8 +1165,13 @@ function marked(src, opt, callback) { pending = tokens.length; - var done = function() { - var out, err; + var done = function(err) { + if (err) { + opt.highlight = highlight; + return callback(err); + } + + var out; try { out = Parser.parse(tokens, opt); @@ -1088,6 +1200,7 @@ function marked(src, opt, callback) { return --pending || done(); } return highlight(token.text, token.lang, function(err, code) { + if (err) return done(err); if (code == null || code === token.text) { return --pending || done(); } @@ -1130,11 +1243,16 @@ marked.defaults = { breaks: false, pedantic: false, sanitize: false, + sanitizer: null, + mangle: true, smartLists: false, silent: false, highlight: null, langPrefix: 'lang-', - smartypants: false + smartypants: false, + headerPrefix: '', + renderer: new Renderer, + xhtml: false }; /** @@ -1144,6 +1262,8 @@ marked.defaults = { marked.Parser = Parser; marked.parser = Parser.parse; +marked.Renderer = Renderer; + marked.Lexer = Lexer; marked.lexer = Lexer.lex; @@ -1152,7 +1272,7 @@ marked.inlineLexer = InlineLexer.output; marked.parse = marked; -if (typeof exports === 'object') { +if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = marked; } else if (typeof define === 'function' && define.amd) { define(function() { return marked; });