Renderer.js (3414B)
1 const { defaults } = require('./defaults.js'); 2 const { 3 cleanUrl, 4 escape 5 } = require('./helpers.js'); 6 7 /** 8 * Renderer 9 */ 10 module.exports = class Renderer { 11 constructor(options) { 12 this.options = options || defaults; 13 } 14 15 code(code, infostring, escaped) { 16 const lang = (infostring || '').match(/\S*/)[0]; 17 if (this.options.highlight) { 18 const out = this.options.highlight(code, lang); 19 if (out != null && out !== code) { 20 escaped = true; 21 code = out; 22 } 23 } 24 25 if (!lang) { 26 return '<pre><code>' 27 + (escaped ? code : escape(code, true)) 28 + '</code></pre>\n'; 29 } 30 31 return '<pre><code class="' 32 + this.options.langPrefix 33 + escape(lang, true) 34 + '">' 35 + (escaped ? code : escape(code, true)) 36 + '</code></pre>\n'; 37 } 38 39 blockquote(quote) { 40 return '<blockquote>\n' + quote + '</blockquote>\n'; 41 } 42 43 html(html) { 44 return html; 45 } 46 47 heading(text, level, raw, slugger) { 48 if (this.options.headerIds) { 49 return '<h' 50 + level 51 + ' id="' 52 + this.options.headerPrefix 53 + slugger.slug(raw) 54 + '">' 55 + text 56 + '</h' 57 + level 58 + '>\n'; 59 } 60 // ignore IDs 61 return '<h' + level + '>' + text + '</h' + level + '>\n'; 62 } 63 64 hr() { 65 return this.options.xhtml ? '<hr/>\n' : '<hr>\n'; 66 } 67 68 list(body, ordered, start) { 69 const type = ordered ? 'ol' : 'ul', 70 startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; 71 return '<' + type + startatt + '>\n' + body + '</' + type + '>\n'; 72 } 73 74 listitem(text) { 75 return '<li>' + text + '</li>\n'; 76 } 77 78 checkbox(checked) { 79 return '<input ' 80 + (checked ? 'checked="" ' : '') 81 + 'disabled="" type="checkbox"' 82 + (this.options.xhtml ? ' /' : '') 83 + '> '; 84 } 85 86 paragraph(text) { 87 return '<p>' + text + '</p>\n'; 88 } 89 90 table(header, body) { 91 if (body) body = '<tbody>' + body + '</tbody>'; 92 93 return '<table>\n' 94 + '<thead>\n' 95 + header 96 + '</thead>\n' 97 + body 98 + '</table>\n'; 99 } 100 101 tablerow(content) { 102 return '<tr>\n' + content + '</tr>\n'; 103 } 104 105 tablecell(content, flags) { 106 const type = flags.header ? 'th' : 'td'; 107 const tag = flags.align 108 ? '<' + type + ' align="' + flags.align + '">' 109 : '<' + type + '>'; 110 return tag + content + '</' + type + '>\n'; 111 } 112 113 // span level renderer 114 strong(text) { 115 return '<strong>' + text + '</strong>'; 116 } 117 118 em(text) { 119 return '<em>' + text + '</em>'; 120 } 121 122 codespan(text) { 123 return '<code>' + text + '</code>'; 124 } 125 126 br() { 127 return this.options.xhtml ? '<br/>' : '<br>'; 128 } 129 130 del(text) { 131 return '<del>' + text + '</del>'; 132 } 133 134 link(href, title, text) { 135 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); 136 if (href === null) { 137 return text; 138 } 139 let out = '<a href="' + escape(href) + '"'; 140 if (title) { 141 out += ' title="' + title + '"'; 142 } 143 out += '>' + text + '</a>'; 144 return out; 145 } 146 147 image(href, title, text) { 148 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); 149 if (href === null) { 150 return text; 151 } 152 153 let out = '<img src="' + href + '" alt="' + text + '"'; 154 if (title) { 155 out += ' title="' + title + '"'; 156 } 157 out += this.options.xhtml ? '/>' : '>'; 158 return out; 159 } 160 161 text(text) { 162 return text; 163 } 164 };