| 449 | |
| 450 | // Parse content to separate line numbers from code |
| 451 | const parseContent = (rawContent: string) => { |
| 452 | const lines = rawContent.split('\n'); |
| 453 | const codeLines: string[] = []; |
| 454 | let minLineNumber = Infinity; |
| 455 | |
| 456 | // First, determine if the content is likely a numbered list from the 'read' tool. |
| 457 | // It is if more than half the non-empty lines match the expected format. |
| 458 | const nonEmptyLines = lines.filter(line => line.trim() !== ''); |
| 459 | if (nonEmptyLines.length === 0) { |
| 460 | return { codeContent: rawContent, startLineNumber: 1 }; |
| 461 | } |
| 462 | const parsableLines = nonEmptyLines.filter(line => /^\s*\d+→/.test(line)).length; |
| 463 | const isLikelyNumbered = (parsableLines / nonEmptyLines.length) > 0.5; |
| 464 | |
| 465 | if (!isLikelyNumbered) { |
| 466 | return { codeContent: rawContent, startLineNumber: 1 }; |
| 467 | } |
| 468 | |
| 469 | // If it's a numbered list, parse it strictly. |
| 470 | for (const line of lines) { |
| 471 | // Remove leading whitespace before parsing |
| 472 | const trimmedLine = line.trimStart(); |
| 473 | const match = trimmedLine.match(/^(\d+)→(.*)$/); |
| 474 | if (match) { |
| 475 | const lineNum = parseInt(match[1], 10); |
| 476 | if (minLineNumber === Infinity) { |
| 477 | minLineNumber = lineNum; |
| 478 | } |
| 479 | // Preserve the code content exactly as it appears after the arrow |
| 480 | codeLines.push(match[2]); |
| 481 | } else if (line.trim() === '') { |
| 482 | // Preserve empty lines |
| 483 | codeLines.push(''); |
| 484 | } else { |
| 485 | // If a line in a numbered block does not match, it's a formatting anomaly. |
| 486 | // Render it as a blank line to avoid showing the raw, un-parsed string. |
| 487 | codeLines.push(''); |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | // Remove trailing empty lines |
| 492 | while (codeLines.length > 0 && codeLines[codeLines.length - 1] === '') { |
| 493 | codeLines.pop(); |
| 494 | } |
| 495 | |
| 496 | return { |
| 497 | codeContent: codeLines.join('\n'), |
| 498 | startLineNumber: minLineNumber === Infinity ? 1 : minLineNumber |
| 499 | }; |
| 500 | }; |
| 501 | |
| 502 | const language = getLanguage(filePath); |
| 503 | const { codeContent, startLineNumber } = parseContent(content); |