| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import MarkdownIt from 'markdown-it';
- import hljs from 'highlight.js';
- import mk from 'markdown-it-katex';
- // 配置 markdown-it
- const md = new MarkdownIt({
- html: true,
- linkify: true,
- typographer: true,
- highlight: function (str, lang) {
- if (lang && hljs.getLanguage(lang)) {
- try {
- return '<pre class="hljs"><code>' +
- hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
- '</code></pre>';
- } catch (__) {}
- }
- return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
- }
- });
- // 添加 LaTeX 数学公式支持
- md.use(mk);
- // 导出渲染函数
- export function renderMarkdown(markdown, container) {
- if (!container) {
- console.error('Markdown container not found');
- return;
- }
- if (!markdown) {
- container.innerHTML = '<p class="text-gray-500">No content</p>';
- return;
- }
- const html = md.render(markdown);
- container.innerHTML = html;
- // 添加样式类
- addMarkdownStyles(container);
- }
- function addMarkdownStyles(container) {
- // 为 markdown 内容添加样式类
- const elements = container.querySelectorAll('h1, h2, h3, h4, h5, h6, p, code, pre, blockquote, ul, ol, li, table, thead, tbody, tr, th, td, a, img');
- elements.forEach(el => {
- // 标题样式
- if (el.tagName.match(/^H[1-6]$/)) {
- el.classList.add('font-bold', 'mt-6', 'mb-4');
- if (el.tagName === 'H1') el.classList.add('text-3xl');
- if (el.tagName === 'H2') el.classList.add('text-2xl');
- if (el.tagName === 'H3') el.classList.add('text-xl');
- if (el.tagName === 'H4') el.classList.add('text-lg');
- }
- // 段落样式
- if (el.tagName === 'P') {
- el.classList.add('mb-4', 'leading-relaxed');
- }
- // 链接样式
- if (el.tagName === 'A') {
- el.classList.add('text-blue-600', 'hover:text-blue-800', 'underline');
- }
- // 代码样式
- if (el.tagName === 'CODE') {
- el.classList.add('bg-gray-100', 'px-2', 'py-1', 'rounded', 'text-sm', 'font-mono');
- }
- // 预格式化代码样式
- if (el.tagName === 'PRE') {
- el.classList.add('bg-gray-900', 'p-4', 'rounded-lg', 'overflow-x-auto', 'mb-4');
- }
- // 块引用样式
- if (el.tagName === 'BLOCKQUOTE') {
- el.classList.add('border-l-4', 'border-blue-500', 'pl-4', 'italic', 'text-gray-600', 'my-4');
- }
- // 表格样式
- if (el.tagName === 'TABLE') {
- el.classList.add('w-full', 'border-collapse', 'mb-4');
- }
- if (el.tagName === 'TH' || el.tagName === 'TD') {
- el.classList.add('border', 'border-gray-300', 'px-4', 'py-2', 'text-left');
- }
- if (el.tagName === 'TH') {
- el.classList.add('bg-gray-100', 'font-semibold');
- }
- // 列表样式
- if (el.tagName === 'UL' || el.tagName === 'OL') {
- el.classList.add('mb-4', 'pl-6');
- }
- if (el.tagName === 'LI') {
- el.classList.add('mb-2');
- }
- // 图片样式
- if (el.tagName === 'IMG') {
- el.classList.add('max-w-full', 'h-auto', 'rounded-lg', 'shadow-md', 'my-4');
- }
- });
- }
- // 导出到全局
- if (typeof window !== 'undefined') {
- window.renderMarkdown = renderMarkdown;
- }
|