diff --git a/src/lib/utils/markup/advancedMarkupParser.ts b/src/lib/utils/markup/advancedMarkupParser.ts index 8777390..e05d970 100644 --- a/src/lib/utils/markup/advancedMarkupParser.ts +++ b/src/lib/utils/markup/advancedMarkupParser.ts @@ -233,24 +233,7 @@ function processFootnotes(content: string): string { } } -/** - * Process blockquotes - */ -function processBlockquotes(content: string): string { - // Match blockquotes that might span multiple lines - const blockquoteRegex = /^>[ \t]?(.+(?:\n>[ \t]?.+)*)/gm; - - return content.replace(blockquoteRegex, (match) => { - // Remove the '>' prefix from each line and preserve line breaks - const text = match - .split("\n") - .map((line) => line.replace(/^>[ \t]?/, "")) - .join("\n") - .trim(); - - return `
${text}
`; - }); -} + /** * Process code blocks by finding consecutive code lines and preserving their content @@ -689,6 +672,8 @@ function isLaTeXContent(content: string): boolean { return latexPatterns.some((pattern) => pattern.test(trimmed)); } + + /** * Parse markup text with advanced formatting */ @@ -706,9 +691,10 @@ export async function parseAdvancedmarkup(text: string): Promise { // Step 3: Process LaTeX math expressions ONLY within inline code blocks (legacy support) processedText = processMathExpressions(processedText); - // Step 4: Process block-level elements (tables, blockquotes, headings, horizontal rules) + // Step 4: Process block-level elements (tables, headings, horizontal rules) + // AI-NOTE: 2025-01-24 - Removed duplicate processBlockquotes call to fix image rendering issues + // Blockquotes are now processed only by parseBasicmarkup to avoid double-processing conflicts processedText = processTables(processedText); - processedText = processBlockquotes(processedText); processedText = processHeadings(processedText); processedText = processHorizontalRules(processedText); diff --git a/src/lib/utils/markup/basicMarkupParser.ts b/src/lib/utils/markup/basicMarkupParser.ts index 043680a..dddd31d 100644 --- a/src/lib/utils/markup/basicMarkupParser.ts +++ b/src/lib/utils/markup/basicMarkupParser.ts @@ -18,7 +18,8 @@ import { // Links and media const MARKUP_LINK = /\[([^\]]+)\]\(([^)]+)\)/g; const MARKUP_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g; -const DIRECT_LINK = /(?"]+)(?!["'])/g; +// AI-NOTE: 2025-01-24 - Added negative lookbehind (?"]+)(?!["'])/g; @@ -156,8 +157,11 @@ function processBasicFormatting(content: string): string { processedText = replaceAlexandriaNostrLinks(processedText); // Process markup images first - processedText = processedText.replace(MARKUP_IMAGE, (_match, alt, url) => { - return processImageWithReveal(url, alt); + processedText = processedText.replace(MARKUP_IMAGE, (match, alt, url) => { + // Clean the URL and alt text + const cleanUrl = url.trim(); + const cleanAlt = alt ? alt.trim() : ""; + return processImageWithReveal(cleanUrl, cleanAlt); }); // Process markup links @@ -242,9 +246,10 @@ export async function parseBasicmarkup(text: string): Promise { .map((para) => para.trim()) .filter((para) => para.length > 0) .map((para) => { - // Skip wrapping if para already contains block-level elements or math blocks + // AI-NOTE: 2025-01-24 - Added img tag to skip wrapping to prevent image rendering issues + // Skip wrapping if para already contains block-level elements, math blocks, or images if ( - /(]*class=["'][^"']*math-block[^"']*["'])|<(div|h[1-6]|blockquote|table|pre|ul|ol|hr)/i.test( + /(]*class=["'][^"']*math-block[^"']*["'])|<(div|h[1-6]|blockquote|table|pre|ul|ol|hr|img)/i.test( para, ) ) { diff --git a/src/lib/utils/markup/embeddedMarkupParser.ts b/src/lib/utils/markup/embeddedMarkupParser.ts index 548f4ba..ab34ddf 100644 --- a/src/lib/utils/markup/embeddedMarkupParser.ts +++ b/src/lib/utils/markup/embeddedMarkupParser.ts @@ -19,7 +19,8 @@ import { // Links and media const MARKUP_LINK = /\[([^\]]+)\]\(([^)]+)\)/g; const MARKUP_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g; -const DIRECT_LINK = /(?"]+)(?!["'])/g; +// AI-NOTE: 2025-01-24 - Added negative lookbehind (?"]+)(?!["'])/g; // Add this helper function near the top: function replaceAlexandriaNostrLinks(text: string): string { @@ -149,8 +150,11 @@ function processBasicFormatting(content: string): string { processedText = replaceAlexandriaNostrLinks(processedText); // Process markup images first - processedText = processedText.replace(MARKUP_IMAGE, (_match, alt, url) => { - return processImageWithReveal(url, alt); + processedText = processedText.replace(MARKUP_IMAGE, (match, alt, url) => { + // Clean the URL and alt text + const cleanUrl = url.trim(); + const cleanAlt = alt ? alt.trim() : ""; + return processImageWithReveal(cleanUrl, cleanAlt); }); // Process markup links @@ -234,9 +238,10 @@ export async function parseEmbeddedMarkup(text: string, nestingLevel: number = 0 .map((para) => para.trim()) .filter((para) => para.length > 0) .map((para) => { - // Skip wrapping if para already contains block-level elements or math blocks + // AI-NOTE: 2025-01-24 - Added img tag to skip wrapping to prevent image rendering issues + // Skip wrapping if para already contains block-level elements, math blocks, or images if ( - /(]*class=["'][^"']*math-block[^"']*["'])|<(div|h[1-6]|blockquote|table|pre|ul|ol|hr)/i.test( + /(]*class=["'][^"']*math-block[^"']*["'])|<(div|h[1-6]|blockquote|table|pre|ul|ol|hr|img)/i.test( para, ) ) {