From 5def2697de57cdeab706ff28855c8be62f40a473 Mon Sep 17 00:00:00 2001
From: QihuAI Design ${c} `
- ).join('');
- const tbody = bodyRows.map((r: string[]) =>
- '' + r.map((c: string, i: number) =>
- ` '
- ).join('');
- const html = `${c} `
- ).join('') + '
`;
- const idx = tableBlocks.length;
- tableBlocks.push(html);
- return '\x00TABLE' + idx + '\x00';
- }
- );
+ // 2.6 Normalize excessive blank lines in prose (code blocks already extracted)
+ text = text.replace(/\n{3,}/g, '\n\n').trim();
// 2.8 LaTeX 数学公式:$$...$$(块级)和 $...$(行内)
// 提取为占位符,渲染后用 KaTeX 处理
@@ -273,15 +240,58 @@ const MarkdownContent: React.FC<{ content: string }> = ({ content }) => {
text = text.replace(/\*\*(.+?)\*\*/g, '$1');
text = text.replace(/(?$1');
+ // 7.5 Extract Markdown tables after inline formatting so cells support bold/italic/links.
+ // 表格提取放在加粗/链接之后,避免单元格内 **xxx** 原样显示;同时压缩单元格内多余 ${thead} ${tbody}
。
+ const tableBlocks: string[] = [];
+ text = text.replace(
+ /((?:^\|.+\|\r?\n)+^\|[\s\-:|]+\|\r?\n(?:^\|.+\|\r?\n?)+)/gm,
+ (_m: string, block: string) => {
+ const lines = block.trim().split(/\r?\n/).filter((l: string) => l.trim());
+ if (lines.length < 2) return block;
+ const headerCells = lines[0].split('|').slice(1, -1).map((c: string) => c.trim());
+ const alignCells = lines[1].split('|').slice(1, -1).map((c: string) => {
+ const t = c.trim();
+ const left = t.startsWith(':');
+ const right = t.endsWith(':');
+ if (left && right) return 'center';
+ if (right) return 'right';
+ if (left) return 'left';
+ return 'left';
+ });
+ const normalizeCell = (cell: string) => {
+ return cell
+ .replace(/
\s*/gi, '
')
+ .replace(/\n/g, '
')
+ .replace(/(
){2,}/g, '
')
+ .replace(/^(
)+|(
)+$/g, '');
+ };
+ const bodyRows = lines.slice(2).map((row: string) =>
+ row.split('|').slice(1, -1).map((c: string) => normalizeCell(c.trim()))
+ );
+ const thead = headerCells.map((c: string, i: number) =>
+ `${normalizeCell(c)} `
+ ).join('');
+ const tbody = bodyRows.map((r: string[]) =>
+ '' + r.map((c: string, i: number) =>
+ ` '
+ ).join('');
+ const html = `${c} `
+ ).join('') + '
`;
+ const idx = tableBlocks.length;
+ tableBlocks.push(html);
+ return '\x00TABLE' + idx + '\x00';
+ }
+ );
+
// 8. Lists
text = text.replace(/^\s*[-*] (.+)$/gm, '${thead} ${tbody}
text = text.replace(/((?:
$1
');
- // 9. Convert double newlines to paragraph breaks, single to
+ // 9. Convert double newlines to paragraph breaks, single newlines to spaces
text = text.replace(/\n\n/g, '
');
- text = text.replace(/\n/g, '
');
+ text = text.replace(/\n/g, ' ');
// 10. Restore code blocks and inline codes
text = text.replace(/\x00CODEBLOCK(\d+)\x00/g, (_m: string, idx: string) => codeBlocks[parseInt(idx)] || '');