fix(chat): refine markdown typography

This commit is contained in:
2026-07-17 14:33:26 +08:00
parent c7bafda135
commit 9173267e09
6 changed files with 96 additions and 24 deletions

View File

@@ -13,7 +13,15 @@ const markdown = new MarkdownIt({ breaks: true, html: false, linkify: true });
const parsed = computed(() => splitReasoning(props.content));
const answer = computed(() => parsed.value.answer.replace(/^\s+/, ""));
const reasoning = computed(() => props.reasoning || parsed.value.reasoning);
const renderedContent = computed(() => answer.value.trim() ? markdown.render(answer.value) : "");
const renderedContent = computed(() => answer.value.trim() ? markdown.render(normalizeStandaloneHeadings(answer.value)) : "");
function normalizeStandaloneHeadings(content: string) {
return content.replace(/^([ \t]*)\*\*(.+)\*\*[ \t]*$/gm, (line, indent: string, title: string) => {
const normalizedTitle = title.trim();
if (!normalizedTitle || normalizedTitle.length > 48 || normalizedTitle.includes("**")) return line;
return `${indent}### ${normalizedTitle}`;
});
}
function splitReasoning(content: string) {
const lower = content.toLowerCase();

View File

@@ -1384,38 +1384,43 @@ textarea {
overflow-wrap: anywhere;
color: #263832;
font-size: 14px;
line-height: 1.75;
line-height: 1.68;
}
.agent-preview-markdown > :first-child { margin-top: 0; }
.agent-preview-markdown > :last-child { margin-bottom: 0; }
.agent-preview-markdown p { margin: 0 0 10px; }
.agent-preview-markdown p { margin: 0 0 8px; }
.agent-preview-markdown h1,
.agent-preview-markdown h2,
.agent-preview-markdown h3,
.agent-preview-markdown h4 {
margin: 16px 0 8px;
.agent-preview-markdown h4,
.agent-preview-markdown h5,
.agent-preview-markdown h6 {
margin: 13px 0 5px;
color: #1f352e;
line-height: 1.45;
line-height: 1.42;
font-weight: 700;
}
.agent-preview-markdown h1 { font-size: 19px; }
.agent-preview-markdown h1 { font-size: 18px; }
.agent-preview-markdown h2 { font-size: 17px; }
.agent-preview-markdown h3,
.agent-preview-markdown h3 { font-size: 16px; }
.agent-preview-markdown h4 { font-size: 15px; }
.agent-preview-markdown h5,
.agent-preview-markdown h6 { font-size: 14px; }
.agent-preview-markdown ul,
.agent-preview-markdown ol {
margin: 8px 0 10px;
padding-left: 22px;
margin: 6px 0 8px;
padding-left: 21px;
}
.agent-preview-markdown li + li { margin-top: 5px; }
.agent-preview-markdown li + li { margin-top: 3px; }
.agent-preview-markdown strong { color: #1f352e; font-weight: 700; }
.agent-preview-markdown blockquote {
margin: 10px 0;
margin: 8px 0;
padding: 7px 10px;
border-left: 3px solid #8cc7b6;
background: #eef7f4;
@@ -1464,6 +1469,12 @@ textarea {
.agent-preview-markdown a { color: #0f735d; font-weight: 700; }
.agent-preview-markdown hr {
margin: 12px 0;
border: 0;
border-top: 1px solid #dbe7e3;
}
.agent-preview-generation-state {
display: flex;
align-items: center;

View File

@@ -23,9 +23,17 @@ const reasoning = computed(() => props.reasoning || parsed.value.reasoning);
const hasAnswer = computed(() => answer.value.trim().length > 0);
const renderedContent = computed(() => {
if (props.role !== "assistant") return answer.value;
return hasAnswer.value ? markdown.render(answer.value) : "";
return hasAnswer.value ? markdown.render(normalizeStandaloneHeadings(answer.value)) : "";
});
function normalizeStandaloneHeadings(content: string) {
return content.replace(/^([ \t]*)\*\*(.+)\*\*[ \t]*$/gm, (line, indent: string, title: string) => {
const normalizedTitle = title.trim();
if (!normalizedTitle || normalizedTitle.length > 48 || normalizedTitle.includes("**")) return line;
return `${indent}### ${normalizedTitle}`;
});
}
function splitReasoning(content: string) {
const lower = content.toLowerCase();
let answer = "";

View File

@@ -1321,7 +1321,7 @@ textarea:focus-visible {
white-space: pre-wrap;
color: inherit;
font-size: 15px;
line-height: 1.78;
line-height: 1.7;
letter-spacing: 0;
}
@@ -1369,35 +1369,39 @@ textarea:focus-visible {
.markdown-content > :first-child { margin-top: 0; }
.markdown-content > :last-child { margin-bottom: 0; }
.markdown-content p { margin: 0 0 12px; }
.markdown-content p { margin: 0 0 8px; }
.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4 {
margin: 20px 0 9px;
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
margin: 15px 0 6px;
color: var(--chat-text);
line-height: 1.45;
line-height: 1.42;
font-weight: 700;
}
.markdown-content h1 { font-size: 20px; }
.markdown-content h2 { font-size: 18px; }
.markdown-content h3,
.markdown-content h3 { font-size: 17px; }
.markdown-content h4 { font-size: 16px; }
.markdown-content h5,
.markdown-content h6 { font-size: 15px; }
.markdown-content ul,
.markdown-content ol {
margin: 8px 0 13px;
padding-left: 22px;
margin: 6px 0 9px;
padding-left: 21px;
}
.markdown-content li + li { margin-top: 6px; }
.markdown-content li + li { margin-top: 3px; }
.markdown-content strong { color: var(--chat-text); font-weight: 700; }
.markdown-content blockquote {
margin: 12px 0;
padding: 8px 12px;
margin: 9px 0;
padding: 7px 11px;
border-left: 3px solid #8cc7b6;
background: var(--chat-brand-soft);
color: #526b63;
@@ -1405,6 +1409,12 @@ textarea:focus-visible {
.markdown-content blockquote p { margin: 0; }
.markdown-content hr {
margin: 14px 0;
border: 0;
border-top: 1px solid var(--chat-border);
}
.chat-composer {
position: relative;
z-index: 6;