fix: forum markdown parser - autolinks, line spacing, Windows line endings
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

- Normalize \r\n to \n before processing
- Strip leading whitespace from lines (textarea indentation)
- Auto-link bare URLs works correctly inside list items
- Smart <br> insertion: skip block elements (ul, li, blockquote, pre)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-02-23 08:54:35 +01:00
parent 53c0d24e2a
commit 7cbd3bb1e7

View File

@ -3,7 +3,7 @@ Simple Markdown Parser for Forum
================================
Converts basic markdown to safe HTML.
Supports: bold, italic, code, links, lists, quotes, @mentions
Supports: bold, italic, code, links, auto-links, lists, quotes, @mentions
"""
import re
@ -19,6 +19,7 @@ def parse_forum_markdown(text):
- *italic* or _italic_
- `inline code`
- [link text](url)
- bare https://... URLs (auto-linked)
- - list items
- > quotes
- @mentions (highlighted)
@ -32,6 +33,9 @@ def parse_forum_markdown(text):
if not text:
return Markup('')
# Normalize line endings (Windows \r\n -> \n)
text = text.replace('\r\n', '\n').replace('\r', '\n')
# Escape HTML first for security
text = str(escape(text))
@ -44,6 +48,17 @@ def parse_forum_markdown(text):
for line in lines:
stripped = line.strip()
# Skip empty lines but preserve paragraph spacing
if not stripped:
if in_list:
result_lines.append('</ul>')
in_list = False
if in_quote:
result_lines.append('</blockquote>')
in_quote = False
result_lines.append('')
continue
# Quote blocks (> text)
if stripped.startswith('&gt; '): # Escaped >
if not in_quote:
@ -66,7 +81,7 @@ def parse_forum_markdown(text):
result_lines.append('</ul>')
in_list = False
result_lines.append(line)
result_lines.append(stripped)
# Close open blocks
if in_list:
@ -121,11 +136,21 @@ def parse_forum_markdown(text):
text
)
# Convert newlines to <br> (but not inside pre/blockquote)
# Simple approach: just convert \n to <br>
text = text.replace('\n', '<br>\n')
# Convert newlines to <br> but skip lines that are HTML block elements
lines = text.split('\n')
output = []
for i, line in enumerate(lines):
output.append(line)
# Don't add <br> after block elements or before them
if i < len(lines) - 1:
stripped = line.strip()
next_stripped = lines[i + 1].strip() if i + 1 < len(lines) else ''
is_block = any(stripped.startswith(t) for t in ['<ul', '</ul>', '<li', '</li>', '<blockquote', '</blockquote>', '<pre', '</pre>'])
next_is_block = any(next_stripped.startswith(t) for t in ['<ul', '</ul>', '<li', '</li>', '<blockquote', '</blockquote>', '<pre', '</pre>'])
if not is_block and not next_is_block:
output.append('<br>')
return Markup(text)
return Markup('\n'.join(output))
def register_markdown_filter(app):