Skip to content

Instantly share code, notes, and snippets.

@barretts
Last active August 7, 2020 11:52
Embed
What would you like to do?
Remarkable JS Markdown parser plugin tutorial
/**
* Created by Barrett Sonntag barretts@github on 3/2/2015.
* http://www.sosuke.com/writing-custom-extensions-for-the-remarkable-javascript-markdown-parser
*
* A plugin tutorial for Remarkable https://github.com/jonschlinkert/remarkable
*/
var markdownParser = new Remarkable();
// open links in new windows
markdownParser.renderer.rules.link_open = (function() {
var original = markdownParser.renderer.rules.link_open;
return function() {
var link = original.apply(this, arguments);
return link.substring(0, link.length - 1) + ' target="_blank">';
};
})();
// add images to lightbox
markdownParser.renderer.rules.image = (function() {
var original = markdownParser.renderer.rules.image;
return function(tokens, idx) {
var href = Remarkable.utils.escapeHtml(tokens[idx].src);
var imgOutput = original.apply(this, arguments);
var anchorStart = '<a href="'+href+'" data-lightbox="markdown">';
return anchorStart + imgOutput + "</a>";
};
})();
// create a custom plugin matching :!:
var parse = function(state) {
// I get my character hex codes from the console using
// "0x"+"[".charCodeAt(0).toString(16).toUpperCase()
var pos = state.pos;
var marker = state.src.charCodeAt(state.pos);
// Our pos starts at 0, so we are looking for :!:
// marker starts with the character at 0
// Given state.src :!:
// We are here: ^
if (marker !== 0x3A/* : */) {
return false;
}
pos++;
marker = state.src.charCodeAt(pos);
// Given state.src :!:
// We are here: ^
if (marker !== 0x21/* ! */) {
return false;
}
pos++;
marker = state.src.charCodeAt(pos);
// Given state.src :!:
// We are here: ^
if (marker !== 0x3A/* : */) {
return false;
}
state.pos = pos+1;
if (state.pos > state.posMax) {
state.pos = state.posMax;
}
// Having matched all three characters we add a token to the state list
var token = {
type: "bangSmiley",
level: state.level,
content: marker
};
state.push(token);
return true;
};
var render = function(tokens, idx, options) {
var smileyString = '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Binette-typo.png/200px-Binette-typo.png" alt="" width="20" height="20"';
smileyString += options.xhtmlOut ? '/>' : '>';
return smileyString;
};
var bangSmiley = function(md) {
md.inline.ruler.push('bangSmiley', parse);
md.renderer.rules.bangSmiley = render;
};
markdownParser.use(bangSmiley);
/*
Markdown:
----------
[new window](http://github.com)
![lightbox](https://assets-cdn.github.com/images/icons/emoji/unicode/1f44d.png)
:!:
Renderered:
----------
<p><a href="http://github.com" target="_blank">new window</a>
</p>
<p>
<a href="https://assets-cdn.github.com/images/icons/emoji/unicode/1f44d.png" data-lightbox="markdown"><img src="https://assets-cdn.github.com/images/icons/emoji/unicode/1f44d.png" alt="lightbox">
</a>
</p>
<p><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Binette-typo.png/200px-Binette-typo.png" alt="" width="20" height="20">
</p>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment