From a329eab091829b9a9c9739981316a09f8ab22ef9 Mon Sep 17 00:00:00 2001 From: mrwnslz Date: Mon, 19 Oct 2026 20:28:27 +0200 Subject: [PATCH] Projekt-Notizen: Markdown-Tabellen; sw v144 Co-Authored-By: Claude Opus 5.5 --- e2e/navigation.spec.js | 3 ++- static/js/projects.js | 17 ++++++++++++++++- static/js/sw.js | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/e2e/navigation.spec.js b/e2e/navigation.spec.js index 407ed54..158b3fc 100644 --- a/e2e/navigation.spec.js +++ b/e2e/navigation.spec.js @@ -123,11 +123,12 @@ test('Projekte: a Forschung project, a paper by DOI, a linked book, a note citin await tab.locator('[data-view="notes"]').click(); await tab.locator('[data-act="new-note"]').click(); await tab.locator('[data-note-title]').fill('These'); - await tab.locator('[data-note-body]').fill('# Idee\nIdeologie zeigt sich im Gehirn [@amodio2007neural, S. 3] und bei [@muster0jdas].'); + await tab.locator('[data-note-body]').fill('# Idee\nIdeologie zeigt sich im Gehirn [@amodio2007neural, S. 3] und bei [@muster0jdas].\n\n| Text | Zeit |\n|---|---|\n| Cobb | 2,5 h |\nDanach.'); await expect(tab.locator('.prj-saved')).toHaveText('gespeichert', {timeout: 5000}); await tab.locator('[data-act="preview"]').click(); await expect(tab.locator('.prj-md .prj-cite').first()).toHaveText('(Amodio & Jost 2007, S. 3)'); await expect(tab.locator('.prj-refs li').first()).toContainText('Nature Neuroscience'); + await expect(tab.locator('.prj-md td')).toHaveText(['Cobb', '2,5 h']); await tab.locator('[data-view="sources"]').click(); const [dl] = await Promise.all([page.waitForEvent('download'), tab.locator('[data-export="bib"]').click()]); diff --git a/static/js/projects.js b/static/js/projects.js index 27222a0..c1ea61b 100644 --- a/static/js/projects.js +++ b/static/js/projects.js @@ -274,8 +274,13 @@ function markdown(text, cite) { const lines = String(text || '').replace(/\r/g, '').split('\n'); - let out = '', list = null, para = [], quote = []; + let out = '', list = null, para = [], quote = [], table = null; const flush = () => { + if (table) { + out += '
' + table.map((row, n) => '' + row.map(c => + (n ? '')).join('') + '').join('') + '
' : '') + inline(c, cite) + (n ? '' : '
'; + table = null; + } if (para.length) { out += '

' + inline(para.join(' '), cite) + '

'; para = []; } if (quote.length) { out += '
' + inline(quote.join(' '), cite) + '
'; quote = []; } if (list) { out += ''; list = null; } @@ -284,6 +289,13 @@ const line = raw.replace(/\s+$/, ''); let m; if (!line.trim()) { flush(); continue; } + // A table: | a | b |, under its head a | --- | --- | line. + if (/^\s*\|.*\|$/.test(line)) { + if (!table) { flush(); table = []; } + if (!/^\s*\|[\s:|-]+\|$/.test(line)) table.push(line.trim().replace(/^\||\|$/g, '').split('|').map(c => c.trim())); + continue; + } + if (table) flush(); if ((m = /^(#{1,4})\s+(.*)$/.exec(line))) { flush(); out += '' + inline(m[2], cite) + ''; continue; } if ((m = /^\s*[-*+]\s+(?:\[( |x)\]\s+)?(.*)$/i.exec(line))) { if (para.length || quote.length || list !== 'ul') { flush(); out += '