From f28c61a373847f98e4f0c1ed58205f1908767ad9 Mon Sep 17 00:00:00 2001 From: Joep Meindertsma Date: Thu, 10 Sep 2026 14:10:05 +0200 Subject: [PATCH] Render a supplier's plain agenda text as markdown, so its links are links Notubiz hands over HTML for meeting and agenda descriptions; iBabs hands over plain text that griffies write with markdown in it. Both were inserted as HTML, so Harderwijk's "[www.harderwijk.nl/vergaderingen](...)" appeared with its brackets and unclickable, with entities in between (#295). Text without the tags a supplier's HTML uses is now decoded, escaped and rendered as markdown: links become links, line breaks survive, and nothing in it can become markup of its own. HTML is passed through as before. --- tests/markdown.test.ts | 32 ++++++++++++++++++++++++++++ web/src/MeetingAgendaTree.svelte | 4 ++-- web/src/markdown.ts | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/markdown.test.ts diff --git a/tests/markdown.test.ts b/tests/markdown.test.ts new file mode 100644 index 0000000..21a2404 --- /dev/null +++ b/tests/markdown.test.ts @@ -0,0 +1,32 @@ +import { renderSupplierText } from "../web/src/markdown.ts"; + +function assert(condition: unknown, message: string): asserts condition { + if (!condition) { + throw new Error(message); + } +} + +Deno.test("plain supplier text with markdown links becomes clickable, and safe", () => { + // #295: Harderwijk's agenda text, as iBabs delivers it. + const html = renderSupplierText( + "De vergadering is te volgen via [www.harderwijk.nl/vergaderingen](https://www.harderwijk.nl/vergaderingen). \n \nProces: is geen markup.", + ); + assert( + html.includes( + 'www.harderwijk.nl/vergaderingen', + ), + `the markdown link is rendered, got ${html}`, + ); + assert(!html.includes(" ") && !html.includes("\r"), "carriage-return entities are dropped"); + assert(!html.includes("