function compile(md){ var renderer = new rs.HtmlRenderer(); renderer.blockcode = function(code, lang){ if (!lang) return '<pre><code>' + code + '</code></pre>\n'; if (lang == 'js') lang = 'javascript'; else if (lang == 'html') lang = 'xml'; else if (lang == 'shell') lang = 'bash'; code = hljs.highlight(lang, code).value.trim(); return '<pre><code class="' + lang + '">' + code + '</code></pre>\n'; }; var sidebar = ''; var links = {}; renderer.header = function(text, level){ if (level <= 2){ // handle duplicate headers var link = slug(text); if (links[link]) link += '-' + links[link]++; else links[link] = 1; sidebar += '<a href="#' + link + '"' + (level == 1 ? ' class="top"' : '') + '>' + text + '</a>\n'; text = '<a href="#' + link + '" name="' + link + '">' + text + '</a>'; } return '<h' + level + '>' + text + '</h' + level + '>\n'; }; var parser = new rs.Markdown(renderer, [rs.EXT_FENCED_CODE]); var html = parser.render(md); return {content: html, toc: sidebar}; }
markdown: function(text) { var renderer = new rs.HtmlRenderer([rs.HTML_USE_XHTML]); var parser = new rs.Markdown( renderer, [ rs.EXT_FENCED_CODE, rs.EXT_TABLES, rs.EXT_AUTOLINK, rs.EXT_NO_INTRA_EMPHASIS, rs.EXT_STRIKETHROUGH ] ); return parser.render(text); },
var render = exports.render = function (markdown, withToc, singleColumn) { var title; var lastList; var inTOC = false; var renderer = new Robotskirt.HtmlRenderer(); // Pre-highlight code blocks renderer.blockcode = function (code, language) { var block = '<pre'; if (singleColumn) { block += ' class="single-column"'; } block += '><code>' + Highlight.highlight(language || 'js', code).value + '</code></pre>'; return block; }; // Wrap lists in 'ul' tags, track the last list for TOC if we care renderer.list = function (text) { var list = '<ul>' + text + '</ul>'; if (inTOC && withToc) { lastList = list; } return list; }; // Escape text to make sure we have an anchor link for all headers // TOC is defined as all text between the first H1 and the first H2 // The first H1 is set as the title and removed from the html output renderer.header = function (text, level) { var header = escape(text); if (level === 1) { if (!title) { title = header.clean; return ''; } if (withToc) { inTOC = true; } } else if (level === 2) { if (inTOC && withToc) { inTOC = false; } } return '<h' + level + '><a name="' + header.escaped + '" class="anchor" href="#' + header.escaped + '">' + header.clean + '</a></h' + level + '>'; }; // the markdown lexer var parser = new Robotskirt.Markdown(renderer, [ // allow tables Robotskirt.EXT_TABLES, // automatically turn urls into links Robotskirt.EXT_AUTOLINK, // allow github-style fenced code blocks Robotskirt.EXT_FENCED_CODE, // don't be so strict about whitespace Robotskirt.EXT_LAX_SPACING ]); // pass the lexed data through the parser to generate html var reference = parser.render(markdown); var toc = []; if (withToc) { // parse the html with Cheerio var $ = Cheerio.load(reference); // TOC is the first 'ul' var ul = $('ul').first(); // iterate over all 'a' tags in the first 'ul' $('a', ul).each(function () { var $this = $(this); // we count parents to see how deep in the TOC we are var depth = $this.parents().length; var anchor = escape($this.text()); // blob representing the 'a' tag we're on now var blob = { tag: anchor.escaped, name: anchor.clean, children: [] }; // default to the root of the toc var list = toc; // depth >= 4 means we're at least one level deep if (depth >= 4) { list = toc[toc.length - 1].children; } // go another level deeper if (depth >= 6) { list = list[list.length - 1].children; } // and one last level if (depth === 8) { list = list[list.length - 1].children; } // append the blob list.push(blob); }); // remove the TOC ul.remove(); // and set reference back to the raw html reference = $.html(); } return { toc: toc, html: reference, title: title }; };
/* * GET home page. */ var rs = require('robotskirt'); var parser = rs.Markdown.std(); var data = { "posts" : [ {"text":"i _am_ using *markdown*. Cool link [Bool.se](http://www.bool.se)"}, {"text":"2i am using __markdown__."} ] }; var findAll = function(callback) { var posts = []; data.posts.forEach(function (post, i) { posts.push({ text: parser.render(post.text) }); }); callback( null, posts ); }; exports.index = function(req, res){ res.render('index', { title: 'Express' }); }; exports.blog = function(req, res){ findAll(function (error, posts){