Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	| ;(function() { "use strict"; | |
| var | |
| /** | |
| * The parsed output string, in HTML format. | |
| * @type {String} | |
| */ | |
| output = "", | |
| BLOCK = "block", | |
| INLINE = "inline", | |
| /** | |
| * Used to attach MarkdownToHtml object to `window` in browser | |
| * context, or as an AMD module where appropriate. | |
| * @type {Object} | |
| */ | |
| exports, | |
| /** | |
| * An array of parse rule descriptor objects. Each object has two keys; | |
| * pattern (the RegExp to match), and replace (the replacement string or | |
| * function to execute). | |
| * @type {Array} | |
| */ | |
| parseMap = [ | |
| { | |
| // <h1> | |
| // A line starting with 1-6 hashes. | |
| pattern: /(#{1,6})([^\n]+)/g, | |
| replace: "<h$L1>$2</h$L1>", | |
| type: BLOCK, | |
| }, | |
| { | |
| // <p> | |
| // Any line surrounded by newlines that doesn't start with | |
| // an HTML tag, asterisk or numeric value with dot following. | |
| pattern: /\n(?!<\/?\w+>|\s?\*|\s?[0-9]+|>|\>|-{5,})([^\n]+)/g, | |
| replace: "<p>$1</p>", | |
| type: BLOCK, | |
| }, | |
| { | |
| // <blockquote> | |
| // A greater-than character preceding any characters. | |
| pattern: /\n(?:>|\>)\W*(.*)/g, | |
| replace: "<blockquote><p>$1</p></blockquote>", | |
| type: BLOCK, | |
| }, | |
| { | |
| // <ul> | |
| // | |
| pattern: /\n\s?\*\s*(.*)/g, | |
| replace: "<ul>\n\t<li>$1</li>\n</ul>", | |
| type: BLOCK, | |
| }, | |
| { | |
| // <ol> | |
| // | |
| pattern: /\n\s?[0-9]+\.\s*(.*)/g, | |
| replace: "<ol>\n\t<li>$1</li>\n</ol>", | |
| type: BLOCK, | |
| }, | |
| { | |
| // <strong> | |
| // Either two asterisks or two underscores, followed by any | |
| // characters, followed by the same two starting characters. | |
| pattern: /(\*\*|__)(.*?)\1/g, | |
| replace: "<strong>$2</strong>", | |
| type: INLINE, | |
| }, | |
| { | |
| // <em> | |
| // Either one asterisk or one underscore, followed by any | |
| // characters, followed by the starting character. | |
| pattern: /(\*|_)(.*?)\1/g, | |
| replace: "<em>$2</em>", | |
| type: INLINE, | |
| }, | |
| { | |
| // <a> | |
| // Not starting with an exclamation mark, square brackets | |
| // surrounding any characters, followed by parenthesis surrounding | |
| // any characters. | |
| pattern: /([^!])\[([^\[]+)\]\(([^\)]+)\)/g, | |
| replace: "$1<a href=\"$3\">$2</a>", | |
| type: INLINE, | |
| }, | |
| { | |
| // <img> | |
| // Starting with an exclamation mark, then followed by square | |
| // brackets surrounding any characters, followed by parenthesis | |
| // surrounding any characters. | |
| pattern: /!\[([^\[]+)\]\(([^\)]+)\)/g, | |
| replace: "<img src=\"$2\" alt=\"$1\" />", | |
| type: INLINE, | |
| }, | |
| { | |
| // <del> | |
| // Double tilde characters surrounding any characters. | |
| pattern: /\~\~(.*?)\~\~/g, | |
| replace: "<del>$1</del>", | |
| type: INLINE, | |
| }, | |
| { | |
| // <code> | |
| // | |
| pattern: /`(.*?)`/g, | |
| replace: "<code>$1</code>", | |
| type: INLINE, | |
| }, | |
| { | |
| // <hr> | |
| // | |
| pattern: /\n-{5,}\n/g, | |
| replace: "<hr />", | |
| type: BLOCK, | |
| }, | |
| ], | |
| $$; | |
| /** | |
| * Self-executing function to handle exporting the parse function for | |
| * external use. | |
| */ | |
| (function go() { | |
| // Export AMD module if possible. | |
| if(typeof module !== "undefined" | |
| && typeof module.exports !== "undefined") { | |
| exports = module.exports; | |
| } | |
| // Otherwise check for browser context. | |
| else if(typeof window !== "undefined") { | |
| window.MarkdownToHtml = {}; | |
| exports = window.MarkdownToHtml; | |
| } | |
| exports.parse = parse; | |
| })(); | |
| /** | |
| * Parses a provided Markdown string into valid HTML. | |
| * | |
| * @param {string} string Markdown input for transformation | |
| * @return {string} Transformed HTML output | |
| */ | |
| function parse(string) { | |
| // Pad with newlines for compatibility. | |
| output = "\n" + string + "\n"; | |
| parseMap.forEach(function(p) { | |
| // Replace all matches of provided RegExp pattern with either the | |
| // replacement string or callback function. | |
| output = output.replace(p.pattern, function() { | |
| // console.log(this, arguments); | |
| return replace.call(this, arguments, p.replace, p.type); | |
| }); | |
| }); | |
| // Perform any post-processing required. | |
| output = clean(output); | |
| // Trim for any spaces or newlines. | |
| output = output.trim(); | |
| // Tidy up newlines to condense where more than 1 occurs back to back. | |
| output = output.replace(/[\n]{1,}/g, "\n"); | |
| return output; | |
| } | |
| function replace(matchList, replacement, type) { | |
| var | |
| i, | |
| $$; | |
| for(i in matchList) { | |
| if(!matchList.hasOwnProperty(i)) { | |
| continue; | |
| } | |
| // Replace $n with the matching regexp group. | |
| replacement = replacement.split("$" + i).join(matchList[i]); | |
| // Replace $Ln with the matching regexp group's string length. | |
| replacement = replacement.split("$L" + i).join(matchList[i].length); | |
| } | |
| if(type === BLOCK) { | |
| replacement = replacement.trim() + "\n"; | |
| } | |
| return replacement; | |
| } | |
| function clean(string) { | |
| var cleaningRuleArray = [ | |
| { | |
| match: /<\/([uo]l)>\s*<\1>/g, | |
| replacement: "", | |
| }, | |
| { | |
| match: /(<\/\w+>)<\/(blockquote)>\s*<\2>/g, | |
| replacement: "$1", | |
| }, | |
| ]; | |
| cleaningRuleArray.forEach(function(rule) { | |
| string = string.replace(rule.match, rule.replacement); | |
| }); | |
| return string; | |
| } | |
| })(); | 
