From 565ce84abf945e0c4b5a8d81bd9e160a74106482 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Fri, 10 Apr 2026 17:41:07 +0000 Subject: [PATCH] Feature: Markdown-Tabellen in Lagebildern Analyzer-Prompts erlauben jetzt Tabellen wenn Daten sich strukturiert vergleichen lassen (Produkte, Modelle, Kennzahlen etc.). Frontend parst Markdown-Tabellensyntax und rendert sie als HTML-Tabellen mit passendem Styling. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/agents/analyzer.py | 4 +++- src/static/css/style.css | 31 +++++++++++++++++++++++++++++++ src/static/js/components.js | 17 +++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/agents/analyzer.py b/src/agents/analyzer.py index d91e052..5c679ae 100644 --- a/src/agents/analyzer.py +++ b/src/agents/analyzer.py @@ -28,7 +28,8 @@ AUFTRAG: STRUKTUR: - Wenn die Meldungen thematisch klar einen einzelnen Strang behandeln: Fließtext ohne Überschriften - Wenn verschiedene Aspekte oder Themenfelder aufkommen (z.B. Ereignis + Reaktionen + Hintergrund): Gliedere mit kurzen Markdown-Zwischenüberschriften (##) -- Die Entscheidung liegt bei dir — Überschriften nur wenn sie dem Leser helfen, verschiedene Themenstränge auseinanderzuhalten +- Wenn sich Daten strukturiert vergleichen lassen (z.B. Produkte, Unternehmen, Kennzahlen, Modelle), verwende eine Markdown-Tabelle (| Spalte1 | Spalte2 | ... mit Trennzeile |---|---|) +- Die Entscheidung liegt bei dir — Überschriften und Tabellen nur wenn sie dem Leser helfen REGELN: - Neutral und sachlich - keine Wertungen oder Spekulationen @@ -130,6 +131,7 @@ AUFTRAG: STRUKTUR: - Fließtext oder mit Markdown-Zwischenüberschriften (##) — je nach Komplexität +- Wenn sich Daten strukturiert vergleichen lassen (z.B. Produkte, Unternehmen, Kennzahlen, Modelle), verwende eine Markdown-Tabelle (| Spalte1 | Spalte2 | ... mit Trennzeile |---|---|) - KEIN Fettdruck (**) verwenden REGELN: diff --git a/src/static/css/style.css b/src/static/css/style.css index 3df375f..9a60934 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -2653,6 +2653,37 @@ a:hover { color: var(--text-secondary); } +/* === Summary Tables === */ +.summary-table-wrap { + overflow-x: auto; + margin: 12px 0; +} +.summary-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + line-height: 1.5; +} +.summary-table th, +.summary-table td { + padding: 8px 12px; + border: 1px solid var(--border); + text-align: left; + vertical-align: top; +} +.summary-table th { + background: var(--bg-secondary); + color: var(--text-primary); + font-weight: 600; + white-space: nowrap; +} +.summary-table td { + color: var(--text-secondary); +} +.summary-table tbody tr:hover { + background: var(--bg-hover); +} + /* === Responsive === */ @media (max-width: 768px) { diff --git a/src/static/js/components.js b/src/static/js/components.js index 8786172..2da4125 100644 --- a/src/static/js/components.js +++ b/src/static/js/components.js @@ -702,6 +702,23 @@ const UI = { html = html.replace(/<\/ul>(
)+/g, ''); html = html.replace(/(
){2,}/g, '
'); + // Markdown-Tabellen rendern + html = html.replace(/(?:^|
)((?:\|.+\|(?:
|$))+)/g, function(match, tableBlock) { + var rows = tableBlock.split('
').filter(function(r) { return r.trim().length > 0; }); + if (rows.length < 2) return match; + var isSep = function(r) { return /^\|[\s\-:|]+\|$/.test(r.trim()); }; + if (!isSep(rows[1])) return match; + var parseRow = function(r) { return r.split('|').slice(1, -1).map(function(c) { return c.trim(); }); }; + var headerCells = parseRow(rows[0]); + var thead = '' + headerCells.map(function(c) { return '' + c + ''; }).join('') + ''; + var tbody = '' + rows.slice(2).map(function(r) { + if (isSep(r)) return ''; + var cells = parseRow(r); + return '' + cells.map(function(c) { return '' + c + ''; }).join('') + ''; + }).join('') + ''; + return '
' + thead + tbody + '
'; + }); + // Inline-Zitate [1], [2], [1383a] etc. als klickbare Links rendern if (sources.length > 0) { html = html.replace(/\[(\d+[a-z]?)\]/g, (match, num) => {