From 1777d308f050cc4fddd1f835e483eaf17071241f Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Fri, 9 Jan 2015 11:02:10 -0800 Subject: Rename js/lib/html-renderer.js -> js/lib/html.js. --- js/lib/html.js | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 js/lib/html.js (limited to 'js/lib/html.js') diff --git a/js/lib/html.js b/js/lib/html.js new file mode 100644 index 0000000..e7953cf --- /dev/null +++ b/js/lib/html.js @@ -0,0 +1,239 @@ +// 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; -- cgit v1.2.3