Update markdown.js to convert line breaks to HTML paragraphs and handle block elements correctly

This commit is contained in:
2026-01-31 16:44:56 +01:00
parent 90d32279c3
commit 6aff8091e3

View File

@@ -94,7 +94,7 @@ export function markdownToHTML(text) {
const lines = blockquoteBlock const lines = blockquoteBlock
.split(/\n/) .split(/\n/)
.map((line) => line.replace(/^[ \t]*>\s*/, '').trim()) .map((line) => line.replace(/^[ \t]*>\s*/, '').trim())
.join('\n'); .join('<br />');
return `${lead}<blockquote class="md-blockquote">${lines}</blockquote>`; return `${lead}<blockquote class="md-blockquote">${lines}</blockquote>`;
} }
); );
@@ -188,44 +188,41 @@ export function markdownToHTML(text) {
)}" target="_blank" rel="noreferrer noopener"><span class="md-link__label">${label}</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="md-icon md-icon-external"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg><span class="md-link__tooltip">${tooltip}</span></a>`; )}" target="_blank" rel="noreferrer noopener"><span class="md-link__label">${label}</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="md-icon md-icon-external"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg><span class="md-link__tooltip">${tooltip}</span></a>`;
}); });
// 6) Convert line-breaks to <br /> for NON-code content (preserve blank lines) // 6) Convert line-breaks to HTML paragraphs and <br /> inside paragraphs
const linesWithHtml = html.split("\n"); const linesWithHtml = html.split("\n");
const htmlLines = []; const htmlLines = [];
let emptyCount = 0; let paragraph = [];
let seenNonEmpty = false; const flushParagraph = () => {
if (paragraph.length === 0) return;
htmlLines.push(`<p class="md-paragraph">${paragraph.join("<br />")}</p>`);
paragraph = [];
};
const isBlockLine = (value) => {
const trimmed = value.trim();
if (!trimmed) return false;
if (/^@@CODEBLOCK\d+@@$/.test(trimmed)) return true;
if (!trimmed.startsWith("<")) return false;
return /^(<h[1-4]\b|<hr\b|<table\b|<ul\b|<ol\b|<blockquote\b|<div class="md-codeblock"\b|<\/(?:h[1-4]|table|ul|ol|blockquote)>)/.test(
trimmed
);
};
for (let i = 0; i < linesWithHtml.length; i += 1) { for (let i = 0; i < linesWithHtml.length; i += 1) {
const line = linesWithHtml[i] ?? ""; const line = linesWithHtml[i] ?? "";
const isEmpty = line.trim().length === 0; if (line.trim().length === 0) {
flushParagraph();
if (isEmpty) {
emptyCount += 1;
continue; continue;
} }
if (isBlockLine(line)) {
if (seenNonEmpty) { flushParagraph();
const breaksToAdd = Math.max(1, emptyCount);
for (let j = 0; j < breaksToAdd; j += 1) {
htmlLines.push("<br />");
}
} else if (emptyCount > 0) {
const extraBreaks = Math.max(0, emptyCount - 1);
for (let j = 0; j < extraBreaks; j += 1) {
htmlLines.push("<br />");
}
}
emptyCount = 0;
htmlLines.push(line); htmlLines.push(line);
seenNonEmpty = true; continue;
} }
paragraph.push(line);
if (emptyCount > 0) {
const extraBreaks = Math.max(0, emptyCount - 1);
for (let j = 0; j < extraBreaks; j += 1) {
htmlLines.push("<br />");
}
} }
flushParagraph();
html = htmlLines.join(""); html = htmlLines.join("");
// 7) Restore code blocks with header + copy button // 7) Restore code blocks with header + copy button