diff --git a/lib/utils/email-content.ts b/lib/utils/email-content.ts index dac643c4..2bf663b8 100644 --- a/lib/utils/email-content.ts +++ b/lib/utils/email-content.ts @@ -278,15 +278,35 @@ export function processHtmlContent(htmlContent: string, textContent?: string): s textNodes.forEach(node => { if (node.nodeValue) { // Replace sequences of whitespace with a single space - node.nodeValue = node.nodeValue.replace(/\s+/g, ' ').trim(); + // But don't change whitespace in
 tags
+            if (!isInPreTag(node)) {
+              node.nodeValue = node.nodeValue.replace(/\s+/g, ' ').trim();
+            }
           }
         });
         
+        // Helper function to check if a node is inside a pre tag
+        function isInPreTag(node: Node): boolean {
+          let parent = node.parentNode;
+          while (parent) {
+            if (parent.nodeName.toLowerCase() === 'pre') {
+              return true;
+            }
+            parent = parent.parentNode;
+          }
+          return false;
+        }
+        
         // Remove empty paragraphs and divs that contain only whitespace
         const emptyElements = tempDiv.querySelectorAll('p, div, span');
         emptyElements.forEach(el => {
           if (el.innerHTML.trim() === '' || el.innerHTML === ' ') {
-            el.parentNode?.removeChild(el);
+            // Only remove if not a child of a layout container like table
+            if (el.parentNode && 
+                el.parentNode.nodeName.toLowerCase() !== 'td' && 
+                el.parentNode.nodeName.toLowerCase() !== 'th') {
+              el.parentNode?.removeChild(el);
+            }
           }
         });
         
@@ -312,7 +332,7 @@ export function processHtmlContent(htmlContent: string, textContent?: string): s
       .replace(/src="data:image\/[^;]+;base64,\s*([^"]+)\s*"/gi, (match, p1) => {
         return `src="data:image/png;base64,${p1.replace(/\s+/g, '')}"`;
       })
-      // Remove excessive whitespace from the HTML string itself
+      // Remove excessive whitespace from the HTML string itself, but be careful not to break preformatted text
       .replace(/>\s+ <');
   } catch (error) {
     console.error('Error processing HTML content:', error);
diff --git a/lib/utils/email-utils.ts b/lib/utils/email-utils.ts
index c7a2ab8a..a14e6c07 100644
--- a/lib/utils/email-utils.ts
+++ b/lib/utils/email-utils.ts
@@ -372,8 +372,27 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
   `;
   
   // Use the original HTML content if available, otherwise format the text
-  const contentHtml = html || (text ? `

${text.replace(/\n/g, '

')}

` : '

No content available

'); + let contentHtml = ''; + if (html) { + // Preserve the original HTML structure + // The key is to preserve all formatting without trying to modify it + contentHtml = `
${html}
`; + } else if (text) { + // For plain text, convert to HTML with proper line breaks + const formattedText = text + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/\n/g, '
'); + + contentHtml = `
${formattedText}
`; + } else { + contentHtml = '
No content available
'; + } + + // Just concatenate the header with the original content + // Don't try to process or reformat the original content const cleanHtml = `${forwardHeader}${contentHtml}`; // Plain text version - with clearer formatting