diff --git a/utils/markdown.py b/utils/markdown.py
index 8cbb62a..a3196f1 100644
--- a/utils/markdown.py
+++ b/utils/markdown.py
@@ -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('')
+ in_list = False
+ if in_quote:
+ result_lines.append('')
+ in_quote = False
+ result_lines.append('')
+ continue
+
# Quote blocks (> text)
if stripped.startswith('> '): # Escaped >
if not in_quote:
@@ -66,7 +81,7 @@ def parse_forum_markdown(text):
result_lines.append('')
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
(but not inside pre/blockquote)
- # Simple approach: just convert \n to
- text = text.replace('\n', '
\n')
+ # Convert newlines to
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
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 ['
', '']) + next_is_block = any(next_stripped.startswith(t) for t in ['', '
- ', '
', '']) + if not is_block and not next_is_block: + output.append('
') - return Markup(text) + return Markup('\n'.join(output)) def register_markdown_filter(app):