$1')
.replace(/\*\*([^*]+)\*\*/g, '$1')
.replace(/(^|[^*])\*([^*]+)\*/g, '$1$2')
.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (m, label, url) => {
const u = String(url).trim();
if (u && !/^(https?:|mailto:|\/|#)/i.test(u)) return m;
return park(link(u, label));
});
// Nackte Quellen-URLs klickbar machen — bei Web-Recherchen nennt der
// Assistent Belege oft als reine URL, nicht als Markdown-Link. Nur http(s),
// und Satzzeichen am Ende gehören zum Satz, nicht zur Adresse.
s = s.replace(/https?:\/\/[^\s<>"'`\u0000]+/g, (u) => {
const m = u.match(/[.,;:!?)\]]+$/);
const rein = m ? u.slice(0, -m[0].length) : u;
return park(link(rein, rein)) + (m ? m[0] : '');
});
return s.replace(/\u0000(\d+)\u0000/g, (m, i) => parked[Number(i)]);
}
function renderMarkdown(src) {
const esc = escapeHtml(src == null ? '' : String(src)).replace(/\r\n/g, '\n');
const lines = esc.split('\n');
let html = '';
let i = 0;
let para = [];
const flushPara = () => {
if (para.length) html += '' + inlineFmt(para.join(' ')) + '
'; para = []; }; while (i < lines.length) { const line = lines[i]; if (/^```/.test(line)) { // fenced code block flushPara(); const code = []; i++; while (i < lines.length && !/^```/.test(lines[i])) { code.push(lines[i]); i++; } i++; // closing fence html += '' + code.join('\n') + '';
continue;
}
const hm = line.match(/^(#{1,6})\s+(.*)$/);
if (hm) {
flushPara();
const lvl = Math.min(hm[1].length, 3);
html += '