From adce60922941823ea8a828bdbb540b3b5ce55d1a Mon Sep 17 00:00:00 2001 From: Tejender Upadhyay Date: Wed, 13 May 2026 16:53:26 +0200 Subject: [PATCH] Improve web UI markdown table --- internal/webui/static/app.js | 30 ++++++++++++++++++++++++++++-- internal/webui/static/style.css | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/internal/webui/static/app.js b/internal/webui/static/app.js index 0968167..68b0c46 100644 --- a/internal/webui/static/app.js +++ b/internal/webui/static/app.js @@ -124,6 +124,32 @@ function renderMarkdown(text) { '$1', ); + // Tables: consecutive lines containing pipes + html = html.replace(/(?:^\|.+\|\s*(?:\n|$))+/gm, (match) => { + const rows = match.trim().split("\n"); + if (rows.length < 2) return match; + // Check if second row is a separator (e.g. |---|---|) + const sepTest = rows[1].replace(/\s/g, ""); + const isSep = /^\|?[\-:|]+(?:\|[\-:|]+)+\|?$/.test(sepTest); + if (!isSep) return match; + + const parseRow = (row) => + row.replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim()); + + const headerCells = parseRow(rows[0]); + const thead = "" + headerCells.map((c) => `${c}`).join("") + ""; + + const bodyRows = rows.slice(2); + const tbody = bodyRows.length + ? "" + bodyRows.map((r) => { + const cells = parseRow(r); + return "" + cells.map((c) => `${c}`).join("") + ""; + }).join("") + "" + : ""; + + return `${thead}${tbody}
`; + }); + // Unordered lists: consecutive lines starting with - or * html = html.replace(/(?:^[*\-] .+(?:\n|$))+/gm, (match) => { const items = match @@ -148,8 +174,8 @@ function renderMarkdown(text) { html = html.replace(/\n/g, "
"); // Clean stray
adjacent to block elements - html = html.replace(/
(<\/?(?:h[2-5]|pre|ul|ol|li|hr))/g, "$1"); - html = html.replace(/((?:<\/(?:h[2-5]|pre|ul|ol|li)>|
))
/g, "$1"); + html = html.replace(/
(<\/?(?:h[2-5]|pre|ul|ol|li|hr|table|thead|tbody|tr|th|td))/g, "$1"); + html = html.replace(/((?:<\/(?:h[2-5]|pre|ul|ol|li|table|thead|tbody|tr|th|td)>|
))
/g, "$1"); // Restore protected code html = html.replace(/\x00CB(\d+)\x00/g, (_, i) => codeBlocks[i]); diff --git a/internal/webui/static/style.css b/internal/webui/static/style.css index ab32587..f07df35 100644 --- a/internal/webui/static/style.css +++ b/internal/webui/static/style.css @@ -346,6 +346,29 @@ input:focus, select:focus, textarea:focus { .bubble.assistant strong { font-weight: 600; } .bubble.assistant em { font-style: italic; } +.bubble.assistant table { + border-collapse: collapse; + width: 100%; + margin: 6px 0; + font-size: 13px; +} + +.bubble.assistant th, +.bubble.assistant td { + border: 1px solid var(--border); + padding: 5px 10px; + text-align: left; +} + +.bubble.assistant th { + background: var(--bg); + font-weight: 600; +} + +.bubble.assistant tr:nth-child(even) td { + background: var(--bg-elev-2); +} + .bubble.error { align-self: stretch; background: var(--bad);