204 lines
3.9 KiB
JavaScript
204 lines
3.9 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, true)
|
||
|
+ '">'
|
||
|
+ (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="' + escape(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;
|
||
|
}
|
||
|
}
|