diff --git a/js/core/marked.js b/js/core/marked.js deleted file mode 100644 index 62a5eb9993..0000000000 --- a/js/core/marked.js +++ /dev/null @@ -1,781 +0,0 @@ -/** - * marked - A markdown parser (https://github.com/chjj/marked) - * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed) - */ - -;(function() { - -/** - * Block-Level Grammar - */ - -var block = { - newline: /^\n+/, - code: /^( {4}[^\n]+\n*)+/, - fences: noop, - hr: /^( *[-*_]){3,} *(?:\n+|$)/, - heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, - lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, - blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/, - list: /^( *)(bull) [^\0]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, - html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, - def: /^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, - paragraph: /^([^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+\n*/, - text: /^[^\n]+/ -}; - -block.bullet = /(?:[*+-]|\d+\.)/; -block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; -block.item = replace(block.item, 'gm') - (/bull/g, block.bullet) - (); - -block.list = replace(block.list) - (/bull/g, block.bullet) - ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/) - (); - -block.html = replace(block.html) - ('comment', //) - ('closed', /<(tag)[^\0]+?<\/\1>/) - ('closing', /])*?>/) - (/tag/g, tag()) - (); - -block.paragraph = replace(block.paragraph) - ('hr', block.hr) - ('heading', block.heading) - ('lheading', block.lheading) - ('blockquote', block.blockquote) - ('tag', '<' + tag()) - ('def', block.def) - (); - -block.normal = { - fences: block.fences, - paragraph: block.paragraph -}; - -block.gfm = { - fences: /^ *(```|~~~) *(\w+)? *\n([^\0]+?)\s*\1 *(?:\n+|$)/, - paragraph: /^/ -}; - -block.gfm.paragraph = replace(block.paragraph) - ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') - (); - -/** - * Block Lexer - */ - -block.lexer = function(src) { - var tokens = []; - - tokens.links = {}; - - src = src - .replace(/\r\n|\r/g, '\n') - .replace(/\t/g, ' '); - - return block.token(src, tokens, true); -}; - -block.token = function(src, tokens, top) { - var src = src.replace(/^ +$/gm, '') - , next - , loose - , cap - , item - , space - , i - , l; - - while (src) { - // newline - if (cap = block.newline.exec(src)) { - src = src.substring(cap[0].length); - if (cap[0].length > 1) { - tokens.push({ - type: 'space' - }); - } - } - - // code - if (cap = block.code.exec(src)) { - src = src.substring(cap[0].length); - cap = cap[0].replace(/^ {4}/gm, ''); - tokens.push({ - type: 'code', - text: !options.pedantic - ? cap.replace(/\n+$/, '') - : cap - }); - continue; - } - - // fences (gfm) - if (cap = block.fences.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'code', - lang: cap[2], - text: cap[3] - }); - continue; - } - - // heading - if (cap = block.heading.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'heading', - depth: cap[1].length, - text: cap[2] - }); - continue; - } - - // lheading - if (cap = block.lheading.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'heading', - depth: cap[2] === '=' ? 1 : 2, - text: cap[1] - }); - continue; - } - - // hr - if (cap = block.hr.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'hr' - }); - continue; - } - - // blockquote - if (cap = block.blockquote.exec(src)) { - src = src.substring(cap[0].length); - - tokens.push({ - type: 'blockquote_start' - }); - - cap = cap[0].replace(/^ *> ?/gm, ''); - - // Pass `top` to keep the current - // "toplevel" state. This is exactly - // how markdown.pl works. - block.token(cap, tokens, top); - - tokens.push({ - type: 'blockquote_end' - }); - - continue; - } - - // list - if (cap = block.list.exec(src)) { - src = src.substring(cap[0].length); - - tokens.push({ - type: 'list_start', - ordered: isFinite(cap[2]) - }); - - // Get each top-level item. - cap = cap[0].match(block.item); - - next = false; - l = cap.length; - i = 0; - - for (; i < l; i++) { - item = cap[i]; - - // Remove the list item's bullet - // so it is seen as the next token. - space = item.length; - item = item.replace(/^ *([*+-]|\d+\.) +/, ''); - - // Outdent whatever the - // list item contains. Hacky. - if (~item.indexOf('\n ')) { - space -= item.length; - item = !options.pedantic - ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') - : item.replace(/^ {1,4}/gm, ''); - } - - // Determine whether item is loose or not. - // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ - // for discount behavior. - loose = next || /\n\n(?!\s*$)/.test(item); - if (i !== l - 1) { - next = item[item.length-1] === '\n'; - if (!loose) loose = next; - } - - tokens.push({ - type: loose - ? 'loose_item_start' - : 'list_item_start' - }); - - // Recurse. - block.token(item, tokens); - - tokens.push({ - type: 'list_item_end' - }); - } - - tokens.push({ - type: 'list_end' - }); - - continue; - } - - // html - if (cap = block.html.exec(src)) { - src = src.substring(cap[0].length); - tokens.push({ - type: options.sanitize - ? 'paragraph' - : 'html', - pre: cap[1] === 'pre', - text: cap[0] - }); - continue; - } - - // def - if (top && (cap = block.def.exec(src))) { - src = src.substring(cap[0].length); - tokens.links[cap[1].toLowerCase()] = { - href: cap[2], - title: cap[3] - }; - continue; - } - - // top-level paragraph - if (top && (cap = block.paragraph.exec(src))) { - src = src.substring(cap[0].length); - tokens.push({ - type: 'paragraph', - text: cap[0] - }); - continue; - } - - // text - if (cap = block.text.exec(src)) { - // Top-level should never reach here. - src = src.substring(cap[0].length); - tokens.push({ - type: 'text', - text: cap[0] - }); - continue; - } - } - - return tokens; -}; - -/** - * Inline Processing - */ - -var inline = { - escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, - autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, - url: noop, - tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, - link: /^!?\[(inside)\]\(href\)/, - reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, - nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, - strong: /^__([^\0]+?)__(?!_)|^\*\*([^\0]+?)\*\*(?!\*)/, - em: /^\b_((?:__|[^\0])+?)_\b|^\*((?:\*\*|[^\0])+?)\*(?!\*)/, - code: /^(`+)([^\0]*?[^`])\1(?!`)/, - br: /^ {2,}\n(?!\s*$)/, - text: /^[^\0]+?(?=[\\?(?:\s+['"]([^\0]*?)['"])?\s*/; - -inline.link = replace(inline.link) - ('inside', inline._linkInside) - ('href', inline._linkHref) - (); - -inline.reflink = replace(inline.reflink) - ('inside', inline._linkInside) - (); - -inline.normal = { - url: inline.url, - strong: inline.strong, - em: inline.em, - text: inline.text -}; - -inline.pedantic = { - strong: /^__(?=\S)([^\0]*?\S)__(?!_)|^\*\*(?=\S)([^\0]*?\S)\*\*(?!\*)/, - em: /^_(?=\S)([^\0]*?\S)_(?!_)|^\*(?=\S)([^\0]*?\S)\*(?!\*)/ -}; - -inline.gfm = { - url: /^(https?:\/\/[^\s]+[^.,:;"')\]\s])/, - text: /^[^\0]+?(?=[\\' - + text - + ''; - continue; - } - - // url (gfm) - if (cap = inline.url.exec(src)) { - src = src.substring(cap[0].length); - text = escape(cap[1]); - href = text; - out += '' - + text - + ''; - continue; - } - - // tag - if (cap = inline.tag.exec(src)) { - src = src.substring(cap[0].length); - out += options.sanitize - ? escape(cap[0]) - : cap[0]; - continue; - } - - // link - if (cap = inline.link.exec(src)) { - src = src.substring(cap[0].length); - out += outputLink(cap, { - href: cap[2], - title: cap[3] - }); - continue; - } - - // reflink, nolink - if ((cap = inline.reflink.exec(src)) - || (cap = inline.nolink.exec(src))) { - src = src.substring(cap[0].length); - link = (cap[2] || cap[1]).replace(/\s+/g, ' '); - link = links[link.toLowerCase()]; - if (!link || !link.href) { - out += cap[0][0]; - src = cap[0].substring(1) + src; - continue; - } - out += outputLink(cap, link); - continue; - } - - // strong - if (cap = inline.strong.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + inline.lexer(cap[2] || cap[1]) - + ''; - continue; - } - - // em - if (cap = inline.em.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + inline.lexer(cap[2] || cap[1]) - + ''; - continue; - } - - // code - if (cap = inline.code.exec(src)) { - src = src.substring(cap[0].length); - out += '' - + escape(cap[2], true) - + ''; - continue; - } - - // br - if (cap = inline.br.exec(src)) { - src = src.substring(cap[0].length); - out += '
'; - continue; - } - - // text - if (cap = inline.text.exec(src)) { - src = src.substring(cap[0].length); - out += escape(cap[0]); - continue; - } - } - - return out; -}; - -function outputLink(cap, link) { - if (cap[0][0] !== '!') { - return '' - + inline.lexer(cap[1]) - + ''; - } else { - return ''
-      + escape(cap[1])
-      + ''; - } -} - -/** - * Parsing - */ - -var tokens - , token; - -function next() { - return token = tokens.pop(); -} - -function tok() { - switch (token.type) { - case 'space': { - return ''; - } - case 'hr': { - return '
\n'; - } - case 'heading': { - return '' - + inline.lexer(token.text) - + '\n'; - } - case 'code': { - if (options.highlight) { - token.code = options.highlight(token.text, token.lang); - if (token.code != null && token.code !== token.text) { - token.escaped = true; - token.text = token.code; - } - } - - if (!token.escaped) { - token.text = escape(token.text, true); - } - - return '
'
-        + token.text
-        + '
\n'; - } - case 'blockquote_start': { - var body = ''; - - while (next().type !== 'blockquote_end') { - body += tok(); - } - - return '
\n' - + body - + '
\n'; - } - case 'list_start': { - var type = token.ordered ? 'ol' : 'ul' - , body = ''; - - while (next().type !== 'list_end') { - body += tok(); - } - - return '<' - + type - + '>\n' - + body - + '\n'; - } - case 'list_item_start': { - var body = ''; - - while (next().type !== 'list_item_end') { - body += token.type === 'text' - ? parseText() - : tok(); - } - - return '
  • ' - + body - + '
  • \n'; - } - case 'loose_item_start': { - var body = ''; - - while (next().type !== 'list_item_end') { - body += tok(); - } - - return '
  • ' - + body - + '
  • \n'; - } - case 'html': { - return !token.pre && !options.pedantic - ? inline.lexer(token.text) - : token.text; - } - case 'paragraph': { - return '

    ' - + inline.lexer(token.text) - + '

    \n'; - } - case 'text': { - return '

    ' - + parseText() - + '

    \n'; - } - } -} - -function parseText() { - var body = token.text - , top; - - while ((top = tokens[tokens.length-1]) - && top.type === 'text') { - body += '\n' + next().text; - } - - return inline.lexer(body); -} - -function parse(src) { - tokens = src.reverse(); - - var out = ''; - while (next()) { - out += tok(); - } - - tokens = null; - token = null; - - return out; -} - -/** - * Helpers - */ - -function escape(html, encode) { - return html - .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} - -function mangle(text) { - var out = '' - , l = text.length - , i = 0 - , ch; - - for (; i < l; i++) { - ch = text.charCodeAt(i); - if (Math.random() > 0.5) { - ch = 'x' + ch.toString(16); - } - out += '&#' + ch + ';'; - } - - return out; -} - -function tag() { - var 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'; - - return tag; -} - -function replace(regex, opt) { - regex = regex.source; - opt = opt || ''; - return function self(name, val) { - if (!name) return new RegExp(regex, opt); - val = val.source || val; - val = val.replace(/(^|[^\[])\^/g, '$1'); - regex = regex.replace(name, val); - return self; - }; -} - -function noop() {} -noop.exec = noop; - -/** - * Marked - */ - -function marked(src, opt) { - setOptions(opt); - return parse(block.lexer(src)); -} - -/** - * Options - */ - -var options - , defaults; - -function setOptions(opt) { - if (!opt) opt = defaults; - if (options === opt) return; - options = opt; - - if (options.gfm) { - block.fences = block.gfm.fences; - block.paragraph = block.gfm.paragraph; - inline.text = inline.gfm.text; - inline.url = inline.gfm.url; - } else { - block.fences = block.normal.fences; - block.paragraph = block.normal.paragraph; - inline.text = inline.normal.text; - inline.url = inline.normal.url; - } - - if (options.pedantic) { - inline.em = inline.pedantic.em; - inline.strong = inline.pedantic.strong; - } else { - inline.em = inline.normal.em; - inline.strong = inline.normal.strong; - } -} - -marked.options = -marked.setOptions = function(opt) { - defaults = opt; - setOptions(opt); - return marked; -}; - -marked.setOptions({ - gfm: true, - pedantic: false, - sanitize: false, - highlight: null -}); - -/** - * Expose - */ - -marked.parser = function(src, opt) { - setOptions(opt); - return parse(src); -}; - -marked.lexer = function(src, opt) { - setOptions(opt); - return block.lexer(src); -}; - -marked.parse = marked; - -if (typeof module !== 'undefined') { - module.exports = marked; -} else { - this.marked = marked; -} - -}).call(function() { - return this || (typeof window !== 'undefined' ? window : global); -}()); \ No newline at end of file diff --git a/js/profile-w3c-common.js b/js/profile-w3c-common.js index a7b364ff6a..5fdba068c6 100644 --- a/js/profile-w3c-common.js +++ b/js/profile-w3c-common.js @@ -13,6 +13,7 @@ require.config({ "fetch": "/node_modules/whatwg-fetch/fetch", "handlebars": "/node_modules/handlebars/dist/handlebars", "jquery": "/node_modules/jquery/dist/jquery", + "marked": "/node_modules/marked/lib/marked", "Promise": "/node_modules/promise-polyfill/promise", "webidl2": "/node_modules/webidl2/lib/webidl2", }, diff --git a/karma.conf.js b/karma.conf.js index 8c020a546c..ee072be547 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -72,6 +72,11 @@ module.exports = function(config) { included: false, served: true, }, + { + pattern: "./node_modules/marked/lib/marked.js", + included: false, + served: true, + }, "tests/spec/SpecHelper.js", "tests/test-main.js", ], diff --git a/package.json b/package.json index 82ff51aac6..3cb1cab0a6 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "command-line-usage": "^2.0.4", "fs-promise": "^0.5.0", "marcosc-async": "^1.1.3", + "marked": "^0.3.5", "nightmare": "^2.3.3" } } diff --git a/tests/test-main.js b/tests/test-main.js index 5992ccda02..ca3bc6a0f0 100644 --- a/tests/test-main.js +++ b/tests/test-main.js @@ -29,7 +29,8 @@ require.config({ "jquery": "/base/node_modules/jquery/dist/jquery", "core/utils": "js/core/utils", "core/jquery-enhanced": "js/core/jquery-enhanced", - "fetch": "/base/node_modules/whatwg-fetch/fetch" + "fetch": "/base/node_modules/whatwg-fetch/fetch", + "marked": "/base/node_modules/marked/lib/marked.js", }, // dynamically load all test files and other deps deps: allDeps, diff --git a/tools/builder.js b/tools/builder.js index f743495f7b..521f5e06c4 100755 --- a/tools/builder.js +++ b/tools/builder.js @@ -86,6 +86,7 @@ var Builder = { "fetch": "../node_modules/whatwg-fetch/fetch", "handlebars": "../node_modules/handlebars/dist/handlebars", "jquery": "../node_modules/jquery/dist/jquery", + "marked": "../node_modules/marked/lib/marked", "Promise": "../node_modules/promise-polyfill/promise", "requireLib": "../node_modules/requirejs/require", "webidl2": "../node_modules/webidl2/lib/webidl2",