mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Fix extra whitespace in markdown rendering. (#3943)
Co-authored-by: Scott Densmore <scottdensmore@mac.com>
This commit is contained in:
@@ -21,7 +21,7 @@ interface MarkdownDisplayProps {
|
||||
// Constants for Markdown parsing and rendering
|
||||
|
||||
const EMPTY_LINE_HEIGHT = 1;
|
||||
const CODE_BLOCK_PADDING = 1;
|
||||
const CODE_BLOCK_PREFIX_PADDING = 1;
|
||||
const LIST_ITEM_PREFIX_PADDING = 1;
|
||||
const LIST_ITEM_TEXT_FLEX_GROW = 1;
|
||||
|
||||
@@ -44,6 +44,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
|
||||
const contentBlocks: React.ReactNode[] = [];
|
||||
let inCodeBlock = false;
|
||||
let lastLineEmpty = true;
|
||||
let codeBlockContent: string[] = [];
|
||||
let codeBlockLang: string | null = null;
|
||||
let codeBlockFence = '';
|
||||
@@ -51,6 +52,13 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
let tableRows: string[][] = [];
|
||||
let tableHeaders: string[] = [];
|
||||
|
||||
function addContentBlock(block: React.ReactNode) {
|
||||
if (block) {
|
||||
contentBlocks.push(block);
|
||||
lastLineEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
const key = `line-${index}`;
|
||||
|
||||
@@ -61,7 +69,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
fenceMatch[1].startsWith(codeBlockFence[0]) &&
|
||||
fenceMatch[1].length >= codeBlockFence.length
|
||||
) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderCodeBlock
|
||||
key={key}
|
||||
content={codeBlockContent}
|
||||
@@ -104,7 +112,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
tableRows = [];
|
||||
} else {
|
||||
// Not a table, treat as regular text
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<Box key={key}>
|
||||
<Text wrap="wrap">
|
||||
<RenderInline text={line} />
|
||||
@@ -128,7 +136,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
} else if (inTable && !tableRowMatch) {
|
||||
// End of table
|
||||
if (tableHeaders.length > 0 && tableRows.length > 0) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderTable
|
||||
key={`table-${contentBlocks.length}`}
|
||||
headers={tableHeaders}
|
||||
@@ -143,7 +151,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
|
||||
// Process current line as normal
|
||||
if (line.trim().length > 0) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<Box key={key}>
|
||||
<Text wrap="wrap">
|
||||
<RenderInline text={line} />
|
||||
@@ -152,7 +160,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
);
|
||||
}
|
||||
} else if (hrMatch) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<Box key={key}>
|
||||
<Text dimColor>---</Text>
|
||||
</Box>,
|
||||
@@ -198,12 +206,12 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
);
|
||||
break;
|
||||
}
|
||||
if (headerNode) contentBlocks.push(<Box key={key}>{headerNode}</Box>);
|
||||
if (headerNode) addContentBlock(<Box key={key}>{headerNode}</Box>);
|
||||
} else if (ulMatch) {
|
||||
const leadingWhitespace = ulMatch[1];
|
||||
const marker = ulMatch[2];
|
||||
const itemText = ulMatch[3];
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderListItem
|
||||
key={key}
|
||||
itemText={itemText}
|
||||
@@ -216,7 +224,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
const leadingWhitespace = olMatch[1];
|
||||
const marker = olMatch[2];
|
||||
const itemText = olMatch[3];
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderListItem
|
||||
key={key}
|
||||
itemText={itemText}
|
||||
@@ -226,12 +234,15 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
/>,
|
||||
);
|
||||
} else {
|
||||
if (line.trim().length === 0) {
|
||||
if (contentBlocks.length > 0 && !inCodeBlock) {
|
||||
contentBlocks.push(<Box key={key} height={EMPTY_LINE_HEIGHT} />);
|
||||
if (line.trim().length === 0 && !inCodeBlock) {
|
||||
if (!lastLineEmpty) {
|
||||
contentBlocks.push(
|
||||
<Box key={`spacer-${index}`} height={EMPTY_LINE_HEIGHT} />,
|
||||
);
|
||||
lastLineEmpty = true;
|
||||
}
|
||||
} else {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<Box key={key}>
|
||||
<Text wrap="wrap">
|
||||
<RenderInline text={line} />
|
||||
@@ -243,7 +254,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
});
|
||||
|
||||
if (inCodeBlock) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderCodeBlock
|
||||
key="line-eof"
|
||||
content={codeBlockContent}
|
||||
@@ -257,7 +268,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
|
||||
// Handle table at end of content
|
||||
if (inTable && tableHeaders.length > 0 && tableRows.length > 0) {
|
||||
contentBlocks.push(
|
||||
addContentBlock(
|
||||
<RenderTable
|
||||
key={`table-${contentBlocks.length}`}
|
||||
headers={tableHeaders}
|
||||
@@ -293,14 +304,14 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
if (isPending && availableTerminalHeight !== undefined) {
|
||||
const MAX_CODE_LINES_WHEN_PENDING = Math.max(
|
||||
0,
|
||||
availableTerminalHeight - CODE_BLOCK_PADDING * 2 - RESERVED_LINES,
|
||||
availableTerminalHeight - RESERVED_LINES,
|
||||
);
|
||||
|
||||
if (content.length > MAX_CODE_LINES_WHEN_PENDING) {
|
||||
if (MAX_CODE_LINES_WHEN_PENDING < MIN_LINES_FOR_MESSAGE) {
|
||||
// Not enough space to even show the message meaningfully
|
||||
return (
|
||||
<Box padding={CODE_BLOCK_PADDING}>
|
||||
<Box paddingLeft={CODE_BLOCK_PREFIX_PADDING}>
|
||||
<Text color={Colors.Gray}>... code is being written ...</Text>
|
||||
</Box>
|
||||
);
|
||||
@@ -310,10 +321,10 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
truncatedContent.join('\n'),
|
||||
lang,
|
||||
availableTerminalHeight,
|
||||
terminalWidth - CODE_BLOCK_PADDING * 2,
|
||||
terminalWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
);
|
||||
return (
|
||||
<Box flexDirection="column" padding={CODE_BLOCK_PADDING}>
|
||||
<Box paddingLeft={CODE_BLOCK_PREFIX_PADDING} flexDirection="column">
|
||||
{colorizedTruncatedCode}
|
||||
<Text color={Colors.Gray}>... generating more ...</Text>
|
||||
</Box>
|
||||
@@ -326,13 +337,13 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
fullContent,
|
||||
lang,
|
||||
availableTerminalHeight,
|
||||
terminalWidth - CODE_BLOCK_PADDING * 2,
|
||||
terminalWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
paddingLeft={CODE_BLOCK_PREFIX_PADDING}
|
||||
flexDirection="column"
|
||||
padding={CODE_BLOCK_PADDING}
|
||||
width={terminalWidth}
|
||||
flexShrink={0}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user