204 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			204 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | import { defaults } from './defaults.js'; | ||
|  | import { | ||
|  |   cleanUrl, | ||
|  |   escape | ||
|  | } from './helpers.js'; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Renderer | ||
|  |  */ | ||
|  | export class Renderer { | ||
|  |   constructor(options) { | ||
|  |     this.options = options || defaults; | ||
|  |   } | ||
|  | 
 | ||
|  |   code(code, infostring, escaped) { | ||
|  |     const lang = (infostring || '').match(/\S*/)[0]; | ||
|  |     if (this.options.highlight) { | ||
|  |       const out = this.options.highlight(code, lang); | ||
|  |       if (out != null && out !== code) { | ||
|  |         escaped = true; | ||
|  |         code = out; | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     code = code.replace(/\n$/, '') + '\n'; | ||
|  | 
 | ||
|  |     if (!lang) { | ||
|  |       return '<pre><code>' | ||
|  |         + (escaped ? code : escape(code, true)) | ||
|  |         + '</code></pre>\n'; | ||
|  |     } | ||
|  | 
 | ||
|  |     return '<pre><code class="' | ||
|  |       + this.options.langPrefix | ||
|  |       + escape(lang) | ||
|  |       + '">' | ||
|  |       + (escaped ? code : escape(code, true)) | ||
|  |       + '</code></pre>\n'; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} quote | ||
|  |    */ | ||
|  |   blockquote(quote) { | ||
|  |     return `<blockquote>\n${quote}</blockquote>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   html(html) { | ||
|  |     return html; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    * @param {string} level | ||
|  |    * @param {string} raw | ||
|  |    * @param {any} slugger | ||
|  |    */ | ||
|  |   heading(text, level, raw, slugger) { | ||
|  |     if (this.options.headerIds) { | ||
|  |       const id = this.options.headerPrefix + slugger.slug(raw); | ||
|  |       return `<h${level} id="${id}">${text}</h${level}>\n`; | ||
|  |     } | ||
|  | 
 | ||
|  |     // ignore IDs
 | ||
|  |     return `<h${level}>${text}</h${level}>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   hr() { | ||
|  |     return this.options.xhtml ? '<hr/>\n' : '<hr>\n'; | ||
|  |   } | ||
|  | 
 | ||
|  |   list(body, ordered, start) { | ||
|  |     const type = ordered ? 'ol' : 'ul', | ||
|  |       startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; | ||
|  |     return '<' + type + startatt + '>\n' + body + '</' + type + '>\n'; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   listitem(text) { | ||
|  |     return `<li>${text}</li>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   checkbox(checked) { | ||
|  |     return '<input ' | ||
|  |       + (checked ? 'checked="" ' : '') | ||
|  |       + 'disabled="" type="checkbox"' | ||
|  |       + (this.options.xhtml ? ' /' : '') | ||
|  |       + '> '; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   paragraph(text) { | ||
|  |     return `<p>${text}</p>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} header | ||
|  |    * @param {string} body | ||
|  |    */ | ||
|  |   table(header, body) { | ||
|  |     if (body) body = `<tbody>${body}</tbody>`; | ||
|  | 
 | ||
|  |     return '<table>\n' | ||
|  |       + '<thead>\n' | ||
|  |       + header | ||
|  |       + '</thead>\n' | ||
|  |       + body | ||
|  |       + '</table>\n'; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} content | ||
|  |    */ | ||
|  |   tablerow(content) { | ||
|  |     return `<tr>\n${content}</tr>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   tablecell(content, flags) { | ||
|  |     const type = flags.header ? 'th' : 'td'; | ||
|  |     const tag = flags.align | ||
|  |       ? `<${type} align="${flags.align}">` | ||
|  |       : `<${type}>`; | ||
|  |     return tag + content + `</${type}>\n`; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * span level renderer | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   strong(text) { | ||
|  |     return `<strong>${text}</strong>`; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   em(text) { | ||
|  |     return `<em>${text}</em>`; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   codespan(text) { | ||
|  |     return `<code>${text}</code>`; | ||
|  |   } | ||
|  | 
 | ||
|  |   br() { | ||
|  |     return this.options.xhtml ? '<br/>' : '<br>'; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   del(text) { | ||
|  |     return `<del>${text}</del>`; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} href | ||
|  |    * @param {string} title | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   link(href, title, text) { | ||
|  |     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); | ||
|  |     if (href === null) { | ||
|  |       return text; | ||
|  |     } | ||
|  |     let out = '<a href="' + href + '"'; | ||
|  |     if (title) { | ||
|  |       out += ' title="' + title + '"'; | ||
|  |     } | ||
|  |     out += '>' + text + '</a>'; | ||
|  |     return out; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * @param {string} href | ||
|  |    * @param {string} title | ||
|  |    * @param {string} text | ||
|  |    */ | ||
|  |   image(href, title, text) { | ||
|  |     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); | ||
|  |     if (href === null) { | ||
|  |       return text; | ||
|  |     } | ||
|  | 
 | ||
|  |     let out = `<img src="${href}" alt="${text}"`; | ||
|  |     if (title) { | ||
|  |       out += ` title="${title}"`; | ||
|  |     } | ||
|  |     out += this.options.xhtml ? '/>' : '>'; | ||
|  |     return out; | ||
|  |   } | ||
|  | 
 | ||
|  |   text(text) { | ||
|  |     return text; | ||
|  |   } | ||
|  | } |