import { Component, Prop, State, Watch, h } from '@stencil/core';
import { marked } from 'marked';
@Component({
tag: 'internal-markdown-renderer',
styleUrl: 'markdown-renderer.css',
shadow: true
})
export class InternalMarkdownRenderer {
@Prop() content: string = '';
@Prop() enableTables: boolean = true;
@Prop() enableTaskLists: boolean = true;
@Prop() enableFootnotes: boolean = true;
@Prop() highlightCode: boolean = true;
@State() private renderedHtml: string = '';
async componentWillLoad() {
await this.renderMarkdown();
}
@Watch('content')
async contentChanged() {
await this.renderMarkdown();
}
private async renderMarkdown() {
if (!this.content) {
this.renderedHtml = '';
return;
}
try {
// 配置 marked
marked.setOptions({
breaks: true,
gfm: true,
});
// 自定义渲染器
const renderer = new marked.Renderer();
// 链接渲染
renderer.link = (token) => {
const href = token.href;
const title = token.title ? ` title="${token.title}"` : '';
return `${token.text}`;
};
// 图片渲染
renderer.image = (token) => {
const src = token.href;
const alt = token.text;
const title = token.title ? ` title="${token.title}"` : '';
return ``;
};
// 代码渲染
renderer.code = (token) => {
const code = token.text;
const lang = token.lang || '';
const className = lang ? `language-${lang}` : '';
return `
${code}`;
};
// 表格渲染
if (this.enableTables) {
renderer.table = (token) => {
let html = '| ${cell} | `; }); html += '
|---|
| ${cell} | `; }); html += '