diff --git a/src/utils/markdown.tsx b/src/utils/markdown.tsx
index d30a571e..bf6cf36c 100644
--- a/src/utils/markdown.tsx
+++ b/src/utils/markdown.tsx
@@ -156,7 +156,6 @@ function replaceMathPlaceholders(
// Parse inline markdown and HTML (bold, italic, code, br, links, images, plain URLs)
function parseInline(text: string, keyPrefix: string): React.ReactNode[] {
// FIRST PASS: Handle escape sequences (e.g., \* should become just *)
- // Process common escaped markdown characters
const unescapedText = text.replace(/\\([*_`[\]()#+-.|!\\])/g, '$1');
// SECOND PASS: Extract inline math and replace with safe tokens that won't be matched by markdown regex
@@ -180,7 +179,7 @@ function parseInline(text: string, keyPrefix: string): React.ReactNode[] {
let key = 0;
// THIRD PASS: Process markdown - math placeholders won't be captured by markdown patterns
- const regex = /(\*\*(.+?)\*\*|\*([^\s*](?:[^*]*[^\s*])?)\*|_([^_]+?)_|`([^`]+?)`|
|(.+?)<\/b>|(.+?)<\/strong>|(.+?)<\/i>|(.+?)<\/em>|(.+?)<\/code>|(.+?)<\/a>|\[([^\]]+)\]\(([^\s)]+)(?:\s+"([^"]+)")?\)|!\[([^\]]*)\]\(([^)]+)\)|(https?:\/\/[^\s<>[\]()]+[^\s<>[\]().,;:!?'"]))/gi;
+ const regex = /(\*\*(.+?)\*\*|\*([^\s*](?:[^*]*[^\s*])?)\*|_([^_]+?)_|`([^`]+?)`|
|(.+?)<\/b>|(.+?)<\/strong>|(.+?)<\/i>|(.+?)<\/em>|(.+?)<\/code>|(.+?)<\/a>|\[([^\]]+)\]\(((?:[^\s()]|\([^\s)]*\))+)(?:\s+"([^"]+)")?\)|!\[([^\]]*)\]\(((?:[^()]|\([^)]*\))+)\)|(https?:\/\/[^\s<>[\]()]+[^\s<>[\]().,;:!?'"]))/gi;
let lastIndex = 0;
let match;
@@ -302,12 +301,14 @@ function parseInline(text: string, keyPrefix: string): React.ReactNode[] {
return parts.length > 0 ? parts : [text];
}
-// Helper function to split table row by | while respecting quoted strings (for tooltips)
+// Helper function to split table row by | while respecting escaped | and links
function splitTableRow(line: string): string[] {
const cells: string[] = [];
let currentCell = '';
let inQuotes = false;
let escaped = false;
+ let bracketDepth = 0; // Track depth of [ ] for nested brackets
+ let inLinkParen = false; // Track if we're inside (...) part of a link
for (let i = 0; i < line.length; i++) {
const char = line[i];
@@ -324,13 +325,35 @@ function splitTableRow(line: string): string[] {
continue;
}
- if (char === '"') {
+ if (char === '[') {
+ bracketDepth++;
+ currentCell += char;
+ continue;
+ }
+
+ if (char === ']' && bracketDepth > 0) {
+ bracketDepth--;
+ currentCell += char;
+ if (bracketDepth === 0 && i + 1 < line.length && line[i + 1] === '(') {
+ inLinkParen = true;
+ }
+ continue;
+ }
+
+ if (char === '"' && (inLinkParen || inQuotes)) {
inQuotes = !inQuotes;
currentCell += char;
continue;
}
- if (char === '|' && !inQuotes) {
+ if (char === ')' && inLinkParen && !inQuotes) {
+ inLinkParen = false;
+ currentCell += char;
+ continue;
+ }
+
+ // Only split on | when not inside brackets, link parens, or quotes
+ if (char === '|' && !inQuotes && bracketDepth === 0 && !inLinkParen) {
cells.push(currentCell);
currentCell = '';
continue;