UNPKG

@discoveryjs/discovery

Version:

Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards

100 lines (99 loc) 3.7 kB
import { Renderer } from "marked"; import { slug as generateSlug } from "github-slugger"; import { escapeHtml } from "../../core/utils/html.js"; export class CustomMarkedRenderer extends Renderer { heading({ tokens, depth, text }) { const { discoveryjs: { host, useAnchors } } = this.options; const slug = generateSlug(text.replace(/<!--.*?-->/g, "")); let anchor = ""; if (useAnchors) { const href = host.encodePageHash( host.pageId, host.pageRef, host.pageParams, slug ); anchor = `<a class="view-header__anchor" id="!anchor:${escapeHtml(slug)}" href="${href}"></a>`; } return `<h${depth} class="view-header view-h${depth}" data-slug="${slug}">${anchor}${this.parser.parseInline(tokens)}</h${depth}> `; } blockquote({ tokens }) { let body = this.parser.parse(tokens); let kind = null; const kindMatch = body.match(/^(<p>)?\[!([a-z]+)\]\n/i); if (kindMatch) { kind = kindMatch[2]; body = (kindMatch[1] || "") + body.slice(kindMatch[0].length); } return `<blockquote class="view-blockquote"${kind ? ` data-kind=${JSON.stringify(kind.toLowerCase())}` : ""}>${body}</blockquote>`; } code({ text: source, lang: syntax }) { const { discoveryjs: { codes } } = this.options; const id = codes.push({ syntax, source }) - 1; return `<code class="discoveryjs-code" data-id="${id}"></code>`; } link({ tokens, href, title }) { const text = this.parser.parseInline(tokens); if (href === null) { return text; } let out = '<a class="view-link md-rendered-link" href="' + escapeHtml(href) + '"'; if (title) { out += ' title="' + escapeHtml(title) + '"'; } out += ">" + text + "</a>"; return out; } checkbox({ checked }) { return '<label class="view-checkbox"><input type="checkbox" disabled' + (checked ? " checked" : "") + "/></label> "; } list({ items, ordered, start }) { const tag = ordered ? "ol" : "ul"; const startAttr = ordered && start !== 1 ? ` start="${start}"` : ""; return `<${tag} class="view-${tag}"${startAttr}> ` + items.map(this.listitem, this).join("\n") + ` </${tag}> `; } listitem(token) { let prefix = ""; if (token.task) { const checkbox = this.checkbox({ checked: Boolean(token.checked) }); if (token.loose) { const firstToken = token.tokens[0]; if (firstToken?.type === "paragraph") { firstToken.text = checkbox + firstToken.text; if (Array.isArray(firstToken.tokens) && firstToken.tokens[0]?.type === "text") { firstToken.tokens[0].text = checkbox + firstToken.tokens[0].text; } } else { token.tokens.unshift({ type: "text", raw: checkbox, text: checkbox }); } } else { prefix += checkbox; } } return `<li class="view-list-item${token.task ? " check-list-item" : ""}">${prefix}${this.parser.parse(token.tokens, Boolean(token.loose))}</li> `; } table({ header, rows }) { const body = rows.map( (row) => '<tr class="view-table-row">' + row.map(this.tablecell, this).join("") + "</tr>" ).join("\n"); return '<table class="view-table">\n<thead>\n' + header.map(this.tablecell, this).join("") + "\n</thead>\n" + (body ? "<tbody>\n" + body + "\n</tbody>\n" : "") + "</table>\n"; } tablecell({ tokens, header, align }) { const type = header ? "th" : "td"; const className = header ? "view-table-header-cell" : "view-table-cell"; return `<${type} class="${className}"${align ? ` align="${align}"` : ""}>` + this.parser.parseInline(tokens) + `</${type}> `; } }