Commit 77ae015b authored by 水玉婷's avatar 水玉婷
Browse files

feat:修改markdown模版渲染机制

parent 30b3eff6
......@@ -87,7 +87,7 @@ export const parseMarkdown = (text: string): string => {
text = text.replace(/^>\s*(.*(?:\n>\s*.*)*)$/gim, (match, content) => {
// 将多行引用内容合并,并用<br>分隔
const lines = content.split(/\n>\s*/);
const processedContent = lines.map(line => line.trim()).join('<br>');
const processedContent = lines.map(line => line.trim()).join('<br/>');
return `<blockquote>${processedContent}</blockquote>`;
});
......@@ -170,35 +170,66 @@ export const parseMarkdown = (text: string): string => {
return `<a href="${url}" ${target}>${text}</a>`;
});
// 处理有序列表(支持列表项中包含图片)
text = text.replace(/^(\d+\.\s+)(.*)$/gim, (match, prefix, content) => {
// 先处理内容中的Markdown格式(包括图片)
const processedContent = parseMarkdown(content);
return `<li>${processedContent}</li>`;
});
text = text.replace(/(<li>.*<\/li>)(?=\s*<li>)/gim, '$1');
text = text.replace(/(<li>.*<\/li>)/gim, '<ol>$1</ol>');
// 处理无序列表(支持列表项中包含图片)
text = text.replace(/^([-*+]\s+)(.*)$/gim, (match, prefix, content) => {
// 先处理内容中的Markdown格式(包括图片)
const processedContent = parseMarkdown(content);
return `<li>${processedContent}</li>`;
});
text = text.replace(/(<li>.*<\/li>)/gim, '<ul>$1</ul>');
// 处理列表的辅助函数
const processLists = (text: string): string => {
const lines = text.split('\n');
let result = '';
let currentListType: 'ol' | 'ul' | null = null;
let listItems: string[] = [];
const flushList = () => {
if (listItems.length > 0 && currentListType) {
result += `<${currentListType}>${listItems.join('')}</${currentListType}>`;
listItems = [];
currentListType = null;
}
};
for (const line of lines) {
const trimmedLine = line.trim();
// 检查有序列表项
const orderedMatch = trimmedLine.match(/^(\d+)\.\s+(.*)$/);
if (orderedMatch) {
if (currentListType !== 'ol') {
flushList();
currentListType = 'ol';
}
const content = parseMarkdown(orderedMatch[2]);
listItems.push(`<li>${content}</li>`);
continue;
}
// 检查无序列表项
const unorderedMatch = trimmedLine.match(/^([-*+])\s+(.*)$/);
if (unorderedMatch) {
if (currentListType !== 'ul') {
flushList();
currentListType = 'ul';
}
const content = parseMarkdown(unorderedMatch[2]);
listItems.push(`<li>${content}</li>`);
continue;
}
// 非列表行
flushList();
result += line + '\n';
}
flushList(); // 处理最后可能存在的列表
return result;
};
// 使用新的列表处理逻辑
text = processLists(text);
// 处理水平分割线
text = text.replace(/^\s*---\s*$/gim, '<hr />');
text = text.replace(/^\s*\*\*\*\s*$/gim, '<hr />');
// 完全删除段落处理逻辑,避免表格被p标签包裹
// 只处理换行,不添加p标签
text = text.replace(/\n{3,}/g, '\n\n'); // 多个换行合并为两个
text = text.replace(/\n\n/g, '<br><br>');
text = text.replace(/\n/g, '<br>');
// 清理HTML结构(移除空行)
text = text.replace(/(<br>\s*)+/g, '<br>');
// 处理换行(保留段落结构)
text = text.replace(/\n\n/g, '<br />');
return text;
};
......@@ -229,25 +260,6 @@ export const markdownTemplate = (content: any, isStreaming: boolean = false): st
// 清理HTML内容:移除不必要的br标签和空p段落
const cleanHtml = htmlContent
.trim()
// 保留blockquote和code块内的换行符,移除其他不必要的br标签
.replace(/<br\s*\/?>/gi, (match, offset, originalString) => {
// 检查当前br标签是否在blockquote或code/pre标签内
const beforeContent = originalString.substring(0, offset);
const afterContent = originalString.substring(offset + match.length);
// 检查前后是否有未闭合的blockquote标签
const openBlockquotesBefore = (beforeContent.match(/<blockquote/g) || []).length;
const closeBlockquotesBefore = (beforeContent.match(/<\/blockquote>/g) || []).length;
const openBlockquotesAfter = (afterContent.match(/<blockquote/g) || []).length;
const closeBlockquotesAfter = (afterContent.match(/<\/blockquote>/g) || []).length;
// 检查是否在code/pre标签内
const isInCodeBlock = beforeContent.includes('<pre>') || beforeContent.includes('<code>');
const isInBlockquote = (openBlockquotesBefore - closeBlockquotesBefore) > 0;
return (isInBlockquote || isInCodeBlock) ? match : '';
})
// 移除空的<p>段落(只包含空格或换行符)
.replace(/<p[^>]*>\s*<\/p>/gi, '')
// 移除只包含空格的<p>段落
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment