Skip to content

Commit

Permalink
Added a live page for the project
Browse files Browse the repository at this point in the history
  • Loading branch information
Chalarangelo committed Mar 24, 2017
1 parent 69ff2a5 commit a99c30a
Showing 1 changed file with 164 additions and 0 deletions.
164 changes: 164 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v2.1.0/dist/mini-default.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<title>Parse-MD.js</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="description" content="A regular expression Markdown parser, written in functional Javascript."/>
<meta name="author" content="Angelos Chalaris (chalarangelo)"/>
<meta property="og:title" content="Parse-MD.js"/>
<meta property="og:type" content="website"/>
<meta property="og:description" content="A regular expression Markdown parser, written in functional Javascript."/>
</head>

<body>
<div class="row">
<div class="col-sm col-lg-10 col-lg-offset-1">
<br />
<h1 style="text-align: center; font-size: 3.5em;">Parse-MD.js<small style="font-size: 33%;">Regex-based Markdown parser in functional JS</small></h1>
<br/>
<p style="text-align: center;"><a href="https://github.com/Chalarangelo/parse-md-js" class="button primary large"><i class="fa fa-github fa-2x"></i><span style="font-size: 150%;">&nbsp;Github</span></a></p>
<br />
<div class="card fluid">
<div class="section double-padded"><h2>Introduction &amp; Usage</h2></div>
<div class="section double-padded"><p><strong>Parse-MD.js</strong> is a really simple tool that converts Markdown to HTML. It's built using regular expressions in combination with functional Javascript. It's really tiny (about 100 lines of code) and can be easily extended by adding more regular expressions. Most major Markdown syntax features are supported (with the exception of tables, that are a little bit tricky to implement using regular expressions). To check the recognized syntax rules, have a look at the <a href="https://github.com/Chalarangelo/parse-md-js/blob/master/README.md">README</a>.</p></div>
<div class="section double-padded"><p>To use the parser, just grab the javascript code from <a href="https://github.com/Chalarangelo/parse-md-js/blob/master/parsemd.js">here</a> and simply call</p><pre>var parsedMD = parseMarkdown(yourMarkdownVar);</pre><p>for the parser to parse the contents of <code>yourMarkdownVar</code> into <code>parsedMD</code> as HTML.</p></div>
</div>
</div>
<div class="col-sm col-lg-10 col-lg-offset-1">
<div class="card fluid">
<div class="section double-padded"><h2>Convert some Markdown!</h2></div>
<div class="section double-padded"><p>Actions speak louder than words, right? Well, let's see it at work thne! Enter some valid Markdown text in the input field below, then press the button below it to convert it to HTML instantly!</p></div>
<textarea id="markdownIn" style="height: 200px;" class="section media double-padded" autocomplete="off"># Sample heading

This is a sample paragraph with a [link](https://github.com/Chalarangelo/parse-md-js) and some `inline code`.

---

Maybe you would like to see some **bold text** or some *italics*, huh?</textarea>
<div class="tabs stacked hidden" id="markdownOutCollapseWrapper">
<input type="checkbox" id="markdownOutCollapse" aria-hidden="true" checked autocomplete="off">
<label for="markdownOutCollapse" aria-hidden="true">Show/hide results</label>
<div id="markdownOut">
</div>
</div>
<button class="section primary large" onClick="document.getElementById('markdownOutCollapseWrapper').className='tabs stacked'; document.getElementById('markdownOut').innerHTML = parseMarkdown(document.getElementById('markdownIn').value);">Convert</button>
</div>
<br/><br/><br />
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm col-lg-10 col-lg-offset-1">
<p>Made with <i class="fa fa-heart-o" aria-hidden="true"></i> by Angelos Chalaris, licensed under the <a href="https://github.com/Chalarangelo/parse-md-js/blob/master/LICENSE">MIT license</a>.</p>
</div>
</div>
</div>
</footer>

<script>
/*** Regex Markdown Parser by chalarangelo ***/
// Replaces 'regex' with 'replacement' in 'str'
// Curry function, usage: replaceRegex(regexVar, replacementVar) (strVar)
const replaceRegex = function(regex, replacement){
return function(str){
return str.replace(regex, replacement);
}
}
// Regular expressions for Markdown (a bit strict, but they work)
const codeBlockRegex = /((\n\t)(.*))+/g;
const inlineCodeRegex = /(`)(.*?)\1/g;
const imageRegex = /!\[([^\[]+)\]\(([^\)]+)\)/g;
const linkRegex = /\[([^\[]+)\]\(([^\)]+)\)/g;
const headingRegex = /\n(#+\s*)(.*)/g;
const boldItalicsRegex = /(\*{1,2})(.*?)\1/g;
const strikethroughRegex = /(\~\~)(.*?)\1/g;
const blockquoteRegex = /\n(&gt;|\>)(.*)/g;
const horizontalRuleRegex = /\n((\-{3,})|(={3,}))/g;
const unorderedListRegex = /(\n\s*(\-|\+)\s.*)+/g;
const orderedListRegex = /(\n\s*([0-9]+\.)\s.*)+/g;
const paragraphRegex = /\n+(?!<pre>)(?!<h)(?!<ul>)(?!<blockquote)(?!<hr)(?!\t)([^\n]+)\n/g;
// Replacer functions for Markdown
const codeBlockReplacer = function(fullMatch){
return '\n<pre>' + fullMatch + '</pre>';
}
const inlineCodeReplacer = function(fullMatch, tagStart, tagContents){
return '<code>' + tagContents + '</code>';
}
const imageReplacer = function(fullMatch, tagTitle, tagURL){
return '<img src="' + tagURL + '" alt="' + tagTitle + '" />';
}
const linkReplacer = function(fullMatch, tagTitle, tagURL){
return '<a href="' + tagURL + '">' + tagTitle + '</a>';
}
const headingReplacer = function(fullMatch, tagStart, tagContents){
return '\n<h' + tagStart.trim().length + '>' + tagContents + '</h' + tagStart.trim().length + '>';
}
const boldItalicsReplacer = function(fullMatch, tagStart, tagContents){
return '<' + ( (tagStart.trim().length==1)?('em'):('strong') ) + '>'+ tagContents + '</' + ( (tagStart.trim().length==1)?('em'):('strong') ) + '>';
}
const strikethroughReplacer = function(fullMatch, tagStart, tagContents){
return '<del>' + tagContents + '</del>';
}
const blockquoteReplacer = function(fullMatch, tagStart, tagContents){
return '\n<blockquote>' + tagContents + '</blockquote>';
}
const horizontalRuleReplacer = function(fullMatch){
return '\n<hr />';
}
const unorderedListReplacer = function(fullMatch){
let items = '';
fullMatch.trim().split('\n').forEach( item => { items += '<li>' + item.substring(2) + '</li>'; } );
return '\n<ul>' + items + '</ul>';
}
const orderedListReplacer = function(fullMatch){
let items = '';
fullMatch.trim().split('\n').forEach( item => { items += '<li>' + item.substring(item.indexOf('.')+2) + '</li>'; } );
return '\n<ol>' + items + '</ol>';
}
const paragraphReplacer = function(fullMatch, tagContents){
return '<p>' + tagContents + '</p>';
}
// Rules for Markdown parsing (use in order of appearance for best results)
const replaceCodeBlocks = replaceRegex(codeBlockRegex, codeBlockReplacer);
const replaceInlineCodes = replaceRegex(inlineCodeRegex, inlineCodeReplacer);
const replaceImages = replaceRegex(imageRegex, imageReplacer);
const replaceLinks = replaceRegex(linkRegex, linkReplacer);
const replaceHeadings = replaceRegex(headingRegex, headingReplacer);
const replaceBoldItalics = replaceRegex(boldItalicsRegex, boldItalicsReplacer);
const replaceceStrikethrough = replaceRegex(strikethroughRegex, strikethroughReplacer);
const replaceBlockquotes = replaceRegex(blockquoteRegex, blockquoteReplacer);
const replaceHorizontalRules = replaceRegex(horizontalRuleRegex, horizontalRuleReplacer);
const replaceUnorderedLists = replaceRegex(unorderedListRegex, unorderedListReplacer);
const replaceOrderedLists = replaceRegex(orderedListRegex, orderedListReplacer);
const replaceParagraphs = replaceRegex(paragraphRegex, paragraphReplacer);
// Fix for tab-indexed code blocks
const codeBlockFixRegex = /\n(<pre>)((\n|.)*)(<\/pre>)/g;
const codeBlockFixer = function(fullMatch, tagStart, tagContents, lastMatch, tagEnd){
let lines = '';
tagContents.split('\n').forEach( line => { lines += line.substring(1) + '\n'; } );
return tagStart + lines + tagEnd;
}
const fixCodeBlocks = replaceRegex(codeBlockFixRegex, codeBlockFixer);
// Replacement rule order function for Markdown
// Do not use as-is, prefer parseMarkdown as seen below
const replaceMarkdown = function(str) {
return replaceParagraphs(replaceOrderedLists(replaceUnorderedLists(
replaceHorizontalRules(replaceBlockquotes(replaceceStrikethrough(
replaceBoldItalics(replaceHeadings(replaceLinks(replaceImages(
replaceInlineCodes(replaceCodeBlocks(str))
))))
)))
)));
}
// Parser for Markdown (fixes code, adds empty lines around for parsing)
// Usage: parseMarkdown(strVar)
const parseMarkdown = function(str) {
return fixCodeBlocks(replaceMarkdown('\n' + str + '\n')).trim();
}

</script>
</body>

0 comments on commit a99c30a

Please sign in to comment.