// Helper function to produce an HTML tag. var tag = function(name, attribs, selfclosing) { var result = '<' + name; if (attribs) { var i = 0; var attrib; while ((attrib = attribs[i]) !== undefined) { result = result.concat(' ', attrib[0], '="', attrib[1], '"'); i++; } } if (selfclosing) result += ' /'; result += '>'; return result; }; var renderNodes = function(block) { var attrs; var info_words; var tagname; var walker = block.walker(); var event, node, entering; var buffer = []; var disableTags = 0; var grandparent; var out = function(s) { if (disableTags > 0) { buffer.push(s.replace(/\<[^>]*\>/g, '')); } else { buffer.push(s); } } var esc = this.escape; var cr = function() { if (buffer.length > 0 && buffer[buffer.length - 1] !== '\n') { out('\n'); } } while (event = walker.next()) { entering = event.entering; node = event.node; switch (node.t) { case 'Text': out(esc(node.c)); break; case 'Softbreak': out(this.softbreak); break; case 'Hardbreak': out(tag('br', [], true)); cr(); break; case 'Emph': out(tag(entering ? 'em' : '/em')); break; case 'Strong': out(tag(entering ? 'strong' : '/strong')); break; case 'Emph': out(tag(entering ? 'strong' : '/strong')); break; case 'Html': out(node.c); break; case 'Link': if (entering) { attrs = [['href', esc(node.destination, true)]]; if (node.title) { attrs.push(['title', esc(node.title, true)]); } out(tag('a', attrs)); } else { out(tag('/a')); } break; case 'Image': if (entering) { if (disableTags == 0) { out('');
                }
                disableTags += 1;
            } else {
                disableTags -= 1;
                if (disableTags == 0) {
                    if (node.title) {
                        out(''); } } break; case 'Code': out(tag('code') + esc(node.c) + tag('/code')); break; case 'Document': break; case 'Paragraph': grandparent = node.parent.parent; if (grandparent !== null && grandparent.t === 'List') { if (grandparent.tight) break; } if (entering) { cr(); out(tag('p')); } else { out(tag('/p')); cr(); } break; case 'BlockQuote': if (entering) { cr(); out(tag('blockquote')); cr(); } else { cr(); out(tag('/blockquote')); cr(); } break; case 'ListItem': if (entering) { out(tag('li')); } else { out(tag('/li')); cr(); } break; case 'List': tagname = node.list_data.type === 'Bullet' ? 'ul' : 'ol'; if (entering) { attr = (!node.list_data.start || node.list_data.start === 1) ? [] : [['start', node.list_data.start.toString()]]; cr(); out(tag(tagname, attr)); cr(); } else { cr(); out(tag('/' + tagname)); cr(); } break; case 'Header': tagname = 'h' + node.level; if (entering) { cr(); out(tag(tagname)); } else { out(tag('/' + tagname)); cr(); } break; case 'CodeBlock': info_words = node.info ? node.info.split(/ +/) : []; attr = (info_words.length === 0 || info_words[0].length === 0) ? [] : [['class', 'language-' + esc(info_words[0], true)]]; cr(); out(tag('pre') + tag('code', attr)); out(this.escape(node.string_content)); out(tag('/code') + tag('/pre')); cr(); break; case 'HtmlBlock': cr(); out(node.string_content); cr(); break; case 'HorizontalRule': cr(); out(tag('hr', [], true)); cr(); break; case 'ReferenceDef': break; default: console.log("Unknown node type " + node.t); } } return buffer.join(''); }; // The HtmlRenderer object. function HtmlRenderer(){ return { // default options: blocksep: '\n', // space between blocks innersep: '\n', // space between block container tag and contents softbreak: '\n', // by default, soft breaks are rendered as newlines in HTML // set to "
" to make them hard breaks // set to " " if you want to ignore line wrapping in source escape: function(s, preserve_entities) { if (preserve_entities) { return s.replace(/[&](?![#](x[a-f0-9]{1,8}|[0-9]{1,8});|[a-z][a-z0-9]{1,31};)/gi, '&') .replace(/[<]/g, '<') .replace(/[>]/g, '>') .replace(/["]/g, '"'); } else { return s.replace(/[&]/g,'&') .replace(/[<]/g, '<') .replace(/[>]/g, '>') .replace(/["]/g, '"'); } }, render: renderNodes }; } module.exports = HtmlRenderer;