aboutsummaryrefslogtreecommitdiffstats
path: root/renderer/src
diff options
context:
space:
mode:
Diffstat (limited to 'renderer/src')
-rw-r--r--renderer/src/components/DocumentPane.tsx67
-rw-r--r--renderer/src/styles/globals.css19
2 files changed, 85 insertions, 1 deletions
diff --git a/renderer/src/components/DocumentPane.tsx b/renderer/src/components/DocumentPane.tsx
index a22ecad..c2e1b2c 100644
--- a/renderer/src/components/DocumentPane.tsx
+++ b/renderer/src/components/DocumentPane.tsx
@@ -9,9 +9,72 @@ interface DocumentPaneProps {
9 showOnboarding?: boolean; 9 showOnboarding?: boolean;
10} 10}
11 11
12function renderTable(tableLines: string[]): string {
13 if (tableLines.length < 2) return tableLines.join("\n");
14
15 const parseRow = (line: string): string[] => {
16 return line
17 .split("|")
18 .slice(1, -1) // Remove empty first/last from |col|col|
19 .map((cell) => cell.trim());
20 };
21
22 const headerCells = parseRow(tableLines[0]);
23 // Skip separator row (index 1)
24 const bodyRows = tableLines.slice(2);
25
26 let html = '<table><thead><tr>';
27 headerCells.forEach((cell) => {
28 html += `<th>${cell}</th>`;
29 });
30 html += '</tr></thead><tbody>';
31
32 bodyRows.forEach((row) => {
33 if (row.trim()) {
34 html += '<tr>';
35 parseRow(row).forEach((cell) => {
36 html += `<td>${cell}</td>`;
37 });
38 html += '</tr>';
39 }
40 });
41
42 html += '</tbody></table>';
43 return html;
44}
45
12function renderMarkdown(md: string): string { 46function renderMarkdown(md: string): string {
47 // First, handle tables (before other transformations)
48 const lines = md.split("\n");
49 const processedLines: string[] = [];
50 let tableBuffer: string[] = [];
51 let inTable = false;
52
53 for (const line of lines) {
54 const isTableLine = /^\|.*\|$/.test(line.trim());
55
56 if (isTableLine) {
57 inTable = true;
58 tableBuffer.push(line);
59 } else {
60 if (inTable && tableBuffer.length > 0) {
61 processedLines.push(renderTable(tableBuffer));
62 tableBuffer = [];
63 inTable = false;
64 }
65 processedLines.push(line);
66 }
67 }
68
69 // Handle table at end of content
70 if (tableBuffer.length > 0) {
71 processedLines.push(renderTable(tableBuffer));
72 }
73
74 let result = processedLines.join("\n");
75
13 return ( 76 return (
14 md 77 result
15 // Headers 78 // Headers
16 .replace(/^### (.*$)/gm, "<h3>$1</h3>") 79 .replace(/^### (.*$)/gm, "<h3>$1</h3>")
17 .replace(/^## (.*$)/gm, "<h2>$1</h2>") 80 .replace(/^## (.*$)/gm, "<h2>$1</h2>")
@@ -43,6 +106,8 @@ function renderMarkdown(md: string): string {
43 .replace(/(<\/pre>)<\/p>/g, "$1") 106 .replace(/(<\/pre>)<\/p>/g, "$1")
44 .replace(/<p>(<li)/g, "$1") 107 .replace(/<p>(<li)/g, "$1")
45 .replace(/(<\/li>)<\/p>/g, "$1") 108 .replace(/(<\/li>)<\/p>/g, "$1")
109 .replace(/<p>(<table>)/g, "$1")
110 .replace(/(<\/table>)<\/p>/g, "$1")
46 ); 111 );
47} 112}
48 113
diff --git a/renderer/src/styles/globals.css b/renderer/src/styles/globals.css
index e1d945a..380a744 100644
--- a/renderer/src/styles/globals.css
+++ b/renderer/src/styles/globals.css
@@ -200,6 +200,25 @@ body {
200.document-content.rendered li.task.done { 200.document-content.rendered li.task.done {
201 color: var(--success); 201 color: var(--success);
202} 202}
203.document-content.rendered table {
204 width: 100%;
205 border-collapse: collapse;
206 margin: 16px 0;
207 font-size: 14px;
208}
209.document-content.rendered th,
210.document-content.rendered td {
211 padding: 10px 12px;
212 text-align: left;
213 border: 1px solid var(--border);
214}
215.document-content.rendered th {
216 background: var(--bg-tertiary);
217 font-weight: 600;
218}
219.document-content.rendered tr:nth-child(even) td {
220 background: var(--bg-secondary);
221}
203.document-content.rendered mark.review { 222.document-content.rendered mark.review {
204 background: var(--warning); 223 background: var(--warning);
205 color: black; 224 color: black;