From 7aba448f42982922e5a5aeecccb3d54c90740cdc Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Thu, 16 Feb 2023 21:51:22 +0800
Subject: [PATCH] Handle multi-paragraph code blocks

This ain't going to be fun if the HTML gets messier in the future
---
 src/components/status.css    |  3 +++
 src/utils/enhance-content.js | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/src/components/status.css b/src/components/status.css
index 5ff6512a..4ddc3ba6 100644
--- a/src/components/status.css
+++ b/src/components/status.css
@@ -286,6 +286,8 @@
 .status .content p {
   /* 12px = 75% of 16px */
   margin-block: min(0.75em, 12px);
+  white-space: pre-wrap;
+  tab-size: 2;
 }
 .status .content p:first-child {
   margin-block-start: 0;
@@ -894,6 +896,7 @@ a.card:is(:hover, :focus) {
     transparent 160px
   );
   white-space: pre-wrap;
+  line-height: 1.2;
 }
 
 .status .content p code {
diff --git a/src/utils/enhance-content.js b/src/utils/enhance-content.js
index 637b92ab..33d2c6d5 100644
--- a/src/utils/enhance-content.js
+++ b/src/utils/enhance-content.js
@@ -43,6 +43,41 @@ function enhanceContent(content, opts = {}) {
     block.replaceWith(pre);
   });
 
+  // Convert multi-paragraph code blocks to <pre><code>code</code></pre>
+  const paragraphs = Array.from(dom.querySelectorAll('p'));
+  // Filter out paragraphs with ``` in beginning only
+  const codeBlocks = paragraphs.filter((p) => /^```/g.test(p.innerText));
+  // For each codeBlocks, get all paragraphs until the last paragraph with ``` at the end only
+  codeBlocks.forEach((block) => {
+    const nextParagraphs = [block];
+    let hasCodeBlock = false;
+    do {
+      const next = block.nextElementSibling;
+      if (next && next.tagName === 'P') {
+        if (/```$/g.test(next.innerText)) {
+          nextParagraphs.push(next);
+          hasCodeBlock = true;
+          break;
+        } else {
+          nextParagraphs.push(next);
+        }
+      } else {
+        break;
+      }
+    } while (true);
+    if (hasCodeBlock) {
+      const pre = document.createElement('pre');
+      nextParagraphs.forEach((p) => {
+        // Replace <br /> with newlines
+        p.querySelectorAll('br').forEach((br) => br.replaceWith('\n'));
+      });
+      const codeText = nextParagraphs.map((p) => p.innerHTML).join('\n\n');
+      pre.innerHTML = `<code>${codeText}</code>`;
+      block.replaceWith(pre);
+      nextParagraphs.forEach((p) => p.remove());
+    }
+  });
+
   // INLINE CODE
   // ===========
   // Convert `code` to <code>code</code>