import { _defaults } from './defaults.ts'; import { cleanUrl, escape, } from './helpers.ts'; import { other } from './rules.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; import type { Tokens } from './Tokens.ts'; import type { _Parser } from './Parser.ts'; /** * Renderer */ export class _Renderer { options: MarkedOptions; parser!: _Parser; // set by the parser constructor(options?: MarkedOptions) { this.options = options || _defaults; } space(token: Tokens.Space): string { return ''; } code({ text, lang, escaped }: Tokens.Code): string { const langString = (lang || '').match(other.notSpaceStart)?.[0]; const code = text.replace(other.endingNewline, '') + '\n'; if (!langString) { return '
'
        + (escaped ? code : escape(code, true))
        + '
\n'; } return '
'
      + (escaped ? code : escape(code, true))
      + '
\n'; } blockquote({ tokens }: Tokens.Blockquote): string { const body = this.parser.parse(tokens); return `
\n${body}
\n`; } html({ text }: Tokens.HTML | Tokens.Tag) : string { return text; } heading({ tokens, depth }: Tokens.Heading): string { return `${this.parser.parseInline(tokens)}\n`; } hr(token: Tokens.Hr): string { return '
\n'; } list(token: Tokens.List): string { const ordered = token.ordered; const start = token.start; let body = ''; for (let j = 0; j < token.items.length; j++) { const item = token.items[j]; body += this.listitem(item); } const type = ordered ? 'ol' : 'ul'; const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : ''; return '<' + type + startAttr + '>\n' + body + '\n'; } listitem(item: Tokens.ListItem): string { let itemBody = ''; if (item.task) { const checkbox = this.checkbox({ checked: !!item.checked }); if (item.loose) { if (item.tokens[0]?.type === 'paragraph') { item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text); item.tokens[0].tokens[0].escaped = true; } } else { item.tokens.unshift({ type: 'text', raw: checkbox + ' ', text: checkbox + ' ', escaped: true, }); } } else { itemBody += checkbox + ' '; } } itemBody += this.parser.parse(item.tokens, !!item.loose); return `
  • ${itemBody}
  • \n`; } checkbox({ checked }: Tokens.Checkbox): string { return ''; } paragraph({ tokens }: Tokens.Paragraph): string { return `

    ${this.parser.parseInline(tokens)}

    \n`; } table(token: Tokens.Table): string { let header = ''; // header let cell = ''; for (let j = 0; j < token.header.length; j++) { cell += this.tablecell(token.header[j]); } header += this.tablerow({ text: cell }); let body = ''; for (let j = 0; j < token.rows.length; j++) { const row = token.rows[j]; cell = ''; for (let k = 0; k < row.length; k++) { cell += this.tablecell(row[k]); } body += this.tablerow({ text: cell }); } if (body) body = `${body}`; return '\n' + '\n' + header + '\n' + body + '
    \n'; } tablerow({ text }: Tokens.TableRow): string { return `\n${text}\n`; } tablecell(token: Tokens.TableCell): string { const content = this.parser.parseInline(token.tokens); const type = token.header ? 'th' : 'td'; const tag = token.align ? `<${type} align="${token.align}">` : `<${type}>`; return tag + content + `\n`; } /** * span level renderer */ strong({ tokens }: Tokens.Strong): string { return `${this.parser.parseInline(tokens)}`; } em({ tokens }: Tokens.Em): string { return `${this.parser.parseInline(tokens)}`; } codespan({ text }: Tokens.Codespan): string { return `${escape(text, true)}`; } br(token: Tokens.Br): string { return '
    '; } del({ tokens }: Tokens.Del): string { return `${this.parser.parseInline(tokens)}`; } link({ href, title, tokens }: Tokens.Link): string { const text = this.parser.parseInline(tokens); const cleanHref = cleanUrl(href); if (cleanHref === null) { return text; } href = cleanHref; let out = ''; return out; } image({ href, title, text, tokens }: Tokens.Image): string { if (tokens) { text = this.parser.parseInline(tokens, this.parser.textRenderer); } const cleanHref = cleanUrl(href); if (cleanHref === null) { return escape(text); } href = cleanHref; let out = `