diff options
author | zhixin <wenzhixin2010@gmail.com> | 2014-04-28 09:22:03 +0800 |
---|---|---|
committer | zhixin <wenzhixin2010@gmail.com> | 2014-04-28 09:22:03 +0800 |
commit | e7a7ca5326fc42f5f5fdf9c2cbc76ba7855f9296 (patch) | |
tree | 614270e4734b3c754defb0f3ae9a000da80bd648 /docs/assets/flatdoc/flatdoc.js | |
parent | 40072b9ab3f9bf7f0d5c4b469a95a823f5563cf4 (diff) | |
download | multiple-select-e7a7ca5326fc42f5f5fdf9c2cbc76ba7855f9296.zip multiple-select-e7a7ca5326fc42f5f5fdf9c2cbc76ba7855f9296.tar.gz multiple-select-e7a7ca5326fc42f5f5fdf9c2cbc76ba7855f9296.tar.bz2 |
Add docs.
Diffstat (limited to 'docs/assets/flatdoc/flatdoc.js')
-rw-r--r-- | docs/assets/flatdoc/flatdoc.js | 1734 |
1 files changed, 1734 insertions, 0 deletions
diff --git a/docs/assets/flatdoc/flatdoc.js b/docs/assets/flatdoc/flatdoc.js new file mode 100644 index 0000000..734accd --- /dev/null +++ b/docs/assets/flatdoc/flatdoc.js @@ -0,0 +1,1734 @@ +/*! +Flatdoc (http://ricostacruz.com/flatdoc) +(c) 2013 Rico Sta. Cruz. MIT licensed. + +Also includes: + + marked + a markdown parser + (c) 2011-2013, Christopher Jeffrey. (MIT Licensed) + https://github.com/chjj/marked + + base64.js + http://github.com/dankogai/js-base64 + +*/ + +(function($) { + var exports = this; + + var marked; + + /** + * Basic Flatdoc module. + * + * The main entry point is `Flatdoc.run()`, which invokes the [Runner]. + * + * Flatdoc.run({ + * fetcher: Flatdoc.github('rstacruz/backbone-patterns'); + * }); + */ + + var Flatdoc = exports.Flatdoc = {}; + + /** + * Creates a runner. + * See [Flatdoc]. + */ + + Flatdoc.run = function(options) { + $(function() { (new Flatdoc.runner(options)).run(); }); + }; + + /** + * File fetcher function. + * + * Fetches a given `url` via AJAX. + * See [Runner#run()] for a description of fetcher functions. + */ + + Flatdoc.file = function(url) { + return function(callback) { + $.get(url) + .fail(function(e) { callback(e, null); }) + .done(function(data) { callback(null, data); }); + }; + }; + + /** + * Github fetcher. + * Fetches from repo `repo` (in format 'user/repo'). + * + * If the parameter `filepath` is supplied, it fetches the contents of that + * given file in the repo. + * + * See [Runner#run()] for a description of fetcher functions. + * + * See: http://developer.github.com/v3/repos/contents/ + */ + Flatdoc.github = function(repo, filepath) { + var url; + if (filepath) { + url = 'https://api.github.com/repos/'+repo+'/contents/'+filepath; + } else { + url = 'https://api.github.com/repos/'+repo+'/readme'; + } + return function(callback) { + $.get(url) + .fail(function(e) { callback(e, null); }) + .done(function(data) { + var markdown = exports.Base64.decode(data.content); + callback(null, markdown); + }); + }; + }; + + /** + * Parser module. + * Parses a given Markdown document and returns a JSON object with data + * on the Markdown document. + * + * var data = Flatdoc.parser.parse('markdown source here'); + * console.log(data); + * + * data == { + * title: 'My Project', + * content: '<p>This project is a...', + * menu: {...} + * } + */ + + var Parser = Flatdoc.parser = {}; + + /** + * Parses a given Markdown document. + * See `Parser` for more info. + */ + Parser.parse = function(source) { + marked = exports.marked; + + Parser.setMarkedOptions(); + + var html = $("<div>" + marked(source)); + var h1 = html.find('h1').eq(0); + var title = h1.text(); + + // Mangle content + Transformer.mangle(html); + var menu = Transformer.getMenu(html); + + return { title: title, content: html, menu: menu }; + }; + + Parser.setMarkedOptions = function() { + marked.setOptions({ + highlight: function(code, lang) { + if (lang) { + var fn = Flatdoc.highlighters[lang] || Flatdoc.highlighters.generic; + return fn(code); + } + return code; + } + }); + }; + + /** + * Transformer module. + * This takes care of any HTML mangling needed. The main entry point is + * `.mangle()` which applies all transformations needed. + * + * var $content = $("<p>Hello there, this is a docu..."); + * Flatdoc.transformer.mangle($content); + * + * If you would like to change any of the transformations, decorate any of + * the functions in `Flatdoc.transformer`. + */ + + var Transformer = Flatdoc.transformer = {}; + + /** + * Takes a given HTML `$content` and improves the markup of it by executing + * the transformations. + * + * > See: [Transformer](#transformer) + */ + Transformer.mangle = function($content) { + this.addIDs($content); + this.buttonize($content); + this.smartquotes($content); + }; + + /** + * Adds IDs to headings. + */ + + Transformer.addIDs = function($content) { + $content.find('h1, h2, h3').each(function() { + var $el = $(this); + var text = $el.text(); + var id = slugify(text); + $el.attr('id', id); + }); + }; + + /** + * Returns menu data for a given HTML. + * + * menu = Flatdoc.transformer.getMenu($content); + * menu == { + * level: 0, + * items: [{ + * section: "Getting started", + * level: 1, + * items: [...]}, ...]} + */ + + Transformer.getMenu = function($content) { + var root = {items: [], id: '', level: 0}; + var cache = [root]; + + function mkdir_p(level) { + var parent = (level > 1) ? mkdir_p(level-1) : root; + if (!cache[level]) { + var obj = { items: [], level: level }; + cache[level] = obj; + parent.items.push(obj); + return obj; + } + return cache[level]; + } + + $content.find('h1, h2, h3').each(function() { + var $el = $(this); + var level = +(this.nodeName.substr(1)); + + var parent = mkdir_p(level-1); + + var obj = { section: $el.text(), items: [], level: level, id: $el.attr('id') }; + parent.items.push(obj); + cache[level] = obj; + }); + + return root; + }; + + /** + * Changes "button >" text to buttons. + */ + + Transformer.buttonize = function($content) { + $content.find('a').each(function() { + var $a = $(this); + + var m = $a.text().match(/^(.*) >$/); + if (m) $a.text(m[1]).addClass('button'); + }); + }; + + /** + * Applies smart quotes to a given element. + * It leaves `code` and `pre` blocks alone. + */ + + Transformer.smartquotes = function ($content) { + var nodes = getTextNodesIn($content), len = nodes.length; + for (var i=0; i<len; i++) { + var node = nodes[i]; + node.nodeValue = quotify(node.nodeValue); + } + }; + + /** + * Syntax highlighters. + * + * You may add or change more highlighters via the `Flatdoc.highlighters` + * object. + * + * Flatdoc.highlighters.js = function(code) { + * }; + * + * Each of these functions + */ + + var Highlighters = Flatdoc.highlighters = {}; + + /** + * JavaScript syntax highlighter. + * + * Thanks @visionmedia! + */ + + Highlighters.js = Highlighters.javascript = function(code) { + return code + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/("[^\"]*?")/g, '<span class="string">$1</span>') + .replace(/('[^\']*?')/g, '<span class="string">$1</span>') + .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>') + .replace(/\/\*(.*)\*\//gm, '<span class="comment">/*$1*/</span>') + .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>') + .replace(/(\d+)/gm, '<span class="number">$1</span>') + .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>'); + }; + + Highlighters.html = function(code) { + return code + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/("[^\"]*?")/g, '<span class="string">$1</span>') + .replace(/('[^\']*?')/g, '<span class="string">$1</span>') + .replace(/<!--(.*)-->/g, '<span class="comment"><!--$1--></span>') + .replace(/<([^!][^ ]*)/g, '<<span class="keyword">$1</span>'); + }; + + Highlighters.generic = function(code) { + return code + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/("[^\"]*?")/g, '<span class="string">$1</span>') + .replace(/('[^\']*?')/g, '<span class="string">$1</span>') + .replace(/(\/\/|#)(.*)/gm, '<span class="comment">$1$2</span>') + .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>') + .replace(/(\d+)/gm, '<span class="number">$1</span>'); + }; + + /** + * Menu view. Renders menus + */ + + var MenuView = Flatdoc.menuView = function(menu) { + var $el = $("<ul>"); + + function process(node, $parent) { + var id = node.id || 'root'; + + var $li = $('<li>') + .attr('id', id + '-item') + .addClass('level-' + node.level) + .appendTo($parent); + + if (node.section) { + var $a = $('<a>') + .html(node.section) + .attr('id', id + '-link') + .attr('href', '#' + node.id) + .addClass('level-' + node.level) + .appendTo($li); + } + + if (node.items.length > 0) { + var $ul = $('<ul>') + .addClass('level-' + (node.level+1)) + .attr('id', id + '-list') + .appendTo($li); + + node.items.forEach(function(item) { + process(item, $ul); + }); + } + } + + process(menu, $el); + return $el; + }; + + /** + * A runner module that fetches via a `fetcher` function. + * + * var runner = new Flatdoc.runner({ + * fetcher: Flatdoc.url('readme.txt') + * }); + * runner.run(); + * + * The following options are available: + * + * - `fetcher` - a function that takes a callback as an argument and + * executes that callback when data is returned. + * + * See: [Flatdoc.run()] + */ + + var Runner = Flatdoc.runner = function(options) { + this.initialize(options); + }; + + Runner.prototype.root = '[role~="flatdoc"]'; + Runner.prototype.menu = '[role~="flatdoc-menu"]'; + Runner.prototype.title = '[role~="flatdoc-title"]'; + Runner.prototype.content = '[role~="flatdoc-content"]'; + + Runner.prototype.initialize = function(options) { + $.extend(this, options); + }; + + /** + * Loads the Markdown document (via the fetcher), parses it, and applies it + * to the elements. + */ + + Runner.prototype.run = function() { + var doc = this; + $(doc.root).trigger('flatdoc:loading'); + doc.fetcher(function(err, markdown) { + if (err) { + console.error('[Flatdoc] fetching Markdown data failed.', err); + return; + } + var data = Flatdoc.parser.parse(markdown); + doc.applyData(data, doc); + $(doc.root).trigger('flatdoc:ready'); + }); + }; + + /** + * Applies given doc data `data` to elements in object `elements`. + */ + + Runner.prototype.applyData = function(data) { + var elements = this; + + elements.el('title').html(data.title); + elements.el('content').html(data.content.find('>*')); + elements.el('menu').html(MenuView(data.menu)); + }; + + /** + * Fetches a given element from the DOM. + * + * Returns a jQuery object. + * @api private + */ + + Runner.prototype.el = function(aspect) { + return $(this[aspect], this.root); + }; + + /* + * Helpers + */ + + // http://stackoverflow.com/questions/298750/how-do-i-select-text-nodes-with-jquery + function getTextNodesIn(el) { + var exclude = 'iframe,pre,code'; + return $(el).find(':not('+exclude+')').andSelf().contents().filter(function() { + return this.nodeType == 3 && $(this).closest(exclude).length === 0; + }); + } + + // http://www.leancrew.com/all-this/2010/11/smart-quotes-in-javascript/ + function quotify(a) { + a = a.replace(/(^|[\-\u2014\s(\["])'/g, "$1\u2018"); // opening singles + a = a.replace(/'/g, "\u2019"); // closing singles & apostrophes + a = a.replace(/(^|[\-\u2014\/\[(\u2018\s])"/g, "$1\u201c"); // opening doubles + a = a.replace(/"/g, "\u201d"); // closing doubles + a = a.replace(/\.\.\./g, "\u2026"); // ellipses + a = a.replace(/--/g, "\u2014"); // em-dashes + return a; + } + + function slugify(text) { + return text.toLowerCase().match(/[a-z0-9]+/g).join('-'); + } +})(jQuery); +/*! + * marked - a markdown parser + * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed) + * https://github.com/chjj/marked + */ + +;(function() { + +/** + * Block-Level Grammar + */ + +var block = { + newline: /^\n+/, + code: /^( {4}[^\n]+\n*)+/, + fences: noop, + hr: /^( *[-*_]){3,} *(?:\n+|$)/, + heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, + nptable: noop, + lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, + blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/, + list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, + html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, + def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, + table: noop, + 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._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'; + +block.html = replace(block.html) + ('comment', /<!--[\s\S]*?-->/) + ('closed', /<(tag)[\s\S]+?<\/\1>/) + ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/) + (/tag/g, block._tag) + (); + +block.paragraph = replace(block.paragraph) + ('hr', block.hr) + ('heading', block.heading) + ('lheading', block.lheading) + ('blockquote', block.blockquote) + ('tag', '<' + block._tag) + ('def', block.def) + (); + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, + paragraph: /^/ +}); + +block.gfm.paragraph = replace(block.paragraph) + ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') + (); + +/** + * GFM + Tables Block Grammar + */ + +block.tables = merge({}, block.gfm, { + nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, + table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ +}); + +/** + * Block Lexer + */ + +function Lexer(options) { + this.tokens = []; + this.tokens.links = {}; + this.options = options || marked.defaults; + this.rules = block.normal; + + if (this.options.gfm) { + if (this.options.tables) { + this.rules = block.tables; + } else { + this.rules = block.gfm; + } + } +} + +/** + * Expose Block Rules + */ + +Lexer.rules = block; + +/** + * Static Lex Method + */ + +Lexer.lex = function(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); +}; + +/** + * Preprocessing + */ + +Lexer.prototype.lex = function(src) { + src = src + .replace(/\r\n|\r/g, '\n') + .replace(/\t/g, ' ') + .replace(/\u00a0/g, ' ') + .replace(/\u2424/g, '\n'); + + return this.token(src, true); +}; + +/** + * Lexing + */ + +Lexer.prototype.token = function(src, top) { + var src = src.replace(/^ +$/gm, '') + , next + , loose + , cap + , bull + , b + , item + , space + , i + , l; + + while (src) { + // newline + if (cap = this.rules.newline.exec(src)) { + src = src.substring(cap[0].length); + if (cap[0].length > 1) { + this.tokens.push({ + type: 'space' + }); + } + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + cap = cap[0].replace(/^ {4}/gm, ''); + this.tokens.push({ + type: 'code', + text: !this.options.pedantic + ? cap.replace(/\n+$/, '') + : cap + }); + continue; + } + + // fences (gfm) + if (cap = this.rules.fences.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'code', + lang: cap[2], + text: cap[3] + }); + continue; + } + + // heading + if (cap = this.rules.heading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[1].length, + text: cap[2] + }); + continue; + } + + // table no leading pipe (gfm) + if (top && (cap = this.rules.nptable.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i].split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // lheading + if (cap = this.rules.lheading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[2] === '=' ? 1 : 2, + text: cap[1] + }); + continue; + } + + // hr + if (cap = this.rules.hr.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'hr' + }); + continue; + } + + // blockquote + if (cap = this.rules.blockquote.exec(src)) { + src = src.substring(cap[0].length); + + this.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. + this.token(cap, top); + + this.tokens.push({ + type: 'blockquote_end' + }); + + continue; + } + + // list + if (cap = this.rules.list.exec(src)) { + src = src.substring(cap[0].length); + bull = cap[2]; + + this.tokens.push({ + type: 'list_start', + ordered: bull.length > 1 + }); + + // Get each top-level item. + cap = cap[0].match(this.rules.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 = !this.options.pedantic + ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') + : item.replace(/^ {1,4}/gm, ''); + } + + // Determine whether the next list item belongs here. + // Backpedal if it does not belong in this list. + if (this.options.smartLists && i !== l - 1) { + b = block.bullet.exec(cap[i+1])[0]; + if (bull !== b && !(bull.length > 1 && b.length > 1)) { + src = cap.slice(i + 1).join('\n') + src; + i = l - 1; + } + } + + // 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; + } + + this.tokens.push({ + type: loose + ? 'loose_item_start' + : 'list_item_start' + }); + + // Recurse. + this.token(item, false); + + this.tokens.push({ + type: 'list_item_end' + }); + } + + this.tokens.push({ + type: 'list_end' + }); + + continue; + } + + // html + if (cap = this.rules.html.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: this.options.sanitize + ? 'paragraph' + : 'html', + pre: cap[1] === 'pre' || cap[1] === 'script', + text: cap[0] + }); + continue; + } + + // def + if (top && (cap = this.rules.def.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.links[cap[1].toLowerCase()] = { + href: cap[2], + title: cap[3] + }; + continue; + } + + // table (gfm) + if (top && (cap = this.rules.table.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/^ *\| *| *\| *$/g, '') + .split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // top-level paragraph + if (top && (cap = this.rules.paragraph.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'paragraph', + text: cap[1][cap[1].length-1] === '\n' + ? cap[1].slice(0, -1) + : cap[1] + }); + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + // Top-level should never reach here. + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'text', + text: cap[0] + }); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return this.tokens; +}; + +/** + * Inline-Level Grammar + */ + +var inline = { + escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, + autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, + url: noop, + tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, + link: /^!?\[(inside)\]\(href\)/, + reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, + nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, + strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, + em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, + code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, + br: /^ {2,}\n(?!\s*$)/, + del: noop, + text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/ +}; + +inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/; +inline._href = /\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/; + +inline.link = replace(inline.link) + ('inside', inline._inside) + ('href', inline._href) + (); + +inline.reflink = replace(inline.reflink) + ('inside', inline._inside) + (); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: replace(inline.escape)('])', '~|])')(), + url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, + del: /^~~(?=\S)([\s\S]*?\S)~~/, + text: replace(inline.text) + (']|', '~]|') + ('|', '|https?://|') + () +}); + +/** + * GFM + Line Breaks Inline Grammar + */ + +inline.breaks = merge({}, inline.gfm, { + br: replace(inline.br)('{2,}', '*')(), + text: replace(inline.gfm.text)('{2,}', '*')() +}); + +/** + * Inline Lexer & Compiler + */ + +function InlineLexer(links, options) { + this.options = options || marked.defaults; + this.links = links; + this.rules = inline.normal; + + if (!this.links) { + throw new + Error('Tokens array requires a `links` property.'); + } + + if (this.options.gfm) { + if (this.options.breaks) { + this.rules = inline.breaks; + } else { + this.rules = inline.gfm; + } + } else if (this.options.pedantic) { + this.rules = inline.pedantic; + } +} + +/** + * Expose Inline Rules + */ + +InlineLexer.rules = inline; + +/** + * Static Lexing/Compiling Method + */ + +InlineLexer.output = function(src, links, options) { + var inline = new InlineLexer(links, options); + return inline.output(src); +}; + +/** + * Lexing/Compiling + */ + +InlineLexer.prototype.output = function(src) { + var out = '' + , link + , text + , href + , cap; + + while (src) { + // escape + if (cap = this.rules.escape.exec(src)) { + src = src.substring(cap[0].length); + out += cap[1]; + continue; + } + + // autolink + if (cap = this.rules.autolink.exec(src)) { + src = src.substring(cap[0].length); + if (cap[2] === '@') { + text = cap[1][6] === ':' + ? this.mangle(cap[1].substring(7)) + : this.mangle(cap[1]); + href = this.mangle('mailto:') + text; + } else { + text = escape(cap[1]); + href = text; + } + out += '<a href="' + + href + + '">' + + text + + '</a>'; + continue; + } + + // url (gfm) + if (cap = this.rules.url.exec(src)) { + src = src.substring(cap[0].length); + text = escape(cap[1]); + href = text; + out += '<a href="' + + href + + '">' + + text + + '</a>'; + continue; + } + + // tag + if (cap = this.rules.tag.exec(src)) { + src = src.substring(cap[0].length); + out += this.options.sanitize + ? escape(cap[0]) + : cap[0]; + continue; + } + + // link + if (cap = this.rules.link.exec(src)) { + src = src.substring(cap[0].length); + out += this.outputLink(cap, { + href: cap[2], + title: cap[3] + }); + continue; + } + + // reflink, nolink + if ((cap = this.rules.reflink.exec(src)) + || (cap = this.rules.nolink.exec(src))) { + src = src.substring(cap[0].length); + link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = this.links[link.toLowerCase()]; + if (!link || !link.href) { + out += cap[0][0]; + src = cap[0].substring(1) + src; + continue; + } + out += this.outputLink(cap, link); + continue; + } + + // strong + if (cap = this.rules.strong.exec(src)) { + src = src.substring(cap[0].length); + out += '<strong>' + + this.output(cap[2] || cap[1]) + + '</strong>'; + continue; + } + + // em + if (cap = this.rules.em.exec(src)) { + src = src.substring(cap[0].length); + out += '<em>' + + this.output(cap[2] || cap[1]) + + '</em>'; + continue; + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + out += '<code>' + + escape(cap[2], true) + + '</code>'; + continue; + } + + // br + if (cap = this.rules.br.exec(src)) { + src = src.substring(cap[0].length); + out += '<br>'; + continue; + } + + // del (gfm) + if (cap = this.rules.del.exec(src)) { + src = src.substring(cap[0].length); + out += '<del>' + + this.output(cap[1]) + + '</del>'; + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + src = src.substring(cap[0].length); + out += escape(cap[0]); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return out; +}; + +/** + * Compile Link + */ + +InlineLexer.prototype.outputLink = function(cap, link) { + if (cap[0][0] !== '!') { + return '<a href="' + + escape(link.href) + + '"' + + (link.title + ? ' title="' + + escape(link.title) + + '"' + : '') + + '>' + + this.output(cap[1]) + + '</a>'; + } else { + return '<img src="' + + escape(link.href) + + '" alt="' + + escape(cap[1]) + + '"' + + (link.title + ? ' title="' + + escape(link.title) + + '"' + : '') + + '>'; + } +}; + +/** + * Smartypants Transformations + */ + +InlineLexer.prototype.smartypants = function(text) { + if (!this.options.smartypants) return text; + return text + .replace(/--/g, '—') + .replace(/'([^']*)'/g, '‘$1’') + .replace(/"([^"]*)"/g, '“$1”') + .replace(/\.{3}/g, '…'); +}; + +/** + * Mangle Links + */ + +InlineLexer.prototype.mangle = function(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; +}; + +/** + * Parsing & Compiling + */ + +function Parser(options) { + this.tokens = []; + this.token = null; + this.options = options || marked.defaults; +} + +/** + * Static Parse Method + */ + +Parser.parse = function(src, options) { + var parser = new Parser(options); + return parser.parse(src); +}; + +/** + * Parse Loop + */ + +Parser.prototype.parse = function(src) { + this.inline = new InlineLexer(src.links, this.options); + this.tokens = src.reverse(); + + var out = ''; + while (this.next()) { + out += this.tok(); + } + + return out; +}; + +/** + * Next Token + */ + +Parser.prototype.next = function() { + return this.token = this.tokens.pop(); +}; + +/** + * Preview Next Token + */ + +Parser.prototype.peek = function() { + return this.tokens[this.tokens.length-1] || 0; +}; + +/** + * Parse Text Tokens + */ + +Parser.prototype.parseText = function() { + var body = this.token.text; + + while (this.peek().type === 'text') { + body += '\n' + this.next().text; + } + + return this.inline.output(body); +}; + +/** + * Parse Current Token + */ + +Parser.prototype.tok = function() { + switch (this.token.type) { + case 'space': { + return ''; + } + case 'hr': { + return '<hr>\n'; + } + case 'heading': { + return '<h' + + this.token.depth + + '>' + + this.inline.output(this.token.text) + + '</h' + + this.token.depth + + '>\n'; + } + case 'code': { + if (this.options.highlight) { + var code = this.options.highlight(this.token.text, this.token.lang); + if (code != null && code !== this.token.text) { + this.token.escaped = true; + this.token.text = code; + } + } + + if (!this.token.escaped) { + this.token.text = escape(this.token.text, true); + } + + return '<pre><code' + + (this.token.lang + ? ' class="' + + this.options.langPrefix + + this.token.lang + + '"' + : '') + + '>' + + this.token.text + + '</code></pre>\n'; + } + case 'table': { + var body = '' + , heading + , i + , row + , cell + , j; + + // header + body += '<thead>\n<tr>\n'; + for (i = 0; i < this.token.header.length; i++) { + heading = this.inline.output(this.token.header[i]); + body += this.token.align[i] + ? '<th align="' + this.token.align[i] + '">' + heading + '</th>\n' + : '<th>' + heading + '</th>\n'; + } + body += '</tr>\n</thead>\n'; + + // body + body += '<tbody>\n' + for (i = 0; i < this.token.cells.length; i++) { + row = this.token.cells[i]; + body += '<tr>\n'; + for (j = 0; j < row.length; j++) { + cell = this.inline.output(row[j]); + body += this.token.align[j] + ? '<td align="' + this.token.align[j] + '">' + cell + '</td>\n' + : '<td>' + cell + '</td>\n'; + } + body += '</tr>\n'; + } + body += '</tbody>\n'; + + return '<table>\n' + + body + + '</table>\n'; + } + case 'blockquote_start': { + var body = ''; + + while (this.next().type !== 'blockquote_end') { + body += this.tok(); + } + + return '<blockquote>\n' + + body + + '</blockquote>\n'; + } + case 'list_start': { + var type = this.token.ordered ? 'ol' : 'ul' + , body = ''; + + while (this.next().type !== 'list_end') { + body += this.tok(); + } + + return '<' + + type + + '>\n' + + body + + '</' + + type + + '>\n'; + } + case 'list_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.token.type === 'text' + ? this.parseText() + : this.tok(); + } + + return '<li>' + + body + + '</li>\n'; + } + case 'loose_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.tok(); + } + + return '<li>' + + body + + '</li>\n'; + } + case 'html': { + return !this.token.pre && !this.options.pedantic + ? this.inline.output(this.token.text) + : this.token.text; + } + case 'paragraph': { + return '<p>' + + this.inline.output(this.token.text) + + '</p>\n'; + } + case 'text': { + return '<p>' + + this.parseText() + + '</p>\n'; + } + } +}; + +/** + * Helpers + */ + +function escape(html, encode) { + return html + .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +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; + +function merge(obj) { + var i = 1 + , target + , key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} + +/** + * Marked + */ + +function marked(src, opt, callback) { + if (callback || typeof opt === 'function') { + if (!callback) { + callback = opt; + opt = null; + } + + if (opt) opt = merge({}, marked.defaults, opt); + + var tokens = Lexer.lex(tokens, opt) + , highlight = opt.highlight + , pending = 0 + , l = tokens.length + , i = 0; + + if (!highlight || highlight.length < 3) { + return callback(null, Parser.parse(tokens, opt)); + } + + var done = function() { + delete opt.highlight; + var out = Parser.parse(tokens, opt); + opt.highlight = highlight; + return callback(null, out); + }; + + for (; i < l; i++) { + (function(token) { + if (token.type !== 'code') return; + pending++; + return highlight(token.text, token.lang, function(err, code) { + if (code == null || code === token.text) { + return --pending || done(); + } + token.text = code; + token.escaped = true; + --pending || done(); + }); + })(tokens[i]); + } + + return; + } + try { + if (opt) opt = merge({}, marked.defaults, opt); + return Parser.parse(Lexer.lex(src, opt), opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/chjj/marked.'; + if ((opt || marked.defaults).silent) { + return '<p>An error occured:</p><pre>' + + escape(e.message + '', true) + + '</pre>'; + } + throw e; + } +} + +/** + * Options + */ + +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + return marked; +}; + +marked.defaults = { + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + smartLists: false, + silent: false, + highlight: null, + langPrefix: 'lang-' +}; + +/** + * Expose + */ + +marked.Parser = Parser; +marked.parser = Parser.parse; + +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; + +marked.InlineLexer = InlineLexer; +marked.inlineLexer = InlineLexer.output; + +marked.parse = marked; + +if (typeof exports === 'object') { + module.exports = marked; +} else if (typeof define === 'function' && define.amd) { + define(function() { return marked; }); +} else { + this.marked = marked; +} + +}).call(function() { + return this || (typeof window !== 'undefined' ? window : global); +}()); +/*! + * $Id: base64.js,v 2.12 2013/05/06 07:54:20 dankogai Exp dankogai $ + * + * Licensed under the MIT license. + * http://opensource.org/licenses/mit-license + * + * References: + * http://en.wikipedia.org/wiki/Base64 + */ + +(function(global) { + 'use strict'; + if (global.Base64) return; + var version = "2.1.2"; + // if node.js, we use Buffer + var buffer; + if (typeof module !== 'undefined' && module.exports) { + buffer = require('buffer').Buffer; + } + // constants + var b64chars + = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + var b64tab = function(bin) { + var t = {}; + for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i; + return t; + }(b64chars); + var fromCharCode = String.fromCharCode; + // encoder stuff + var cb_utob = function(c) { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + + fromCharCode(0x80 | (cc & 0x3f))) + : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | ( cc & 0x3f))); + } else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | ( cc & 0x3f))); + } + }; + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; + var utob = function(u) { + return u.replace(re_utob, cb_utob); + }; + var cb_encode = function(ccc) { + var padlen = [0, 2, 1][ccc.length % 3], + ord = ccc.charCodeAt(0) << 16 + | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) + | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)), + chars = [ + b64chars.charAt( ord >>> 18), + b64chars.charAt((ord >>> 12) & 63), + padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63), + padlen >= 1 ? '=' : b64chars.charAt(ord & 63) + ]; + return chars.join(''); + }; + var btoa = global.btoa || function(b) { + return b.replace(/[\s\S]{1,3}/g, cb_encode); + }; + var _encode = buffer + ? function (u) { return (new buffer(u)).toString('base64') } + : function (u) { return btoa(utob(u)) } + ; + var encode = function(u, urisafe) { + return !urisafe + ? _encode(u) + : _encode(u).replace(/[+\/]/g, function(m0) { + return m0 == '+' ? '-' : '_'; + }).replace(/=/g, ''); + }; + var encodeURI = function(u) { return encode(u, true) }; + // decoder stuff + var re_btou = new RegExp([ + '[\xC0-\xDF][\x80-\xBF]', + '[\xE0-\xEF][\x80-\xBF]{2}', + '[\xF0-\xF7][\x80-\xBF]{3}' + ].join('|'), 'g'); + var cb_btou = function(cccc) { + switch(cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), + offset = cp - 0x10000; + return (fromCharCode((offset >>> 10) + 0xD800) + + fromCharCode((offset & 0x3FF) + 0xDC00)); + case 3: + return fromCharCode( + ((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2)) + ); + default: + return fromCharCode( + ((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1)) + ); + } + }; + var btou = function(b) { + return b.replace(re_btou, cb_btou); + }; + var cb_decode = function(cccc) { + var len = cccc.length, + padlen = len % 4, + n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0) + | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0) + | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0) + | (len > 3 ? b64tab[cccc.charAt(3)] : 0), + chars = [ + fromCharCode( n >>> 16), + fromCharCode((n >>> 8) & 0xff), + fromCharCode( n & 0xff) + ]; + chars.length -= [0, 0, 2, 1][padlen]; + return chars.join(''); + }; + var atob = global.atob || function(a){ + return a.replace(/[\s\S]{1,4}/g, cb_decode); + }; + var _decode = buffer + ? function(a) { return (new buffer(a, 'base64')).toString() } + : function(a) { return btou(atob(a)) }; + var decode = function(a){ + return _decode( + a.replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' }) + .replace(/[^A-Za-z0-9\+\/]/g, '') + ); + }; + // export Base64 + global.Base64 = { + VERSION: version, + atob: atob, + btoa: btoa, + fromBase64: decode, + toBase64: encode, + utob: utob, + encode: encode, + encodeURI: encodeURI, + btou: btou, + decode: decode + }; + // if ES5 is available, make Base64.extendString() available + if (typeof Object.defineProperty === 'function') { + var noEnum = function(v){ + return {value:v,enumerable:false,writable:true,configurable:true}; + }; + global.Base64.extendString = function () { + Object.defineProperty( + String.prototype, 'fromBase64', noEnum(function () { + return decode(this) + })); + Object.defineProperty( + String.prototype, 'toBase64', noEnum(function (urisafe) { + return encode(this, urisafe) + })); + Object.defineProperty( + String.prototype, 'toBase64URI', noEnum(function () { + return encode(this, true) + })); + }; + } + // that's it! +})(this);
\ No newline at end of file |