Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
水玉婷
ai-wechat
Commits
77ae015b
Commit
77ae015b
authored
Jan 23, 2026
by
水玉婷
Browse files
feat:修改markdown模版渲染机制
parent
30b3eff6
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/views/components/utils/markdownTemplate.ts
View file @
77ae015b
...
...
@@ -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>段落
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment