From 0d8b8a3f601dd575c2a939503fce408966e56392 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Mon, 12 May 2025 21:03:24 +0200 Subject: [PATCH] fix nested lists and correct the styling of wikilinks and hashtags --- src/lib/utils/markdown/basicMarkdownParser.ts | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/src/lib/utils/markdown/basicMarkdownParser.ts b/src/lib/utils/markdown/basicMarkdownParser.ts index f53d731..aaa5b29 100644 --- a/src/lib/utils/markdown/basicMarkdownParser.ts +++ b/src/lib/utils/markdown/basicMarkdownParser.ts @@ -145,11 +145,59 @@ function replaceWikilinks(text: string): string { const normalized = normalizeDTag(target.trim()); const display = (label || target).trim(); const url = `https://next-alexandria.gitcitadel.eu/publication?d=${normalized}`; - // Output as a clickable with the [[display]] format - return `[[${display}]]`; + // Output as a clickable with the [[display]] format and matching link colors + return `[[${display}]]`; }); } +function renderListGroup(lines: string[]): string { + // Recursive function to render a list group with proper nesting + function render(lines: string[], start = 0, indent = 0): [string, number] { + let html = ''; + let i = start; + let currentTag = ''; + while (i < lines.length) { + const line = lines[i]; + const match = line.match(/^([ \t]*)([*+-]|\d+\.)[ \t]+(.*)$/); + if (!match) break; + const lineIndent = match[1].replace(/\t/g, ' ').length; + const isOrdered = /\d+\./.test(match[2]); + const tag = isOrdered ? 'ol' : 'ul'; + if (!currentTag) { + html += `<${tag} class="ml-6 mb-2">`; + currentTag = tag; + } else if (lineIndent > indent) { + // Nested list + const [nestedHtml, consumed] = render(lines, i, lineIndent); + html += nestedHtml; + i = consumed; + continue; + } else if (lineIndent < indent) { + break; + } + html += `
  • ${match[3]}`; + // Check if next line is more indented (nested) + if (i + 1 < lines.length) { + const nextMatch = lines[i + 1].match(/^([ \t]*)([*+-]|\d+\.)[ \t]+/); + if (nextMatch) { + const nextIndent = nextMatch[1].replace(/\t/g, ' ').length; + if (nextIndent > lineIndent) { + const [nestedHtml, consumed] = render(lines, i + 1, nextIndent); + html += nestedHtml; + i = consumed - 1; + } + } + } + html += '
  • '; + i++; + } + html += ``; + return [html, i]; + } + const [html] = render(lines); + return html; +} + function processBasicFormatting(content: string): string { if (!content) return ''; @@ -229,7 +277,33 @@ function processBasicFormatting(content: string): string { }); // Process hashtags - processedText = processedText.replace(HASHTAG_REGEX, '#$1'); + processedText = processedText.replace(HASHTAG_REGEX, '#$1'); + + // --- Improved List Grouping and Parsing --- + const lines = processedText.split('\n'); + let output = ''; + let buffer: string[] = []; + let inList = false; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (/^([ \t]*)([*+-]|\d+\.)[ \t]+/.test(line)) { + buffer.push(line); + inList = true; + } else { + if (inList) { + output += renderListGroup(buffer); + buffer = []; + inList = false; + } + output += (output && !output.endsWith('\n') ? '\n' : '') + line + '\n'; + } + } + if (buffer.length) { + output += renderListGroup(buffer); + } + processedText = output; + // --- End Improved List Grouping and Parsing --- + } catch (error) { console.error('Error in processBasicFormatting:', error); }